odai-dsh-agent 0.2.13 → 0.2.16
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.
- package/README.md +25 -12
- package/build/bin/odai-dsh-agent.mjs +88 -7
- package/build/bin/odai-dsh-agent.mjs.map +1 -1
- package/build/src/control-center-installer.d.mts +32 -0
- package/build/src/control-center-installer.d.mts.map +1 -0
- package/build/src/control-center-installer.mjs +112 -0
- package/build/src/control-center-installer.mjs.map +1 -0
- package/build/src/control-center-prompt.d.mts +4 -0
- package/build/src/control-center-prompt.d.mts.map +1 -0
- package/build/src/control-center-prompt.mjs +15 -0
- package/build/src/control-center-prompt.mjs.map +1 -0
- package/build/src/installer.d.mts +3 -1
- package/build/src/installer.d.mts.map +1 -1
- package/build/src/installer.mjs +46 -4
- package/build/src/installer.mjs.map +1 -1
- package/client/client.js +517 -0
- package/control-center.cordis.patch.yml +3 -0
- package/package.json +24 -5
- package/preset/odai/agent.cordis.yml +12 -7
- package/preset/odai/runtime/canonical-reference.d.mts +15 -0
- package/preset/odai/runtime/canonical-reference.d.mts.map +1 -0
- package/preset/odai/runtime/canonical-reference.mjs +64 -0
- package/preset/odai/runtime/canonical-reference.mjs.map +1 -0
- package/preset/odai/runtime/compaction-config.mjs +1 -1
- package/preset/odai/runtime/compaction-config.mjs.map +1 -1
- package/preset/odai/runtime/context-activation.d.mts +2 -3
- package/preset/odai/runtime/context-activation.d.mts.map +1 -1
- package/preset/odai/runtime/context-activation.mjs +8 -5
- package/preset/odai/runtime/context-activation.mjs.map +1 -1
- package/preset/odai/runtime/control-center-host.d.mts +10 -0
- package/preset/odai/runtime/control-center-host.d.mts.map +1 -0
- package/preset/odai/runtime/control-center-host.mjs +15 -0
- package/preset/odai/runtime/control-center-host.mjs.map +1 -0
- package/preset/odai/runtime/control-center-runtime.d.mts +26 -0
- package/preset/odai/runtime/control-center-runtime.d.mts.map +1 -0
- package/preset/odai/runtime/control-center-runtime.mjs +118 -0
- package/preset/odai/runtime/control-center-runtime.mjs.map +1 -0
- package/preset/odai/runtime/governance.d.mts +1 -1
- package/preset/odai/runtime/governance.d.mts.map +1 -1
- package/preset/odai/runtime/governance.mjs +0 -1
- package/preset/odai/runtime/governance.mjs.map +1 -1
- package/preset/odai/runtime/human-care.d.mts +0 -1
- package/preset/odai/runtime/human-care.d.mts.map +1 -1
- package/preset/odai/runtime/human-care.mjs +0 -1
- package/preset/odai/runtime/human-care.mjs.map +1 -1
- package/preset/odai/runtime/human-safety.d.mts +0 -1
- package/preset/odai/runtime/human-safety.d.mts.map +1 -1
- package/preset/odai/runtime/human-safety.mjs +0 -1
- package/preset/odai/runtime/human-safety.mjs.map +1 -1
- package/preset/odai/runtime/index.d.mts.map +1 -1
- package/preset/odai/runtime/index.mjs +10 -1
- package/preset/odai/runtime/index.mjs.map +1 -1
- package/preset/odai/runtime/lifecycle-runtime.d.mts +0 -2
- package/preset/odai/runtime/lifecycle-runtime.d.mts.map +1 -1
- package/preset/odai/runtime/lifecycle-runtime.mjs +3 -74
- package/preset/odai/runtime/lifecycle-runtime.mjs.map +1 -1
- package/preset/odai/runtime/output-config.d.mts +1 -1
- package/preset/odai/runtime/output-config.d.mts.map +1 -1
- package/preset/odai/runtime/output-config.mjs +2 -2
- package/preset/odai/runtime/output-config.mjs.map +1 -1
- package/preset/odai/runtime/prompt-runtime.d.mts +0 -1
- package/preset/odai/runtime/prompt-runtime.d.mts.map +1 -1
- package/preset/odai/runtime/prompt-runtime.mjs +1 -13
- package/preset/odai/runtime/prompt-runtime.mjs.map +1 -1
- package/preset/odai/runtime/responsibility-return.d.mts +1 -4
- package/preset/odai/runtime/responsibility-return.d.mts.map +1 -1
- package/preset/odai/runtime/responsibility-return.mjs +10 -25
- package/preset/odai/runtime/responsibility-return.mjs.map +1 -1
- package/preset/odai/runtime/responsibility-scope.d.mts +1 -5
- package/preset/odai/runtime/responsibility-scope.d.mts.map +1 -1
- package/preset/odai/runtime/responsibility-scope.mjs +4 -24
- package/preset/odai/runtime/responsibility-scope.mjs.map +1 -1
- package/preset/odai/runtime/role-overlays.d.mts.map +1 -1
- package/preset/odai/runtime/role-overlays.mjs +1 -4
- package/preset/odai/runtime/role-overlays.mjs.map +1 -1
- package/preset/odai/runtime/router.d.mts +3 -13
- package/preset/odai/runtime/router.d.mts.map +1 -1
- package/preset/odai/runtime/router.mjs +9 -22
- package/preset/odai/runtime/router.mjs.map +1 -1
- package/preset/odai/runtime/routing-config.d.mts +11 -2
- package/preset/odai/runtime/routing-config.d.mts.map +1 -1
- package/preset/odai/runtime/routing-config.mjs +96 -86
- package/preset/odai/runtime/routing-config.mjs.map +1 -1
- package/preset/odai/runtime/routing-context.d.mts.map +1 -1
- package/preset/odai/runtime/routing-context.mjs +3 -24
- package/preset/odai/runtime/routing-context.mjs.map +1 -1
- package/preset/odai/runtime/runtime-config.d.mts +1 -1
- package/preset/odai/runtime/runtime-config.d.mts.map +1 -1
- package/preset/odai/runtime/runtime-support.d.mts.map +1 -1
- package/preset/odai/runtime/runtime-support.mjs +1 -3
- package/preset/odai/runtime/runtime-support.mjs.map +1 -1
- package/preset/odai/runtime/runtime-types.d.mts +1 -4
- package/preset/odai/runtime/runtime-types.d.mts.map +1 -1
- package/preset/odai/runtime/skill-bundle.d.mts +8 -2
- package/preset/odai/runtime/skill-bundle.d.mts.map +1 -1
- package/preset/odai/runtime/skill-bundle.mjs +56 -22
- package/preset/odai/runtime/skill-bundle.mjs.map +1 -1
- package/preset/odai/runtime/skill-evolution.d.mts.map +1 -1
- package/preset/odai/runtime/skill-evolution.mjs +15 -4
- package/preset/odai/runtime/skill-evolution.mjs.map +1 -1
- package/preset/odai/runtime/tool-runtime.d.mts +0 -1
- package/preset/odai/runtime/tool-runtime.d.mts.map +1 -1
- package/preset/odai/runtime/tool-runtime.mjs +17 -53
- package/preset/odai/runtime/tool-runtime.mjs.map +1 -1
- package/preset/odai/skills/odai/SKILL.md +31 -34
- package/preset/odai/skills/odai/assets/routing-roles/controller.md +4 -4
- package/preset/odai/skills/odai/assets/routing-roles/planner.md +2 -3
- package/preset/odai/skills/odai/assets/routing-roles/researcher.md +1 -1
- package/preset/odai/skills/odai/assets/routing-roles/reviewer.md +2 -2
- package/preset/odai/skills/odai/manifest.json +20 -5
- package/preset/odai/skills/odai/references/leverage.md +9 -12
- package/preset/odai/skills/odai/references/support.md +7 -13
- package/preset/odai/skills/odai/references/verification.md +1 -0
- package/preset/odai/skills/odai/scripts/build-routing.mjs +71 -30
- package/preset/odai/skills/odai/scripts/install-routing.mjs +18 -22
- package/preset/odai/skills/odai/scripts/run-role.mjs +8 -59
- package/preset/odai/skills/odai/scripts/verify-routing.mjs +3 -3
- package/preset/odai/runtime/route-card.d.mts +0 -42
- package/preset/odai/runtime/route-card.d.mts.map +0 -1
- package/preset/odai/runtime/route-card.mjs +0 -180
- package/preset/odai/runtime/route-card.mjs.map +0 -1
- package/preset/odai/skills/odai/assets/routing-roles/executor.md +0 -11
- package/preset/odai/skills/odai/scripts/run-routing.mjs +0 -1154
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# odai dsh agent
|
|
2
2
|
|
|
3
|
-
`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`:
|
|
3
|
+
`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 install does not activate global governance. In an interactive terminal, the command separately offers to add the same package's Control Center to the Web profile and performs that profile change only after confirmation.
|
|
4
4
|
|
|
5
5
|
The installed preset is self-contained:
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ $DSH_HOME/.agent-presets/odai/
|
|
|
13
13
|
.odai-agent.json
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The source composition preserves every capability row and setting from the `standard` agent surface in `@deepseek-ai/dsh@0.1.
|
|
16
|
+
The source composition preserves every capability row and setting from the `standard` agent surface in `@deepseek-ai/dsh@0.1.2-alpha.2`, then adds the scoped Odai runtime in default `auto` mode. For `0.1.1-rc.2`, the installer deterministically removes alpha.2-only goal-command and subagent-model rows and restores the rc.2 Web setting before hashing and publishing the managed preset. Release verification resolves each release's own Standard package path and compares the rendered composition against that exact source; a missing, added, reordered, or changed Standard row fails the probe. 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 evidence packet whose diff is newer than the last write and whose latest successful test follows that diff. 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 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.
|
|
17
17
|
|
|
18
18
|
The preset includes the same local long-term semantic memory runtime as the Plugin. Default `auto` mode performs no hidden model call: it automatically captures only high-confidence durable statements from the direct-human message authenticated by the latest open-turn session event, keeps ambiguous or conflicting candidates inert, and recalls only bounded active global/project records as untrusted historical context. Matching direct intent, or the compact capability gateway on a later step, exposes the controller-only `odai_memory` tool for inspection, search, confirmation, correction, physical forgetting, exact-phrase clearing, and `auto`/`off` mode changes. Recognized secrets, contact identifiers, health/crisis content, temporary instructions, hypotheses, quotes, and code are rejected; the current user and project authority always override memory. State lives at `$DSH_HOME/odai/memory/store.json`, outside `.agent-presets`, so install, update, and uninstall preserve it. An invalid or symlinked store fails closed. The matcher is not a replacement for protecting the underlying DSH session history from sensitive input.
|
|
19
19
|
|
|
@@ -31,7 +31,7 @@ With DSH already installed, run the single Agent package command below. The pack
|
|
|
31
31
|
npx odai-dsh-agent install
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
The installer checks `dsh -V`
|
|
34
|
+
The installer checks `dsh -V`; the `0.2.16` candidate accepts exactly `0.1.1-rc.2` and `0.1.2-alpha.2` and rejects every other developer-preview release. It records the detected version in the managed manifest and renders the Standard composition for that exact release. In an interactive terminal it then asks `同时把 Odai 控制中心安装到 DSH profile “web”?[Y/n]`; Enter or `y` installs it, while `n` leaves the profile unchanged. Non-interactive and `--json` installs never infer consent: automation can use `--with-control-center` or `--without-control-center` explicitly, with `--profile <name>` selecting a profile other than `web`.
|
|
35
35
|
|
|
36
36
|
`DSH_HOME` is honored. An explicit location can be supplied without changing the environment:
|
|
37
37
|
|
|
@@ -47,23 +47,36 @@ The installer copies through a mode-tightened staging directory and atomically p
|
|
|
47
47
|
|
|
48
48
|
DSH classifies this as a `trust: user` preset. User presets have the same privileges as shell access, so install only reviewed package versions; the installer repeats this trust notice in both plain and JSON output.
|
|
49
49
|
|
|
50
|
+
## Control Center
|
|
51
|
+
|
|
52
|
+
The optional profile entry ships inside `odai-dsh-agent`; it is not a third package. It adds one Chinese Control Center launcher to DSH Web with a real current-turn responsibility graph, session evidence timeline, structured event inspector, and routing controls for the four optional responsibilities. 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.
|
|
53
|
+
|
|
54
|
+
The main `install` prompt is the recommended entry. These lifecycle commands remain available for inspection, recovery, and automation:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
npx odai-dsh-agent control-center install [--profile web]
|
|
58
|
+
npx odai-dsh-agent control-center status [--profile web]
|
|
59
|
+
npx odai-dsh-agent control-center uninstall [--profile web]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
A Control Center profile change requires one normal DSH Web process restart. Removing it does not remove the Agent preset, routing configuration, or session evidence.
|
|
63
|
+
|
|
50
64
|
## Responsibility models
|
|
51
65
|
|
|
52
|
-
The Agent ships no researcher, planner,
|
|
66
|
+
The Agent ships no researcher, planner, reviewer, or frontend 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:
|
|
53
67
|
|
|
54
68
|
```text
|
|
55
69
|
证据调查用 provider-r/model-research,推理档 high。
|
|
56
70
|
规划用 provider-x/model-plan,推理档 high。
|
|
57
|
-
执行模型设为 provider-x/model-y。
|
|
58
71
|
验收改用 provider-z/model-review,推理档 max。
|
|
59
72
|
前端制作用 provider-f/model-frontend,输出上限 4096。
|
|
60
73
|
规划职责改成 child,前端职责保持 same-turn。
|
|
61
74
|
研究和验收职责改成 same-turn。
|
|
62
75
|
```
|
|
63
76
|
|
|
64
|
-
The controller calls `odai_routing_config` to persist that explicit choice. Researcher, planner, reviewer, and frontend each accept an explicit `same-turn` or `child` dispatch override;
|
|
77
|
+
The controller calls `odai_routing_config` to persist that explicit choice. Researcher, planner, reviewer, and frontend each accept an explicit `same-turn` or `child` dispatch override; implementation remains with the controller. 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 managed preset, so installer updates do not report them as drift. 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.
|
|
65
78
|
|
|
66
|
-
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
|
|
79
|
+
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. A generic subagent is not a responsibility route. A manual responsibility child must use an `odai-<responsibility>` label and cannot finish successfully without a matching actual-route receipt. Odai never chooses a model or price on the user's behalf.
|
|
67
80
|
|
|
68
81
|
## Controller output policy
|
|
69
82
|
|
|
@@ -87,7 +100,7 @@ A same-provider/model compaction inherits controller reasoning while keeping its
|
|
|
87
100
|
|
|
88
101
|
The default compaction-summary model is `inherit`, which preserves the conversation's current provider/model behavior. A user can explicitly set a separate target and optional reasoning effort in natural language, such as `压缩模型用 provider-x/model-summary,推理档 high`; `odai_compaction_config` persists those explicit values in `$DSH_HOME/odai/compaction.json`. Removing the target restores inheritance. Agent and Plugin share the store when both are deliberately present.
|
|
89
102
|
|
|
90
|
-
The target applies only to future `compaction` summary requests. It does not change the controller, researcher, planner,
|
|
103
|
+
The target applies only to future `compaction` summary requests. It does not change the controller, researcher, planner, reviewer, frontend, ordinary conversation, summary output budget, or cache-retention policy. An explicitly configured `reasoningEffort` overrides reasoning only for those summaries. When omitted, existing behavior remains: same-route summaries can inherit controller reasoning, while a cross-model target removes only reasoning proven by equality with the durable controller route and preserves a distinct preselected effort. Each configured target receives one provider-neutral integrity suffix that keeps current facts above superseded/rejected history, preserves continuation-critical opaque values exactly, and self-checks contradictions; duplicate Agent/Plugin runtime instances add it only once. Odai never chooses the provider, model, or reasoning effort on the user's behalf. An invalid store is reported by the tool while runtime requests inherit safely until `set` or `remove` repairs it. The configured stream is buffered until a valid terminal result. Partial failed chunks are discarded before one retry with the untouched inherited request; deterministic invalid persisted targets are backed up and exact-match removed, transient failures preserve them, and DSH retains original history until a complete summary lands.
|
|
91
104
|
|
|
92
105
|
## Skill sources
|
|
93
106
|
|
|
@@ -121,13 +134,13 @@ npx odai-dsh-agent uninstall
|
|
|
121
134
|
|
|
122
135
|
## Plugin versus Agent
|
|
123
136
|
|
|
124
|
-
|
|
137
|
+
Choose either package or install both when their scopes are useful:
|
|
125
138
|
|
|
126
139
|
- `odai-dsh-plugin`: profile-wide governance for every preset in that profile.
|
|
127
|
-
- `odai-dsh-agent`: selectable Odai governance for
|
|
128
|
-
- both: supported
|
|
140
|
+
- `odai-dsh-agent`: selectable Odai governance for sessions using this preset.
|
|
141
|
+
- both: supported even when users arrive at the combination independently; Plugin provides the single Control Center surface while the Agent preset remains selectable.
|
|
129
142
|
|
|
130
|
-
When both are
|
|
143
|
+
When both are present, a process-shared per-agent/per-turn skill snapshot keeps prompt governance and role contracts identical, the compatibility-safe evidence store deduplicates tool and route records, host RPC registration is reference-counted, and denials remain monotonic. Removing either package leaves the other package and shared routing/evidence stores usable. Neither package installs or changes the provider-neutral `odai-cli`.
|
|
131
144
|
|
|
132
145
|
## Development
|
|
133
146
|
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { promptForControlCenterInstall } from "../src/control-center-prompt.mjs";
|
|
3
|
+
import { inspectAgentControlCenter, installAgentControlCenter, uninstallAgentControlCenter, } from "../src/control-center-installer.mjs";
|
|
2
4
|
import { readDshVersion } from "../src/dsh-version.mjs";
|
|
3
5
|
import { inspectAgentInstallation, installAgentPreset, SUPPORTED_DSH_VERSIONS, uninstallAgentPreset, } from "../src/installer.mjs";
|
|
4
6
|
const HELP = `Usage: odai-dsh-agent <command> [options]
|
|
5
7
|
|
|
6
8
|
Commands:
|
|
7
|
-
install
|
|
8
|
-
status
|
|
9
|
-
uninstall
|
|
9
|
+
install Install or update the managed Odai preset
|
|
10
|
+
status Inspect the managed Odai preset
|
|
11
|
+
uninstall Remove the preset when its managed files are unchanged
|
|
12
|
+
control-center install Add the Agent package's Control Center to a DSH profile
|
|
13
|
+
control-center status Inspect the Agent Control Center profile state
|
|
14
|
+
control-center uninstall Remove only the Agent Control Center profile state
|
|
10
15
|
|
|
11
16
|
Options:
|
|
12
17
|
--dsh-home <path> Override DSH_HOME
|
|
13
|
-
--
|
|
18
|
+
--profile <name> Control Center profile (default: web)
|
|
19
|
+
--with-control-center Install Control Center without prompting
|
|
20
|
+
--without-control-center Skip the interactive Control Center prompt
|
|
21
|
+
--json Print JSON; never prompts
|
|
14
22
|
--yes Confirm DSH is stopped; active-process verification still applies
|
|
15
23
|
-h, --help Show this help
|
|
16
24
|
`;
|
|
@@ -21,11 +29,27 @@ try {
|
|
|
21
29
|
}
|
|
22
30
|
else if (args.command === "install") {
|
|
23
31
|
const dshVersion = assertDshVersion();
|
|
24
|
-
|
|
32
|
+
const preset = await installAgentPreset({
|
|
25
33
|
dshHome: args.dshHome,
|
|
26
34
|
dshVersion,
|
|
27
35
|
confirmDshStopped: args.yes,
|
|
28
|
-
})
|
|
36
|
+
});
|
|
37
|
+
if (args.json) {
|
|
38
|
+
const controlCenter = args.controlCenter === true
|
|
39
|
+
? await installAgentControlCenter({ dshHome: args.dshHome, profile: args.profile })
|
|
40
|
+
: undefined;
|
|
41
|
+
process.stdout.write(`${JSON.stringify({
|
|
42
|
+
...preset,
|
|
43
|
+
...(controlCenter ? { controlCenter } : {}),
|
|
44
|
+
}, null, 2)}\n`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
print(preset, false);
|
|
48
|
+
const installControlCenter = await shouldInstallControlCenter(args);
|
|
49
|
+
if (installControlCenter) {
|
|
50
|
+
print(await installAgentControlCenter({ dshHome: args.dshHome, profile: args.profile }), false);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
29
53
|
}
|
|
30
54
|
else if (args.command === "status") {
|
|
31
55
|
const result = await inspectAgentInstallation({ dshHome: args.dshHome });
|
|
@@ -39,6 +63,18 @@ try {
|
|
|
39
63
|
confirmDshStopped: args.yes,
|
|
40
64
|
}), args.json);
|
|
41
65
|
}
|
|
66
|
+
else if (args.command === "control-center" && args.controlCenterCommand === "install") {
|
|
67
|
+
print(await installAgentControlCenter({ dshHome: args.dshHome, profile: args.profile }), args.json);
|
|
68
|
+
}
|
|
69
|
+
else if (args.command === "control-center" && args.controlCenterCommand === "status") {
|
|
70
|
+
const result = await inspectAgentControlCenter({ dshHome: args.dshHome, profile: args.profile });
|
|
71
|
+
print(result, args.json);
|
|
72
|
+
if (result.status === "drifted")
|
|
73
|
+
process.exitCode = 2;
|
|
74
|
+
}
|
|
75
|
+
else if (args.command === "control-center" && args.controlCenterCommand === "uninstall") {
|
|
76
|
+
print(await uninstallAgentControlCenter({ dshHome: args.dshHome, profile: args.profile }), args.json);
|
|
77
|
+
}
|
|
42
78
|
else {
|
|
43
79
|
throw new Error("a command is required\n\n" + HELP);
|
|
44
80
|
}
|
|
@@ -47,6 +83,27 @@ catch (error) {
|
|
|
47
83
|
process.stderr.write(`odai-dsh-agent: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
48
84
|
process.exitCode = 1;
|
|
49
85
|
}
|
|
86
|
+
async function shouldInstallControlCenter(args) {
|
|
87
|
+
if (args.controlCenter !== undefined)
|
|
88
|
+
return args.controlCenter;
|
|
89
|
+
if (args.json || !process.stdin.isTTY || !process.stdout.isTTY)
|
|
90
|
+
return false;
|
|
91
|
+
const current = await inspectAgentControlCenter({ dshHome: args.dshHome, profile: args.profile });
|
|
92
|
+
if (current.status === "installed") {
|
|
93
|
+
process.stdout.write(`Control Center 已安装:${current.target}\n`);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (current.status === "drifted") {
|
|
97
|
+
process.stdout.write(`Control Center profile 状态存在漂移,已跳过:${current.target}\n`);
|
|
98
|
+
for (const issue of current.issues)
|
|
99
|
+
process.stdout.write(`- ${issue}\n`);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const accepted = await promptForControlCenterInstall(process.stdin, process.stdout, args.profile ?? "web");
|
|
103
|
+
if (!accepted)
|
|
104
|
+
process.stdout.write("已跳过 Control Center;稍后可运行 odai-dsh-agent control-center install。\n");
|
|
105
|
+
return accepted;
|
|
106
|
+
}
|
|
50
107
|
function assertDshVersion() {
|
|
51
108
|
const dsh = process.env.DSH_BIN ?? "dsh";
|
|
52
109
|
let actual;
|
|
@@ -71,16 +128,40 @@ function parseArgs(argv) {
|
|
|
71
128
|
parsed.json = true;
|
|
72
129
|
else if (arg === "--yes")
|
|
73
130
|
parsed.yes = true;
|
|
131
|
+
else if (arg === "--with-control-center") {
|
|
132
|
+
if (parsed.controlCenter === false)
|
|
133
|
+
throw new Error("--with-control-center conflicts with --without-control-center");
|
|
134
|
+
parsed.controlCenter = true;
|
|
135
|
+
}
|
|
136
|
+
else if (arg === "--without-control-center") {
|
|
137
|
+
if (parsed.controlCenter === true)
|
|
138
|
+
throw new Error("--without-control-center conflicts with --with-control-center");
|
|
139
|
+
parsed.controlCenter = false;
|
|
140
|
+
}
|
|
74
141
|
else if (arg === "--dsh-home")
|
|
75
142
|
parsed.dshHome = argv[++index];
|
|
76
|
-
else if (
|
|
143
|
+
else if (arg === "--profile")
|
|
144
|
+
parsed.profile = argv[++index];
|
|
145
|
+
else if (!parsed.command && (arg === "install" || arg === "status" || arg === "uninstall" || arg === "control-center"))
|
|
77
146
|
parsed.command = arg;
|
|
147
|
+
else if (parsed.command === "control-center" && !parsed.controlCenterCommand
|
|
148
|
+
&& (arg === "install" || arg === "status" || arg === "uninstall"))
|
|
149
|
+
parsed.controlCenterCommand = arg;
|
|
78
150
|
else
|
|
79
151
|
throw new Error(`unknown argument: ${arg}`);
|
|
80
152
|
}
|
|
81
153
|
if (parsed.dshHome !== undefined && parsed.dshHome.trim() === "") {
|
|
82
154
|
throw new Error("--dsh-home requires a non-empty path");
|
|
83
155
|
}
|
|
156
|
+
if (parsed.profile !== undefined && parsed.profile.trim() === "") {
|
|
157
|
+
throw new Error("--profile requires a non-empty name");
|
|
158
|
+
}
|
|
159
|
+
if (parsed.command === "control-center" && !parsed.controlCenterCommand && !parsed.help) {
|
|
160
|
+
throw new Error("control-center requires install, status, or uninstall");
|
|
161
|
+
}
|
|
162
|
+
if (parsed.controlCenter !== undefined && parsed.command !== "install" && !parsed.help) {
|
|
163
|
+
throw new Error("--with-control-center and --without-control-center are valid only with install");
|
|
164
|
+
}
|
|
84
165
|
return parsed;
|
|
85
166
|
}
|
|
86
167
|
function print(result, json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odai-dsh-agent.mjs","sourceRoot":"","sources":["../../bin/odai-dsh-agent.mts"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"odai-dsh-agent.mjs","sourceRoot":"","sources":["../../bin/odai-dsh-agent.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ExecFileSyncOptionsWithStringEncoding } from "node:child_process";
|
|
2
|
+
type CommandExecutor = (command: string, args: string[], options: ExecFileSyncOptionsWithStringEncoding) => string;
|
|
3
|
+
export interface AgentControlCenterOptions {
|
|
4
|
+
dshHome?: string;
|
|
5
|
+
profile?: string;
|
|
6
|
+
packageSpec?: string;
|
|
7
|
+
dshBin?: string;
|
|
8
|
+
platform?: NodeJS.Platform;
|
|
9
|
+
execute?: CommandExecutor;
|
|
10
|
+
}
|
|
11
|
+
export interface AgentControlCenterInspection {
|
|
12
|
+
status: "absent" | "installed" | "drifted";
|
|
13
|
+
issues: string[];
|
|
14
|
+
dshHome: string;
|
|
15
|
+
profile: string;
|
|
16
|
+
target: string;
|
|
17
|
+
dependency?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function inspectAgentControlCenter(options?: AgentControlCenterOptions): Promise<AgentControlCenterInspection>;
|
|
20
|
+
export declare function installAgentControlCenter(options?: AgentControlCenterOptions): Promise<Readonly<{
|
|
21
|
+
operation: "installed" | "unchanged";
|
|
22
|
+
target: string;
|
|
23
|
+
profile: string;
|
|
24
|
+
dependency: string;
|
|
25
|
+
}>>;
|
|
26
|
+
export declare function uninstallAgentControlCenter(options?: AgentControlCenterOptions): Promise<Readonly<{
|
|
27
|
+
operation: "uninstalled" | "absent";
|
|
28
|
+
target: string;
|
|
29
|
+
profile: string;
|
|
30
|
+
}>>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=control-center-installer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-installer.d.mts","sourceRoot":"","sources":["../../src/control-center-installer.mts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,oBAAoB,CAAC;AAiBhF,KAAK,eAAe,GAAG,CACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,qCAAqC,KAC3C,MAAM,CAAC;AAEZ,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0CD,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,4BAA4B,CAAC,CAoBvC;AAmBD,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,QAAQ,CAAC;IAAE,SAAS,EAAE,WAAW,GAAG,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAelH;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,QAAQ,CAAC;IAAE,SAAS,EAAE,aAAa,GAAG,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAY7F"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve, sep } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { resolveDshHome } from "./installer.mjs";
|
|
6
|
+
const moduleDirectory = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const packageRoot = resolve(moduleDirectory, moduleDirectory.endsWith(`${sep}build${sep}src`) ? "../.." : "..");
|
|
8
|
+
const parsedMetadata = JSON.parse(await readFile(resolve(packageRoot, "package.json"), "utf8"));
|
|
9
|
+
if (!isRecord(parsedMetadata) || typeof parsedMetadata.name !== "string" || typeof parsedMetadata.version !== "string") {
|
|
10
|
+
throw new Error("odai-dsh-agent package metadata is invalid for Control Center management");
|
|
11
|
+
}
|
|
12
|
+
const packageMetadata = { name: parsedMetadata.name, version: parsedMetadata.version };
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function assertProfile(value) {
|
|
17
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(value)) {
|
|
18
|
+
throw new TypeError("profile must contain only letters, digits, dots, underscores, or hyphens");
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
async function profileMetadata(path) {
|
|
23
|
+
let source;
|
|
24
|
+
try {
|
|
25
|
+
source = await readFile(path, "utf8");
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (isRecord(error) && error.code === "ENOENT")
|
|
29
|
+
return undefined;
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
const parsed = JSON.parse(source);
|
|
33
|
+
if (!isRecord(parsed))
|
|
34
|
+
throw new TypeError(`DSH profile package metadata ${path} must be an object`);
|
|
35
|
+
const dependencies = isRecord(parsed.dependencies)
|
|
36
|
+
? Object.fromEntries(Object.entries(parsed.dependencies).filter((entry) => typeof entry[1] === "string"))
|
|
37
|
+
: undefined;
|
|
38
|
+
const dsh = isRecord(parsed.dsh) && isRecord(parsed.dsh.profile)
|
|
39
|
+
? { profile: { bundles: Array.isArray(parsed.dsh.profile.bundles)
|
|
40
|
+
? parsed.dsh.profile.bundles.filter((entry) => typeof entry === "string")
|
|
41
|
+
: undefined } }
|
|
42
|
+
: undefined;
|
|
43
|
+
return { dependencies, dsh };
|
|
44
|
+
}
|
|
45
|
+
export async function inspectAgentControlCenter(options = {}) {
|
|
46
|
+
const dshHome = resolveDshHome(options.dshHome);
|
|
47
|
+
const profile = assertProfile(options.profile ?? "web");
|
|
48
|
+
const target = resolve(dshHome, "profiles", profile);
|
|
49
|
+
const metadata = await profileMetadata(resolve(target, "package.json"));
|
|
50
|
+
if (!metadata)
|
|
51
|
+
return { status: "absent", issues: [], dshHome, profile, target };
|
|
52
|
+
const dependency = metadata.dependencies?.[packageMetadata.name];
|
|
53
|
+
const bundled = metadata.dsh?.profile?.bundles?.includes(packageMetadata.name) === true;
|
|
54
|
+
if (!dependency && !bundled)
|
|
55
|
+
return { status: "absent", issues: [], dshHome, profile, target };
|
|
56
|
+
const issues = [];
|
|
57
|
+
if (!dependency)
|
|
58
|
+
issues.push(`missing ${packageMetadata.name} profile dependency`);
|
|
59
|
+
if (!bundled)
|
|
60
|
+
issues.push(`missing ${packageMetadata.name} profile bundle entry`);
|
|
61
|
+
return {
|
|
62
|
+
status: issues.length === 0 ? "installed" : "drifted",
|
|
63
|
+
issues,
|
|
64
|
+
dshHome,
|
|
65
|
+
profile,
|
|
66
|
+
target,
|
|
67
|
+
...(dependency ? { dependency } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function runPluginCommand(action, operand, options) {
|
|
71
|
+
const dsh = options.dshBin ?? process.env.DSH_BIN ?? "dsh";
|
|
72
|
+
const platform = options.platform ?? process.platform;
|
|
73
|
+
const command = platform === "win32" && dsh === "dsh" ? "dsh.cmd" : dsh;
|
|
74
|
+
const execute = options.execute ?? execFileSync;
|
|
75
|
+
const processOptions = {
|
|
76
|
+
encoding: "utf8",
|
|
77
|
+
env: { ...process.env, DSH_HOME: resolveDshHome(options.dshHome) },
|
|
78
|
+
...(platform === "win32" ? { shell: true } : {}),
|
|
79
|
+
};
|
|
80
|
+
execute(command, ["plugin", "--profile", assertProfile(options.profile ?? "web"), action, operand], processOptions);
|
|
81
|
+
}
|
|
82
|
+
export async function installAgentControlCenter(options = {}) {
|
|
83
|
+
const current = await inspectAgentControlCenter(options);
|
|
84
|
+
if (current.status === "drifted") {
|
|
85
|
+
throw new Error(`refusing to replace drifted Control Center profile state at ${current.target}: ${current.issues.join("; ")}`);
|
|
86
|
+
}
|
|
87
|
+
if (current.status === "installed") {
|
|
88
|
+
return Object.freeze({ operation: "unchanged", target: current.target, profile: current.profile, dependency: current.dependency ?? "" });
|
|
89
|
+
}
|
|
90
|
+
const packageSpec = options.packageSpec ?? `${packageMetadata.name}@${packageMetadata.version}`;
|
|
91
|
+
runPluginCommand("add", packageSpec, options);
|
|
92
|
+
const installed = await inspectAgentControlCenter(options);
|
|
93
|
+
if (installed.status !== "installed" || !installed.dependency) {
|
|
94
|
+
throw new Error(`DSH plugin manager did not install the Agent Control Center completely: ${installed.issues.join("; ") || installed.status}`);
|
|
95
|
+
}
|
|
96
|
+
return Object.freeze({ operation: "installed", target: installed.target, profile: installed.profile, dependency: installed.dependency });
|
|
97
|
+
}
|
|
98
|
+
export async function uninstallAgentControlCenter(options = {}) {
|
|
99
|
+
const current = await inspectAgentControlCenter(options);
|
|
100
|
+
if (current.status === "absent")
|
|
101
|
+
return Object.freeze({ operation: "absent", target: current.target, profile: current.profile });
|
|
102
|
+
if (current.status === "drifted") {
|
|
103
|
+
throw new Error(`refusing to remove drifted Control Center profile state at ${current.target}: ${current.issues.join("; ")}`);
|
|
104
|
+
}
|
|
105
|
+
runPluginCommand("remove", packageMetadata.name, options);
|
|
106
|
+
const removed = await inspectAgentControlCenter(options);
|
|
107
|
+
if (removed.status !== "absent") {
|
|
108
|
+
throw new Error(`DSH plugin manager did not remove the Agent Control Center completely: ${removed.issues.join("; ") || removed.status}`);
|
|
109
|
+
}
|
|
110
|
+
return Object.freeze({ operation: "uninstalled", target: removed.target, profile: removed.profile });
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=control-center-installer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-installer.mjs","sourceRoot":"","sources":["../../src/control-center-installer.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
export declare function acceptsControlCenterInstall(answer: string): boolean;
|
|
3
|
+
export declare function promptForControlCenterInstall(input?: Readable, output?: Writable, profile?: string): Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=control-center-prompt.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-prompt.d.mts","sourceRoot":"","sources":["../../src/control-center-prompt.mts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAsB,6BAA6B,CACjD,KAAK,GAAE,QAAwB,EAC/B,MAAM,GAAE,QAAyB,EACjC,OAAO,SAAQ,GACd,OAAO,CAAC,OAAO,CAAC,CAQlB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
export function acceptsControlCenterInstall(answer) {
|
|
3
|
+
return /^(?:|y|yes)$/iu.test(answer.trim());
|
|
4
|
+
}
|
|
5
|
+
export async function promptForControlCenterInstall(input = process.stdin, output = process.stdout, profile = "web") {
|
|
6
|
+
const readline = createInterface({ input, output });
|
|
7
|
+
try {
|
|
8
|
+
const answer = await readline.question(`同时把 Odai 控制中心安装到 DSH profile “${profile}”?[Y/n] `);
|
|
9
|
+
return acceptsControlCenterInstall(answer);
|
|
10
|
+
}
|
|
11
|
+
finally {
|
|
12
|
+
readline.close();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=control-center-prompt.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-prompt.mjs","sourceRoot":"","sources":["../../src/control-center-prompt.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,UAAU,2BAA2B,CAAC,MAAc;IACxD,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,KAAK,GAAa,OAAO,CAAC,KAAK,EAC/B,MAAM,GAAa,OAAO,CAAC,MAAM,EACjC,OAAO,GAAG,KAAK;IAEf,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,OAAO,UAAU,CAAC,CAAC;QAC3F,OAAO,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -9,8 +9,10 @@ export interface AgentInstallerOptions {
|
|
|
9
9
|
}
|
|
10
10
|
export declare const DEFAULT_PRESET_ID = "odai";
|
|
11
11
|
export declare const MANIFEST_FILE = ".odai-agent.json";
|
|
12
|
+
export declare const inject: string[];
|
|
13
|
+
export declare function apply(ctx: unknown, rawConfig?: unknown): Promise<void>;
|
|
12
14
|
export declare const SUPPORTED_DSH_VERSIONS: readonly string[];
|
|
13
|
-
export declare const SUPPORTED_DSH_VERSION = "0.1.
|
|
15
|
+
export declare const SUPPORTED_DSH_VERSION = "0.1.2-alpha.2";
|
|
14
16
|
export declare function renderAgentCompositionForDsh(composition: string, dshVersion?: string): string;
|
|
15
17
|
export declare function resolveDshHome(configured?: string, env?: NodeJS.ProcessEnv): string;
|
|
16
18
|
export declare function inspectAgentInstallation(options?: AgentInstallerOptions): Promise<Readonly<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.mts","sourceRoot":"","sources":["../../src/installer.mts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,wCAAwC,CAAC;AAQhD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAgCD,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,aAAa,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"installer.d.mts","sourceRoot":"","sources":["../../src/installer.mts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,wCAAwC,CAAC;AAQhD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAgCD,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAKhD,eAAO,MAAM,MAAM,UAAwB,CAAC;AAE5C,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,GAAE,OAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhF;AAmBD,eAAO,MAAM,sBAAsB,mBAElC,CAAC;AAWF,eAAO,MAAM,qBAAqB,kBAAqB,CAAC;AAqBxD,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,SAAwB,GAAG,MAAM,CAiC5G;AAED,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAShG;AAED,wBAAsB,wBAAwB,CAAC,OAAO,GAAE,qBAA0B;YAtIxE,QAAQ,GAAG,WAAW,GAAG,SAAS;YAClC,MAAM,EAAE;cACN,MAAM;iBACH,MAAM;;;;IAyIpB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,qBAA0B;;;;;;;;;;IAsF3E;AAED,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B;;;;;;;;;IAyB7E"}
|
package/build/src/installer.mjs
CHANGED
|
@@ -17,6 +17,15 @@ export const DEFAULT_PRESET_ID = "odai";
|
|
|
17
17
|
export const MANIFEST_FILE = ".odai-agent.json";
|
|
18
18
|
const moduleDirectory = dirname(fileURLToPath(import.meta.url));
|
|
19
19
|
const packageRoot = resolve(moduleDirectory, moduleDirectory.endsWith(`${sep}build${sep}src`) ? "../.." : "..");
|
|
20
|
+
export const inject = ["connection", "llm"];
|
|
21
|
+
export async function apply(ctx, rawConfig = {}) {
|
|
22
|
+
const moduleUrl = pathToFileURL(resolve(packageRoot, "preset/odai/runtime/control-center-host.mjs")).href;
|
|
23
|
+
const host = await import(moduleUrl);
|
|
24
|
+
if (!isRecord(host) || typeof host.apply !== "function") {
|
|
25
|
+
throw new Error("odai-dsh-agent Control Center host artifact is invalid");
|
|
26
|
+
}
|
|
27
|
+
await host.apply(ctx, rawConfig);
|
|
28
|
+
}
|
|
20
29
|
const defaultSourceRoot = resolve(packageRoot, "preset/odai");
|
|
21
30
|
const parsedPackageMetadata = JSON.parse(await readFile(resolve(packageRoot, "package.json"), "utf8"));
|
|
22
31
|
if (!isRecord(parsedPackageMetadata) || typeof parsedPackageMetadata.name !== "string"
|
|
@@ -37,9 +46,12 @@ export const SUPPORTED_DSH_VERSIONS = Object.freeze(peerRange.split(/\s*\|\|\s*/
|
|
|
37
46
|
if (SUPPORTED_DSH_VERSIONS.length === 0 || SUPPORTED_DSH_VERSIONS.some((version) => !DSH_VERSION_PATTERN.test(version))) {
|
|
38
47
|
throw new Error("odai-dsh-agent peer dependency must list exact supported DSH versions");
|
|
39
48
|
}
|
|
40
|
-
const SOURCE_DSH_VERSION = "0.1.
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
const SOURCE_DSH_VERSION = "0.1.2-alpha.2";
|
|
50
|
+
const LEGACY_DSH_VERSION = "0.1.1-rc.2";
|
|
51
|
+
if (!SUPPORTED_DSH_VERSIONS.includes(SOURCE_DSH_VERSION)
|
|
52
|
+
|| !SUPPORTED_DSH_VERSIONS.includes(LEGACY_DSH_VERSION)
|
|
53
|
+
|| SUPPORTED_DSH_VERSIONS.length !== 2) {
|
|
54
|
+
throw new Error(`Odai Agent peer must target exactly ${LEGACY_DSH_VERSION} and source composition ${SOURCE_DSH_VERSION}`);
|
|
43
55
|
}
|
|
44
56
|
export const SUPPORTED_DSH_VERSION = SOURCE_DSH_VERSION;
|
|
45
57
|
const requiredFiles = Object.freeze([
|
|
@@ -56,6 +68,11 @@ const requiredFiles = Object.freeze([
|
|
|
56
68
|
"skills/odai/SKILL.md",
|
|
57
69
|
"skills/odai/manifest.json",
|
|
58
70
|
]);
|
|
71
|
+
function replaceRequired(value, oldString, newString, label) {
|
|
72
|
+
if (!value.includes(oldString))
|
|
73
|
+
throw new Error(`agent source composition is missing ${label}`);
|
|
74
|
+
return value.replace(oldString, newString);
|
|
75
|
+
}
|
|
59
76
|
export function renderAgentCompositionForDsh(composition, dshVersion = SUPPORTED_DSH_VERSION) {
|
|
60
77
|
if (typeof composition !== "string" || composition.trim() === "") {
|
|
61
78
|
throw new TypeError("agent composition must be a non-empty string");
|
|
@@ -63,7 +80,32 @@ export function renderAgentCompositionForDsh(composition, dshVersion = SUPPORTED
|
|
|
63
80
|
if (!SUPPORTED_DSH_VERSIONS.includes(dshVersion)) {
|
|
64
81
|
throw new Error(`unsupported DSH version ${dshVersion || "<empty>"}; expected one of ${SUPPORTED_DSH_VERSIONS.join(", ")}`);
|
|
65
82
|
}
|
|
66
|
-
|
|
83
|
+
let rendered = composition.replace(/\r\n/gu, "\n");
|
|
84
|
+
if (dshVersion === SOURCE_DSH_VERSION)
|
|
85
|
+
return rendered;
|
|
86
|
+
rendered = replaceRequired(rendered, [
|
|
87
|
+
"# The goal service and session driver stay on the host plane, where the Gateway",
|
|
88
|
+
"# can resolve them. The human command and model-facing tool register into this",
|
|
89
|
+
"# preset's scoped layers.",
|
|
90
|
+
"- id: command-goal",
|
|
91
|
+
" name: '@deepseek-ai/dsh-command-goal'",
|
|
92
|
+
].join("\n") + "\n\n", [
|
|
93
|
+
"# Only the model-facing tool. The goal SERVICE, its session driver, and the",
|
|
94
|
+
"# `/goal` command stay on the host plane: the Gateway serves the goal domain as",
|
|
95
|
+
"# Remote endpoints whose receiver comes from a generated descriptor, so it",
|
|
96
|
+
"# resolves `goals` on the host and an entry-local realm here would hide it. The",
|
|
97
|
+
"# registry is keyed by session anyway, so one host instance serves every",
|
|
98
|
+
"# session. What a preset chooses is whether its agent can call the goal tool.",
|
|
99
|
+
].join("\n") + "\n", "alpha.2 goal command block");
|
|
100
|
+
rendered = replaceRequired(rendered, " modelSelectionSettings: true\n", "", "alpha.2 spawn model selection setting");
|
|
101
|
+
rendered = replaceRequired(rendered, [
|
|
102
|
+
" # Fork omits model selection so provider/model stay equal to the parent and",
|
|
103
|
+
" # the inherited history remains eligible for KV Cache reuse. This preset",
|
|
104
|
+
" # keeps fork continuable and accepts its child-scoped `report` additions invalidating",
|
|
105
|
+
" # that prefix; issue #2124 tracks cache-preserving continuable fork.",
|
|
106
|
+
].join("\n") + "\n", "", "alpha.2 fork cache guidance");
|
|
107
|
+
rendered = replaceRequired(rendered, " fetch: true\n", " fetch: false\n", "alpha.2 web fetch setting");
|
|
108
|
+
return rendered;
|
|
67
109
|
}
|
|
68
110
|
export function resolveDshHome(configured, env = process.env) {
|
|
69
111
|
const value = configured ?? env.DSH_HOME ?? resolve(homedir(), ".dsh");
|