sortie-dogs 0.11.1 → 0.11.3

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
@@ -51,6 +51,12 @@ The auxiliary settings select Luna6 Fast for summaries and titles. Keep any
51
51
  additional settings on those agents. Sortie permits SOL6 and Luna6 for its
52
52
  execution requests; reviewer/advisor model selections are independent.
53
53
 
54
+ The package exposes a native `./tui` entry for the live work overview. If you use
55
+ a local V2 wrapper, place `export { default } from "sortie-dogs/server";` in
56
+ `.opencode/plugins/sortie-dogs/index.js` and register that directory. `init` installs
57
+ its companion `tui.tsx` alongside it. For a global installation, use the same
58
+ `plugins/sortie-dogs/` layout under the OpenCode global config directory.
59
+
54
60
  Restart the OpenCode host after installing or updating the plugin, then run:
55
61
 
56
62
  ```text
@@ -63,6 +69,21 @@ is an internal implementation child. The default V2 package export and
63
69
 
64
70
  ## How v0.11 works
65
71
 
72
+ ### Feedback and supervision
73
+
74
+ Send corrections in the same conversation. The original request and subsequent
75
+ instructions are retained across interruptions and compaction and are delivered
76
+ to the same implementation child. The operator inspects real results before
77
+ continuing or accepting the work. Native controller ledgers can keep long jobs
78
+ running and return control to that operator when they finish.
79
+
80
+ Progress checkpoints wait for a native response boundary; an in-flight provider
81
+ response keeps its native timeout. A checkpoint does not mean the user's task is
82
+ complete. Required checks, attempts and known/unknown costs remain cumulative.
83
+ Feedback retention is per job: the v0.11 loop does not automatically apply the
84
+ v0.10 reflection policy to future jobs. Reproducible product feedback is recorded
85
+ in [the v0.11.2 dogfooding incident](docs/feedback/v0112-redispatch-loop.md).
86
+
66
87
  1. **Keep the original request.** The host retains the user's words, attachments,
67
88
  selected skills and subsequent instructions in durable plugin storage.
68
89
  2. **Delegate practical work.** The operator adds short guidance and dispatches
@@ -4,5 +4,5 @@
4
4
  */
5
5
  export declare const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
6
  export declare const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1-v2-depth1-process-replacement1-unstarted-v2-1-cold-turn1-return-report-v2-2-root-revision1";
7
- export declare const V011_RUNTIME_ASSET_VERSION = "0.11.1-user-proxy-native-v4-progress-recovery";
7
+ export declare const V011_RUNTIME_ASSET_VERSION = "0.11.3-cooperative-progress-v1";
8
8
  export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION | typeof V011_RUNTIME_ASSET_VERSION;
@@ -4,4 +4,4 @@
4
4
  */
5
5
  export const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
6
6
  export const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1-v2-depth1-process-replacement1-unstarted-v2-1-cold-turn1-return-report-v2-2-root-revision1";
7
- export const V011_RUNTIME_ASSET_VERSION = "0.11.1-user-proxy-native-v4-progress-recovery";
7
+ export const V011_RUNTIME_ASSET_VERSION = "0.11.3-cooperative-progress-v1";
@@ -7,7 +7,7 @@ export declare const WORK_LIMITS: {
7
7
  readonly checks: 128;
8
8
  readonly outputBytes: number;
9
9
  };
10
- export type WorkPhase = "ready" | "running" | "review" | "blocked" | "interrupted" | "completed" | "cancelled";
10
+ export type WorkPhase = "ready" | "running" | "waiting" | "review" | "yielded" | "blocked" | "interrupted" | "completed" | "cancelled";
11
11
  export interface WorkRequest {
12
12
  id: string;
13
13
  text: string;
@@ -35,12 +35,44 @@ export interface WorkCheck {
35
35
  after: string;
36
36
  output: string;
37
37
  at: number;
38
+ pending?: boolean;
38
39
  }
39
40
  export interface WorkCheckReplacement {
40
41
  check: string;
41
42
  replacement: string;
42
43
  reason: string;
43
44
  }
45
+ export interface WorkCommand {
46
+ id: string;
47
+ callID: string;
48
+ command: string;
49
+ timeout: number;
50
+ at: number;
51
+ status: "launching" | "completed" | "interrupted";
52
+ exit: number | null;
53
+ output: string;
54
+ nativeID?: string;
55
+ nativeFile?: string;
56
+ nativeStatus?: string;
57
+ retryOf?: string;
58
+ }
59
+ export interface WorkUsageReceipt {
60
+ session: string;
61
+ model: string;
62
+ tokens: number | null;
63
+ usd: number | null;
64
+ tier?: string;
65
+ requestedTier?: string;
66
+ local?: boolean;
67
+ pending?: boolean;
68
+ }
69
+ export interface WorkAuxiliaryUsage {
70
+ id: string;
71
+ root: string;
72
+ at: number;
73
+ kind: string;
74
+ receipt: WorkUsageReceipt;
75
+ }
44
76
  export interface WorkState {
45
77
  version: 1;
46
78
  id: string;
@@ -55,6 +87,7 @@ export interface WorkState {
55
87
  child: string | null;
56
88
  baseline: SourceSnapshot;
57
89
  checks: WorkCheck[];
90
+ settledCallID?: string;
58
91
  startedAt: number;
59
92
  updatedAt: number;
60
93
  report: string;
@@ -67,12 +100,70 @@ export interface WorkState {
67
100
  intent: string;
68
101
  evidence?: string;
69
102
  };
103
+ sourceView?: {
104
+ fingerprint: string;
105
+ changed: string[];
106
+ at: number;
107
+ };
70
108
  checkReplacements?: WorkCheckReplacement[];
71
109
  progress?: WorkProgress;
110
+ commands?: WorkCommand[];
111
+ controller?: {
112
+ path: string;
113
+ stopCommand?: string;
114
+ runID: string | null;
115
+ status: string;
116
+ input: string | null;
117
+ snapshot?: Record<string, unknown>;
118
+ notified?: boolean;
119
+ };
120
+ presentation?: {
121
+ id: string;
122
+ report: string;
123
+ };
124
+ directory?: string;
125
+ usage?: {
126
+ tokens: number | null;
127
+ usd: number | null;
128
+ models: Array<{
129
+ model: string;
130
+ tokens: number;
131
+ }>;
132
+ estimatedUsd?: number;
133
+ unpricedRequests?: number;
134
+ requests?: number;
135
+ meteredAt?: number;
136
+ };
137
+ userStopped?: boolean;
138
+ usageReceipts?: Record<string, WorkUsageReceipt>;
139
+ supportSessions?: Array<{
140
+ id: string;
141
+ role: string;
142
+ }>;
143
+ usageUntil?: number;
144
+ attemptLimit?: number;
145
+ attemptExtensions?: Array<{
146
+ at: number;
147
+ attempts: number;
148
+ limit: number;
149
+ evidence: string[];
150
+ assessment: string;
151
+ }>;
72
152
  }
73
153
  export interface WorkStore {
74
154
  get(key: string): Promise<unknown>;
75
155
  set(key: string, value: unknown): Promise<void>;
156
+ scan?(options: {
157
+ prefix: string;
158
+ after?: string;
159
+ limit?: number;
160
+ }): Promise<{
161
+ entries: Array<{
162
+ key: string;
163
+ value: unknown;
164
+ }>;
165
+ next?: string;
166
+ }>;
76
167
  }
77
168
  export declare const isRecord: (value: unknown) => value is Record<string, any>;
78
169
  /** Content identity, including new nonignored files. Git commits do not invalidate identical source. */
@@ -95,18 +186,37 @@ export declare class WorkLoop {
95
186
  private read;
96
187
  private update;
97
188
  current(root: string): Promise<WorkState | null>;
189
+ progress(root: string): Promise<WorkProgress | null>;
190
+ operatorNudge(root: string): Promise<number>;
191
+ usage(root: string, workID: string, usage: NonNullable<WorkState["usage"]>): Promise<void>;
192
+ support(root: string, id: string, role: string): Promise<void>;
193
+ meter(root: string, workID: string, receipts: Record<string, WorkUsageReceipt>): Promise<void>;
194
+ private updateUsageWork;
195
+ auxiliaryUsage(value: WorkAuxiliaryUsage): Promise<void>;
196
+ auxiliaryReceipts(root: string, since: number, until?: number): Promise<WorkAuxiliaryUsage[]>;
197
+ presentation(root: string, id: string, report: string): Promise<{
198
+ id: string;
199
+ report: string;
200
+ }>;
201
+ controller(root: string, path: string, snapshot?: Record<string, unknown>): Promise<void>;
202
+ controllerNotified(root: string): Promise<void>;
203
+ bindController(root: string, path: string, stopCommand: string): Promise<void>;
204
+ retained(): Promise<WorkState[]>;
205
+ private evidence;
98
206
  inspect(root: string, actor: string): Promise<{
99
207
  work: WorkState | null;
100
208
  source: SourceSnapshot;
101
209
  }>;
102
210
  observe(root: string, request: WorkRequest): Promise<void>;
103
- start(root: string, instructions: string): Promise<WorkState>;
211
+ start(root: string, instructions: string, evidence?: string[], graceMs?: number): Promise<WorkState>;
104
212
  task(work: WorkState): {
105
213
  sessionID?: string | undefined;
106
214
  agent: string;
107
215
  description: string;
108
216
  prompt: string;
109
217
  };
218
+ attemptLimit(work: WorkState): number;
219
+ private continuationBudget;
110
220
  admit(root: string, callID: string, input: Record<string, unknown>): Promise<void>;
111
221
  claim(root: string, child: string, prompt: string): Promise<string>;
112
222
  assertWorker(root: string, child: string): Promise<WorkState>;
@@ -115,8 +225,24 @@ export declare class WorkLoop {
115
225
  exit: number | null;
116
226
  }): Promise<void>;
117
227
  stall(root: string, callID: string, reason: string): Promise<boolean>;
228
+ beginCommand(root: string, callID: string, command: string, timeout: number, retryOf?: string): Promise<{
229
+ command: WorkCommand;
230
+ launch: boolean;
231
+ }>;
232
+ nativeCommand(root: string, id: string, nativeID: string, result?: {
233
+ status: string;
234
+ exit: number | null;
235
+ output: string;
236
+ file?: string;
237
+ }): Promise<void>;
238
+ endCommand(root: string, id: string, result: {
239
+ exit: number | null;
240
+ interrupted: boolean;
241
+ output: string;
242
+ rejected?: boolean;
243
+ }): Promise<void>;
118
244
  check(root: string, actor: string, command: string, timeout: number, signal?: AbortSignal, execute?: typeof runWorkCheck): Promise<WorkCheck>;
119
245
  settled(root: string, callID: string, succeeded: boolean, report: string): Promise<void>;
120
246
  interrupt(root: string, cancelled?: boolean): Promise<void>;
121
- review(root: string, decision: "accept" | "revise" | "blocked", assessment: string, checks: string[], replacements?: WorkCheckReplacement[]): Promise<WorkState>;
247
+ review(root: string, decision: "accept" | "revise" | "blocked", assessment: string, checks: string[], replacements?: WorkCheckReplacement[], graceMs?: number): Promise<WorkState>;
122
248
  }