odai-dsh-agent 0.2.56 → 0.3.1

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 (78) hide show
  1. package/README.md +11 -9
  2. package/client/client.js +83 -6
  3. package/package.json +1 -1
  4. package/preset/odai/package.json +2 -1
  5. package/preset/odai/runtime/context-activation.mjs +1 -1
  6. package/preset/odai/runtime/context-activation.mjs.map +1 -1
  7. package/preset/odai/runtime/control-center-runtime.d.mts +3 -0
  8. package/preset/odai/runtime/control-center-runtime.d.mts.map +1 -1
  9. package/preset/odai/runtime/control-center-runtime.mjs +8 -3
  10. package/preset/odai/runtime/control-center-runtime.mjs.map +1 -1
  11. package/preset/odai/runtime/index.d.mts.map +1 -1
  12. package/preset/odai/runtime/index.mjs +52 -2
  13. package/preset/odai/runtime/index.mjs.map +1 -1
  14. package/preset/odai/runtime/lead-mode.d.mts +23 -0
  15. package/preset/odai/runtime/lead-mode.d.mts.map +1 -0
  16. package/preset/odai/runtime/lead-mode.mjs +17 -0
  17. package/preset/odai/runtime/lead-mode.mjs.map +1 -0
  18. package/preset/odai/runtime/lifecycle-runtime.d.mts.map +1 -1
  19. package/preset/odai/runtime/lifecycle-runtime.mjs +199 -13
  20. package/preset/odai/runtime/lifecycle-runtime.mjs.map +1 -1
  21. package/preset/odai/runtime/responsibility-gap.d.mts +4 -1
  22. package/preset/odai/runtime/responsibility-gap.d.mts.map +1 -1
  23. package/preset/odai/runtime/responsibility-gap.mjs +1 -0
  24. package/preset/odai/runtime/responsibility-gap.mjs.map +1 -1
  25. package/preset/odai/runtime/role-overlays.d.mts +1 -1
  26. package/preset/odai/runtime/role-overlays.d.mts.map +1 -1
  27. package/preset/odai/runtime/role-overlays.mjs +4 -1
  28. package/preset/odai/runtime/role-overlays.mjs.map +1 -1
  29. package/preset/odai/runtime/route-session.d.mts +20 -0
  30. package/preset/odai/runtime/route-session.d.mts.map +1 -0
  31. package/preset/odai/runtime/route-session.mjs +44 -0
  32. package/preset/odai/runtime/route-session.mjs.map +1 -0
  33. package/preset/odai/runtime/router.d.mts +2 -1
  34. package/preset/odai/runtime/router.d.mts.map +1 -1
  35. package/preset/odai/runtime/router.mjs +52 -1
  36. package/preset/odai/runtime/router.mjs.map +1 -1
  37. package/preset/odai/runtime/routing-config.d.mts +5 -2
  38. package/preset/odai/runtime/routing-config.d.mts.map +1 -1
  39. package/preset/odai/runtime/routing-config.mjs +25 -14
  40. package/preset/odai/runtime/routing-config.mjs.map +1 -1
  41. package/preset/odai/runtime/runtime-config.d.mts +1 -1
  42. package/preset/odai/runtime/runtime-config.d.mts.map +1 -1
  43. package/preset/odai/runtime/runtime-support.d.mts +6 -1
  44. package/preset/odai/runtime/runtime-support.d.mts.map +1 -1
  45. package/preset/odai/runtime/runtime-support.mjs +15 -7
  46. package/preset/odai/runtime/runtime-support.mjs.map +1 -1
  47. package/preset/odai/runtime/runtime-types.d.mts +2 -0
  48. package/preset/odai/runtime/runtime-types.d.mts.map +1 -1
  49. package/preset/odai/runtime/runtime-types.mjs.map +1 -1
  50. package/preset/odai/runtime/session-controls.d.mts +33 -0
  51. package/preset/odai/runtime/session-controls.d.mts.map +1 -0
  52. package/preset/odai/runtime/session-controls.mjs +64 -0
  53. package/preset/odai/runtime/session-controls.mjs.map +1 -0
  54. package/preset/odai/runtime/session-evidence.d.mts.map +1 -1
  55. package/preset/odai/runtime/session-evidence.mjs +11 -4
  56. package/preset/odai/runtime/session-evidence.mjs.map +1 -1
  57. package/preset/odai/runtime/skill-bundle.d.mts +1 -1
  58. package/preset/odai/runtime/skill-bundle.d.mts.map +1 -1
  59. package/preset/odai/runtime/tool-runtime.d.mts.map +1 -1
  60. package/preset/odai/runtime/tool-runtime.mjs +28 -0
  61. package/preset/odai/runtime/tool-runtime.mjs.map +1 -1
  62. package/preset/odai/skills/odai-orchestration/SKILL.md +1 -1
  63. package/preset/odai/skills/odai-orchestration/assets/routing-roles/controller.md +1 -1
  64. package/preset/odai/skills/odai-orchestration/assets/routing-roles/writer.md +9 -0
  65. package/preset/odai/skills/odai-orchestration/manifest.json +10 -4
  66. package/preset/odai/skills/odai-orchestration/references/install.md +66 -4
  67. package/preset/odai/skills/odai-orchestration/references/orchestration.md +2 -1
  68. package/preset/odai/skills/odai-orchestration/scripts/build-routing.mjs +78 -24
  69. package/preset/odai/skills/odai-orchestration/scripts/compose-contracts.d.mts +1 -1
  70. package/preset/odai/skills/odai-orchestration/scripts/compose-contracts.mjs +6 -5
  71. package/preset/odai/skills/odai-orchestration/scripts/install-routing.mjs +66 -15
  72. package/preset/odai/skills/odai-orchestration/scripts/local-cli.d.mts +8 -0
  73. package/preset/odai/skills/odai-orchestration/scripts/local-cli.mjs +25 -9
  74. package/preset/odai/skills/odai-orchestration/scripts/recognize-routing.d.mts +6 -0
  75. package/preset/odai/skills/odai-orchestration/scripts/recognize-routing.mjs +93 -0
  76. package/preset/odai/skills/odai-orchestration/scripts/route-hook.mjs +243 -0
  77. package/preset/odai/skills/odai-orchestration/scripts/run-role.mjs +71 -16
  78. package/preset/odai/skills/odai-orchestration/scripts/verify-routing.mjs +2 -2
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # odai dsh agent
2
2
 
3
+ Optional writer (写作) handles drafting, rewriting, translation, and localization once direction is settled. Creative owns direction, ideation, and taste review; without a writer mapping, creative continues to handle writing as before. Writer is read-only and child-only on API and local CLI routes, returning drafts or replacement text for the controller to verify and apply.
4
+
3
5
  `odai-dsh-agent` installs a selectable, session-scoped Odai Agent preset for DeepSeek Harness (`dsh`). It is independent from the profile-wide `odai-dsh-plugin`: the preset does not activate global governance.
4
6
 
5
7
  DSH `0.1.7` registers agent presets only from profile bundle declarations; it no longer scans `$DSH_HOME/.agent-presets`. The package is therefore a DSH bundle. Installing it into a profile (default `web`) through DSH's plugin manager applies two patches:
@@ -15,7 +17,7 @@ odai-dsh-agent/
15
17
 
16
18
  The preset id stays `odai`, so sessions saved with it keep resolving after an upgrade. In DSH's Plugins page the whole bundle and its Control Center row can be switched on and off; the preset declaration and the rows inside the preset are read-only there, because DSH does not let its plugin manager edit a preset's composition.
17
19
 
