super-dsh 0.1.3 → 0.1.4
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 +9 -8
- package/agent-agy/cordis.patch.yml +8 -4
- package/agent-agy/dist/agent-preset-agy.d.ts +23 -43
- package/agent-agy/dist/agent-preset-agy.js +29 -166
- package/agent-agy/dist/agent.d.ts +2 -1
- package/agent-agy/dist/agent.js +3 -2
- package/agent-agy/dist/agy-sessions.d.ts +2 -1
- package/agent-agy/dist/agy-sessions.js +2 -11
- package/agent-agy/dist/index.js +13 -12
- package/agent-agy/dist/world-plugin.d.ts +2 -1
- package/agent-agy/dist/world-plugin.js +16 -21
- package/agent-agy/package.json +6 -6
- package/agent-claude/cordis.patch.yml +8 -4
- package/agent-claude/dist/agent-preset-claude.js +29 -166
- package/agent-claude/dist/agent.js +10 -10
- package/agent-claude/dist/claude-client.js +22 -3
- package/agent-claude/dist/claude-home.js +0 -8
- package/agent-claude/dist/index.js +12 -15
- package/agent-claude/dist/session-map.js +2 -5
- package/agent-claude/dist/world-plugin.js +3 -3
- package/agent-claude/package.json +9 -9
- package/agent-codex/README.md +8 -8
- package/agent-codex/cordis.patch.yml +9 -5
- package/agent-codex/dist/agent-preset-codex.js +29 -168
- package/agent-codex/dist/agent.js +17 -12
- package/agent-codex/dist/codex-store.js +0 -9
- package/agent-codex/dist/index.js +13 -16
- package/agent-codex/dist/session-map.js +2 -5
- package/agent-codex/dist/world-plugin.js +15 -20
- package/agent-codex/package.json +14 -11
- package/agent-hermes/README.md +9 -8
- package/agent-hermes/cordis.patch.yml +8 -4
- package/agent-hermes/dist/agent-preset-hermes.js +29 -168
- package/agent-hermes/dist/agent.js +33 -19
- package/agent-hermes/dist/hermes-client.js +5 -5
- package/agent-hermes/dist/hermes-store.js +2 -11
- package/agent-hermes/dist/index.js +13 -12
- package/agent-hermes/dist/world-plugin.js +16 -21
- package/agent-hermes/package.json +14 -11
- package/agent-omp/README.md +2 -2
- package/agent-omp/cordis.patch.yml +12 -7
- package/agent-omp/dist/agent-preset-omp.js +30 -169
- package/agent-omp/dist/agent.js +13 -5
- package/agent-omp/dist/index.js +12 -22
- package/agent-omp/dist/mobile/gesture.js +2 -2
- package/agent-omp/dist/mobile/zoom-guard.js +4 -4
- package/agent-omp/dist/mobile-boot.js +2 -2
- package/agent-omp/dist/omp-cli.js +1 -1
- package/agent-omp/dist/omp-disk-discovery.js +1 -1
- package/agent-omp/dist/protocol.js +1 -1
- package/agent-omp/dist/sidecar-client.js +1 -1
- package/agent-omp/dist/world-plugin.js +22 -19
- package/agent-omp/package.json +18 -14
- package/agent-omp/sidecar/main.ts +2 -2
- package/agent-pi/README.md +5 -5
- package/agent-pi/cordis.patch.yml +8 -4
- package/agent-pi/dist/agent-preset-pi.js +29 -166
- package/agent-pi/dist/agent.js +18 -12
- package/agent-pi/dist/index.js +14 -16
- package/agent-pi/dist/pi-home.js +2 -12
- package/agent-pi/dist/world-plugin.js +16 -21
- package/agent-pi/package.json +14 -11
- package/cordis.patch.yml +31 -21
- package/package.json +30 -38
- package/{agent-hub → superd-hub}/cordis.patch.yml +3 -3
- package/{agent-hub → superd-hub}/dist/carrier.d.ts +9 -3
- package/{agent-hub → superd-hub}/dist/carrier.js +29 -3
- package/{agent-hub → superd-hub}/dist/gateway.d.ts +2 -2
- package/{agent-hub → superd-hub}/dist/gateway.js +1 -1
- package/{agent-hub → superd-hub}/dist/index.d.ts +5 -3
- package/{agent-hub → superd-hub}/dist/index.js +5 -3
- package/{agent-hub → superd-hub}/dist/roster.d.ts +2 -2
- package/{agent-hub → superd-hub}/dist/rpc.js +1 -1
- package/{agent-hub → superd-hub}/dist/spawn-world.d.ts +27 -6
- package/superd-hub/dist/spawn-world.js +277 -0
- package/superd-hub/dist/system-head.d.ts +69 -0
- package/superd-hub/dist/system-head.js +194 -0
- package/superd-hub/dist/web-trust.d.ts +112 -0
- package/superd-hub/dist/web-trust.js +126 -0
- package/{agent-hub → superd-hub}/dist/world-entry.d.ts +2 -2
- package/{agent-hub → superd-hub}/dist/world-entry.js +4 -4
- package/{agent-hub → superd-hub}/dist/world-host.d.ts +1 -1
- package/{agent-hub → superd-hub}/dist/world-join.d.ts +2 -1
- package/{agent-hub → superd-hub}/dist/world-join.js +16 -21
- package/{agent-hub → superd-hub}/dist/world-mount.d.ts +14 -6
- package/{agent-hub → superd-hub}/dist/world-mount.js +28 -7
- package/{agent-hub → superd-hub}/dist/world-mux.d.ts +21 -6
- package/superd-hub/dist/world-mux.js +392 -0
- package/{agent-hub → superd-hub}/dist/world-provision.d.ts +20 -4
- package/superd-hub/dist/world-provision.js +196 -0
- package/{agent-hub → superd-hub}/dist/world-web-server.js +7 -1
- package/{agent-hub → superd-hub}/package.json +9 -16
- package/agent-hub/dist/spawn-world.js +0 -72
- package/agent-hub/dist/world-mux.js +0 -224
- package/agent-hub/dist/world-provision.js +0 -122
- package/agent-hub/lib/client/index.js +0 -242
- package/client/index.js +0 -242
- /package/{agent-hub → superd-hub}/dist/agent-roster.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/agent-roster.js +0 -0
- /package/{agent-hub → superd-hub}/dist/client-shim.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/client-shim.js +0 -0
- /package/{agent-hub → superd-hub}/dist/envelope.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/envelope.js +0 -0
- /package/{agent-hub → superd-hub}/dist/index-pass.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/index-pass.js +0 -0
- /package/{agent-hub → superd-hub}/dist/labels.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/labels.js +0 -0
- /package/{agent-hub → superd-hub}/dist/ownership.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/ownership.js +0 -0
- /package/{agent-hub → superd-hub}/dist/roster.js +0 -0
- /package/{agent-hub → superd-hub}/dist/rpc.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/targets.d.ts +0 -0
- /package/{agent-hub → superd-hub}/dist/targets.js +0 -0
- /package/{agent-hub → superd-hub}/dist/world-host.js +0 -0
- /package/{agent-hub → superd-hub}/dist/world-web-server.d.ts +0 -0
|
@@ -1,171 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
return useValue ? value : void 0;
|
|
7
|
-
};
|
|
8
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
-
var _, done = false;
|
|
14
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
-
var context = {};
|
|
16
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
-
if (kind === "accessor") {
|
|
21
|
-
if (result === void 0) continue;
|
|
22
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
-
}
|
|
27
|
-
else if (_ = accept(result)) {
|
|
28
|
-
if (kind === "field") initializers.unshift(_);
|
|
29
|
-
else descriptor[key] = _;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
-
done = true;
|
|
34
|
-
};
|
|
35
|
-
import { Remote, RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
36
|
-
const HERMES_PRESET = Object.freeze({
|
|
37
|
-
id: "hermes",
|
|
38
|
-
trust: "system",
|
|
39
|
-
path: "",
|
|
1
|
+
export const HERMES_PRESET_ID = "hermes";
|
|
2
|
+
/** The single fixed Hermes preset: mounting it composes nothing. */
|
|
3
|
+
export const HERMES_PRESET = Object.freeze({
|
|
4
|
+
id: HERMES_PRESET_ID,
|
|
40
5
|
name: "Hermes",
|
|
41
6
|
description: "Hermes agent via the agent-hermes adapter",
|
|
7
|
+
plugins: Object.freeze([]),
|
|
42
8
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
_remoteRead_decorators = [Remote("read")];
|
|
68
|
-
_remoteCopy_decorators = [Remote("copy")];
|
|
69
|
-
_remoteDelete_decorators = [Remote("deletePreset")];
|
|
70
|
-
_remoteSelect_decorators = [Remote("select")];
|
|
71
|
-
__esDecorate(this, null, _remoteList_decorators, { kind: "method", name: "remoteList", static: false, private: false, access: { has: obj => "remoteList" in obj, get: obj => obj.remoteList }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
72
|
-
__esDecorate(this, null, _remoteRead_decorators, { kind: "method", name: "remoteRead", static: false, private: false, access: { has: obj => "remoteRead" in obj, get: obj => obj.remoteRead }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
73
|
-
__esDecorate(this, null, _remoteCopy_decorators, { kind: "method", name: "remoteCopy", static: false, private: false, access: { has: obj => "remoteCopy" in obj, get: obj => obj.remoteCopy }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
74
|
-
__esDecorate(this, null, _remoteDelete_decorators, { kind: "method", name: "remoteDelete", static: false, private: false, access: { has: obj => "remoteDelete" in obj, get: obj => obj.remoteDelete }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
75
|
-
__esDecorate(this, null, _remoteSelect_decorators, { kind: "method", name: "remoteSelect", static: false, private: false, access: { has: obj => "remoteSelect" in obj, get: obj => obj.remoteSelect }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
76
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
77
|
-
}
|
|
78
|
-
constructor(ctx) {
|
|
79
|
-
super(ctx, "agentPresets");
|
|
80
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
81
|
-
}
|
|
82
|
-
get defaultId() {
|
|
83
|
-
return HERMES_PRESET.id;
|
|
84
|
-
}
|
|
85
|
-
get roots() {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
get authorable() {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
async list() {
|
|
92
|
-
return [HERMES_PRESET];
|
|
93
|
-
}
|
|
94
|
-
async resolve(id) {
|
|
95
|
-
if (id === undefined || id === HERMES_PRESET.id)
|
|
96
|
-
return HERMES_PRESET;
|
|
97
|
-
throw new RemoteError("agent-preset/not-found", `agent-presets: preset "${id}" not found (available: hermes)`, { agentPreset: id, available: [HERMES_PRESET.id] });
|
|
98
|
-
}
|
|
99
|
-
async mount(_agentCtx, id) {
|
|
100
|
-
return this.resolve(id);
|
|
101
|
-
}
|
|
102
|
-
async recompose(_agentCtx, id) {
|
|
103
|
-
return this.resolve(id);
|
|
104
|
-
}
|
|
105
|
-
async read(id) {
|
|
106
|
-
await this.resolve(id);
|
|
107
|
-
return COMPOSITION_TEXT;
|
|
108
|
-
}
|
|
109
|
-
// ── Remote RPC surface (alpha: agentPresets routes come from @Remote) ────
|
|
110
|
-
// The stock dsh-host-apiproxy mapped cordis methods to routes; alpha serves
|
|
111
|
-
// them from @Remote decorators on a TypertRemoteService. A plain Service
|
|
112
|
-
// registers no routes, which is why Settings → Agent Preset 404'd.
|
|
113
|
-
async remoteList() {
|
|
114
|
-
if (process.env.HERMES_TRACE === "1")
|
|
115
|
-
process.stderr.write("[hermes-roster] remoteList INVOKED\n");
|
|
116
|
-
return {
|
|
117
|
-
presets: [
|
|
118
|
-
{
|
|
119
|
-
id: HERMES_PRESET.id,
|
|
120
|
-
trust: HERMES_PRESET.trust,
|
|
121
|
-
isDefault: true,
|
|
122
|
-
name: HERMES_PRESET.name,
|
|
123
|
-
description: HERMES_PRESET.description,
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
authorable: this.authorable,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
async remoteRead(agentPreset) {
|
|
130
|
-
const preset = await this.resolve(agentPreset);
|
|
131
|
-
return {
|
|
132
|
-
agentPreset: preset.id,
|
|
133
|
-
trust: preset.trust,
|
|
134
|
-
content: await this.read(preset.id),
|
|
135
|
-
name: preset.name,
|
|
136
|
-
description: preset.description,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
async remoteCopy(from, id, name) {
|
|
140
|
-
await this.copy(from, id, name);
|
|
141
|
-
}
|
|
142
|
-
async remoteDelete(id) {
|
|
143
|
-
await this.remove(id);
|
|
144
|
-
}
|
|
145
|
-
/** Fixed roster: one preset, so selecting it is a no-op ack; anything else is unknown. */
|
|
146
|
-
async remoteSelect(agent, agentPreset) {
|
|
147
|
-
const preset = await this.resolve(agentPreset);
|
|
148
|
-
return preset.id;
|
|
149
|
-
}
|
|
150
|
-
async copy(_from, id, _name) {
|
|
151
|
-
throw new RemoteError("agent-preset/read-only", `agent-presets: preset "${id}" cannot be written: the Hermes roster is fixed and ships exactly one preset`, { agentPreset: id, reason: "the Hermes roster is fixed and ships exactly one preset" });
|
|
152
|
-
}
|
|
153
|
-
async remove(id) {
|
|
154
|
-
throw new RemoteError("agent-preset/read-only", `agent-presets: preset "${id}" cannot be written: the Hermes roster is fixed and ships exactly one preset`, { agentPreset: id, reason: "the Hermes roster is fixed and ships exactly one preset" });
|
|
155
|
-
}
|
|
156
|
-
serviceFor(_agent, _name) {
|
|
157
|
-
return undefined;
|
|
158
|
-
}
|
|
159
|
-
composeFrom(_agentCtx, _parentCtx) {
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
composedPreset(_agentCtx) {
|
|
163
|
-
return HERMES_PRESET.id;
|
|
164
|
-
}
|
|
165
|
-
async standingKeyFor(id) {
|
|
166
|
-
await this.resolve(id);
|
|
167
|
-
return STANDING_KEY;
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
})();
|
|
171
|
-
export { SingleHermesPresetRoster };
|
|
9
|
+
/**
|
|
10
|
+
* Register the fixed preset into the host `AgentPresetRegistry` once the
|
|
11
|
+
* service is up. Registration failure keeps the roster row visible as
|
|
12
|
+
* `broken` inside the registry (upstream owns that lifecycle) — the adapter
|
|
13
|
+
* only owns the disposer.
|
|
14
|
+
*/
|
|
15
|
+
export function registerHermesPreset(ctx) {
|
|
16
|
+
ctx.inject(["agentPresets"], (scoped) => {
|
|
17
|
+
let dispose;
|
|
18
|
+
let settled = false;
|
|
19
|
+
void scoped.agentPresets.register(HERMES_PRESET).then((unregister) => {
|
|
20
|
+
if (settled) {
|
|
21
|
+
void unregister();
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
dispose = unregister;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
ctx.effect(() => async () => {
|
|
28
|
+
settled = true;
|
|
29
|
+
await dispose?.();
|
|
30
|
+
}, "hermesAdapter.preset");
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -4,6 +4,7 @@ import { LlmAttemptId, ToolCallId, QUOTA_EXCEEDED_CODE, createAssistantMessage,
|
|
|
4
4
|
import { createScope } from "@deepseek-ai/dsh-scope";
|
|
5
5
|
import { GatewayRpcError, HERMES_SPAWN_ATTEMPTS } from "./hermes-client.js";
|
|
6
6
|
import { approvalChoiceFromOutcome } from "./permission.js";
|
|
7
|
+
import { withSystemHead } from "../../superd-hub/dist/index.js";
|
|
7
8
|
/**
|
|
8
9
|
* v2 live assistant-stream publication for the Hermes bridge — the same frame
|
|
9
10
|
* protocol the reference loop's AssistantStreamAttempt speaks (start marker,
|
|
@@ -58,22 +59,27 @@ const trace = (...parts) => {
|
|
|
58
59
|
export function convertContent(blocks) {
|
|
59
60
|
if (blocks === undefined)
|
|
60
61
|
return [];
|
|
61
|
-
|
|
62
|
+
// 0.1.6 renders blocks in ARRAY order; the native stream emits reasoning
|
|
63
|
+
// BEFORE text, so gateway messages that trail their thinking blocks must be
|
|
64
|
+
// hoisted — otherwise the WebUI draws "Thought for a while" AFTER the
|
|
65
|
+
// response (2026-09-23 evidence).
|
|
66
|
+
const reasoning = [];
|
|
67
|
+
const rest = [];
|
|
62
68
|
for (const block of blocks) {
|
|
63
69
|
switch (block.type) {
|
|
64
70
|
case "text":
|
|
65
71
|
if (typeof block.text === "string")
|
|
66
|
-
|
|
72
|
+
rest.push({ type: "text", text: block.text });
|
|
67
73
|
break;
|
|
68
74
|
case "thinking":
|
|
69
75
|
if (typeof block.thinking === "string")
|
|
70
|
-
|
|
76
|
+
reasoning.push({ type: "reasoning", text: block.thinking });
|
|
71
77
|
break;
|
|
72
78
|
case "toolCall": {
|
|
73
79
|
const id = typeof block.id === "string" ? block.id : "";
|
|
74
80
|
const name = typeof block.name === "string" ? block.name : "";
|
|
75
81
|
const args = typeof block.arguments === "string" ? block.arguments : JSON.stringify(block.arguments ?? {});
|
|
76
|
-
|
|
82
|
+
rest.push({ type: "tool-call", id: ToolCallId(id), name, arguments: args });
|
|
77
83
|
break;
|
|
78
84
|
}
|
|
79
85
|
default:
|
|
@@ -81,7 +87,7 @@ export function convertContent(blocks) {
|
|
|
81
87
|
break;
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
|
-
return
|
|
90
|
+
return [...reasoning, ...rest];
|
|
85
91
|
}
|
|
86
92
|
/**
|
|
87
93
|
* Classify the wire's `stopReason: "error"` assistant message into a Dash
|
|
@@ -191,8 +197,13 @@ function userMessageText(message) {
|
|
|
191
197
|
* work) and echo it into history as a fake user prompt. Detect and drop it.
|
|
192
198
|
*/
|
|
193
199
|
function isApprovalNarration(message) {
|
|
194
|
-
|
|
195
|
-
|
|
200
|
+
// 0.1.7: the shared `plugin` source kind is gone (MessageSourceMap is
|
|
201
|
+
// merge-extensible; each producer declares its own kind) — user-approval
|
|
202
|
+
// now carries the dedicated `user-approval` kind.
|
|
203
|
+
// Type-only: loads the `user-approval` MessageSourceMap augmentation
|
|
204
|
+
// (0.1.7: producer-owned source kinds; the shared `plugin` kind is gone).
|
|
205
|
+
// noinspection JSValidateTypes
|
|
206
|
+
return message.source.kind === "user-approval";
|
|
196
207
|
}
|
|
197
208
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
198
209
|
/**
|
|
@@ -264,6 +275,8 @@ export class HermesAgent {
|
|
|
264
275
|
#pendingFailure = null;
|
|
265
276
|
/** Last title mirrored into `session/title` (dedupes repeated gateway events). */
|
|
266
277
|
#mirroredTitle = null;
|
|
278
|
+
/** Seq of the session's first user/message (v4 title citations derive from it). */
|
|
279
|
+
#titleSourceSeq;
|
|
267
280
|
/** Live v2 assistant-stream publication for the in-flight wire message. */
|
|
268
281
|
#streamBridge;
|
|
269
282
|
#assistantAttemptCounter = 0;
|
|
@@ -299,7 +312,7 @@ export class HermesAgent {
|
|
|
299
312
|
this.#loopCtx = loopCtx;
|
|
300
313
|
this.id = id;
|
|
301
314
|
this.options = options;
|
|
302
|
-
this.session = session;
|
|
315
|
+
this.session = withSystemHead(session, () => createSystemMessage(""));
|
|
303
316
|
this.#client = client;
|
|
304
317
|
this.#onIdleExit = onIdleExit;
|
|
305
318
|
this.#runtimeInfo = runtimeInfo;
|
|
@@ -482,7 +495,7 @@ export class HermesAgent {
|
|
|
482
495
|
return;
|
|
483
496
|
this.session.append("turn/start", { turn: this.#dashTurn });
|
|
484
497
|
await this.#emitRequestContext();
|
|
485
|
-
this.session.append("user/message", message, { surfaceOp: "append" });
|
|
498
|
+
this.#titleSourceSeq ??= this.session.append("user/message", message, { surfaceOp: "append" }).seq;
|
|
486
499
|
this.#armTurnDeadline();
|
|
487
500
|
void this.#client
|
|
488
501
|
.prompt(userMessageText(message))
|
|
@@ -555,20 +568,19 @@ export class HermesAgent {
|
|
|
555
568
|
if (this.#runtimeInfo === undefined || !this.#turnOpen)
|
|
556
569
|
return;
|
|
557
570
|
this.#commitStepStart();
|
|
558
|
-
|
|
571
|
+
// commitStepStart re-enters #emitSystemMessage (step open → stamp); the
|
|
572
|
+
// outer call must re-check the one-shot flag after the recursion.
|
|
573
|
+
if (this.#systemMessageDone)
|
|
559
574
|
return;
|
|
560
|
-
if (this
|
|
561
|
-
this.#systemMessageDone = true;
|
|
575
|
+
if (this.#step === 0)
|
|
562
576
|
return;
|
|
563
|
-
}
|
|
564
577
|
const text = this.#runtimeInfo.systemPrompt();
|
|
565
578
|
if (text === undefined || text.trim() === "")
|
|
566
579
|
return;
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}, { surfaceOp: "append" });
|
|
580
|
+
// v4 protected-head posture: replace the placeholder head (stamped before
|
|
581
|
+
// the first user message); an append here would corrupt the log for the
|
|
582
|
+
// 0.1.7 reader ("system/message requires a protected first surface head").
|
|
583
|
+
this.session.stampSystemPrompt(this.#dashTurn, this.#step, createSystemMessage(text));
|
|
572
584
|
this.#systemMessageDone = true;
|
|
573
585
|
const title = this.#runtimeInfo.sessionTitle();
|
|
574
586
|
if (title !== undefined && title !== "")
|
|
@@ -941,9 +953,11 @@ export class HermesAgent {
|
|
|
941
953
|
return;
|
|
942
954
|
this.#mirroredTitle = name;
|
|
943
955
|
try {
|
|
956
|
+
if (this.#titleSourceSeq === undefined)
|
|
957
|
+
return; // v4: a provider title cites the user message it titles
|
|
944
958
|
this.session.append("session/title", {
|
|
945
959
|
title: name,
|
|
946
|
-
messageSeqs: [],
|
|
960
|
+
messageSeqs: [this.#titleSourceSeq],
|
|
947
961
|
source: { kind: "provider", provider: "hermes" },
|
|
948
962
|
});
|
|
949
963
|
trace(`session/title ← hermes: "${name}"`);
|
|
@@ -109,9 +109,9 @@ let gatewayFactory = defaultGatewayFactory;
|
|
|
109
109
|
export function setGatewayFactory(factory) {
|
|
110
110
|
gatewayFactory = factory ?? defaultGatewayFactory;
|
|
111
111
|
}
|
|
112
|
-
/** Brief-pinned order:
|
|
112
|
+
/** Brief-pinned order: SUPERD_HERMES_PYTHON → <root>/venv/bin/python → <root>/.venv/bin/python → PATH python3. */
|
|
113
113
|
export function resolveHermesPython(root) {
|
|
114
|
-
const configured = process.env.
|
|
114
|
+
const configured = process.env.SUPERD_HERMES_PYTHON?.trim();
|
|
115
115
|
if (configured)
|
|
116
116
|
return configured;
|
|
117
117
|
for (const p of [resolve(root, "venv/bin/python"), resolve(root, ".venv/bin/python")]) {
|
|
@@ -120,9 +120,9 @@ export function resolveHermesPython(root) {
|
|
|
120
120
|
}
|
|
121
121
|
return "python3";
|
|
122
122
|
}
|
|
123
|
-
/** Hermes root:
|
|
123
|
+
/** Hermes root: SUPERD_HERMES_ROOT → ~/.hermes/hermes-agent (native home — never redirected). */
|
|
124
124
|
export function resolveHermesRoot() {
|
|
125
|
-
return process.env.
|
|
125
|
+
return process.env.SUPERD_HERMES_ROOT?.trim() || resolve(homedir(), ".hermes/hermes-agent");
|
|
126
126
|
}
|
|
127
127
|
function asRecord(value) {
|
|
128
128
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
@@ -946,7 +946,7 @@ export class HermesGatewayClient {
|
|
|
946
946
|
return this.#stderrLines.slice(-20).join("\n");
|
|
947
947
|
}
|
|
948
948
|
#trace(line) {
|
|
949
|
-
if (process.env.
|
|
949
|
+
if (process.env.SUPERD_HERMES_TRACE === "1") {
|
|
950
950
|
process.stderr.write(`[hermes-client] ${line}\n`);
|
|
951
951
|
}
|
|
952
952
|
}
|
|
@@ -19,15 +19,7 @@
|
|
|
19
19
|
* degrades to "unknown session" rather than breaking every operation.
|
|
20
20
|
*/
|
|
21
21
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
22
|
-
import { homedir } from "node:os";
|
|
23
22
|
import { basename, dirname, join, resolve } from "node:path";
|
|
24
|
-
/** Prod homes that must never be resolved into (repo red line). */
|
|
25
|
-
const PROD_HOMES = [join(homedir(), ".dsh"), join(homedir(), ".superd")];
|
|
26
|
-
function assertNotProdHome(path, label) {
|
|
27
|
-
if (PROD_HOMES.includes(path) || PROD_HOMES.some((p) => path.startsWith(`${p}/`))) {
|
|
28
|
-
throw new Error(`hermes-store: refusing prod home as ${label}: ${path}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
23
|
/**
|
|
32
24
|
* The adapter's DSH-side state dir — `<dshHome>/agents/hermes`. This is DSH-SIDE
|
|
33
25
|
* adapter state (the identity map), NOT hermes data: hermes keeps its native
|
|
@@ -40,13 +32,12 @@ function assertNotProdHome(path, label) {
|
|
|
40
32
|
* - Form-B: the boot-provided home is ALREADY the world home
|
|
41
33
|
* (`<root>/agents/hermes`) — passed through as-is, never double-nested.
|
|
42
34
|
* Precedence: explicit home (boot-provided `dshHomePath`), then `$DSH_HOME`,
|
|
43
|
-
* then the line's historical test-home default.
|
|
35
|
+
* then the line's historical test-home default.
|
|
44
36
|
*/
|
|
45
37
|
export function resolveHermesAppDir(home) {
|
|
46
|
-
const base = resolve(home ?? process.env.DSH_HOME ?? join(process.cwd(), ".tests", "
|
|
38
|
+
const base = resolve(home ?? process.env.DSH_HOME ?? join(process.cwd(), ".tests", "superd"));
|
|
47
39
|
// Form-B world home is already `<root>/agents/hermes` — never double-nest.
|
|
48
40
|
const dir = basename(base) === "hermes" && basename(dirname(base)) === "agents" ? base : join(base, "agents", "hermes");
|
|
49
|
-
assertNotProdHome(dir, "hermes app dir");
|
|
50
41
|
return dir;
|
|
51
42
|
}
|
|
52
43
|
/** The map file's path inside the adapter's DSH-side app dir. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* agent-hermes provider — Hermes provider plugin for DeepSeek Harness
|
|
3
|
-
* (
|
|
3
|
+
* (Super D, TUI gateway line).
|
|
4
4
|
*
|
|
5
5
|
* Replaces the built-in agent loop with an `AgentFactory` that drives a
|
|
6
6
|
* `HermesGatewayClient` (one spawned `python -m tui_gateway.entry` child per
|
|
@@ -24,13 +24,12 @@
|
|
|
24
24
|
import { realpathSync, statSync } from "node:fs";
|
|
25
25
|
import { join } from "node:path";
|
|
26
26
|
import { Service } from "@deepseek-ai/cordis";
|
|
27
|
-
import {
|
|
27
|
+
import { installModelSelection } from "@deepseek-ai/dsh-agent";
|
|
28
28
|
import { SessionLogOffset, SessionPreparation, interruptedTurnClosers, } from "@deepseek-ai/dsh-session";
|
|
29
29
|
import { HermesGatewayClient, HERMES_SPAWN_GRACE_MS } from "./hermes-client.js";
|
|
30
30
|
import { HermesAgent } from "./agent.js";
|
|
31
31
|
import { HermesLlmAdapter, HERMES_PROVIDER_ID } from "./adapter.js";
|
|
32
|
-
import {
|
|
33
|
-
import { hermesAgentPresetProjection } from "./agent-preset-projection.js";
|
|
32
|
+
import { registerHermesPreset } from "./agent-preset-hermes.js";
|
|
34
33
|
import { sessionRecord, upsertSession } from "./hermes-store.js";
|
|
35
34
|
import { hermesProviderSlugs, readHermesModelCatalog } from "./models.js";
|
|
36
35
|
import { envApprovalMode, defaultPermissionPreset, presetFromEvents } from "./permission.js";
|
|
@@ -96,11 +95,12 @@ export class HermesProvider extends Service {
|
|
|
96
95
|
this.#registerDefaultModel();
|
|
97
96
|
// The roster must be visible to the API gateway's root-level remote
|
|
98
97
|
// enumeration; register it on this plugin's own (top-level) fiber.
|
|
99
|
-
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
// 0.1.7: roster/selection/document RPC + the `agentPreset` session
|
|
99
|
+
// projection all live in the host AgentPresetRegistry (mounted by the
|
|
100
|
+
// dsh-web-app bundle's `agent-preset-registry` row; the adapter patch
|
|
101
|
+
// pins its `default` to the Hermes preset). The adapter only registers
|
|
102
|
+
// its one fixed preset into the registry.
|
|
103
|
+
registerHermesPreset(ctx);
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
106
|
* The factory owns its sessions' route (user directive 2026-09-15,
|
|
@@ -217,7 +217,7 @@ export class HermesProvider extends Service {
|
|
|
217
217
|
if (typeof resolved === "string" && resolved !== "")
|
|
218
218
|
return resolved;
|
|
219
219
|
}
|
|
220
|
-
return process.env.DSH_HOME ?? join(process.cwd(), ".tests", "
|
|
220
|
+
return process.env.DSH_HOME ?? join(process.cwd(), ".tests", "superd");
|
|
221
221
|
}
|
|
222
222
|
/**
|
|
223
223
|
* Push the gateway's default model into the world's `agentDefaultModel`
|
|
@@ -499,8 +499,9 @@ async function setupAndPublish(loopCtx, ownerCtx, id, agentOptions, setup, sessi
|
|
|
499
499
|
agent.ctx.sessions.announce(session);
|
|
500
500
|
}
|
|
501
501
|
detachAgent = loopCtx.agents.enter(agent, parentAgent);
|
|
502
|
-
|
|
503
|
-
|
|
502
|
+
// 0.1.6: announce(agent, source) is required, async, and emits agent/created
|
|
503
|
+
// itself — the manual agent/session-start emission is gone upstream.
|
|
504
|
+
await loopCtx.agents.announce(agent, source);
|
|
504
505
|
let disposed = false;
|
|
505
506
|
let unfollowOwner;
|
|
506
507
|
const dispose = async () => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* agent-hermes — the Hermes adapter's WORLD plugin (spec S2):
|
|
3
3
|
* activation IS roster membership.
|
|
4
4
|
*
|
|
5
|
-
* AW-B URL scheme (DL1–DL5), mirroring `@pgmi-builds/agent-
|
|
6
|
-
* and `@pgmi-builds/agent-
|
|
5
|
+
* AW-B URL scheme (DL1–DL5), mirroring `@pgmi-builds/agent-omp/world`
|
|
6
|
+
* and `@pgmi-builds/agent-codex/world` so the hub sees every foreign
|
|
7
7
|
* runtime through one shape: the world is spawned as a sibling ROOT context
|
|
8
8
|
* with NO listener (`worldMountPatches`) and mounts itself under `/hermes`
|
|
9
9
|
* through the hub —
|
|
@@ -17,12 +17,10 @@
|
|
|
17
17
|
import { mkdirSync } from 'node:fs';
|
|
18
18
|
import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
|
-
import { spawnWorld, registerAgent, setReady, registerForeignTarget, registerHostMount, mountWorld, worldMountPatches, provisionWorldProfile, } from '../../
|
|
21
|
-
export const name = '
|
|
20
|
+
import { spawnWorld, registerAgent, setReady, registerForeignTarget, registerHostMount, mountWorld, worldMountPatches, provisionWorldProfile, resolveInstallAnchor, } from '../../superd-hub/dist/index.js';
|
|
21
|
+
export const name = 'agent-hermes';
|
|
22
22
|
/** Runtime key — also the mount label. */
|
|
23
23
|
const KEY = 'hermes';
|
|
24
|
-
const ANCHOR = process.env.SUPERD_DSH_ANCHOR
|
|
25
|
-
?? '/home/u1/.local/lib/node_modules/@deepseek-ai/dsh/package.json';
|
|
26
24
|
export function apply(ctx) {
|
|
27
25
|
registerAgent({ key: KEY, label: 'Hermes', ready: false });
|
|
28
26
|
// Harness resolver (env → ~/.dsh): a consumer install has no DSH_HOME and
|
|
@@ -39,12 +37,10 @@ export function apply(ctx) {
|
|
|
39
37
|
const worldHome = join(root, 'agents', KEY);
|
|
40
38
|
mkdirSync(join(worldHome, 'profiles'), { recursive: true });
|
|
41
39
|
// Publish story: a foreign install has no line bootstrap, so the nested
|
|
42
|
-
// profile + @pgmi-builds links are provisioned HERE (idempotent
|
|
43
|
-
|
|
44
|
-
// overrides the resolved base).
|
|
45
|
-
const bareBase = provisionWorldProfile({
|
|
40
|
+
// profile + @pgmi-builds links are provisioned HERE (idempotent).
|
|
41
|
+
provisionWorldProfile({
|
|
46
42
|
key: KEY,
|
|
47
|
-
adapterPkg: '@pgmi-builds/agent-
|
|
43
|
+
adapterPkg: '@pgmi-builds/agent-hermes',
|
|
48
44
|
worldHome,
|
|
49
45
|
});
|
|
50
46
|
const world = (async () => {
|
|
@@ -64,16 +60,15 @@ export function apply(ctx) {
|
|
|
64
60
|
authorize: (req, res) => connection.authorizeIndex(req, res),
|
|
65
61
|
});
|
|
66
62
|
const ctxW = await spawnWorld({
|
|
67
|
-
appName: `
|
|
63
|
+
appName: `superd-${KEY}`,
|
|
68
64
|
profileName: 'web',
|
|
69
|
-
installAnchor:
|
|
65
|
+
installAnchor: resolveInstallAnchor(ctx), // lazy: never at module scope — import must stay side-effect-free
|
|
70
66
|
home: worldHome,
|
|
71
67
|
dataHome: worldHome,
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
bareModuleBaseUrl: process.env.AW_BARE_BASE ?? bareBase ?? undefined,
|
|
68
|
+
// The host's live table carries this world: spawnWorld republishes a
|
|
69
|
+
// widened successor before boot imports anything (spec §2.1), and
|
|
70
|
+
// @pgmi-builds rows resolve from the profile-local links written above.
|
|
71
|
+
host: ctx,
|
|
77
72
|
extraPatches: worldMountPatches(KEY),
|
|
78
73
|
});
|
|
79
74
|
const gateway = ctxW.get('typertGateway');
|
|
@@ -89,7 +84,7 @@ export function apply(ctx) {
|
|
|
89
84
|
ctx.effect?.(() => () => {
|
|
90
85
|
mounted.dispose();
|
|
91
86
|
dropHostMount();
|
|
92
|
-
}, `
|
|
87
|
+
}, `agent-${KEY}: mount`);
|
|
93
88
|
return ctxW;
|
|
94
89
|
})().catch((cause) => {
|
|
95
90
|
// A failed world degrades to a not-ready roster row; a rejected provided
|
|
@@ -97,5 +92,5 @@ export function apply(ctx) {
|
|
|
97
92
|
console.error(`[super-dsh] ${KEY} world failed:`, cause);
|
|
98
93
|
return null;
|
|
99
94
|
});
|
|
100
|
-
ctx.provide(`
|
|
95
|
+
ctx.provide(`superd.world.${KEY}`, world);
|
|
101
96
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@pgmi-builds/agent-
|
|
2
|
+
"name": "@pgmi-builds/agent-hermes",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"description": "Hermes provider for DeepSeek Harness (dsh) — an AgentFactory that embeds Nous Research Hermes Agent via the TUI gateway JSON-RPC (python -m tui_gateway.entry) and bridges its session surface into Dash Agent/Session contracts
|
|
4
|
+
"description": "Hermes provider for DeepSeek Harness (dsh) — an AgentFactory that embeds Nous Research Hermes Agent via the TUI gateway JSON-RPC (python -m tui_gateway.entry) and bridges its session surface into Dash Agent/Session contracts .",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./dist/index.js",
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"test": "node --test test/*.test.mjs"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"
|
|
26
|
-
"zod": "3.25.76"
|
|
25
|
+
"zod": "4.4.3"
|
|
27
26
|
},
|
|
28
27
|
"peerDependencies": {
|
|
29
28
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
30
|
-
"@deepseek-ai/dsh-agent": "0.1.5-
|
|
31
|
-
"@deepseek-ai/dsh-agent-presets": "0.1.5-
|
|
32
|
-
"@deepseek-ai/dsh-llm": "0.1.5-
|
|
33
|
-
"@deepseek-ai/dsh-scope": "0.1.5-
|
|
34
|
-
"@deepseek-ai/dsh-session": "0.1.5-
|
|
35
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.5-
|
|
36
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.5-
|
|
29
|
+
"@deepseek-ai/dsh-agent": ">=0.1.5-0 <0.3.0-0",
|
|
30
|
+
"@deepseek-ai/dsh-agent-presets": ">=0.1.5-0 <0.3.0-0",
|
|
31
|
+
"@deepseek-ai/dsh-llm": ">=0.1.5-0 <0.3.0-0",
|
|
32
|
+
"@deepseek-ai/dsh-scope": ">=0.1.5-0 <0.3.0-0",
|
|
33
|
+
"@deepseek-ai/dsh-session": ">=0.1.5-0 <0.3.0-0",
|
|
34
|
+
"@deepseek-ai/dsh-session-persistence": ">=0.1.5-0 <0.3.0-0",
|
|
35
|
+
"@deepseek-ai/dsh-typert-protocol": ">=0.1.5-0 <0.3.0-0",
|
|
36
|
+
"@pgmi-builds/superd-hub": "*"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@deepseek-ai/cordis": {
|
|
@@ -59,6 +59,9 @@
|
|
|
59
59
|
},
|
|
60
60
|
"@deepseek-ai/dsh-typert-protocol": {
|
|
61
61
|
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"@pgmi-builds/superd-hub": {
|
|
64
|
+
"optional": true
|
|
62
65
|
}
|
|
63
66
|
},
|
|
64
67
|
"devDependencies": {
|
package/agent-omp/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @pgmi-builds/agent-omp(OMP adapter,SDK 线)
|
|
2
2
|
|
|
3
3
|
OMP Web 的 SDK 线:**衔接层(DSH 契约/术语/类形状)沿用 `apps/omp-web` 现行源码,内核从 `omp --mode rpc` 子进程换成 `@oh-my-pi/pi-coding-agent` SDK**。数据面目标 = `docs/plans/sdk-data-surface-assessment.md` 的 A1–A8 / S1–S10。
|
|
4
4
|
|
|
@@ -34,7 +34,7 @@ dsh 宿主 (Node 22, 本包 dist/) Bun sidecar (本包 sidecar/)
|
|
|
34
34
|
- `sidecar/main.ts`(bun 入口):ready 握手 + JSON-lines 请求/响应/事件三帧协议;app 级共享单例 `authStorage`/`modelRegistry`;session 池(create/dispose/事件转发)。
|
|
35
35
|
- `src/protocol.ts`:协议与方法表类型(sys.ping / models.list / settings.get / session.create|info|prompt|steer|followUp|abort|dispose / sessions.list)。
|
|
36
36
|
- `src/sidecar-client.ts`:Node 侧 spawn/关联/事件分发/优雅关停;`src/index.ts` 暂导出 client。
|
|
37
|
-
-
|
|
37
|
+
- ~~冒烟 `test/sidecar-smoke.test.mjs`~~(2026-09-24 场景退役删除;整包验证走 superd 的 4999 pack 线 + dev3)。
|
|
38
38
|
- 坑已修:`ModelRegistry.refreshInBackground()` 此版本返回 void(非 Promise),可选链后接 `.catch` 会炸;ready-timeout 定时器必须 clear 否则 Node 进程挂 60s。
|
|
39
39
|
|
|
40
40
|
## As-built:衔接层移植(2026-09-09,已完成 ✅)
|