@kasenri/dsh-orbit 0.5.8 → 0.5.9
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 +3 -0
- package/lib/activation.js +3 -2
- package/lib/client.js +11 -11
- package/lib/dsh-host.js +4 -0
- package/lib/index.js +26 -2
- package/lib/supervisor.js +12 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -104,6 +104,9 @@ Orbit supports three activation styles:
|
|
|
104
104
|
|
|
105
105
|
All three routes converge on the existing `orbit_controller` tool and
|
|
106
106
|
`OrbitService`; the activation layer never starts a run of its own.
|
|
107
|
+
After a hard-activated run reaches `SUCCESS`, the initiating Session displays
|
|
108
|
+
the Final Commander's user-visible result directly, with the Commander's frozen
|
|
109
|
+
provider/model provenance. The parent model and parent tools remain bypassed.
|
|
107
110
|
|
|
108
111
|
## Model configuration (Web)
|
|
109
112
|
|
package/lib/activation.js
CHANGED
|
@@ -116,7 +116,8 @@ export function registerOrbitToggleCommand(ctx) {
|
|
|
116
116
|
* call while the message stays in the conversation as durable history.
|
|
117
117
|
*/
|
|
118
118
|
export function installOrbitGestureBoundary(ctx, options = {}) {
|
|
119
|
-
ctx.on('agent/pre-step', async (
|
|
119
|
+
ctx.on('agent/pre-step', async (payload, next) => {
|
|
120
|
+
const { agent, messages, signal } = payload;
|
|
120
121
|
const decision = await next();
|
|
121
122
|
if (decision.kind === 'reject')
|
|
122
123
|
return decision;
|
|
@@ -134,7 +135,7 @@ export function installOrbitGestureBoundary(ctx, options = {}) {
|
|
|
134
135
|
// `decision.messages`, which this path leaves empty.
|
|
135
136
|
for (const message of messages)
|
|
136
137
|
agent.session.append('user/message', message, { surfaceOp: 'append' });
|
|
137
|
-
await activate(agent, goal, signal);
|
|
138
|
+
await activate(agent, goal, { turn: payload.turn, step: payload.step }, signal);
|
|
138
139
|
return { kind: 'enter', messages: [] };
|
|
139
140
|
});
|
|
140
141
|
}
|
package/lib/client.js
CHANGED
|
@@ -94,22 +94,22 @@ window.__ModuleLoader__.load({
|
|
|
94
94
|
document.head.appendChild(tag);
|
|
95
95
|
}
|
|
96
96
|
var OrbitModelSelect_module_css_default = {
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"rowValue": "f77nca_rowValue",
|
|
97
|
+
"title": "f77nca_title",
|
|
98
|
+
"panel": "f77nca_panel",
|
|
100
99
|
"switchControl": "f77nca_switchControl",
|
|
100
|
+
"error": "f77nca_error",
|
|
101
101
|
"rowDetail": "f77nca_rowDetail",
|
|
102
|
-
"rowLabel": "f77nca_rowLabel",
|
|
103
|
-
"switchRow": "f77nca_switchRow",
|
|
104
|
-
"separator": "f77nca_separator",
|
|
105
102
|
"chevron": "f77nca_chevron",
|
|
106
|
-
"row": "f77nca_row",
|
|
107
103
|
"group": "f77nca_group",
|
|
108
|
-
"
|
|
104
|
+
"row": "f77nca_row",
|
|
105
|
+
"switchRow": "f77nca_switchRow",
|
|
106
|
+
"hint": "f77nca_hint",
|
|
107
|
+
"rowValueActive": "f77nca_rowValueActive",
|
|
108
|
+
"rowValue": "f77nca_rowValue",
|
|
109
|
+
"rowLabel": "f77nca_rowLabel",
|
|
109
110
|
"check": "f77nca_check",
|
|
110
|
-
"
|
|
111
|
-
"back": "f77nca_back"
|
|
112
|
-
"panel": "f77nca_panel"
|
|
111
|
+
"separator": "f77nca_separator",
|
|
112
|
+
"back": "f77nca_back"
|
|
113
113
|
};
|
|
114
114
|
//#endregion
|
|
115
115
|
//#region client/OrbitModelSelect.tsx
|
package/lib/dsh-host.js
CHANGED
|
@@ -13,6 +13,9 @@ function contentToText(blocks) {
|
|
|
13
13
|
.map((block) => (block.type === 'text' ? block.text : `[${block.type}]`))
|
|
14
14
|
.join('\n');
|
|
15
15
|
}
|
|
16
|
+
function visibleContentToText(blocks) {
|
|
17
|
+
return blocks?.flatMap((block) => block.type === 'text' && block.text.trim() !== '' ? [block.text] : []).join('\n') ?? '';
|
|
18
|
+
}
|
|
16
19
|
/**
|
|
17
20
|
* Wire the Orbit supervisor to DeepSeek Harness native Agent/Subagent services.
|
|
18
21
|
*
|
|
@@ -81,6 +84,7 @@ export class DshOrbitHost {
|
|
|
81
84
|
.then((value) => ({
|
|
82
85
|
childId: run.id,
|
|
83
86
|
output: contentToText(value.output),
|
|
87
|
+
visibleOutput: visibleContentToText(value.output),
|
|
84
88
|
interrupted: value.stopReason !== 'completed',
|
|
85
89
|
...(value.stopReason !== 'completed' ? { reason: value.stopReason } : {}),
|
|
86
90
|
...(value.diagnostic ? { testSummary: [value.diagnostic] } : {}),
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { boundContextSummary, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
1
|
+
import { AssistantStreamAccumulator, boundContextSummary, createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
3
|
import { installOrbitGestureBoundary, registerOrbitCommand, registerOrbitToggleCommand } from "./activation.js";
|
|
4
4
|
import { createOrbitPreExecuteHandler } from "./pipeline-guard.js";
|
|
@@ -120,7 +120,7 @@ export function apply(ctx, config) {
|
|
|
120
120
|
});
|
|
121
121
|
installOrbitGestureBoundary(ctx, {
|
|
122
122
|
sessionEnabled: (session) => orbitEnabledOf(ctx, session),
|
|
123
|
-
activate: async (agent, goal, signal) => {
|
|
123
|
+
activate: async (agent, goal, position, signal) => {
|
|
124
124
|
const cwd = agent.session.header.cwd ?? process.cwd();
|
|
125
125
|
let result;
|
|
126
126
|
try {
|
|
@@ -135,6 +135,10 @@ export function apply(ctx, config) {
|
|
|
135
135
|
appendOrbitNotice(agent.session, `Orbit 启动失败:${error instanceof Error ? error.message : String(error)}`);
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
|
+
if (result.ok && result.phase === 'SUCCESS' && result.final_output !== undefined) {
|
|
139
|
+
appendOrbitFinalOutput(agent.session, position, result.final_output);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
138
142
|
const notice = activationNotice(result);
|
|
139
143
|
if (notice !== undefined)
|
|
140
144
|
appendOrbitNotice(agent.session, notice);
|
|
@@ -168,6 +172,26 @@ export function apply(ctx, config) {
|
|
|
168
172
|
ctx.on('tools/pre-execute', (exec, next) => handler(exec, next));
|
|
169
173
|
}
|
|
170
174
|
}
|
|
175
|
+
/** Append the existing Final Commander answer as this consumed turn's sole assistant result. */
|
|
176
|
+
function appendOrbitFinalOutput(session, position, output) {
|
|
177
|
+
const message = createAssistantMessage({
|
|
178
|
+
content: [{ type: 'text', text: output.text }],
|
|
179
|
+
source: { provider: output.provider, model: output.model },
|
|
180
|
+
});
|
|
181
|
+
const stream = new AssistantStreamAccumulator();
|
|
182
|
+
const time = Date.now();
|
|
183
|
+
stream.push({ time, chunk: { type: 'block-start', index: 0, blockType: 'text' } });
|
|
184
|
+
stream.push({ time, chunk: { type: 'text-delta', index: 0, text: output.text } });
|
|
185
|
+
stream.push({ time, chunk: { type: 'block-end', index: 0, block: { type: 'text', text: output.text } } });
|
|
186
|
+
stream.push({ time, chunk: { type: 'finish', reason: { kind: 'stop' } } });
|
|
187
|
+
session.append('step/start', position);
|
|
188
|
+
try {
|
|
189
|
+
session.append('assistant/message', { ...position, message, stream: [...stream.snapshot()] }, { surfaceOp: 'append' });
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
session.append('step/end', position);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
171
195
|
/**
|
|
172
196
|
* One durable, user-visible Orbit notice. The DSH `plugin` + `form: 'notice'`
|
|
173
197
|
* source renders as a collapsed notice row instead of a user message, and the
|
package/lib/supervisor.js
CHANGED
|
@@ -328,7 +328,7 @@ export class OrbitSupervisor {
|
|
|
328
328
|
return { kind: 'interrupted', reason: outcome.reason };
|
|
329
329
|
try {
|
|
330
330
|
const decision = assertCommanderDecision(outcome.structured, mode);
|
|
331
|
-
return { kind: 'decision', decision };
|
|
331
|
+
return { kind: 'decision', decision, output: outcome.output };
|
|
332
332
|
}
|
|
333
333
|
catch (error) {
|
|
334
334
|
// Invalid/temporary output is recoverable; it must not become NEEDS_USER.
|
|
@@ -387,7 +387,7 @@ export class OrbitSupervisor {
|
|
|
387
387
|
if (raced.value.structured === undefined) {
|
|
388
388
|
return { kind: 'interrupted', reason: `${mode}_STRUCTURED_OUTPUT_MISSING` };
|
|
389
389
|
}
|
|
390
|
-
return { kind: 'output', output: raced.value.output, structured: raced.value.structured };
|
|
390
|
+
return { kind: 'output', output: raced.value.visibleOutput ?? raced.value.output, structured: raced.value.structured };
|
|
391
391
|
}
|
|
392
392
|
if (raced.kind === 'aborted' || signal?.aborted) {
|
|
393
393
|
await this.cancelHandle(handle, 'ORBIT_ABORTED');
|
|
@@ -586,7 +586,7 @@ export class OrbitSupervisor {
|
|
|
586
586
|
if (decision.decision === 'SUCCESS') {
|
|
587
587
|
applyFinalSuccess(state, decision.summary);
|
|
588
588
|
this.store.writeState(state);
|
|
589
|
-
return this.result(state, true);
|
|
589
|
+
return this.result(state, true, undefined, outcome.output);
|
|
590
590
|
}
|
|
591
591
|
if (decision.decision === 'PASS_CURRENT_STEP') {
|
|
592
592
|
applyStepPass(state, step, decision.summary);
|
|
@@ -873,7 +873,7 @@ export class OrbitSupervisor {
|
|
|
873
873
|
return { ok: false, action: 'status', message: 'ORBIT_RUN_NOT_FOUND: 没有 Run 状态。' };
|
|
874
874
|
return this.result(state, true);
|
|
875
875
|
}
|
|
876
|
-
result(state, ok, message) {
|
|
876
|
+
result(state, ok, message, finalOutput) {
|
|
877
877
|
// Tool output must be lossless JSON: optional state fields are omitted, not
|
|
878
878
|
// emitted as `undefined`.
|
|
879
879
|
const data = {
|
|
@@ -896,6 +896,7 @@ export class OrbitSupervisor {
|
|
|
896
896
|
driver_ownership: state.driver_ownership,
|
|
897
897
|
state_revision: state.state_revision,
|
|
898
898
|
};
|
|
899
|
+
const displayText = state.phase === 'SUCCESS' ? finalOutput?.trim() || state.commander?.summary?.trim() : undefined;
|
|
899
900
|
return {
|
|
900
901
|
ok,
|
|
901
902
|
action: 'run',
|
|
@@ -903,6 +904,13 @@ export class OrbitSupervisor {
|
|
|
903
904
|
phase: state.phase,
|
|
904
905
|
status: state.status,
|
|
905
906
|
...(message ? { message } : {}),
|
|
907
|
+
...(displayText ? {
|
|
908
|
+
final_output: {
|
|
909
|
+
text: displayText,
|
|
910
|
+
provider: state.routes.commander.provider,
|
|
911
|
+
model: state.routes.commander.model,
|
|
912
|
+
},
|
|
913
|
+
} : {}),
|
|
906
914
|
data: Object.fromEntries(Object.entries(data).filter(([, value]) => value !== undefined)),
|
|
907
915
|
};
|
|
908
916
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kasenri/dsh-orbit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Deterministic engineering orchestration for DeepSeek Harness with Commander, Executor, Smart Watchdog, bounded recovery and durable execution state.",
|
|
6
6
|
"license": "MIT",
|