chore: sync worktree changes - update protocols, trellis workspace, and config

This commit is contained in:
qzl
2026-04-23 16:04:04 +08:00
parent eeed737949
commit dcb0eb4c65
13 changed files with 519 additions and 40 deletions
+1 -1
View File
@@ -101,4 +101,4 @@ SOCIAL_ANALYTICS__PASSWORD=analytics-secret-change-me
# Test相关
############
SOCIAL_TEST__PHONE=8613812345678
SOCIAL_TEST__PASSWORD=Test@123456
SOCIAL_TEST__CODE=123456
-2
View File
@@ -308,8 +308,6 @@ infra/docker/supabase/volumes/storage/
# .opencode/ is now tracked - see .opencode/.gitignore for exclusions
.opencode/opencode.json.old
# Agents and skills
.agents/
# Local git worktrees
.worktrees/
+20 -7
View File
@@ -1,10 +1,23 @@
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"supabase": {
"type": "remote",
"enabled": true,
"url": "http://localhost:8001/mcp"
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "allow",
"git checkout --*": "ask",
"git checkout -- *": "ask",
"git restore *": "ask",
"git reset --hard*": "ask",
"git reset HEAD*": "ask",
"git revert*": "ask",
"git clean*": "ask",
"git stash drop*": "ask"
}
},
"mcp": {
"supabase": {
"type": "remote",
"enabled": true,
"url": "http://localhost:8001/mcp"
}
}
}
}
+376
View File
@@ -0,0 +1,376 @@
{
"name": ".opencode",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@opencode-ai/plugin": "1.14.19"
}
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
"integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
"integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
"integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
"integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
"integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
"integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@opencode-ai/plugin": {
"version": "1.14.19",
"resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.14.19.tgz",
"integrity": "sha512-g0C8Viocybmet7nBqJK/1xrQnacRS1f30VmqRTPScPmWz+4knIZzc2TEQp8+920sN8rB6BuoGwfBUVRXJmavhQ==",
"license": "MIT",
"dependencies": {
"@opencode-ai/sdk": "1.14.19",
"effect": "4.0.0-beta.48",
"zod": "4.1.8"
},
"peerDependencies": {
"@opentui/core": ">=0.1.101",
"@opentui/solid": ">=0.1.101"
},
"peerDependenciesMeta": {
"@opentui/core": {
"optional": true
},
"@opentui/solid": {
"optional": true
}
}
},
"node_modules/@opencode-ai/sdk": {
"version": "1.14.19",
"resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.14.19.tgz",
"integrity": "sha512-9sTGsi8/HlBBeaWfsUjdJ2yi/SqpRvqSld0IFXc3ldaPb1w1uIPvgCGzhlHYQtqatXxSaX5lTN7zpudMaE21aw==",
"license": "MIT",
"dependencies": {
"cross-spawn": "7.0.6"
}
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/effect": {
"version": "4.0.0-beta.48",
"resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-beta.48.tgz",
"integrity": "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw==",
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"fast-check": "^4.6.0",
"find-my-way-ts": "^0.1.6",
"ini": "^6.0.0",
"kubernetes-types": "^1.30.0",
"msgpackr": "^1.11.9",
"multipasta": "^0.2.7",
"toml": "^4.1.1",
"uuid": "^13.0.0",
"yaml": "^2.8.3"
}
},
"node_modules/fast-check": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.7.0.tgz",
"integrity": "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/dubzzz"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fast-check"
}
],
"license": "MIT",
"dependencies": {
"pure-rand": "^8.0.0"
},
"engines": {
"node": ">=12.17.0"
}
},
"node_modules/find-my-way-ts": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz",
"integrity": "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==",
"license": "MIT"
},
"node_modules/ini": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz",
"integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==",
"license": "ISC",
"engines": {
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/kubernetes-types": {
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.30.0.tgz",
"integrity": "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==",
"license": "Apache-2.0"
},
"node_modules/msgpackr": {
"version": "1.11.10",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.10.tgz",
"integrity": "sha512-iCZNq+HszvF+fC3anCm4nBmWEnbeIAfpDs6IStAEKhQ2YSgkjzVG2FF9XJqwwQh5bH3N9OUTUt4QwVN6MLMLtA==",
"license": "MIT",
"optionalDependencies": {
"msgpackr-extract": "^3.0.2"
}
},
"node_modules/msgpackr-extract": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
"integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"node-gyp-build-optional-packages": "5.2.2"
},
"bin": {
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
},
"optionalDependencies": {
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
}
},
"node_modules/multipasta": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.7.tgz",
"integrity": "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==",
"license": "MIT"
},
"node_modules/node-gyp-build-optional-packages": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
"integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
"license": "MIT",
"optional": true,
"dependencies": {
"detect-libc": "^2.0.1"
},
"bin": {
"node-gyp-build-optional-packages": "bin.js",
"node-gyp-build-optional-packages-optional": "optional.js",
"node-gyp-build-optional-packages-test": "build-test.js"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pure-rand": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz",
"integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/dubzzz"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fast-check"
}
],
"license": "MIT"
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/toml": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/toml/-/toml-4.1.1.tgz",
"integrity": "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==",
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/uuid": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/yaml": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
"integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/zod": {
"version": "4.1.8",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
@@ -13,11 +13,11 @@
"subtasks": [
{
"name": "Fill backend guidelines",
"status": "pending"
"status": "completed"
},
{
"name": "Add code examples",
"status": "pending"
"status": "completed"
}
],
"children": [],
@@ -14,7 +14,7 @@
"branch": null,
"base_branch": "dev",
"worktree_path": null,
"current_phase": 2,
"current_phase": 3,
"next_action": [
{
"phase": 1,
+4 -3
View File
@@ -8,8 +8,8 @@
<!-- @@@auto:current-status -->
- **Active File**: `journal-1.md`
- **Total Sessions**: 0
- **Last Active**: -
- **Total Sessions**: 1
- **Last Active**: 2026-04-22
<!-- @@@/auto:current-status -->
---
@@ -19,7 +19,7 @@
<!-- @@@auto:active-documents -->
| File | Lines | Status |
|------|-------|--------|
| `journal-1.md` | ~0 | Active |
| `journal-1.md` | ~40 | Active |
<!-- @@@/auto:active-documents -->
---
@@ -29,6 +29,7 @@
<!-- @@@auto:session-history -->
| # | Date | Title | Commits |
|---|------|-------|---------|
| 1 | 2026-04-22 | AgentScope CLI/Skill Runtime Simplification | - |
<!-- @@@/auto:session-history -->
---
+46
View File
@@ -5,3 +5,49 @@
---
## 2026-04-22 - AgentScope CLI/Skill Runtime Simplification
### Completed
- Removed runtime injection of `tool_prompt.py` and deleted the file.
- Simplified router contract to a minimal `RouterAgentOutput`:
- `objective`
- `context_summary`
- `requires_tool_evidence`
- Removed router schema complexity that was not driving runtime behavior:
- `normalized_task_input`
- `task_typing`
- `result_typing`
- `execution_mode`
- related enums/models/exports/tests
- Simplified worker prompt back to a generic execution contract prompt instead of tool-specific instructions.
- Added runtime forcing for the first worker tool call when `requires_tool_evidence=true` by setting `tool_choice='required'` once.
- Added minimal compatibility for observed qwen tool-call shape where `project_cli.args` is emitted as a JSON string.
### Verified Findings
- Router is now producing the expected compact contract in persisted metadata.
- Direct provider calls with the current worker prompt and current tool schema do produce `tool_use(project_cli)`.
- `ReActAgent + Toolkit` can execute tool calls in isolation.
- Local direct `JsonReActAgent` execution can also reach the tool call path.
### Current Blocker
- Live integration is still not fully passing.
- In live runs, SSE/history still do not show persisted `TOOL_CALL_RESULT` messages.
- This means the remaining issue is no longer router schema complexity.
- Current evidence suggests the remaining fault is in the live AgentScope runtime/event path rather than in router intent extraction.
### Important Distinction About Credentials
- One observed local repro failed with `CREDENTIAL_INVALID`, but that repro used a plain user bearer token where the runtime expects a dedicated issued `tool_credential` JWT.
- That credential failure is real for that local repro, but it is not sufficient to explain the main live failure by itself.
- The main live failure is that tool events are still missing from SSE/history even after router contract simplification and forced tool choice.
### Next Steps
1. Trace the live runtime path from worker tool execution to `PipelineStageEmitter` and event persistence.
2. Confirm whether tool calls are being executed in live runs but dropped before SSE/history.
3. Inspect the tool-result parsing path around `parse_tool_agent_output(...)` and emitter state handling.
4. After live tool events are visible, rerun the calendar live integration until the sequence is stable.
5. Do one more cleanup pass to remove any remaining non-essential compatibility or glue.
+13 -6
View File
@@ -64,13 +64,20 @@
## Error Codes
推荐错误码(由后端映射为 4xx
当前实现(`backend/src/v1/schedule_items/service.py`)实际返回以下稳定错误码
- `INVALID_DATETIME_FORMAT`
- `NAIVE_DATETIME_FORBIDDEN`
- `INVALID_TIMEZONE`
- `TIMEZONE_REQUIRED`
- `INVALID_TIME_RANGE`
- `SCHEDULE_ITEM_DATETIME_TIMEZONE_REQUIRED`:输入 datetime 缺少时区偏移
- `SCHEDULE_ITEM_START_AT_TIMEZONE_REQUIRED``end_at` 校验阶段缺少可用的 `start_at` 时区信息
- `SCHEDULE_ITEM_INVALID_TIME_RANGE``end_at <= start_at`
说明:`timezone` 非法、`start_at/end_at` 无时区等基础结构错误在 schema 校验阶段由 FastAPI/Pydantic 返回 `422`,业务错误码表(`docs/protocols/common/http-error-codes.md`)目前仅登记服务层稳定码。
---
## Compatibility Strategy
- 策略:`backward-compatible`
- 本次为文档对齐更新,不改变线上接口行为;客户端若仅按 HTTP 状态码处理不受影响。
---
+25 -17
View File
@@ -12,28 +12,29 @@
### 1) 作用域级别
- `anonymous`:未登录态(或未绑定用户上下文)
当前实现仅启用以下作用域:
- `user:<user_id>`:已登录用户态
未登录态实现说明:
- `apps/lib/app/services/session_scope_manager.dart` 在登出后会调用 `CacheScope.resetProvider()`
- 当 provider 未配置时,`apps/lib/data/cache/cached_repository.dart` 会跳过 scoped cache 读写,而不是写入 `anonymous` 命名空间。
### 2) 键格式
客户端持久缓存最终键必须按以下格式生成:
`cache:<scope>:<feature-key>`
其中 `<scope>` 可以附带会话代际后缀(推荐)
当前实现未使用会话代际后缀(epoch/version token),最终键格式为
- `user:<user_id>:v<epoch>`
- `anonymous:v<epoch>`
该后缀用于切号并发场景,确保旧会话异步回写落在旧命名空间。
- `cache:user:<user_id>:<feature-key>`
示例:
- `cache:user:8ef4...:chat:history:first:default`
- `cache:user:8ef4...:v12:chat:history:first:default`
- `cache:user:8ef4...:v12:calendar:day:2026-03-29`
- `cache:anonymous:v13:inbox:list:all`
- `cache:user:8ef4...:calendar:day:2026-03-29`
---
@@ -47,18 +48,18 @@
### 应用层(必须)
- 在认证状态变化时更新当前缓存作用域:
- 登录成功 -> `user:<user_id>`
- 登出/失效 -> `anonymous`
- 登录成功 -> `user:<user_id>`
- 登出/失效 -> 清空当前用户作用域并重置 provider(不进入 `anonymous` 作用域)
---
## 并发与切号安全
- 切号后,旧账号异步请求结果不得回写到新账号 UI 状态。
- 推荐使用会话代际(epoch/token)保护异步回写。
- 缓存分区与 UI 状态隔离必须同时存在:
- 仅有分区,无代际保护:仍可能出现瞬时回流显示。
- 仅有代际保护,无分区:仍可能读取到旧持久缓存
- 当前实现依赖 `user:<user_id>` 级别缓存分区 + 认证切换时清理上一用户前缀:
- - 登录切换:清理上一用户 `cache:user:<old_user_id>:` 前缀
- - 登出:清理当前用户前缀并关闭 scoped cache 读写
- 当前实现未引入 epoch/token 代际保护;若未来出现“切号后旧请求晚到并覆盖新 UI”问题,需要另行升级协议与实现
---
@@ -67,7 +68,7 @@
### 向后兼容
- 旧无作用域键允许保留在本地存储中,不参与新读取路径。
- 新版本只读取带 `cache:<scope>:` 前缀的键。
- 新版本只读取带 `cache:user:<user_id>:` 前缀的键。
### 迁移方式
@@ -79,5 +80,12 @@
## 验收标准
1. 同设备 A/B 账号来回切换,不出现跨账号历史/列表串读。
2. 登录后首次读取命中当前用户作用域键;登出后读取命中匿名作用域键
2. 登录后首次读取命中当前用户作用域键;登出后 scoped cache 不再参与读取。
3. Feature 仓库不再自行实现 userId 拼 key 逻辑。
---
## Compatibility Strategy
- 策略:`backward-compatible`
- 本次为文档对齐更新,收敛未落地的 `anonymous`/epoch 设计,不改变现有应用行为。
+13
View File
@@ -215,12 +215,18 @@ data: {"event_id":"6f0d...","occurred_at":"2026-03-30T07:00:00Z","user_id":"..."
"occurred_at": "datetime",
"user_id": "uuid",
"message_id": "uuid",
"event_type": "INBOX_MESSAGE_CREATED | INBOX_MESSAGE_READ_CHANGED | INBOX_MESSAGE_STATUS_CHANGED | INBOX_SNAPSHOT_REQUIRED",
"op": "created | read_changed | status_changed | snapshot_required",
"version": 1743313300000,
"data": {}
}
```
说明:
- SSE 帧的 `event:` 行与 payload 内 `event_type` 当前实现保持一致。
- 客户端可优先使用 SSE `event`,也可在 payload 内读取 `event_type` 做调试或补偿。
### Delta 约定
- `created`:
@@ -275,3 +281,10 @@ data: {"event_id":"6f0d...","occurred_at":"2026-03-30T07:00:00Z","user_id":"..."
- 对 `message_type=calendar`,前端必须按 `content.type` 严格分发:`invite | updated | deleted`。
- 若 `content` 缺少协议必填字段(`schema_version/item/actor/summary`,以及 `updated` 的 `changes`),前端必须进入协议异常展示路径。
- 禁止将协议异常消息兜底渲染为“默认日历邀请”或其他正常业务消息。
---
## Compatibility Strategy
- 策略:`backward-compatible`
- 本次仅补全文档遗漏字段 `event_type`,不改变现有 SSE wire 协议。
+8 -1
View File
@@ -43,7 +43,7 @@ Base URL: `/api/v1/users`
字段说明:
- `id`: 用户唯一标识符 (UUID)
- `username`: 用户名,3-30 字符
- `username`: 用户名,当前后端更新接口约束为最大 30 字符(最小长度未在 API 层强制)
- `phone`: E.164 格式手机号,可为 null
- `avatar_url`: 头像 URL,可为 null
- `bio`: 个人简介,最大 200 字符,可为 null
@@ -142,3 +142,10 @@ Base URL: `/api/v1/users`
### Response
`UserContext` 对象。
---
## Compatibility Strategy
- 策略:`backward-compatible`
- 本次仅修正文档约束描述与实现一致,不改变接口字段与响应结构。
+10
View File
@@ -0,0 +1,10 @@
{
"version": 1,
"skills": {
"agentscope-skill": {
"source": "agentscope-ai/agentscope-skills",
"sourceType": "github",
"computedHash": "1515501dc701bfa9090bf32336ebd7f36225ff233a11598dc89a984cfe5be369"
}
}
}