@mrciphersmith/keryx 0.3.75 → 0.3.77
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/dist/cli.js +629 -449
- package/dist/core.js +6 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20145,7 +20145,7 @@ var package_default;
|
|
|
20145
20145
|
var init_package = __esm(() => {
|
|
20146
20146
|
package_default = {
|
|
20147
20147
|
name: "@mrciphersmith/keryx",
|
|
20148
|
-
version: "0.3.
|
|
20148
|
+
version: "0.3.77",
|
|
20149
20149
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
20150
20150
|
private: false,
|
|
20151
20151
|
publishConfig: {
|
|
@@ -97077,109 +97077,6 @@ function createSpawnSubagentTool(deps) {
|
|
|
97077
97077
|
outcome
|
|
97078
97078
|
});
|
|
97079
97079
|
};
|
|
97080
|
-
const parent = deps.getParentModel();
|
|
97081
|
-
const detected = deps.getDetectedProviders();
|
|
97082
|
-
const session = { providerId: parent.providerId, modelId: parent.modelId };
|
|
97083
|
-
const catalog = detected.map((p) => ({
|
|
97084
|
-
name: p.name,
|
|
97085
|
-
models: p.models ?? []
|
|
97086
|
-
}));
|
|
97087
|
-
const requestedTier = parseModelTier(typeof input.model_tier === "string" ? input.model_tier : undefined);
|
|
97088
|
-
let categoryModelRequest;
|
|
97089
|
-
if (requestedTier === undefined) {
|
|
97090
|
-
const routingLocation = { cwd: deps.cwd };
|
|
97091
|
-
const [projectRouting, userRouting] = await Promise.all([
|
|
97092
|
-
loadRoutingConfig("project", routingLocation),
|
|
97093
|
-
loadRoutingConfig("user", routingLocation)
|
|
97094
|
-
]);
|
|
97095
|
-
for (const layer of [projectRouting, userRouting]) {
|
|
97096
|
-
if (layer.error !== undefined) {
|
|
97097
|
-
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "system", text: `routing: ${layer.error}` } });
|
|
97098
|
-
}
|
|
97099
|
-
}
|
|
97100
|
-
const external = await resolveExternalSetting({ cwd: deps.cwd });
|
|
97101
|
-
const { config: externalConfig } = loadExternalProvidersConfig();
|
|
97102
|
-
const connected = externalAllowedConnectedPredicate(connectedPredicateFrom(catalog), external.value === "on", externalConfig);
|
|
97103
|
-
const resolved = resolveCategoryDetailed("subagents", { project: projectRouting.table, user: userRouting.table }, connected);
|
|
97104
|
-
if (resolved.rejected !== undefined) {
|
|
97105
|
-
emitFleetEvent({
|
|
97106
|
-
kind: "log",
|
|
97107
|
-
id: workerId,
|
|
97108
|
-
entry: { kind: "system", text: `routing: ${describeFallbackNotice(resolved.rejected.assignment, resolved.assignment)}` }
|
|
97109
|
-
});
|
|
97110
|
-
}
|
|
97111
|
-
categoryModelRequest = categoryAssignmentToChildModelRequest(resolved.assignment);
|
|
97112
|
-
}
|
|
97113
|
-
const dispatchModelRequest = requestedTier !== undefined ? { kind: "tier", tier: requestedTier } : categoryModelRequest;
|
|
97114
|
-
let tierMap = buildTierMap(session, catalog);
|
|
97115
|
-
const tierPrices = deps.tierRank?.prices?.(session.providerId);
|
|
97116
|
-
let tierResolution = requestedTier === undefined ? undefined : resolveTierModel(session, requestedTier, catalog, undefined, tierPrices);
|
|
97117
|
-
if (requestedTier !== undefined && deps.tierRank !== undefined) {
|
|
97118
|
-
tierResolution = await resolveTierWithAgent(session, requestedTier, rankDiscoveredModels(session, catalog), {
|
|
97119
|
-
agent: deps.tierRank.agent,
|
|
97120
|
-
...deps.tierRank.cache !== undefined ? { cache: deps.tierRank.cache } : {},
|
|
97121
|
-
...tierPrices !== undefined ? { prices: tierPrices } : {},
|
|
97122
|
-
...parent.baseUrl !== undefined ? { baseUrl: parent.baseUrl } : {}
|
|
97123
|
-
});
|
|
97124
|
-
if (tierResolution.source === "agent-ranked") {
|
|
97125
|
-
tierMap = applyTierResolution(tierMap, tierResolution);
|
|
97126
|
-
}
|
|
97127
|
-
}
|
|
97128
|
-
const ctx = {
|
|
97129
|
-
parentRunId,
|
|
97130
|
-
parentSessionId,
|
|
97131
|
-
parentProvenance,
|
|
97132
|
-
contextManifestHash: sha2569(`${parentRunId}:${parentSessionId}`),
|
|
97133
|
-
canonicalContractVersion: "1.0.0",
|
|
97134
|
-
parentModel: session,
|
|
97135
|
-
parentPolicy: parentShellPolicy(),
|
|
97136
|
-
ledger,
|
|
97137
|
-
detected: detected.length > 0 ? detected : [{ name: parent.providerId }],
|
|
97138
|
-
config: {
|
|
97139
|
-
maxTreeDepth: 2,
|
|
97140
|
-
maxChildren: DEFAULT_MAX_CHILDREN,
|
|
97141
|
-
tiers: tierMap
|
|
97142
|
-
}
|
|
97143
|
-
};
|
|
97144
|
-
const attemptId = idSeq();
|
|
97145
|
-
const branchId = idSeq();
|
|
97146
|
-
const reservationId = idSeq();
|
|
97147
|
-
const artifactHash = sha2569(task);
|
|
97148
|
-
const spawned = spawnSubagent({
|
|
97149
|
-
attempt: { attemptId, number: childSeq },
|
|
97150
|
-
branchId,
|
|
97151
|
-
budgetRequest: {
|
|
97152
|
-
reservationId,
|
|
97153
|
-
maxRuntimeMs: 5 * 60000
|
|
97154
|
-
},
|
|
97155
|
-
policyRequest: childReadOnlyPolicy(),
|
|
97156
|
-
durableResultArtifact: {
|
|
97157
|
-
artifactId: idSeq(),
|
|
97158
|
-
kind: "final-report",
|
|
97159
|
-
hash: artifactHash
|
|
97160
|
-
},
|
|
97161
|
-
...dispatchModelRequest !== undefined ? { modelRequest: dispatchModelRequest } : {}
|
|
97162
|
-
}, ctx, { idSeq, clock });
|
|
97163
|
-
if (!spawned.ok) {
|
|
97164
|
-
emitFleetEvent({
|
|
97165
|
-
id: workerId,
|
|
97166
|
-
kind: "upsert",
|
|
97167
|
-
label,
|
|
97168
|
-
status: "failed",
|
|
97169
|
-
detail: "denied",
|
|
97170
|
-
task
|
|
97171
|
-
});
|
|
97172
|
-
return {
|
|
97173
|
-
status: "Denied",
|
|
97174
|
-
output: `spawn_subagent denied by MAE: ${spawned.reason}`,
|
|
97175
|
-
isError: true
|
|
97176
|
-
};
|
|
97177
|
-
}
|
|
97178
|
-
const runModel = spawned.runModel ?? {
|
|
97179
|
-
provider: parent.providerId,
|
|
97180
|
-
model: parent.modelId
|
|
97181
|
-
};
|
|
97182
|
-
const tierRecord = tierResolution === undefined ? undefined : `model tier ${tierResolution.tier} \u2192 ${runModel.provider}/${runModel.model} ` + `[${tierResolution.source}] ${tierResolution.reason}` + (tierResolution.agent === undefined ? "" : ` (agent ${tierResolution.agent.trigger}, ran on ${tierResolution.agent.runOn.providerId}/${tierResolution.agent.runOn.modelId}, ` + `${tierResolution.agent.cacheHit ? "cache hit" : "asked"}${tierResolution.agent.failure === null ? "" : `, failed: ${tierResolution.agent.failure}`})`);
|
|
97183
97080
|
const externalRuntime = readExternalRuntimeRequest(input);
|
|
97184
97081
|
const externalAgentId = externalRuntime === undefined || typeof externalRuntime.agent !== "string" ? undefined : externalRuntime.agent;
|
|
97185
97082
|
const externalMark = externalRuntime !== undefined && deps.runExternal !== undefined ? { runtime: "external", ...externalAgentId === undefined ? {} : { agentId: externalAgentId } } : {};
|
|
@@ -97188,29 +97085,190 @@ function createSpawnSubagentTool(deps) {
|
|
|
97188
97085
|
id: workerId,
|
|
97189
97086
|
label,
|
|
97190
97087
|
status: "running",
|
|
97191
|
-
detail:
|
|
97192
|
-
model: `${runModel.provider}/${runModel.model}`,
|
|
97088
|
+
detail: "preparing",
|
|
97193
97089
|
task,
|
|
97194
97090
|
...externalMark
|
|
97195
97091
|
});
|
|
97196
|
-
|
|
97197
|
-
|
|
97198
|
-
|
|
97199
|
-
|
|
97200
|
-
const
|
|
97201
|
-
|
|
97202
|
-
|
|
97092
|
+
try {
|
|
97093
|
+
const parent = deps.getParentModel();
|
|
97094
|
+
const detected = deps.getDetectedProviders();
|
|
97095
|
+
const session = { providerId: parent.providerId, modelId: parent.modelId };
|
|
97096
|
+
const catalog = detected.map((p) => ({
|
|
97097
|
+
name: p.name,
|
|
97098
|
+
models: p.models ?? []
|
|
97099
|
+
}));
|
|
97100
|
+
const requestedTier = parseModelTier(typeof input.model_tier === "string" ? input.model_tier : undefined);
|
|
97101
|
+
let categoryModelRequest;
|
|
97102
|
+
if (requestedTier === undefined) {
|
|
97103
|
+
const routingLocation = { cwd: deps.cwd };
|
|
97104
|
+
const [projectRouting, userRouting] = await Promise.all([
|
|
97105
|
+
loadRoutingConfig("project", routingLocation),
|
|
97106
|
+
loadRoutingConfig("user", routingLocation)
|
|
97107
|
+
]);
|
|
97108
|
+
for (const layer of [projectRouting, userRouting]) {
|
|
97109
|
+
if (layer.error !== undefined) {
|
|
97110
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "system", text: `routing: ${layer.error}` } });
|
|
97111
|
+
}
|
|
97112
|
+
}
|
|
97113
|
+
const external = await resolveExternalSetting({ cwd: deps.cwd });
|
|
97114
|
+
const { config: externalConfig } = loadExternalProvidersConfig();
|
|
97115
|
+
const connected = externalAllowedConnectedPredicate(connectedPredicateFrom(catalog), external.value === "on", externalConfig);
|
|
97116
|
+
const resolved = resolveCategoryDetailed("subagents", { project: projectRouting.table, user: userRouting.table }, connected);
|
|
97117
|
+
if (resolved.rejected !== undefined) {
|
|
97118
|
+
emitFleetEvent({
|
|
97119
|
+
kind: "log",
|
|
97120
|
+
id: workerId,
|
|
97121
|
+
entry: { kind: "system", text: `routing: ${describeFallbackNotice(resolved.rejected.assignment, resolved.assignment)}` }
|
|
97122
|
+
});
|
|
97123
|
+
}
|
|
97124
|
+
categoryModelRequest = categoryAssignmentToChildModelRequest(resolved.assignment);
|
|
97125
|
+
}
|
|
97126
|
+
const dispatchModelRequest = requestedTier !== undefined ? { kind: "tier", tier: requestedTier } : categoryModelRequest;
|
|
97127
|
+
let tierMap = buildTierMap(session, catalog);
|
|
97128
|
+
const tierPrices = deps.tierRank?.prices?.(session.providerId);
|
|
97129
|
+
let tierResolution = requestedTier === undefined ? undefined : resolveTierModel(session, requestedTier, catalog, undefined, tierPrices);
|
|
97130
|
+
if (requestedTier !== undefined && deps.tierRank !== undefined) {
|
|
97131
|
+
tierResolution = await resolveTierWithAgent(session, requestedTier, rankDiscoveredModels(session, catalog), {
|
|
97132
|
+
agent: deps.tierRank.agent,
|
|
97133
|
+
...deps.tierRank.cache !== undefined ? { cache: deps.tierRank.cache } : {},
|
|
97134
|
+
...tierPrices !== undefined ? { prices: tierPrices } : {},
|
|
97135
|
+
...parent.baseUrl !== undefined ? { baseUrl: parent.baseUrl } : {}
|
|
97136
|
+
});
|
|
97137
|
+
if (tierResolution.source === "agent-ranked") {
|
|
97138
|
+
tierMap = applyTierResolution(tierMap, tierResolution);
|
|
97139
|
+
}
|
|
97140
|
+
}
|
|
97141
|
+
const ctx = {
|
|
97142
|
+
parentRunId,
|
|
97143
|
+
parentSessionId,
|
|
97144
|
+
parentProvenance,
|
|
97145
|
+
contextManifestHash: sha2569(`${parentRunId}:${parentSessionId}`),
|
|
97146
|
+
canonicalContractVersion: "1.0.0",
|
|
97147
|
+
parentModel: session,
|
|
97148
|
+
parentPolicy: parentShellPolicy(),
|
|
97149
|
+
ledger,
|
|
97150
|
+
detected: detected.length > 0 ? detected : [{ name: parent.providerId }],
|
|
97151
|
+
config: {
|
|
97152
|
+
maxTreeDepth: 2,
|
|
97153
|
+
maxChildren: DEFAULT_MAX_CHILDREN,
|
|
97154
|
+
tiers: tierMap
|
|
97155
|
+
}
|
|
97156
|
+
};
|
|
97157
|
+
const attemptId = idSeq();
|
|
97158
|
+
const branchId = idSeq();
|
|
97159
|
+
const reservationId = idSeq();
|
|
97160
|
+
const artifactHash = sha2569(task);
|
|
97161
|
+
const spawned = spawnSubagent({
|
|
97162
|
+
attempt: { attemptId, number: childSeq },
|
|
97163
|
+
branchId,
|
|
97164
|
+
budgetRequest: {
|
|
97165
|
+
reservationId,
|
|
97166
|
+
maxRuntimeMs: 5 * 60000
|
|
97167
|
+
},
|
|
97168
|
+
policyRequest: childReadOnlyPolicy(),
|
|
97169
|
+
durableResultArtifact: {
|
|
97170
|
+
artifactId: idSeq(),
|
|
97171
|
+
kind: "final-report",
|
|
97172
|
+
hash: artifactHash
|
|
97173
|
+
},
|
|
97174
|
+
...dispatchModelRequest !== undefined ? { modelRequest: dispatchModelRequest } : {}
|
|
97175
|
+
}, ctx, { idSeq, clock });
|
|
97176
|
+
if (!spawned.ok) {
|
|
97203
97177
|
emitFleetEvent({
|
|
97204
|
-
kind: "upsert",
|
|
97205
97178
|
id: workerId,
|
|
97179
|
+
kind: "upsert",
|
|
97206
97180
|
label,
|
|
97207
97181
|
status: "failed",
|
|
97208
|
-
detail: "
|
|
97209
|
-
task
|
|
97210
|
-
...externalMark
|
|
97182
|
+
detail: "denied",
|
|
97183
|
+
task
|
|
97211
97184
|
});
|
|
97185
|
+
return {
|
|
97186
|
+
status: "Denied",
|
|
97187
|
+
output: `spawn_subagent denied by MAE: ${spawned.reason}`,
|
|
97188
|
+
isError: true
|
|
97189
|
+
};
|
|
97190
|
+
}
|
|
97191
|
+
const runModel = spawned.runModel ?? {
|
|
97192
|
+
provider: parent.providerId,
|
|
97193
|
+
model: parent.modelId
|
|
97194
|
+
};
|
|
97195
|
+
const tierRecord = tierResolution === undefined ? undefined : `model tier ${tierResolution.tier} \u2192 ${runModel.provider}/${runModel.model} ` + `[${tierResolution.source}] ${tierResolution.reason}` + (tierResolution.agent === undefined ? "" : ` (agent ${tierResolution.agent.trigger}, ran on ${tierResolution.agent.runOn.providerId}/${tierResolution.agent.runOn.modelId}, ` + `${tierResolution.agent.cacheHit ? "cache hit" : "asked"}${tierResolution.agent.failure === null ? "" : `, failed: ${tierResolution.agent.failure}`})`);
|
|
97196
|
+
emitFleetEvent({
|
|
97197
|
+
kind: "upsert",
|
|
97198
|
+
id: workerId,
|
|
97199
|
+
label,
|
|
97200
|
+
status: "running",
|
|
97201
|
+
detail: mode === "read_only" ? "read-only" : "general",
|
|
97202
|
+
model: `${runModel.provider}/${runModel.model}`,
|
|
97203
|
+
task,
|
|
97204
|
+
...externalMark
|
|
97205
|
+
});
|
|
97206
|
+
if (tierRecord !== undefined) {
|
|
97207
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "system", text: tierRecord } });
|
|
97208
|
+
}
|
|
97209
|
+
if (externalRuntime !== undefined && deps.runExternal !== undefined) {
|
|
97210
|
+
const externalStartedAt = performance.now();
|
|
97211
|
+
const startOutcome = await fireSubagentStart("external");
|
|
97212
|
+
if (startOutcome === "deny" || startOutcome === "ask") {
|
|
97213
|
+
emitFleetEvent({
|
|
97214
|
+
kind: "upsert",
|
|
97215
|
+
id: workerId,
|
|
97216
|
+
label,
|
|
97217
|
+
status: "failed",
|
|
97218
|
+
detail: "hook-denied",
|
|
97219
|
+
task,
|
|
97220
|
+
...externalMark
|
|
97221
|
+
});
|
|
97222
|
+
ledger.release(spawned.reservation.reservationId, {
|
|
97223
|
+
maxRuntimeMs: Math.round(performance.now() - externalStartedAt)
|
|
97224
|
+
});
|
|
97225
|
+
return {
|
|
97226
|
+
status: "Denied",
|
|
97227
|
+
output: `spawn_subagent denied by a SubagentStart hook for ${workerId}`,
|
|
97228
|
+
isError: true
|
|
97229
|
+
};
|
|
97230
|
+
}
|
|
97231
|
+
try {
|
|
97232
|
+
const external = await deps.runExternal({ runtime: externalRuntime, task, mode, workerId, label });
|
|
97233
|
+
emitFleetEvent({
|
|
97234
|
+
kind: "upsert",
|
|
97235
|
+
id: workerId,
|
|
97236
|
+
label,
|
|
97237
|
+
status: external.isError ? "failed" : "done",
|
|
97238
|
+
detail: external.status,
|
|
97239
|
+
task,
|
|
97240
|
+
...externalMark
|
|
97241
|
+
});
|
|
97242
|
+
await fireSubagentStop(external.status);
|
|
97243
|
+
return external;
|
|
97244
|
+
} catch (err) {
|
|
97245
|
+
emitFleetEvent({
|
|
97246
|
+
kind: "upsert",
|
|
97247
|
+
id: workerId,
|
|
97248
|
+
label,
|
|
97249
|
+
status: "failed",
|
|
97250
|
+
detail: "error",
|
|
97251
|
+
task,
|
|
97252
|
+
...externalMark
|
|
97253
|
+
});
|
|
97254
|
+
await fireSubagentStop("Error");
|
|
97255
|
+
return {
|
|
97256
|
+
status: "Error",
|
|
97257
|
+
output: `external runtime failed before the agent could report: ${err.message}`,
|
|
97258
|
+
isError: true
|
|
97259
|
+
};
|
|
97260
|
+
} finally {
|
|
97261
|
+
ledger.release(spawned.reservation.reservationId, {
|
|
97262
|
+
maxRuntimeMs: Math.round(performance.now() - externalStartedAt)
|
|
97263
|
+
});
|
|
97264
|
+
}
|
|
97265
|
+
}
|
|
97266
|
+
const nativeStartedAt = performance.now();
|
|
97267
|
+
const nativeStartOutcome = await fireSubagentStart("internal");
|
|
97268
|
+
if (nativeStartOutcome === "deny" || nativeStartOutcome === "ask") {
|
|
97269
|
+
emitFleetEvent({ kind: "upsert", id: workerId, label, status: "failed", detail: "hook-denied", task });
|
|
97212
97270
|
ledger.release(spawned.reservation.reservationId, {
|
|
97213
|
-
maxRuntimeMs: Math.round(performance.now() -
|
|
97271
|
+
maxRuntimeMs: Math.round(performance.now() - nativeStartedAt)
|
|
97214
97272
|
});
|
|
97215
97273
|
return {
|
|
97216
97274
|
status: "Denied",
|
|
@@ -97218,333 +97276,289 @@ function createSpawnSubagentTool(deps) {
|
|
|
97218
97276
|
isError: true
|
|
97219
97277
|
};
|
|
97220
97278
|
}
|
|
97279
|
+
const cwd = childCwd;
|
|
97280
|
+
const tools = mode === "read_only" ? [
|
|
97281
|
+
...builtinReadOnlyTools(cwd),
|
|
97282
|
+
...builtinMetaprojectTools(cwd, makeKeryxRunner(cwd), createMetaprojectAdapter(cwd))
|
|
97283
|
+
] : [
|
|
97284
|
+
...builtinReadOnlyTools(cwd),
|
|
97285
|
+
...builtinMetaprojectTools(cwd, makeKeryxRunner(cwd), createMetaprojectAdapter(cwd))
|
|
97286
|
+
];
|
|
97287
|
+
let ephemeralDir;
|
|
97288
|
+
let openedChildSlate;
|
|
97289
|
+
let dispatchId = "";
|
|
97290
|
+
let closing = false;
|
|
97221
97291
|
try {
|
|
97222
|
-
|
|
97223
|
-
|
|
97224
|
-
|
|
97225
|
-
|
|
97226
|
-
|
|
97227
|
-
|
|
97228
|
-
|
|
97229
|
-
task,
|
|
97230
|
-
...externalMark
|
|
97292
|
+
ephemeralDir = await mkdtemp2(path220.join(tmpdir6(), "keryx-subagent-slate-"));
|
|
97293
|
+
dispatchId = path220.basename(ephemeralDir);
|
|
97294
|
+
openedChildSlate = await openSlate({
|
|
97295
|
+
dir: ephemeralDir,
|
|
97296
|
+
cwd,
|
|
97297
|
+
mintAttemptId: () => idSeq(),
|
|
97298
|
+
runtime: { provider: runModel.provider, model: runModel.model }
|
|
97231
97299
|
});
|
|
97232
|
-
|
|
97233
|
-
|
|
97234
|
-
|
|
97235
|
-
|
|
97236
|
-
|
|
97237
|
-
|
|
97238
|
-
|
|
97239
|
-
|
|
97240
|
-
|
|
97241
|
-
|
|
97242
|
-
|
|
97243
|
-
});
|
|
97244
|
-
await fireSubagentStop("Error");
|
|
97245
|
-
return {
|
|
97246
|
-
status: "Error",
|
|
97247
|
-
output: `external runtime failed before the agent could report: ${err.message}`,
|
|
97248
|
-
isError: true
|
|
97249
|
-
};
|
|
97250
|
-
} finally {
|
|
97300
|
+
tools.push(slateWriteSeedTool(() => closing ? undefined : ephemeralDir, idSeq, clock));
|
|
97301
|
+
} catch {
|
|
97302
|
+
openedChildSlate = undefined;
|
|
97303
|
+
}
|
|
97304
|
+
let provider;
|
|
97305
|
+
try {
|
|
97306
|
+
provider = deps.makeProvider(runModel.provider, runModel.model, parent.baseUrl);
|
|
97307
|
+
} catch (cause) {
|
|
97308
|
+
if (ephemeralDir !== undefined) {
|
|
97309
|
+
await rm15(ephemeralDir, { recursive: true, force: true }).catch(() => {});
|
|
97310
|
+
}
|
|
97311
|
+
await fireSubagentStop("Error").catch(() => {});
|
|
97251
97312
|
ledger.release(spawned.reservation.reservationId, {
|
|
97252
|
-
maxRuntimeMs: Math.round(performance.now() -
|
|
97313
|
+
maxRuntimeMs: Math.round(performance.now() - nativeStartedAt)
|
|
97253
97314
|
});
|
|
97315
|
+
throw cause;
|
|
97254
97316
|
}
|
|
97255
|
-
|
|
97256
|
-
|
|
97257
|
-
|
|
97258
|
-
|
|
97259
|
-
|
|
97260
|
-
|
|
97261
|
-
|
|
97262
|
-
|
|
97263
|
-
|
|
97264
|
-
|
|
97265
|
-
|
|
97266
|
-
|
|
97317
|
+
const childHooks = deps.hooks === undefined ? undefined : (() => {
|
|
97318
|
+
const childRunId = idSeq();
|
|
97319
|
+
return { runtime: deps.hooks.forChild({ sessionId: workerId, runId: childRunId }), sessionId: workerId, runId: childRunId };
|
|
97320
|
+
})();
|
|
97321
|
+
const childDeps = {
|
|
97322
|
+
provider,
|
|
97323
|
+
providerId: runModel.provider,
|
|
97324
|
+
modelId: runModel.model,
|
|
97325
|
+
tools,
|
|
97326
|
+
...childHooks !== undefined ? { hooks: childHooks } : {},
|
|
97327
|
+
systemInstruction: "You are a keryx subagent. Complete ONLY the assigned task. " + "Be concise. Use tools when needed. Do not spawn further subagents. " + (configuredMaxToolCalls === undefined ? "" : `You may invoke at most ${configuredMaxToolCalls} tools in total (a hard limit). `) + (advisoryToolCalls === undefined ? "" : `Aim to finish within about ${advisoryToolCalls} tool calls \u2014 a target, not a hard stop; ` + "tool results will tell you when you are close. ") + `You have up to ${maxRounds} model turns (rounds) to complete this task \u2014 each round ` + "may include several tool calls; an identical call repeated does not start a new round " + "but is still capped at a few attempts, so do not retry the same query hoping for a " + "different answer. If a graph/symbol/wiki lookup returns empty or 'not found', that tool " + "has no index for this \u2014 do not re-run it with a slightly reworded query; switch tool " + "(e.g. a direct file read or a plain text/code search) or report the gap instead of " + "spending rounds probing the same dead end. When a tool result says your budget is nearly " + "spent, stop exploring and return your result. If a limit is reached you get one final round " + "in which the only tool is submit_result \u2014 use it to hand back a partial result. " + "End with a short factual summary the parent can use.",
|
|
97328
|
+
idSeq: () => idSeq(),
|
|
97329
|
+
controlNonce: generateControlNonce(),
|
|
97330
|
+
maxRounds,
|
|
97331
|
+
...configuredMaxToolCalls === undefined ? {} : { maxToolCalls: configuredMaxToolCalls },
|
|
97332
|
+
subagentBudget: advisoryToolCalls === undefined ? {} : { advisoryToolCalls }
|
|
97267
97333
|
};
|
|
97268
|
-
|
|
97269
|
-
|
|
97270
|
-
|
|
97271
|
-
|
|
97272
|
-
|
|
97273
|
-
|
|
97274
|
-
|
|
97275
|
-
|
|
97276
|
-
|
|
97277
|
-
|
|
97278
|
-
|
|
97279
|
-
|
|
97280
|
-
|
|
97281
|
-
|
|
97282
|
-
|
|
97283
|
-
|
|
97284
|
-
|
|
97285
|
-
|
|
97286
|
-
|
|
97287
|
-
|
|
97288
|
-
|
|
97289
|
-
|
|
97290
|
-
|
|
97291
|
-
|
|
97292
|
-
|
|
97293
|
-
|
|
97294
|
-
|
|
97295
|
-
|
|
97296
|
-
|
|
97297
|
-
|
|
97298
|
-
|
|
97299
|
-
|
|
97300
|
-
|
|
97301
|
-
|
|
97302
|
-
|
|
97303
|
-
|
|
97304
|
-
|
|
97305
|
-
|
|
97306
|
-
|
|
97307
|
-
|
|
97308
|
-
|
|
97309
|
-
|
|
97310
|
-
|
|
97311
|
-
|
|
97312
|
-
|
|
97313
|
-
|
|
97314
|
-
|
|
97315
|
-
|
|
97316
|
-
|
|
97317
|
-
|
|
97318
|
-
|
|
97319
|
-
|
|
97320
|
-
|
|
97321
|
-
|
|
97322
|
-
|
|
97323
|
-
|
|
97324
|
-
|
|
97325
|
-
|
|
97326
|
-
|
|
97327
|
-
|
|
97328
|
-
const io = {
|
|
97329
|
-
write: (s) => {
|
|
97330
|
-
assistant += s;
|
|
97331
|
-
},
|
|
97332
|
-
onAssistantText: (text) => {
|
|
97333
|
-
assistant = text;
|
|
97334
|
-
if (closed) {
|
|
97335
|
-
return;
|
|
97336
|
-
}
|
|
97337
|
-
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "text", text } });
|
|
97338
|
-
},
|
|
97339
|
-
onReasoning: (text) => {
|
|
97340
|
-
if (closed) {
|
|
97341
|
-
return;
|
|
97342
|
-
}
|
|
97343
|
-
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "reasoning", text } });
|
|
97344
|
-
},
|
|
97345
|
-
onToolCall: (name) => {
|
|
97346
|
-
if (closed) {
|
|
97347
|
-
return;
|
|
97348
|
-
}
|
|
97349
|
-
emitFleetEvent({
|
|
97350
|
-
kind: "upsert",
|
|
97351
|
-
id: workerId,
|
|
97352
|
-
label,
|
|
97353
|
-
status: "running",
|
|
97354
|
-
detail: name.length > 14 ? `${name.slice(0, 12)}\u2026` : name,
|
|
97355
|
-
model: `${runModel.provider}/${runModel.model}`,
|
|
97356
|
-
task
|
|
97357
|
-
});
|
|
97358
|
-
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "tool", text: name } });
|
|
97359
|
-
},
|
|
97360
|
-
onToolResult: (name, result) => {
|
|
97361
|
-
if (closed) {
|
|
97362
|
-
return;
|
|
97363
|
-
}
|
|
97364
|
-
const preview = result.output.trim().slice(0, 400);
|
|
97365
|
-
emitFleetEvent({
|
|
97366
|
-
kind: "log",
|
|
97367
|
-
id: workerId,
|
|
97368
|
-
entry: { kind: "result", text: `${name}${result.isError ? " (error)" : ""} ${preview}` }
|
|
97334
|
+
let assistant = "";
|
|
97335
|
+
let closed = false;
|
|
97336
|
+
const internalAbort = new AbortController;
|
|
97337
|
+
const composed = composeAbortSignals(toolCtx?.signal, internalAbort.signal);
|
|
97338
|
+
const io = {
|
|
97339
|
+
write: (s) => {
|
|
97340
|
+
assistant += s;
|
|
97341
|
+
},
|
|
97342
|
+
onAssistantText: (text) => {
|
|
97343
|
+
assistant = text;
|
|
97344
|
+
if (closed) {
|
|
97345
|
+
return;
|
|
97346
|
+
}
|
|
97347
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "text", text } });
|
|
97348
|
+
},
|
|
97349
|
+
onReasoning: (text) => {
|
|
97350
|
+
if (closed) {
|
|
97351
|
+
return;
|
|
97352
|
+
}
|
|
97353
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "reasoning", text } });
|
|
97354
|
+
},
|
|
97355
|
+
onToolCall: (name) => {
|
|
97356
|
+
if (closed) {
|
|
97357
|
+
return;
|
|
97358
|
+
}
|
|
97359
|
+
emitFleetEvent({
|
|
97360
|
+
kind: "upsert",
|
|
97361
|
+
id: workerId,
|
|
97362
|
+
label,
|
|
97363
|
+
status: "running",
|
|
97364
|
+
detail: name.length > 14 ? `${name.slice(0, 12)}\u2026` : name,
|
|
97365
|
+
model: `${runModel.provider}/${runModel.model}`,
|
|
97366
|
+
task
|
|
97367
|
+
});
|
|
97368
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "tool", text: name } });
|
|
97369
|
+
},
|
|
97370
|
+
onToolResult: (name, result) => {
|
|
97371
|
+
if (closed) {
|
|
97372
|
+
return;
|
|
97373
|
+
}
|
|
97374
|
+
const preview = result.output.trim().slice(0, 400);
|
|
97375
|
+
emitFleetEvent({
|
|
97376
|
+
kind: "log",
|
|
97377
|
+
id: workerId,
|
|
97378
|
+
entry: { kind: "result", text: `${name}${result.isError ? " (error)" : ""} ${preview}` }
|
|
97379
|
+
});
|
|
97380
|
+
},
|
|
97381
|
+
onSystem: (text) => {
|
|
97382
|
+
if (closed) {
|
|
97383
|
+
return;
|
|
97384
|
+
}
|
|
97385
|
+
emitFleetEvent({ kind: "log", id: workerId, entry: { kind: "system", text } });
|
|
97386
|
+
},
|
|
97387
|
+
requestApproval: async () => false
|
|
97388
|
+
};
|
|
97389
|
+
const deadlineMs = resolveSubagentTimeoutMs(spawned.reservation.maxRuntimeMs);
|
|
97390
|
+
const startedAt = performance.now();
|
|
97391
|
+
const releaseBudget = () => {
|
|
97392
|
+
ledger.release(spawned.reservation.reservationId, {
|
|
97393
|
+
maxRuntimeMs: Math.round(performance.now() - startedAt)
|
|
97369
97394
|
});
|
|
97370
|
-
}
|
|
97371
|
-
|
|
97372
|
-
|
|
97395
|
+
};
|
|
97396
|
+
const foldChildSlateAndCleanup = async (status) => {
|
|
97397
|
+
closing = true;
|
|
97398
|
+
if (ephemeralDir === undefined) {
|
|
97373
97399
|
return;
|
|
97374
97400
|
}
|
|
97375
|
-
|
|
97376
|
-
|
|
97377
|
-
|
|
97378
|
-
|
|
97379
|
-
|
|
97380
|
-
|
|
97381
|
-
|
|
97382
|
-
|
|
97383
|
-
|
|
97384
|
-
|
|
97385
|
-
|
|
97386
|
-
|
|
97387
|
-
|
|
97388
|
-
if (ephemeralDir === undefined) {
|
|
97389
|
-
return;
|
|
97390
|
-
}
|
|
97391
|
-
const dirToClean = ephemeralDir;
|
|
97392
|
-
try {
|
|
97393
|
-
await withFileLock(slateLockPath(dirToClean), async () => {
|
|
97394
|
-
try {
|
|
97395
|
-
const slateSession = deps.getSlateSession?.();
|
|
97396
|
-
if (openedChildSlate !== undefined && slateSession !== undefined) {
|
|
97397
|
-
try {
|
|
97398
|
-
const childSlate = await readSlate(dirToClean);
|
|
97399
|
-
const dispatch = {
|
|
97400
|
-
anchors: childSlate?.anchors ?? openedChildSlate.anchors,
|
|
97401
|
-
course: childSlate?.course ?? openedChildSlate.course,
|
|
97402
|
-
seeds: childSlate?.seeds ?? [],
|
|
97403
|
-
status
|
|
97404
|
-
};
|
|
97405
|
-
const parentDir = slateSession.dir;
|
|
97406
|
-
await writeSlate(parentDir, (prev) => {
|
|
97407
|
-
if (prev === undefined) {
|
|
97408
|
-
throw new Error(`foldChildSlateAndCleanup: no open parent slate in ${parentDir}`);
|
|
97409
|
-
}
|
|
97410
|
-
return {
|
|
97411
|
-
...prev,
|
|
97412
|
-
childDispatches: { ...prev.childDispatches ?? {}, [dispatchId]: dispatch }
|
|
97401
|
+
const dirToClean = ephemeralDir;
|
|
97402
|
+
try {
|
|
97403
|
+
await withFileLock(slateLockPath(dirToClean), async () => {
|
|
97404
|
+
try {
|
|
97405
|
+
const slateSession = deps.getSlateSession?.();
|
|
97406
|
+
if (openedChildSlate !== undefined && slateSession !== undefined) {
|
|
97407
|
+
try {
|
|
97408
|
+
const childSlate = await readSlate(dirToClean);
|
|
97409
|
+
const dispatch = {
|
|
97410
|
+
anchors: childSlate?.anchors ?? openedChildSlate.anchors,
|
|
97411
|
+
course: childSlate?.course ?? openedChildSlate.course,
|
|
97412
|
+
seeds: childSlate?.seeds ?? [],
|
|
97413
|
+
status
|
|
97413
97414
|
};
|
|
97414
|
-
|
|
97415
|
-
|
|
97416
|
-
|
|
97417
|
-
|
|
97418
|
-
|
|
97419
|
-
|
|
97420
|
-
|
|
97421
|
-
|
|
97415
|
+
const parentDir = slateSession.dir;
|
|
97416
|
+
await writeSlate(parentDir, (prev) => {
|
|
97417
|
+
if (prev === undefined) {
|
|
97418
|
+
throw new Error(`foldChildSlateAndCleanup: no open parent slate in ${parentDir}`);
|
|
97419
|
+
}
|
|
97420
|
+
return {
|
|
97421
|
+
...prev,
|
|
97422
|
+
childDispatches: { ...prev.childDispatches ?? {}, [dispatchId]: dispatch }
|
|
97423
|
+
};
|
|
97424
|
+
});
|
|
97425
|
+
} catch (foldCause) {
|
|
97426
|
+
const foldMsg = foldCause instanceof Error ? foldCause.message : String(foldCause);
|
|
97427
|
+
emitFleetEvent({
|
|
97428
|
+
kind: "log",
|
|
97429
|
+
id: workerId,
|
|
97430
|
+
entry: { kind: "system", text: `slate fold failed (ignored): ${foldMsg}` }
|
|
97431
|
+
});
|
|
97432
|
+
}
|
|
97422
97433
|
}
|
|
97434
|
+
} finally {
|
|
97435
|
+
await rm15(dirToClean, { recursive: true, force: true }).catch(() => {});
|
|
97423
97436
|
}
|
|
97424
|
-
}
|
|
97425
|
-
|
|
97426
|
-
|
|
97427
|
-
|
|
97428
|
-
|
|
97429
|
-
|
|
97430
|
-
|
|
97431
|
-
|
|
97432
|
-
|
|
97433
|
-
|
|
97434
|
-
|
|
97435
|
-
|
|
97436
|
-
|
|
97437
|
-
|
|
97438
|
-
|
|
97439
|
-
|
|
97440
|
-
|
|
97441
|
-
history.push({ role: "user", content: renderAnchorsBlock(openedChildSlate.anchors), provenance: "project", injected: true });
|
|
97442
|
-
}
|
|
97443
|
-
const userLine = `## Subagent task (${mode})
|
|
97437
|
+
});
|
|
97438
|
+
} catch (lockCause) {
|
|
97439
|
+
const lockMsg = lockCause instanceof Error ? lockCause.message : String(lockCause);
|
|
97440
|
+
emitFleetEvent({
|
|
97441
|
+
kind: "log",
|
|
97442
|
+
id: workerId,
|
|
97443
|
+
entry: { kind: "system", text: `slate cleanup lock failed (ignored): ${lockMsg}` }
|
|
97444
|
+
});
|
|
97445
|
+
await rm15(dirToClean, { recursive: true, force: true }).catch(() => {});
|
|
97446
|
+
}
|
|
97447
|
+
};
|
|
97448
|
+
try {
|
|
97449
|
+
const history = [];
|
|
97450
|
+
if (openedChildSlate !== undefined) {
|
|
97451
|
+
history.push({ role: "user", content: renderAnchorsBlock(openedChildSlate.anchors), provenance: "project", injected: true });
|
|
97452
|
+
}
|
|
97453
|
+
const userLine = `## Subagent task (${mode})
|
|
97444
97454
|
` + `${task}
|
|
97445
97455
|
|
|
97446
97456
|
` + `Project root: ${childCwd}
|
|
97447
97457
|
` + `Round budget: ${maxRounds} rounds \u2014 plan which tools to try before spending them; prefer a ` + "direct, targeted lookup (exact file path, exact symbol) over a broad/guessed one, and fall " + `back to a different tool rather than repeating a failed call.
|
|
97448
97458
|
|
|
97449
97459
|
` + "Return a concise summary of findings and any recommended next steps for the parent agent.";
|
|
97450
|
-
|
|
97451
|
-
|
|
97452
|
-
|
|
97453
|
-
|
|
97454
|
-
|
|
97455
|
-
|
|
97456
|
-
|
|
97457
|
-
|
|
97458
|
-
|
|
97459
|
-
|
|
97460
|
-
|
|
97461
|
-
|
|
97462
|
-
|
|
97463
|
-
|
|
97464
|
-
|
|
97465
|
-
|
|
97466
|
-
|
|
97467
|
-
|
|
97468
|
-
|
|
97469
|
-
|
|
97470
|
-
|
|
97471
|
-
|
|
97472
|
-
|
|
97473
|
-
|
|
97474
|
-
|
|
97475
|
-
|
|
97476
|
-
|
|
97477
|
-
|
|
97460
|
+
const turn = runAgentTurn(io, childDeps, history, userLine, { signal: composed.signal });
|
|
97461
|
+
let turnResult;
|
|
97462
|
+
if (deadlineMs > 0) {
|
|
97463
|
+
let timer;
|
|
97464
|
+
const expired = new Promise((resolve) => {
|
|
97465
|
+
timer = setTimeout(() => resolve("timeout"), deadlineMs);
|
|
97466
|
+
});
|
|
97467
|
+
let outcome;
|
|
97468
|
+
try {
|
|
97469
|
+
outcome = await Promise.race([turn.then(() => "done"), expired]);
|
|
97470
|
+
} finally {
|
|
97471
|
+
if (timer !== undefined)
|
|
97472
|
+
clearTimeout(timer);
|
|
97473
|
+
}
|
|
97474
|
+
if (outcome === "timeout") {
|
|
97475
|
+
closed = true;
|
|
97476
|
+
internalAbort.abort();
|
|
97477
|
+
turn.catch(() => {});
|
|
97478
|
+
composed.dispose();
|
|
97479
|
+
releaseBudget();
|
|
97480
|
+
emitFleetEvent({ kind: "upsert", id: workerId, label, status: "failed", detail: "timeout", task });
|
|
97481
|
+
await foldChildSlateAndCleanup("incomplete");
|
|
97482
|
+
await fireSubagentStop("Timeout");
|
|
97483
|
+
const partial = assistant.trim();
|
|
97484
|
+
const foldedPartial = partial.length > 0 ? foldChildSummary(partial).text : "";
|
|
97485
|
+
return {
|
|
97486
|
+
status: "Timeout",
|
|
97487
|
+
output: `subagent ${label} (${workerId}) timed out after ${deadlineMs}ms and was abandoned ` + `(tighten or disable with ${ENV_SUBAGENT_TIMEOUT_MS})` + (foldedPartial.length > 0 ? `
|
|
97478
97488
|
--- partial output ---
|
|
97479
97489
|
${boundSummary(foldedPartial)}` : ""),
|
|
97480
|
-
|
|
97481
|
-
|
|
97482
|
-
|
|
97490
|
+
isError: true,
|
|
97491
|
+
...foldedPartial.length > 0 ? { partial: boundSummary(foldedPartial) } : {}
|
|
97492
|
+
};
|
|
97493
|
+
}
|
|
97494
|
+
turnResult = await turn;
|
|
97495
|
+
} else {
|
|
97496
|
+
turnResult = await turn;
|
|
97483
97497
|
}
|
|
97484
|
-
|
|
97485
|
-
|
|
97486
|
-
|
|
97487
|
-
|
|
97488
|
-
closed = true;
|
|
97489
|
-
composed.dispose();
|
|
97490
|
-
releaseBudget();
|
|
97491
|
-
const raw = assistant.trim().length > 0 ? assistant.trim() : history.filter((m) => m.role === "assistant").map((m) => m.content).join(`
|
|
97498
|
+
closed = true;
|
|
97499
|
+
composed.dispose();
|
|
97500
|
+
releaseBudget();
|
|
97501
|
+
const raw = assistant.trim().length > 0 ? assistant.trim() : history.filter((m) => m.role === "assistant").map((m) => m.content).join(`
|
|
97492
97502
|
`).trim() || "(subagent produced no text)";
|
|
97493
|
-
|
|
97494
|
-
|
|
97495
|
-
|
|
97496
|
-
|
|
97497
|
-
|
|
97498
|
-
|
|
97499
|
-
|
|
97500
|
-
|
|
97501
|
-
|
|
97502
|
-
|
|
97503
|
-
|
|
97504
|
-
|
|
97505
|
-
|
|
97506
|
-
|
|
97507
|
-
|
|
97503
|
+
const folded = foldChildSummary(raw);
|
|
97504
|
+
const status = subagentStatusForFinishReason(turnResult?.finishReason);
|
|
97505
|
+
const isError = status !== "Completed";
|
|
97506
|
+
emitFleetEvent({
|
|
97507
|
+
kind: "upsert",
|
|
97508
|
+
id: workerId,
|
|
97509
|
+
label,
|
|
97510
|
+
status: isError ? "failed" : "done",
|
|
97511
|
+
detail: subagentFleetDetail(status),
|
|
97512
|
+
model: `${runModel.provider}/${runModel.model}`,
|
|
97513
|
+
task
|
|
97514
|
+
});
|
|
97515
|
+
await foldChildSlateAndCleanup(isError ? "incomplete" : "completed");
|
|
97516
|
+
await fireSubagentStop(status);
|
|
97517
|
+
const header = `subagent ${label} (${workerId}) ${mode} via ${runModel.provider}/${runModel.model}
|
|
97508
97518
|
` + `MAE reservation: rounds\u2264${maxRounds} ` + (configuredMaxToolCalls === undefined ? "" : `calls\u2264${configuredMaxToolCalls} `) + (advisoryToolCalls === undefined ? "" : `calls~${advisoryToolCalls}(advisory) `) + `runtime\u2264${spawned.reservation.maxRuntimeMs}ms children=${ledger.childCount}
|
|
97509
97519
|
` + (tierRecord === undefined ? "" : `${tierRecord}
|
|
97510
97520
|
`);
|
|
97511
|
-
|
|
97512
|
-
|
|
97521
|
+
if (status === "Completed") {
|
|
97522
|
+
return { status, isError, output: `${header}--- summary ---
|
|
97513
97523
|
${boundSummary(folded.text)}` };
|
|
97514
|
-
|
|
97515
|
-
|
|
97516
|
-
|
|
97517
|
-
|
|
97524
|
+
}
|
|
97525
|
+
const statusLine = formatStoppedStatusLine(status, turnResult);
|
|
97526
|
+
const submitted = turnResult?.submittedResult;
|
|
97527
|
+
const resultBlock = submitted !== undefined ? foldChildSummary(`--- submitted result (${submitted.status}) ---
|
|
97518
97528
|
` + `summary: ${submitted.summary}
|
|
97519
97529
|
` + `result:
|
|
97520
97530
|
${typeof submitted.result === "string" ? submitted.result : JSON.stringify(submitted.result, null, 2)}`).text : foldChildSummary(`no result submitted${turnResult?.submitResultError !== undefined ? ` (${turnResult.submitResultError})` : ""}
|
|
97521
97531
|
` + `--- last output ---
|
|
97522
97532
|
${raw}`).text;
|
|
97523
|
-
|
|
97524
|
-
|
|
97525
|
-
|
|
97526
|
-
|
|
97527
|
-
|
|
97533
|
+
const boundedResult = boundSummary(resultBlock);
|
|
97534
|
+
return {
|
|
97535
|
+
status,
|
|
97536
|
+
isError,
|
|
97537
|
+
output: `${statusLine}
|
|
97528
97538
|
${header}${boundedResult}`,
|
|
97529
|
-
|
|
97530
|
-
|
|
97539
|
+
partial: boundedResult
|
|
97540
|
+
};
|
|
97541
|
+
} catch (cause) {
|
|
97542
|
+
closed = true;
|
|
97543
|
+
internalAbort.abort();
|
|
97544
|
+
composed.dispose();
|
|
97545
|
+
releaseBudget();
|
|
97546
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
97547
|
+
emitFleetEvent({
|
|
97548
|
+
kind: "upsert",
|
|
97549
|
+
id: workerId,
|
|
97550
|
+
label,
|
|
97551
|
+
status: "failed",
|
|
97552
|
+
detail: "error",
|
|
97553
|
+
task
|
|
97554
|
+
});
|
|
97555
|
+
await foldChildSlateAndCleanup("incomplete");
|
|
97556
|
+
await fireSubagentStop("Error");
|
|
97557
|
+
return { status: "Error", output: `subagent ${label} failed: ${msg}`, isError: true };
|
|
97558
|
+
}
|
|
97531
97559
|
} catch (cause) {
|
|
97532
|
-
|
|
97533
|
-
|
|
97534
|
-
composed.dispose();
|
|
97535
|
-
releaseBudget();
|
|
97536
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
97537
|
-
emitFleetEvent({
|
|
97538
|
-
kind: "upsert",
|
|
97539
|
-
id: workerId,
|
|
97540
|
-
label,
|
|
97541
|
-
status: "failed",
|
|
97542
|
-
detail: "error",
|
|
97543
|
-
task
|
|
97544
|
-
});
|
|
97545
|
-
await foldChildSlateAndCleanup("incomplete");
|
|
97546
|
-
await fireSubagentStop("Error");
|
|
97547
|
-
return { status: "Error", output: `subagent ${label} failed: ${msg}`, isError: true };
|
|
97560
|
+
emitFleetEvent({ kind: "upsert", id: workerId, label, status: "failed", detail: "setup-error", task });
|
|
97561
|
+
throw cause;
|
|
97548
97562
|
}
|
|
97549
97563
|
}
|
|
97550
97564
|
};
|
|
@@ -107425,6 +107439,12 @@ var init_help_groups = __esm(() => {
|
|
|
107425
107439
|
group: "Working in keryx shell",
|
|
107426
107440
|
summary: "Manage the main queue \u2014 /queue <remove|edit|force> [N] (N = qN position, default 1)."
|
|
107427
107441
|
},
|
|
107442
|
+
{
|
|
107443
|
+
kind: "slash",
|
|
107444
|
+
name: "/tasks",
|
|
107445
|
+
group: "Working in keryx shell",
|
|
107446
|
+
summary: "List supervised shell tasks \u2014 /tasks [output <task_id> [cursor] | kill <task_id>]."
|
|
107447
|
+
},
|
|
107428
107448
|
{
|
|
107429
107449
|
kind: "slash",
|
|
107430
107450
|
name: "/interrupt",
|
|
@@ -109761,6 +109781,10 @@ function createBlockView(otui, renderer, parent, block, options = {}) {
|
|
|
109761
109781
|
render: (state, opts = {}) => {
|
|
109762
109782
|
paintHeader(state, opts.focused === true);
|
|
109763
109783
|
if (state.collapsed) {
|
|
109784
|
+
if (options.collapsedPreview !== undefined) {
|
|
109785
|
+
showBody(options.collapsedPreview);
|
|
109786
|
+
return;
|
|
109787
|
+
}
|
|
109764
109788
|
dropBody();
|
|
109765
109789
|
return;
|
|
109766
109790
|
}
|
|
@@ -123085,6 +123109,11 @@ var init_agent_commands = __esm(() => {
|
|
|
123085
123109
|
description: "Hand a task to an external agent CLI \u2014 /delegate <agent> <task>",
|
|
123086
123110
|
modes: AGENT_ONLY
|
|
123087
123111
|
},
|
|
123112
|
+
{
|
|
123113
|
+
name: "/tasks",
|
|
123114
|
+
description: "Shell tasks \u2014 /tasks, /tasks output <task_id> [cursor], /tasks kill <task_id>",
|
|
123115
|
+
modes: AGENT_ONLY
|
|
123116
|
+
},
|
|
123088
123117
|
{
|
|
123089
123118
|
name: "/demote",
|
|
123090
123119
|
description: "Move a running foreground task to the background \u2014 /demote <task_id>",
|
|
@@ -126890,13 +126919,75 @@ var init_proxy = __esm(() => {
|
|
|
126890
126919
|
init_guard();
|
|
126891
126920
|
});
|
|
126892
126921
|
|
|
126922
|
+
// src/commands/granted-json-ids.ts
|
|
126923
|
+
function letters(index) {
|
|
126924
|
+
return String(index).replace(/\d/g, (d) => String.fromCharCode(97 + Number(d)));
|
|
126925
|
+
}
|
|
126926
|
+
function protectJsonIds(text) {
|
|
126927
|
+
const head = text.trim();
|
|
126928
|
+
if (head.length === 0 || head[0] !== "[" && head[0] !== "{")
|
|
126929
|
+
return;
|
|
126930
|
+
if (text.includes(PLACEHOLDER))
|
|
126931
|
+
return;
|
|
126932
|
+
try {
|
|
126933
|
+
JSON.parse(head);
|
|
126934
|
+
} catch {
|
|
126935
|
+
return;
|
|
126936
|
+
}
|
|
126937
|
+
const hidden = [];
|
|
126938
|
+
const hide = (value) => {
|
|
126939
|
+
hidden.push(value);
|
|
126940
|
+
return `${PLACEHOLDER}${letters(hidden.length - 1)}x`;
|
|
126941
|
+
};
|
|
126942
|
+
let out = "";
|
|
126943
|
+
let i = 0;
|
|
126944
|
+
while (i < text.length) {
|
|
126945
|
+
const ch = text[i];
|
|
126946
|
+
if (ch === '"') {
|
|
126947
|
+
let j = i + 1;
|
|
126948
|
+
while (j < text.length && text[j] !== '"')
|
|
126949
|
+
j += text[j] === "\\" ? 2 : 1;
|
|
126950
|
+
const literal = text.slice(i, j + 1);
|
|
126951
|
+
const inner = literal.slice(1, -1);
|
|
126952
|
+
const prefix = GITHUB_URL_PREFIX.exec(inner);
|
|
126953
|
+
const rest = prefix === null ? "" : inner.slice(prefix[0].length);
|
|
126954
|
+
out += prefix !== null && GITHUB_URL_REST.test(rest) ? `"${prefix[0]}${rest.replace(/\d+/g, hide)}"` : literal;
|
|
126955
|
+
i = j + 1;
|
|
126956
|
+
continue;
|
|
126957
|
+
}
|
|
126958
|
+
const number = ch === "-" || ch >= "0" && ch <= "9" ? NUMBER2.exec(text.slice(i, i + 40)) : null;
|
|
126959
|
+
if (number !== null) {
|
|
126960
|
+
const key = /"((?:[^"\\]|\\.)*)"\s*:\s*$/.exec(out.slice(-120))?.[1] ?? "";
|
|
126961
|
+
out += SENSITIVE_KEY.test(key) ? number[0] : hide(number[0]);
|
|
126962
|
+
i += number[0].length;
|
|
126963
|
+
continue;
|
|
126964
|
+
}
|
|
126965
|
+
out += ch;
|
|
126966
|
+
i += 1;
|
|
126967
|
+
}
|
|
126968
|
+
return {
|
|
126969
|
+
text: out,
|
|
126970
|
+
restore: (scrubbed) => scrubbed.replace(new RegExp(`${PLACEHOLDER}([a-j]+)x`, "g"), (whole, index) => {
|
|
126971
|
+
const at = Number(index.replace(/[a-j]/g, (c) => String(c.charCodeAt(0) - 97)));
|
|
126972
|
+
return hidden[at] ?? whole;
|
|
126973
|
+
})
|
|
126974
|
+
};
|
|
126975
|
+
}
|
|
126976
|
+
var PLACEHOLDER = "kxjsonid", GITHUB_URL_PREFIX, GITHUB_URL_REST, SENSITIVE_KEY, NUMBER2;
|
|
126977
|
+
var init_granted_json_ids = __esm(() => {
|
|
126978
|
+
GITHUB_URL_PREFIX = /^https:\/\/(?:api\.)?github\.com\/(?:repos\/)?[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\//;
|
|
126979
|
+
GITHUB_URL_REST = /^(?:actions\/runs|pull|issues)\/\d+(?:\/[A-Za-z0-9_-]+)*(?:#[A-Za-z_-]+-?\d+)?$/;
|
|
126980
|
+
SENSITIVE_KEY = /token|secret|pass|key|auth|credential|private|ssn|phone|card|account|iban|pin|otp/i;
|
|
126981
|
+
NUMBER2 = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
|
|
126982
|
+
});
|
|
126983
|
+
|
|
126893
126984
|
// src/commands/trigger-agent-task.ts
|
|
126894
126985
|
import { execFile as execFile11 } from "child_process";
|
|
126895
126986
|
import { randomUUID as randomUUID35 } from "crypto";
|
|
126896
126987
|
import { mkdtemp as mkdtemp5, mkdir as mkdir60, readdir as readdir42, rm as rm19, writeFile as writeFile37 } from "fs/promises";
|
|
126897
126988
|
import { homedir as homedir12, tmpdir as tmpdir11 } from "os";
|
|
126898
126989
|
import path266 from "path";
|
|
126899
|
-
function scrubGrantedOutput(text, env, secrets = []) {
|
|
126990
|
+
function scrubGrantedOutput(text, env, secrets = [], json = false) {
|
|
126900
126991
|
let out = text;
|
|
126901
126992
|
for (const value of secrets) {
|
|
126902
126993
|
if (value.length >= 8)
|
|
@@ -126909,10 +127000,18 @@ function scrubGrantedOutput(text, env, secrets = []) {
|
|
|
126909
127000
|
}
|
|
126910
127001
|
for (const [shape, mask] of TOKEN_SHAPES)
|
|
126911
127002
|
out = out.replace(shape, mask);
|
|
127003
|
+
if (json) {
|
|
127004
|
+
const at = out.indexOf(STDERR_MARK);
|
|
127005
|
+
const protectedJson = protectJsonIds(at === -1 ? out : out.slice(0, at));
|
|
127006
|
+
if (protectedJson !== undefined) {
|
|
127007
|
+
const tail = at === -1 ? "" : redactSensitiveText(out.slice(at));
|
|
127008
|
+
return protectedJson.restore(redactSensitiveText(protectedJson.text)) + tail;
|
|
127009
|
+
}
|
|
127010
|
+
}
|
|
126912
127011
|
return redactSensitiveText(out);
|
|
126913
127012
|
}
|
|
126914
|
-
function scrubThenCap(raw, env, secrets, max = GRANTED_MAX_BYTES) {
|
|
126915
|
-
const scrubbed = scrubGrantedOutput(raw, env, secrets);
|
|
127013
|
+
function scrubThenCap(raw, env, secrets, max = GRANTED_MAX_BYTES, json = false) {
|
|
127014
|
+
const scrubbed = scrubGrantedOutput(raw, env, secrets, json);
|
|
126916
127015
|
if (scrubbed.length <= max)
|
|
126917
127016
|
return scrubbed;
|
|
126918
127017
|
const head = scrubbed.slice(0, max);
|
|
@@ -126930,7 +127029,7 @@ ${stderr}` : ""}`;
|
|
|
126930
127029
|
const code = error === null ? 0 : typeof error.code === "number" ? error.code : null;
|
|
126931
127030
|
const reason = error === null ? "" : `
|
|
126932
127031
|
[exit: ${code ?? error.message}]`;
|
|
126933
|
-
resolve({ output: `${scrubThenCap(raw, env, secrets)}${scrubGrantedOutput(reason, env, secrets)}`, exitCode: code, ok: error === null });
|
|
127032
|
+
resolve({ output: `${scrubThenCap(raw, env, secrets, GRANTED_MAX_BYTES, true)}${scrubGrantedOutput(reason, env, secrets)}`, exitCode: code, ok: error === null });
|
|
126934
127033
|
});
|
|
126935
127034
|
});
|
|
126936
127035
|
}
|
|
@@ -127297,7 +127396,9 @@ function defaultArmTimeout2(ms, fire) {
|
|
|
127297
127396
|
timer.unref?.();
|
|
127298
127397
|
return () => clearTimeout(timer);
|
|
127299
127398
|
}
|
|
127300
|
-
var GRANTED_TIMEOUT_MS = 30000, GRANTED_MAX_BYTES,
|
|
127399
|
+
var GRANTED_TIMEOUT_MS = 30000, GRANTED_MAX_BYTES, STDERR_MARK = `
|
|
127400
|
+
[stderr]
|
|
127401
|
+
`, SECRET_ENV_NAME, TOKEN_SHAPES;
|
|
127301
127402
|
var init_trigger_agent_task = __esm(() => {
|
|
127302
127403
|
init_agent();
|
|
127303
127404
|
init_agent_hooks();
|
|
@@ -127309,6 +127410,7 @@ var init_trigger_agent_task = __esm(() => {
|
|
|
127309
127410
|
init_fs();
|
|
127310
127411
|
init_maintenance_lock();
|
|
127311
127412
|
init_service2();
|
|
127413
|
+
init_granted_json_ids();
|
|
127312
127414
|
init_granted_binary();
|
|
127313
127415
|
init_schedule_verify();
|
|
127314
127416
|
init_granted_tools();
|
|
@@ -127359,9 +127461,9 @@ function ghEnvForProject(projectRoot, base = process.env) {
|
|
|
127359
127461
|
function parseGrantedOutput(output, ok, exitCode) {
|
|
127360
127462
|
const exit = EXIT_MARK.exec(output);
|
|
127361
127463
|
const withoutExit = exit === null ? output : output.slice(0, exit.index);
|
|
127362
|
-
const stderrAt = withoutExit.indexOf(
|
|
127464
|
+
const stderrAt = withoutExit.indexOf(STDERR_MARK2);
|
|
127363
127465
|
const stdout = stderrAt === -1 ? withoutExit : withoutExit.slice(0, stderrAt);
|
|
127364
|
-
const stderr = stderrAt === -1 ? "" : withoutExit.slice(stderrAt +
|
|
127466
|
+
const stderr = stderrAt === -1 ? "" : withoutExit.slice(stderrAt + STDERR_MARK2.length).trim();
|
|
127365
127467
|
if (!ok) {
|
|
127366
127468
|
const why = stderr.length > 0 ? stderr : exit !== null ? exit[0].trim() : "gh failed";
|
|
127367
127469
|
return { ok: false, stdout: "", detail: `${why.replace(/\s+/g, " ").slice(0, 300)}`, exitCode };
|
|
@@ -127371,7 +127473,7 @@ function parseGrantedOutput(output, ok, exitCode) {
|
|
|
127371
127473
|
}
|
|
127372
127474
|
return { ok: true, stdout, detail: "", exitCode };
|
|
127373
127475
|
}
|
|
127374
|
-
var GH_ENV_ALLOWED,
|
|
127476
|
+
var GH_ENV_ALLOWED, STDERR_MARK2 = `
|
|
127375
127477
|
[stderr]
|
|
127376
127478
|
`, TRUNCATED, EXIT_MARK, defaultGhRunner = async (call) => {
|
|
127377
127479
|
const result = await runGrantedCommand(call.bin, call.argv, call.cwd, call.env, call.signal, call.secrets);
|
|
@@ -144030,15 +144132,18 @@ function classifyDeterministic(line) {
|
|
|
144030
144132
|
return;
|
|
144031
144133
|
if (REVIEW_RE.test(trimmed))
|
|
144032
144134
|
return "review";
|
|
144135
|
+
if (RUSSIAN_CHITCHAT_RE.test(trimmed))
|
|
144136
|
+
return "quick";
|
|
144033
144137
|
const words = trimmed.split(/\s+/).filter((w) => w.length > 0);
|
|
144034
144138
|
if (trimmed.length <= CHITCHAT_MAX_CHARS && words.length <= CHITCHAT_MAX_WORDS && CHITCHAT_RE.test(trimmed)) {
|
|
144035
144139
|
return "quick";
|
|
144036
144140
|
}
|
|
144037
144141
|
return;
|
|
144038
144142
|
}
|
|
144039
|
-
var CHITCHAT_RE, CHITCHAT_MAX_CHARS = 24, CHITCHAT_MAX_WORDS = 4, REVIEW_RE;
|
|
144143
|
+
var CHITCHAT_RE, CHITCHAT_MAX_CHARS = 24, CHITCHAT_MAX_WORDS = 4, RUSSIAN_CHITCHAT_RE, REVIEW_RE;
|
|
144040
144144
|
var init_deterministic_shortcuts = __esm(() => {
|
|
144041
144145
|
CHITCHAT_RE = /^(?:hi|hello|hey|yo|thanks|thank you|thx|ty|ok|okay|k|cool|nice|great|awesome|sounds good|got it|sure|yes|no|yep|yup|nope|nah|good morning|good night|gm|lol|haha|np|no problem|welcome|you're welcome)[.!?]*$/i;
|
|
144146
|
+
RUSSIAN_CHITCHAT_RE = /^(?:\u043F\u0440\u0438\u0432\u0435\u0442|\u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439|\u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435|\u0441\u043F\u0430\u0441\u0438\u0431\u043E|\u043E\u043A|\u0434\u0430|\u043D\u0435\u0442)[.!?]*(?:\s+\u043E\u0442\u0432\u0435\u0442\u044C \u043E\u0434\u043D\u0438\u043C \u0441\u043B\u043E\u0432\u043E\u043C[.!?]*)?$/i;
|
|
144042
144147
|
REVIEW_RE = /\b(?:code\s+review|review(?:s|ed|ing)?|PRs?|pull\s+requests?)\b/i;
|
|
144043
144148
|
});
|
|
144044
144149
|
|
|
@@ -144298,6 +144403,11 @@ async function runRoutingClassifierForTurn(line, opts) {
|
|
|
144298
144403
|
}
|
|
144299
144404
|
return { classification, category, assignment: resolved.assignment };
|
|
144300
144405
|
}
|
|
144406
|
+
function renderRoutingFallbackLine(result) {
|
|
144407
|
+
if (result === undefined)
|
|
144408
|
+
return "[route fallback: no classifier category; using session model]";
|
|
144409
|
+
return `[route fallback: ${result.category} -> ${describeAssignment(result.assignment)}; using session model]`;
|
|
144410
|
+
}
|
|
144301
144411
|
function pct6(n) {
|
|
144302
144412
|
return `${Math.round(n * 100)}%`;
|
|
144303
144413
|
}
|
|
@@ -147101,6 +147211,71 @@ var init_help_first_run = __esm(() => {
|
|
|
147101
147211
|
init_config_dir();
|
|
147102
147212
|
});
|
|
147103
147213
|
|
|
147214
|
+
// src/tui/tasks-command.ts
|
|
147215
|
+
async function runTasksCommand(args, registry) {
|
|
147216
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
147217
|
+
const usage = `Usage: /tasks [output <task_id> [cursor] | kill <task_id>]
|
|
147218
|
+
`;
|
|
147219
|
+
if (registry === undefined)
|
|
147220
|
+
return `This session tracks no shell tasks.
|
|
147221
|
+
`;
|
|
147222
|
+
if (parts.length === 0) {
|
|
147223
|
+
const tasks = registry.list();
|
|
147224
|
+
return tasks.length === 0 ? `No shell tasks.
|
|
147225
|
+
` : tasks.map((task) => `${task.jobId} \xB7 ${task.status} \xB7 ${task.phase} \xB7 ${task.description ?? task.command}`).join(`
|
|
147226
|
+
`) + `
|
|
147227
|
+
`;
|
|
147228
|
+
}
|
|
147229
|
+
const [action, id, rawCursor] = parts;
|
|
147230
|
+
if (id === undefined)
|
|
147231
|
+
return usage;
|
|
147232
|
+
if (action === "output" && parts.length <= 3) {
|
|
147233
|
+
if (rawCursor !== undefined && !/^\d+$/.test(rawCursor))
|
|
147234
|
+
return usage;
|
|
147235
|
+
const cursor = Number(rawCursor ?? 0);
|
|
147236
|
+
if (!Number.isSafeInteger(cursor))
|
|
147237
|
+
return usage;
|
|
147238
|
+
const result = registry.readOutputSince(id, cursor);
|
|
147239
|
+
if (!result.ok)
|
|
147240
|
+
return `${result.error}
|
|
147241
|
+
`;
|
|
147242
|
+
return `${id} \xB7 ${result.status} \xB7 next_cursor=${result.nextCursor}${result.missed > 0 ? ` \xB7 missed=${result.missed}` : ""}
|
|
147243
|
+
${result.output}
|
|
147244
|
+
`;
|
|
147245
|
+
}
|
|
147246
|
+
if (action === "kill" && parts.length === 2) {
|
|
147247
|
+
const result = await registry.kill(id, "operator");
|
|
147248
|
+
if (!result.ok)
|
|
147249
|
+
return `${result.error}
|
|
147250
|
+
`;
|
|
147251
|
+
return `${id} \xB7 ${registry.get(id)?.status ?? "unknown"}
|
|
147252
|
+
`;
|
|
147253
|
+
}
|
|
147254
|
+
return usage;
|
|
147255
|
+
}
|
|
147256
|
+
|
|
147257
|
+
// src/tui/usage-format.ts
|
|
147258
|
+
function formatUsageLine(usage) {
|
|
147259
|
+
const parts = [];
|
|
147260
|
+
if (usage.inputTokens !== undefined)
|
|
147261
|
+
parts.push(`\u2191${usage.inputTokens}`);
|
|
147262
|
+
if (usage.outputTokens !== undefined)
|
|
147263
|
+
parts.push(`\u2193${usage.outputTokens}`);
|
|
147264
|
+
if (parts.length === 0)
|
|
147265
|
+
return;
|
|
147266
|
+
const cache = [];
|
|
147267
|
+
if (usage.cacheReadTokens !== undefined)
|
|
147268
|
+
cache.push(`cache-read ${usage.cacheReadTokens}`);
|
|
147269
|
+
if (usage.cacheWriteTokens !== undefined)
|
|
147270
|
+
cache.push(`cache-write ${usage.cacheWriteTokens}`);
|
|
147271
|
+
if (usage.inputTokens !== undefined && usage.cacheReadTokens !== undefined && usage.cacheWriteTokens !== undefined) {
|
|
147272
|
+
const uncached = usage.inputTokens - usage.cacheReadTokens - usage.cacheWriteTokens;
|
|
147273
|
+
if (uncached >= 0)
|
|
147274
|
+
cache.push(`uncached ${uncached}`);
|
|
147275
|
+
}
|
|
147276
|
+
return `${parts.join(" ")} tokens${cache.length > 0 ? ` \xB7 ${cache.join(" \xB7 ")}` : " \xB7 cache not reported"}`;
|
|
147277
|
+
}
|
|
147278
|
+
|
|
147104
147279
|
// src/tui/settings-actions.ts
|
|
147105
147280
|
async function runSettingsCommand(command, handlers) {
|
|
147106
147281
|
const [name = "", ...rest] = command.trim().split(/\s+/);
|
|
@@ -157575,16 +157750,9 @@ function createTuiAgentIo(otui, renderer, transcript) {
|
|
|
157575
157750
|
}))}`);
|
|
157576
157751
|
},
|
|
157577
157752
|
onUsage: (usage) => {
|
|
157578
|
-
const
|
|
157579
|
-
if (
|
|
157580
|
-
|
|
157581
|
-
}
|
|
157582
|
-
if (usage.outputTokens !== undefined) {
|
|
157583
|
-
parts.push(`\u2193${usage.outputTokens}`);
|
|
157584
|
-
}
|
|
157585
|
-
if (parts.length > 0) {
|
|
157586
|
-
append(otui.t`${dimChunk(otui, `${parts.join(" ")} tokens`)}`);
|
|
157587
|
-
}
|
|
157753
|
+
const line = formatUsageLine(usage);
|
|
157754
|
+
if (line !== undefined)
|
|
157755
|
+
append(otui.t`${dimChunk(otui, line)}`);
|
|
157588
157756
|
},
|
|
157589
157757
|
onToolCall: (name, input) => {
|
|
157590
157758
|
const args = summarizeToolArgs(input);
|
|
@@ -162453,6 +162621,10 @@ ${formatThemeList(getThemeId())}`);
|
|
|
162453
162621
|
}
|
|
162454
162622
|
return;
|
|
162455
162623
|
}
|
|
162624
|
+
if (command.name === "/tasks") {
|
|
162625
|
+
trackCommandWork(() => runTasksCommand(line.slice(command.name.length), deps.jobRegistry).then((text) => io.onSystem?.(text)));
|
|
162626
|
+
return;
|
|
162627
|
+
}
|
|
162456
162628
|
if (command.name === "/clear" || command.name === "/new") {
|
|
162457
162629
|
(async () => {
|
|
162458
162630
|
await closeSlateSession(slateSession, mintTimestampAttemptId);
|
|
@@ -163022,6 +163194,15 @@ ${formatThemeList(getThemeId())}`);
|
|
|
163022
163194
|
if (line.startsWith("/")) {
|
|
163023
163195
|
io.onSystem?.(describeUnavailableCommand(line, "agent") ?? `Unknown command: ${line}
|
|
163024
163196
|
`);
|
|
163197
|
+
const help = renderCommandHelp("agent");
|
|
163198
|
+
addBlock({ kind: "output", fullText: help, summary: "Available commands", lineCount: help.trimEnd().split(`
|
|
163199
|
+
`).length }, {
|
|
163200
|
+
hint: "ctrl+o \xB7 Enter to expand",
|
|
163201
|
+
collapsedPreview: help.trimEnd().split(`
|
|
163202
|
+
`).slice(0, 8).join(`
|
|
163203
|
+
`),
|
|
163204
|
+
maxLines: 500
|
|
163205
|
+
});
|
|
163025
163206
|
io.onSystem?.(helpText());
|
|
163026
163207
|
return;
|
|
163027
163208
|
}
|
|
@@ -163258,6 +163439,10 @@ ${formatThemeList(getThemeId())}`);
|
|
|
163258
163439
|
(async () => {
|
|
163259
163440
|
let deps = sessionDeps;
|
|
163260
163441
|
let routingOutcome;
|
|
163442
|
+
if (routingEnabled && sessionModelExplicit && origin === "operator") {
|
|
163443
|
+
io.onSystem?.(`[route skipped: manual /model selection pins this session]
|
|
163444
|
+
`);
|
|
163445
|
+
}
|
|
163261
163446
|
if (routingEnabled && !sessionModelExplicit && origin === "operator" && line.trim().length > 0) {
|
|
163262
163447
|
try {
|
|
163263
163448
|
routingOutcome = await runRoutingClassifierForTurn(line, {
|
|
@@ -163287,7 +163472,12 @@ ${formatThemeList(getThemeId())}`);
|
|
|
163287
163472
|
`);
|
|
163288
163473
|
} catch {
|
|
163289
163474
|
deps = sessionDeps;
|
|
163475
|
+
io.onSystem?.(`[route fallback: selected model could not be prepared; check availability and external policy; using session model]
|
|
163476
|
+
`);
|
|
163290
163477
|
}
|
|
163478
|
+
} else {
|
|
163479
|
+
io.onSystem?.(`${renderRoutingFallbackLine(routingOutcome)}
|
|
163480
|
+
`);
|
|
163291
163481
|
}
|
|
163292
163482
|
}
|
|
163293
163483
|
const turnCategory = routingOutcome?.category;
|
|
@@ -165563,20 +165753,8 @@ ${rows.length > 0 ? rows.join(`
|
|
|
165563
165753
|
`;
|
|
165564
165754
|
}
|
|
165565
165755
|
function formatUsage(usage) {
|
|
165566
|
-
|
|
165567
|
-
|
|
165568
|
-
}
|
|
165569
|
-
const parts = [];
|
|
165570
|
-
if (usage.inputTokens !== undefined) {
|
|
165571
|
-
parts.push(`\u2191${usage.inputTokens}`);
|
|
165572
|
-
}
|
|
165573
|
-
if (usage.outputTokens !== undefined) {
|
|
165574
|
-
parts.push(`\u2193${usage.outputTokens}`);
|
|
165575
|
-
}
|
|
165576
|
-
if (parts.length === 0) {
|
|
165577
|
-
return "";
|
|
165578
|
-
}
|
|
165579
|
-
return style.dim(`${parts.join(" ")} tokens`);
|
|
165756
|
+
const line = usage === undefined ? undefined : formatUsageLine(usage);
|
|
165757
|
+
return line === undefined ? "" : style.dim(line);
|
|
165580
165758
|
}
|
|
165581
165759
|
async function runAgentRepl(lines, rich, deps, metaprojectPort, sessionOpts, initialPermissionMode, slateSessionBox = { current: undefined }, events, configDir, orient) {
|
|
165582
165760
|
const out = rich.write ?? ((s) => {
|
|
@@ -166413,6 +166591,8 @@ ${GUTTER}${turnSeparator()}
|
|
|
166413
166591
|
`);
|
|
166414
166592
|
}
|
|
166415
166593
|
}
|
|
166594
|
+
} else if (command === "/tasks") {
|
|
166595
|
+
agentIo.onSystem?.(await runTasksCommand(rest, deps.jobRegistry));
|
|
166416
166596
|
} else if (command === "/demote") {
|
|
166417
166597
|
const parsed = parseDemoteCommand(rest);
|
|
166418
166598
|
if (!parsed.ok) {
|
|
@@ -185161,10 +185341,10 @@ function codeOf(text) {
|
|
|
185161
185341
|
return stripTrailingComment2(text).trimEnd();
|
|
185162
185342
|
}
|
|
185163
185343
|
function numericSkeleton(text) {
|
|
185164
|
-
return text.replace(
|
|
185344
|
+
return text.replace(NUMBER3, "\x00");
|
|
185165
185345
|
}
|
|
185166
185346
|
function numbersOf(text) {
|
|
185167
|
-
return [...text.matchAll(
|
|
185347
|
+
return [...text.matchAll(NUMBER3)].map((match) => ({ value: Number(match[0]), index: match.index ?? 0 }));
|
|
185168
185348
|
}
|
|
185169
185349
|
function enclosingNames(code, index) {
|
|
185170
185350
|
const names = [];
|
|
@@ -185427,7 +185607,7 @@ function renderFloorMarkdown(report) {
|
|
|
185427
185607
|
return lines.join(`
|
|
185428
185608
|
`);
|
|
185429
185609
|
}
|
|
185430
|
-
var FLOOR_FINDING_KINDS, COMMENT_OPENER, FLOOR_WORDS, CEILING_WORDS, CAPACITY_WORDS,
|
|
185610
|
+
var FLOOR_FINDING_KINDS, COMMENT_OPENER, FLOOR_WORDS, CEILING_WORDS, CAPACITY_WORDS, NUMBER3, KEY_SEPARATORS, TRAILING_IDENTIFIER, TRAILING_INDEX, OPENS_CONTAINER, TYPE_KEYWORDS, COMMENTED_LINE, MODIFIER_SEGMENT, DISABLED_CALL, DISABLED_ANNOTATION, OTHER_TEST_PATHS, ASSERTION_HEAD, SUPPRESSION_MARKERS, ANNOTATION_MARKERS;
|
|
185431
185611
|
var init_floor = __esm(() => {
|
|
185432
185612
|
init_selection();
|
|
185433
185613
|
FLOOR_FINDING_KINDS = [
|
|
@@ -185517,7 +185697,7 @@ var init_floor = __esm(() => {
|
|
|
185517
185697
|
"parallel",
|
|
185518
185698
|
"batch"
|
|
185519
185699
|
]);
|
|
185520
|
-
|
|
185700
|
+
NUMBER3 = /[0-9]+(?:\.[0-9]+)?/g;
|
|
185521
185701
|
KEY_SEPARATORS = /[\s:=(["'`{<]*$/;
|
|
185522
185702
|
TRAILING_IDENTIFIER = /[A-Za-z0-9_$.-]+$/;
|
|
185523
185703
|
TRAILING_INDEX = /\[\s*[0-9]*\s*\]$/;
|