Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
a990b6e
chore: start v1.16.2 development
3aKHP Oct 10, 2026
f6006ec
feat(llm): add revisioned configuration database
3aKHP Oct 12, 2026
23d0335
feat(web-admin): add structured LLM config editor
3aKHP Oct 12, 2026
bc931f2
feat(deploy): integrate LLM config migration
3aKHP Oct 12, 2026
7572eb4
docs(llm): clarify operation timestamp examples
3aKHP Oct 12, 2026
a410e89
fix(llm): enforce credential and model boundaries
3aKHP Oct 12, 2026
3a814e3
fix(diagnostics): observe bot-owned model tasks
3aKHP Oct 12, 2026
466c7b9
fix(deploy): preserve private migration assets
3aKHP Oct 12, 2026
a40af50
fix(web-admin): retain config editing state
3aKHP Oct 12, 2026
e4cd127
fix(web-admin): preserve replacement entry identity
3aKHP Oct 12, 2026
9bd3b9f
Merge pull request #287 from 3aKHP/feat/llm-config-db
3aKHP Oct 12, 2026
f428319
chore: bump v1.16.2-dev.1
3aKHP Oct 12, 2026
d1ee73b
chore: remove private infrastructure references
3aKHP Oct 12, 2026
d321f48
feat(llm): add persistent session identities
3aKHP Oct 12, 2026
20cc48f
fix(session): reject late archived tool results
3aKHP Oct 12, 2026
04d8340
fix(session): close invalidated error loops
3aKHP Oct 12, 2026
2fad29c
Merge pull request #288 from 3aKHP/feat/session-lifecycle
3aKHP Oct 12, 2026
627d5b3
feat(llm): add client fingerprint profiles
3aKHP Oct 12, 2026
69b1316
fix(llm): fence profile startup and schema upgrade
3aKHP Oct 12, 2026
f70c458
test(llm): isolate profile schema regression
3aKHP Oct 12, 2026
2f07384
Merge pull request #290 from 3aKHP/feat/client-fingerprint-profiles
3aKHP Oct 12, 2026
185dbce
chore: bump dev version to 1.16.2-dev.2
3aKHP Oct 12, 2026
0af5b3e
feat(profiles): add OpenCode 2 Chat fingerprint
3aKHP Oct 13, 2026
cd8a92b
feat(profiles): align native HTTP header layout
3aKHP Oct 13, 2026
8b1f73f
refactor(profiles): separate identity and transport
3aKHP Oct 13, 2026
c4b18f1
Merge pull request #292 from 3aKHP/feat/opencode2-fingerprint
3aKHP Oct 13, 2026
b0619d7
feat(profiles): add lightweight Codex identity
3aKHP Oct 13, 2026
87893e2
refactor(profiles): share cache field vocabulary
3aKHP Oct 13, 2026
5d7433f
Merge pull request #293 from 3aKHP/feat/codex-fingerprint
3aKHP Oct 13, 2026
db88a06
feat(llm): add Claude Code Messages profile
3aKHP Oct 13, 2026
b0477b0
Merge pull request #294 from 3aKHP/feat/claude-code-profile
3aKHP Oct 13, 2026
6dd4889
feat(profiles): set protocol client defaults
3aKHP Oct 13, 2026
9a91e75
test(profiles): isolate default identity files
3aKHP Oct 13, 2026
8df6bdc
Merge pull request #295 from 3aKHP/feat/protocol-default-profiles
3aKHP Oct 13, 2026
867c761
chore: bump dev version to 1.16.2-dev.6
3aKHP Oct 13, 2026
96b032e
fix(storage): detach deleted message references
3aKHP Oct 13, 2026
3f357e6
refactor(llm): share storage readiness check
3aKHP Oct 13, 2026
8be6f83
Merge pull request #296 from 3aKHP/fix/session-turn-reference-lifecycle
3aKHP Oct 13, 2026
5c61b95
chore: bump dev version to 1.16.2-dev.7
3aKHP Oct 13, 2026
9e00f5b
feat(llm): add Gemini CLI fingerprint
3aKHP Oct 14, 2026
ba9d49c
docs(llm): document session model projection
3aKHP Oct 14, 2026
dbe1ae6
Merge pull request #297 from 3aKHP/feat/gemini-cli-profile
3aKHP Oct 14, 2026
0f29f53
fix(trace): index stale pending lookups
3aKHP Oct 14, 2026
7db3e37
Merge pull request #298 from 3aKHP/fix/trace-pending-index
3aKHP Oct 14, 2026
fb78865
feat(llm): add revision notes and provider-scoped pricing (config sch…
3aKHP Oct 14, 2026
18ef8af
feat(web-admin): rework LLM config workbench with version labels and …
3aKHP Oct 14, 2026
e636937
docs(llm): document revision notes, format 2 and provider-scoped pricing
3aKHP Oct 14, 2026
26d29d6
Merge pull request #299 from 3aKHP/feat/v1.16.2-llm-config-workbench
3aKHP Oct 14, 2026
b083da8
chore: bump dev version to 1.16.2-dev.8
3aKHP Oct 14, 2026
2b48097
fix(webview): normalize IPv6 admin URLs
3aKHP Oct 14, 2026
a18002d
fix(commands): prefer canonical session command
3aKHP Oct 14, 2026
ed35f17
test(llm): verify group binding transitions
3aKHP Oct 14, 2026
0f7398f
test(storage): cover retention boundaries
3aKHP Oct 14, 2026
50f701e
docs(llm): document request troubleshooting
3aKHP Oct 14, 2026
549cca3
Merge pull request #300 from 3aKHP/fix/v1.16.2-acceptance-closeout
3aKHP Oct 14, 2026
e2d07d8
docs(release): define focused release review
3aKHP Oct 14, 2026
6232877
chore(release): prepare v1.16.2
3aKHP Oct 14, 2026
cd77909
fix(release): include Windows package metadata
3aKHP Oct 14, 2026
a0a6a9c
docs(release): align public guides for v1.16.2
3aKHP Oct 14, 2026
385ee54
docs(release): finalize v1.16.2 documentation
3aKHP Oct 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .claude/agents/quickquip-cr-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ You are an independent code reviewer for the QuickQuip repository. You did not p
- State the reviewed scope and base in the output.
- Read the diff and surrounding code. A summary alone is insufficient.

### Release scope

For a Release, apply the release-specific review in `docs/dev/branching.md`. Record the target-branch or previous-tag base, the frozen development SHA, and the final candidate SHA. Use the cumulative diff to map delivered work and evidence; review the release-preparation diff and relevant integration code directly. Existing PR reviews and checks can bound the review scope. Cumulative size and a deep-review trigger on that cumulative range do not require a full historical line-by-line review.

Check release metadata and upgrade/rollback instructions against actual configuration, persistence, startup, packaging, and deployment paths. Select the important cross-PR interfaces for this release and state the code and evidence inspected. Expand a module's review when missing evidence, conflicting contracts, or a reproducible failure warrants it. Grade new implementation fixes against their own starting SHA using the normal Standard/Huge rules. Report platform and real-provider checks not performed under Not verified. Special milestones use the additional checklist fixed by the maintainer.

## Read the contracts first

- `CLAUDE.md` and `CONTRIBUTING.md`: repository boundaries, branch rules, secrets, local configuration, and verification.
- `docs/dev/README.md`: developer-document ownership and the public/private boundary.
- `docs/dev/documenting.md`: public-document responsibilities, factual accuracy, reader-focused prose, operational examples, maintenance, and review; check preemptive disclaimers and excessive boundary statements by their purpose for the reader.
- `docs/dev/style.md`: responsibilities, prohibited god structures, module boundaries, input validation, durable state, and review questions.
- `docs/dev/testing.md`: test discipline — admission, assertion basis, antipatterns, and keep/merge/delete rules for test changes.
- `docs/dev/architecture.md`: dependency direction and domain ownership.
Expand Down
12 changes: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ PORT=8080
# 容器与进程的时区(日志、定时任务展示时间等),compose 部署默认 Asia/Shanghai。
TZ=Asia/Shanghai
ONEBOT_ACCESS_TOKEN=your_token_here
# 本地直跑(非 compose)连本机 OneBot 协议端正向 WebSocket 时取消注释并按实际地址修改;JSON 数组,可配多个。
# compose 部署由编排注入默认值,无需设置。
# 本机源码运行时,取消下一行注释并填写 OneBot 正向 WebSocket 地址;JSON 数组支持多个连接。
# compose 部署由编排提供容器网络中的默认地址。
# ONEBOT_WS_URLS=["ws://localhost:3001/"]
QQ_ACCOUNT=your_qq_account_here
OPENAI_API_KEY=your_openai_key_here
ANTHROPIC_API_KEY=your_claude_key_here
GEMINI_API_KEY=your_gemini_key_here
DEEPSEEK_API_KEY=your_deepseek_key_here
SEARXNG_BASE_URL=http://127.0.0.1:8888
# 仅 prod.example 运维模板必填:指向外部 searxng 实例(未设置 compose 启动报错)。
# docker-compose.example.yml 自包含模板无需设置(内联默认已生效)。
# prod.example 运维模板使用外部 SearXNG,请填写下面的地址;缺失时 compose 校验失败。
# 根 docker-compose.example.yml 提供内置 SearXNG 和默认容器地址。
# QUICKQUIP_SEARXNG_BASE_URL=http://searxng:8080
SEARXNG_PUBLIC_BASE_URL=http://127.0.0.1:8888/
SEARXNG_BIND_ADDRESS=127.0.0.1
SEARXNG_BIND_PORT=8888
SEARXNG_SECRET=change-this-secret
TAVILY_API_KEY=your_tavily_key_here
# openweather MCP 示例(config/llm.toml.example)引用的天气 API key,启用该示例时填写。
# 旧 TOML 迁移模板中的 openweather MCP 示例引用此天气 API key;启用该服务时填写。
# OWM_API_KEY=
GITHUB_PERSONAL_ACCESS_TOKEN=your_github_pat_here
GITHUB_TOOLSETS=context,repos,issues,pull_requests,users,actions
GITHUB_READ_ONLY=
MCP_ARXIV_PAPERS_MOUNT=arxiv-papers:/root/.arxiv-mcp-server/papers
# prts_wiki MCP 鉴权 token,见 config/llm.toml.example。
# prts_wiki MCP 鉴权 token,见 config/llm.json.example 的 settings.mcp.servers。
# MCP_PRTS_WIKI_TOKEN=
TIEBA_ENABLED=false
TIEBA_FORUM_KEYWORD=
Expand Down
12 changes: 4 additions & 8 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
# Binary files are auto-detected and never touched.
* text=auto eol=lf

# Windows-native scripts must keep CRLF. PowerShell 7+ accepts LF, but we
# keep CRLF explicitly so Windows-only tooling never trips over line endings.
*.ps1 text eol=crlf
*.bat text eol=crlf
*.cmd text eol=crlf

# Cross-platform production templates use UTF-8 with LF.
prod.example/*.ps1 text eol=lf
# Textual Windows launchers and cross-platform templates use LF.
*.ps1 text eol=lf
*.bat text eol=lf
*.cmd text eol=lf

# Image assets
*.png binary
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ body:
- type: textarea
id: boundaries
attributes:
label: 边界与非目标 / Boundaries & non-goals
description: 范围之外的内容;不应改变的行为。
label: 使用条件与取舍 / Constraints & trade-offs
description: 影响方案选择的实际条件、目标范围与需要保留的行为。
- type: textarea
id: related
attributes:
Expand Down
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/memo.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ labels: [memo]

## 现象与锚点 / Observations & anchors

<!-- 每条一行,带 file:line 或 #issue 锚点;多条目备忘逐条编号 -->
<!-- 记录具体观察与证据;需要定位实现时附 file:line 或 #issue,多条目逐条编号 -->

## 待厘清的设计问题 / Open design questions

<!-- 推进前必须先回答什么 -->

## 边界与非目标 / Boundaries & non-goals
## 约束与取舍 / Constraints & trade-offs

<!-- 不承诺实现 / 不冻结方案 / 不因本 issue 改动的既有合同 -->
<!-- 写明影响方案选择的实际条件、已确定的范围与需要保留的行为 -->

## 范围与状态 / Scope & status

Expand Down
38 changes: 31 additions & 7 deletions .github/PULL_REQUEST_TEMPLATE/release.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
发布 PR:dev → main(docs/dev/branching.md「发布生命周期」)。
发布 PR:dev 或 release/* → main(docs/dev/branching.md「发布生命周期」)。
标题格式:release: vX.Y.Z — <摘要>
GitHub 不一定展示 PR 模板选择器,可显式指定本模板:
gh pr create --base main --title "release: vX.Y.Z — <摘要>" \
Expand All @@ -10,8 +10,9 @@
## Summary

- 本版自上一 tag 以来承载的变更与重点。
- 目标版本与冻结的候选 SHA。
- 合并后在 main 已接受提交上打 `vX.Y.Z` tag,触发 release.yml。
- 目标版本、普通累积版本/特殊里程碑,以及发行范围。
- 目标分支/上一 tag 基线、开发冻结 SHA、最终候选 SHA。
- 合并与最终 tag 分别等待维护者专门人工审核批准。

## Release checklist

Expand All @@ -20,21 +21,44 @@
- [ ] `skills.example/` 有变动时,Release notes 含「预置 Skill 变动」小节(提示部署者运行 `scripts/sync_preset_skills.py` 同步)
- [ ] 公开文档、配置模板与 `prod.example/` 完成旧术语扫尾
- [ ] `README.md` 功能亮点清单与本版新增能力对照(新功能是否露出、既有描述是否过期)
- [ ] 分级要求的评审完成(至少 Standard;达到门槛时按 Huge 执行 Deep-CR)
- [ ] 独立发布专项 CR 完成:交付证据、发布一致性、重要集成边界
- [ ] Blocking 已修复;Should-fix 已修复或附延期理由
- [ ] 特殊里程碑的专项清单已确定并完成(普通 Release 注明不适用)

## Release CR

- 累计交付范围与已有 PR 证据:
- 发布准备新增差异:
- 实际检查的集成边界与代码/测试:
- Blocking / Should-fix / Nits:
- Verified claims / Not verified:

按 `docs/dev/branching.md` 的发布专项 CR 检查交付证据、发布准备差异和重要集成接口;复审范围由证据与具体问题确定。新增功能性修复按自身差异执行 Standard/Huge 规则。

## Test Plan

- [ ] `.venv/bin/ruff check .`
- [ ] `.venv/bin/python scripts/ci/validate_toml_examples.py`
- [ ] `.venv/bin/python -m pytest -n auto`
- [ ] `pnpm --dir frontend type-check`
- [ ] `pnpm --dir frontend test`
- [ ] `pnpm --dir frontend build`
- [ ] tag 后发行产物核对:tag、Windows 懒人包、Docker 镜像 revision/digest 与 Release notes 一致
- [ ] 与风险相称的 Windows / Docker / Linux 消费者验收
- [ ] self-docs 同步、ID 检查及发布说明提取通过
- 未验证平台/真实渠道与后续安排:

## 人工合并审核

- [ ] 最终候选 SHA 的 CI 通过,评审结论与该 SHA 对应
- [ ] 维护者已专门批准该候选合并;批准记录:

候选变化后更新检查与结论,重新提交审核。合并与 tag 分别记录批准。

## 合并后 / After merge

- [ ] 在 main 创建并推送 `vX.Y.Z` tag,触发 release.yml
- [ ] main 合并提交及 CI 核对完成
- [ ] 维护者单独批准 `vX.Y.Z` 的目标 SHA;批准记录:
- [ ] 获批后在 main 创建并推送 tag,触发 release.yml
- [ ] 核对发行 workflow 构建/smoke、tag、版本、Windows ZIP、镜像 revision/digest 与 Release notes
- [ ] main 回灌 dev(可快进则 `--ff-only`,否则开 `chore/back-merge-vX.Y.Z` PR)
- [ ] 核对 dev 下一目标版本(常规发布后默认下一 Patch 的 `-dev.0`),必要时更新 `pyproject.toml`
- [ ] 清理已发布的本地 changelog 草稿与短分支
Expand Down
24 changes: 21 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ jobs:
env:
PLAYWRIGHT_BROWSERS_PATH: "0"

- name: Install QuickQuip project
run: |
staging\python\python.exe -m pip install --no-warn-script-location "setuptools>=68" wheel
if ($LASTEXITCODE -ne 0) { throw "QuickQuip build dependencies installation failed" }
# Embedded Python uses ._pth; build with the installed backend.
staging\python\python.exe -m pip install --no-deps --no-build-isolation --no-warn-script-location .
env:
PIP_NO_CACHE_DIR: "1"

- name: Copy project files
run: |
Copy-Item -Recurse src\quickquip staging\
Expand All @@ -94,7 +103,7 @@ jobs:
$expected = @(
"staging\start.bat", "staging\.env.example", "staging\scripts\backfill_chat_archive.py", "staging\scripts\backfill_record_identities.py",
"staging\scripts\sync_preset_skills.py",
"staging\config\llm.toml.example", "staging\config\chat_rules.toml.example",
"staging\config\llm.json.example", "staging\config\llm.toml.example", "staging\config\chat_rules.toml.example",
"staging\config\generation.toml.example", "staging\config\games.toml.example",
"staging\config\awakening.toml.example", "staging\config\sensitive_words.toml.example",
"staging\config\niuniu_text.toml.example", "staging\config\niuniu_text_safe.toml.example",
Expand Down Expand Up @@ -132,9 +141,18 @@ jobs:
run: |
staging\python\python.exe -m compileall -q staging\bot.py staging\web_api.py staging\webview_launcher.py staging\quickquip staging\plugins
staging\python\python.exe -c "import webview; print('pywebview ok')"
staging\python\python.exe -c "from importlib.metadata import version; from pathlib import Path; from packaging.version import Version; import tomllib; expected = tomllib.loads(Path('pyproject.toml').read_text(encoding='utf-8'))['project']['version']; assert Version(version('quickquip')) == Version(expected); print('QuickQuip installed version ok')"
if ($LASTEXITCODE -ne 0) { throw "QuickQuip package version smoke test failed" }
Push-Location staging
try {
.\python\python.exe -c "import quickquip, plugins, web_api; print('app import ok')"
.\python\python.exe -m quickquip.llm.config_cli init
if ($LASTEXITCODE -ne 0) { throw "Configuration database initialization failed" }
.\python\python.exe -m quickquip.llm.config_cli validate
if ($LASTEXITCODE -ne 0) { throw "Configuration database validation failed" }
.\python\python.exe -m quickquip.llm.config_cli validate config\llm.json.example
if ($LASTEXITCODE -ne 0) { throw "Configuration JSON example validation failed" }
.\python\python.exe -c "import quickquip, plugins, web_api; from importlib.metadata import version; from quickquip.llm.client_fingerprints.identity import client_version; assert client_version() == version('quickquip'); print('app import and client version ok')"
if ($LASTEXITCODE -ne 0) { throw "Application import and client version smoke test failed" }
.\python\python.exe scripts\sync_preset_skills.py --apply --skills-dir data\preset-sync-smoke
if ($LASTEXITCODE -ne 0) { throw "Preset Skill sync startup smoke test failed" }
.\python\python.exe scripts\sync_preset_skills.py --check --skills-dir data\preset-sync-smoke
Expand Down Expand Up @@ -247,7 +265,7 @@ jobs:

- name: Smoke test Docker image
run: |
docker run --rm quickquip:smoke sh -euxc 'test -f /app/frontend/dist/index.html && test -f /app/llm_about/vocab.yaml.example && docker --version && python -m compileall -q bot.py web_api.py && python -c "import quickquip, plugins, web_api"'
docker run --rm quickquip:smoke sh -euxc 'test -f /app/frontend/dist/index.html && test -f /app/llm_about/vocab.yaml.example && docker --version && python -m compileall -q bot.py web_api.py && python -m quickquip.llm.config_cli init && python -m quickquip.llm.config_cli validate config/llm.json.example && python -c "import quickquip, plugins, web_api"'
docker run --rm quickquip:smoke sh -euxc 'python scripts/sync_preset_skills.py --apply --skills-dir /tmp/preset-sync-smoke && python scripts/sync_preset_skills.py --check --skills-dir /tmp/preset-sync-smoke'
# 存活探测:bot.py 必须活到 timeout(退出码 124)——import 冒烟抓不到
# nonebot.load_plugins 的路径约束。勿改成 -euxc:set -e 会让 124 直接
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ config/sensitive_words.toml
config/awakening.toml
config/admins.toml
config/personas/
config/client_profiles/
config/llm.local.toml
config/llm.*.local.toml
!config/*.example
Expand Down
Loading
Loading