@kodax-ai/kodax 0.7.72 → 0.7.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +48 -14
  3. package/README_CN.md +33 -10
  4. package/dist/chunks/{agent-YKGU4USA.js → agent-T6PGT6AU.js} +1 -1
  5. package/dist/chunks/argument-completer-QGMWA2C3.js +2 -0
  6. package/dist/chunks/{chunk-SQODXBLX.js → chunk-64M5HOCA.js} +1 -1
  7. package/dist/chunks/{chunk-PKQOEDHJ.js → chunk-6JTWXGVU.js} +217 -223
  8. package/dist/chunks/{chunk-IR5KIK7E.js → chunk-6RI2RBTF.js} +1 -1
  9. package/dist/chunks/chunk-AGDDM5AW.js +329 -0
  10. package/dist/chunks/chunk-BUPJGG3C.js +5 -0
  11. package/dist/chunks/chunk-EAD4SF3Z.js +413 -0
  12. package/dist/chunks/chunk-F7AIEHSS.js +46 -0
  13. package/dist/chunks/{chunk-E27LHEIP.js → chunk-GAFFYJU3.js} +1 -1
  14. package/dist/chunks/chunk-HVCNAZ52.js +365 -0
  15. package/dist/chunks/{chunk-MVARIMQV.js → chunk-M7FXNPWV.js} +2 -2
  16. package/dist/chunks/{chunk-44QXPEEE.js → chunk-MBAPT2R5.js} +1 -1
  17. package/dist/chunks/{chunk-WIBLZK4G.js → chunk-MLEAQTCD.js} +2 -2
  18. package/dist/chunks/{chunk-JSDLBXME.js → chunk-OG6DRNKV.js} +63 -63
  19. package/dist/chunks/{chunk-2RI252RN.js → chunk-PFH53O4M.js} +1 -1
  20. package/dist/chunks/chunk-V4F6IYNK.js +73 -0
  21. package/dist/chunks/chunk-WQ6PWGK5.js +320 -0
  22. package/dist/chunks/chunk-XXQLPTAN.js +78 -0
  23. package/dist/chunks/compaction-config-IHJBP4GO.js +2 -0
  24. package/dist/chunks/{construction-bootstrap-ZJPXUPXQ.js → construction-bootstrap-EGRUHKLP.js} +1 -1
  25. package/dist/chunks/dist-5N3I2RTW.js +2 -0
  26. package/dist/chunks/{dist-GOUP4YVE.js → dist-EVEJAII2.js} +1 -1
  27. package/dist/chunks/host-MECITNE3.js +2 -0
  28. package/dist/chunks/run-manager-AY7RQOWM.js +2 -0
  29. package/dist/chunks/{utils-OTT5CG5J.js → utils-2GAE4XIM.js} +1 -1
  30. package/dist/index.d.ts +16 -16
  31. package/dist/index.js +5 -5
  32. package/dist/kodax_cli.js +1341 -1320
  33. package/dist/provider-capabilities.json +184 -5
  34. package/dist/runtime-worker.js +1227 -1216
  35. package/dist/sdk-a2a.d.ts +10 -10
  36. package/dist/sdk-a2a.js +1 -1
  37. package/dist/sdk-agent.d.ts +13 -13
  38. package/dist/sdk-agent.js +1 -1
  39. package/dist/sdk-coding.d.ts +96 -30
  40. package/dist/sdk-coding.js +1 -1
  41. package/dist/sdk-experimental-memory.d.ts +1 -1
  42. package/dist/sdk-experimental-memory.js +1 -1
  43. package/dist/sdk-llm.d.ts +8 -49
  44. package/dist/sdk-llm.js +1 -1
  45. package/dist/sdk-mcp.js +1 -1
  46. package/dist/sdk-media.d.ts +1 -1
  47. package/dist/sdk-media.js +1 -1
  48. package/dist/sdk-repl.d.ts +138 -16
  49. package/dist/sdk-repl.js +2 -2
  50. package/dist/sdk-runtime.d.ts +99 -17
  51. package/dist/sdk-runtime.js +1 -1
  52. package/dist/sdk-session.d.ts +6 -6
  53. package/dist/sdk-session.js +1 -1
  54. package/dist/sdk-skills.js +1 -1
  55. package/dist/semantic-worker.js +10 -10
  56. package/dist/types-chunks/{base.d-Cz_rwpOi.d.ts → base.d-ChvpaKjZ.d.ts} +1 -1
  57. package/dist/types-chunks/{bash-prefix-extractor.d-CHJO5y94.d.ts → bash-prefix-extractor.d-bApf5nGw.d.ts} +3 -3
  58. package/dist/types-chunks/{capability-learning.d-_lR0J4iR.d.ts → capability-learning.d-DPrYxRjF.d.ts} +1 -1
  59. package/dist/types-chunks/{capsule.d-DxtdE-GD.d.ts → capsule.d-CGWltwno.d.ts} +2 -2
  60. package/dist/types-chunks/{commands.d-DZxHzH5-.d.ts → commands.d-CEHGwRok.d.ts} +62 -6
  61. package/dist/types-chunks/{guardrail.d-DlpMnd-Y.d.ts → guardrail.d-CC4vAQl7.d.ts} +2 -1
  62. package/dist/types-chunks/{guardrail.d-auV61_h5.d.ts → guardrail.d-CXIPlWP3.d.ts} +10 -10
  63. package/dist/types-chunks/{public-api.d--IDNJsu1.d.ts → public-api.d-FBmX0kxo.d.ts} +4 -3
  64. package/dist/types-chunks/{run-manager.d-Bh50OdVl.d.ts → run-manager.d-DUNnJcpE.d.ts} +1 -1
  65. package/dist/types-chunks/{sdk-session-Cfw6NFu-.d.ts → sdk-session-XqacVOs8.d.ts} +3 -3
  66. package/dist/types-chunks/{resolver.d-ssgNSlrh.d.ts → side-query.d-DWTMsndP.d.ts} +68 -5
  67. package/dist/types-chunks/{types.d-DH1mvdcl.d.ts → types.d-BnPhGmar.d.ts} +3 -1
  68. package/dist/types-chunks/{types.d-Cqaw71Ax.d.ts → types.d-CSmF0t0n.d.ts} +6 -5
  69. package/dist/types-chunks/{types.d-EqQmHztg.d.ts → types.d-DKr6TCXL.d.ts} +16 -9
  70. package/dist/types-chunks/{types.d-CNZgY52F.d.ts → types.d-DgciGHoG.d.ts} +2 -2
  71. package/dist/types-chunks/{utils.d-gmn3c5U4.d.ts → utils.d-BPYX7-KN.d.ts} +94 -10
  72. package/docs/SDK_EMBEDDER_GUIDE.md +128 -21
  73. package/package.json +2 -2
  74. package/dist/chunks/argument-completer-QZETLNAB.js +0 -2
  75. package/dist/chunks/chunk-23X6REO4.js +0 -46
  76. package/dist/chunks/chunk-CLFP6UGU.js +0 -71
  77. package/dist/chunks/chunk-EDZ5KJFT.js +0 -5
  78. package/dist/chunks/chunk-GIK4SGAT.js +0 -364
  79. package/dist/chunks/chunk-GVWPHE23.js +0 -310
  80. package/dist/chunks/chunk-VDGCGOQH.js +0 -328
  81. package/dist/chunks/chunk-VVE3UM4F.js +0 -410
  82. package/dist/chunks/chunk-ZJIMT5I3.js +0 -78
  83. package/dist/chunks/compaction-config-TWCDFLX6.js +0 -2
  84. package/dist/chunks/dist-JT4ATXVM.js +0 -2
  85. package/dist/chunks/host-SVEDZUC5.js +0 -2
  86. package/dist/chunks/run-manager-RX42UNEM.js +0 -2
