fix(sdk): compose token meter for compact projects

This commit is contained in:
Hypatia May
2026-07-16 10:07:11 +08:00
parent 8d0d9bdd1d
commit 7250aaea7e
3 changed files with 18 additions and 21 deletions

View File

@@ -24,7 +24,7 @@ A harness is one [Cordis](cordis-primer.md) context. Packages contribute service
| ctx key | Package family | Role |
|---|---|---|
| `ctx.llm` | [`llm/`](../packages/llm/README.md) | adapter registry and streaming model calls |
| `ctx.tokenMeter` | [`llm/token-meter`](../packages/llm/token-meter/README.md) | replay-aware per-model request and surface pressure |
| `ctx.tokenMeter` | [`llm/token-meter`](../packages/llm/token-meter/README.md) | replay-aware request/surface pressure per model |
| `ctx.bash` | [`bash/`](../packages/bash/README.md) | foreground/background command execution |
| `ctx.sandbox` | [`sandbox/`](../packages/sandbox/README.md) | same-world process confinement (argv wrapping, per-call policy) |
| `ctx.codeRuntime` | [`code-runtime/`](../packages/code-runtime/README.md) | model-written program execution |
@@ -82,7 +82,7 @@ forever:
agent/request (config only) -> log request/header -> llm/stream (frozen)
'assistant/chunk'
agent/step-result
'assistant/message' (transformed content, or an empty successful-call anchor if step-result rejects)
'assistant/message' (transformed content or empty success anchor after step-result rejection)
each tool call:
'tool/call'
tools/pre-execute -> monotonic guards -> tools/execute -> tools/post-execute -> tools/result
@@ -126,7 +126,7 @@ Durability is a plugin concern. Persistence backends buffer synchronous `session
### Model Content
Messages are arrays of typed content blocks (`text`, `reasoning`, `tool-call`, `tool-result`). The union derives from the merge-extensible `ContentBlockMap`; the same pattern types `MessageSource`, `FinishReason`, `TurnTrigger`, and `TurnEndReason`. New block types are coordinated across adapters, UI bridges, token metering, and persistence, so block types remain a repo-wide contract. Replay measurement types are cataloged in [token-meter.md](core-data-structures/token-meter.md).
Messages are arrays of typed content blocks (`text`, `reasoning`, `tool-call`, `tool-result`). The union derives from the merge-extensible `ContentBlockMap`; the same pattern types `MessageSource`, `FinishReason`, `TurnTrigger`, and `TurnEndReason`. New block types require coordinated adapter, UI, token-meter, and persistence changes; replay measurement types live in [token-meter.md](core-data-structures/token-meter.md).
Streaming is a raw chunk protocol (`block-start` through `finish`) with `BlockAssembler` as the shared chunk-to-block assembler. The loop logs raw chunks while assembling them for dispatch. `LlmAdapter` is the provider seam: subclass, implement `stream()`, and register with `ctx.llm.registerAdapter(models, adapter)`. StreamChunk conventions live in [llm-streaming.md](core-data-structures/llm-streaming.md).

View File

@@ -33,7 +33,6 @@
},
"devDependencies": {
"@deepseek-ai/dsh-brand": "workspace:^",
"@deepseek-ai/dsh-compact-basic": "workspace:^",
"@deepseek-ai/dsh-hooks-claude": "workspace:^",
"@deepseek-ai/dsh-hooks-codex": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",

32
pnpm-lock.yaml generated
View File

@@ -832,7 +832,7 @@ importers:
dependencies:
'@earendil-works/pi-ai':
specifier: ^0.79.1
version: 0.79.3(ws@8.21.0)(zod@4.4.3)
version: 0.79.3(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.21.0)(zod@4.4.3)
schemastery:
specifier: ^3.18.0
version: 3.18.0
@@ -953,9 +953,6 @@ importers:
'@deepseek-ai/dsh-brand':
specifier: workspace:^
version: link:../../util/brand
'@deepseek-ai/dsh-compact-basic':
specifier: workspace:^
version: link:../../compact/compact-basic
'@deepseek-ai/dsh-hooks-claude':
specifier: workspace:^
version: link:../../hooks/hooks-claude
@@ -3091,6 +3088,10 @@ packages:
cpu: [x64]
os: [win32]
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
@@ -5557,11 +5558,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
engines: {node: '>=0.8.0'}
hasBin: true
unbash@3.0.0:
resolution: {integrity: sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==}
engines: {node: '>=14'}
@@ -6169,11 +6165,11 @@ snapshots:
'@csstools/css-tokenizer@4.0.0': {}
'@earendil-works/pi-ai@0.79.3(ws@8.21.0)(zod@4.4.3)':
'@earendil-works/pi-ai@0.79.3(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.21.0)(zod@4.4.3)':
dependencies:
'@anthropic-ai/sdk': 0.91.1(zod@4.4.3)
'@aws-sdk/client-bedrock-runtime': 3.1048.0
'@google/genai': 1.52.0
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))
'@mistralai/mistralai': 2.2.1
'@smithy/node-http-handler': 4.7.3
http-proxy-agent: 7.0.2
@@ -6331,12 +6327,14 @@ snapshots:
'@exodus/bytes@1.15.1': {}
'@google/genai@1.52.0':
'@google/genai@1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))':
dependencies:
google-auth-library: 10.7.0
p-retry: 4.6.2
protobufjs: 7.6.4
ws: 8.21.0
optionalDependencies:
'@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3)
transitivePeerDependencies:
- bufferutil
- supports-color
@@ -6595,6 +6593,9 @@ snapshots:
'@oxc-resolver/binding-win32-x64-msvc@11.20.0':
optional: true
'@pkgjs/parseargs@0.11.0':
optional: true
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
@@ -7959,8 +7960,6 @@ snapshots:
neo-async: 2.6.2
source-map: 0.6.1
wordwrap: 1.0.0
optionalDependencies:
uglify-js: 3.19.3
has-flag@4.0.0: {}
@@ -8066,6 +8065,8 @@ snapshots:
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
jiti@2.7.0: {}
@@ -9306,9 +9307,6 @@ snapshots:
typescript@6.0.3: {}
uglify-js@3.19.3:
optional: true
unbash@3.0.0: {}
unconfig-core@7.5.0: