@aitne/daemon 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/whatsapp-adapter.d.ts.map +1 -1
- package/dist/adapters/whatsapp-adapter.js +0 -1
- package/dist/adapters/whatsapp-adapter.js.map +1 -1
- package/dist/api/integration-route-gate.d.ts +15 -11
- package/dist/api/integration-route-gate.d.ts.map +1 -1
- package/dist/api/integration-route-gate.js +60 -23
- package/dist/api/integration-route-gate.js.map +1 -1
- package/dist/api/json-body.d.ts +22 -7
- package/dist/api/json-body.d.ts.map +1 -1
- package/dist/api/json-body.js +27 -8
- package/dist/api/json-body.js.map +1 -1
- package/dist/api/routes/agent.d.ts.map +1 -1
- package/dist/api/routes/agent.js +18 -0
- package/dist/api/routes/agent.js.map +1 -1
- package/dist/api/routes/backends.d.ts.map +1 -1
- package/dist/api/routes/backends.js +96 -1
- package/dist/api/routes/backends.js.map +1 -1
- package/dist/api/routes/books.js +1 -1
- package/dist/api/routes/books.js.map +1 -1
- package/dist/api/routes/context.d.ts.map +1 -1
- package/dist/api/routes/context.js +13 -1
- package/dist/api/routes/context.js.map +1 -1
- package/dist/api/routes/dashboard.d.ts.map +1 -1
- package/dist/api/routes/dashboard.js +75 -5
- package/dist/api/routes/dashboard.js.map +1 -1
- package/dist/api/routes/github.d.ts.map +1 -1
- package/dist/api/routes/github.js +38 -5
- package/dist/api/routes/github.js.map +1 -1
- package/dist/api/routes/integrations.d.ts +35 -6
- package/dist/api/routes/integrations.d.ts.map +1 -1
- package/dist/api/routes/integrations.js +191 -16
- package/dist/api/routes/integrations.js.map +1 -1
- package/dist/api/routes/mail.d.ts.map +1 -1
- package/dist/api/routes/mail.js +112 -46
- package/dist/api/routes/mail.js.map +1 -1
- package/dist/api/routes/observations.d.ts.map +1 -1
- package/dist/api/routes/observations.js +161 -8
- package/dist/api/routes/observations.js.map +1 -1
- package/dist/api/routes/setup-migrate.d.ts +9 -1
- package/dist/api/routes/setup-migrate.d.ts.map +1 -1
- package/dist/api/routes/setup-migrate.js +4 -2
- package/dist/api/routes/setup-migrate.js.map +1 -1
- package/dist/api/routes/skills.d.ts.map +1 -1
- package/dist/api/routes/skills.js +39 -1
- package/dist/api/routes/skills.js.map +1 -1
- package/dist/api/routes/voice.d.ts.map +1 -1
- package/dist/api/routes/voice.js +62 -4
- package/dist/api/routes/voice.js.map +1 -1
- package/dist/bootstrap/adapters.d.ts +109 -0
- package/dist/bootstrap/adapters.d.ts.map +1 -0
- package/dist/bootstrap/adapters.js +237 -0
- package/dist/bootstrap/adapters.js.map +1 -0
- package/dist/bootstrap/catchup.d.ts +23 -0
- package/dist/bootstrap/catchup.d.ts.map +1 -0
- package/dist/bootstrap/catchup.js +124 -0
- package/dist/bootstrap/catchup.js.map +1 -0
- package/dist/bootstrap/schedule-helpers.d.ts +18 -0
- package/dist/bootstrap/schedule-helpers.d.ts.map +1 -0
- package/dist/bootstrap/schedule-helpers.js +96 -0
- package/dist/bootstrap/schedule-helpers.js.map +1 -0
- package/dist/bootstrap/services.d.ts +60 -0
- package/dist/bootstrap/services.d.ts.map +1 -0
- package/dist/bootstrap/services.js +209 -0
- package/dist/bootstrap/services.js.map +1 -0
- package/dist/core/backends/backend-router.d.ts +23 -0
- package/dist/core/backends/backend-router.d.ts.map +1 -1
- package/dist/core/backends/backend-router.js +48 -3
- package/dist/core/backends/backend-router.js.map +1 -1
- package/dist/core/backends/claude-auth.d.ts +70 -0
- package/dist/core/backends/claude-auth.d.ts.map +1 -0
- package/dist/core/backends/claude-auth.js +198 -0
- package/dist/core/backends/claude-auth.js.map +1 -0
- package/dist/core/backends/claude-code-core.d.ts +47 -119
- package/dist/core/backends/claude-code-core.d.ts.map +1 -1
- package/dist/core/backends/claude-code-core.js +112 -1565
- package/dist/core/backends/claude-code-core.js.map +1 -1
- package/dist/core/backends/claude-delegated.d.ts +86 -0
- package/dist/core/backends/claude-delegated.d.ts.map +1 -0
- package/dist/core/backends/claude-delegated.js +801 -0
- package/dist/core/backends/claude-delegated.js.map +1 -0
- package/dist/core/backends/claude-errors.d.ts +39 -0
- package/dist/core/backends/claude-errors.d.ts.map +1 -0
- package/dist/core/backends/claude-errors.js +71 -0
- package/dist/core/backends/claude-errors.js.map +1 -0
- package/dist/core/backends/claude-probe.d.ts +103 -0
- package/dist/core/backends/claude-probe.d.ts.map +1 -0
- package/dist/core/backends/claude-probe.js +336 -0
- package/dist/core/backends/claude-probe.js.map +1 -0
- package/dist/core/backends/claude-tool-collection.d.ts +135 -0
- package/dist/core/backends/claude-tool-collection.d.ts.map +1 -0
- package/dist/core/backends/claude-tool-collection.js +831 -0
- package/dist/core/backends/claude-tool-collection.js.map +1 -0
- package/dist/core/backends/gemini-cli-core.d.ts +21 -0
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
- package/dist/core/backends/gemini-cli-core.js +84 -6
- package/dist/core/backends/gemini-cli-core.js.map +1 -1
- package/dist/core/backends/prompt-utils.d.ts +1 -0
- package/dist/core/backends/prompt-utils.d.ts.map +1 -1
- package/dist/core/backends/prompt-utils.js +60 -3
- package/dist/core/backends/prompt-utils.js.map +1 -1
- package/dist/core/context-builder.d.ts +36 -12
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +179 -89
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/dispatcher-date-utils.d.ts +49 -0
- package/dist/core/dispatcher-date-utils.d.ts.map +1 -0
- package/dist/core/dispatcher-date-utils.js +132 -0
- package/dist/core/dispatcher-date-utils.js.map +1 -0
- package/dist/core/dispatcher-error-handling.d.ts +159 -0
- package/dist/core/dispatcher-error-handling.d.ts.map +1 -0
- package/dist/core/dispatcher-error-handling.js +393 -0
- package/dist/core/dispatcher-error-handling.js.map +1 -0
- package/dist/core/dispatcher-hourly-check.d.ts +150 -0
- package/dist/core/dispatcher-hourly-check.d.ts.map +1 -0
- package/dist/core/dispatcher-hourly-check.js +665 -0
- package/dist/core/dispatcher-hourly-check.js.map +1 -0
- package/dist/core/dispatcher-message-handler.d.ts +170 -0
- package/dist/core/dispatcher-message-handler.d.ts.map +1 -0
- package/dist/core/dispatcher-message-handler.js +1054 -0
- package/dist/core/dispatcher-message-handler.js.map +1 -0
- package/dist/core/dispatcher-morning-routine.d.ts +169 -0
- package/dist/core/dispatcher-morning-routine.d.ts.map +1 -0
- package/dist/core/dispatcher-morning-routine.js +434 -0
- package/dist/core/dispatcher-morning-routine.js.map +1 -0
- package/dist/core/dispatcher-prompt.d.ts +107 -0
- package/dist/core/dispatcher-prompt.d.ts.map +1 -0
- package/dist/core/dispatcher-prompt.js +227 -0
- package/dist/core/dispatcher-prompt.js.map +1 -0
- package/dist/core/dispatcher-repository-helpers.d.ts +39 -0
- package/dist/core/dispatcher-repository-helpers.d.ts.map +1 -0
- package/dist/core/dispatcher-repository-helpers.js +86 -0
- package/dist/core/dispatcher-repository-helpers.js.map +1 -0
- package/dist/core/dispatcher-result-processor.d.ts +145 -0
- package/dist/core/dispatcher-result-processor.d.ts.map +1 -0
- package/dist/core/dispatcher-result-processor.js +414 -0
- package/dist/core/dispatcher-result-processor.js.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts +406 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.js +998 -0
- package/dist/core/dispatcher-scheduled-tasks.js.map +1 -0
- package/dist/core/dispatcher-types.d.ts +296 -0
- package/dist/core/dispatcher-types.d.ts.map +1 -0
- package/dist/core/dispatcher-types.js +106 -0
- package/dist/core/dispatcher-types.js.map +1 -0
- package/dist/core/dispatcher.d.ts +86 -610
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/dispatcher.js +293 -3542
- package/dist/core/dispatcher.js.map +1 -1
- package/dist/core/integration-health.d.ts +18 -10
- package/dist/core/integration-health.d.ts.map +1 -1
- package/dist/core/integration-health.js +31 -1
- package/dist/core/integration-health.js.map +1 -1
- package/dist/core/integration-lifecycle.d.ts +65 -0
- package/dist/core/integration-lifecycle.d.ts.map +1 -1
- package/dist/core/integration-lifecycle.js +167 -16
- package/dist/core/integration-lifecycle.js.map +1 -1
- package/dist/core/integration-main-backend.d.ts +40 -0
- package/dist/core/integration-main-backend.d.ts.map +1 -1
- package/dist/core/integration-main-backend.js +89 -2
- package/dist/core/integration-main-backend.js.map +1 -1
- package/dist/core/management-md.d.ts +51 -17
- package/dist/core/management-md.d.ts.map +1 -1
- package/dist/core/management-md.js +233 -56
- package/dist/core/management-md.js.map +1 -1
- package/dist/core/output-language-policy.d.ts +74 -0
- package/dist/core/output-language-policy.d.ts.map +1 -0
- package/dist/core/output-language-policy.js +194 -0
- package/dist/core/output-language-policy.js.map +1 -0
- package/dist/core/prompts.d.ts +1 -0
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/prompts.js +121 -3
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/repository-management-docs.d.ts +24 -0
- package/dist/core/repository-management-docs.d.ts.map +1 -1
- package/dist/core/repository-management-docs.js +210 -26
- package/dist/core/repository-management-docs.js.map +1 -1
- package/dist/core/routine-acquisition-plan.d.ts +131 -0
- package/dist/core/routine-acquisition-plan.d.ts.map +1 -0
- package/dist/core/routine-acquisition-plan.js +268 -0
- package/dist/core/routine-acquisition-plan.js.map +1 -0
- package/dist/core/routine-fetch-window-runner.d.ts +201 -0
- package/dist/core/routine-fetch-window-runner.d.ts.map +1 -0
- package/dist/core/routine-fetch-window-runner.js +661 -0
- package/dist/core/routine-fetch-window-runner.js.map +1 -0
- package/dist/core/routine-windows.d.ts +156 -0
- package/dist/core/routine-windows.d.ts.map +1 -0
- package/dist/core/routine-windows.js +330 -0
- package/dist/core/routine-windows.js.map +1 -0
- package/dist/core/skills-compiler.d.ts +11 -0
- package/dist/core/skills-compiler.d.ts.map +1 -1
- package/dist/core/skills-compiler.js +102 -13
- package/dist/core/skills-compiler.js.map +1 -1
- package/dist/core/skills-manifest.d.ts.map +1 -1
- package/dist/core/skills-manifest.js +26 -0
- package/dist/core/skills-manifest.js.map +1 -1
- package/dist/core/system-reset.d.ts.map +1 -1
- package/dist/core/system-reset.js +25 -2
- package/dist/core/system-reset.js.map +1 -1
- package/dist/db/observations.d.ts +45 -2
- package/dist/db/observations.d.ts.map +1 -1
- package/dist/db/observations.js +112 -14
- package/dist/db/observations.js.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +13 -25
- package/dist/db/schema.js.map +1 -1
- package/dist/index.js +83 -610
- package/dist/index.js.map +1 -1
- package/dist/observers/delegated-sync-worker.d.ts +45 -2
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
- package/dist/observers/delegated-sync-worker.js +71 -21
- package/dist/observers/delegated-sync-worker.js.map +1 -1
- package/dist/observers/mail-poller.d.ts +12 -5
- package/dist/observers/mail-poller.d.ts.map +1 -1
- package/dist/observers/mail-poller.js +36 -14
- package/dist/observers/mail-poller.js.map +1 -1
- package/dist/observers/manager.d.ts +37 -5
- package/dist/observers/manager.d.ts.map +1 -1
- package/dist/observers/manager.js +28 -10
- package/dist/observers/manager.js.map +1 -1
- package/dist/services/delegated-backend-invoker.d.ts +1 -51
- package/dist/services/delegated-backend-invoker.d.ts.map +1 -1
- package/dist/services/delegated-backend-invoker.js +41 -480
- package/dist/services/delegated-backend-invoker.js.map +1 -1
- package/dist/services/delegated-invoker-audit.d.ts +94 -0
- package/dist/services/delegated-invoker-audit.d.ts.map +1 -0
- package/dist/services/delegated-invoker-audit.js +238 -0
- package/dist/services/delegated-invoker-audit.js.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts +34 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.js +104 -0
- package/dist/services/delegated-invoker-cache-hits.js.map +1 -0
- package/dist/services/delegated-invoker-janitors.d.ts +28 -0
- package/dist/services/delegated-invoker-janitors.d.ts.map +1 -0
- package/dist/services/delegated-invoker-janitors.js +104 -0
- package/dist/services/delegated-invoker-janitors.js.map +1 -0
- package/dist/services/delegated-invoker-utils.d.ts +42 -0
- package/dist/services/delegated-invoker-utils.d.ts.map +1 -0
- package/dist/services/delegated-invoker-utils.js +100 -0
- package/dist/services/delegated-invoker-utils.js.map +1 -0
- package/dist/services/delegated-task-runtime.d.ts +1 -1
- package/dist/services/delegated-task-runtime.js +1 -1
- package/dist/services/integrations/snapshot-partitions.d.ts +5 -0
- package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -1
- package/dist/services/integrations/snapshot-partitions.js +12 -0
- package/dist/services/integrations/snapshot-partitions.js.map +1 -1
- package/dist/services/voice/transcriber-impl.d.ts.map +1 -1
- package/dist/services/voice/transcriber-impl.js +7 -8
- package/dist/services/voice/transcriber-impl.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { filterDeniedToolsForBackend, getAgentDayDateStr, } from "@aitne/shared";
|
|
5
5
|
import { createLogger } from "../logging.js";
|
|
@@ -11,6 +11,9 @@ import { buildRetryFollowup, buildTaskPrompt, classifyStructuredOutput, compileS
|
|
|
11
11
|
import { DelegatedTaskResultCache, execScope, integrationVersionFor, runScope, } from "./delegated-task-result-cache.js";
|
|
12
12
|
import { DelegatedTaskSessionPool, SESSION_POOL_TEMPDIR_PREFIX, } from "./delegated-task-session-pool.js";
|
|
13
13
|
import { readRuntimeState, writeRuntimeState, } from "../db/runtime-state.js";
|
|
14
|
+
import { LegacyOneShotLease, mergeCost, readFileSyncIfExists, stripCodeFences, zeroCost, } from "./delegated-invoker-utils.js";
|
|
15
|
+
import { completeTaskHeader, recordAction, recordTaskHeaderInProgress, recordTaskToolStep, } from "./delegated-invoker-audit.js";
|
|
16
|
+
import { buildCacheHitRunResult, buildCacheHitTaskResult, } from "./delegated-invoker-cache-hits.js";
|
|
14
17
|
const logger = createLogger("delegated-proxy-invoker");
|
|
15
18
|
export class DelegatedBackendInvoker {
|
|
16
19
|
deps;
|
|
@@ -174,7 +177,7 @@ export class DelegatedBackendInvoker {
|
|
|
174
177
|
// Queue saturation — surfaces as 503 in the route handler. Don't
|
|
175
178
|
// create a tempdir, don't materialize anything. Cost row is still
|
|
176
179
|
// written (zero-cost) so the dashboard sees a saturation event.
|
|
177
|
-
this.
|
|
180
|
+
recordAction(this.deps.db, {
|
|
178
181
|
backendId: fastCheck.backendId,
|
|
179
182
|
modelId: fastCheck.modelId,
|
|
180
183
|
params,
|
|
@@ -205,7 +208,7 @@ export class DelegatedBackendInvoker {
|
|
|
205
208
|
this.releasePermit();
|
|
206
209
|
const nowIso = new Date(this.now()).toISOString();
|
|
207
210
|
const message = `integration state changed during queue wait: ${liveCheck.message}`;
|
|
208
|
-
this.
|
|
211
|
+
recordAction(this.deps.db, {
|
|
209
212
|
backendId: liveCheck.backendId ?? fastCheck.backendId,
|
|
210
213
|
modelId: fastCheck.modelId,
|
|
211
214
|
params,
|
|
@@ -294,7 +297,7 @@ export class DelegatedBackendInvoker {
|
|
|
294
297
|
}
|
|
295
298
|
const completedAtIso = new Date(this.now()).toISOString();
|
|
296
299
|
if (unimplemented) {
|
|
297
|
-
this.
|
|
300
|
+
recordAction(this.deps.db, {
|
|
298
301
|
backendId,
|
|
299
302
|
modelId,
|
|
300
303
|
params,
|
|
@@ -314,7 +317,7 @@ export class DelegatedBackendInvoker {
|
|
|
314
317
|
};
|
|
315
318
|
}
|
|
316
319
|
if (unhandledMessage !== null) {
|
|
317
|
-
this.
|
|
320
|
+
recordAction(this.deps.db, {
|
|
318
321
|
backendId,
|
|
319
322
|
modelId,
|
|
320
323
|
params,
|
|
@@ -336,7 +339,7 @@ export class DelegatedBackendInvoker {
|
|
|
336
339
|
if (!toolResult) {
|
|
337
340
|
// Defensive: should not happen unless runDelegatedTool resolved with
|
|
338
341
|
// null/undefined, which violates the contract.
|
|
339
|
-
this.
|
|
342
|
+
recordAction(this.deps.db, {
|
|
340
343
|
backendId,
|
|
341
344
|
modelId,
|
|
342
345
|
params,
|
|
@@ -356,7 +359,7 @@ export class DelegatedBackendInvoker {
|
|
|
356
359
|
};
|
|
357
360
|
}
|
|
358
361
|
if (toolResult.ok) {
|
|
359
|
-
this.
|
|
362
|
+
recordAction(this.deps.db, {
|
|
360
363
|
backendId,
|
|
361
364
|
modelId,
|
|
362
365
|
params,
|
|
@@ -373,7 +376,7 @@ export class DelegatedBackendInvoker {
|
|
|
373
376
|
modelId,
|
|
374
377
|
};
|
|
375
378
|
}
|
|
376
|
-
this.
|
|
379
|
+
recordAction(this.deps.db, {
|
|
377
380
|
backendId,
|
|
378
381
|
modelId,
|
|
379
382
|
params,
|
|
@@ -403,10 +406,17 @@ export class DelegatedBackendInvoker {
|
|
|
403
406
|
*/
|
|
404
407
|
resolvePreconditions(integrationKey, modelOverride) {
|
|
405
408
|
const state = readIntegrations(this.deps.db)[integrationKey];
|
|
409
|
+
// INTEGRATION_NATIVE_MODE_DESIGN.md §17 (Phase B1 file list) — the
|
|
410
|
+
// invoker must defensively reject every non-delegated mode, including
|
|
411
|
+
// the new `native` mode. A flip from delegated to native during a
|
|
412
|
+
// queued task would otherwise resolve through this path with stale
|
|
413
|
+
// state; failing here forces the caller to re-route through the
|
|
414
|
+
// native MCP surface (§3.3 invariant: native MUST NOT call the
|
|
415
|
+
// daemon proxy).
|
|
406
416
|
if (!state || state.mode !== "delegated" || !state.delegatedBackend) {
|
|
407
417
|
return {
|
|
408
418
|
ok: false,
|
|
409
|
-
message: `integration '${integrationKey}' is not in delegated mode (mode=${state?.mode ?? "missing"}, delegatedBackend=${state?.delegatedBackend ?? "null"})`,
|
|
419
|
+
message: `integration '${integrationKey}' is not in delegated mode (mode=${state?.mode ?? "missing"}, delegatedBackend=${state?.delegatedBackend ?? "null"}, nativeBackend=${state?.nativeBackend ?? "null"})`,
|
|
410
420
|
};
|
|
411
421
|
}
|
|
412
422
|
const backendId = state.delegatedBackend;
|
|
@@ -518,57 +528,13 @@ export class DelegatedBackendInvoker {
|
|
|
518
528
|
mkdirSync(dirname(target), { recursive: true });
|
|
519
529
|
writeFileSync(target, body, "utf-8");
|
|
520
530
|
}
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
};
|
|
529
|
-
try {
|
|
530
|
-
this.deps.db
|
|
531
|
-
.prepare(
|
|
532
|
-
// datetime(@started_at) coerces ISO-8601 input into SQLite's
|
|
533
|
-
// canonical 'YYYY-MM-DD HH:MM:SS' so this row sorts correctly
|
|
534
|
-
// alongside rows written via datetime('now') elsewhere — without
|
|
535
|
-
// it, mixed formats break ORDER BY started_at.
|
|
536
|
-
`INSERT INTO agent_actions (
|
|
537
|
-
event_id, action_type, trigger, model_used,
|
|
538
|
-
cost_usd, tokens_input, tokens_output,
|
|
539
|
-
cache_creation_tokens, cache_read_tokens,
|
|
540
|
-
duration_ms, num_turns, result, detail,
|
|
541
|
-
started_at, completed_at, error, backend, cost_source
|
|
542
|
-
) VALUES (
|
|
543
|
-
@event_id, 'delegated_proxy.invoke', @trigger, @model_used,
|
|
544
|
-
@cost_usd, @tokens_input, @tokens_output,
|
|
545
|
-
@cache_creation_tokens, @cache_read_tokens,
|
|
546
|
-
@duration_ms, @num_turns, @result, @detail,
|
|
547
|
-
datetime(@started_at), datetime(@completed_at), @error, @backend, 'sdk'
|
|
548
|
-
)`)
|
|
549
|
-
.run({
|
|
550
|
-
event_id: args.params.parentEventId ?? null,
|
|
551
|
-
trigger: args.params.parentProcessKey ?? null,
|
|
552
|
-
model_used: args.modelId,
|
|
553
|
-
cost_usd: args.cost.costUsd,
|
|
554
|
-
tokens_input: args.cost.tokensInput,
|
|
555
|
-
tokens_output: args.cost.tokensOutput,
|
|
556
|
-
cache_creation_tokens: args.cost.cacheCreationTokens,
|
|
557
|
-
cache_read_tokens: args.cost.cacheReadTokens,
|
|
558
|
-
duration_ms: args.cost.durationMs,
|
|
559
|
-
num_turns: args.cost.numTurns,
|
|
560
|
-
result: args.result,
|
|
561
|
-
detail: JSON.stringify(detail),
|
|
562
|
-
started_at: args.startedAt,
|
|
563
|
-
completed_at: args.completedAt,
|
|
564
|
-
error: args.errorMessage ?? null,
|
|
565
|
-
backend: args.backendId,
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
catch (err) {
|
|
569
|
-
logger.error({ err, integrationKey: args.params.integrationKey }, "failed to record delegated_proxy.invoke action");
|
|
570
|
-
}
|
|
571
|
-
}
|
|
531
|
+
// The five `agent_actions` row-writers (recordAction,
|
|
532
|
+
// recordCacheHitAuditRow, recordTaskHeaderInProgress, completeTaskHeader,
|
|
533
|
+
// recordTaskToolStep) live in `delegated-invoker-audit.ts`; the two
|
|
534
|
+
// cache-hit result builders (buildCacheHitTaskResult /
|
|
535
|
+
// buildCacheHitRunResult) live in `delegated-invoker-cache-hits.ts`.
|
|
536
|
+
// Call sites pass `this.deps.db` and `this.now` explicitly — see
|
|
537
|
+
// file-split-plan.md §9.
|
|
572
538
|
// ── Model resolution ────────────────────────────────────────────────────
|
|
573
539
|
resolveModel(state, integrationKey, backendId, modelOverride) {
|
|
574
540
|
// Caller-side override (cadence path passes medium tier — see
|
|
@@ -701,11 +667,12 @@ export class DelegatedBackendInvoker {
|
|
|
701
667
|
};
|
|
702
668
|
const hit = cache.get(cacheKey);
|
|
703
669
|
if (hit) {
|
|
704
|
-
return this.
|
|
670
|
+
return buildCacheHitTaskResult(this.deps.db, {
|
|
705
671
|
params,
|
|
706
672
|
hit,
|
|
707
673
|
backendId: fastCheck.backendId,
|
|
708
674
|
modelId: fastCheck.modelId,
|
|
675
|
+
now: this.now,
|
|
709
676
|
});
|
|
710
677
|
}
|
|
711
678
|
}
|
|
@@ -823,7 +790,7 @@ export class DelegatedBackendInvoker {
|
|
|
823
790
|
const taskHash = hashTaskArgs(params.task);
|
|
824
791
|
const schemaHash = hashTaskArgs(params.outputSchema);
|
|
825
792
|
// §11.1 — write header row BEFORE spawn so step rows can FK to its id.
|
|
826
|
-
const headerId = this.
|
|
793
|
+
const headerId = recordTaskHeaderInProgress(this.deps.db, {
|
|
827
794
|
actionType: "delegated_task.exec",
|
|
828
795
|
backendId,
|
|
829
796
|
modelId,
|
|
@@ -913,7 +880,7 @@ export class DelegatedBackendInvoker {
|
|
|
913
880
|
structuredOutputEnabled,
|
|
914
881
|
...(wrappedSchema ? { wrappedSchema } : {}),
|
|
915
882
|
onToolStep: (step) => {
|
|
916
|
-
this.
|
|
883
|
+
recordTaskToolStep(this.deps.db, {
|
|
917
884
|
parentTaskActionId: headerId,
|
|
918
885
|
backendId,
|
|
919
886
|
modelId,
|
|
@@ -1224,7 +1191,7 @@ export class DelegatedBackendInvoker {
|
|
|
1224
1191
|
}
|
|
1225
1192
|
}
|
|
1226
1193
|
// §11.1 — finalise the header row.
|
|
1227
|
-
this.
|
|
1194
|
+
completeTaskHeader(this.deps.db, {
|
|
1228
1195
|
headerId,
|
|
1229
1196
|
result: outcome?.ok ? "success" : "failed",
|
|
1230
1197
|
cost: aggregatedCost,
|
|
@@ -1282,56 +1249,6 @@ export class DelegatedBackendInvoker {
|
|
|
1282
1249
|
}
|
|
1283
1250
|
return outcome;
|
|
1284
1251
|
}
|
|
1285
|
-
/**
|
|
1286
|
-
* §13 Phase 3.3 — synthesize a `TaskInvokeResult` from a cache hit and
|
|
1287
|
-
* write the corresponding `delegated_task.exec` audit row with cost 0
|
|
1288
|
-
* and `detail.cacheHit=true`. Cache hits do not consume the per-day
|
|
1289
|
-
* quota (the quota counts subprocess invocations) and do not acquire a
|
|
1290
|
-
* concurrency permit (looked up before `acquirePermit`).
|
|
1291
|
-
*/
|
|
1292
|
-
buildCacheHitTaskResult(args) {
|
|
1293
|
-
const nowIso = new Date(this.now()).toISOString();
|
|
1294
|
-
const taskHash = hashTaskArgs(args.params.task);
|
|
1295
|
-
const schemaHash = hashTaskArgs(args.params.outputSchema);
|
|
1296
|
-
this.recordCacheHitAuditRow({
|
|
1297
|
-
actionType: "delegated_task.exec",
|
|
1298
|
-
backendId: args.backendId,
|
|
1299
|
-
modelId: args.modelId,
|
|
1300
|
-
...(args.params.parentEventId !== undefined
|
|
1301
|
-
? { parentEventId: args.params.parentEventId }
|
|
1302
|
-
: {}),
|
|
1303
|
-
...(args.params.parentProcessKey !== undefined
|
|
1304
|
-
? { parentProcessKey: args.params.parentProcessKey }
|
|
1305
|
-
: {}),
|
|
1306
|
-
timestamp: nowIso,
|
|
1307
|
-
toolCallCount: args.hit.trace.length,
|
|
1308
|
-
detail: {
|
|
1309
|
-
integrationKey: args.params.integrationKey,
|
|
1310
|
-
delegatedBackend: args.backendId,
|
|
1311
|
-
taskHash,
|
|
1312
|
-
schemaHash,
|
|
1313
|
-
cacheHit: true,
|
|
1314
|
-
toolCallCount: args.hit.trace.length,
|
|
1315
|
-
retried: false,
|
|
1316
|
-
// §11.2 — cache hits are gated on the original outcome being
|
|
1317
|
-
// non-confirmation (see Phase 3.3 cache guard); record this
|
|
1318
|
-
// explicitly so the metric aggregator's schema stays uniform
|
|
1319
|
-
// across live + cache-hit rows.
|
|
1320
|
-
needsConfirmation: false,
|
|
1321
|
-
},
|
|
1322
|
-
});
|
|
1323
|
-
return {
|
|
1324
|
-
ok: true,
|
|
1325
|
-
result: args.hit.result,
|
|
1326
|
-
needsConfirmation: false,
|
|
1327
|
-
confirmationPlan: null,
|
|
1328
|
-
cost: zeroCost(),
|
|
1329
|
-
trace: args.hit.trace,
|
|
1330
|
-
backendId: args.backendId,
|
|
1331
|
-
modelId: args.modelId,
|
|
1332
|
-
retried: false,
|
|
1333
|
-
};
|
|
1334
|
-
}
|
|
1335
1252
|
/**
|
|
1336
1253
|
* DELEGATED-TASK-MODE-DESIGN.md §4.2 — Phase 2 generic task mode.
|
|
1337
1254
|
* Mirror of `task()` but with no `integrationKey`: the caller pins
|
|
@@ -1422,11 +1339,12 @@ export class DelegatedBackendInvoker {
|
|
|
1422
1339
|
};
|
|
1423
1340
|
const hit = cache.get(cacheKey);
|
|
1424
1341
|
if (hit) {
|
|
1425
|
-
return this.
|
|
1342
|
+
return buildCacheHitRunResult(this.deps.db, {
|
|
1426
1343
|
params,
|
|
1427
1344
|
hit,
|
|
1428
1345
|
backendId,
|
|
1429
1346
|
modelId: runModelId,
|
|
1347
|
+
now: this.now,
|
|
1430
1348
|
});
|
|
1431
1349
|
}
|
|
1432
1350
|
}
|
|
@@ -1517,7 +1435,7 @@ export class DelegatedBackendInvoker {
|
|
|
1517
1435
|
const schemaHash = hashTaskArgs(params.outputSchema);
|
|
1518
1436
|
const allowedToolsHash = hashTaskArgs(allowedTools);
|
|
1519
1437
|
// §11.1 — header row BEFORE spawn so step rows can FK to it.
|
|
1520
|
-
const headerId = this.
|
|
1438
|
+
const headerId = recordTaskHeaderInProgress(this.deps.db, {
|
|
1521
1439
|
actionType: "delegated_task.run",
|
|
1522
1440
|
backendId,
|
|
1523
1441
|
modelId,
|
|
@@ -1594,7 +1512,7 @@ export class DelegatedBackendInvoker {
|
|
|
1594
1512
|
structuredOutputEnabled,
|
|
1595
1513
|
...(wrappedSchema ? { wrappedSchema } : {}),
|
|
1596
1514
|
onToolStep: (step) => {
|
|
1597
|
-
this.
|
|
1515
|
+
recordTaskToolStep(this.deps.db, {
|
|
1598
1516
|
parentTaskActionId: headerId,
|
|
1599
1517
|
backendId,
|
|
1600
1518
|
modelId,
|
|
@@ -1873,7 +1791,7 @@ export class DelegatedBackendInvoker {
|
|
|
1873
1791
|
}
|
|
1874
1792
|
}
|
|
1875
1793
|
// §11.1 — finalise the header row.
|
|
1876
|
-
this.
|
|
1794
|
+
completeTaskHeader(this.deps.db, {
|
|
1877
1795
|
headerId,
|
|
1878
1796
|
result: outcome?.ok ? "success" : "failed",
|
|
1879
1797
|
cost: aggregatedCost,
|
|
@@ -1925,52 +1843,6 @@ export class DelegatedBackendInvoker {
|
|
|
1925
1843
|
}
|
|
1926
1844
|
return outcome;
|
|
1927
1845
|
}
|
|
1928
|
-
/**
|
|
1929
|
-
* §13 Phase 3.3 — cache-hit synthesizer for `/run`. Same shape as
|
|
1930
|
-
* `buildCacheHitTaskResult` but writes a `delegated_task.run` audit row.
|
|
1931
|
-
*/
|
|
1932
|
-
buildCacheHitRunResult(args) {
|
|
1933
|
-
const nowIso = new Date(this.now()).toISOString();
|
|
1934
|
-
const taskHash = hashTaskArgs(args.params.task);
|
|
1935
|
-
const schemaHash = hashTaskArgs(args.params.outputSchema);
|
|
1936
|
-
const allowedToolsHash = hashTaskArgs(args.params.allowedTools);
|
|
1937
|
-
this.recordCacheHitAuditRow({
|
|
1938
|
-
actionType: "delegated_task.run",
|
|
1939
|
-
backendId: args.backendId,
|
|
1940
|
-
modelId: args.modelId,
|
|
1941
|
-
...(args.params.parentEventId !== undefined
|
|
1942
|
-
? { parentEventId: args.params.parentEventId }
|
|
1943
|
-
: {}),
|
|
1944
|
-
...(args.params.parentProcessKey !== undefined
|
|
1945
|
-
? { parentProcessKey: args.params.parentProcessKey }
|
|
1946
|
-
: {}),
|
|
1947
|
-
timestamp: nowIso,
|
|
1948
|
-
toolCallCount: args.hit.trace.length,
|
|
1949
|
-
detail: {
|
|
1950
|
-
delegatedBackend: args.backendId,
|
|
1951
|
-
taskHash,
|
|
1952
|
-
schemaHash,
|
|
1953
|
-
allowedToolsHash,
|
|
1954
|
-
allowedToolsCount: args.params.allowedTools.length,
|
|
1955
|
-
cacheHit: true,
|
|
1956
|
-
toolCallCount: args.hit.trace.length,
|
|
1957
|
-
retried: false,
|
|
1958
|
-
// §11.2 — see /exec equivalent.
|
|
1959
|
-
needsConfirmation: false,
|
|
1960
|
-
},
|
|
1961
|
-
});
|
|
1962
|
-
return {
|
|
1963
|
-
ok: true,
|
|
1964
|
-
result: args.hit.result,
|
|
1965
|
-
needsConfirmation: false,
|
|
1966
|
-
confirmationPlan: null,
|
|
1967
|
-
cost: zeroCost(),
|
|
1968
|
-
trace: args.hit.trace,
|
|
1969
|
-
backendId: args.backendId,
|
|
1970
|
-
modelId: args.modelId,
|
|
1971
|
-
retried: false,
|
|
1972
|
-
};
|
|
1973
|
-
}
|
|
1974
1846
|
/**
|
|
1975
1847
|
* Resolve the model for a task-mode call.
|
|
1976
1848
|
*
|
|
@@ -2039,181 +1911,6 @@ export class DelegatedBackendInvoker {
|
|
|
2039
1911
|
logger.warn({ err }, "failed to increment delegated task quota counter");
|
|
2040
1912
|
}
|
|
2041
1913
|
}
|
|
2042
|
-
// ── agent_actions header / step persistence ───────────────────────────────
|
|
2043
|
-
/**
|
|
2044
|
-
* §13 Phase 3.3 — single-shot INSERT for cache-hit audit rows. Cache
|
|
2045
|
-
* hits don't go through the in-progress → complete two-step lifecycle
|
|
2046
|
-
* (the outcome is known synchronously), so this writes one row with
|
|
2047
|
-
* `result='success'`, `cost_usd=0`, `cost_source='cache'` for clean
|
|
2048
|
-
* dashboard cost-source filtering.
|
|
2049
|
-
*/
|
|
2050
|
-
recordCacheHitAuditRow(args) {
|
|
2051
|
-
try {
|
|
2052
|
-
const result = this.deps.db
|
|
2053
|
-
.prepare(`INSERT INTO agent_actions (
|
|
2054
|
-
event_id, action_type, trigger, model_used,
|
|
2055
|
-
cost_usd, tokens_input, tokens_output,
|
|
2056
|
-
cache_creation_tokens, cache_read_tokens,
|
|
2057
|
-
duration_ms, num_turns, result, detail,
|
|
2058
|
-
started_at, completed_at, error, backend, cost_source
|
|
2059
|
-
) VALUES (
|
|
2060
|
-
@event_id, @action_type, @trigger, @model_used,
|
|
2061
|
-
0, 0, 0, 0, 0,
|
|
2062
|
-
0, @num_turns, 'success', @detail,
|
|
2063
|
-
datetime(@ts), datetime(@ts), NULL, @backend, 'cache'
|
|
2064
|
-
)`)
|
|
2065
|
-
.run({
|
|
2066
|
-
event_id: args.parentEventId ?? null,
|
|
2067
|
-
action_type: args.actionType,
|
|
2068
|
-
trigger: args.parentProcessKey ?? null,
|
|
2069
|
-
model_used: args.modelId,
|
|
2070
|
-
num_turns: args.toolCallCount,
|
|
2071
|
-
detail: JSON.stringify(args.detail),
|
|
2072
|
-
ts: args.timestamp,
|
|
2073
|
-
backend: args.backendId,
|
|
2074
|
-
});
|
|
2075
|
-
return Number(result.lastInsertRowid);
|
|
2076
|
-
}
|
|
2077
|
-
catch (err) {
|
|
2078
|
-
logger.error({ err, actionType: args.actionType, detail: args.detail }, "failed to write delegated_task cache-hit audit row");
|
|
2079
|
-
return -1;
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
recordTaskHeaderInProgress(args) {
|
|
2083
|
-
try {
|
|
2084
|
-
const result = this.deps.db
|
|
2085
|
-
.prepare(`INSERT INTO agent_actions (
|
|
2086
|
-
event_id, action_type, trigger, model_used,
|
|
2087
|
-
cost_usd, tokens_input, tokens_output,
|
|
2088
|
-
cache_creation_tokens, cache_read_tokens,
|
|
2089
|
-
duration_ms, num_turns, result, detail,
|
|
2090
|
-
started_at, completed_at, error, backend, cost_source
|
|
2091
|
-
) VALUES (
|
|
2092
|
-
@event_id, @action_type, @trigger, @model_used,
|
|
2093
|
-
0, 0, 0, 0, 0,
|
|
2094
|
-
0, 0, 'in_progress', @detail,
|
|
2095
|
-
datetime(@started_at), NULL, NULL, @backend, 'sdk'
|
|
2096
|
-
)`)
|
|
2097
|
-
.run({
|
|
2098
|
-
event_id: args.parentEventId ?? null,
|
|
2099
|
-
action_type: args.actionType,
|
|
2100
|
-
trigger: args.parentProcessKey ?? null,
|
|
2101
|
-
model_used: args.modelId,
|
|
2102
|
-
detail: JSON.stringify(args.detail),
|
|
2103
|
-
started_at: args.startedAt,
|
|
2104
|
-
backend: args.backendId,
|
|
2105
|
-
});
|
|
2106
|
-
return Number(result.lastInsertRowid);
|
|
2107
|
-
}
|
|
2108
|
-
catch (err) {
|
|
2109
|
-
logger.error({ err, actionType: args.actionType, detail: args.detail }, "failed to write delegated_task header row");
|
|
2110
|
-
return -1;
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
completeTaskHeader(args) {
|
|
2114
|
-
if (args.headerId < 0)
|
|
2115
|
-
return;
|
|
2116
|
-
try {
|
|
2117
|
-
this.deps.db
|
|
2118
|
-
.prepare(`UPDATE agent_actions SET
|
|
2119
|
-
result = @result,
|
|
2120
|
-
cost_usd = @cost_usd,
|
|
2121
|
-
tokens_input = @tokens_input,
|
|
2122
|
-
tokens_output = @tokens_output,
|
|
2123
|
-
cache_creation_tokens = @cache_creation_tokens,
|
|
2124
|
-
cache_read_tokens = @cache_read_tokens,
|
|
2125
|
-
duration_ms = @duration_ms,
|
|
2126
|
-
num_turns = @num_turns,
|
|
2127
|
-
completed_at = datetime(@completed_at),
|
|
2128
|
-
error = @error,
|
|
2129
|
-
detail = @detail
|
|
2130
|
-
WHERE id = @id`)
|
|
2131
|
-
.run({
|
|
2132
|
-
id: args.headerId,
|
|
2133
|
-
result: args.result,
|
|
2134
|
-
cost_usd: args.cost.costUsd,
|
|
2135
|
-
tokens_input: args.cost.tokensInput,
|
|
2136
|
-
tokens_output: args.cost.tokensOutput,
|
|
2137
|
-
cache_creation_tokens: args.cost.cacheCreationTokens,
|
|
2138
|
-
cache_read_tokens: args.cost.cacheReadTokens,
|
|
2139
|
-
duration_ms: args.cost.durationMs,
|
|
2140
|
-
num_turns: args.cost.numTurns,
|
|
2141
|
-
completed_at: args.completedAt,
|
|
2142
|
-
error: args.errorMessage,
|
|
2143
|
-
detail: JSON.stringify(args.detail),
|
|
2144
|
-
});
|
|
2145
|
-
}
|
|
2146
|
-
catch (err) {
|
|
2147
|
-
logger.error({ err, headerId: args.headerId }, "failed to update delegated_task.exec header row");
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
recordTaskToolStep(args) {
|
|
2151
|
-
try {
|
|
2152
|
-
this.deps.db
|
|
2153
|
-
.prepare(`INSERT INTO agent_actions (
|
|
2154
|
-
action_type, trigger, model_used,
|
|
2155
|
-
cost_usd, tokens_input, tokens_output,
|
|
2156
|
-
cache_creation_tokens, cache_read_tokens,
|
|
2157
|
-
duration_ms, num_turns, result, detail,
|
|
2158
|
-
started_at, completed_at, error, backend, cost_source
|
|
2159
|
-
) VALUES (
|
|
2160
|
-
'delegated_task.tool_step', NULL, @model_used,
|
|
2161
|
-
@cost_usd, @tokens_input, @tokens_output,
|
|
2162
|
-
0, 0,
|
|
2163
|
-
@duration_ms, 1, @result, @detail,
|
|
2164
|
-
datetime('now'), datetime('now'), @error, @backend, 'sdk'
|
|
2165
|
-
)`)
|
|
2166
|
-
.run({
|
|
2167
|
-
model_used: args.modelId,
|
|
2168
|
-
cost_usd: args.step.costUsd,
|
|
2169
|
-
tokens_input: args.step.tokensInput,
|
|
2170
|
-
tokens_output: args.step.tokensOutput,
|
|
2171
|
-
duration_ms: args.step.durationMs,
|
|
2172
|
-
result: args.step.status === "ok" ? "success" : "failed",
|
|
2173
|
-
detail: JSON.stringify({
|
|
2174
|
-
...(args.integrationKey ? { integrationKey: args.integrationKey } : {}),
|
|
2175
|
-
toolName: args.step.toolName,
|
|
2176
|
-
toolArgsHash: hashTaskArgs(args.step.toolArgs),
|
|
2177
|
-
toolStatus: args.step.status,
|
|
2178
|
-
parentTaskActionId: args.parentTaskActionId,
|
|
2179
|
-
}),
|
|
2180
|
-
error: args.step.status === "error" ? "tool_step_error" : null,
|
|
2181
|
-
backend: args.backendId,
|
|
2182
|
-
});
|
|
2183
|
-
}
|
|
2184
|
-
catch (err) {
|
|
2185
|
-
logger.warn({ err, parentTaskActionId: args.parentTaskActionId }, "failed to write delegated_task.tool_step row");
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
/**
|
|
2190
|
-
* §13 Phase 3.2 — synthetic lease used when pooling is disabled. Implements
|
|
2191
|
-
* the same `release()` / `discard()` shape as `SessionPoolLease` so the
|
|
2192
|
-
* task() / run() loop doesn't have to branch on whether pooling is active.
|
|
2193
|
-
* Both methods clean up the tempdir (no TTL semantics — there's no pool
|
|
2194
|
-
* to return to).
|
|
2195
|
-
*/
|
|
2196
|
-
class LegacyOneShotLease {
|
|
2197
|
-
sessionDir;
|
|
2198
|
-
cleanup;
|
|
2199
|
-
fromPool = false;
|
|
2200
|
-
released = false;
|
|
2201
|
-
constructor(sessionDir, cleanup) {
|
|
2202
|
-
this.sessionDir = sessionDir;
|
|
2203
|
-
this.cleanup = cleanup;
|
|
2204
|
-
}
|
|
2205
|
-
release() {
|
|
2206
|
-
if (this.released)
|
|
2207
|
-
return;
|
|
2208
|
-
this.released = true;
|
|
2209
|
-
this.cleanup();
|
|
2210
|
-
}
|
|
2211
|
-
discard() {
|
|
2212
|
-
if (this.released)
|
|
2213
|
-
return;
|
|
2214
|
-
this.released = true;
|
|
2215
|
-
this.cleanup();
|
|
2216
|
-
}
|
|
2217
1914
|
}
|
|
2218
1915
|
const FALLBACK_PROXY_PROFILE = `# Delegated Proxy
|
|
2219
1916
|
|
|
@@ -2223,150 +1920,14 @@ exception: if the named tool's schema is not yet loaded, call ToolSearch
|
|
|
2223
1920
|
to load it, then immediately call the named tool. Do not browse other
|
|
2224
1921
|
tools. If the tool errors, return the error verbatim.
|
|
2225
1922
|
`;
|
|
2226
|
-
function readFileSyncIfExists(path) {
|
|
2227
|
-
if (!existsSync(path))
|
|
2228
|
-
return null;
|
|
2229
|
-
return readFileSync(path, "utf-8");
|
|
2230
|
-
}
|
|
2231
|
-
function hashArgs(args) {
|
|
2232
|
-
try {
|
|
2233
|
-
const serialized = JSON.stringify(args ?? null);
|
|
2234
|
-
return createHash("sha256")
|
|
2235
|
-
.update(serialized)
|
|
2236
|
-
.digest("hex")
|
|
2237
|
-
.slice(0, 16);
|
|
2238
|
-
}
|
|
2239
|
-
catch {
|
|
2240
|
-
return "unhashable";
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
function zeroCost() {
|
|
2244
|
-
return {
|
|
2245
|
-
tokensInput: 0,
|
|
2246
|
-
tokensOutput: 0,
|
|
2247
|
-
cacheCreationTokens: 0,
|
|
2248
|
-
cacheReadTokens: 0,
|
|
2249
|
-
costUsd: 0,
|
|
2250
|
-
durationMs: 0,
|
|
2251
|
-
numTurns: 0,
|
|
2252
|
-
};
|
|
2253
|
-
}
|
|
2254
|
-
function mergeCost(a, b) {
|
|
2255
|
-
return {
|
|
2256
|
-
tokensInput: a.tokensInput + b.tokensInput,
|
|
2257
|
-
tokensOutput: a.tokensOutput + b.tokensOutput,
|
|
2258
|
-
cacheCreationTokens: a.cacheCreationTokens + b.cacheCreationTokens,
|
|
2259
|
-
cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,
|
|
2260
|
-
costUsd: a.costUsd + b.costUsd,
|
|
2261
|
-
durationMs: a.durationMs + b.durationMs,
|
|
2262
|
-
numTurns: a.numTurns + b.numTurns,
|
|
2263
|
-
};
|
|
2264
|
-
}
|
|
2265
|
-
/**
|
|
2266
|
-
* Local copy of the runtime helper's fence stripper to avoid cycle —
|
|
2267
|
-
* `delegated-task-runtime.ts` already exports the canonical version, but
|
|
2268
|
-
* importing it here would cycle (the runtime imports types from this
|
|
2269
|
-
* file's `agent-core.ts` chain). Tiny duplication is the cleanest fix.
|
|
2270
|
-
*/
|
|
2271
|
-
function stripCodeFences(input) {
|
|
2272
|
-
let s = input.trim();
|
|
2273
|
-
const fenceRe = /^```(?:json|JSON|jsonc|JSONC)?\s*\r?\n([\s\S]*?)\r?\n```$/;
|
|
2274
|
-
const m = s.match(fenceRe);
|
|
2275
|
-
if (m)
|
|
2276
|
-
return m[1];
|
|
2277
|
-
s = s.replace(/^```(?:json|JSON|jsonc|JSONC)?\s*\r?\n/, "");
|
|
2278
|
-
s = s.replace(/\r?\n```\s*$/, "");
|
|
2279
|
-
return s;
|
|
2280
|
-
}
|
|
2281
1923
|
/**
|
|
2282
1924
|
* DELEGATED-TASK-MODE-DESIGN.md §8.3 — runtime_state key for the per-day
|
|
2283
1925
|
* task-mode quota counter. Resets at the agent-day boundary; mirrors the
|
|
2284
1926
|
* Gemini per-day request counter shape.
|
|
2285
1927
|
*/
|
|
2286
1928
|
const DELEGATED_TASK_COUNT_STATE_KEY = "delegated_task_count_today";
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
* `error='subprocess_orphaned'`. Without this, a daemon crash mid-task
|
|
2292
|
-
* leaves the row in flight forever and poisons the dashboard's "in-flight
|
|
2293
|
-
* task" counter.
|
|
2294
|
-
*
|
|
2295
|
-
* Returns the number of rows updated.
|
|
2296
|
-
*/
|
|
2297
|
-
export function runDelegatedTaskOrphanJanitor(db, options = {}) {
|
|
2298
|
-
const maxAgeMs = options.maxAgeMs ?? DELEGATED_PROXY_DEFAULTS.janitorMaxAgeMs;
|
|
2299
|
-
const cutoffMs = (options.now?.() ?? Date.now()) - maxAgeMs;
|
|
2300
|
-
const cutoffIso = new Date(cutoffMs).toISOString();
|
|
2301
|
-
try {
|
|
2302
|
-
const result = db
|
|
2303
|
-
.prepare(`UPDATE agent_actions SET
|
|
2304
|
-
result = 'failed',
|
|
2305
|
-
error = 'subprocess_orphaned',
|
|
2306
|
-
completed_at = datetime('now')
|
|
2307
|
-
WHERE action_type IN ('delegated_task.exec', 'delegated_task.run', 'delegated_task.tool_step')
|
|
2308
|
-
AND result = 'in_progress'
|
|
2309
|
-
AND started_at < datetime(?)`)
|
|
2310
|
-
.run(cutoffIso);
|
|
2311
|
-
if (result.changes > 0) {
|
|
2312
|
-
logger.info({ changes: result.changes }, "delegated task janitor: closed orphaned in-progress rows");
|
|
2313
|
-
}
|
|
2314
|
-
return result.changes;
|
|
2315
|
-
}
|
|
2316
|
-
catch (err) {
|
|
2317
|
-
logger.warn({ err }, "delegated task janitor: SQL update failed");
|
|
2318
|
-
return 0;
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
/**
|
|
2322
|
-
* Boot-time janitor — scans the sessions root for orphan `proxy-*` dirs
|
|
2323
|
-
* older than the configured threshold and removes them. Covers the SIGKILL
|
|
2324
|
-
* mid-call case the per-call `finally` cannot. Safe to call before any
|
|
2325
|
-
* invocations have happened.
|
|
2326
|
-
*
|
|
2327
|
-
* Returns the number of directories removed (for logging at startup).
|
|
2328
|
-
*/
|
|
2329
|
-
export function runProxyTempdirJanitor(dataDir, options = {}) {
|
|
2330
|
-
const now = options.now ?? Date.now;
|
|
2331
|
-
const maxAgeMs = options.maxAgeMs ?? DELEGATED_PROXY_DEFAULTS.janitorMaxAgeMs;
|
|
2332
|
-
const root = join(dataDir, "agent-sessions");
|
|
2333
|
-
if (!existsSync(root))
|
|
2334
|
-
return 0;
|
|
2335
|
-
let removed = 0;
|
|
2336
|
-
let entries;
|
|
2337
|
-
try {
|
|
2338
|
-
entries = readdirSync(root);
|
|
2339
|
-
}
|
|
2340
|
-
catch (err) {
|
|
2341
|
-
logger.warn({ err, root }, "proxy janitor: readdir failed");
|
|
2342
|
-
return 0;
|
|
2343
|
-
}
|
|
2344
|
-
for (const entry of entries) {
|
|
2345
|
-
if (!entry.startsWith(DELEGATED_PROXY_DEFAULTS.tempdirPrefix))
|
|
2346
|
-
continue;
|
|
2347
|
-
const path = join(root, entry);
|
|
2348
|
-
let stat;
|
|
2349
|
-
try {
|
|
2350
|
-
stat = statSync(path);
|
|
2351
|
-
}
|
|
2352
|
-
catch {
|
|
2353
|
-
continue;
|
|
2354
|
-
}
|
|
2355
|
-
if (!stat.isDirectory())
|
|
2356
|
-
continue;
|
|
2357
|
-
if (now() - stat.mtimeMs < maxAgeMs)
|
|
2358
|
-
continue;
|
|
2359
|
-
try {
|
|
2360
|
-
rmSync(path, { recursive: true, force: true });
|
|
2361
|
-
removed++;
|
|
2362
|
-
}
|
|
2363
|
-
catch (err) {
|
|
2364
|
-
logger.warn({ err, path }, "proxy janitor: rm failed");
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
if (removed > 0) {
|
|
2368
|
-
logger.info({ removed }, "proxy janitor: removed orphan tempdirs");
|
|
2369
|
-
}
|
|
2370
|
-
return removed;
|
|
2371
|
-
}
|
|
1929
|
+
// Boot-time janitors live in `delegated-invoker-janitors.ts`. Re-export
|
|
1930
|
+
// here so `index.ts` and tests that import from this module keep working
|
|
1931
|
+
// without an import-path churn — see file-split-plan.md §6.
|
|
1932
|
+
export { runDelegatedTaskOrphanJanitor, runProxyTempdirJanitor, } from "./delegated-invoker-janitors.js";
|
|
2372
1933
|
//# sourceMappingURL=delegated-backend-invoker.js.map
|