18
- Odai owns its composition and capability set, with a scoped runtime in default `auto` mode. The `0.2.56` candidate uses DSH `0.2.1-rc.2` as its minimum supported baseline and admits later versions, including prereleases. Its npm peer stays `*` to avoid a package-manager prerelease allow-list. The release matrix targets `0.2.1-rc.2`; later versions still need compatible bundle and runtime services and are not automatically certified. Working-directory context comes from the host service rather than the retired `{{cwd}}` prompt variable. Standard is an upstream reference, not a required composition; release checks load Odai against the real host and verify scoped tool and prompt behavior.
20
+ Odai owns its composition and capability set, with a scoped runtime in default `auto` mode. The `0.3.1` candidate uses DSH `0.2.1-rc.2` as its minimum supported baseline and admits later versions, including prereleases. Its npm peer stays `*` to avoid a package-manager prerelease allow-list. The release matrix targets `0.2.1-rc.2`; later versions still need compatible bundle and runtime services and are not automatically certified. Working-directory context comes from the host service rather than the retired `{{cwd}}` prompt variable. Standard is an upstream reference, not a required composition; release checks load Odai against the real host and verify scoped tool and prompt behavior.
19
21
 
20
22
  Host-owned persistence, sandbox, approval, registries, and base controller selection remain in the selected DSH profile. Ordinary requests stay on that controller. Responsibility words are optional signals rather than commands: evidence-grounded task-state gaps route at any step, the gap tool records rather than claims a route start, terminal decisions consume the proposal, an incomplete reviewer proposal waits for changed native evidence, and an identical planner/controller model remains inline without another model call. After planner handback, the controller resumes implementation only when the current user task authorizes it; plan-only, new-task, expanded-scope, and unknown authorization remain non-implementing. Reviewer children require a current hash-addressed schema 3 evidence packet whose diff is newer than the last write and whose latest successful test or read-only check follows the last write; viewing a diff does not itself invalidate an earlier successful check. The packet binds to the authenticated direct-user task when available, excludes all prior-task session events, records its boundary in route evidence, and fails closed if an explicit task binding cannot be resolved uniquely. An incomplete packet keeps the current controller route, reports why native evidence was excluded, suppresses unchanged repeat notices, and reassesses the pending proposal after decisive evidence changes without claiming independent acceptance or terminating the authorized task. Every API route is resolved before provider I/O; deterministic invalid persisted mappings are backed up and exact-match removed, while recoverable provider failures preserve them. Frontend route failure becomes an explicit local controller fallback without a routed receipt. `execute` remains an explicit comparison mode and `observe` changes no model or child while retaining fail-closed high-impact protection. Configured compaction streams are buffered so partial failed output cannot contaminate the inherited-route retry or replace original history.
21
23
 
@@ -37,7 +39,7 @@ With DSH `0.2.1-rc.2` or a compatible later version installed, run:
37
39
  npx odai-dsh-agent install [--profile web] [--dsh-home /path/to/dsh-home]
38
40
  ```
39
41
 
40
- The installer checks `dsh -V` (the `0.2.56` candidate accepts `>=0.2.1-rc.2`, including later prereleases, without an upper version cap; published `0.2.37` targets `0.1.5-rc.2` and keeps its copied-preset installer), then runs `dsh plugin --profile <profile> add odai-dsh-agent@<version> --save-exact`. DSH's plugin manager checks the package's DSH peer before downloading anything. The package already contains the canonical skills and runtime; it does not require the Plugin. Restart the DSH Web process after a profile change, open a new session, and select `odai 治理模式` in the preset picker. Existing sessions keep the composition they started with.
42
+ The installer checks `dsh -V` (the `0.3.1` candidate accepts `>=0.2.1-rc.2`, including later prereleases, without an upper version cap; published `0.2.37` targets `0.1.5-rc.2` and keeps its copied-preset installer), then runs `dsh plugin --profile <profile> add odai-dsh-agent@<version> --save-exact`. DSH's plugin manager checks the package's DSH peer before downloading anything. The package already contains the canonical skills and runtime; it does not require the Plugin. Restart the DSH Web process after a profile change, open a new session, and select `odai 治理模式` in the preset picker. Existing sessions keep the composition they started with.
41
43
 
42
44
  DSH `0.1.7` does not carry the earlier `agent-presets.default` setting forward. To make odai the default preset again, choose it as the default in DSH; the choice is saved in the profile's own `cordis.patch.yml`.
43
45
 
@@ -49,13 +51,13 @@ DSH bundles run in-process with the host's privileges, so install only reviewed
49
51
 
50
52
  ## Control Center
51
53
 
52
- The Control Center ships inside the same bundle. It adds one Chinese launcher to DSH Web with a current-turn responsibility graph, session evidence timeline, structured event inspector, and routing controls for the five optional responsibilities: researcher, planner, reviewer, frontend, and creative, labeled 调查、规划、审查、设计、创意. Creative defaults to child and disables same-turn. The controller remains host-managed and read-only. Routing writes use the same validated, locked, atomic routing action as the conversation tool and apply on the next user turn. Configured models alone are never displayed as execution evidence. A native-collaboration summary shows observed `subagent`/`subagent_fork` tool receipts; these are not named-role model verification or child completion evidence.
54
+ The Control Center ships inside the same bundle. It adds one Chinese launcher to DSH Web with a current-turn responsibility graph, session evidence timeline, structured event inspector, and routing controls for the six optional responsibilities: researcher, planner, reviewer, frontend, creative, and writer, labeled 调查、规划、审查、设计、创意、写作. Creative and writer default to child and disable same-turn. The controller remains host-managed and read-only. Routing writes use the same validated, locked, atomic routing action as the conversation tool and apply on the next user turn. Configured models alone are never displayed as execution evidence. A native-collaboration summary shows observed `subagent`/`subagent_fork` tool receipts; these are not named-role model verification or child completion evidence.
53
55
 
54
56
  The earlier `control-center install|status|uninstall` commands remain as aliases for `install|status|uninstall`. `--with-control-center` and `--without-control-center` are accepted and ignored; disable the Control Center row in the Plugins page instead.
55
57
 
56
58
  ## Responsibility models
57
59
 
58
- The Agent ships no researcher, planner, reviewer, frontend, or creative model mapping. It stays quiet when an unconfigured responsibility is not needed. If a real task gap needs one, Odai says which responsibility is missing, confirms that no route ran, and asks for the provider, model, and optional reasoning effort in natural language. For example:
60
+ The Agent ships no researcher, planner, reviewer, frontend, creative, or writer model mapping. It stays quiet when an unconfigured responsibility is not needed. If a real task gap needs one, Odai says which responsibility is missing, confirms that no route ran, and asks for the provider, model, and optional reasoning effort in natural language. For example:
59
61
 
60
62
  ```text
61
63
  证据调查用 provider-r/model-research,推理档 high。
@@ -66,11 +68,11 @@ The Agent ships no researcher, planner, reviewer, frontend, or creative model ma
66
68
  研究和验收职责改成 same-turn。
