@kasenri/dsh-orbit 0.5.7 → 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 +27 -19
- package/cordis.patch.yml +2 -2
- package/lib/activation.js +12 -11
- package/lib/capabilities.js +23 -0
- package/lib/client.js +47 -77
- package/lib/decisions.js +4 -4
- package/lib/dsh-host.js +112 -30
- package/lib/evidence.js +24 -0
- package/lib/guard.js +17 -17
- package/lib/index.js +64 -43
- package/lib/kernel.js +33 -21
- package/lib/pipeline-guard.js +16 -4
- package/lib/routes.js +58 -56
- package/lib/sanitize.js +3 -2
- package/lib/service.js +75 -15
- package/lib/settlement.js +4 -1
- package/lib/state-store.js +15 -7
- package/lib/supervisor.js +135 -40
- package/lib/tool.js +10 -11
- package/lib/types.js +6 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,17 +94,19 @@ The `orbit_controller` tool drives the run:
|
|
|
94
94
|
Orbit supports three activation styles:
|
|
95
95
|
|
|
96
96
|
1. `/agent-orbit <goal>` — deterministic slash-command activation. In the Web
|
|
97
|
-
GUI it appears in the `/` menu (
|
|
98
|
-
engineering orchestration`); on headless/CLI surfaces a genuine user message
|
|
97
|
+
GUI it appears in the `/` menu (`使用 Orbit 确定性工程编排执行目标`); on headless/CLI surfaces a genuine user message
|
|
99
98
|
that starts with `/agent-orbit` activates Orbit directly. The original
|
|
100
99
|
command line stays visible in the conversation, the goal is passed through
|
|
101
100
|
without rewriting, and no goal asks for one instead of starting an empty run.
|
|
102
|
-
2. `orbit模式` — recommended natural-language activation, e.g.
|
|
101
|
+
2. `orbit模式` — recommended natural-language activation, e.g.
|
|
103
102
|
“用 orbit模式完成这个项目”.
|
|
104
|
-
3. `cx模式` — legacy compatibility; still resolves to Orbit.
|
|
103
|
+
3. `cx模式` — legacy compatibility; still resolves to Orbit.
|
|
105
104
|
|
|
106
105
|
All three routes converge on the existing `orbit_controller` tool and
|
|
107
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.
|
|
108
110
|
|
|
109
111
|
## Model configuration (Web)
|
|
110
112
|
|
|
@@ -113,20 +115,21 @@ seat (`conversation.input.right` renders before `conversation.input.model`).
|
|
|
113
115
|
Its button names the Commander's model; the menu edits three roles:
|
|
114
116
|
|
|
115
117
|
- **Commander** and **Watchdog** pick from the same native model catalog and
|
|
116
|
-
persist into the DSH `orbit` settings namespace (`settings.yaml`)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
inherited.
|
|
118
|
+
persist into the DSH `orbit` settings namespace (`settings.yaml`). Picking a
|
|
119
|
+
model first opens reasoning selection; nothing is saved until the user chooses
|
|
120
|
+
a catalog-declared effort or provider default. No effort is inferred.
|
|
120
121
|
- **Executor** follows the current session model ("Follows current session
|
|
121
122
|
model"). Both the Orbit row and the native seat read and write the SAME
|
|
122
123
|
per-session `ModelDirectory`, so a change in either place updates the other.
|
|
123
124
|
|
|
124
125
|
A new run resolves its routes exactly once — Commander/Watchdog from `orbit`
|
|
125
|
-
settings, Executor from the initiating session's current selection
|
|
126
|
-
|
|
126
|
+
settings, Executor from the initiating session's current selection — and freezes
|
|
127
|
+
them into `state.routes`. Orbit ships no provider/model or reasoning defaults.
|
|
127
128
|
Changes made while a run is active apply to the next run; resumed runs keep
|
|
128
|
-
their frozen routes.
|
|
129
|
-
|
|
129
|
+
their frozen routes. Explicit profile routes are permitted for headless/CLI:
|
|
130
|
+
Commander/Watchdog use settings then explicit config; Executor uses the Session
|
|
131
|
+
selection, with explicit config only when there is no Session. Missing or
|
|
132
|
+
unavailable roles block creation of a Run before any child starts.
|
|
130
133
|
|
|
131
134
|
## State machine
|
|
132
135
|
|
|
@@ -158,11 +161,16 @@ PLAN → EXECUTE → EVALUATE → SUCCESS
|
|
|
158
161
|
## Safety boundaries
|
|
159
162
|
|
|
160
163
|
- Commander and Watchdog receive read-only tool allowlists.
|
|
161
|
-
- Executors receive
|
|
162
|
-
|
|
164
|
+
- Executors always receive only base read tools (`read/read_image/glob/grep`).
|
|
165
|
+
Each Step explicitly declares `filesystem`, `shell`, `web`, or `browser` to
|
|
166
|
+
add only the corresponding tools. Legacy `web-api-recon` normalizes to `web`
|
|
167
|
+
plus `browser`. No capability means no bash, writers, web, or browser tools.
|
|
163
168
|
- While Orbit owns a workspace, other top-level autonomous drivers
|
|
164
169
|
(`create_goal`, `ralph`, `workflow`) are refused, and Orbit refuses to start
|
|
165
|
-
while an active
|
|
170
|
+
while an active Goal driver owns the same workspace. Only an Orbit-owned
|
|
171
|
+
Executor child can use mutation tools while Orbit owns that workspace.
|
|
172
|
+
- Bounded, redacted `step_results` preserve each Step's summary, changes and
|
|
173
|
+
test evidence. Cold resume retains them and FINAL_EVALUATE sees every Step.
|
|
166
174
|
- `.cx` durable state is written only by the Orbit service (atomic write, short
|
|
167
175
|
lock transaction, monotonic revision).
|
|
168
176
|
|
|
@@ -171,10 +179,10 @@ PLAN → EXECUTE → EVALUATE → SUCCESS
|
|
|
171
179
|
| Key | Default | Meaning |
|
|
172
180
|
|---|---|---|
|
|
173
181
|
| `projectDir` | session cwd | Project the run operates on. |
|
|
174
|
-
| `routes.commander` |
|
|
175
|
-
| `routes.executor` |
|
|
176
|
-
| `routes.watchdog` |
|
|
177
|
-
| `executorTools` | read/glob/grep
|
|
182
|
+
| `routes.commander` | none | Explicit profile fallback; normally user-selected in Orbit settings. |
|
|
183
|
+
| `routes.executor` | none | Explicit config only without a Session; otherwise follows DSH Session selection. |
|
|
184
|
+
| `routes.watchdog` | none | Explicit profile fallback; normally user-selected in Orbit settings. |
|
|
185
|
+
| `executorTools` | read/read_image/glob/grep | Base read-only subset; mutation tools require Step capabilities. |
|
|
178
186
|
| `browserTools` | `["agent_browser"]` | Browser capability tool names. |
|
|
179
187
|
| `commanderReadOnlyTools` | read/glob/grep/web… | Commander allowlist. |
|
|
180
188
|
| `watchdogTools` | read/glob/grep | Watchdog allowlist. |
|
package/cordis.patch.yml
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Adds the Orbit engineering orchestration plugin (OrbitService + orbit_controller
|
|
4
4
|
# tool; `cx_controller` remains a legacy alias) on top of the active bundle stack.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# Orbit does not ship model-route defaults. Users select Commander/Watchdog in
|
|
6
|
+
# Orbit settings; Executor follows the current DSH Session selection.
|
|
7
7
|
- insert:
|
|
8
8
|
- id: dsh-orbit
|
|
9
9
|
name: '@kasenri/dsh-orbit'
|
package/lib/activation.js
CHANGED
|
@@ -65,18 +65,18 @@ export function invokedOrbitMessage(messages) {
|
|
|
65
65
|
export function registerOrbitCommand(ctx) {
|
|
66
66
|
ctx.effect(() => ctx.commands.register({
|
|
67
67
|
name: AGENT_ORBIT_COMMAND,
|
|
68
|
-
description: '
|
|
69
|
-
input: { hint: '
|
|
68
|
+
description: '使用 Orbit 确定性工程编排执行目标',
|
|
69
|
+
input: { hint: '描述要交给 Orbit 完成的工程目标' },
|
|
70
70
|
handler(invocation) {
|
|
71
71
|
const goal = invocation.rawInput.trim();
|
|
72
72
|
if (goal === '') {
|
|
73
|
-
return { kind: 'error', text:
|
|
73
|
+
return { kind: 'error', text: `用法:/${AGENT_ORBIT_COMMAND} <goal>,请输入任务。` };
|
|
74
74
|
}
|
|
75
75
|
invocation.agent.followup(createUserMessage({
|
|
76
76
|
content: [{ type: 'text', text: `/${AGENT_ORBIT_COMMAND}${invocation.rawInput}` }],
|
|
77
77
|
source: { kind: 'user' },
|
|
78
78
|
}));
|
|
79
|
-
return { kind: 'success', text: 'Orbit
|
|
79
|
+
return { kind: 'success', text: 'Orbit 已激活,现有 Supervisor 将处理此目标。' };
|
|
80
80
|
},
|
|
81
81
|
}), 'dsh-orbit: /agent-orbit host command');
|
|
82
82
|
}
|
|
@@ -91,18 +91,18 @@ export function registerOrbitCommand(ctx) {
|
|
|
91
91
|
export function registerOrbitToggleCommand(ctx) {
|
|
92
92
|
ctx.effect(() => ctx.commands.register({
|
|
93
93
|
name: ORBIT_TOGGLE_COMMAND,
|
|
94
|
-
description: '
|
|
95
|
-
input: { hint: 'on
|
|
94
|
+
description: '启用或关闭本会话 Orbit,不启动 Run',
|
|
95
|
+
input: { hint: '请输入 on 或 off' },
|
|
96
96
|
handler(invocation) {
|
|
97
97
|
const enabled = parseOrbitToggle(invocation.rawInput);
|
|
98
98
|
if (enabled === undefined) {
|
|
99
|
-
return { kind: 'error', text:
|
|
99
|
+
return { kind: 'error', text: `用法:/${ORBIT_TOGGLE_COMMAND} on|off,请输入 on 或 off。` };
|
|
100
100
|
}
|
|
101
101
|
return {
|
|
102
102
|
kind: 'success',
|
|
103
103
|
text: enabled
|
|
104
|
-
? 'Orbit
|
|
105
|
-
: 'Orbit
|
|
104
|
+
? '本会话 Orbit 已启用,普通消息将进入 Orbit。'
|
|
105
|
+
: '本会话 Orbit 已关闭,普通消息使用原生执行方式。',
|
|
106
106
|
};
|
|
107
107
|
},
|
|
108
108
|
}), 'dsh-orbit: /orbit-toggle host command');
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const EXECUTOR_READ_ONLY_TOOLS = ['read', 'read_image', 'glob', 'grep'];
|
|
2
|
+
export const FILESYSTEM_TOOLS = ['write', 'edit', 'str_replace_editor'];
|
|
3
|
+
export const SHELL_TOOLS = ['bash'];
|
|
4
|
+
export const WEB_TOOLS = ['web_search', 'web_fetch'];
|
|
5
|
+
export const READ_ONLY_ROLE_TOOLS = [...EXECUTOR_READ_ONLY_TOOLS, ...WEB_TOOLS];
|
|
6
|
+
const READ_ONLY_SET = new Set(EXECUTOR_READ_ONLY_TOOLS);
|
|
7
|
+
/** Deterministically map bounded capability ids to tool names. */
|
|
8
|
+
export function executorToolsFor(capabilities, browserTools, configuredReadOnly = EXECUTOR_READ_ONLY_TOOLS) {
|
|
9
|
+
const tools = configuredReadOnly.filter((tool) => READ_ONLY_SET.has(tool));
|
|
10
|
+
if (capabilities.includes('filesystem'))
|
|
11
|
+
tools.push(...FILESYSTEM_TOOLS);
|
|
12
|
+
if (capabilities.includes('shell'))
|
|
13
|
+
tools.push(...SHELL_TOOLS);
|
|
14
|
+
if (capabilities.includes('web'))
|
|
15
|
+
tools.push(...WEB_TOOLS);
|
|
16
|
+
if (capabilities.includes('browser'))
|
|
17
|
+
tools.push(...browserTools);
|
|
18
|
+
return [...new Set(tools)];
|
|
19
|
+
}
|
|
20
|
+
/** Tools that can mutate workspace or browser state while Orbit owns it. */
|
|
21
|
+
export function mutationTools(browserTools) {
|
|
22
|
+
return new Set([...FILESYSTEM_TOOLS, ...SHELL_TOOLS, 'pwsh', 'apply_patch', 'delete_file', 'move_file', ...browserTools]);
|
|
23
|
+
}
|
package/lib/client.js
CHANGED
|
@@ -19,46 +19,22 @@ window.__ModuleLoader__.load({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* picker
|
|
25
|
-
* selection error path.
|
|
26
|
-
*/
|
|
27
|
-
const FALLBACK_REASONING_EFFORTS = [
|
|
28
|
-
"low",
|
|
29
|
-
"medium",
|
|
30
|
-
"high",
|
|
31
|
-
"xhigh",
|
|
32
|
-
"max"
|
|
33
|
-
];
|
|
34
|
-
const FALLBACK_EFFORT_LABELS = {
|
|
35
|
-
low: "Low",
|
|
36
|
-
medium: "Medium",
|
|
37
|
-
high: "High",
|
|
38
|
-
xhigh: "XHigh",
|
|
39
|
-
max: "Max"
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Effort options for one model: the adapter's explicit list when the catalog
|
|
43
|
-
* declares one, otherwise the Orbit UI fallback ladder.
|
|
22
|
+
* Effort options for one model: exactly the DSH model metadata's explicit
|
|
23
|
+
* `reasoning.efforts`. A model without reasoning metadata yields none; the
|
|
24
|
+
* picker then offers only Provider default.
|
|
44
25
|
*/
|
|
45
26
|
function effortsOf(model) {
|
|
46
|
-
|
|
47
|
-
if (explicit.length > 0) return explicit.map((effort) => ({
|
|
27
|
+
return (model?.reasoning?.efforts ?? []).map((effort) => ({
|
|
48
28
|
id: effort.id,
|
|
49
29
|
name: effort.name
|
|
50
30
|
}));
|
|
51
|
-
return FALLBACK_REASONING_EFFORTS.map((id) => ({
|
|
52
|
-
id,
|
|
53
|
-
name: FALLBACK_EFFORT_LABELS[id] ?? id
|
|
54
|
-
}));
|
|
55
31
|
}
|
|
56
32
|
/** Human effort label for a stored effort id; falls back to the raw id. */
|
|
57
33
|
function effortLabelOf(model, effort) {
|
|
58
34
|
if (effort === void 0 || effort === "") return void 0;
|
|
59
35
|
const explicit = model?.reasoning?.efforts.find((entry) => entry.id === effort);
|
|
60
36
|
if (explicit !== void 0) return explicit.name;
|
|
61
|
-
return
|
|
37
|
+
return effort;
|
|
62
38
|
}
|
|
63
39
|
/** Display name for a stored route: catalog name, then its model id. */
|
|
64
40
|
function routeLabelOf(state, route) {
|
|
@@ -66,33 +42,19 @@ window.__ModuleLoader__.load({
|
|
|
66
42
|
return modelOf(state, route)?.name ?? route.model;
|
|
67
43
|
}
|
|
68
44
|
/**
|
|
69
|
-
* Route for a freshly picked model:
|
|
70
|
-
*
|
|
71
|
-
* never inherited.
|
|
45
|
+
* Route for a freshly picked model: no reasoning effort is adopted, not even
|
|
46
|
+
* the catalog metadata's `defaultEffort`. Provider default means the absent
|
|
47
|
+
* effort, and a previous model's effort is never inherited.
|
|
72
48
|
*/
|
|
73
49
|
function routeForModel(provider, model) {
|
|
74
|
-
const defaultEffort = model.reasoning?.defaultEffort;
|
|
75
|
-
return {
|
|
76
|
-
provider,
|
|
77
|
-
model: model.id,
|
|
78
|
-
...defaultEffort === void 0 ? {} : { reasoningEffort: defaultEffort }
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Selection for the shared Session directory: preserve the current effort
|
|
83
|
-
* when the route did not change, otherwise use the picked model's default.
|
|
84
|
-
*/
|
|
85
|
-
function selectionForModel(state, provider, model) {
|
|
86
|
-
const effort = state.current?.provider === provider && state.current.model === model.id ? state.current?.reasoningEffort ?? model.reasoning?.defaultEffort : model.reasoning?.defaultEffort;
|
|
87
50
|
return {
|
|
88
51
|
provider,
|
|
89
|
-
model: model.id
|
|
90
|
-
...effort === void 0 ? {} : { reasoningEffort: effort }
|
|
52
|
+
model: model.id
|
|
91
53
|
};
|
|
92
54
|
}
|
|
93
55
|
/**
|
|
94
56
|
* Effort rows for one model: Provider default (an undefined effort) first,
|
|
95
|
-
* then the model's explicit
|
|
57
|
+
* then the model's explicit metadata efforts, if any.
|
|
96
58
|
*/
|
|
97
59
|
function effortChoicesOf(model, providerDefaultLabel) {
|
|
98
60
|
return [{
|
|
@@ -132,22 +94,22 @@ window.__ModuleLoader__.load({
|
|
|
132
94
|
document.head.appendChild(tag);
|
|
133
95
|
}
|
|
134
96
|
var OrbitModelSelect_module_css_default = {
|
|
135
|
-
"back": "f77nca_back",
|
|
136
|
-
"rowLabel": "f77nca_rowLabel",
|
|
137
97
|
"title": "f77nca_title",
|
|
138
|
-
"row": "f77nca_row",
|
|
139
|
-
"hint": "f77nca_hint",
|
|
140
|
-
"switchRow": "f77nca_switchRow",
|
|
141
98
|
"panel": "f77nca_panel",
|
|
99
|
+
"switchControl": "f77nca_switchControl",
|
|
100
|
+
"error": "f77nca_error",
|
|
142
101
|
"rowDetail": "f77nca_rowDetail",
|
|
102
|
+
"chevron": "f77nca_chevron",
|
|
143
103
|
"group": "f77nca_group",
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
104
|
+
"row": "f77nca_row",
|
|
105
|
+
"switchRow": "f77nca_switchRow",
|
|
106
|
+
"hint": "f77nca_hint",
|
|
147
107
|
"rowValueActive": "f77nca_rowValueActive",
|
|
148
|
-
"
|
|
108
|
+
"rowValue": "f77nca_rowValue",
|
|
109
|
+
"rowLabel": "f77nca_rowLabel",
|
|
149
110
|
"check": "f77nca_check",
|
|
150
|
-
"separator": "f77nca_separator"
|
|
111
|
+
"separator": "f77nca_separator",
|
|
112
|
+
"back": "f77nca_back"
|
|
151
113
|
};
|
|
152
114
|
//#endregion
|
|
153
115
|
//#region client/OrbitModelSelect.tsx
|
|
@@ -200,6 +162,7 @@ window.__ModuleLoader__.load({
|
|
|
200
162
|
const [open, setOpen] = (0, react.useState)(false);
|
|
201
163
|
const [pane, setPane] = (0, react.useState)({ kind: "root" });
|
|
202
164
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
165
|
+
const submitting = (0, react.useRef)(false);
|
|
203
166
|
const triggerRef = (0, react.useRef)(null);
|
|
204
167
|
const panelRef = (0, react.useRef)(null);
|
|
205
168
|
const position = (0, _deepseek_ai_dsh_client_ui_primitives.useAnchoredPosition)({
|
|
@@ -236,16 +199,26 @@ window.__ModuleLoader__.load({
|
|
|
236
199
|
const watchdogLabel = watchdogRoute === void 0 ? void 0 : routeLabelOf(dir, watchdogRoute) ?? watchdogRoute.model;
|
|
237
200
|
const watchdogEffort = effortLabelOf(watchdogModel, watchdogRoute?.reasoningEffort);
|
|
238
201
|
const commitRole = async (role, route) => {
|
|
202
|
+
if (submitting.current || config.status !== "ready") return;
|
|
203
|
+
submitting.current = true;
|
|
239
204
|
setBusy(true);
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
205
|
+
try {
|
|
206
|
+
if (await writeRole(role, route)) setOpen(false);
|
|
207
|
+
} finally {
|
|
208
|
+
submitting.current = false;
|
|
209
|
+
setBusy(false);
|
|
210
|
+
}
|
|
243
211
|
};
|
|
244
212
|
const commitExecutor = async (selection) => {
|
|
213
|
+
if (submitting.current) return;
|
|
214
|
+
submitting.current = true;
|
|
245
215
|
setBusy(true);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
216
|
+
try {
|
|
217
|
+
if (await selectModel(selection)) setOpen(false);
|
|
218
|
+
} finally {
|
|
219
|
+
submitting.current = false;
|
|
220
|
+
setBusy(false);
|
|
221
|
+
}
|
|
249
222
|
};
|
|
250
223
|
const currentRouteOf = (role) => role === "commander" ? config.commander : role === "watchdog" ? config.watchdog : executorRoute;
|
|
251
224
|
const roleLabelOf = (role) => role === "commander" ? commanderLabel : role === "watchdog" ? watchdogLabel : executorLabel;
|
|
@@ -272,15 +245,11 @@ window.__ModuleLoader__.load({
|
|
|
272
245
|
className: OrbitModelSelect_module_css_default.row,
|
|
273
246
|
disabled: busy,
|
|
274
247
|
onClick: () => {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
commitExecutor(selectionForModel(dir, provider, model));
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
commitRole(role, routeForModel(provider, model));
|
|
248
|
+
setPane({
|
|
249
|
+
kind: "efforts",
|
|
250
|
+
role,
|
|
251
|
+
draft: routeForModel(provider, model)
|
|
252
|
+
});
|
|
284
253
|
},
|
|
285
254
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
286
255
|
className: OrbitModelSelect_module_css_default.rowLabel,
|
|
@@ -294,7 +263,7 @@ window.__ModuleLoader__.load({
|
|
|
294
263
|
}) : null]
|
|
295
264
|
}, `${provider}/${model.id}`);
|
|
296
265
|
};
|
|
297
|
-
const effortPaneRoute = pane.kind === "efforts" ? currentRouteOf(pane.role) : void 0;
|
|
266
|
+
const effortPaneRoute = pane.kind === "efforts" ? pane.draft ?? currentRouteOf(pane.role) : void 0;
|
|
298
267
|
const effortPaneModel = modelOf(dir, effortPaneRoute);
|
|
299
268
|
const effortPaneChoices = pane.kind === "efforts" ? effortChoicesOf(effortPaneModel, t("providerDefault")) : [];
|
|
300
269
|
const settingsError = config.error;
|
|
@@ -553,7 +522,7 @@ window.__ModuleLoader__.load({
|
|
|
553
522
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
554
523
|
className: OrbitModelSelect_module_css_default.rowLabel,
|
|
555
524
|
children: choice.label
|
|
556
|
-
}), effortPaneRoute.reasoningEffort === choice.effort ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
525
|
+
}), pane.draft === void 0 && effortPaneRoute.reasoningEffort === choice.effort ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
557
526
|
className: OrbitModelSelect_module_css_default.check,
|
|
558
527
|
children: "✓"
|
|
559
528
|
}) : null]
|
|
@@ -571,7 +540,7 @@ window.__ModuleLoader__.load({
|
|
|
571
540
|
const NS = "orbit-model";
|
|
572
541
|
/** English strings (the key-set source of truth for this pair). */
|
|
573
542
|
const en = {
|
|
574
|
-
triggerFallback: "
|
|
543
|
+
triggerFallback: "Not configured",
|
|
575
544
|
tooltip: "Orbit model configuration",
|
|
576
545
|
title: "Orbit — Self-reviewing continuous execution",
|
|
577
546
|
enableLongRun: "Enable long-running execution",
|
|
@@ -596,7 +565,7 @@ window.__ModuleLoader__.load({
|
|
|
596
565
|
};
|
|
597
566
|
/** Chinese strings. */
|
|
598
567
|
const zh = {
|
|
599
|
-
triggerFallback: "
|
|
568
|
+
triggerFallback: "未配置",
|
|
600
569
|
tooltip: "Orbit 模型配置",
|
|
601
570
|
title: "Orbit 让AI自我审核连续执行",
|
|
602
571
|
enableLongRun: "启用一键长执行",
|
|
@@ -690,6 +659,7 @@ window.__ModuleLoader__.load({
|
|
|
690
659
|
}, "dsh-orbit: settings mirror");
|
|
691
660
|
const writeRole = async (role, route) => {
|
|
692
661
|
const snapshot = settings.getSnapshot();
|
|
662
|
+
if (snapshot.status !== "ready" || snapshot.revision === void 0) return false;
|
|
693
663
|
try {
|
|
694
664
|
const response = await ctx.remote.settings.update(ORBIT_SETTINGS_NS, { [role]: {
|
|
695
665
|
provider: route.provider,
|
package/lib/decisions.js
CHANGED
|
@@ -14,16 +14,16 @@ export const COMMANDER_PLAN_SCHEMA = {
|
|
|
14
14
|
additionalProperties: false,
|
|
15
15
|
required: ['summary', 'steps'],
|
|
16
16
|
properties: {
|
|
17
|
-
summary: { type: 'string', description: '
|
|
17
|
+
summary: { type: 'string', description: '一句话计划摘要。' },
|
|
18
18
|
steps: {
|
|
19
19
|
type: 'array',
|
|
20
|
-
description: '
|
|
20
|
+
description: '1-5 个逻辑工程步骤。',
|
|
21
21
|
items: {
|
|
22
22
|
type: 'object',
|
|
23
23
|
additionalProperties: false,
|
|
24
24
|
required: ['goal'],
|
|
25
25
|
properties: {
|
|
26
|
-
id: { type: 'string', description: '
|
|
26
|
+
id: { type: 'string', description: '稳定标识,例如 P0。' },
|
|
27
27
|
goal: { type: 'string' },
|
|
28
28
|
capabilities: { type: 'array', items: { type: 'string', enum: CAPABILITY_ENUM } },
|
|
29
29
|
},
|
|
@@ -94,7 +94,7 @@ export const WATCHDOG_STRATEGY_SCHEMA = {
|
|
|
94
94
|
additionalProperties: false,
|
|
95
95
|
required: ['question'],
|
|
96
96
|
properties: {
|
|
97
|
-
question: { type: 'string', description: '
|
|
97
|
+
question: { type: 'string', description: '提交给 Commander 的单个策略质疑问题。' },
|
|
98
98
|
},
|
|
99
99
|
};
|
|
100
100
|
export const WATCHDOG_GUARD_SCHEMA = {
|