package/CHANGELOG.md CHANGED
@@ -6,6 +6,98 @@ All notable changes to this project will be documented in this file.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.7.73] - 2026-07-20
10
+
11
+ ### Added
12
+
13
+ - **Qwen Token Plan provider.** The new `qwen-token-plan` alias uses the
14
+ Anthropic-compatible Alibaba Cloud Token Plan endpoint and
15
+ `QWEN_TOKEN_API_KEY`. It defaults to `qwen3.8-max-preview`, exposes the
16
+ supported Qwen 3.7/3.6, GLM-5.2, and DeepSeek V4 Pro routes with one-million-
17
+ token context metadata, and declares verified reasoning, image-input, and
18
+ nominal subscription-cost capabilities without changing the existing `qwen`
19
+ provider.
20
+ - **First-run provider setup (FEATURE_271).** A bare interactive `kodax`
21
+ launch with no selected provider and no supported local credential now opens
22
+ a focused provider/model setup flow before Runtime, daemon, session, or REPL
23
+ startup. `kodax setup` reruns the same flow explicitly. It stores only
24
+ non-secret metadata, preserves unrelated config through a revision-checked
25
+ atomic write, refuses malformed existing custom providers and credential-
26
+ bearing endpoint URLs, and then names the required environment variable and
27
+ terminal restart steps.
28
+ - **Typed Auto Mode SDK contract (FEATURE_271).** The root and REPL SDK
29
+ entries now export one pure `resolveAutoModeSettings()` plus the authoritative
30
+ loader and related types; `loadConfig().autoMode` is declared, Runtime Session
31
+ settings persist `autoModeSpeculativeWindowMs` (including `0`), and side
32
+ queries return prompt-free provider/model/timing/retry/phase diagnostics.
33
+ - **Runtime-owned concrete permission grants.** Embedded and daemon SDK clients
34
+ can submit concrete `toolInput` and `executionCwd`, receive only opaque
35
+ Runtime-issued Session/persistent grant suggestions, and select a suggestion
36
+ without constructing or widening its hidden matcher. Exact command, known
37
+ file-tool path, and generic exact-call matchers remain revisioned and audited;
38
+ dynamic or dangerous shell calls never receive a persistent suggestion.
39
+
40
+ ### Fixed
41
+
42
+ - **Reasoning, Auto Mode, and confirmation regressions.** Native
43
+ disabled-thinking requests now send the provider's explicit disabled form
44
+ only for models that declare support (including verified Qwen Token Plan 3.7
45
+ routes); always-thinking variants retain their declared behavior. Sidecar
46
+ queries preserve a supported `none` effort, persisted Runtime Auto engines
47
+ are not overwritten by a fresh REPL, `/mode` synchronizes before reporting
48
+ success, and concurrent confirmation prompts are serialized instead of
49
+ replacing one another.
50
+ - **Legacy permission-grant upgrade safety.** Matcherless grants persisted by
51
+ older releases remain visible and revocable but can no longer authorize a
52
+ concrete tool call. The next invocation requires a fresh Runtime-issued
53
+ matcher, so old coarse Bash grants cannot bypass exact-command, dynamic-shell,
54
+ or absolute-deny protections.
55
+ - **Classifier credential boundary.** Auto[LLM] now redacts explicitly named
56
+ credential values inside shell-escaped JSON before sending an action to its
57
+ side provider, while retaining adjacent operational fields. Redaction is
58
+ documented as defense in depth; arbitrary Base64/hex values are not treated
59
+ as secrets without a credential signal.
60
+ - **Todo/Actor semantic progress checkpoint (FEATURE_270 follow-up).** Worker
61
+ guidance now treats Todo rows as user-visible milestones rather than Actor
62
+ instances and requires timely updates at milestone boundaries. Structured
63
+ terminal child results arm one deduplicated, warn-only reconciliation
64
+ reminder; transcript scans are append-incremental with safe compaction
65
+ fallback, and Sidecar accept-time residual reconciliation emits a diagnostic
66
+ without changing its existing bridge contract.
67
+ - **Auto LLM classifier timeout and missing-model escalation.** Runtime now
68
+ treats omitted Auto engine as the documented LLM default and still owns the
69
+ guardrail, while a missing/blank/malformed effective classifier model fails
70
+ as a typed recoverable Runtime error or a local block in the shared
71
+ `createAutoModeToolGuardrail` boundary. The final guardrail check runs before
72
+ provider lookup and cannot invoke `askUser`, record a circuit-breaker error,
73
+ or downgrade to rules. Classifier requests strip assistant prose/thinking,
74
+ cap normalized transcript/tool-result/action/prompt bytes, remove image
75
+ paths, and cap the structured response at 256 tokens. The 20-second deadline remains bounded:
76
+ a four-call `zai-coding/glm-5.2` probe completed representative Windows
77
+ permission verdicts in 1.9–2.8 seconds, while the matching production session
78
+ revealed a 1.625 MB tool result that had bypassed the existing sanitizer.
79
+ - **Auto guardrail daemon and tracing semantics.** Auto-started Runtime clients
80
+ now require `runtimeAutoModeGuardrail:3`. It retains v2's effective
81
+ timeout/window defaults, bounded classifier input, and diagnostics metadata,
82
+ and adds opaque concrete-grant semantics. Capability negotiation is monotonic
83
+ (v3 satisfies v2/v1); idle older daemons use the existing fenced upgrade path,
84
+ while busy daemons are left untouched with a recoverable error. Guardrail
85
+ spans now cover the awaited callback instead of timing only final verdict
86
+ emission.
87
+ - **Concurrent daemon startup publication race.** A cleanly exiting loser now
88
+ gives the elected owner a bounded publication grace period, preventing an
89
+ SDK starter from reporting failure during the short lock/state handoff gap.
90
+ - **Guardrail/permission execution parity.** Both Runner paths now commit each
91
+ guardrail rewrite before permission policy and execution, reject correlation-
92
+ id rewrites, propagate blocks as visible audited tool results, and preserve
93
+ embedded host policy hooks while rejecting non-transportable daemon hooks.
94
+ Calls rewritten into Bash retain serialized shell ordering.
95
+ - **Managed-run capacity and tool-dispatch accounting.** A complete system
96
+ prompt override no longer double-counts Skills, missing provider usage rebases
97
+ from the final request envelope, and authoritative provider usage remains
98
+ intact. Non-Bash tool calls keep parallel dispatch, Bash remains sequential,
99
+ and aggregate tool-result spill decisions use the complete batch budget.
100
+
9
101
  ## [0.7.72] - 2026-07-19
10
102
 
11
103
  ### Added
package/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
  <a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-KAI--FCL_1.0-orange?style=flat-square"></a>
18
18
  <a href="https://github.com/icetomoyo/KodaX/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/icetomoyo/KodaX?style=flat-square&logo=github&color=f1c40f"></a>
19
19
  <a href="https://github.com/icetomoyo/KodaX/actions"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/icetomoyo/KodaX/release.yml?style=flat-square&label=release"></a>
20
- <img alt="providers" src="https://img.shields.io/badge/LLMs-15_aliases_+_custom-2ecc71?style=flat-square">
20
+ <img alt="providers" src="https://img.shields.io/badge/LLMs-16_aliases_+_custom-2ecc71?style=flat-square">
21
21
  </p>
22
22
 
23
23
  <p align="center">
@@ -44,12 +44,18 @@ npm i -g @kodax-ai/kodax
44
44
  # Pick any one you have an API key for:
45
45
  export ZHIPU_API_KEY=... # or ANTHROPIC_API_KEY / OPENAI_API_KEY / KIMI_API_KEY /
46
46
  # MINIMAX_API_KEY / MIMO_API_KEY / ARK_API_KEY / QWEN_API_KEY /
47
+ # QWEN_TOKEN_API_KEY /
47
48
  # DEEPSEEK_API_KEY / GEMINI_API_KEY
