@astrosheep/keiyaku 4.5.26 → 4.5.28
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/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +82 -162
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +153 -76
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +68 -64
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +115 -146
- package/build/src/akuma/akuma-errors.d.ts +6 -0
- package/build/src/akuma/akuma-errors.js +11 -0
- package/build/src/akuma/akuma-handle.d.ts +54 -1
- package/build/src/akuma/akuma-handle.js +79 -8
- package/build/src/akuma/akuma-instance.js +6 -22
- package/build/src/akuma/akuma-observe.d.ts +6 -0
- package/build/src/akuma/akuma-observe.js +3 -1
- package/build/src/akuma/akuma-probe.d.ts +20 -1
- package/build/src/akuma/akuma-probe.js +20 -3
- package/build/src/akuma/akuma.d.ts +13 -0
- package/build/src/akuma/akuma.js +1 -0
- package/build/src/akuma/allowed.d.ts +2 -1
- package/build/src/akuma/allowed.js +9 -4
- package/build/src/akuma/archetype.js +3 -3
- package/build/src/akuma/body.js +8 -3
- package/build/src/akuma/fleet-execution.d.ts +13 -2
- package/build/src/akuma/fleet-execution.js +45 -0
- package/build/src/akuma/fleet-observation.d.ts +241 -0
- package/build/src/akuma/fleet-observation.js +13 -0
- package/build/src/akuma/fleet-owner-port.d.ts +12 -0
- package/build/src/akuma/fleet-owner-port.js +46 -0
- package/build/src/akuma/fleet-request.d.ts +55 -4
- package/build/src/akuma/fleet-request.js +101 -6
- package/build/src/akuma/heart/index.d.ts +1 -0
- package/build/src/akuma/heart/index.js +4 -1
- package/build/src/akuma/heart/rows.d.ts +1 -0
- package/build/src/akuma/heart/rows.js +8 -0
- package/build/src/akuma/heart/soul.js +2 -2
- package/build/src/akuma/identity.js +11 -9
- package/build/src/akuma/projection.d.ts +36 -0
- package/build/src/akuma/projection.js +2 -1
- package/build/src/akuma/provider.d.ts +14 -0
- package/build/src/akuma/provider.js +66 -4
- package/build/src/akuma/providers/acp/events.js +16 -8
- package/build/src/akuma/providers/claude/events.js +5 -7
- package/build/src/akuma/providers/opencode-sdk/events.js +9 -5
- package/build/src/akuma/providers/pi/events.js +4 -3
- package/build/src/akuma/request-lifecycle.js +10 -1
- package/build/src/akuma-body.js +1 -33
- package/build/src/alias/index.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -0
- package/build/src/cli/commands/akuma-invoke.js +67 -6
- package/build/src/cli/commands/akuma.d.ts +1 -0
- package/build/src/cli/commands/akuma.js +19 -30
- package/build/src/cli/commands/contract-help.d.ts +1 -0
- package/build/src/cli/commands/contract-help.js +9 -5
- package/build/src/cli/invoke.js +1 -1
- package/build/src/cli/render/akuma-activity.d.ts +7 -1
- package/build/src/cli/render/akuma-activity.js +164 -50
- package/build/src/cli/render/akuma-tool.d.ts +5 -0
- package/build/src/cli/render/akuma-tool.js +118 -14
- package/build/src/cli/render/akuma.d.ts +12 -1
- package/build/src/cli/render/akuma.js +74 -2
- package/build/src/cli/render/catalog.js +2 -3
- package/build/src/cli/render/contract-observation.d.ts +1 -0
- package/build/src/cli/render/contract-observation.js +20 -1
- package/build/src/cli/render/contract.js +4 -4
- package/build/src/cli/render/execution-progress.d.ts +1 -0
- package/build/src/cli/render/execution-progress.js +77 -3
- package/build/src/cli/render/kanshi.js +5 -19
- package/build/src/cli/render/terminal.js +3 -1
- package/build/src/cli/runtime.d.ts +6 -0
- package/build/src/cli/runtime.js +35 -17
- package/build/src/core/facts/offer.d.ts +1 -2
- package/build/src/core/verbs/abandon.js +1 -1
- package/build/src/core/verbs/amend.js +1 -1
- package/build/src/core/verbs/arc.js +1 -1
- package/build/src/core/verbs/attestation.js +1 -1
- package/build/src/core/verbs/bind.js +1 -1
- package/build/src/core/verbs/deliver.js +1 -1
- package/build/src/core/verbs/placement.js +1 -1
- package/build/src/core/verbs/reintegrate.js +1 -1
- package/build/src/git/admission.js +18 -7
- package/build/src/identity/coordinates.js +1 -1
- package/build/src/identity/normalize.d.ts +3 -0
- package/build/src/identity/normalize.js +10 -0
- package/build/src/identity/selector.d.ts +1 -0
- package/build/src/identity/selector.js +15 -4
- package/build/src/library/address.d.ts +33 -3
- package/build/src/library/address.js +90 -29
- package/build/src/library/akuma-creation.d.ts +1 -1
- package/build/src/library/akuma-creation.js +10 -52
- package/build/src/library/composition.d.ts +14 -1
- package/build/src/library/fleet.d.ts +13 -2
- package/build/src/library/fleet.js +142 -48
- package/build/src/library/keiyaku.d.ts +14 -1
- package/build/src/plugin/public.d.ts +2 -0
- package/build/src/protocol/completion.js +9 -2
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { akumaIdSchema } from "./akuma.js";
|
|
2
2
|
import { requestBodyCommand } from "./request-rendezvous.js";
|
|
3
3
|
import { eraseRequestCommand, } from "./request-wire.js";
|
|
4
|
-
import { fleetResultSchemas, isKillResult, isTellResult, isWaitResult, } from "./fleet-observation.js";
|
|
4
|
+
import { fleetResultSchemas, isKillResult, isTellResult, isTellWaitResult, isWaitResult, } from "./fleet-observation.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { schemaJsonText } from "./schema.js";
|
|
7
|
-
import { AkumaDecodeError } from "./akuma-errors.js";
|
|
7
|
+
import { AkumaDecodeError, AkumaNotBornError, AkumaObservationError } from "./akuma-errors.js";
|
|
8
8
|
const nonblankTextSchema = z.string().refine((value) => value.trim() !== "");
|
|
9
9
|
const fleetTargetsSchema = z
|
|
10
10
|
.array(akumaIdSchema)
|
|
@@ -39,6 +39,17 @@ const tellAnswerRequestSchema = z
|
|
|
39
39
|
})
|
|
40
40
|
.strict()
|
|
41
41
|
.transform((request) => ({ action: "akuma.tell-answer", ...request }));
|
|
42
|
+
const tellWaitRequestSchema = z
|
|
43
|
+
.object({
|
|
44
|
+
target: akumaIdSchema,
|
|
45
|
+
body: z.string(),
|
|
46
|
+
timeoutMs: z.number().int().nonnegative(),
|
|
47
|
+
schemaJson: nonblankTextSchema.optional(),
|
|
48
|
+
initiator: nonblankTextSchema.optional(),
|
|
49
|
+
interrupt: z.boolean().optional(),
|
|
50
|
+
})
|
|
51
|
+
.strict()
|
|
52
|
+
.transform((request) => ({ action: "akuma.tell-wait", ...request }));
|
|
42
53
|
const killRequestSchema = z
|
|
43
54
|
.object({ targets: fleetTargetsSchema })
|
|
44
55
|
.strict()
|
|
@@ -47,12 +58,49 @@ const waitServiceSchema = z.object({ action: z.literal("akuma.wait") }).strict()
|
|
|
47
58
|
const tellServiceSchema = z
|
|
48
59
|
.object({ action: z.literal("akuma.tell"), target: akumaIdSchema, tellId: nonblankTextSchema })
|
|
49
60
|
.strict();
|
|
61
|
+
const tellWaitServiceSchema = z
|
|
62
|
+
.object({ action: z.literal("akuma.tell-wait"), target: akumaIdSchema, tellId: nonblankTextSchema })
|
|
63
|
+
.strict();
|
|
50
64
|
const killServiceSchema = z
|
|
51
65
|
.object({
|
|
52
66
|
action: z.literal("akuma.kill"),
|
|
53
67
|
results: z.array(z.object({ id: akumaIdSchema, evidence: fleetResultSchemas.killEvidence }).strict()),
|
|
54
68
|
})
|
|
55
69
|
.strict();
|
|
70
|
+
/**
|
|
71
|
+
* A forwarded Fleet request leaves selection and observation to the parent, so
|
|
72
|
+
* the parent's typed refusal is the only evidence the child can classify on.
|
|
73
|
+
* Transporting it is the codec's own duty: an unencoded failure reaches the
|
|
74
|
+
* caller as an anonymous request error and loses the identity it names.
|
|
75
|
+
*
|
|
76
|
+
* The transport voids a begun request only when the encoded failure proves no
|
|
77
|
+
* product effect. A refused selection or an unreadable observation never
|
|
78
|
+
* reached an action, so Fleet proves that through the same refusal envelope
|
|
79
|
+
* the Contract codec uses; a genuinely failed action stays unencoded and
|
|
80
|
+
* keeps its existing anonymous classification.
|
|
81
|
+
*/
|
|
82
|
+
const fleetRefusalSchema = z.union([
|
|
83
|
+
z.object({ kind: z.literal("akuma-not-born"), id: akumaIdSchema }).strict(),
|
|
84
|
+
z.object({ kind: z.literal("akuma-observation"), id: akumaIdSchema, diagnostic: z.string() }).strict(),
|
|
85
|
+
]);
|
|
86
|
+
const fleetLiveFailureSchema = z.object({ kind: z.literal("refused"), failure: fleetRefusalSchema }).strict();
|
|
87
|
+
export function encodeFleetLiveFailure(error) {
|
|
88
|
+
const failure = error instanceof AkumaNotBornError
|
|
89
|
+
? { kind: "akuma-not-born", id: error.id }
|
|
90
|
+
: error instanceof AkumaObservationError
|
|
91
|
+
? { kind: "akuma-observation", id: error.id, diagnostic: error.diagnostic }
|
|
92
|
+
: null;
|
|
93
|
+
return failure === null ? null : { kind: "refused", failure };
|
|
94
|
+
}
|
|
95
|
+
export function decodeFleetLiveFailure(value) {
|
|
96
|
+
const parsed = fleetLiveFailureSchema.safeParse(value);
|
|
97
|
+
if (!parsed.success)
|
|
98
|
+
return null;
|
|
99
|
+
const failure = parsed.data.failure;
|
|
100
|
+
return failure.kind === "akuma-not-born"
|
|
101
|
+
? new AkumaNotBornError(failure.id)
|
|
102
|
+
: new AkumaObservationError(failure.id, failure.diagnostic);
|
|
103
|
+
}
|
|
56
104
|
function decodeFleetRequest(action, value) {
|
|
57
105
|
const schema = action === "akuma.wait"
|
|
58
106
|
? waitRequestSchema
|
|
@@ -60,7 +108,9 @@ function decodeFleetRequest(action, value) {
|
|
|
60
108
|
? tellRequestSchema
|
|
61
109
|
: action === "akuma.tell-answer"
|
|
62
110
|
? tellAnswerRequestSchema
|
|
63
|
-
:
|
|
111
|
+
: action === "akuma.tell-wait"
|
|
112
|
+
? tellWaitRequestSchema
|
|
113
|
+
: killRequestSchema;
|
|
64
114
|
const parsed = schema.safeParse(value);
|
|
65
115
|
return parsed.success ? parsed.data : null;
|
|
66
116
|
}
|
|
@@ -69,7 +119,9 @@ function decodeFleetService(action, value) {
|
|
|
69
119
|
? waitServiceSchema
|
|
70
120
|
: action === "akuma.tell" || action === "akuma.tell-answer"
|
|
71
121
|
? tellServiceSchema
|
|
72
|
-
:
|
|
122
|
+
: action === "akuma.tell-wait"
|
|
123
|
+
? tellWaitServiceSchema
|
|
124
|
+
: killServiceSchema;
|
|
73
125
|
const parsed = schema.safeParse(value);
|
|
74
126
|
if (!parsed.success)
|
|
75
127
|
throw new Error("malformed stored Fleet service evidence");
|
|
@@ -82,7 +134,9 @@ function decodedFleetResult(action, value) {
|
|
|
82
134
|
? fleetResultSchemas.wait
|
|
83
135
|
: action === "akuma.tell"
|
|
84
136
|
? fleetResultSchemas.tell
|
|
85
|
-
:
|
|
137
|
+
: action === "akuma.tell-wait"
|
|
138
|
+
? fleetResultSchemas.tellWait
|
|
139
|
+
: fleetResultSchemas.kill;
|
|
86
140
|
const parsed = schema.safeParse(value);
|
|
87
141
|
if (!parsed.success)
|
|
88
142
|
throw new Error(`Akuma body request returned an invalid live result for ${action}`);
|
|
@@ -100,9 +154,12 @@ export function fleetRequestProtocol(action) {
|
|
|
100
154
|
decodeRequest: (payload) => decodeFleetRequest(action, payload),
|
|
101
155
|
encodeResult: (result) => result,
|
|
102
156
|
decodeResult: (result) => decodedFleetResult(action, result),
|
|
157
|
+
encodeFailure: encodeFleetLiveFailure,
|
|
158
|
+
decodeFailure: decodeFleetLiveFailure,
|
|
103
159
|
decodeReference: (reference) => decodeFleetService(action, reference),
|
|
104
160
|
isPermitted: (allowed) => action === "akuma.wait" ||
|
|
105
|
-
((action === "akuma.tell" || action === "akuma.tell-answer"
|
|
161
|
+
((action === "akuma.tell" || action === "akuma.tell-answer" || action === "akuma.tell-wait") &&
|
|
162
|
+
allowed.includes("akuma.tell")) ||
|
|
106
163
|
(action === "akuma.kill" && allowed.includes("akuma.kill")),
|
|
107
164
|
};
|
|
108
165
|
}
|
|
@@ -148,6 +205,24 @@ export function fleetRequestCommand(action, port) {
|
|
|
148
205
|
service: { action: "akuma.tell", target: request.target, tellId: facts.id },
|
|
149
206
|
};
|
|
150
207
|
}
|
|
208
|
+
if (request.action === "akuma.tell-wait") {
|
|
209
|
+
if (port.tellWait === undefined)
|
|
210
|
+
throw new Error("bounded Tell Fleet port is unavailable");
|
|
211
|
+
return {
|
|
212
|
+
result: await port.tellWait({
|
|
213
|
+
target: request.target,
|
|
214
|
+
body: request.body,
|
|
215
|
+
tellId: facts.id,
|
|
216
|
+
recordedAt: facts.admittedAt,
|
|
217
|
+
timeoutMs: request.timeoutMs,
|
|
218
|
+
...(request.schemaJson === undefined ? {} : { schemaJson: request.schemaJson }),
|
|
219
|
+
...(request.initiator === undefined ? {} : { initiator: request.initiator }),
|
|
220
|
+
...(request.interrupt === undefined ? {} : { interrupt: request.interrupt }),
|
|
221
|
+
signal: facts.signal,
|
|
222
|
+
}),
|
|
223
|
+
service: { action: request.action, target: request.target, tellId: facts.id },
|
|
224
|
+
};
|
|
225
|
+
}
|
|
151
226
|
const result = await port.kill({ targets: request.targets, signal: facts.signal });
|
|
152
227
|
if ("result" in result)
|
|
153
228
|
return { result: result.result, service: { action: request.action, results: result.service } };
|
|
@@ -163,6 +238,7 @@ export function fleetRequestCommands(port) {
|
|
|
163
238
|
"akuma.wait": eraseRequestCommand(fleetRequestCommand("akuma.wait", port)),
|
|
164
239
|
"akuma.tell": eraseRequestCommand(fleetRequestCommand("akuma.tell", port)),
|
|
165
240
|
"akuma.tell-answer": eraseRequestCommand(fleetRequestCommand("akuma.tell-answer", port)),
|
|
241
|
+
"akuma.tell-wait": eraseRequestCommand(fleetRequestCommand("akuma.tell-wait", port)),
|
|
166
242
|
"akuma.kill": eraseRequestCommand(fleetRequestCommand("akuma.kill", port)),
|
|
167
243
|
};
|
|
168
244
|
}
|
|
@@ -195,6 +271,8 @@ function forwardedFleetCommandResult(response, action) {
|
|
|
195
271
|
return response.result;
|
|
196
272
|
if (action === "akuma.tell" && isTellResult(response.result))
|
|
197
273
|
return response.result;
|
|
274
|
+
if (action === "akuma.tell-wait" && isTellWaitResult(response.result))
|
|
275
|
+
return response.result;
|
|
198
276
|
if (action === "akuma.kill" && isKillResult(response.result))
|
|
199
277
|
return response.result;
|
|
200
278
|
throw new Error(`transport integrity: request Fleet ${action} returned an invalid live result`);
|
|
@@ -229,6 +307,23 @@ export async function requestForwardedFleetTell(input) {
|
|
|
229
307
|
});
|
|
230
308
|
return forwardedFleetCommandResult(response, "akuma.tell");
|
|
231
309
|
}
|
|
310
|
+
export async function requestForwardedFleetTellWait(input) {
|
|
311
|
+
const response = await requestBodyCommand({
|
|
312
|
+
directory: input.directory,
|
|
313
|
+
command: fleetRequestProtocol("akuma.tell-wait"),
|
|
314
|
+
value: {
|
|
315
|
+
action: "akuma.tell-wait",
|
|
316
|
+
target: input.target,
|
|
317
|
+
body: input.body,
|
|
318
|
+
timeoutMs: input.timeoutMs,
|
|
319
|
+
...(input.schema === undefined ? {} : { schemaJson: schemaJsonText(input.schema) }),
|
|
320
|
+
...(input.initiator === undefined ? {} : { initiator: input.initiator }),
|
|
321
|
+
...(input.interrupt === undefined ? {} : { interrupt: input.interrupt }),
|
|
322
|
+
},
|
|
323
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
324
|
+
});
|
|
325
|
+
return forwardedFleetCommandResult(response, "akuma.tell-wait");
|
|
326
|
+
}
|
|
232
327
|
export async function requestForwardedFleetKill(input) {
|
|
233
328
|
const response = await requestBodyCommand({
|
|
234
329
|
directory: input.directory,
|
|
@@ -94,6 +94,7 @@ export declare function failOpenBoundTurns(paths: AkumaPaths, input: Readonly<{
|
|
|
94
94
|
completedAt: string;
|
|
95
95
|
}>): Promise<readonly number[]>;
|
|
96
96
|
export declare function readTurn(paths: AkumaPaths, sequence: number): Promise<TurnFact | null>;
|
|
97
|
+
export declare function readLatestTurnForBody(paths: AkumaPaths, bodySequence: number): Promise<TurnFact | null>;
|
|
97
98
|
export declare function endTurn(paths: AkumaPaths, input: Readonly<{
|
|
98
99
|
turnSequence: number;
|
|
99
100
|
outcome: TurnOutcome;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parsePublicHistoryId } from "../identity.js";
|
|
2
|
-
import { answeredTurnFact, endBodyFact, finishBodyFact, deleteStopControl, insertActivityFact, insertTurnEndFact, insertTurnStartFact, insertPauseControl, insertKillFact, insertSessionFact, insertStopControl, killFactForBody, latestBodyFact, latestKillFact, latestSessionFact, lastAnsweredTurnFact, pauseFact, sessionFactForCoordinate, stopFact, turnFact, } from "./rows.js";
|
|
2
|
+
import { answeredTurnFact, endBodyFact, finishBodyFact, deleteStopControl, insertActivityFact, insertTurnEndFact, insertTurnStartFact, insertPauseControl, insertKillFact, insertSessionFact, insertStopControl, killFactForBody, latestBodyFact, latestKillFact, latestSessionFact, latestTurnFactForBody, lastAnsweredTurnFact, pauseFact, sessionFactForCoordinate, stopFact, turnFact, } from "./rows.js";
|
|
3
3
|
import { insertTellDeliveryFact, dispositionSnapshotProven, insertTellBindingFact, insertTellDispositionSnapshot, insertTellFact, insertTellReceiptFact, insertUndeliveredTellReceipts, latestOpenTellDisposition, openBoundTurns, openTellDispositionIds, pendingTellFacts, hasPendingTell, resolveTellDispositionSnapshot, tellDispositionResolved, tellFact, tellIdsForFence, } from "./tells.js";
|
|
4
4
|
import { activityFactSlice, statusFacts, lastActivityAt as readLastActivityAt, pruneActivityFacts, } from "./timeline.js";
|
|
5
5
|
import { isHeartAbsent, readSealFromLeash, withHeartTransaction, withReadOnlyHeart } from "./storage.js";
|
|
@@ -264,6 +264,9 @@ export async function failOpenBoundTurns(paths, input) {
|
|
|
264
264
|
export async function readTurn(paths, sequence) {
|
|
265
265
|
return await withReadOnlyHeart(paths, (heart) => turnFact(heart, sequence));
|
|
266
266
|
}
|
|
267
|
+
export async function readLatestTurnForBody(paths, bodySequence) {
|
|
268
|
+
return await withReadOnlyHeart(paths, (heart) => latestTurnFactForBody(heart, bodySequence));
|
|
269
|
+
}
|
|
267
270
|
export async function endTurn(paths, input) {
|
|
268
271
|
return await withHeartTransaction(paths, (heart) => {
|
|
269
272
|
const fact = insertTurnEndFact(heart, { kind: "turn-end", ...input });
|
|
@@ -122,4 +122,5 @@ export declare function latestKillFact(database: DatabaseSync): KillFact | null;
|
|
|
122
122
|
export declare function killFactForBody(database: DatabaseSync, bodySequence: number): KillFact | null;
|
|
123
123
|
export declare function lastAnsweredTurnFact(database: DatabaseSync): TurnFact | null;
|
|
124
124
|
export declare function answeredTurnFact(database: DatabaseSync, turnSequence: number): TurnFact | null;
|
|
125
|
+
export declare function latestTurnFactForBody(database: DatabaseSync, bodySequence: number): TurnFact | null;
|
|
125
126
|
export declare function turnFact(database: DatabaseSync, turnSequence: number): TurnFact | null;
|
|
@@ -299,6 +299,14 @@ export function answeredTurnFact(database, turnSequence) {
|
|
|
299
299
|
.get(turnSequence);
|
|
300
300
|
return row === undefined ? null : decodeTurnRow(row);
|
|
301
301
|
}
|
|
302
|
+
export function latestTurnFactForBody(database, bodySequence) {
|
|
303
|
+
const row = database
|
|
304
|
+
.prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
|
|
305
|
+
session_json, answer, answer_json, schema_json, initiator, diagnostic, completed_at
|
|
306
|
+
FROM turns WHERE body_sequence = ? ORDER BY sequence DESC LIMIT 1`)
|
|
307
|
+
.get(bodySequence);
|
|
308
|
+
return row === undefined ? null : decodeTurnRow(row);
|
|
309
|
+
}
|
|
302
310
|
export function turnFact(database, turnSequence) {
|
|
303
311
|
const row = database
|
|
304
312
|
.prepare(`SELECT sequence, body_sequence, started_at, end_sequence, outcome, history_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseAkuId } from "../identity.js";
|
|
2
2
|
import { decodeProviderOptions, decodeProviderRecipe, decodeReadonlyRestraint } from "../provider-recipe.js";
|
|
3
|
-
import {
|
|
3
|
+
import { historicalAllowedActions } from "../allowed.js";
|
|
4
4
|
function record(value) {
|
|
5
5
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
6
6
|
? value
|
|
@@ -68,7 +68,7 @@ function validateSoul(value) {
|
|
|
68
68
|
...(restraint === undefined ? {} : { readonly: restraint }),
|
|
69
69
|
cwd: nonblank(soul.cwd, "cwd"),
|
|
70
70
|
origin: decodeOrigin(soul.origin),
|
|
71
|
-
allowed:
|
|
71
|
+
allowed: historicalAllowedActions(soul.allowed),
|
|
72
72
|
createdAt: nonblank(soul.createdAt, "createdAt"),
|
|
73
73
|
};
|
|
74
74
|
}
|
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { identityCoordinate, identitySegments } from "../identity/coordinates.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isCanonicalAkumaName, validateAkumaName } from "../identity/normalize.js";
|
|
6
6
|
const HEX8 = /^[0-9a-f]{8}$/u;
|
|
7
7
|
export function parsePublicHistoryId(value) {
|
|
8
8
|
const match = /^turn\/([1-9][0-9]*)$/u.exec(value);
|
|
@@ -12,10 +12,7 @@ export function parsePublicHistoryId(value) {
|
|
|
12
12
|
return Number.isSafeInteger(sequence) ? sequence : null;
|
|
13
13
|
}
|
|
14
14
|
export function archetypeName(value) {
|
|
15
|
-
|
|
16
|
-
throw new TypeError("Akuma name must be one normalized human identity segment");
|
|
17
|
-
}
|
|
18
|
-
return value;
|
|
15
|
+
return validateAkumaName(value);
|
|
19
16
|
}
|
|
20
17
|
function suffixSegment(value) {
|
|
21
18
|
if (!HEX8.test(value))
|
|
@@ -32,15 +29,20 @@ export function parseAkuId(value) {
|
|
|
32
29
|
const segments = identitySegments({ family: "aku", value });
|
|
33
30
|
if (segments.length !== 2)
|
|
34
31
|
throw new TypeError("Akuma identity must be aku/<akuma>/<hex8>");
|
|
35
|
-
const archetype =
|
|
32
|
+
const archetype = segments[0];
|
|
33
|
+
// Existing identities remain addressable after new births gain a name limit.
|
|
34
|
+
if (!isCanonicalAkumaName(archetype))
|
|
35
|
+
throw new TypeError("Akuma name must be one normalized human identity segment");
|
|
36
36
|
const suffix = suffixSegment(segments[1]);
|
|
37
|
-
return { id:
|
|
37
|
+
return { id: value, archetype, suffix };
|
|
38
38
|
}
|
|
39
39
|
export function akumaRunRoot(worldRoot) {
|
|
40
40
|
return join(worldRoot, ".keiyaku", "akuma", "run");
|
|
41
41
|
}
|
|
42
42
|
export function akumaPaths(input) {
|
|
43
|
-
|
|
43
|
+
if (!isCanonicalAkumaName(input.archetype))
|
|
44
|
+
throw new TypeError("Akuma name must be one normalized human identity segment");
|
|
45
|
+
const directory = join(input.runRoot, `${input.archetype}-${suffixSegment(input.suffix)}`);
|
|
44
46
|
return {
|
|
45
47
|
directory,
|
|
46
48
|
heart: join(directory, "heart.db"),
|
|
@@ -54,7 +56,7 @@ export function akuIdFromDirectoryName(name) {
|
|
|
54
56
|
throw new Error(`invalid Akuma run directory ${name}`);
|
|
55
57
|
const archetype = name.slice(0, -9);
|
|
56
58
|
const suffix = name.slice(-8);
|
|
57
|
-
return
|
|
59
|
+
return parseAkuId(`aku/${archetype}/${suffix}`);
|
|
58
60
|
}
|
|
59
61
|
export async function ensureAkumaRunRoot(worldRoot) {
|
|
60
62
|
const runRoot = akumaRunRoot(worldRoot);
|
|
@@ -122,6 +122,10 @@ declare const activeToolRowSchema: z.ZodObject<{
|
|
|
122
122
|
}, z.core.$strict>, z.ZodObject<{
|
|
123
123
|
kind: z.ZodLiteral<"other">;
|
|
124
124
|
display: z.ZodString;
|
|
125
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
126
|
+
json: z.ZodString;
|
|
127
|
+
truncated: z.ZodBoolean;
|
|
128
|
+
}, z.core.$strict>>;
|
|
125
129
|
}, z.core.$strict>]>;
|
|
126
130
|
state: z.ZodLiteral<"active">;
|
|
127
131
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -170,6 +174,10 @@ declare const completedToolRowSchema: z.ZodObject<{
|
|
|
170
174
|
}, z.core.$strict>, z.ZodObject<{
|
|
171
175
|
kind: z.ZodLiteral<"other">;
|
|
172
176
|
display: z.ZodString;
|
|
177
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
178
|
+
json: z.ZodString;
|
|
179
|
+
truncated: z.ZodBoolean;
|
|
180
|
+
}, z.core.$strict>>;
|
|
173
181
|
}, z.core.$strict>]>;
|
|
174
182
|
state: z.ZodObject<{
|
|
175
183
|
status: z.ZodEnum<{
|
|
@@ -223,6 +231,10 @@ declare const unsettledToolRowSchema: z.ZodObject<{
|
|
|
223
231
|
}, z.core.$strict>, z.ZodObject<{
|
|
224
232
|
kind: z.ZodLiteral<"other">;
|
|
225
233
|
display: z.ZodString;
|
|
234
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
json: z.ZodString;
|
|
236
|
+
truncated: z.ZodBoolean;
|
|
237
|
+
}, z.core.$strict>>;
|
|
226
238
|
}, z.core.$strict>]>;
|
|
227
239
|
state: z.ZodLiteral<"unsettled">;
|
|
228
240
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -328,6 +340,10 @@ declare const openSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z
|
|
|
328
340
|
}, z.core.$strict>, z.ZodObject<{
|
|
329
341
|
kind: z.ZodLiteral<"other">;
|
|
330
342
|
display: z.ZodString;
|
|
343
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
344
|
+
json: z.ZodString;
|
|
345
|
+
truncated: z.ZodBoolean;
|
|
346
|
+
}, z.core.$strict>>;
|
|
331
347
|
}, z.core.$strict>]>;
|
|
332
348
|
state: z.ZodLiteral<"active">;
|
|
333
349
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -375,6 +391,10 @@ declare const openSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z
|
|
|
375
391
|
}, z.core.$strict>, z.ZodObject<{
|
|
376
392
|
kind: z.ZodLiteral<"other">;
|
|
377
393
|
display: z.ZodString;
|
|
394
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
395
|
+
json: z.ZodString;
|
|
396
|
+
truncated: z.ZodBoolean;
|
|
397
|
+
}, z.core.$strict>>;
|
|
378
398
|
}, z.core.$strict>]>;
|
|
379
399
|
state: z.ZodObject<{
|
|
380
400
|
status: z.ZodEnum<{
|
|
@@ -489,6 +509,10 @@ declare const idleSnapshotRowSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z
|
|
|
489
509
|
}, z.core.$strict>, z.ZodObject<{
|
|
490
510
|
kind: z.ZodLiteral<"other">;
|
|
491
511
|
display: z.ZodString;
|
|
512
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
513
|
+
json: z.ZodString;
|
|
514
|
+
truncated: z.ZodBoolean;
|
|
515
|
+
}, z.core.$strict>>;
|
|
492
516
|
}, z.core.$strict>]>;
|
|
493
517
|
state: z.ZodObject<{
|
|
494
518
|
status: z.ZodEnum<{
|
|
@@ -673,6 +697,10 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
673
697
|
}, z.core.$strict>, z.ZodObject<{
|
|
674
698
|
kind: z.ZodLiteral<"other">;
|
|
675
699
|
display: z.ZodString;
|
|
700
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
701
|
+
json: z.ZodString;
|
|
702
|
+
truncated: z.ZodBoolean;
|
|
703
|
+
}, z.core.$strict>>;
|
|
676
704
|
}, z.core.$strict>]>;
|
|
677
705
|
state: z.ZodLiteral<"active">;
|
|
678
706
|
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
@@ -720,6 +748,10 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
720
748
|
}, z.core.$strict>, z.ZodObject<{
|
|
721
749
|
kind: z.ZodLiteral<"other">;
|
|
722
750
|
display: z.ZodString;
|
|
751
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
752
|
+
json: z.ZodString;
|
|
753
|
+
truncated: z.ZodBoolean;
|
|
754
|
+
}, z.core.$strict>>;
|
|
723
755
|
}, z.core.$strict>]>;
|
|
724
756
|
state: z.ZodObject<{
|
|
725
757
|
status: z.ZodEnum<{
|
|
@@ -875,6 +907,10 @@ export declare const activitySnapshotSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
875
907
|
}, z.core.$strict>, z.ZodObject<{
|
|
876
908
|
kind: z.ZodLiteral<"other">;
|
|
877
909
|
display: z.ZodString;
|
|
910
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
911
|
+
json: z.ZodString;
|
|
912
|
+
truncated: z.ZodBoolean;
|
|
913
|
+
}, z.core.$strict>>;
|
|
878
914
|
}, z.core.$strict>]>;
|
|
879
915
|
state: z.ZodObject<{
|
|
880
916
|
status: z.ZodEnum<{
|
|
@@ -13,6 +13,7 @@ const fileChangeSchema = z
|
|
|
13
13
|
diffstat: diffstatSchema.optional(),
|
|
14
14
|
})
|
|
15
15
|
.strict();
|
|
16
|
+
const toolInputSchema = z.object({ json: z.string(), truncated: z.boolean() }).strict();
|
|
16
17
|
const toolCallSchema = z.union([
|
|
17
18
|
z.object({ kind: z.literal("run"), command: z.string() }).strict(),
|
|
18
19
|
z
|
|
@@ -33,7 +34,7 @@ const toolCallSchema = z.union([
|
|
|
33
34
|
})
|
|
34
35
|
.strict(),
|
|
35
36
|
z.object({ kind: z.literal("fileChange"), changes: z.array(fileChangeSchema).readonly() }).strict(),
|
|
36
|
-
z.object({ kind: z.literal("other"), display: z.string() }).strict(),
|
|
37
|
+
z.object({ kind: z.literal("other"), display: z.string(), input: toolInputSchema.optional() }).strict(),
|
|
37
38
|
]);
|
|
38
39
|
const toolResultSchema = z
|
|
39
40
|
.object({ status: z.enum(["ok", "error"]), message: z.string().optional(), exitCode: z.number().int().optional() })
|
|
@@ -6,6 +6,10 @@ export declare const AGENT_EVENT_TEXT_LIMIT = 16384;
|
|
|
6
6
|
export declare const AGENT_THOUGHT_TEXT_LIMIT = 4000;
|
|
7
7
|
export declare const AGENT_EVENT_QUEUE_LIMIT = 256;
|
|
8
8
|
export type SearchScope = "content" | "files" | "web";
|
|
9
|
+
export type ToolInput = Readonly<{
|
|
10
|
+
json: string;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
}>;
|
|
9
13
|
export type ToolCall = Readonly<{
|
|
10
14
|
kind: "run";
|
|
11
15
|
command: string;
|
|
@@ -33,6 +37,7 @@ export type ToolCall = Readonly<{
|
|
|
33
37
|
}> | Readonly<{
|
|
34
38
|
kind: "other";
|
|
35
39
|
display: string;
|
|
40
|
+
input?: ToolInput;
|
|
36
41
|
}>;
|
|
37
42
|
export type ToolResult = Readonly<{
|
|
38
43
|
status: "ok" | "error";
|
|
@@ -75,6 +80,15 @@ export type AgentEvent = Readonly<{
|
|
|
75
80
|
export { decodeResumeCoordinate, encodeResumeCoordinate };
|
|
76
81
|
export declare function decodeAgentEvent(value: unknown): AgentEvent;
|
|
77
82
|
export declare function encodeAgentEvent(event: AgentEvent): unknown;
|
|
83
|
+
/**
|
|
84
|
+
* Admit only a compact JSON view of structured tool invocation input. This
|
|
85
|
+
* deliberately receives adapter start evidence, never result or delta bodies.
|
|
86
|
+
*/
|
|
87
|
+
export declare function boundedToolInput(input: unknown): ToolInput | undefined;
|
|
88
|
+
/** Build one generic call from the provider's structured invocation evidence. */
|
|
89
|
+
export declare function otherToolCall(display: string, input?: unknown): Extract<ToolCall, {
|
|
90
|
+
kind: "other";
|
|
91
|
+
}>;
|
|
78
92
|
export declare function boundedEventText(value: string): string;
|
|
79
93
|
export declare function boundedThoughtText(value: string): string;
|
|
80
94
|
export declare function noteEvent(note: string): Extract<AgentEvent, {
|
|
@@ -107,8 +107,19 @@ function decodeFileChangeCall(call) {
|
|
|
107
107
|
const changes = call.changes.map(decodeFileChangeMember);
|
|
108
108
|
return changes.every((change) => change !== null) ? { kind: "fileChange", changes } : null;
|
|
109
109
|
}
|
|
110
|
+
function decodeToolInput(value) {
|
|
111
|
+
if (value === undefined)
|
|
112
|
+
return undefined;
|
|
113
|
+
const input = object(value);
|
|
114
|
+
if (input === null || typeof input.json !== "string" || typeof input.truncated !== "boolean")
|
|
115
|
+
return null;
|
|
116
|
+
return { json: input.json, truncated: input.truncated };
|
|
117
|
+
}
|
|
110
118
|
function decodeOtherCall(call) {
|
|
111
|
-
|
|
119
|
+
if (typeof call.display !== "string")
|
|
120
|
+
return null;
|
|
121
|
+
const input = decodeToolInput(call.input);
|
|
122
|
+
return input === null ? null : { kind: "other", display: call.display, ...(input === undefined ? {} : { input }) };
|
|
112
123
|
}
|
|
113
124
|
function decodeToolCall(value) {
|
|
114
125
|
const call = object(value);
|
|
@@ -242,11 +253,22 @@ function boundedToolCall(call) {
|
|
|
242
253
|
},
|
|
243
254
|
truncated: call.changes.some((change) => change.path.length > AGENT_EVENT_TEXT_LIMIT),
|
|
244
255
|
};
|
|
245
|
-
case "other":
|
|
256
|
+
case "other": {
|
|
257
|
+
const input = call.input;
|
|
258
|
+
const display = boundedEventText(call.display);
|
|
259
|
+
const bounded = input === undefined ? undefined : boundedToolInputJson(input.json);
|
|
246
260
|
return {
|
|
247
|
-
value: {
|
|
248
|
-
|
|
261
|
+
value: {
|
|
262
|
+
kind: call.kind,
|
|
263
|
+
display,
|
|
264
|
+
...(bounded === undefined || input === undefined
|
|
265
|
+
? {}
|
|
266
|
+
: { input: { json: bounded.value, truncated: input.truncated || bounded.truncated } }),
|
|
267
|
+
},
|
|
268
|
+
truncated: call.display.length > AGENT_EVENT_TEXT_LIMIT ||
|
|
269
|
+
(input !== undefined && (input.truncated || bounded?.truncated === true)),
|
|
249
270
|
};
|
|
271
|
+
}
|
|
250
272
|
default:
|
|
251
273
|
return call;
|
|
252
274
|
}
|
|
@@ -302,6 +324,46 @@ export function encodeAgentEvent(event) {
|
|
|
302
324
|
return event;
|
|
303
325
|
}
|
|
304
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Admit only a compact JSON view of structured tool invocation input. This
|
|
329
|
+
* deliberately receives adapter start evidence, never result or delta bodies.
|
|
330
|
+
*/
|
|
331
|
+
export function boundedToolInput(input) {
|
|
332
|
+
if (input === undefined)
|
|
333
|
+
return undefined;
|
|
334
|
+
let json;
|
|
335
|
+
try {
|
|
336
|
+
const encoded = JSON.stringify(input);
|
|
337
|
+
if (encoded === undefined)
|
|
338
|
+
return undefined;
|
|
339
|
+
json = encoded;
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
const bounded = boundedToolInputJson(json);
|
|
345
|
+
return { json: bounded.value, truncated: bounded.truncated };
|
|
346
|
+
}
|
|
347
|
+
/** Build one generic call from the provider's structured invocation evidence. */
|
|
348
|
+
export function otherToolCall(display, input) {
|
|
349
|
+
const preview = boundedToolInput(input);
|
|
350
|
+
return { kind: "other", display, ...(preview === undefined ? {} : { input: preview }) };
|
|
351
|
+
}
|
|
352
|
+
function boundedToolInputJson(value) {
|
|
353
|
+
if (new TextEncoder().encode(value).length <= AGENT_EVENT_TEXT_LIMIT)
|
|
354
|
+
return { value, truncated: false };
|
|
355
|
+
let bytes = 0;
|
|
356
|
+
let prefix = "";
|
|
357
|
+
const encoder = new TextEncoder();
|
|
358
|
+
for (const codePoint of value) {
|
|
359
|
+
const length = encoder.encode(codePoint).length;
|
|
360
|
+
if (bytes + length > AGENT_EVENT_TEXT_LIMIT)
|
|
361
|
+
break;
|
|
362
|
+
prefix += codePoint;
|
|
363
|
+
bytes += length;
|
|
364
|
+
}
|
|
365
|
+
return { value: prefix, truncated: true };
|
|
366
|
+
}
|
|
305
367
|
export function boundedEventText(value) {
|
|
306
368
|
return value.slice(0, AGENT_EVENT_TEXT_LIMIT);
|
|
307
369
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { noteEvent, unknownEvent } from "../../provider.js";
|
|
1
|
+
import { noteEvent, otherToolCall, unknownEvent } from "../../provider.js";
|
|
2
2
|
export const EMPTY_ACP_EVENT_STATE = Object.freeze({
|
|
3
3
|
answer: "",
|
|
4
4
|
assistantMessageId: null,
|
|
@@ -38,8 +38,8 @@ function object(value) {
|
|
|
38
38
|
function positiveLine(value) {
|
|
39
39
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : undefined;
|
|
40
40
|
}
|
|
41
|
-
function otherCall(name) {
|
|
42
|
-
return
|
|
41
|
+
function otherCall(name, input) {
|
|
42
|
+
return otherToolCall(name, input);
|
|
43
43
|
}
|
|
44
44
|
function locationFact(locations) {
|
|
45
45
|
if (locations === null || locations === undefined)
|
|
@@ -57,7 +57,7 @@ function standardCall(update, name) {
|
|
|
57
57
|
const location = locationFact(update.locations);
|
|
58
58
|
if (update.kind === "read") {
|
|
59
59
|
return location.path === undefined
|
|
60
|
-
? otherCall(name)
|
|
60
|
+
? otherCall(name, update.rawInput)
|
|
61
61
|
: {
|
|
62
62
|
kind: "read",
|
|
63
63
|
path: location.path,
|
|
@@ -67,12 +67,12 @@ function standardCall(update, name) {
|
|
|
67
67
|
const input = object(update.rawInput);
|
|
68
68
|
if (update.kind === "execute") {
|
|
69
69
|
const command = nonblank(input?.command);
|
|
70
|
-
return command === undefined ? otherCall(name) : { kind: "run", command };
|
|
70
|
+
return command === undefined ? otherCall(name, update.rawInput) : { kind: "run", command };
|
|
71
71
|
}
|
|
72
72
|
if (update.kind === "search") {
|
|
73
73
|
const query = nonblank(input?.query);
|
|
74
74
|
if (query === undefined)
|
|
75
|
-
return otherCall(name);
|
|
75
|
+
return otherCall(name, update.rawInput);
|
|
76
76
|
const path = nonblank(input?.path);
|
|
77
77
|
const glob = nonblank(input?.glob);
|
|
78
78
|
const scope = input?.scope;
|
|
@@ -85,7 +85,7 @@ function standardCall(update, name) {
|
|
|
85
85
|
...(glob === undefined ? {} : { glob }),
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
|
-
return otherCall(name);
|
|
88
|
+
return otherCall(name, update.rawInput);
|
|
89
89
|
}
|
|
90
90
|
function strongest(previous, next) {
|
|
91
91
|
if (previous === undefined || previous.kind === "other")
|
|
@@ -96,7 +96,15 @@ function observeTool(update, previous, interpret) {
|
|
|
96
96
|
const name = nonblank(update.name) ?? nonblank(update.title) ?? previous?.name ?? "ACP tool";
|
|
97
97
|
const standard = standardCall(update, name);
|
|
98
98
|
const dialect = standard.kind === "other" ? interpret?.(update) : undefined;
|
|
99
|
-
|
|
99
|
+
const call = strongest(previous?.call, dialect ?? standard);
|
|
100
|
+
if (call.kind !== "other")
|
|
101
|
+
return { name, call };
|
|
102
|
+
// The correlated start's admitted preview is authority: a later update never
|
|
103
|
+
// overwrites it, empty or not, while a start without one adopts first supplied evidence.
|
|
104
|
+
const started = previous?.call.kind === "other" ? previous.call.input : undefined;
|
|
105
|
+
const supplied = standard.kind === "other" ? standard.input : undefined;
|
|
106
|
+
const input = started ?? supplied;
|
|
107
|
+
return { name, call: input === undefined ? call : { kind: "other", display: call.display, input } };
|
|
100
108
|
}
|
|
101
109
|
export function mapAcpUpdate(update, previous, interpret) {
|
|
102
110
|
switch (update.sessionUpdate) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { noteEvent, unknownEvent } from "../../provider.js";
|
|
1
|
+
import { noteEvent, otherToolCall, unknownEvent } from "../../provider.js";
|
|
2
2
|
export const CLAUDE_MESSAGE_DISPOSITIONS = {
|
|
3
3
|
assistant: "assistant",
|
|
4
4
|
auth_status: "auth",
|
|
@@ -104,11 +104,11 @@ const CLAUDE_SYSTEM_NOTES = {
|
|
|
104
104
|
task_updated: (message) => `Task ${nonblank(message.task_id) ?? "unknown"} updated`,
|
|
105
105
|
worker_shutting_down: (message) => `Worker stopping: ${nonblank(message.reason) ?? "unknown reason"}`,
|
|
106
106
|
};
|
|
107
|
-
function runCall(name, value) {
|
|
107
|
+
function runCall(name, value, input) {
|
|
108
108
|
if (name !== "Bash")
|
|
109
109
|
return undefined;
|
|
110
110
|
const command = nonblank(value.command);
|
|
111
|
-
return command === undefined ?
|
|
111
|
+
return command === undefined ? otherToolCall(name, input) : { kind: "run", command };
|
|
112
112
|
}
|
|
113
113
|
function readCall(name, path, value) {
|
|
114
114
|
return name === "Read" && path !== undefined ? { kind: "read", path, ...readRange(value) } : undefined;
|
|
@@ -192,13 +192,11 @@ function structuredFileChange(name, result) {
|
|
|
192
192
|
}
|
|
193
193
|
function toolCall(name, input) {
|
|
194
194
|
const value = object(input) ?? {};
|
|
195
|
-
const run = runCall(name, value);
|
|
195
|
+
const run = runCall(name, value, input);
|
|
196
196
|
if (run !== undefined)
|
|
197
197
|
return run;
|
|
198
198
|
const path = startedPath(name, value);
|
|
199
|
-
return (readCall(name, path, value) ??
|
|
200
|
-
searchCall(name, value) ??
|
|
201
|
-
fileChangeCall(name, path) ?? { kind: "other", display: name });
|
|
199
|
+
return (readCall(name, path, value) ?? searchCall(name, value) ?? fileChangeCall(name, path) ?? otherToolCall(name, input));
|
|
202
200
|
}
|
|
203
201
|
function assistantEvents(message, events, state) {
|
|
204
202
|
if (message.aborted === true)
|