67
69
  ```
68
70
 
69
- The controller calls `odai_routing_config` to persist that explicit choice. For API routes, researcher, planner, reviewer, and frontend each accept an explicit `same-turn` or `child` dispatch override; creative supports only child on both API and local CLI routes, defaulting to child and rejecting explicit same-turn. The controller owns integration, validation, and final delivery. Children remain read-only; explicitly delegated patch preparation returns unapplied proposals, while research, planning, and review keep their narrower contracts. The tool uses separate `set-dispatch`/`reset-dispatch` actions, so changing a dispatch override does not remove its model mapping. Researcher activation is task-gated but not price-aware: its mapping enables the narrow trigger and does not guarantee lower cost. The tool repeats that warning whenever a researcher mapping is shown; Odai must use authoritative provider prices and measured usage instead of inventing either. The user does not edit Agent files, YAML, or JSON and does not add trigger terms to later tasks. Mappings live in `$DSH_HOME/odai/routing.json`, outside the package, so updates never replace them. A legacy Executor mapping is ignored without invalidating current responsibilities and is removed on the next configuration write. Audit evidence likewise lives under `$DSH_HOME/odai/session-evidence/` instead of using private DSH session-event types, so changing or removing the preset cannot make a session unreadable. Changes apply from the next user turn. Whenever routing or explicit mapping management needs it, runtime resolves a fresh merged effective-mapping snapshot, with persisted mappings preferred over deployment mappings; the full snapshot enters the model prompt only for mapping-management intent and remains authoritative over stale compaction text. The tool also exposes the latest current-session actual route receipt; configured targets alone never prove that a responsibility ran. If reasoning effort is omitted, the target provider/model uses its own default rather than inheriting the source controller's setting. Plugin and Agent read the same stores when both are deliberately present.
71
+ The controller calls `odai_routing_config` to persist that explicit choice. For API routes, researcher, planner, reviewer, and frontend each accept an explicit `same-turn` or `child` dispatch override; creative and writer support only child on both API and local CLI routes, defaulting to child and rejecting explicit same-turn. The controller owns integration, validation, and final delivery. Children remain read-only; explicitly delegated patch preparation returns unapplied proposals, while research, planning, and review keep their narrower contracts. The tool uses separate `set-dispatch`/`reset-dispatch` actions, so changing a dispatch override does not remove its model mapping. Researcher activation is task-gated but not price-aware: its mapping enables the narrow trigger and does not guarantee lower cost. The tool repeats that warning whenever a researcher mapping is shown; Odai must use authoritative provider prices and measured usage instead of inventing either. The user does not edit Agent files, YAML, or JSON and does not add trigger terms to later tasks. Mappings live in `$DSH_HOME/odai/routing.json`, outside the package, so updates never replace them. A legacy Executor mapping is ignored without invalidating current responsibilities and is removed on the next configuration write. Audit evidence likewise lives under `$DSH_HOME/odai/session-evidence/` instead of using private DSH session-event types, so changing or removing the preset cannot make a session unreadable. Changes apply from the next user turn. Whenever routing or explicit mapping management needs it, runtime resolves a fresh merged effective-mapping snapshot, with persisted mappings preferred over deployment mappings; the full snapshot enters the model prompt only for mapping-management intent and remains authoritative over stale compaction text. The tool also exposes the latest current-session actual route receipt; configured targets alone never prove that a responsibility ran. If reasoning effort is omitted, the target provider/model uses its own default rather than inheriting the source controller's setting. Plugin and Agent read the same stores when both are deliberately present.
70
72
 
71
- Researcher and frontend are optional evidence/production upgrades whose missing mappings keep the original route without claiming success. A researcher child is limited to a bounded multi-source repository question; technical facts available through controller tools are investigated directly instead of manufacturing a role call. Planner and reviewer are independent optional responsibilities; if a needed one has no mapping, high-impact work fails closed and remains read-only, while lower-impact work continues only where it does not depend on the missing responsibility. Same-turn routes and child outputs require actual request-header evidence. Same-turn researcher, planner, and reviewer are read-only and must return through `odai_responsibility_return` to the controller, which resumes any authorized implementation. Missing handback restores and continues the controller instead of treating the read-only text as final delivery. Deterministic invalid persisted mappings are backed up and exact-match removed; credentials, quota, rate-limit, server, timeout, and transport failures preserve configuration and fall back only for the current call. Matching responsibilities use `odai_responsibility_gap` to honor configured models, dispatch, and evidence gates. A generic subagent is not a responsibility route. Exceptional manual planner/frontend/creative children using API routes use the native tool's `description` prefix `odai-planner:`, `odai-frontend:`, or `odai-creative:` and require a matching actual-route receipt; researcher/reviewer require managed evidence validation. Local child routing receipts reach the parent's Control Center under the corresponding role, without claiming task completion. Odai never chooses a model or price on the user's behalf.
73
+ Researcher and frontend are optional evidence/production upgrades whose missing mappings keep the original route without claiming success. A researcher child is limited to a bounded multi-source repository question; technical facts available through controller tools are investigated directly instead of manufacturing a role call. Planner and reviewer are independent optional responsibilities; if a needed one has no mapping, high-impact work fails closed and remains read-only, while lower-impact work continues only where it does not depend on the missing responsibility. Same-turn routes and child outputs require actual request-header evidence. Same-turn researcher, planner, and reviewer are read-only and must return through `odai_responsibility_return` to the controller, which resumes any authorized implementation. Missing handback restores and continues the controller instead of treating the read-only text as final delivery. Deterministic invalid persisted mappings are backed up and exact-match removed; credentials, quota, rate-limit, server, timeout, and transport failures preserve configuration and fall back only for the current call. Matching responsibilities use `odai_responsibility_gap` to honor configured models, dispatch, and evidence gates. A generic subagent is not a responsibility route. Exceptional manual planner/frontend/creative/writer children using API routes use the native tool's `description` prefix `odai-planner:`, `odai-frontend:`, `odai-creative:`, or `odai-writer:` and require a matching actual-route receipt; researcher/reviewer require managed evidence validation. Local child routing receipts reach the parent's Control Center under the corresponding role, without claiming task completion. Odai never chooses a model or price on the user's behalf.
72
74
 
73
- Planner/frontend/creative also support read-only, child-only local Claude Code, Codex, Antigravity (`agy`), and Grok CLI routes via `odai_routing_config` (`cli`: `claude`, `codex`, `antigravity`, `grok`). Grok is implemented from official documentation and has not been tested against a real CLI. These routes reject native manual labels and same-turn dispatch. See the [local CLI configuration and receipt contract](https://github.com/orziz/odai/blob/main/dsh/README.md#local-cli-responsibility-routes).
75
+ Planner/frontend/creative/writer also support read-only, child-only local Claude Code, Codex, Antigravity (`agy`), and Grok CLI routes via `odai_routing_config` (`cli`: `claude`, `codex`, `antigravity`, `grok`). Grok is implemented from official documentation and has not been tested against a real CLI. These routes reject native manual labels and same-turn dispatch. See the [local CLI configuration and receipt contract](https://github.com/orziz/odai/blob/main/dsh/README.md#local-cli-responsibility-routes).
74
76
 
75
77
  ## Controller output policy
76
78
 
@@ -108,11 +110,11 @@ The Agent keeps the bundle's complete skill copy as its `bundled` default, so ex
108
110
 
109
111
  An independent install must be a complete directory bundle containing `SKILL.md`, `manifest.json`, and every manifest-declared file. The runtime checks SemVer 2.0.0 `skillVersion`, an exact supported `runtimeContract`, complete-file SHA-256 integrity, and same-version content conflicts. Prompt governance and routing role contracts are selected atomically for one agent turn; project sources are scoped by that session's cwd, and changes are reconsidered on the next user turn. Explicit deployment `skillPath` or `ODAI_SKILL_PATH` remains highest priority and requires a DSH restart.
110
112
 
111
- The `0.2.56` source candidate bundles governance `0.7.1` (schema `5`, runtime contract `9`) and `odai-orchestration` `0.2.2` (schema `1`). The latest published pair is `0.2.55`, with governance `0.7.1`, runtime contract `9`, and orchestration `0.2.2`. Published `0.2.38` bundles orchestration `0.2.0`. Published `0.2.37` bundles governance `0.7.0` with the same schemas and runtime contract, and orchestration `0.2.0`. Governance has no role or orchestration dependency. The bundle carries both skills and its own trusted compiler, combining separate source digests into one immutable turn snapshot; it never executes external scripts or discovers neighboring orchestration. Incompatible older sources fall back visibly without rewriting their files; an incompatible explicit `skillPath` fails fast.
113
+ The `0.3.1` source candidate bundles governance `0.7.1` (schema `5`, runtime contract `9`) and `odai-orchestration` `0.2.3` (schema `1`). The latest published pair is `0.2.57`. Published `0.2.56` bundles governance `0.7.1`, runtime contract `9`, and orchestration `0.2.2`. Published `0.2.38` bundles orchestration `0.2.0`. Published `0.2.37` bundles governance `0.7.0` with the same schemas and runtime contract, and orchestration `0.2.0`. Governance has no role or orchestration dependency. The bundle carries both skills and its own trusted compiler, combining separate source digests into one immutable turn snapshot; it never executes external scripts or discovers neighboring orchestration. Incompatible older sources fall back visibly without rewriting their files; an incompatible explicit `skillPath` fails fast.
112
114
 
113
115
  ## Retired skill evolution
114
116
 
115
- Releases before `0.2.37` could refine both governance and orchestration Markdown in `$DSH_HOME/odai/skill-evolution`. Published `0.2.37` retired that overlay together with `odai_skill_evolution`, `ODAI_DISABLE_EVOLUTION`, and `governance.evolutionRoot`; later releases, including the `0.2.56` candidate, preserve that retirement. Previously active refinements stop taking effect after upgrading and restarting DSH. The runtime no longer reads the store, no package install, update, repair, or removal deletes it, and a leftover `evolutionRoot` is ignored.
117
+ Releases before `0.2.37` could refine both governance and orchestration Markdown in `$DSH_HOME/odai/skill-evolution`. Published `0.2.37` retired that overlay together with `odai_skill_evolution`, `ODAI_DISABLE_EVOLUTION`, and `governance.evolutionRoot`; later releases, including the `0.3.1` candidate, preserve that retirement. Previously active refinements stop taking effect after upgrading and restarting DSH. The runtime no longer reads the store, no package install, update, repair, or removal deletes it, and a leftover `evolutionRoot` is ignored.
116
118
 
117
119
  To retain governance customizations, start with a complete schema `5` / contract `9` user-level bundle, review and apply the desired rules, assign a distinct valid SemVer `skillVersion`, then ask Odai to set the source to `user`. Modified content retaining this candidate's bundled version `0.7.1` falls back with `same-version-content-conflict`; changing only build metadata is insufficient. On the next turn verify the actual canonical source, version and governance digest, not just the saved setting. Explicit deployment paths take precedence.
118
120
 
package/client/client.js CHANGED
@@ -8,7 +8,7 @@ window.__ModuleLoader__.load({
8
8
  const ReactDOM = require_("react-dom");
9
9
  const { createElement: h, useEffect, useMemo, useRef, useState, useSyncExternalStore } = React;
10
10
  const PACKAGE_ID = "odai-dsh-agent";
11
- const ROLES = Object.freeze(["researcher", "planner", "reviewer", "frontend", "creative"]);
11
+ const ROLES = Object.freeze(["researcher", "planner", "reviewer", "frontend", "creative", "writer"]);
12
12
  const ROLE_LABELS = Object.freeze({
13
13
  controller: "总控",
14
14
  researcher: "调查",
@@ -16,6 +16,7 @@ window.__ModuleLoader__.load({
16
16
  reviewer: "审查",
17
17
  frontend: "设计",
18
18
  creative: "创意",
19
+ writer: "写作",
19
20
  });
20
21
  const STATE_LABELS = Object.freeze({
21
22
  proposal: "已提议",
@@ -69,6 +70,7 @@ window.__ModuleLoader__.load({
69
70
  if (timeout && (!positiveInteger(timeout) || Number(timeout) > 7200))
70
71
  return undefined;
71
72
  return {
73
+ ...(form.session ? { session: form.session } : {}),
72
74
  action: "set", responsibility: role, backend: "local-cli", cli: form.cli, model,
73
75
  ...(effort ? { reasoningEffort: effort } : {}),
74
76
  ...(timeout ? { timeoutSeconds: Number(timeout) } : {}),
@@ -79,6 +81,7 @@ window.__ModuleLoader__.load({
79
81
  if (!provider || (maxTokens && !positiveInteger(maxTokens)))
80
82
  return undefined;
81
83
  return {
84
+ ...(form.session ? { session: form.session } : {}),
82
85
  action: "set", responsibility: role, provider, model,
83
86
  ...(effort ? { reasoningEffort: effort } : {}),
84
87
  ...(maxTokens ? { maxTokens: Number(maxTokens) } : {}),
@@ -154,6 +157,7 @@ window.__ModuleLoader__.load({
154
157
  if (route.backend === "local-cli" && (route.cli === "claude" || route.cli === "codex" || route.cli === "antigravity" || route.cli === "grok"))
155
158
  return Object.freeze({
156
159
  backend: "local-cli", cli: route.cli, model: text(route.model),
160
+ ...(route.session === "fresh" || route.session === "continue" ? { session: route.session } : {}),
157
161
  reasoningEffort: text(route.reasoningEffort) || undefined,
158
162
  timeoutSeconds: positiveInteger(route.timeoutSeconds),
159
163
  });
@@ -162,6 +166,7 @@ window.__ModuleLoader__.load({
162
166
  return Object.freeze({
163
167
  provider: text(route.provider),
164
168
  model: text(route.model),
169
+ ...(route.session === "fresh" || route.session === "continue" ? { session: route.session } : {}),
165
170
  reasoningEffort: text(route.reasoningEffort) || undefined,
166
171
  maxTokens: positiveInteger(route.maxTokens),
167
172
  });
@@ -422,12 +427,13 @@ window.__ModuleLoader__.load({
422
427
  const route = config?.roles?.[role];
423
428
  const source = config?.sources?.[role];
424
429
  const localCli = route?.backend === "local-cli";
425
- const childOnly = role === "creative" || localCli;
430
+ const childOnly = role === "creative" || role === "writer" || localCli;
426
431
  const dispatch = config?.dispatch?.[role];
427
432
  const dispatchSource = config?.dispatchSources?.[role];
428
433
  const [editing, setEditing] = useState(false);
429
434
  const [provider, setProvider] = useState(route?.provider ?? "");
430
435
  const [model, setModel] = useState(route?.model ?? "");
436
+ const [session, setSession] = useState(route?.session ?? "fresh");
431
437
  const [effort, setEffort] = useState(route?.reasoningEffort ?? "");
432
438
  const [maxTokens, setMaxTokens] = useState(route?.maxTokens ? String(route.maxTokens) : "");
433
439
  const [timeoutSeconds, setTimeoutSeconds] = useState(route?.timeoutSeconds ? String(route.timeoutSeconds) : "");
@@ -441,13 +447,14 @@ window.__ModuleLoader__.load({
441
447
  setCli(route?.cli ?? "claude");
442
448
  setProvider(route?.provider ?? "");
443
449
  setModel(route?.model ?? "");
450
+ setSession(route?.session ?? "fresh");
444
451
  setEffort(route?.reasoningEffort ?? "");
445
452
  setMaxTokens(route?.maxTokens ? String(route.maxTokens) : "");
446
453
  setTimeoutSeconds(route?.timeoutSeconds ? String(route.timeoutSeconds) : "");
447
454
  }, [route, editing]);
448
455
  const formCli = backend === "local-cli";
449
456
  const efforts = LOCAL_CLI_OPTIONS.find((option) => option.id === cli)?.efforts;
450
- const payload = routeEditorPayload(role, { backend, cli, provider, model, effort, maxTokens, timeoutSeconds });
457
+ const payload = routeEditorPayload(role, { backend, cli, provider, model, effort, maxTokens, timeoutSeconds, session });
451
458
  const save = () => payload ? onApply(payload).then(() => setEditing(false)) : undefined;
452
459
  const remove = () => {
453
460
  if (!window.confirm(`确认移除“${ROLE_LABELS[role]}”的本地模型映射?`))
@@ -460,7 +467,7 @@ window.__ModuleLoader__.load({
460
467
  else
461
468
  onApply({ action: "set-dispatch", responsibility: role, dispatch: value });
462
469
  };
463
- return h("article", { className: "odaiCC__routeRow" }, h("div", { className: "odaiCC__routeSummary" }, h(RoleBadge, { role }), h("div", { className: "odaiCC__routeValue" }, h("strong", null, formatRoute(route)), h("span", null, sourceLabel(source))), h("button", { type: "button", className: "odaiCC__quietButton", onClick: () => setEditing((value) => !value), disabled: busy }, editing ? "取消" : "编辑")), h("div", { className: "odaiCC__dispatch" }, h("span", null, "调度方式"), h("div", { className: "odaiCC__segments", role: "group", "aria-label": `${ROLE_LABELS[role]}调度方式` }, ["default", "same-turn", "child"].map((value) => h("button", {
470
+ return h("article", { className: "odaiCC__routeRow" }, h("div", { className: "odaiCC__routeSummary" }, h(RoleBadge, { role }), h("div", { className: "odaiCC__routeValue" }, h("strong", null, formatRoute(route)), h("span", null, sourceLabel(source), route?.session === "continue" ? " · 会话续接" : "")), h("button", { type: "button", className: "odaiCC__quietButton", onClick: () => setEditing((value) => !value), disabled: busy }, editing ? "取消" : "编辑")), h("div", { className: "odaiCC__dispatch" }, h("span", null, "调度方式"), h("div", { className: "odaiCC__segments", role: "group", "aria-label": `${ROLE_LABELS[role]}调度方式` }, ["default", "same-turn", "child"].map((value) => h("button", {
464
471
  key: value,
465
472
  type: "button",
466
473
  className: (dispatch ?? "default") === value ? "is-active" : "",
@@ -476,7 +483,7 @@ window.__ModuleLoader__.load({
476
483
  ? h("label", null, h("span", null, "本机 CLI"), h("select", { value: cli, onChange: (event) => setCli(event.target.value), disabled: busy }, LOCAL_CLI_OPTIONS.map((option) => h("option", { key: option.id, value: option.id }, option.label))))
477
484
  : h("label", null, h("span", null, "Provider"), h("input", { value: provider, onChange: (event) => setProvider(event.target.value), placeholder: "Provider ID", disabled: busy })), h("label", null, h("span", null, "模型"), h("input", { value: model, onChange: (event) => setModel(event.target.value), placeholder: formCli ? "模型 ID 或别名" : "模型 ID", disabled: busy })), h("label", null, h("span", null, "推理档位"), h("input", { value: effort, onChange: (event) => setEffort(event.target.value), placeholder: formCli && efforts ? `可选:${efforts}` : "可选", disabled: busy })), formCli
478
485
  ? h("label", null, h("span", null, "超时(秒)"), h("input", { value: timeoutSeconds, onChange: (event) => setTimeoutSeconds(event.target.value), inputMode: "numeric", placeholder: "可选,默认 1200", disabled: busy }))
479
- : h("label", null, h("span", null, "最大 tokens"), h("input", { value: maxTokens, onChange: (event) => setMaxTokens(event.target.value), inputMode: "numeric", placeholder: "可选", disabled: busy })), h("div", { className: "odaiCC__formActions" }, route ? h("button", { type: "button", className: "odaiCC__dangerButton", onClick: remove, disabled: busy }, "移除映射") : null, h("button", { type: "button", className: "odaiCC__primaryButton", onClick: save, disabled: busy || !payload }, busy ? "正在验证…" : (formCli ? "保存" : "验证并保存")))) : null);
486
+ : h("label", null, h("span", null, "最大 tokens"), h("input", { value: maxTokens, onChange: (event) => setMaxTokens(event.target.value), inputMode: "numeric", placeholder: "可选", disabled: busy })), h("label", null, h("span", null, "会话续接"), h("select", { value: session, onChange: (event) => setSession(event.target.value), disabled: busy }, h("option", { value: "fresh" }, "每次新开(默认)"), h("option", { value: "continue" }, "续接(不支持的后端会明确报错)"))), h("div", { className: "odaiCC__formActions" }, route ? h("button", { type: "button", className: "odaiCC__dangerButton", onClick: remove, disabled: busy }, "移除映射") : null, h("button", { type: "button", className: "odaiCC__primaryButton", onClick: save, disabled: busy || !payload }, busy ? "正在验证…" : (formCli ? "保存" : "验证并保存")))) : null);
480
487
  }
481
488
  function RoutingView({ connection, config, setConfig, loading, error, reload }) {
482
489
  const [busyRole, setBusyRole] = useState(undefined);
@@ -601,9 +608,79 @@ window.__ModuleLoader__.load({
601
608
  ? h(LiveView, { trace, evidenceError })
602
609
  : h(RoutingView, { connection, config, setConfig, loading, error, reload })))), document.body);
603
610
  }
611
+ function SessionControls({ sessionId, connection }) {
612
+ const [state, setState] = useState(null);
613
+ const [error, setError] = useState("");
614
+ const [busy, setBusy] = useState(false);
615
+ const lifetime = useRef(null);
616
+ const sequence = useRef(0);
617
+ const mutating = useRef(false);
618
+ const request = async (payload, signal) => {
619
+ const current = ++sequence.current;
620
+ const response = await connection.rpc.call("/api", "odai-control-center/session", { sessionId, ...payload }, signal);
621
+ if (!response?.ok || !response.value?.ok)
622
+ throw new Error(response?.value?.error?.message || response?.error?.message || "会话控制不可用");
623
+ if (!signal.aborted && current === sequence.current) {
624
+ setState(response.value.session);
625
+ setError("");
626
+ }
627
+ };
628
+ useEffect(() => {
629
+ const controller = new AbortController();
630
+ lifetime.current = controller;
631
+ setState(null);
632
+ setError("");
633
+ setBusy(false);
634
+ let pending = false;
635
+ const refresh = async () => {
636
+ if (!sessionId || pending || mutating.current)
637
+ return;
638
+ pending = true;
639
+ try {
640
+ await request({ action: "show" }, controller.signal);
641
+ }
642
+ catch (e) {
643
+ if (!controller.signal.aborted)
644
+ setError(String(e));
645
+ }
646
+ finally {
647
+ pending = false;
648
+ }
649
+ };
650
+ void refresh();
651
+ const timer = setInterval(refresh, 2500);
652
+ return () => { controller.abort(); clearInterval(timer); };
653
+ }, [sessionId, connection]);
654
+ const change = async (payload) => {
655
+ const controller = lifetime.current;
656
+ if (!controller || busy)
657
+ return;
658
+ mutating.current = true;
659
+ setBusy(true);
660
+ try {
661
+ await request(payload, controller.signal);
662
+ }
663
+ catch (e) {
664
+ if (!controller.signal.aborted)
665
+ setError(String(e));
666
+ }
667
+ finally {
668
+ mutating.current = false;
669
+ if (!controller.signal.aborted)
670
+ setBusy(false);
671
+ }
672
+ };
673
+ const details = state?.continuation.roles.map((r) => `${r.responsibility}:${r.reason || (r.effective === "continue" ? "续接" : "新开")}`).join(";");
674
+ return h("span", { style: { display: "inline-flex", gap: "6px", alignItems: "center", flexWrap: "wrap" } }, h("button", { type: "button", className: "odaiCC__launcher", role: "switch", "aria-checked": !!state?.lead.enabled,
675
+ disabled: busy || !state || (!state.lead.enabled && !state.lead.available), title: state?.lead.reason || "本会话:首次写入前规划,写入后审查;不取消正在运行的调用",
676
+ onClick: () => change({ action: "set-lead", enabled: !state.lead.enabled }) }, `主导:${state ? state.lead.enabled ? "开" : "关" : "…"}`), h("label", { title: details || state?.continuation.reason }, "职责续接 ", h("select", {
677
+ "aria-label": "本会话职责续接", disabled: busy || !state, value: state?.continuation.override ?? "inherit",
678
+ onChange: (event) => change({ action: "set-continuation", value: event.target.value })
679
+ }, h("option", { value: "inherit" }, "按映射"), h("option", { value: "fresh" }, "关闭"), h("option", { value: "continue", disabled: !state?.continuation.available }, "开启(支持的职责)"))), error ? h("span", { role: "alert" }, error) : state?.lead.reason || state?.continuation.reason ? h("small", null, state.lead.reason || state.continuation.reason) : null);
680
+ }
604
681
  function Launcher(props) {
605
682
  const [open, setOpen] = useState(false);
606
- return h(React.Fragment, null, h("button", {
683
+ return h(React.Fragment, null, h(SessionControls, { key: props.sessionId, sessionId: props.sessionId, connection: props.connection }), h("button", {
607
684
  type: "button",
608
685
  className: "odaiCC__launcher",
609
686
  onClick: () => setOpen(true),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odai-dsh-agent",
3
- "version": "0.2.56",
3
+ "version": "0.3.1",
4
4
  "description": "独立维护的 odai 治理模式预设(DSH bundle),按任务需要提供治理与协作。",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -3,6 +3,7 @@
3
3
  "type": "module",
4
4
  "imports": {
5
5
  "#odai-contracts": "./skills/odai-orchestration/scripts/compose-contracts.mjs",
6
- "#odai-local-cli": "./skills/odai-orchestration/scripts/local-cli.mjs"
6
+ "#odai-local-cli": "./skills/odai-orchestration/scripts/local-cli.mjs",
7
+ "#odai-recognize-routing": "./skills/odai-orchestration/scripts/recognize-routing.mjs"
7
8
  }
8
9
  }
@@ -17,7 +17,7 @@ export const ODAI_CORE_TOOL_NAMES = Object.freeze([
17
17
  ]);
18
18
  const CARE_CUE = /(?:疲惫|心累|焦虑|紧张|自我怀疑|怀疑自己|否定自己|内耗|反刍|反复纠结|羞耻|丢脸|害怕犯错|怕犯错|持续消极|提不起劲|失去行动感|阿岱|欧黛|fatigue|burn(?:ed|t) out|anxi(?:ous|ety)|self[- ]doubt|doubt myself|ruminat(?:e|ing|ion)|shame|fear of mistakes?|persistent negativity|cannot get started|companionship style|practical support style)/iu;
19
19
  const CRISIS_CUE = /(?:持续低落|越来越低落|绝望|无望|撑不住|活不下去|不想活|想死|结束生命|成为负担|自伤|自残|轻生|自杀|伤害自己|immediate danger|persistent low mood|hopeless|cannot go on|burden|self[- ]harm|suicid(?:e|al)|want to die|kill myself|end my life)/iu;
20
- const ROUTING_CONFIG_CUE = /(?:(?:研究|调查|规划|计划|审查|验收|前端|创意|researcher|planner|reviewer|frontend|creative).{0,24}(?:模型|路由|映射|调度|派发|provider|model|route|mapping|dispatch|same-turn|child|同轮|子代理)|(?:模型|路由|映射|调度|派发|provider|model|route|mapping|dispatch|same-turn|child|同轮|子代理).{0,24}(?:研究|调查|规划|计划|审查|验收|前端|创意|researcher|planner|reviewer|frontend|creative)|(?:所有|当前|职责|责任)?(?:模型|路由|调度|派发)(?:配置|映射)|routing config)/iu;
20
+ const ROUTING_CONFIG_CUE = /(?:(?:研究|调查|规划|计划|审查|验收|前端|创意|写作|researcher|planner|reviewer|frontend|creative|writer).{0,24}(?:模型|路由|映射|调度|派发|provider|model|route|mapping|dispatch|same-turn|child|同轮|子代理)|(?:模型|路由|映射|调度|派发|provider|model|route|mapping|dispatch|same-turn|child|同轮|子代理).{0,24}(?:研究|调查|规划|计划|审查|验收|前端|创意|写作|researcher|planner|reviewer|frontend|creative|writer)|(?:所有|当前|职责|责任)?(?:模型|路由|调度|派发)(?:配置|映射)|routing config)/iu;
21
21
  const SKILL_SOURCE_CUE = /(?:(?:odai|阿岱|欧黛).{0,20}(?:skill|治理).{0,20}(?:来源|source|bundled|auto|user)|(?:skill|治理).{0,20}(?:来源|source).{0,20}(?:odai|阿岱|欧黛))/iu;
22
22
  const OUTPUT_CONFIG_CUE = /(?:(?:输出|回复|回答).{0,20}(?:normal|正常|简洁|精简|concise|economy|经济|token|上限)|(?:maxTokens|token 上限|output mode|输出模式)|(?:(?:这个|当前|本次|本)(?:会话|对话)|\b(?:this|current)\s+(?:chat|conversation|session)\b).{0,24}(?:上限|限制|limit|cap|ceiling)|(?:\b(?:output|token)?\s*(?:limit|cap|ceiling)\b).{0,24}\b(?:this|current)\s+(?:chat|conversation|session)\b)/iu;
23
23
  const COMPACTION_CONFIG_CUE = /(?:(?:压缩|compaction).{0,32}(?:模型|provider|model|推理|reasoning|配置|设置|查看|重置)|(?:模型|provider|model).{0,20}(?:压缩摘要|compaction summary))/iu;
@@ -1 +1 @@
1
- {"version":3,"file":"context-activation.mjs","sourceRoot":"","sources":["../src/context-activation.mts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,qBAAqB;IACrB,iBAAiB;IACjB,mBAAmB;IACnB,4BAA4B;IAC5B,sBAAsB;IACtB,0BAA0B;IAC1B,oBAAoB;IACpB,wBAAwB;IACxB,aAAa;IACb,8BAA8B;CACtB,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,yBAAyB;IACzB,yBAAyB;IACzB,gBAAgB;CACR,CAAC,CAAC;AAsBZ,MAAM,QAAQ,GAAG,wRAAwR,CAAC;AAC1S,MAAM,UAAU,GAAG,qMAAqM,CAAC;AACzN,MAAM,kBAAkB,GAAG,+XAA+X,CAAC;AAC3Z,MAAM,gBAAgB,GAAG,qIAAqI,CAAC;AAC/J,MAAM,iBAAiB,GAAG,kVAAkV,CAAC;AAC7W,MAAM,qBAAqB,GAAG,sIAAsI,CAAC;AACrK,MAAM,UAAU,GAAG,oJAAoJ,CAAC;AACxK,MAAM,cAAc,GAAG,0KAA0K,CAAC;AAElM,MAAM,UAAU,yBAAyB,CAAC,IAAa;IACrD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QACrC,MAAM;QACN,aAAa,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7C,WAAW,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QACzC,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3C,gBAAgB,EAAE,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QACnD,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,UAAU,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;KACvC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAA6B,EAC7B,OAAO,GAAsB,EAAE;IAE/B,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChG,MAAM,KAAK,GAAG,IAAI,GAAG,CAAe,oBAAoB,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,qBAAqB,KAAK,KAAK;QAAE,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACrF,IAAI,OAAO,CAAC,oBAAoB;QAAE,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjE,IAAI,UAAU,CAAC,aAAa;QAAE,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC/D,IAAI,UAAU,CAAC,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAClD,IAAI,UAAU,CAAC,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,oBAAoB;QAAE,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1E,IAAI,UAAU,CAAC,WAAW;QAAE,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,YAAY;QAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC7D,IAAI,UAAU,CAAC,gBAAgB;QAAE,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACrE,IAAI,UAAU,CAAC,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,UAAU;QAAE,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAA6B;IACjE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,MAAM,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvF,CAAC"}
1
+ {"version":3,"file":"context-activation.mjs","sourceRoot":"","sources":["../src/context-activation.mts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type SessionControlsSnapshot } from "./session-controls.mjs";
1
2
  import { type RoleDispatches, type RoleRoutes, type RoutingConfigResult } from "./routing-config.mjs";
2
3
  import type { SessionEvidenceEvent } from "./session-evidence.mjs";
3
4
  import type { DshRuntimeContext, RuntimeLogger } from "./runtime-types.mjs";
@@ -10,6 +11,7 @@ interface RpcFailure {
10
11
  }
11
12
  export interface ControlCenterResponse {
12
13
  ok: boolean;
14
+ session?: SessionControlsSnapshot;
13
15
  config?: Omit<RoutingConfigResult, "configPath" | "latestRoute">;
14
16
  events?: readonly SessionEvidenceEvent[];
15
17
  revision?: string;
@@ -18,6 +20,7 @@ export interface ControlCenterResponse {
18
20
  }
19
21
  export interface ControlCenterRuntimeOptions {
20
22
  configPath: string;
23
+ routingMode?: string;
21
24
  evidenceRoot?: string;
22
25
  configuredRoles?: Readonly<RoleRoutes>;
23
26
  configuredDispatch?: Readonly<RoleDispatches>;
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-runtime.d.mts","sourceRoot":"","sources":["../src/control-center-runtime.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAG3F,QAAA,MAAM,sBAAsB,yBAAyB,CAAC;AACtD,QAAA,MAAM,uBAAuB,YAAY,CAAC;AAC1C,QAAA,MAAM,gCAAgC,aAAa,CAAC;AAGpD,UAAU,UAAU;IAClB,IAAI,EAAE,aAAa,GAAG,gBAAgB,GAAG,aAAa,GAAG,UAAU,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAwDD,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AA0DD,wBAAgB,wCAAwC,CACtD,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,2BAA2B,GACnC,MAAM,OAAO,CAAC,IAAI,CAAC,CAmCrB;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,2BAA2B,GACnC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAqEnC;AAED,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,CAAC"}
1
+ {"version":3,"file":"control-center-runtime.d.mts","sourceRoot":"","sources":["../src/control-center-runtime.mts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAG3F,QAAA,MAAM,sBAAsB,yBAAyB,CAAC;AACtD,QAAA,MAAM,uBAAuB,YAAY,CAAC;AAC1C,QAAA,MAAM,gCAAgC,aAAa,CAAC;AAIpD,UAAU,UAAU;IAClB,IAAI,EAAE,aAAa,GAAG,gBAAgB,GAAG,aAAa,GAAG,UAAU,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAwDD,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AA2DD,wBAAgB,wCAAwC,CACtD,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,2BAA2B,GACnC,MAAM,OAAO,CAAC,IAAI,CAAC,CAmCrB;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,2BAA2B,GACnC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAsEnC;AAED,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,CAAC"}
@@ -1,14 +1,16 @@
1
+ import { applySessionControl } from "./session-controls.mjs";
1
2
  import { applyRoutingConfigAction, } from "./routing-config.mjs";
2
3
  import { readStoredSessionEvidence, resolveSessionEvidenceRoot, storedSessionEvidenceRevision, } from "./session-evidence.mjs";
3
4
  import { isUnknownRecord } from "./runtime-types.mjs";
4
5
  const CONTROL_CENTER_CHANNEL = "/odai-control-center";
5
6
  const CONTROL_CENTER_ENDPOINT = "routing";
6
7
  const CONTROL_CENTER_EVIDENCE_ENDPOINT = "evidence";
8
+ const CONTROL_CENTER_SESSION_ENDPOINT = "session";
7
9
  const MAX_EVIDENCE_EVENTS = 2_000;
8
10
  function registerControlCenter(connection, handler) {
9
11
  if (!connection.fetch)
10
12
  return connection.rpc.handle(CONTROL_CENTER_CHANNEL, handler, { authority: "loopback" });
11
- const disposers = [CONTROL_CENTER_ENDPOINT, CONTROL_CENTER_EVIDENCE_ENDPOINT].map((endpoint) => {
13
+ const disposers = [CONTROL_CENTER_ENDPOINT, CONTROL_CENTER_EVIDENCE_ENDPOINT, CONTROL_CENTER_SESSION_ENDPOINT].map((endpoint) => {
12
14
  const method = `${CONTROL_CENTER_CHANNEL.slice(1)}/${endpoint}`;
13
15
  return connection.fetch.register({
14
16
  path: `/api/${method}`, methods: ["POST"], requestBody: "buffered",
@@ -37,7 +39,8 @@ function effectiveOptions(owners) {
37
39
  for (const options of owners.values()) {
38
40
  const weight = Object.keys(options.configuredRoles ?? {}).length
39
41
  + Object.keys(options.configuredDispatch ?? {}).length;
40
- if (selected === undefined || weight > selectedWeight) {
42
+ if (selected === undefined || weight > selectedWeight
43
+ || (weight === selectedWeight && selected.routingMode === undefined && options.routingMode !== undefined)) {
41
44
  selected = options;
42
45
  selectedWeight = weight;
43
46
  }
@@ -154,11 +157,13 @@ export function installControlCenterRuntime(ctx, options) {
154
157
  }
155
158
  const owners = new Map([[owner, options]]);
156
159
  const dispose = registerControlCenter(connection, async (endpoint, payload, signal) => {
157
- if (endpoint !== CONTROL_CENTER_ENDPOINT && endpoint !== CONTROL_CENTER_EVIDENCE_ENDPOINT) {
160
+ if (endpoint !== CONTROL_CENTER_ENDPOINT && endpoint !== CONTROL_CENTER_EVIDENCE_ENDPOINT && endpoint !== CONTROL_CENTER_SESSION_ENDPOINT) {
158
161
  return { ok: true, value: { ok: false, error: { code: "unavailable", message: "unknown Odai Control Center endpoint" } } };
159
162
  }
160
163
  const active = effectiveOptions(owners);
161
164
  try {
165
+ if (endpoint === CONTROL_CENTER_SESSION_ENDPOINT)
166
+ return { ok: true, value: { ok: true, session: applySessionControl(payload, { ...active, evidenceRoot: active.evidenceRoot ?? resolveSessionEvidenceRoot(active.configPath) }) } };
162
167
  if (endpoint === CONTROL_CENTER_EVIDENCE_ENDPOINT) {
163
168
  const request = evidenceRequest(payload);
164
169
  const evidenceRoot = active.evidenceRoot ?? resolveSessionEvidenceRoot(active.configPath);
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-runtime.mjs","sourceRoot":"","sources":["../src/control-center-runtime.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"control-center-runtime.mjs","sourceRoot":"","sources":["../src/control-center-runtime.mts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAeA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAML,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EAEV,iBAAiB,EAKlB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,IAAI,qBAAe,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC;AAEtF,eAAO,MAAM,MAAM,UAA4D,CAAC;AA0BhF,wBAAgB,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAoOtE"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAeA,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAML,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EAEV,iBAAiB,EAKlB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,IAAI,qBAAe,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC;AAEtF,eAAO,MAAM,MAAM,UAA4D,CAAC;AA0BhF,wBAAgB,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CA6QtE"}
@@ -20,7 +20,7 @@ export { inheritCompactionReasoning, resolveConfig, resolveSkillPath, runRoutedR
20
20
  export const inject = ["systemPrompt", "tools", "subagents", "sessions", "llm"];
21
21
  function isResponsibilityGapProposal(data) {
22
22
  return typeof data.responsibility === "string"
23
- && ["researcher", "planner", "reviewer", "frontend", "creative", "user"].includes(data.responsibility)
23
+ && ["researcher", "planner", "reviewer", "frontend", "creative", "writer", "user"].includes(data.responsibility)
24
24
  && typeof data.gap === "string"
25
25
  && Array.isArray(data.evidenceRefs)
26
26
  && data.evidenceRefs.every((value) => typeof value === "string")
@@ -33,6 +33,7 @@ export function apply(ctx, rawConfig) {
33
33
  const logger = loggerFor(ctx);
34
34
  const disposeControlCenter = installControlCenterRuntimeWhenAvailable(ctx, {
35
35
  configPath: config.routing.configPath,
36
+ routingMode: config.routing.mode,
36
37
  configuredRoles: config.routing.roles,
37
38
  configuredDispatch: config.routing.dispatch,
38
39
  logger,
@@ -137,9 +138,49 @@ export function apply(ctx, rawConfig) {
137
138
  return undefined;
138
139
  const events = evidence.events(agent);
139
140
  const consumed = new Set(events.flatMap((event) => (event.type === "odai/responsibility-gap-consumed" ? [event.data?.stateDigest] : [])));
141
+ // Named requests share the existing gap queue, consumption and reviewer deferral.
142
+ for (const event of events) {
143
+ const data = event.data;
144
+ if (event.type !== "odai/responsibility-gap" || data.userNamed !== true || consumed.has(data.stateDigest) || !isResponsibilityGapProposal(data))
145
+ continue;
146
+ const message = latestDirectUserMessage(agent);
147
+ if (!message)
148
+ continue;
149
+ if (message.id !== data.taskMessageId && classifyPendingReviewerText(extractLatestUserText([message])) !== "continue") {
150
+ appendEvent(agent, "odai/responsibility-gap-consumed", { turn, step, responsibility: data.responsibility, stateDigest: data.stateDigest, reason: "SUPERSEDED_BY_DIRECT_USER_TASK" });
151
+ continue;
152
+ }
153
+ const satisfied = events.slice(events.indexOf(event) + 1).some(result => {
154
+ let actualRoute = result.data.actualRoute;
155
+ let startStep = result.data.step;
156
+ if (result.type === "odai/responsibility-returned" && result.data.returned === true && result.data.responsibility === data.responsibility) {
157
+ const receipt = events.find(item => item.type === "odai/route-applied" && item.data.responsibilityScopeId === result.data.scopeId && item.data.status === "applied");
158
+ const scope = events.find(item => item.type === "odai/responsibility-scope-started" && item.data.scopeId === result.data.scopeId);
159
+ actualRoute = receipt?.data.actualRoute;
160
+ startStep = scope?.data.startStep;
161
+ if (!receipt || !scope)
162
+ return false;
163
+ }
164
+ else if (!["odai/route-result", "odai/research-result"].includes(result.type) || result.data.role !== data.responsibility || result.data.status !== "completed" || result.data.routeReceiptStatus !== "applied")
165
+ return false;
166
+ if (!actualRoute || (data.requestedRoute && !sameRequestModelRoute(actualRoute, data.requestedRoute)))
167
+ return false;
168
+ if (result.data.userNamed === true && result.data.stateDigest !== data.stateDigest)
169
+ return false;
170
+ const decision = events.find(item => item.type === "odai/route-decided" && item.data.turn === result.data.turn && item.data.step === startStep);
171
+ return !events.some(item => item.type === "odai/responsibility-gap" && item.data.userNamed === true && item.data.stateDigest === decision?.data.stateDigest && item.data.stateDigest !== data.stateDigest);
172
+ });
173
+ if (satisfied) {
174
+ appendEvent(agent, "odai/responsibility-gap-consumed", { turn, step, responsibility: data.responsibility, stateDigest: data.stateDigest, reason: "SATISFIED_BY_VERIFIED_ROUTE" });
175
+ continue;
176
+ }
177
+ if (data.timing === "completion" && !events.some(item => item.type === "odai/named-request-prompted" && item.data.stateDigest === data.stateDigest))
178
+ continue;
179
+ return data;
180
+ }
140
181
  for (let index = events.length - 1; index >= 0; index -= 1) {
141
182
  const event = events[index];
142
- if (event.data?.turn !== turn
183
+ if (event.data?.userNamed === true || event.data?.turn !== turn
143
184
  || event.type !== "odai/responsibility-gap"
144
185
  || typeof event.data?.step !== "number"
145
186
  || !Number.isSafeInteger(event.data.step)
@@ -174,6 +215,7 @@ export function apply(ctx, rawConfig) {
174
215
  for (let index = events.length - 1; index >= 0; index -= 1) {
175
216
  const event = events[index];
176
217
  if (event.type !== "odai/responsibility-gap"
218
+ || event.data?.userNamed === true
177
219
  || event.data?.responsibility !== "reviewer"
178
220
  || typeof event.data.turn !== "number"
179
221
  || event.data.turn >= turn
@@ -203,6 +245,14 @@ export function apply(ctx, rawConfig) {
203
245
  return undefined;
204
246
  };
205
247
  const invalidateFailedRoleRoute = (agent, role, route, source, failure, position = {}) => {
248
+ const parent = childReceiptParents.get(agent.session);
249
+ const scope = responsibilityScopes.get(agent);
250
+ const decisionOwner = parent?.parent ?? agent;
251
+ const decisionTurn = parent?.turn ?? scope?.turn ?? position.turn;
252
+ const decisionStep = parent?.step ?? scope?.startStep ?? position.step;
253
+ const namedDecision = evidence.events(decisionOwner).some(event => ["odai/route-decided", "odai/research-decided"].includes(event.type) && event.data.turn === decisionTurn && event.data.step === decisionStep && (event.data.role === role || event.data.targetRole === role) && typeof event.data.stateDigest === "string" && event.data.stateDigest.startsWith("user-named:"));
254
+ if (namedDecision)
255
+ return Object.freeze({ invalidated: false, reason: "user-named-route-preserved" });
206
256
  let invalidation = Object.freeze({ invalidated: false, reason: "not-deterministic-or-not-persisted" });
207
257
  if (failure.kind === "deterministic" && source === "persisted-mapping") {
208
258
  try {