sortie-dogs 0.9.3 → 0.9.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 +1 -1
- package/dist/plugin/fast-lane.d.ts +12 -0
- package/dist/plugin/fast-lane.js +26 -0
- package/dist/plugin/index.js +39 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Requirements: Node.js 22.6 or newer, npm, and OpenCode.
|
|
|
24
24
|
|
|
25
25
|
Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md) · [CLI testing](docs/cli-testing.md)
|
|
26
26
|
|
|
27
|
-
Release: [v0.9.
|
|
27
|
+
Release: [v0.9.4](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.9.4)
|
|
28
28
|
|
|
29
29
|
## Quick start
|
|
30
30
|
|
|
@@ -4,6 +4,15 @@ export declare class FastLaneDeniedError extends Error {
|
|
|
4
4
|
readonly code: FastLaneDenialCode;
|
|
5
5
|
constructor(code: FastLaneDenialCode);
|
|
6
6
|
}
|
|
7
|
+
export interface WorkerAccounting {
|
|
8
|
+
readonly totalWorkerDispatches: number;
|
|
9
|
+
readonly workerDispatches: number;
|
|
10
|
+
readonly workerInFlight: boolean;
|
|
11
|
+
readonly workerResumeUsed: boolean;
|
|
12
|
+
readonly workerResumeSessionID?: string;
|
|
13
|
+
readonly workerResumeTaskID?: string;
|
|
14
|
+
readonly workerTaskID?: string;
|
|
15
|
+
}
|
|
7
16
|
export interface FastLaneToolOptions {
|
|
8
17
|
readonly readonlyDiagnosisAuthorized?: boolean;
|
|
9
18
|
readonly consultationFallbackAuthorized?: boolean;
|
|
@@ -25,5 +34,8 @@ export declare class FastLaneController {
|
|
|
25
34
|
continuationQueued(sessionID: string): void;
|
|
26
35
|
authorizeRecoverableWorkerResume(sessionID: string, taskID: string, childSessionID: string): boolean;
|
|
27
36
|
workerCompleted(sessionID: string): void;
|
|
37
|
+
/** Snapshot worker accounting so a later denial in the same dispatch cannot leak the slot. */
|
|
38
|
+
snapshotWorkerAccounting(sessionID: string): WorkerAccounting | undefined;
|
|
39
|
+
restoreWorkerAccounting(sessionID: string, snapshot: WorkerAccounting | undefined): void;
|
|
28
40
|
beforeTool(sessionID: string, tool: string, args: unknown, options?: FastLaneToolOptions): string | undefined;
|
|
29
41
|
}
|
package/dist/plugin/fast-lane.js
CHANGED
|
@@ -199,6 +199,32 @@ export class FastLaneController {
|
|
|
199
199
|
if (state !== undefined)
|
|
200
200
|
state.workerInFlight = false;
|
|
201
201
|
}
|
|
202
|
+
/** Snapshot worker accounting so a later denial in the same dispatch cannot leak the slot. */
|
|
203
|
+
snapshotWorkerAccounting(sessionID) {
|
|
204
|
+
const state = this.sessions.get(sessionID);
|
|
205
|
+
if (state === undefined)
|
|
206
|
+
return undefined;
|
|
207
|
+
return { totalWorkerDispatches: state.totalWorkerDispatches, workerDispatches: state.workerDispatches,
|
|
208
|
+
workerInFlight: state.workerInFlight, workerResumeUsed: state.workerResumeUsed,
|
|
209
|
+
workerResumeSessionID: state.workerResumeSessionID, workerResumeTaskID: state.workerResumeTaskID,
|
|
210
|
+
workerTaskID: state.workerTaskID };
|
|
211
|
+
}
|
|
212
|
+
restoreWorkerAccounting(sessionID, snapshot) {
|
|
213
|
+
const state = this.sessions.get(sessionID);
|
|
214
|
+
if (state === undefined || snapshot === undefined)
|
|
215
|
+
return;
|
|
216
|
+
state.totalWorkerDispatches = snapshot.totalWorkerDispatches;
|
|
217
|
+
state.workerDispatches = snapshot.workerDispatches;
|
|
218
|
+
state.workerInFlight = snapshot.workerInFlight;
|
|
219
|
+
state.workerResumeUsed = snapshot.workerResumeUsed;
|
|
220
|
+
for (const [key, value] of Object.entries({ workerResumeSessionID: snapshot.workerResumeSessionID,
|
|
221
|
+
workerResumeTaskID: snapshot.workerResumeTaskID, workerTaskID: snapshot.workerTaskID })) {
|
|
222
|
+
if (value === undefined)
|
|
223
|
+
delete state[key];
|
|
224
|
+
else
|
|
225
|
+
state[key] = value;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
202
228
|
beforeTool(sessionID, tool, args, options = {}) {
|
|
203
229
|
const state = this.sessions.get(sessionID);
|
|
204
230
|
if (state === undefined) {
|
package/dist/plugin/index.js
CHANGED
|
@@ -6231,46 +6231,55 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
6231
6231
|
// therefore be repaired by a corrected Task call in this same coordinator turn.
|
|
6232
6232
|
await bindGoalDeclaration(toolInput.sessionID, typeof output.args.prompt === "string" ? output.args.prompt : "");
|
|
6233
6233
|
}
|
|
6234
|
+
// Accounting is provisional until this dispatch is fully admitted. A later denial such as a
|
|
6235
|
+
// budget stop must release the serial slot, or no worker could be dispatched or resumed again.
|
|
6236
|
+
const workerAccounting = fastLane.snapshotWorkerAccounting(toolInput.sessionID);
|
|
6234
6237
|
const resumedWorkerSessionID = fastLane.beforeTool(toolInput.sessionID, toolInput.tool, output.args, {
|
|
6235
6238
|
readonlyDiagnosisAuthorized: readonlyDiagnosis,
|
|
6236
6239
|
consultationFallbackAuthorized,
|
|
6237
6240
|
parallelWorkerAlreadyBound,
|
|
6238
6241
|
parallelWorkerAuthorized,
|
|
6239
6242
|
});
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
if (validatedRootAcceptance !== undefined && reservedParallelDescriptor === undefined) {
|
|
6245
|
-
rootAcceptanceContinuity.delete(toolInput.sessionID);
|
|
6246
|
-
rootAcceptanceContinuity.set(toolInput.sessionID, validatedRootAcceptance);
|
|
6247
|
-
while (rootAcceptanceContinuity.size > ACTIVE_SESSION_CACHE.maximum) {
|
|
6248
|
-
rootAcceptanceContinuity.delete(rootAcceptanceContinuity.keys().next().value);
|
|
6243
|
+
try {
|
|
6244
|
+
if (toolInput.tool === "task" && taskRole !== undefined && IMPLEMENTATION_AGENTS.has(taskRole) &&
|
|
6245
|
+
isRecord(output.args)) {
|
|
6246
|
+
await reserveGoalDispatch(toolInput.sessionID, toolInput.callID, typeof output.args.prompt === "string" ? output.args.prompt : "");
|
|
6249
6247
|
}
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6248
|
+
if (validatedRootAcceptance !== undefined && reservedParallelDescriptor === undefined) {
|
|
6249
|
+
rootAcceptanceContinuity.delete(toolInput.sessionID);
|
|
6250
|
+
rootAcceptanceContinuity.set(toolInput.sessionID, validatedRootAcceptance);
|
|
6251
|
+
while (rootAcceptanceContinuity.size > ACTIVE_SESSION_CACHE.maximum) {
|
|
6252
|
+
rootAcceptanceContinuity.delete(rootAcceptanceContinuity.keys().next().value);
|
|
6253
|
+
}
|
|
6256
6254
|
}
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6255
|
+
if (resumedWorkerSessionID !== undefined) {
|
|
6256
|
+
const recoverableParallel = parallelRecoverableChildren.get(resumedWorkerSessionID);
|
|
6257
|
+
if (recoverableParallel !== undefined) {
|
|
6258
|
+
parallelCalls.set(toolInput.callID, recoverableParallel);
|
|
6259
|
+
parallelRecoverableChildren.delete(resumedWorkerSessionID);
|
|
6260
|
+
}
|
|
6261
|
+
recoverableWorkerChildren.delete(resumedWorkerSessionID);
|
|
6262
|
+
}
|
|
6263
|
+
if (toolInput.tool === "task" && taskRole !== undefined && IMPLEMENTATION_AGENTS.has(taskRole)) {
|
|
6264
|
+
if (readonlyDiagnosis && isRecord(output.args))
|
|
6265
|
+
await claimDiagnosisTask(toolInput.sessionID, toolInput.callID, output.args, true);
|
|
6266
|
+
bootstrapRequired = false;
|
|
6267
|
+
bootstrapCompleted = true;
|
|
6268
|
+
bootstrapIdleWarnings.delete(toolInput.sessionID);
|
|
6269
|
+
beginCoordinatorTask(toolInput.sessionID, toolInput.callID);
|
|
6270
|
+
if (reservedParallelDescriptor !== undefined) {
|
|
6271
|
+
parallelCalls.set(toolInput.callID, {
|
|
6272
|
+
ownerRoot: toolInput.sessionID,
|
|
6273
|
+
descriptor: reservedParallelDescriptor,
|
|
6274
|
+
completionCallID: toolInput.callID,
|
|
6275
|
+
});
|
|
6276
|
+
}
|
|
6272
6277
|
}
|
|
6273
6278
|
}
|
|
6279
|
+
catch (error) {
|
|
6280
|
+
fastLane.restoreWorkerAccounting(toolInput.sessionID, workerAccounting);
|
|
6281
|
+
throw error;
|
|
6282
|
+
}
|
|
6274
6283
|
return;
|
|
6275
6284
|
}
|
|
6276
6285
|
const status = activeSessionStatus(toolInput.sessionID);
|