48
49
 
49
50
  kodax
50
51
  ```
51
52
 
52
- That's it. You're in the REPL — ask anything in natural language.
53
+ That's it. You're in the REPL — ask anything in natural language. If this is a
54
+ new machine with no provider selection or supported API-key environment
55
+ variable, the bare `kodax` launch opens a metadata-only setup flow first. It
56
+ never asks for the key itself; after choosing a provider/model, set the named
57
+ environment variable, restart the terminal, and run `kodax` again. Use
58
+ `kodax setup` to rerun that flow explicitly.
53
59
 
54
60
  > **No-Node target machines:** download a Bun-compiled single binary for Windows / macOS / Linux × x64 + arm64 from the [GitHub Releases](https://github.com/icetomoyo/KodaX/releases) page. See [docs/release.md](docs/release.md) for the build pipeline.
55
61
 
@@ -141,6 +147,14 @@ npm link
141
147
 
142
148
  KodaX reads API keys from environment variables. For built-in providers, the fastest path is:
143
149
 
150
+ ```bash
151
+ # Interactive metadata-only provider/model setup (does not collect a key)
152
+ kodax setup
153
+ ```
154
+
155
+ The command tells you the exact environment-variable name to set and exits so
156
+ you can restart the terminal. You can also configure it directly:
157
+
144
158
  ```bash
145
159
  # macOS / Linux
146
160
  export ZHIPU_API_KEY=your_api_key
@@ -149,6 +163,14 @@ export ZHIPU_API_KEY=your_api_key
149
163
  $env:ZHIPU_API_KEY="your_api_key"
150
164
  ```
151
165
 
166
+ For Qwen Token Plan, select `qwen-token-plan` and use its separate credential;
167
+ `QWEN_API_KEY` does not authenticate this route:
168
+
169
+ ```bash
170
+ export QWEN_TOKEN_API_KEY=your_api_key
171
+ kodax --provider qwen-token-plan
172
+ ```
173
+
152
174
  For CLI defaults, create `~/.kodax/config.json`:
153
175
 
154
176
  ```json
@@ -386,12 +408,16 @@ context diagnostics, and daemon protocol schemas, see
386
408
  The Space/IDE shared-daemon contract is documented in
