@kasenri/dsh-orbit 0.5.9 → 0.5.10

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 CHANGED
@@ -3,10 +3,12 @@
3
3
  Community plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH).
4
4
  Not affiliated with or endorsed by DeepSeek.
5
5
 
6
+ **让 AI 项目可以在无人监管下持续推进。**
7
+ Orbit 会自动规划任务、分工执行、逐步检查并继续完成后续工作;不同环节可以使用不同模型,让低成本模型承担执行任务、强模型负责规划和审核,从而降低整体 AI 使用成本。Watchdog 还会监控运行异常,在任务卡死或中断时协助恢复。
8
+
6
9
  **Orbit — Deterministic Engineering Orchestration for DeepSeek Harness**
7
10
 
8
- Orbit is a deterministic engineering orchestration runtime for DSH, implemented
9
- as a Cordis plugin:
11
+ Technical integration:
10
12
 
11
13
  - an `OrbitService` on `ctx.orbit`
12
14
  - a model-facing `orbit_controller` tool (`cx_controller` remains a legacy alias)
@@ -110,9 +112,10 @@ provider/model provenance. The parent model and parent tools remain bypassed.
110
112
 
111
113
  ## Model configuration (Web)
112
114
 
113
- The Orbit model control sits immediately left of the native composer model
114
- seat (`conversation.input.right` renders before `conversation.input.model`).
115
- Its button names the Commander's model; the menu edits three roles:
115
+ The Orbit model control is the final entry in `conversation.input.right`, so
116
+ other composer-side controls (for example DSH's rollback control) stay to its
117
+ left while the native `conversation.input.model` seat stays immediately to its
118
+ right. Its button names the Commander's model; the menu edits three roles:
116
119
 
117
120
  - **Commander** and **Watchdog** pick from the same native model catalog and
118
121
  persist into the DSH `orbit` settings namespace (`settings.yaml`). Picking a
@@ -143,6 +146,11 @@ PLAN → EXECUTE → EVALUATE → SUCCESS
143
146
  ```
144
147
 
145
148
  - Only a normally completed Executor step consumes one loop from the budget.
149
+ - Runs without an explicit user/tool budget start from the historical floor of
150
+ 5 loops; after PLAN, Orbit deterministically reserves two extra bounded slots
151
+ beyond the accepted base plan (`max(5, steps + 2)`, therefore at most 7 for
152
+ the 1–5-step plan schema). Explicit `approved_loop_count` / `max_loops`
153
+ values are never enlarged automatically.
146
154
  - Corrections are limited per base step and reserve budget for the remaining
147
155
  planned steps.
148
156
  - Commander decisions are validated in code (`PASS_CURRENT_STEP` /
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
+ "check": "f77nca_check",
98
+ "chevron": "f77nca_chevron",
99
+ "rowDetail": "f77nca_rowDetail",
97
100
  "title": "f77nca_title",
101
+ "separator": "f77nca_separator",
102
+ "row": "f77nca_row",
103
+ "group": "f77nca_group",
98
104
  "panel": "f77nca_panel",
105
+ "rowLabel": "f77nca_rowLabel",
106
+ "rowValue": "f77nca_rowValue",
107
+ "hint": "f77nca_hint",
108
+ "back": "f77nca_back",
99
109
  "switchControl": "f77nca_switchControl",
100
- "error": "f77nca_error",
101
- "rowDetail": "f77nca_rowDetail",
102
- "chevron": "f77nca_chevron",
103
- "group": "f77nca_group",
104
- "row": "f77nca_row",
105
110
  "switchRow": "f77nca_switchRow",
106
- "hint": "f77nca_hint",
107
- "rowValueActive": "f77nca_rowValueActive",
108
- "rowValue": "f77nca_rowValue",
109
- "rowLabel": "f77nca_rowLabel",
110
- "check": "f77nca_check",
111
- "separator": "f77nca_separator",
112
- "back": "f77nca_back"
111
+ "error": "f77nca_error",
112
+ "rowValueActive": "f77nca_rowValueActive"
113
113
  };
114
114
  //#endregion
115
115
  //#region client/OrbitModelSelect.tsx
@@ -592,6 +592,13 @@ window.__ModuleLoader__.load({
592
592
  //#region client/index.ts
593
593
  /** The host settings namespace Orbit registers for its own two roles. */
594
594
  const ORBIT_SETTINGS_NS = "orbit";
595
+ /**
596
+ * Keep Orbit as the final list entry in `conversation.input.right`.
597
+ * DSH renders the whole right list before the named model seat, so this gives
598
+ * the stable local order: other right-side controls → Orbit → model selector.
599
+ */
600
+ const ORBIT_INPUT_RIGHT_PRIORITY = Number.MAX_SAFE_INTEGER;
601
+ const ORBIT_INPUT_RIGHT_ORDER = Number.MAX_SAFE_INTEGER;
595
602
  /** Required client services: slots, the shared model directory, Remote (settings namespace), and locale. */
596
603
  const inject = [
597
604
  "slots",
@@ -718,13 +725,16 @@ window.__ModuleLoader__.load({
718
725
  scope.slots.inject("conversation.input.right", () => scope.slots.register({
719
726
  name: "conversation.input.right",
720
727
  id: "orbit-model",
721
- order: 10,
728
+ priority: ORBIT_INPUT_RIGHT_PRIORITY,
729
+ order: ORBIT_INPUT_RIGHT_ORDER,
722
730
  locale: NS,
723
731
  inject: injected
724
732
  }, OrbitModelSelect));
725
733
  });
726
734
  }
727
735
  //#endregion
736
+ exports.ORBIT_INPUT_RIGHT_ORDER = ORBIT_INPUT_RIGHT_ORDER;
737
+ exports.ORBIT_INPUT_RIGHT_PRIORITY = ORBIT_INPUT_RIGHT_PRIORITY;
728
738
  exports.ORBIT_SETTINGS_NS = ORBIT_SETTINGS_NS;
729
739
  exports.apply = apply;
730
740
  exports.inject = inject;
package/lib/index.js CHANGED
@@ -6,11 +6,6 @@ import { agentDefaultSelectionOf, resolveEffectiveRoutes, sessionModelSelectionO
6
6
  import { installOrbitSessionProjection, orbitEnabledOf } from "./session-state.js";
7
7
  import { OrbitService } from "./service.js";
8
8
  import { createOrbitTool } from "./tool.js";
9
- /**
10
- * Fixed hard-activation budget. Explicit tool calls may still supply a bounded
11
- * user-owned budget; ordinary activation never guesses complexity from words.
12
- */
13
- const HARD_ACTIVATION_LOOP_BUDGET = 5;
14
9
  export const name = 'dsh-orbit';
15
10
  export const inject = ['tools', 'agents', 'subagents'];
16
11
  const Route = z.object({
@@ -126,10 +121,7 @@ export function apply(ctx, config) {
126
121
  try {
127
122
  // The initiator scope makes the run's children belong to this Agent;
128
123
  // the parent model is never asked to decide or to run the task.
129
- result = await ctx.agents.withInitiator(agent, () => service.run({
130
- goal,
131
- approved_loop_count: HARD_ACTIVATION_LOOP_BUDGET,
132
- }, cwd, signal));
124
+ result = await ctx.agents.withInitiator(agent, () => service.run({ goal }, cwd, signal));
133
125
  }
134
126
  catch (error) {
135
127
  appendOrbitNotice(agent.session, `Orbit 启动失败:${error instanceof Error ? error.message : String(error)}`);
package/lib/kernel.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * read a clock, or use randomness. Runtime values (routes, timestamps, run ids)
6
6
  * are supplied by the supervisor, which owns orchestration and persistence.
7
7
  */
8
- import { MAX_CORRECTION_DEPTH, DEFAULT_LOOP_BUDGET, MAX_PLAN_STEPS, MAX_WATCHDOG_CALLS_PER_STEP, MIN_PLAN_STEPS, ORBIT_SCHEMA_VERSION, } from "./types.js";
8
+ import { MAX_CORRECTION_DEPTH, DEFAULT_LOOP_BUDGET, AUTOMATIC_LOOP_RECOVERY_RESERVE, MAX_AUTOMATIC_LOOP_BUDGET, MAX_PLAN_STEPS, MAX_WATCHDOG_CALLS_PER_STEP, MIN_PLAN_STEPS, ORBIT_SCHEMA_VERSION, } from "./types.js";
9
9
  /** Capabilities a plan step may request. */
10
10
  export const ORBIT_CAPABILITIES = ['filesystem', 'shell', 'web', 'browser'];
11
11
  const STEP_CAPABILITIES = new Set(ORBIT_CAPABILITIES);
@@ -83,6 +83,29 @@ export function updateLoopBudget(state, budget) {
83
83
  state.loop_count = state.loop.used;
84
84
  state.remaining_budget = Math.max(0, budget - state.loop.used);
85
85
  }
86
+ /**
87
+ * Deterministic budget for an Orbit-owned run after PLAN is known.
88
+ * Small plans keep the historical floor of five; four/five-step plans gain two
89
+ * bounded recovery slots, with a hard automatic ceiling of seven.
90
+ */
91
+ export function automaticLoopBudgetForPlan(stepCount) {
92
+ if (!Number.isSafeInteger(stepCount) || stepCount < MIN_PLAN_STEPS || stepCount > MAX_PLAN_STEPS) {
93
+ throw new Error(`ORBIT_PLAN_STEP_COUNT_INVALID: expected ${MIN_PLAN_STEPS}-${MAX_PLAN_STEPS}, got ${stepCount}`);
94
+ }
95
+ return Math.min(MAX_AUTOMATIC_LOOP_BUDGET, Math.max(DEFAULT_LOOP_BUDGET, stepCount + AUTOMATIC_LOOP_RECOVERY_RESERVE));
96
+ }
97
+ /**
98
+ * Expand only Orbit-owned automatic budgets. Explicit user/tool budgets and
99
+ * old states without a recorded mode are never silently increased.
100
+ */
101
+ export function ensureAutomaticLoopBudgetForPlan(state) {
102
+ if (state.loop_budget_mode !== 'automatic')
103
+ return;
104
+ const baseSteps = state.plan.steps.filter((step) => isBaseStepId(step.id)).length;
105
+ const target = automaticLoopBudgetForPlan(baseSteps);
106
+ if (target > state.loop.max)
107
+ updateLoopBudget(state, target);
108
+ }
86
109
  export function hashGoal(goal) {
87
110
  let hash = 0;
88
111
  for (let index = 0; index < goal.length; index += 1) {
@@ -123,8 +146,8 @@ export function correctionBlockCode(state, step) {
123
146
  return undefined;
124
147
  }
125
148
  export function createInitialState(input) {
126
- const max = explicitLoopBudget({ approved_loop_count: input.approvedLoopCount, max_loops: input.maxLoops }) ??
127
- DEFAULT_LOOP_BUDGET;
149
+ const explicit = explicitLoopBudget({ approved_loop_count: input.approvedLoopCount, max_loops: input.maxLoops });
150
+ const max = explicit ?? DEFAULT_LOOP_BUDGET;
128
151
  return {
129
152
  schema_version: ORBIT_SCHEMA_VERSION,
130
153
  active_run_id: input.runId,
@@ -139,6 +162,7 @@ export function createInitialState(input) {
139
162
  preset: input.preset ?? 'orbit-lite',
140
163
  routes: structuredClone(input.routes),
141
164
  loop: { used: 0, max },
165
+ loop_budget_mode: explicit === undefined ? 'automatic' : 'explicit',
142
166
  approved_loop_count: max,
143
167
  remaining_budget: max,
144
168
  loop_count: 0,
package/lib/supervisor.js CHANGED
@@ -2,7 +2,7 @@ import { join } from 'node:path';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { buildEvidenceBundle, buildStepResult, formatStepResults, formatEvidenceBundle } from "./evidence.js";
4
4
  import { assertCommanderDecision, assertStrategyDecision, assertTimeoutDecision, assertWatchdogDecision, assertGuardWatchdogDecision, COMMANDER_FINAL_EVALUATE_SCHEMA, COMMANDER_PLAN_SCHEMA, COMMANDER_STEP_EVALUATE_SCHEMA, COMMANDER_STRATEGY_SCHEMA, WATCHDOG_GUARD_SCHEMA, WATCHDOG_RUNTIME_SCHEMA, WATCHDOG_STRATEGY_SCHEMA, WATCHDOG_TIMEOUT_SCHEMA, } from "./decisions.js";
5
- import { applyCommanderNeedsUser, applyCorrectionStep, applyExecutorCapabilityUnavailable, applyExecutorInterrupted, applyExecutorResume, applyExecutorSuccess, applyFinalAppend, applyFinalSuccess, applyPlan, applyStepPass, baseStepIdOf, beginStep, clearExecutorChild, clearGuardRecovery, correctionBlockCode, correctionDepthOf, createInitialState, enterBudgetExhausted, enterNeedsUser, markStrategyChallengeUsed, normalizePlan, openWatchdogAttempt, recordGuardRecovery, recordPlanFailure, recordWatchdogDecision, restoreEvaluationState, resumeFromNeedsUser, stopRun, upsertStepResult, normalizeCapabilities, } from "./kernel.js";
5
+ import { applyCommanderNeedsUser, applyCorrectionStep, applyExecutorCapabilityUnavailable, applyExecutorInterrupted, applyExecutorResume, applyExecutorSuccess, applyFinalAppend, applyFinalSuccess, applyPlan, applyStepPass, baseStepIdOf, beginStep, clearExecutorChild, clearGuardRecovery, correctionBlockCode, correctionDepthOf, createInitialState, enterBudgetExhausted, enterNeedsUser, ensureAutomaticLoopBudgetForPlan, markStrategyChallengeUsed, normalizePlan, openWatchdogAttempt, recordGuardRecovery, recordPlanFailure, recordWatchdogDecision, restoreEvaluationState, resumeFromNeedsUser, stopRun, upsertStepResult, normalizeCapabilities, } from "./kernel.js";
6
6
  import { truncateSafe } from "./sanitize.js";
7
7
  import { OrbitStateStore } from "./state-store.js";
8
8
  import { executorToolsFor, EXECUTOR_READ_ONLY_TOOLS, READ_ONLY_ROLE_TOOLS } from "./capabilities.js";
@@ -305,6 +305,7 @@ export class OrbitSupervisor {
305
305
  try {
306
306
  const plan = normalizePlan(outcome.structured);
307
307
  applyPlan(state, plan);
308
+ ensureAutomaticLoopBudgetForPlan(state);
308
309
  this.store.writeState(state);
309
310
  return undefined;
310
311
  }
package/lib/types.js CHANGED
@@ -13,6 +13,9 @@ export const MAX_EXECUTOR_INTERRUPT_RETRIES = 2;
13
13
  export const MAX_PLAN_STEPS = 5;
14
14
  export const MIN_PLAN_STEPS = 1;
15
15
  export const DEFAULT_LOOP_BUDGET = 5;
16
+ /** Automatic runs reserve two bounded execution slots beyond the accepted base plan. */
17
+ export const AUTOMATIC_LOOP_RECOVERY_RESERVE = 2;
18
+ export const MAX_AUTOMATIC_LOOP_BUDGET = MAX_PLAN_STEPS + AUTOMATIC_LOOP_RECOVERY_RESERVE;
16
19
  export const GUARD_FIRST_INSTRUCTION = '请改用更安全的方法继续当前任务,不要原样重试刚被阻断的操作。';
17
20
  export const GUARD_REPEAT_INSTRUCTION = '同一操作再次被阻断。请停止重复,并选择不同的安全方案。';
18
21
  export const GUARD_RETRY_INSTRUCTION = '之前的方案反复触发 Orbit 安全护栏。请改用不同的安全方案,不要重试被阻断的操作。';
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@kasenri/dsh-orbit",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "type": "module",
5
- "description": "Deterministic engineering orchestration for DeepSeek Harness with Commander, Executor, Smart Watchdog, bounded recovery and durable execution state.",
5
+ "description": " AI 项目可以在无人监管下持续推进。Orbit 会自动规划任务、分工执行、逐步检查并继续完成后续工作;不同环节可以使用不同模型,让低成本模型承担执行任务、强模型负责规划和审核,从而降低整体 AI 使用成本。Watchdog 还会监控运行异常,在任务卡死或中断时协助恢复。",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",