387
409
  [SDK Embedder Guide section 23](docs/SDK_EMBEDDER_GUIDE.md#23-shared-coder-daemon-for-space-and-ide-hosts-feature_269-v0769).
388
410
 
389
- **v0.7.72 Runtime correction:** Auto Mode is now owned by the Runtime session,
411
+ **v0.7.72–v0.7.73 Runtime permission contract:** Auto Mode is owned by the Runtime session,
390
412
  not by a UI hook. It reuses its LLM/rules guardrail across turns, classifies
391
413
  before the shared permission bridge, and persists an automatic fallback to
392
414
  rules. The same session settings can select a classifier model and bounded
393
- timeout. Host plan exit is exposed only when the host supplies an approval
394
- callback. See the [Runtime Auto Mode integration guide](docs/SDK_EMBEDDER_GUIDE.md#24-runtime-owned-auto-mode-and-plan-approval-bridges-v072).
415
+ timeout; `auto` defaults to LLM classification and fails with a recoverable
416
+ configuration error when no effective classifier model exists, rather than
417
+ silently falling back. Runtime permission prompts now offer opaque, exact
418
+ allow-once/session/persistent grant suggestions; persistent grants are
419
+ daemon-owned and revisioned. Host plan exit is exposed only when the host
420
+ supplies an approval callback. See the [Runtime Auto Mode integration guide](docs/SDK_EMBEDDER_GUIDE.md#24-runtime-owned-auto-mode-and-plan-approval-bridges-v072).
395
421
 
396
422
  ## Repo Intelligence
397
423
 
@@ -411,7 +437,7 @@ KodaX uses a **monorepo architecture** with npm workspaces. Source layout curren
411
437
  ```
412
438
  KodaX/
413
439
  ├── packages/ # 4 workspace packages (FEATURE_194 v0.7.43)
414
- │ ├── llm/ # @kodax-ai/llm - LLM abstraction (15 built-in provider aliases)
440
+ │ ├── llm/ # @kodax-ai/llm - LLM abstraction (16 built-in provider aliases)
415
441
  │ │ └── providers/ # Anthropic, OpenAI, DeepSeek, Kimi, MiMo, MiniMax, Zhipu, Ark, …
416
442
  │ │
417
443
  │ ├── agent/ # @kodax-ai/agent - Generic Agent framework
@@ -459,7 +485,7 @@ KodaX/
459
485
  ┌──────────────┐ ┌──────────────────────────┐ ┌──────────────┐
460
486
  │@kodax-ai/ │ │@kodax-ai/agent │ │@kodax-ai/llm │
461
487
  │coding (via │ │Runner + fan-out + │ │LLM Abstract │
462
- │above) │ │idle-yield + session- │ │(15 aliases) │
488
+ │above) │ │idle-yield + session- │ │(16 aliases) │
463
489
  │ │ │lineage + skills + mcp + │ │ │
464
490
  │ │ │tracing (FEATURE_194) │ │ │
465
491
  └──────────────┘ └──────────────────────────┘ └──────────────┘
@@ -471,7 +497,7 @@ Source-side workspace package names (`@kodax-ai/*`). npm consumers install the s
471
497
 
472
498
  | Workspace package | Purpose | Key Dependencies |
473
499
  |---------|---------|------------------|
474
- | `@kodax-ai/llm` | LLM abstraction (15 built-in provider aliases + custom registration) | @anthropic-ai/sdk, openai |
500
+ | `@kodax-ai/llm` | LLM abstraction (16 built-in provider aliases + custom registration) | @anthropic-ai/sdk, openai |
475
501
  | `@kodax-ai/agent` | Generic Agent framework — Runner, fan-out, idle-yield, media/input artifacts, session-lineage, capabilities (mcp + skills), tracing (ADR-036 v0.7.43 consolidation; subpaths: `/media`, `/session-lineage`, `/capabilities/mcp`, `/capabilities/skills`, `/tracing`) | @kodax-ai/llm, js-tiktoken, fflate, jimp, yaml |
476
502
  | `@kodax-ai/coding` | Coding Agent — 50+ tools (incl. canonical Actor collaboration tools) + role prompts + auto-continue + repo-intelligence protocol | @kodax-ai/llm, @kodax-ai/agent |
477
503
  | `@kodax-ai/repl` | Complete interactive terminal UI (Ink/React, permission modes, commands, streaming) | @kodax-ai/coding, ink, react |
@@ -487,7 +513,7 @@ KodaX has two layers that consumers should understand separately:
487
513
 
488
514
  | Source package | npm subpath | Type | What you get | Example consumer |
489
515
  |---|---|---|---|---|
490
- | `packages/llm` | `@kodax-ai/kodax/llm` | Full package | 15-alias LLM abstraction (108 exports) | Standalone LLM clients |
516
+ | `packages/llm` | `@kodax-ai/kodax/llm` | Full package | 16-alias LLM abstraction (108 exports) | Standalone LLM clients |
491
517
  | `packages/agent` | `@kodax-ai/kodax/agent` | Full package | Runner / fan-out / external-agent plane / session-lineage / capabilities / tracing (331 exports) | Custom agent frameworks |
492
518
  | `packages/agent` | `@kodax-ai/kodax/skills` | **Narrow subset** | Skills system only — `SkillRegistry` / `loadFullSkill` / `expandSkillForLLM` / ... (26 exports = pre-v0.7.43 `@kodax-ai/skills` complete API) | Skill loaders, IDE plugins |
493
519
  | `packages/agent` | `@kodax-ai/kodax/mcp` | **Narrow subset** | MCP only — `McpCapabilityProvider` / `createMcpTransport` / `searchMcpCatalog` / ... (23 exports) | MCP server hosts |
@@ -626,7 +652,7 @@ one-time provisioning).
626
652
  ## Features
627
653
 
628
654
  - **Modular Architecture** - Use as CLI, as a library, or as a Node-free single binary
629
- - **15 Built-in Provider Aliases** - Anthropic, OpenAI, DeepSeek, Kimi, Kimi Code, Qwen, Zhipu, Zhipu Coding, Zai Coding, MiniMax Coding, MiMo Coding, MiMo, Ark Coding, Gemini CLI, Codex CLI - plus user-defined OpenAI/Anthropic-compatible providers
655
+ - **16 Built-in Provider Aliases** - Anthropic, OpenAI, DeepSeek, Kimi, Kimi Code, Qwen, Qwen Token Plan, Zhipu, Zhipu Coding, Zai Coding, MiniMax Coding, MiMo Coding, MiMo, Ark Coding, Gemini CLI, Codex CLI - plus user-defined OpenAI/Anthropic-compatible providers
630
656
  - **Dynamic Workflows + SDK Process Surface** - Generate/reuse capability-routed workflows, observe live progress through `WorkflowProcessSnapshot`, and control workflow lifecycle from SDK hosts without parsing REPL output
631
657
  - **V2 Worker single-loop + Sidecar Verifier (default)** - Single-agent main loop with an out-of-band Sidecar Verifier as Stop-hook (claudecode-shape; FEATURE_184 v0.7.42, ADR-030). Verifier returns accept/revise/blocked verdict on Worker text-only termination. The pre-v0.7.43 V1 chain is retired, `emit_handoff` is deleted, accept-verdict UI silently passes through, and content-aware gating skips trivial-chat sidecar calls. Adaptive child steering uses the canonical Actor collaboration tools with idle-yield waiting; specialist routing uses `spawn_agent(agent_id=...)`.
632
658
  - **Reasoning Effort** - Effort-first control (`off/auto/low/medium/high` plus model-supported extras) across providers
@@ -728,7 +754,7 @@ For smaller surface and tree-shake-friendly imports, the SDK is also exposed via
728
754
 
729
755
  ```typescript
730
756
  import { Runner } from '@kodax-ai/kodax/agent'; // agent runtime
731
- import { getProvider } from '@kodax-ai/kodax/llm'; // LLM abstraction (15 aliases)
757
+ import { getProvider } from '@kodax-ai/kodax/llm'; // LLM abstraction (16 aliases)
732
758
  import { runKodaX } from '@kodax-ai/kodax/coding'; // coding tools + prompts
733
759
  import { createImageArtifactFromPath } from '@kodax-ai/kodax/media'; // input artifacts
734
760
  import { SkillRegistry } from '@kodax-ai/kodax/skills'; // zero-dep skill loader
@@ -896,6 +922,12 @@ KodaX provides 3 permission modes for fine-grained control:
896
922
  - Auto Mode runs guardrail classification before the permission UI; a safe
897
923
  allow verdict does not create a pending approval request. The session records
898
924
  an automatic LLM-to-rules fallback for later turns.
925
+ - Runtime-backed prompts can offer exact `allow once`, `allow this session`,
926
+ and `always allow` choices. Return the Runtime-issued opaque suggestion;
927
+ never derive or widen a permission rule from the displayed command or path.
928
+ Persistent grants are daemon-owned, revisioned, and can be listed/revoked
929
+ through `runtime.permissions` by an authorized SDK host. Dynamic shell
930
+ commands deliberately receive no persistent-grant suggestion.
899
931
 
900
932
  ### CLI Help Topics
901
933
 
@@ -1059,7 +1091,7 @@ npm install @kodax-ai/kodax
1059
1091
  ```typescript
1060
1092
  import { runKodaX } from '@kodax-ai/kodax'; // root: CLI helpers + runKodaX
1061
1093
  import { Runner, runFanOut } from '@kodax-ai/kodax/agent'; // generic Agent framework
1062
- import { getProvider } from '@kodax-ai/kodax/llm'; // 15-alias LLM abstraction
1094
+ import { getProvider } from '@kodax-ai/kodax/llm'; // 16-alias LLM abstraction
1063
1095
  import { KODAX_TOOLS } from '@kodax-ai/kodax/coding'; // tools + prompts + agent loop
1064
1096
  import { createImageArtifactFromPath } from '@kodax-ai/kodax/media'; // input artifact helpers
1065
1097
  import { runInkInteractiveMode } from '@kodax-ai/kodax/repl'; // Ink TUI entrypoint
@@ -1075,7 +1107,7 @@ import { createMemoryAgent } from '@kodax-ai/kodax/experimental-memory'; // opt-
1075
1107
 
1076
1108
  ### `@kodax-ai/kodax/llm` — LLM Abstraction
1077
1109
 
1078
- 15 built-in provider aliases (Anthropic, OpenAI, DeepSeek, Kimi, Kimi-Code, Qwen, Zhipu, Zhipu-Coding, Zai-Coding, MiniMax-Coding, MiMo, MiMo-Coding, Ark-Coding, Gemini-CLI, Codex-CLI) + custom provider registration.
1110
+ 16 built-in provider aliases (Anthropic, OpenAI, DeepSeek, Kimi, Kimi-Code, Qwen, Qwen-Token-Plan, Zhipu, Zhipu-Coding, Zai-Coding, MiniMax-Coding, MiMo, MiMo-Coding, Ark-Coding, Gemini-CLI, Codex-CLI) + custom provider registration.
1079
1111
 
1080
1112
  ```typescript
1081
1113
  import { getProvider, KodaXBaseProvider } from '@kodax-ai/kodax/llm';
@@ -1213,7 +1245,7 @@ await runInkInteractiveMode({ provider: 'zhipu-coding', effort: 'auto' });
1213
1245
 
1214
1246
  | Use Case | Subpath | Why |
1215
1247
  |----------|---------|-----|
1216
- | Only need LLM abstraction | `@kodax-ai/kodax/llm` | Minimal deps; 15 built-in aliases |
1248
+ | Only need LLM abstraction | `@kodax-ai/kodax/llm` | Minimal deps; 16 built-in aliases |
1217
1249
  | Building custom agent | `@kodax-ai/kodax/agent` | Runner + fan-out + idle-yield + session-lineage + capabilities |
1218
1250
  | Coding tasks | `@kodax-ai/kodax/coding` | Complete coding agent + tools |
1219
1251
  | Terminal app | `@kodax-ai/kodax/repl` | Full interactive experience |
@@ -1229,6 +1261,7 @@ await runInkInteractiveMode({ provider: 'zhipu-coding', effort: 'auto' });
1229
1261
  | kimi | `KIMI_API_KEY` | Native | kimi-k2.7-code (262,144-token context; `kimi-k2.7-code-highspeed` / `kimi-k2.6` / `kimi-k2.5` via `/model`) |
1230
1262
  | kimi-code | `KIMI_CODE_API_KEY` | Native | kimi-for-coding (`k3-256k` for Moderato / `k3` 1M for Allegretto+ / `kimi-for-coding-highspeed` via `/model`; both K3 choices use upstream `k3`) |
1231
1263
  | qwen | `QWEN_API_KEY` | Native | qwen3.5-plus |
1264
+ | qwen-token-plan | `QWEN_TOKEN_API_KEY` | Native | qwen3.8-max-preview (Anthropic-compat; `qwen3.7-max` / `qwen3.7-plus` / `qwen3.6-flash` / `glm-5.2` / `deepseek-v4-pro` via `/model`; all 1M context; image input on Qwen 3.8 / 3.7 Plus / 3.6 Flash) |
1232
1265
  | zhipu | `ZHIPU_API_KEY` | Native | glm-5 (`glm-5.2` 1M ctx / `glm-5.1` / `glm-5-turbo` via `/model`) |
1233
1266
  | zhipu-coding | `ZHIPU_CODING_API_KEY` | Native | glm-5.2 (1M ctx; legacy `glm-5.1` and `glm-5-turbo` remain selectable via `/model`) |
1234
1267
  | zai-coding | `ZAI_CODING_API_KEY` | Native | glm-5.2 (Zhipu Coding Plan overseas mirror via `api.z.ai`, Anthropic-compat — same model lineup as `zhipu-coding`, served from outside CN) |
@@ -1465,6 +1498,7 @@ KodaX uses an **English-first** comment style with selective Chinese brief notes
1465
1498
  ## Documentation
1466
1499
 
1467
1500
  - [README_CN.md](README_CN.md) - Chinese Documentation
1501
+ - [docs/SDK_EMBEDDER_GUIDE.md](docs/SDK_EMBEDDER_GUIDE.md) - SDK hosting, shared Runtime daemon, Auto Mode, and permission-grant contracts
1468
1502
  - [docs/release.md](docs/release.md) - Standalone binary build & release pipeline
1469
1503
  - [docs/PRD.md](docs/PRD.md) - Product Requirements
1470
1504
  - [docs/ADR.md](docs/ADR.md) - Architecture Decisions
package/README_CN.md CHANGED
@@ -17,7 +17,7 @@
17
17
  <a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-KAI--FCL_1.0-orange?style=flat-square"></a>
18
18
  <a href="https://github.com/icetomoyo/KodaX/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/icetomoyo/KodaX?style=flat-square&logo=github&color=f1c40f"></a>
19
19
  <a href="https://github.com/icetomoyo/KodaX/actions"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/icetomoyo/KodaX/release.yml?style=flat-square&label=release"></a>
20
- <img alt="providers" src="https://img.shields.io/badge/LLMs-15_aliases_+_custom-2ecc71?style=flat-square">
20
+ <img alt="providers" src="https://img.shields.io/badge/LLMs-16_aliases_+_custom-2ecc71?style=flat-square">
21
21
  </p>
22
22
 
23
23
  <p align="center">
@@ -44,12 +44,15 @@ npm i -g @kodax-ai/kodax
44
44
  # 选一个你有 API key 的 provider
45
45
  export ZHIPU_API_KEY=... # 或 KIMI_API_KEY / MINIMAX_API_KEY / MIMO_API_KEY /
46
46
  # ARK_API_KEY / DEEPSEEK_API_KEY / ANTHROPIC_API_KEY /
47
- # OPENAI_API_KEY / QWEN_API_KEY / GEMINI_API_KEY
47
+ # OPENAI_API_KEY / QWEN_API_KEY / QWEN_TOKEN_API_KEY / GEMINI_API_KEY
48
48
 
49
49
  kodax
50
50
  ```
51
51
 
52
- 就这样。进 REPL,自然语言提问。
52
+ 就这样。进 REPL,自然语言提问。如果新机器既没有选择 provider,也没有任何
53
+ 受支持的 API Key 环境变量,直接运行 `kodax` 会先打开只配置元数据的向导;它不会
54
+ 要求输入或保存 Key。选择 provider/model 后,按提示设置对应环境变量、重启终端,
55
+ 再运行 `kodax`。需要主动重新配置时可运行 `kodax setup`。
53
56
 
54
57
  > **不装 Node 的目标机器**:从 [GitHub Releases](https://github.com/icetomoyo/KodaX/releases) 拿 Bun 编译的单文件二进制(Win / macOS / Linux × x64 + arm64)。详见 [docs/release.md](docs/release.md)。
55
58
 
@@ -88,10 +91,14 @@ daemon,不会再次打开 GUI。`ELECTRON_RUN_AS_NODE` 只存在于子进程
88
91
  再使用 attach-only 模式连接。SDK 的 `homeDir` 是拥有 `.kodax` 的 CLI 风格基础目录,
89
92
  不是 `.kodax` 目录本身。
90
93
 
91
- **v0.7.72 Runtime 修正:**Auto Mode 的权限决策由 Runtime Session 持有,
94
+ **v0.7.72–v0.7.73 Runtime 权限契约:**Auto Mode 的权限决策由 Runtime Session 持有,
92
95
  不再由 UI hook 抢先决定。Runtime 会跨 turn 复用 LLM/rules guardrail,先分类、
93
96
  仅在 `escalate` 时创建共享 permission 请求,并把自动降级到 rules 的结果持久化到
94
- session。Session 也可设置 classifier model 和有界 timeout;没有宿主审批回调时,
97
+ session。Session 也可设置 classifier model 和有界 timeout;`auto` 默认使用 LLM
98
+ 分类,没有有效 classifier model 时会在调用 provider 或创建审批前返回可恢复配置错误,
99
+ 绝不静默退回 rules。Runtime 权限请求可给出由 Runtime 生成的精确作用域建议:一次允许、
100
+ 本 Session 允许,或(仅安全场景)持久允许;客户端只能回传不透明 suggestion id,不能从
101
+ 预览内容自行扩大范围。持久授权由 daemon 持有并通过 revision 管理。没有宿主审批回调时,
95
102
  不会向模型暴露 `exit_plan_mode`。完整 SDK 接入见
96
103
  [Runtime Auto Mode 指引](docs/SDK_EMBEDDER_GUIDE.md#24-runtime-owned-auto-mode-and-plan-approval-bridges-v072)。
97
104
 
@@ -174,7 +181,14 @@ kodax
174
181
 
175
182
  ### 2. 配置模型提供商
176
183
 
177
- 最简单的方式是先设置 API Key:
184
+ 可以先运行不会收集 Key 的交互配置:
185
+
186
+ ```bash
187
+ kodax setup
188
+ ```
189
+
190
+ 命令会保存 provider/model,告诉你准确的环境变量名,然后退出以便重启终端。
191
+ 也可以直接设置 API Key:
178
192
 
179
193
  ```bash
180
194
  # macOS / Linux
@@ -184,6 +198,14 @@ export ZHIPU_API_KEY=your_api_key
184
198
  $env:ZHIPU_API_KEY="your_api_key"
185
199
  ```
186
200
 
201
+ Qwen Token Plan 需要选择 `qwen-token-plan` 并使用单独的凭据;`QWEN_API_KEY`
202
+ 不能用于该路由:
203
+
204
+ ```bash
205
+ export QWEN_TOKEN_API_KEY=your_api_key
206
+ kodax --provider qwen-token-plan
207
+ ```
208
+
187
209
  然后在 `~/.kodax/config.json` 里写一个最小配置:
188
210
 
189
211
  ```json
@@ -235,7 +257,7 @@ const result = await runKodaX(
235
257
 
236
258
  ```typescript
237
259
  import { Runner } from '@kodax-ai/kodax/agent'; // Agent runtime
238
- import { getProvider } from '@kodax-ai/kodax/llm'; // LLM 抽象(15 个内置 alias)
260
+ import { getProvider } from '@kodax-ai/kodax/llm'; // LLM 抽象(16 个内置 alias)
239
261
  import { runKodaX } from '@kodax-ai/kodax/coding'; // Coding tools + prompts
240
262
  import { createImageArtifactFromPath } from '@kodax-ai/kodax/media'; // 输入 artifact helpers
241
263
  import { SkillRegistry } from '@kodax-ai/kodax/skills'; // 零依赖 skill loader
@@ -472,6 +494,7 @@ dist/binary/linux-x64/
472
494
  | kimi | `KIMI_API_KEY` | Native | kimi-k2.7-code(262,144 token;可 `/model` 切换 `kimi-k2.7-code-highspeed` / `kimi-k2.6` / `kimi-k2.5`) |
473
495
  | kimi-code | `KIMI_CODE_API_KEY` | Native | kimi-for-coding(可 `/model` 切换 `k3-256k`〔Moderato,256K〕/ `k3`〔Allegretto+,1M〕/ `kimi-for-coding-highspeed`;两个 K3 选项均请求上游 `k3`) |
474
496
  | qwen | `QWEN_API_KEY` | Native | qwen3.5-plus |
497
+ | qwen-token-plan | `QWEN_TOKEN_API_KEY` | Native | qwen3.8-max-preview(Anthropic 协议;可 `/model` 切换 `qwen3.7-max` / `qwen3.7-plus` / `qwen3.6-flash` / `glm-5.2` / `deepseek-v4-pro`;均为 1M ctx;Qwen 3.8 / 3.7 Plus / 3.6 Flash 支持图片理解) |
475
498
  | zhipu | `ZHIPU_API_KEY` | Native | glm-5(可 `/model` 切换 `glm-5.2` 1M ctx / `glm-5.1` / `glm-5-turbo`) |
476
499
  | zhipu-coding | `ZHIPU_CODING_API_KEY` | Native | glm-5.2(1M ctx;仍可通过 `/model` 显式选择兼容模型 `glm-5.1` / `glm-5-turbo`) |
477
500
  | zai-coding | `ZAI_CODING_API_KEY` | Native | glm-5.2(GLM Coding Plan 海外站,通过 `api.z.ai` 接入,Anthropic 协议 — 模型清单和 `zhipu-coding` 完全一致) |
@@ -568,7 +591,7 @@ KodaX 是基于 npm workspaces 的 TypeScript monorepo,**源码层 4 个 works
568
591
 
569
592
  | Workspace 包 | 作用 | 主要依赖 |
570
593
  |----|------|---------|
571
- | `@kodax-ai/llm` | LLM 抽象层(15 个内置 provider alias + 自定义 provider 注册),可独立使用 | `@anthropic-ai/sdk`, `openai` |
594
+ | `@kodax-ai/llm` | LLM 抽象层(16 个内置 provider alias + 自定义 provider 注册),可独立使用 | `@anthropic-ai/sdk`, `openai` |
572
595
  | `@kodax-ai/agent` | 通用 Agent 框架 —— Runner / runFanOut / runWithIdleYield / AgentActorController / AgentTurnScheduler + media/input artifacts + 会话管理 + tokenization + 可插拔 compaction + **inline 后**:session-lineage 子树 + capabilities (mcp + skills + builtin) + tracing(subpaths: `/media`、`/session-lineage`、`/capabilities/mcp`、`/capabilities/skills`、`/tracing`) | `@kodax-ai/llm`, `js-tiktoken`, `fflate`, `jimp`, `yaml` |
573
596
  | `@kodax-ai/coding` | Coding Agent:50+ 工具(含 canonical Actor 协作工具)、role prompts、agent loop、auto-continue + repo-intelligence protocol(v0.7.43 inline) | `@kodax-ai/llm`, `@kodax-ai/agent` |
574
597
  | `@kodax-ai/repl` | 完整交互式终端 UI(Ink / React、权限模式、命令系统、流式渲染) | `@kodax-ai/coding`, `ink`, `react` |
@@ -709,7 +732,7 @@ REPL 显示、唤醒或消费。
709
732
  ```
710
733
  KodaX/ # 4 workspace packages(FEATURE_194 v0.7.43)
711
734
  ├── packages/
712
- │ ├── llm/ # @kodax-ai/llm —— 15 个内置 provider alias
735
+ │ ├── llm/ # @kodax-ai/llm —— 16 个内置 provider alias
713
736
  │ ├── agent/ # @kodax-ai/agent —— Runner / fan-out / idle-yield + 子树:
714
737
  │ │ ├── session-lineage/ # 分支 session tree (v0.7.43 inline)
715
738
  │ │ ├── capabilities/
@@ -817,7 +840,7 @@ KodaX 现在会把 Repo Intelligence 的本地缓存分成内置引擎 profile
817
840
  ## 文档
818
841
 
819
842
  - [README.md](README.md) - 英文版 README
820
- - [docs/SDK_EMBEDDER_GUIDE.md](docs/SDK_EMBEDDER_GUIDE.md) - SDK 宿主集成、shared Runtimev0.7.72 Auto Mode 契约
843
+ - [docs/SDK_EMBEDDER_GUIDE.md](docs/SDK_EMBEDDER_GUIDE.md) - SDK 宿主集成、shared Runtimev0.7.73 Auto Mode 与精确授权契约
821
844
  - [docs/release.md](docs/release.md) - 单文件二进制构建与发布流程
822
845
  - [docs/PRD.md](docs/PRD.md) - 产品需求
823
846
  - [docs/ADR.md](docs/ADR.md) - 架构决策
@@ -1,2 +1,2 @@
1
1
  // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{Ga as i,Ma as j,da as d,ea as e,fa as f,j as c,ua as g,va as h}from"./chunk-VDGCGOQH.js";import"./chunk-SQODXBLX.js";import"./chunk-44QXPEEE.js";import"./chunk-GIK4SGAT.js";import"./chunk-ZJIMT5I3.js";import{sb as a,tb as b}from"./chunk-JSDLBXME.js";import"./chunk-E27LHEIP.js";import"./chunk-EDZ5KJFT.js";import"./chunk-23X6REO4.js";import"./chunk-ONUPGMER.js";export{e as bucketProviderPayloadSize,g as buildAutoRepoIntelligenceContext,f as checkPromiseSignal,b as cleanupIncompleteToolCalls,h as describeTransientProviderRetry,c as emitResilienceDebug,d as estimateProviderPayloadBytes,j as runKodaX,i as saveSessionSnapshot,a as validateAndFixToolHistory};
2
+ import{Ga as i,Ma as j,da as d,ea as e,fa as f,j as c,ua as g,va as h}from"./chunk-AGDDM5AW.js";import"./chunk-64M5HOCA.js";import"./chunk-MBAPT2R5.js";import"./chunk-HVCNAZ52.js";import"./chunk-XXQLPTAN.js";import{sb as a,tb as b}from"./chunk-OG6DRNKV.js";import"./chunk-GAFFYJU3.js";import"./chunk-BUPJGG3C.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{e as bucketProviderPayloadSize,g as buildAutoRepoIntelligenceContext,f as checkPromiseSignal,b as cleanupIncompleteToolCalls,h as describeTransientProviderRetry,c as emitResilienceDebug,d as estimateProviderPayloadBytes,j as runKodaX,i as saveSessionSnapshot,a as validateAndFixToolHistory};
@@ -0,0 +1,2 @@
1
+ // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
+ import{Ea as a,Fa as b}from"./chunk-6JTWXGVU.js";import"./chunk-MLEAQTCD.js";import"./chunk-PFH53O4M.js";import"./chunk-EAD4SF3Z.js";import"./chunk-6RI2RBTF.js";import"./chunk-M7FXNPWV.js";import"./chunk-AGDDM5AW.js";import"./chunk-64M5HOCA.js";import"./chunk-MBAPT2R5.js";import"./chunk-HVCNAZ52.js";import"./chunk-XXQLPTAN.js";import"./chunk-OG6DRNKV.js";import"./chunk-GAFFYJU3.js";import"./chunk-BUPJGG3C.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{a as ArgumentCompleter,b as createArgumentCompleter};
@@ -1,5 +1,5 @@
1
1
  // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{m as f}from"./chunk-E27LHEIP.js";import{a as h}from"./chunk-ONUPGMER.js";import{createHash as R}from"node:crypto";function O(i){return new y(i)}h(O,"createMemoryAgent");var y=class{static{h(this,"DefaultMemoryAgent")}options;constructor(e){this.options=e}async startSession(e){let t=this.options.initialMemoryPack??await this.options.controlPlane.buildMemoryPack({task:e.objective,identity:e.identity,maxCandidates:12,maxHints:5});return new g(e,t.memoryRevision,t.candidates,this.options)}},g=class{static{h(this,"DefaultMemorySession")}input;memoryRevision;candidates;options;observations=new Map;consumedReminderKeys=new Set;lastSequence=0;closed=!1;completion;prefetchGeneration=0;prefetch;readyPrefetch;queryByEpoch=new Map;injectedReceiptIds=[];constructor(e,t,n,c){this.input=e,this.memoryRevision=t,this.candidates=n,this.options=c}observe(e){if(this.assertOpen(),v(e.summary))return;let t=K(e,this.options.sourcePolicy),n=this.observations.get(e.id);if(n!==void 0){if(n.sequence===t.sequence&&w(n)===w(t))return;throw new Error(`conflicting duplicate memory observation: ${e.id}`)}if(!Number.isSafeInteger(e.sequence)||e.sequence<=this.lastSequence)throw new Error(`memory observation sequence must be strictly monotonic after ${this.lastSequence}`);if(e.summary.trim().length===0)throw new Error("memory observation summary must not be empty");this.observations.set(e.id,t),this.lastSequence=e.sequence}recall(e){this.assertOpen();let t=[...this.observations.values()].filter(d=>d.sequence<=e.throughSequence).filter(d=>I(d,e)).sort((d,l)=>l.sequence-d.sequence).slice(0,3),n=this.candidates.filter(d=>P(d,e)).slice(0,Math.max(0,3-t.length)),c=this.prefetchKey(e),s=this.consumeReadyPrefetch(c).filter(d=>!n.some(l=>l.ref.id===d.ref.id)).slice(0,Math.max(0,3-t.length-n.length)),a=m([...t.flatMap(d=>d.evidence.map(l=>l.ref)),...n.map(d=>d.ref.id),...s.map(d=>d.ref.id)]),r=k([...t.length>0||n.length>0?["exact"]:[],...s.length>0?["semantic_prefetch"]:[]]);if(t.length===0&&n.length===0&&s.length===0){this.startPrefetch(c,e),this.emitDecisionReceipt(e,[],[],r);return}let o=[...t.map(d=>d.summary.trim()),...n.map(d=>d.bodySnippet??d.hook),...s.map(d=>d.bodySnippet??d.hook)].join(`
2
+ import{m as f}from"./chunk-GAFFYJU3.js";import{a as h}from"./chunk-ONUPGMER.js";import{createHash as R}from"node:crypto";function O(i){return new y(i)}h(O,"createMemoryAgent");var y=class{static{h(this,"DefaultMemoryAgent")}options;constructor(e){this.options=e}async startSession(e){let t=this.options.initialMemoryPack??await this.options.controlPlane.buildMemoryPack({task:e.objective,identity:e.identity,maxCandidates:12,maxHints:5});return new g(e,t.memoryRevision,t.candidates,this.options)}},g=class{static{h(this,"DefaultMemorySession")}input;memoryRevision;candidates;options;observations=new Map;consumedReminderKeys=new Set;lastSequence=0;closed=!1;completion;prefetchGeneration=0;prefetch;readyPrefetch;queryByEpoch=new Map;injectedReceiptIds=[];constructor(e,t,n,c){this.input=e,this.memoryRevision=t,this.candidates=n,this.options=c}observe(e){if(this.assertOpen(),v(e.summary))return;let t=K(e,this.options.sourcePolicy),n=this.observations.get(e.id);if(n!==void 0){if(n.sequence===t.sequence&&w(n)===w(t))return;throw new Error(`conflicting duplicate memory observation: ${e.id}`)}if(!Number.isSafeInteger(e.sequence)||e.sequence<=this.lastSequence)throw new Error(`memory observation sequence must be strictly monotonic after ${this.lastSequence}`);if(e.summary.trim().length===0)throw new Error("memory observation summary must not be empty");this.observations.set(e.id,t),this.lastSequence=e.sequence}recall(e){this.assertOpen();let t=[...this.observations.values()].filter(d=>d.sequence<=e.throughSequence).filter(d=>I(d,e)).sort((d,l)=>l.sequence-d.sequence).slice(0,3),n=this.candidates.filter(d=>P(d,e)).slice(0,Math.max(0,3-t.length)),c=this.prefetchKey(e),s=this.consumeReadyPrefetch(c).filter(d=>!n.some(l=>l.ref.id===d.ref.id)).slice(0,Math.max(0,3-t.length-n.length)),a=m([...t.flatMap(d=>d.evidence.map(l=>l.ref)),...n.map(d=>d.ref.id),...s.map(d=>d.ref.id)]),r=k([...t.length>0||n.length>0?["exact"]:[],...s.length>0?["semantic_prefetch"]:[]]);if(t.length===0&&n.length===0&&s.length===0){this.startPrefetch(c,e),this.emitDecisionReceipt(e,[],[],r);return}let o=[...t.map(d=>d.summary.trim()),...n.map(d=>d.bodySnippet??d.hook),...s.map(d=>d.bodySnippet??d.hook)].join(`
3
3
  `),b=u(`${a.join("\0")}\0${e.actionSignature??e.decisionIntent}`);if(this.consumedReminderKeys.has(b)){this.emitDecisionReceipt(e,a,[],r);return}return this.consumedReminderKeys.add(b),this.emitDecisionReceipt(e,a,a,r),{content:o,evidenceRefs:a}}query(e){this.assertOpen();let t=p(e.decisionRevision,e.throughSequence),n=E(e.need),c=u([t,this.memoryRevision,n??"",e.actionSignature??"",f].join("\0")),s=this.queryByEpoch.get(t);if(s!==void 0)return s.key===c?s.result:Promise.resolve(void 0);let a=n===void 0?Promise.resolve(void 0):this.queryOnce(e,n);return this.queryByEpoch.set(t,{key:c,result:a}),n===void 0&&this.emitDecisionReceipt(e,[],[],["deliberate_query"]),a}rewind(e){if(this.assertOpen(),!Number.isSafeInteger(e.throughSequence)||e.throughSequence<0)throw new Error("rewind sequence must be a non-negative safe integer");for(let[t,n]of this.observations)n.sequence>e.throughSequence&&this.observations.delete(t);for(this.lastSequence=e.throughSequence,this.consumedReminderKeys.clear(),this.queryByEpoch.clear();this.injectedReceiptIds.length>0;)this.injectedReceiptIds.pop();this.cancelPrefetch("rewind")}complete(e){return this.assertOpen(),this.completion!==void 0?this.completion:(this.completion=this.completeOnce(e),this.completion)}async close(e={}){this.cancelPrefetch("close"),e.drain!==!1&&this.completion!==void 0&&await this.completion,this.closed=!0}async completeOnce(e){if(e.status==="cancelled"||v(e.summary))return;let t=j(this.input,[...this.observations.values()],{...e,status:e.status,evidence:e.evidence.map(n=>q(n,this.options.sourcePolicy))},this.options.now?.()??new Date().toISOString(),this.injectedReceiptIds);await this.options.persistOutcomeDigest?.(t),await this.reviewWithTimeout(t)}async reviewWithTimeout(e){let t=this.options.reviewEpisode;if(t===void 0)return;let n=new AbortController,c=Math.max(1,this.options.reviewTimeoutMs??3e4),s,a=await Promise.race([t(e,n.signal).then(()=>!1),new Promise(r=>{s=setTimeout(()=>{n.abort(),r(!0)},c)})]);s!==void 0&&clearTimeout(s),a&&this.options.onTrace?.({type:"review.timed_out",key:e.reviewKey,detail:`${c}ms`})}assertOpen(){if(this.closed)throw new Error("memory session is closed")}prefetchKey(e){return u([e.decisionRevision,e.decisionIntent,e.actionSignature??"",String(e.throughSequence),this.memoryRevision,this.candidates.map(t=>t.ref.id).join(",")].join("\0"))}async queryOnce(e,t){try{let n=await this.options.controlPlane.buildMemoryPack({task:this.input.objective,identity:this.input.identity,decisionIntent:t,...e.actionSignature!==void 0?{actionSignature:e.actionSignature}:{},maxCandidates:3,maxHints:3,includeSnippets:!0,purpose:"deliberate_query"}),c=n.promptHints.filter(M).filter(o=>o.bodySnippet!==void 0&&o.bodySnippet.trim().length>0).slice(0,3),s=c.map(o=>o.ref.id),a=x(c.map(o=>o.bodySnippet??"")),r=a.length===0?[]:s;return this.emitDecisionReceipt(e,s,r,["deliberate_query"],n.candidates.map(o=>o.ref.id)),a.length===0?void 0:{content:a,evidenceRefs:s}}catch(n){this.emitDecisionReceipt(e,[],[],["deliberate_query"]),this.options.onTrace?.({type:"query.failed",key:p(e.decisionRevision,e.throughSequence),detail:n instanceof Error?n.message:String(n)});return}}emitDecisionReceipt(e,t,n,c,s=this.candidates.map(a=>a.ref.id)){let a=p(e.decisionRevision,e.throughSequence),r=u(s.join("\0")),o={id:`memory-decision:${u([a,f,r,t.join(","),n.join(","),c.join(",")].join("\0")).slice(0,24)}`,decisionEpoch:a,decisionRevision:e.decisionRevision,policyVersion:f,candidateSetFingerprint:r,candidateRefs:[...s],selectedRefs:[...t],injectedRefs:[...n],selectionModes:[...c],...e.actionSignature!==void 0?{actionSignature:e.actionSignature}:{},throughSequence:e.throughSequence};n.length>0&&!this.injectedReceiptIds.includes(o.id)&&this.injectedReceiptIds.push(o.id),this.options.onTrace?.({type:"memory.decision",receipt:o})}consumeReadyPrefetch(e){if(this.readyPrefetch?.key!==e)return[];let t=new Set(this.readyPrefetch.refIds);return this.readyPrefetch=void 0,this.candidates.filter(n=>t.has(n.ref.id))}startPrefetch(e,t){let n=this.options.recallRunner;if(n===void 0||this.candidates.length===0||this.prefetch?.key===e)return;this.cancelPrefetch("superseded");let c=new AbortController,s=++this.prefetchGeneration;this.prefetch={key:e,controller:c};let a=new Set(this.candidates.map(r=>r.ref.id));n({objective:t.objective,decisionContext:t.decisionContext,decisionIntent:t.decisionIntent,candidates:this.candidates.map(r=>({refId:r.ref.id,claim:r.bodySnippet??r.hook,...r.ref.claimKind!==void 0?{claimKind:r.ref.claimKind}:{}})),signal:c.signal}).then(r=>{if(c.signal.aborted||s!==this.prefetchGeneration||this.prefetch?.key!==e){this.options.onTrace?.({type:"recall.prefetch.discarded",key:e});return}this.readyPrefetch={key:e,refIds:m(r.selectedRefIds.filter(o=>a.has(o)))},this.prefetch=void 0,this.options.onTrace?.({type:"recall.prefetch.completed",key:e})}).catch(r=>{c.signal.aborted||(s===this.prefetchGeneration&&(this.prefetch=void 0),this.options.onTrace?.({type:"recall.prefetch.failed",key:e,detail:r instanceof Error?r.message:String(r)}))})}cancelPrefetch(e){if(this.prefetch===void 0)return;let t=this.prefetch.key;this.prefetch.controller.abort(),this.prefetch=void 0,this.prefetchGeneration+=1,this.options.onTrace?.({type:"recall.prefetch.discarded",key:t,detail:e})}};function I(i,e){return i.actionSignature!==void 0&&e.actionSignature!==void 0?i.actionSignature===e.actionSignature:i.claimKey!==void 0&&i.claimKey===e.decisionIntent}h(I,"exactObservationMatch");function P(i,e){return i.ref.actionSignature!==void 0&&e.actionSignature!==void 0?i.ref.actionSignature===e.actionSignature:i.ref.claimKey!==void 0&&i.ref.claimKey===e.decisionIntent}h(P,"exactCandidateMatch");function j(i,e,t,n,c){let s=[...e].reverse().find(o=>o.kind==="outcome"),a=e.at(-1)?.sequence??0,r=u([i.identity.sessionId,String(a),t.status,t.summary].join("\0"));return{id:`memory-outcome:${r.slice(0,24)}`,reviewKey:r,sessionId:i.identity.sessionId,branchId:i.identity.sessionId,sequence:a,objective:i.objective,...s?.actionSignature!==void 0?{actionSignature:s.actionSignature}:{},approach:s?.summary??"episode completion",outcome:t.status,summary:t.summary.trim(),evidenceRefs:m(t.evidence.map(o=>o.ref)),evidence:t.evidence.map(o=>({ref:o.ref,grade:o.requestedGrade,source:o.source,observedAt:o.observedAt})),...c.length>0?{memoryInfluence:m(c).map(o=>({decisionReceiptRef:o,grade:"exposed"}))}:{},visibility:s?.visibility??"prompt_safe",createdAt:n}}h(j,"buildOutcomeDigest");function E(i){let e=i.replace(/\s+/g," ").trim();if(!(e.length===0||S(e)>512||v(e))&&!/^(?:list|show|dump|enumerate)\s+(?:all|every)\s+(?:the\s+)?memor(?:y|ies)\b/i.test(e)&&!/\b(?:all|every)\s+(?:project|workspace|tenant|user|agent)(?:s|'s)?\b/i.test(e))return e}h(E,"normalizeQueryNeed");function S(i){let e=0,t=0;for(let n of i)n.codePointAt(0)<=127?e+=1:t+=1;return Math.ceil(e/4)+t}h(S,"estimateMemoryTokens");function M(i){return i.ref.visibility==="prompt_safe"&&i.ref.authority!=="proposal_only"&&(i.ref.lifecycle==="active"||i.ref.lifecycle==="trusted"||i.ref.lifecycle==="readonly")}h(M,"isGovernedQueryHint");function x(i){let e=i.map(n=>n.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g,"").replace(/<\/?[^>]+>/g,"").replace(/[<>]/g,"").replace(/\s+/g," ").trim()).filter(n=>n.length>0),t=e.join(`
4
4
  `);for(;S(t)>512&&e.length>1;)e.pop(),t=e.join(`
5
5
  `);return S(t)<=512?t:""}h(x,"boundedQueryContent");function p(i,e){return u(`${i}\0${e}`).slice(0,24)}h(p,"decisionEpoch");function k(i){return[...new Set(i)]}h(k,"uniqueModes");function K(i,e){return Object.freeze({...i,evidence:Object.freeze(i.evidence.map(t=>Object.freeze(q(t,e)))),...i.metadata!==void 0?{metadata:Object.freeze({...i.metadata})}:{}})}h(K,"freezeObservation");function q(i,e){let t=e?.(i)??"inferred";return{...i,requestedGrade:_(i.requestedGrade,t)}}h(q,"applySourcePolicy");function _(i,e){let t=["inferred","observed","corroborated","verified","authoritative"];return t[Math.min(t.indexOf(i),t.indexOf(e))]??"inferred"}h(_,"lowerEvidenceGrade");function w(i){return JSON.stringify(i)}h(w,"stableObservation");function m(i){return[...new Set(i)]}h(m,"unique");function u(i){return R("sha256").update(i).digest("hex")}h(u,"digest");function v(i){return/(?:-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|authorization:\s*bearer\s+\S+|(?:api[_-]?key|password|secret|token)\s*[:=]\s*\S+)/i.test(i)}h(v,"isRestrictedMemoryContent");export{O as a};