@ashx-j/lunr 0.2.27 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.js +5 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/accounting.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts +4 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +5 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +5 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +68 -40
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts +0 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +28 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.d.ts +7 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js +70 -38
- package/dist/builtin-extensions/pi-subagents/src/shared/session-tokens.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +9 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +13 -62
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-tps.js +10 -2
- package/dist/builtin-extensions/pi-tps.js.map +1 -1
- package/dist/catalog/models.json +1 -1
- package/dist/catalog/providers/google-vertex.json +1 -1
- package/dist/catalog/providers/google.json +1 -1
- package/dist/catalog/publication.json +3 -3
- package/dist/core/agent-session.d.ts +6 -15
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +35 -50
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/cache-stats.d.ts +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -11
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +38 -92
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context-breakdown.d.ts +2 -2
- package/dist/core/context-breakdown.d.ts.map +1 -1
- package/dist/core/context-breakdown.js +22 -20
- package/dist/core/context-breakdown.js.map +1 -1
- package/dist/core/extensions/types.d.ts +3 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/session-manager.d.ts +5 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +16 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/usage-accounting.d.ts +47 -0
- package/dist/core/usage-accounting.d.ts.map +1 -0
- package/dist/core/usage-accounting.js +205 -0
- package/dist/core/usage-accounting.js.map +1 -0
- package/dist/core/usage-history.d.ts +1 -18
- package/dist/core/usage-history.d.ts.map +1 -1
- package/dist/core/usage-history.js +46 -114
- package/dist/core/usage-history.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts.map +1 -1
- package/dist/gateway/mobile-commands.js +13 -1
- package/dist/gateway/mobile-commands.js.map +1 -1
- package/dist/modes/interactive/components/context-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/context-view.js +2 -2
- package/dist/modes/interactive/components/context-view.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -12
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/usage-view.d.ts +5 -0
- package/dist/modes/interactive/components/usage-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/usage-view.js +21 -6
- package/dist/modes/interactive/components/usage-view.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +55 -22
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/{agent-session-services-KDMSPQDY.js → agent-session-services-RTUGP3XR.js} +5 -4
- package/dist/node-runtime/{builtin-extensions-OX6KELNX.js → builtin-extensions-N4EUD6SB.js} +1 -1
- package/dist/node-runtime/{chunk-A2WO6WIN.js → chunk-4QRUZ64T.js} +11 -5
- package/dist/node-runtime/{chunk-ZDJUR45D.js → chunk-BMRXLQWQ.js} +41 -38
- package/dist/node-runtime/{chunk-MQPKUHRN.js → chunk-DFMPRAQQ.js} +8 -8
- package/dist/node-runtime/{chunk-C3P6Q3B2.js → chunk-E5DQGNJI.js} +10 -10
- package/dist/node-runtime/{chunk-FIRA54AC.js → chunk-ICKGAKWX.js} +22 -55
- package/dist/node-runtime/{chunk-JWEVT363.js → chunk-JEK35V2M.js} +14 -8
- package/dist/node-runtime/{chunk-EPR2F3GU.js → chunk-PWHTSQC4.js} +15 -1
- package/dist/node-runtime/{chunk-AYHH7YSD.js → chunk-QT3F6UEV.js} +61 -30
- package/dist/node-runtime/{chunk-JQYNHAKX.js → chunk-RY3FJ6WI.js} +29 -27
- package/dist/node-runtime/{chunk-I2H5QMWW.js → chunk-STMX7W5I.js} +1 -1
- package/dist/node-runtime/chunk-SWWHZ2RI.js +158 -0
- package/dist/node-runtime/{chunk-QNVMKNNN.js → chunk-U3YVZ6UC.js} +4 -4
- package/dist/node-runtime/{command-3HMSY6W2.js → command-YRT7I2BW.js} +1 -1
- package/dist/node-runtime/{commands-OCSSEEWJ.js → commands-2ETOWWRA.js} +5 -5
- package/dist/node-runtime/{export-html-BRWF5AHI.js → export-html-DBQRRMAY.js} +1 -1
- package/dist/node-runtime/{gateway-6623C2U3.js → gateway-V6K2CDWN.js} +9 -9
- package/dist/node-runtime/{goal-AIHEDUYA.js → goal-J7TYMOBK.js} +9 -3
- package/dist/node-runtime/index.js +9 -8
- package/dist/node-runtime/{interactive-mode-FM5DNUSW.js → interactive-mode-ASZ7APYP.js} +7 -6
- package/dist/node-runtime/{lunr-cron-LKVA5CZZ.js → lunr-cron-WD3YH4CR.js} +4 -4
- package/dist/node-runtime/main.js +7 -6
- package/dist/node-runtime/{mobile-commands-XT3NQXLD.js → mobile-commands-ICUXFW5V.js} +2 -2
- package/dist/node-runtime/{pi-subagents-LT3CTO4E.js → pi-subagents-QPU3OXE4.js} +17 -62
- package/dist/node-runtime/rpc-entry.js +7 -6
- package/dist/node-runtime/{session-handoff-LNSPDTKY.js → session-handoff-LYH53ESV.js} +2 -2
- package/dist/node-runtime/{session-manager-YIFIAVGC.js → session-manager-ZJ3N5Q74.js} +1 -1
- package/dist/node-runtime/{subagent-executor-Q5F7DBVM.js → subagent-executor-UI6SHG3X.js} +294 -231
- package/docs/features.md +10 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/install-lock/package-lock.json +24 -24
- package/install-lock/package.json +2 -2
- package/npm-shrinkwrap.json +21 -21
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
lunR is derived from pi. The npm package is **`@ashx-j/lunr@0.2.
|
|
3
|
+
lunR is derived from pi. The npm package is **`@ashx-j/lunr@0.2.28`**. Versioned sections below (`0.80.x` and earlier) are **upstream pi history** and do not describe lunR releases.
|
|
4
|
+
|
|
5
|
+
## [0.2.28] - 2026-10-04
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Session, gateway, goal, and history totals count title, summary, and child requests once, including cached input and failed fallback attempts. Branch navigation retains incurred usage; forks exclude inherited usage.
|
|
10
|
+
- Context estimates include system instructions and tools and discard obsolete measurements after compaction or prompt changes.
|
|
11
|
+
- Provider accounting preserves reported usage and charges, reasoning tokens, and cache writes. Gemini long-context pricing matches the reviewed provider tiers.
|
|
12
|
+
- Usage labels distinguish full input, estimated cache misses, visible thinking, approximate context, and subscription quota. Output-rate counters reset for each response.
|
|
4
13
|
|
|
5
14
|
## [0.2.27] - 2026-10-04
|
|
6
15
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accounting.d.ts","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB;AAOD,UAAU,YAAY;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,OAAO,QAUtB;AAED,wBAAgB,eAAe,CAC9B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,YAAY,EACjB,aAAa,UAA2B,QAQxC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,UAO7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,UAM7C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEzE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,UAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,sBAIlD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,UAWlD;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,UAU3D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAI3D","sourcesContent":["// @ts-nocheck\nimport { collectUsageRequests, totalRequestUsage, collectChildUsage, totalChildUsage } from \"../../../core/usage-accounting.ts\";\nimport type { Usage } from \"@ashx-j/lunr-ai\";\n\nexport interface GoalAccountingState {\n\tstatus: string;\n\tbaselineTokens: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tactiveStartedAt?: number;\n\tupdatedAt: number;\n}\n\ninterface AssistantUsageEntryLike {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\ninterface UsageContext {\n\tsessionManager?: unknown;\n}\n\nexport function checkpointGoalActiveTime(\n\tgoal: GoalAccountingState,\n\tnow: number,\n\tcontinueClock: boolean,\n) {\n\tconst accumulated = nonNegativeFiniteNumber(goal.timeUsedSeconds);\n\tconst startedAt = goal.activeStartedAt;\n\tif (typeof startedAt === \"number\" && Number.isFinite(startedAt)) {\n\t\tgoal.timeUsedSeconds = accumulated + Math.max(0, now - startedAt) / 1000;\n\t} else {\n\t\tgoal.timeUsedSeconds = accumulated;\n\t}\n\tgoal.activeStartedAt = continueClock ? now : undefined;\n}\n\nexport function updateGoalUsage(\n\tgoal: GoalAccountingState,\n\tctx: UsageContext,\n\tcontinueClock = goal.status === \"active\",\n) {\n\tconst now = Date.now();\n\tconst baselineTokens = nonNegativeFiniteNumber(goal.baselineTokens);\n\tgoal.baselineTokens = baselineTokens;\n\tgoal.tokensUsed = Math.max(nonNegativeFiniteNumber(goal.tokensUsed), currentTokenTotal(ctx) - baselineTokens);\n\tcheckpointGoalActiveTime(goal, now, continueClock);\n\tgoal.updatedAt = now;\n}\n\nexport function formatDuration(seconds: number) {\n\tconst wholeSeconds = Math.max(0, Math.floor(nonNegativeFiniteNumber(seconds)));\n\tif (wholeSeconds < 60) return `${wholeSeconds}s`;\n\tconst minutes = Math.floor(wholeSeconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\tconst hours = Math.floor(minutes / 60);\n\treturn `${hours}h${minutes % 60}m`;\n}\n\nexport function formatTokenCount(value: number) {\n\tif (value < 1_000) return `${value}`;\n\tif (value < 1_000_000) {\n\t\treturn `${Number.isInteger(value / 1_000) ? value / 1_000 : (value / 1_000).toFixed(1)}k`;\n\t}\n\treturn `${Number.isInteger(value / 1_000_000) ? value / 1_000_000 : (value / 1_000_000).toFixed(1)}m`;\n}\n\nexport function isNonNegativeFiniteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nexport function nonNegativeFiniteNumber(value: unknown) {\n\treturn isNonNegativeFiniteNumber(value) ? value : 0;\n}\n\nexport function normalizeTokenBudget(value: unknown) {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value > 0\n\t\t? value\n\t\t: undefined;\n}\n\nexport function assistantUsageTokens(value: unknown) {\n\tif (!value || typeof value !== \"object\") return 0;\n\tconst usage = value as Partial<Usage>;\n\tif (isNonNegativeFiniteNumber(usage.totalTokens)) return usage.totalTokens;\n\treturn Math.min(\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tnonNegativeFiniteNumber(usage.input) +\n\t\t\tnonNegativeFiniteNumber(usage.output) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheRead) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheWrite),\n\t);\n}\n\nexport function cumulativeAssistantTokens(entries: unknown[]) {\n\tlet total = 0;\n\tfor (const entry of entries) {\n\t\tconst candidate = entry as AssistantUsageEntryLike;\n\t\tif (candidate?.type !== \"message\") continue;\n\t\tconst message = candidate.message as { role?: unknown; usage?: unknown } | undefined;\n\t\tif (message?.role !== \"assistant\") continue;\n\t\ttotal = Math.min(Number.MAX_SAFE_INTEGER, total + assistantUsageTokens(message.usage));\n\t}\n\treturn total;\n}\n\nexport function currentTokenTotal(ctx: UsageContext): number {\n\tconst sessionManager = ctx.sessionManager as { getEntries?: () => unknown[]; getBranch?: () => unknown[] } | undefined;\n\tconst entries = sessionManager?.getEntries?.() ?? sessionManager?.getBranch?.() ?? [];\n\treturn totalRequestUsage(collectUsageRequests(entries)).total + totalChildUsage(collectChildUsage(entries)).total;\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { collectUsageRequests, totalRequestUsage, collectChildUsage, totalChildUsage } from "../../../core/usage-accounting.js";
|
|
1
3
|
export function checkpointGoalActiveTime(goal, now, continueClock) {
|
|
2
4
|
const accumulated = nonNegativeFiniteNumber(goal.timeUsedSeconds);
|
|
3
5
|
const startedAt = goal.activeStartedAt;
|
|
@@ -13,7 +15,7 @@ export function updateGoalUsage(goal, ctx, continueClock = goal.status === "acti
|
|
|
13
15
|
const now = Date.now();
|
|
14
16
|
const baselineTokens = nonNegativeFiniteNumber(goal.baselineTokens);
|
|
15
17
|
goal.baselineTokens = baselineTokens;
|
|
16
|
-
goal.tokensUsed = Math.max(
|
|
18
|
+
goal.tokensUsed = Math.max(nonNegativeFiniteNumber(goal.tokensUsed), currentTokenTotal(ctx) - baselineTokens);
|
|
17
19
|
checkpointGoalActiveTime(goal, now, continueClock);
|
|
18
20
|
goal.updatedAt = now;
|
|
19
21
|
}
|
|
@@ -72,6 +74,7 @@ export function cumulativeAssistantTokens(entries) {
|
|
|
72
74
|
}
|
|
73
75
|
export function currentTokenTotal(ctx) {
|
|
74
76
|
const sessionManager = ctx.sessionManager;
|
|
75
|
-
|
|
77
|
+
const entries = sessionManager?.getEntries?.() ?? sessionManager?.getBranch?.() ?? [];
|
|
78
|
+
return totalRequestUsage(collectUsageRequests(entries)).total + totalChildUsage(collectChildUsage(entries)).total;
|
|
76
79
|
}
|
|
77
80
|
//# sourceMappingURL=accounting.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../../../src/builtin-extensions/narumiruna-pi-goal/src/accounting.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport { collectUsageRequests, totalRequestUsage, collectChildUsage, totalChildUsage } from \"../../../core/usage-accounting.ts\";\nimport type { Usage } from \"@ashx-j/lunr-ai\";\n\nexport interface GoalAccountingState {\n\tstatus: string;\n\tbaselineTokens: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tactiveStartedAt?: number;\n\tupdatedAt: number;\n}\n\ninterface AssistantUsageEntryLike {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\ninterface UsageContext {\n\tsessionManager?: unknown;\n}\n\nexport function checkpointGoalActiveTime(\n\tgoal: GoalAccountingState,\n\tnow: number,\n\tcontinueClock: boolean,\n) {\n\tconst accumulated = nonNegativeFiniteNumber(goal.timeUsedSeconds);\n\tconst startedAt = goal.activeStartedAt;\n\tif (typeof startedAt === \"number\" && Number.isFinite(startedAt)) {\n\t\tgoal.timeUsedSeconds = accumulated + Math.max(0, now - startedAt) / 1000;\n\t} else {\n\t\tgoal.timeUsedSeconds = accumulated;\n\t}\n\tgoal.activeStartedAt = continueClock ? now : undefined;\n}\n\nexport function updateGoalUsage(\n\tgoal: GoalAccountingState,\n\tctx: UsageContext,\n\tcontinueClock = goal.status === \"active\",\n) {\n\tconst now = Date.now();\n\tconst baselineTokens = nonNegativeFiniteNumber(goal.baselineTokens);\n\tgoal.baselineTokens = baselineTokens;\n\tgoal.tokensUsed = Math.max(nonNegativeFiniteNumber(goal.tokensUsed), currentTokenTotal(ctx) - baselineTokens);\n\tcheckpointGoalActiveTime(goal, now, continueClock);\n\tgoal.updatedAt = now;\n}\n\nexport function formatDuration(seconds: number) {\n\tconst wholeSeconds = Math.max(0, Math.floor(nonNegativeFiniteNumber(seconds)));\n\tif (wholeSeconds < 60) return `${wholeSeconds}s`;\n\tconst minutes = Math.floor(wholeSeconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\tconst hours = Math.floor(minutes / 60);\n\treturn `${hours}h${minutes % 60}m`;\n}\n\nexport function formatTokenCount(value: number) {\n\tif (value < 1_000) return `${value}`;\n\tif (value < 1_000_000) {\n\t\treturn `${Number.isInteger(value / 1_000) ? value / 1_000 : (value / 1_000).toFixed(1)}k`;\n\t}\n\treturn `${Number.isInteger(value / 1_000_000) ? value / 1_000_000 : (value / 1_000_000).toFixed(1)}m`;\n}\n\nexport function isNonNegativeFiniteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nexport function nonNegativeFiniteNumber(value: unknown) {\n\treturn isNonNegativeFiniteNumber(value) ? value : 0;\n}\n\nexport function normalizeTokenBudget(value: unknown) {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value > 0\n\t\t? value\n\t\t: undefined;\n}\n\nexport function assistantUsageTokens(value: unknown) {\n\tif (!value || typeof value !== \"object\") return 0;\n\tconst usage = value as Partial<Usage>;\n\tif (isNonNegativeFiniteNumber(usage.totalTokens)) return usage.totalTokens;\n\treturn Math.min(\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\tnonNegativeFiniteNumber(usage.input) +\n\t\t\tnonNegativeFiniteNumber(usage.output) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheRead) +\n\t\t\tnonNegativeFiniteNumber(usage.cacheWrite),\n\t);\n}\n\nexport function cumulativeAssistantTokens(entries: unknown[]) {\n\tlet total = 0;\n\tfor (const entry of entries) {\n\t\tconst candidate = entry as AssistantUsageEntryLike;\n\t\tif (candidate?.type !== \"message\") continue;\n\t\tconst message = candidate.message as { role?: unknown; usage?: unknown } | undefined;\n\t\tif (message?.role !== \"assistant\") continue;\n\t\ttotal = Math.min(Number.MAX_SAFE_INTEGER, total + assistantUsageTokens(message.usage));\n\t}\n\treturn total;\n}\n\nexport function currentTokenTotal(ctx: UsageContext): number {\n\tconst sessionManager = ctx.sessionManager as { getEntries?: () => unknown[]; getBranch?: () => unknown[] } | undefined;\n\tconst entries = sessionManager?.getEntries?.() ?? sessionManager?.getBranch?.() ?? [];\n\treturn totalRequestUsage(collectUsageRequests(entries)).total + totalChildUsage(collectChildUsage(entries)).total;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AccountedRequest } from "../../../../../core/usage-accounting.ts";
|
|
2
|
+
import type { AcceptanceLedger, CostSummary, ModelAttempt, Usage } from "../../shared/types.ts";
|
|
2
3
|
export interface ImportedAsyncRoot {
|
|
3
4
|
runId: string;
|
|
4
5
|
asyncDir: string;
|
|
@@ -16,6 +17,8 @@ export interface ImportedAsyncRootResult {
|
|
|
16
17
|
model?: string;
|
|
17
18
|
attemptedModels?: string[];
|
|
18
19
|
modelAttempts?: ModelAttempt[];
|
|
20
|
+
usage?: Usage;
|
|
21
|
+
usageRequests?: AccountedRequest[];
|
|
19
22
|
totalCost?: CostSummary;
|
|
20
23
|
structuredOutput?: unknown;
|
|
21
24
|
structuredOutputPath?: string;
|
package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-root-attachment.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAe,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGtG,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AA6ID,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACjJ,OAAO,CAAC,uBAAuB,CAAC,CAuBlC;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpF","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AcceptanceLedger, AsyncStatus, CostSummary, ModelAttempt } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\n\nexport interface ImportedAsyncRoot {\n\trunId: string;\n\tasyncDir: string;\n\tresultPath: string;\n\tindex: number;\n}\n\nexport interface ImportedAsyncRootResult {\n\tagent: string;\n\toutput: string;\n\tsuccess: boolean;\n\texitCode: number;\n\terror?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\ttotalCost?: CostSummary;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n}\n\ninterface AsyncResultFile {\n\tstate?: string;\n\tsuccess?: boolean;\n\tsummary?: string;\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tresults?: Array<{\n\t\tagent?: string;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tsuccess?: boolean;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tsessionFile?: string;\n\t\tintercomTarget?: string;\n\t\tmodel?: string;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\t\ttotalCost?: CostSummary;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t}>;\n}\n\nconst TERMINAL_STATES = new Set([\"complete\", \"failed\", \"paused\", \"stopped\"]);\nconst TERMINAL_STEP_STATUSES = new Set([\"complete\", \"completed\", \"failed\", \"paused\", \"stopped\"]);\n\nfunction readResultFile(resultPath: string): AsyncResultFile | undefined {\n\ttry {\n\t\treturn JSON.parse(fs.readFileSync(resultPath, \"utf-8\")) as AsyncResultFile;\n\t} catch (error) {\n\t\tif (typeof error === \"object\" && error !== null && \"code\" in error && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction selectedStatusStep(status: AsyncStatus | null, index: number): NonNullable<AsyncStatus[\"steps\"]>[number] | undefined {\n\treturn status?.steps?.[index];\n}\n\nfunction isTerminalStatus(status: AsyncStatus | null, index: number): boolean {\n\tif (!status) return false;\n\tconst step = selectedStatusStep(status, index);\n\tif (step && TERMINAL_STEP_STATUSES.has(step.status)) return true;\n\treturn TERMINAL_STATES.has(status.state);\n}\n\nfunction resultState(result: AsyncResultFile | undefined, child: NonNullable<AsyncResultFile[\"results\"]>[number] | undefined): \"complete\" | \"failed\" | \"paused\" | \"stopped\" | undefined {\n\tif (!result) return undefined;\n\tif (child?.stopped === true) return \"stopped\";\n\tif (child?.success === true) return \"complete\";\n\tif (child?.success === false) return result.state === \"stopped\" ? \"stopped\" : result.state === \"paused\" ? \"paused\" : \"failed\";\n\tif (result.state === \"complete\" || result.state === \"failed\" || result.state === \"paused\" || result.state === \"stopped\") return result.state;\n\tif (result.success === true) return \"complete\";\n\tif (result.success === false) return \"failed\";\n\treturn undefined;\n}\n\nfunction outputFromTerminalStatus(root: ImportedAsyncRoot, status: AsyncStatus, step: NonNullable<AsyncStatus[\"steps\"]>[number] | undefined): ImportedAsyncRootResult {\n\tconst agent = step?.agent ?? status.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst timedOut = step?.timedOut === true || status.timedOut === true;\n\tconst stopped = step?.stopped === true || status.stopped === true || status.state === \"stopped\";\n\tconst message = step?.error ?? status.error ?? (stopped ? \"Subagent stopped by user.\" : `Attached async root ${root.runId} ended without a result file at ${root.resultPath}.`);\n\treturn {\n\t\tagent,\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(step?.sessionFile ?? status.sessionFile ? { sessionFile: step?.sessionFile ?? status.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t...(step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(step?.structuredOutputPath ? { structuredOutputPath: step.structuredOutputPath } : {}),\n\t\t...(step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: step.structuredOutputSchemaPath } : {}),\n\t\t...(step?.acceptance ? { acceptance: step.acceptance } : {}),\n\t};\n}\n\nfunction outputFromTimeout(root: ImportedAsyncRoot, status: AsyncStatus | null, message: string): ImportedAsyncRootResult {\n\tconst step = selectedStatusStep(status, root.index);\n\treturn {\n\t\tagent: step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\",\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\ttimedOut: true,\n\t\t...(step?.sessionFile ?? status?.sessionFile ? { sessionFile: step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t};\n}\n\nfunction buildImportedResult(root: ImportedAsyncRoot, status: AsyncStatus | null, result: AsyncResultFile): ImportedAsyncRootResult {\n\tconst child = result.results?.[root.index];\n\tconst step = selectedStatusStep(status, root.index);\n\tconst state = resultState(result, child);\n\tconst agent = child?.agent ?? step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst output = child?.output ?? result.summary ?? \"\";\n\tconst timedOut = child?.timedOut === true || step?.timedOut === true || result.timedOut === true || status?.timedOut === true;\n\tconst stopped = child?.stopped === true || step?.stopped === true || result.stopped === true || status?.stopped === true || state === \"stopped\";\n\tconst success = state === \"complete\" && !timedOut && !stopped;\n\tconst error = child?.error ?? (success ? undefined : stopped ? \"Subagent stopped by user.\" : result.error ?? result.summary ?? status?.error ?? `Attached async root ${root.runId} did not complete successfully.`);\n\treturn {\n\t\tagent,\n\t\toutput: success ? output : (output || error || \"\"),\n\t\tsuccess,\n\t\texitCode: success ? 0 : 1,\n\t\t...(error ? { error } : {}),\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile ? { sessionFile: child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(child?.intercomTarget ? { intercomTarget: child.intercomTarget } : {}),\n\t\t...(child?.model ?? step?.model ? { model: child?.model ?? step?.model } : {}),\n\t\t...(child?.modelSelection ?? step?.modelSelection ? { modelSelection: child?.modelSelection ?? step?.modelSelection } : {}),\n\t\t...(child?.attemptedModels ?? step?.attemptedModels ? { attemptedModels: child?.attemptedModels ?? step?.attemptedModels } : {}),\n\t\t...(child?.modelAttempts ?? step?.modelAttempts ? { modelAttempts: child?.modelAttempts ?? step?.modelAttempts } : {}),\n\t\t...(child?.totalCost ?? step?.totalCost ? { totalCost: child?.totalCost ?? step?.totalCost } : {}),\n\t\t...(child?.structuredOutput !== undefined ? { structuredOutput: child.structuredOutput } : step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(child?.structuredOutputPath ?? step?.structuredOutputPath ? { structuredOutputPath: child?.structuredOutputPath ?? step?.structuredOutputPath } : {}),\n\t\t...(child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath } : {}),\n\t\t...(child?.acceptance ?? step?.acceptance ? { acceptance: child?.acceptance ?? step?.acceptance } : {}),\n\t};\n}\n\nexport async function waitForImportedAsyncRoot(\n\troot: ImportedAsyncRoot,\n\toptions: { pollIntervalMs?: number; terminalResultGraceMs?: number; now?: () => number; shouldAbort?: () => boolean; timeoutMessage?: string } = {},\n): Promise<ImportedAsyncRootResult> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 500;\n\tconst terminalResultGraceMs = options.terminalResultGraceMs ?? 1_000;\n\tconst now = options.now ?? Date.now;\n\tlet terminalSince: number | undefined;\n\tfor (;;) {\n\t\tconst status = readStatus(root.asyncDir);\n\t\tif (options.shouldAbort?.()) return outputFromTimeout(root, status, options.timeoutMessage ?? \"Subagent timed out.\");\n\t\tconst result = readResultFile(root.resultPath);\n\t\tif (result) return buildImportedResult(root, status, result);\n\t\tif (isTerminalStatus(status, root.index)) {\n\t\t\tterminalSince ??= now();\n\t\t\tif (now() - terminalSince >= terminalResultGraceMs) {\n\t\t\t\treturn outputFromTerminalStatus(root, status!, selectedStatusStep(status, root.index));\n\t\t\t}\n\t\t} else {\n\t\t\tterminalSince = undefined;\n\t\t}\n\t\tif (!status && !fs.existsSync(root.asyncDir)) {\n\t\t\tthrow new Error(`Attached async root '${root.runId}' directory does not exist: ${root.asyncDir}`);\n\t\t}\n\t\tawait new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n\t}\n}\n\nexport function resolveAsyncRootResultPath(resultsDir: string, runId: string): string {\n\treturn path.join(resultsDir, `${runId}.json`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chain-root-attachment.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAe,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG7G,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAiJD,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,iBAAiB,EACvB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACjJ,OAAO,CAAC,uBAAuB,CAAC,CAuBlC;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpF","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AccountedRequest } from \"../../../../../core/usage-accounting.ts\";\nimport type { AcceptanceLedger, AsyncStatus, CostSummary, ModelAttempt, Usage } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\n\nexport interface ImportedAsyncRoot {\n\trunId: string;\n\tasyncDir: string;\n\tresultPath: string;\n\tindex: number;\n}\n\nexport interface ImportedAsyncRootResult {\n\tagent: string;\n\toutput: string;\n\tsuccess: boolean;\n\texitCode: number;\n\terror?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\tusage?: Usage;\n\tusageRequests?: AccountedRequest[];\n\ttotalCost?: CostSummary;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n}\n\ninterface AsyncResultFile {\n\tstate?: string;\n\tsuccess?: boolean;\n\tsummary?: string;\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tresults?: Array<{\n\t\tagent?: string;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tsuccess?: boolean;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tsessionFile?: string;\n\t\tintercomTarget?: string;\n\t\tmodel?: string;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\tusage?: Usage;\n\tusageRequests?: AccountedRequest[];\n\t\ttotalCost?: CostSummary;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t}>;\n}\n\nconst TERMINAL_STATES = new Set([\"complete\", \"failed\", \"paused\", \"stopped\"]);\nconst TERMINAL_STEP_STATUSES = new Set([\"complete\", \"completed\", \"failed\", \"paused\", \"stopped\"]);\n\nfunction readResultFile(resultPath: string): AsyncResultFile | undefined {\n\ttry {\n\t\treturn JSON.parse(fs.readFileSync(resultPath, \"utf-8\")) as AsyncResultFile;\n\t} catch (error) {\n\t\tif (typeof error === \"object\" && error !== null && \"code\" in error && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction selectedStatusStep(status: AsyncStatus | null, index: number): NonNullable<AsyncStatus[\"steps\"]>[number] | undefined {\n\treturn status?.steps?.[index];\n}\n\nfunction isTerminalStatus(status: AsyncStatus | null, index: number): boolean {\n\tif (!status) return false;\n\tconst step = selectedStatusStep(status, index);\n\tif (step && TERMINAL_STEP_STATUSES.has(step.status)) return true;\n\treturn TERMINAL_STATES.has(status.state);\n}\n\nfunction resultState(result: AsyncResultFile | undefined, child: NonNullable<AsyncResultFile[\"results\"]>[number] | undefined): \"complete\" | \"failed\" | \"paused\" | \"stopped\" | undefined {\n\tif (!result) return undefined;\n\tif (child?.stopped === true) return \"stopped\";\n\tif (child?.success === true) return \"complete\";\n\tif (child?.success === false) return result.state === \"stopped\" ? \"stopped\" : result.state === \"paused\" ? \"paused\" : \"failed\";\n\tif (result.state === \"complete\" || result.state === \"failed\" || result.state === \"paused\" || result.state === \"stopped\") return result.state;\n\tif (result.success === true) return \"complete\";\n\tif (result.success === false) return \"failed\";\n\treturn undefined;\n}\n\nfunction outputFromTerminalStatus(root: ImportedAsyncRoot, status: AsyncStatus, step: NonNullable<AsyncStatus[\"steps\"]>[number] | undefined): ImportedAsyncRootResult {\n\tconst agent = step?.agent ?? status.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst timedOut = step?.timedOut === true || status.timedOut === true;\n\tconst stopped = step?.stopped === true || status.stopped === true || status.state === \"stopped\";\n\tconst message = step?.error ?? status.error ?? (stopped ? \"Subagent stopped by user.\" : `Attached async root ${root.runId} ended without a result file at ${root.resultPath}.`);\n\treturn {\n\t\tagent,\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(step?.sessionFile ?? status.sessionFile ? { sessionFile: step?.sessionFile ?? status.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t...(step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(step?.structuredOutputPath ? { structuredOutputPath: step.structuredOutputPath } : {}),\n\t\t...(step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: step.structuredOutputSchemaPath } : {}),\n\t\t...(step?.acceptance ? { acceptance: step.acceptance } : {}),\n\t};\n}\n\nfunction outputFromTimeout(root: ImportedAsyncRoot, status: AsyncStatus | null, message: string): ImportedAsyncRootResult {\n\tconst step = selectedStatusStep(status, root.index);\n\treturn {\n\t\tagent: step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\",\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\ttimedOut: true,\n\t\t...(step?.sessionFile ?? status?.sessionFile ? { sessionFile: step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t};\n}\n\nfunction buildImportedResult(root: ImportedAsyncRoot, status: AsyncStatus | null, result: AsyncResultFile): ImportedAsyncRootResult {\n\tconst child = result.results?.[root.index];\n\tconst step = selectedStatusStep(status, root.index);\n\tconst state = resultState(result, child);\n\tconst agent = child?.agent ?? step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst output = child?.output ?? result.summary ?? \"\";\n\tconst timedOut = child?.timedOut === true || step?.timedOut === true || result.timedOut === true || status?.timedOut === true;\n\tconst stopped = child?.stopped === true || step?.stopped === true || result.stopped === true || status?.stopped === true || state === \"stopped\";\n\tconst success = state === \"complete\" && !timedOut && !stopped;\n\tconst error = child?.error ?? (success ? undefined : stopped ? \"Subagent stopped by user.\" : result.error ?? result.summary ?? status?.error ?? `Attached async root ${root.runId} did not complete successfully.`);\n\treturn {\n\t\tagent,\n\t\toutput: success ? output : (output || error || \"\"),\n\t\tsuccess,\n\t\texitCode: success ? 0 : 1,\n\t\t...(error ? { error } : {}),\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile ? { sessionFile: child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(child?.intercomTarget ? { intercomTarget: child.intercomTarget } : {}),\n\t\t...(child?.model ?? step?.model ? { model: child?.model ?? step?.model } : {}),\n\t\t...(child?.modelSelection ?? step?.modelSelection ? { modelSelection: child?.modelSelection ?? step?.modelSelection } : {}),\n\t\t...(child?.attemptedModels ?? step?.attemptedModels ? { attemptedModels: child?.attemptedModels ?? step?.attemptedModels } : {}),\n\t\t...(child?.usage ? { usage: child.usage } : {}),\n\t\t...(child?.usageRequests ? { usageRequests: child.usageRequests } : {}),\n\t\t...(child?.modelAttempts ?? step?.modelAttempts ? { modelAttempts: child?.modelAttempts ?? step?.modelAttempts } : {}),\n\t\t...(child?.totalCost ?? step?.totalCost ? { totalCost: child?.totalCost ?? step?.totalCost } : {}),\n\t\t...(child?.structuredOutput !== undefined ? { structuredOutput: child.structuredOutput } : step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(child?.structuredOutputPath ?? step?.structuredOutputPath ? { structuredOutputPath: child?.structuredOutputPath ?? step?.structuredOutputPath } : {}),\n\t\t...(child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath } : {}),\n\t\t...(child?.acceptance ?? step?.acceptance ? { acceptance: child?.acceptance ?? step?.acceptance } : {}),\n\t};\n}\n\nexport async function waitForImportedAsyncRoot(\n\troot: ImportedAsyncRoot,\n\toptions: { pollIntervalMs?: number; terminalResultGraceMs?: number; now?: () => number; shouldAbort?: () => boolean; timeoutMessage?: string } = {},\n): Promise<ImportedAsyncRootResult> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 500;\n\tconst terminalResultGraceMs = options.terminalResultGraceMs ?? 1_000;\n\tconst now = options.now ?? Date.now;\n\tlet terminalSince: number | undefined;\n\tfor (;;) {\n\t\tconst status = readStatus(root.asyncDir);\n\t\tif (options.shouldAbort?.()) return outputFromTimeout(root, status, options.timeoutMessage ?? \"Subagent timed out.\");\n\t\tconst result = readResultFile(root.resultPath);\n\t\tif (result) return buildImportedResult(root, status, result);\n\t\tif (isTerminalStatus(status, root.index)) {\n\t\t\tterminalSince ??= now();\n\t\t\tif (now() - terminalSince >= terminalResultGraceMs) {\n\t\t\t\treturn outputFromTerminalStatus(root, status!, selectedStatusStep(status, root.index));\n\t\t\t}\n\t\t} else {\n\t\t\tterminalSince = undefined;\n\t\t}\n\t\tif (!status && !fs.existsSync(root.asyncDir)) {\n\t\t\tthrow new Error(`Attached async root '${root.runId}' directory does not exist: ${root.asyncDir}`);\n\t\t}\n\t\tawait new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n\t}\n}\n\nexport function resolveAsyncRootResultPath(resultsDir: string, runId: string): string {\n\treturn path.join(resultsDir, `${runId}.json`);\n}\n"]}
|
|
@@ -108,6 +108,8 @@ function buildImportedResult(root, status, result) {
|
|
|
108
108
|
...(child?.model ?? step?.model ? { model: child?.model ?? step?.model } : {}),
|
|
109
109
|
...(child?.modelSelection ?? step?.modelSelection ? { modelSelection: child?.modelSelection ?? step?.modelSelection } : {}),
|
|
110
110
|
...(child?.attemptedModels ?? step?.attemptedModels ? { attemptedModels: child?.attemptedModels ?? step?.attemptedModels } : {}),
|
|
111
|
+
...(child?.usage ? { usage: child.usage } : {}),
|
|
112
|
+
...(child?.usageRequests ? { usageRequests: child.usageRequests } : {}),
|
|
111
113
|
...(child?.modelAttempts ?? step?.modelAttempts ? { modelAttempts: child?.modelAttempts ?? step?.modelAttempts } : {}),
|
|
112
114
|
...(child?.totalCost ?? step?.totalCost ? { totalCost: child?.totalCost ?? step?.totalCost } : {}),
|
|
113
115
|
...(child?.structuredOutput !== undefined ? { structuredOutput: child.structuredOutput } : step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),
|
package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-root-attachment.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AcceptanceLedger, AsyncStatus, CostSummary, ModelAttempt } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\n\nexport interface ImportedAsyncRoot {\n\trunId: string;\n\tasyncDir: string;\n\tresultPath: string;\n\tindex: number;\n}\n\nexport interface ImportedAsyncRootResult {\n\tagent: string;\n\toutput: string;\n\tsuccess: boolean;\n\texitCode: number;\n\terror?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\ttotalCost?: CostSummary;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n}\n\ninterface AsyncResultFile {\n\tstate?: string;\n\tsuccess?: boolean;\n\tsummary?: string;\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tresults?: Array<{\n\t\tagent?: string;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tsuccess?: boolean;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tsessionFile?: string;\n\t\tintercomTarget?: string;\n\t\tmodel?: string;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\t\ttotalCost?: CostSummary;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t}>;\n}\n\nconst TERMINAL_STATES = new Set([\"complete\", \"failed\", \"paused\", \"stopped\"]);\nconst TERMINAL_STEP_STATUSES = new Set([\"complete\", \"completed\", \"failed\", \"paused\", \"stopped\"]);\n\nfunction readResultFile(resultPath: string): AsyncResultFile | undefined {\n\ttry {\n\t\treturn JSON.parse(fs.readFileSync(resultPath, \"utf-8\")) as AsyncResultFile;\n\t} catch (error) {\n\t\tif (typeof error === \"object\" && error !== null && \"code\" in error && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction selectedStatusStep(status: AsyncStatus | null, index: number): NonNullable<AsyncStatus[\"steps\"]>[number] | undefined {\n\treturn status?.steps?.[index];\n}\n\nfunction isTerminalStatus(status: AsyncStatus | null, index: number): boolean {\n\tif (!status) return false;\n\tconst step = selectedStatusStep(status, index);\n\tif (step && TERMINAL_STEP_STATUSES.has(step.status)) return true;\n\treturn TERMINAL_STATES.has(status.state);\n}\n\nfunction resultState(result: AsyncResultFile | undefined, child: NonNullable<AsyncResultFile[\"results\"]>[number] | undefined): \"complete\" | \"failed\" | \"paused\" | \"stopped\" | undefined {\n\tif (!result) return undefined;\n\tif (child?.stopped === true) return \"stopped\";\n\tif (child?.success === true) return \"complete\";\n\tif (child?.success === false) return result.state === \"stopped\" ? \"stopped\" : result.state === \"paused\" ? \"paused\" : \"failed\";\n\tif (result.state === \"complete\" || result.state === \"failed\" || result.state === \"paused\" || result.state === \"stopped\") return result.state;\n\tif (result.success === true) return \"complete\";\n\tif (result.success === false) return \"failed\";\n\treturn undefined;\n}\n\nfunction outputFromTerminalStatus(root: ImportedAsyncRoot, status: AsyncStatus, step: NonNullable<AsyncStatus[\"steps\"]>[number] | undefined): ImportedAsyncRootResult {\n\tconst agent = step?.agent ?? status.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst timedOut = step?.timedOut === true || status.timedOut === true;\n\tconst stopped = step?.stopped === true || status.stopped === true || status.state === \"stopped\";\n\tconst message = step?.error ?? status.error ?? (stopped ? \"Subagent stopped by user.\" : `Attached async root ${root.runId} ended without a result file at ${root.resultPath}.`);\n\treturn {\n\t\tagent,\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(step?.sessionFile ?? status.sessionFile ? { sessionFile: step?.sessionFile ?? status.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t...(step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(step?.structuredOutputPath ? { structuredOutputPath: step.structuredOutputPath } : {}),\n\t\t...(step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: step.structuredOutputSchemaPath } : {}),\n\t\t...(step?.acceptance ? { acceptance: step.acceptance } : {}),\n\t};\n}\n\nfunction outputFromTimeout(root: ImportedAsyncRoot, status: AsyncStatus | null, message: string): ImportedAsyncRootResult {\n\tconst step = selectedStatusStep(status, root.index);\n\treturn {\n\t\tagent: step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\",\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\ttimedOut: true,\n\t\t...(step?.sessionFile ?? status?.sessionFile ? { sessionFile: step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t};\n}\n\nfunction buildImportedResult(root: ImportedAsyncRoot, status: AsyncStatus | null, result: AsyncResultFile): ImportedAsyncRootResult {\n\tconst child = result.results?.[root.index];\n\tconst step = selectedStatusStep(status, root.index);\n\tconst state = resultState(result, child);\n\tconst agent = child?.agent ?? step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst output = child?.output ?? result.summary ?? \"\";\n\tconst timedOut = child?.timedOut === true || step?.timedOut === true || result.timedOut === true || status?.timedOut === true;\n\tconst stopped = child?.stopped === true || step?.stopped === true || result.stopped === true || status?.stopped === true || state === \"stopped\";\n\tconst success = state === \"complete\" && !timedOut && !stopped;\n\tconst error = child?.error ?? (success ? undefined : stopped ? \"Subagent stopped by user.\" : result.error ?? result.summary ?? status?.error ?? `Attached async root ${root.runId} did not complete successfully.`);\n\treturn {\n\t\tagent,\n\t\toutput: success ? output : (output || error || \"\"),\n\t\tsuccess,\n\t\texitCode: success ? 0 : 1,\n\t\t...(error ? { error } : {}),\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile ? { sessionFile: child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(child?.intercomTarget ? { intercomTarget: child.intercomTarget } : {}),\n\t\t...(child?.model ?? step?.model ? { model: child?.model ?? step?.model } : {}),\n\t\t...(child?.modelSelection ?? step?.modelSelection ? { modelSelection: child?.modelSelection ?? step?.modelSelection } : {}),\n\t\t...(child?.attemptedModels ?? step?.attemptedModels ? { attemptedModels: child?.attemptedModels ?? step?.attemptedModels } : {}),\n\t\t...(child?.modelAttempts ?? step?.modelAttempts ? { modelAttempts: child?.modelAttempts ?? step?.modelAttempts } : {}),\n\t\t...(child?.totalCost ?? step?.totalCost ? { totalCost: child?.totalCost ?? step?.totalCost } : {}),\n\t\t...(child?.structuredOutput !== undefined ? { structuredOutput: child.structuredOutput } : step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(child?.structuredOutputPath ?? step?.structuredOutputPath ? { structuredOutputPath: child?.structuredOutputPath ?? step?.structuredOutputPath } : {}),\n\t\t...(child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath } : {}),\n\t\t...(child?.acceptance ?? step?.acceptance ? { acceptance: child?.acceptance ?? step?.acceptance } : {}),\n\t};\n}\n\nexport async function waitForImportedAsyncRoot(\n\troot: ImportedAsyncRoot,\n\toptions: { pollIntervalMs?: number; terminalResultGraceMs?: number; now?: () => number; shouldAbort?: () => boolean; timeoutMessage?: string } = {},\n): Promise<ImportedAsyncRootResult> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 500;\n\tconst terminalResultGraceMs = options.terminalResultGraceMs ?? 1_000;\n\tconst now = options.now ?? Date.now;\n\tlet terminalSince: number | undefined;\n\tfor (;;) {\n\t\tconst status = readStatus(root.asyncDir);\n\t\tif (options.shouldAbort?.()) return outputFromTimeout(root, status, options.timeoutMessage ?? \"Subagent timed out.\");\n\t\tconst result = readResultFile(root.resultPath);\n\t\tif (result) return buildImportedResult(root, status, result);\n\t\tif (isTerminalStatus(status, root.index)) {\n\t\t\tterminalSince ??= now();\n\t\t\tif (now() - terminalSince >= terminalResultGraceMs) {\n\t\t\t\treturn outputFromTerminalStatus(root, status!, selectedStatusStep(status, root.index));\n\t\t\t}\n\t\t} else {\n\t\t\tterminalSince = undefined;\n\t\t}\n\t\tif (!status && !fs.existsSync(root.asyncDir)) {\n\t\t\tthrow new Error(`Attached async root '${root.runId}' directory does not exist: ${root.asyncDir}`);\n\t\t}\n\t\tawait new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n\t}\n}\n\nexport function resolveAsyncRootResultPath(resultsDir: string, runId: string): string {\n\treturn path.join(resultsDir, `${runId}.json`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chain-root-attachment.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AccountedRequest } from \"../../../../../core/usage-accounting.ts\";\nimport type { AcceptanceLedger, AsyncStatus, CostSummary, ModelAttempt, Usage } from \"../../shared/types.ts\";\nimport { readStatus } from \"../../shared/utils.ts\";\n\nexport interface ImportedAsyncRoot {\n\trunId: string;\n\tasyncDir: string;\n\tresultPath: string;\n\tindex: number;\n}\n\nexport interface ImportedAsyncRootResult {\n\tagent: string;\n\toutput: string;\n\tsuccess: boolean;\n\texitCode: number;\n\terror?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\tusage?: Usage;\n\tusageRequests?: AccountedRequest[];\n\ttotalCost?: CostSummary;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n}\n\ninterface AsyncResultFile {\n\tstate?: string;\n\tsuccess?: boolean;\n\tsummary?: string;\n\terror?: string;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tresults?: Array<{\n\t\tagent?: string;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tsuccess?: boolean;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tsessionFile?: string;\n\t\tintercomTarget?: string;\n\t\tmodel?: string;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\tusage?: Usage;\n\tusageRequests?: AccountedRequest[];\n\t\ttotalCost?: CostSummary;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t}>;\n}\n\nconst TERMINAL_STATES = new Set([\"complete\", \"failed\", \"paused\", \"stopped\"]);\nconst TERMINAL_STEP_STATUSES = new Set([\"complete\", \"completed\", \"failed\", \"paused\", \"stopped\"]);\n\nfunction readResultFile(resultPath: string): AsyncResultFile | undefined {\n\ttry {\n\t\treturn JSON.parse(fs.readFileSync(resultPath, \"utf-8\")) as AsyncResultFile;\n\t} catch (error) {\n\t\tif (typeof error === \"object\" && error !== null && \"code\" in error && (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction selectedStatusStep(status: AsyncStatus | null, index: number): NonNullable<AsyncStatus[\"steps\"]>[number] | undefined {\n\treturn status?.steps?.[index];\n}\n\nfunction isTerminalStatus(status: AsyncStatus | null, index: number): boolean {\n\tif (!status) return false;\n\tconst step = selectedStatusStep(status, index);\n\tif (step && TERMINAL_STEP_STATUSES.has(step.status)) return true;\n\treturn TERMINAL_STATES.has(status.state);\n}\n\nfunction resultState(result: AsyncResultFile | undefined, child: NonNullable<AsyncResultFile[\"results\"]>[number] | undefined): \"complete\" | \"failed\" | \"paused\" | \"stopped\" | undefined {\n\tif (!result) return undefined;\n\tif (child?.stopped === true) return \"stopped\";\n\tif (child?.success === true) return \"complete\";\n\tif (child?.success === false) return result.state === \"stopped\" ? \"stopped\" : result.state === \"paused\" ? \"paused\" : \"failed\";\n\tif (result.state === \"complete\" || result.state === \"failed\" || result.state === \"paused\" || result.state === \"stopped\") return result.state;\n\tif (result.success === true) return \"complete\";\n\tif (result.success === false) return \"failed\";\n\treturn undefined;\n}\n\nfunction outputFromTerminalStatus(root: ImportedAsyncRoot, status: AsyncStatus, step: NonNullable<AsyncStatus[\"steps\"]>[number] | undefined): ImportedAsyncRootResult {\n\tconst agent = step?.agent ?? status.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst timedOut = step?.timedOut === true || status.timedOut === true;\n\tconst stopped = step?.stopped === true || status.stopped === true || status.state === \"stopped\";\n\tconst message = step?.error ?? status.error ?? (stopped ? \"Subagent stopped by user.\" : `Attached async root ${root.runId} ended without a result file at ${root.resultPath}.`);\n\treturn {\n\t\tagent,\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(step?.sessionFile ?? status.sessionFile ? { sessionFile: step?.sessionFile ?? status.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t\t...(step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(step?.structuredOutputPath ? { structuredOutputPath: step.structuredOutputPath } : {}),\n\t\t...(step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: step.structuredOutputSchemaPath } : {}),\n\t\t...(step?.acceptance ? { acceptance: step.acceptance } : {}),\n\t};\n}\n\nfunction outputFromTimeout(root: ImportedAsyncRoot, status: AsyncStatus | null, message: string): ImportedAsyncRootResult {\n\tconst step = selectedStatusStep(status, root.index);\n\treturn {\n\t\tagent: step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\",\n\t\toutput: message,\n\t\tsuccess: false,\n\t\texitCode: 1,\n\t\terror: message,\n\t\ttimedOut: true,\n\t\t...(step?.sessionFile ?? status?.sessionFile ? { sessionFile: step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(step?.model ? { model: step.model } : {}),\n\t\t...(step?.modelSelection ? { modelSelection: step.modelSelection } : {}),\n\t\t...(step?.attemptedModels ? { attemptedModels: step.attemptedModels } : {}),\n\t\t...(step?.modelAttempts ? { modelAttempts: step.modelAttempts } : {}),\n\t\t...(step?.totalCost ? { totalCost: step.totalCost } : {}),\n\t};\n}\n\nfunction buildImportedResult(root: ImportedAsyncRoot, status: AsyncStatus | null, result: AsyncResultFile): ImportedAsyncRootResult {\n\tconst child = result.results?.[root.index];\n\tconst step = selectedStatusStep(status, root.index);\n\tconst state = resultState(result, child);\n\tconst agent = child?.agent ?? step?.agent ?? status?.steps?.[root.index]?.agent ?? \"subagent\";\n\tconst output = child?.output ?? result.summary ?? \"\";\n\tconst timedOut = child?.timedOut === true || step?.timedOut === true || result.timedOut === true || status?.timedOut === true;\n\tconst stopped = child?.stopped === true || step?.stopped === true || result.stopped === true || status?.stopped === true || state === \"stopped\";\n\tconst success = state === \"complete\" && !timedOut && !stopped;\n\tconst error = child?.error ?? (success ? undefined : stopped ? \"Subagent stopped by user.\" : result.error ?? result.summary ?? status?.error ?? `Attached async root ${root.runId} did not complete successfully.`);\n\treturn {\n\t\tagent,\n\t\toutput: success ? output : (output || error || \"\"),\n\t\tsuccess,\n\t\texitCode: success ? 0 : 1,\n\t\t...(error ? { error } : {}),\n\t\t...(timedOut ? { timedOut: true } : {}),\n\t\t...(stopped ? { stopped: true } : {}),\n\t\t...(child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile ? { sessionFile: child?.sessionFile ?? step?.sessionFile ?? status?.sessionFile } : {}),\n\t\t...(child?.intercomTarget ? { intercomTarget: child.intercomTarget } : {}),\n\t\t...(child?.model ?? step?.model ? { model: child?.model ?? step?.model } : {}),\n\t\t...(child?.modelSelection ?? step?.modelSelection ? { modelSelection: child?.modelSelection ?? step?.modelSelection } : {}),\n\t\t...(child?.attemptedModels ?? step?.attemptedModels ? { attemptedModels: child?.attemptedModels ?? step?.attemptedModels } : {}),\n\t\t...(child?.usage ? { usage: child.usage } : {}),\n\t\t...(child?.usageRequests ? { usageRequests: child.usageRequests } : {}),\n\t\t...(child?.modelAttempts ?? step?.modelAttempts ? { modelAttempts: child?.modelAttempts ?? step?.modelAttempts } : {}),\n\t\t...(child?.totalCost ?? step?.totalCost ? { totalCost: child?.totalCost ?? step?.totalCost } : {}),\n\t\t...(child?.structuredOutput !== undefined ? { structuredOutput: child.structuredOutput } : step?.structuredOutput !== undefined ? { structuredOutput: step.structuredOutput } : {}),\n\t\t...(child?.structuredOutputPath ?? step?.structuredOutputPath ? { structuredOutputPath: child?.structuredOutputPath ?? step?.structuredOutputPath } : {}),\n\t\t...(child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath ? { structuredOutputSchemaPath: child?.structuredOutputSchemaPath ?? step?.structuredOutputSchemaPath } : {}),\n\t\t...(child?.acceptance ?? step?.acceptance ? { acceptance: child?.acceptance ?? step?.acceptance } : {}),\n\t};\n}\n\nexport async function waitForImportedAsyncRoot(\n\troot: ImportedAsyncRoot,\n\toptions: { pollIntervalMs?: number; terminalResultGraceMs?: number; now?: () => number; shouldAbort?: () => boolean; timeoutMessage?: string } = {},\n): Promise<ImportedAsyncRootResult> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 500;\n\tconst terminalResultGraceMs = options.terminalResultGraceMs ?? 1_000;\n\tconst now = options.now ?? Date.now;\n\tlet terminalSince: number | undefined;\n\tfor (;;) {\n\t\tconst status = readStatus(root.asyncDir);\n\t\tif (options.shouldAbort?.()) return outputFromTimeout(root, status, options.timeoutMessage ?? \"Subagent timed out.\");\n\t\tconst result = readResultFile(root.resultPath);\n\t\tif (result) return buildImportedResult(root, status, result);\n\t\tif (isTerminalStatus(status, root.index)) {\n\t\t\tterminalSince ??= now();\n\t\t\tif (now() - terminalSince >= terminalResultGraceMs) {\n\t\t\t\treturn outputFromTerminalStatus(root, status!, selectedStatusStep(status, root.index));\n\t\t\t}\n\t\t} else {\n\t\t\tterminalSince = undefined;\n\t\t}\n\t\tif (!status && !fs.existsSync(root.asyncDir)) {\n\t\t\tthrow new Error(`Attached async root '${root.runId}' directory does not exist: ${root.asyncDir}`);\n\t\t}\n\t\tawait new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n\t}\n}\n\nexport function resolveAsyncRootResultPath(resultsDir: string, runId: string): string {\n\treturn path.join(resultsDir, `${runId}.json`);\n}\n"]}
|
|
@@ -12,6 +12,10 @@ import { type CompletionBatchConfig } from "./completion-batcher.ts";
|
|
|
12
12
|
import { type AcceptanceLedger, type SubagentResultIntercomChild, type SubagentState } from "../../shared/types.ts";
|
|
13
13
|
interface ChainStepResult extends Partial<SubagentResultIntercomChild> {
|
|
14
14
|
agent: string;
|
|
15
|
+
childId?: string;
|
|
16
|
+
sessionFile?: string;
|
|
17
|
+
usage?: import("../../shared/types.ts").Usage;
|
|
18
|
+
usageRequests?: import("../../../../../core/usage-accounting.ts").AccountedRequest[];
|
|
15
19
|
output: string;
|
|
16
20
|
summary?: string;
|
|
17
21
|
error?: string;
|
|
@@ -20,6 +24,7 @@ interface ChainStepResult extends Partial<SubagentResultIntercomChild> {
|
|
|
20
24
|
}
|
|
21
25
|
export interface SubagentNotifyDetails {
|
|
22
26
|
agent: string;
|
|
27
|
+
children?: ChainStepResult[];
|
|
23
28
|
status: "completed" | "failed" | "paused" | "stopped";
|
|
24
29
|
source?: "async" | "foreground";
|
|
25
30
|
taskInfo?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/notify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Subagent completion notifications.\n *\n * Successful (completed) async results are held briefly and emitted as a\n * single grouped message when sibling jobs finish within a short window (see\n * `completion-batcher.ts`). Failed and paused results bypass grouping and fire\n * immediately, flushing any held successes first, so failure and attention\n * signals are never delayed.\n */\n\nimport type { ExtensionAPI } from \"@ashx-j/lunr\";\nimport { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from \"./completion-dedupe.ts\";\nimport {\n\ttype CompletionBatchConfig,\n\ttype CompletionBatcher,\n\tcreateCompletionBatcher,\n\tresolveCompletionBatchConfig,\n} from \"./completion-batcher.ts\";\nimport { formatNestedResultLines, resolveSubagentResultStatus } from \"../../intercom/result-intercom.ts\";\nimport { SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT, type AcceptanceLedger, type SubagentResultIntercomChild, type SubagentState } from \"../../shared/types.ts\";\n\ninterface ChainStepResult extends Partial<SubagentResultIntercomChild> {\n\tagent: string;\n\toutput: string;\n\tsummary?: string;\n\terror?: string;\n\tacceptance?: AcceptanceLedger;\n\tsuccess: boolean;\n}\n\nexport interface SubagentNotifyDetails {\n\tagent: string;\n\tstatus: \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsource?: \"async\" | \"foreground\";\n\ttaskInfo?: string;\n\tresultPreview: string;\n\tdurationMs?: number;\n\tsessionLabel?: string;\n\tsessionValue?: string;\n}\n\ninterface SubagentResult {\n\tid: string | null;\n\tsource?: \"async\" | \"foreground\";\n\tagent: string | null;\n\tsuccess: boolean;\n\tsummary: string;\n\texitCode?: number;\n\tstate?: string;\n\ttimestamp: number;\n\tdurationMs?: number;\n\tcwd?: string;\n\tasyncDir?: string;\n\tsessionFile?: string;\n\tshareUrl?: string;\n\tgistUrl?: string;\n\tshareError?: string;\n\tresults?: ChainStepResult[];\n\ttaskIndex?: number;\n\ttotalTasks?: number;\n\tsessionId?: string | null;\n}\n\ninterface NotifyTimerApi {\n\tsetTimeout(handler: () => void, delayMs: number): unknown;\n\tclearTimeout(handle: unknown): void;\n}\n\nexport interface RegisterSubagentNotifyOptions {\n\tbatchConfig?: CompletionBatchConfig;\n\ttimers?: NotifyTimerApi;\n\tnow?: () => number;\n}\n\nfunction formatSessionLine(details: SubagentNotifyDetails): string | undefined {\n\tif (!details.sessionValue) return undefined;\n\treturn details.sessionLabel ? `${details.sessionLabel}: ${details.sessionValue}` : details.sessionValue;\n}\n\nexport function formatSingleCompletion(details: SubagentNotifyDetails): string {\n\tconst sessionLine = formatSessionLine(details);\n\tconst taskKind = details.source === \"foreground\" ? \"Detached foreground task\" : \"Background task\";\n\treturn [\n\t\t`${taskKind} ${details.status}: **${details.agent}**${details.taskInfo ?? \"\"}`,\n\t\t\"\",\n\t\tdetails.resultPreview.trim() ? details.resultPreview : \"(no output)\",\n\t\tsessionLine ? \"\" : undefined,\n\t\tsessionLine,\n\t]\n\t\t.filter((line) => line !== undefined)\n\t\t.join(\"\\n\");\n}\n\nexport function parseSubagentNotifyContent(content: string): SubagentNotifyDetails | undefined {\n\tconst lines = content.split(\"\\n\");\n\tconst match = (lines[0] ?? \"\").match(/^(Background task|Detached foreground task) (completed|failed|paused|stopped): \\*\\*(.+?)\\*\\*(?:\\s+(\\([^)]*\\)))?$/);\n\tif (!match) return undefined;\n\tconst body = lines.slice(2);\n\tlet sessionIndex = -1;\n\tfor (let i = body.length - 1; i >= 1; i--) {\n\t\tif (body[i - 1]?.trim() === \"\" && /^(Session|Session file|Session share error):\\s+/.test(body[i]!)) {\n\t\t\tsessionIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;\n\tconst resultPreview = (sessionIndex >= 0 ? body.slice(0, sessionIndex) : body).join(\"\\n\").trim() || \"(no output)\";\n\tlet sessionLabel: string | undefined;\n\tlet sessionValue: string | undefined;\n\tif (sessionLine) {\n\t\tconst separator = sessionLine.indexOf(\":\");\n\t\tsessionLabel = sessionLine.slice(0, separator).toLowerCase();\n\t\tsessionValue = sessionLine.slice(separator + 1).trim();\n\t}\n\treturn {\n\t\tagent: match[3]!,\n\t\tstatus: match[2] as SubagentNotifyDetails[\"status\"],\n\t\t...(match[1] === \"Detached foreground task\" ? { source: \"foreground\" as const } : {}),\n\t\t...(match[4] ? { taskInfo: match[4] } : {}),\n\t\tresultPreview,\n\t\t...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),\n\t};\n}\n\nexport function formatGroupedCompletion(details: SubagentNotifyDetails[]): string {\n\tconst header = `Background tasks completed (${details.length}): ${details.map((d) => `**${d.agent}**${d.taskInfo ?? \"\"}`).join(\", \")}`;\n\tconst blocks: string[] = [header, \"\"];\n\tfor (let index = 0; index < details.length; index++) {\n\t\tconst detail = details[index];\n\t\tif (!detail) continue;\n\t\tconst sessionLine = formatSessionLine(detail);\n\t\tblocks.push(`${index + 1}. ${detail.agent}${detail.taskInfo ?? \"\"}`);\n\t\tblocks.push(detail.resultPreview.trim() ? detail.resultPreview : \"(no output)\");\n\t\tif (sessionLine) blocks.push(sessionLine);\n\t\tblocks.push(\"\");\n\t}\n\treturn blocks.join(\"\\n\").trimEnd();\n}\n\nfunction sendCompletion(pi: Pick<ExtensionAPI, \"sendMessage\">, details: SubagentNotifyDetails[]): void {\n\tif (details.length === 0) return;\n\tconst content = details.length === 1\n\t\t? formatSingleCompletion(details[0]!)\n\t\t: formatGroupedCompletion(details);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"subagent-notify\",\n\t\t\tcontent,\n\t\t\tdisplay: true,\n\t\t},\n\t\t{ triggerTurn: details.some((detail) => detail.status !== \"stopped\") },\n\t);\n}\n\nfunction completionBatchKey(result: SubagentResult): string {\n\tconst sessionId = typeof result.sessionId === \"string\" ? result.sessionId.trim() : \"\";\n\tif (sessionId) return `session:${sessionId}`;\n\tconst cwd = typeof result.cwd === \"string\" ? result.cwd.trim() : \"\";\n\treturn cwd ? `cwd:${cwd}` : \"unknown\";\n}\n\nexport function buildCompletionDetails(result: SubagentResult): SubagentNotifyDetails {\n\tconst agent = result.agent ?? \"unknown\";\n\tconst summary = typeof result.summary === \"string\" ? result.summary : \"\";\n\tconst paused = !result.success && (\n\t\tresult.exitCode === 0\n\t\t|| result.state === \"paused\"\n\t\t|| summary.startsWith(\"Paused after interrupt.\")\n\t);\n\tconst status = result.state === \"stopped\" ? \"stopped\" : paused ? \"paused\" : result.success ? \"completed\" : \"failed\";\n\n\tconst taskInfo =\n\t\tresult.taskIndex !== undefined && result.totalTasks !== undefined\n\t\t\t? ` (${result.taskIndex + 1}/${result.totalTasks})`\n\t\t\t: undefined;\n\n\tconst session =\n\t\tresult.shareUrl\n\t\t\t? { label: \"Session\", value: result.shareUrl }\n\t\t\t: result.shareError\n\t\t\t\t? { label: \"Session share error\", value: result.shareError }\n\t\t\t\t: result.sessionFile\n\t\t\t\t\t? { label: \"Session file\", value: result.sessionFile }\n\t\t\t\t\t: undefined;\n\n\treturn {\n\t\tagent,\n\t\tstatus,\n\t\t...(result.source ? { source: result.source } : {}),\n\t\t...(taskInfo ? { taskInfo } : {}),\n\t\tresultPreview: [\n\t\t\tresult.id ? `Run: ${result.id}` : undefined,\n\t\t\tresult.asyncDir ? `Async dir: ${result.asyncDir}` : undefined,\n\t\t\tresult.results?.length\n\t\t\t\t? result.results.map((child, index) => {\n\t\t\t\t\tconst output = child.summary ?? (child.error ? `${child.error}\\n\\nOutput:\\n${child.output}` : child.output);\n\t\t\t\t\tconst report = child.acceptance?.childReport;\n\t\t\t\t\tconst childIndex = child.index ?? index;\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`${childIndex + 1}. ${child.agent} [${child.status ?? resolveSubagentResultStatus({ success: child.success, state: result.state })}]`,\n\t\t\t\t\t\tchild.artifactPath ? `Output artifact: ${child.artifactPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath ? `Session: ${child.sessionPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath && result.id && result.source !== \"foreground\"\n\t\t\t\t\t\t\t? `Revive: subagent({ action: \"resume\", id: ${JSON.stringify(result.id)}, index: ${childIndex}, message: \"...\" })`\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t...formatNestedResultLines(child.children),\n\t\t\t\t\t\toutput,\n\t\t\t\t\t\treport ? `\\`\\`\\`acceptance-report\\n${JSON.stringify(report, null, 2)}\\n\\`\\`\\`` : undefined,\n\t\t\t\t\t].filter((line) => line !== undefined).join(\"\\n\");\n\t\t\t\t}).join(\"\\n\\n\")\n\t\t\t\t: summary,\n\t\t].filter((line) => line !== undefined).join(\"\\n\\n\"),\n\t\t...(typeof result.durationMs === \"number\" ? { durationMs: result.durationMs } : {}),\n\t\t...(session ? { sessionLabel: session.label, sessionValue: session.value } : {}),\n\t};\n}\n\nexport default function registerSubagentNotify(\n\tpi: ExtensionAPI,\n\tstate: Pick<SubagentState, \"currentSessionId\">,\n\toptions: RegisterSubagentNotifyOptions = {},\n): () => void {\n\tlet disposed = false;\n\tconst seen = getGlobalSeenMap(\"__pi_subagents_notify_seen__\");\n\tconst ttlMs = 10 * 60 * 1000;\n\tconst nowFn = options.now ?? Date.now;\n\tconst batchConfig = resolveCompletionBatchConfig(options.batchConfig);\n\tconst batchers = new Map<string, CompletionBatcher<SubagentNotifyDetails>>();\n\tconst handleComplete = (data: unknown) => {\n\t\tif (disposed) return;\n\t\tconst result = data as SubagentResult;\n\t\tif (typeof result.sessionId !== \"string\" || result.sessionId !== state.currentSessionId) return;\n\t\tconst now = nowFn();\n\t\tconst key = `${result.sessionId}:${buildCompletionKey(result, \"notify\")}`;\n\t\tif (markSeenWithTtl(seen, key, now, ttlMs)) return;\n\n\t\tconst details = buildCompletionDetails(result);\n\t\tif (result.source === \"foreground\") {\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tconst batchKey = completionBatchKey(result);\n\t\tlet batcher = batchers.get(batchKey);\n\t\tif (!batcher) {\n\t\t\tbatcher = createCompletionBatcher<SubagentNotifyDetails>({\n\t\t\t\tconfig: batchConfig,\n\t\t\t\temit: (items) => {\n\t\t\t\t\tif (!disposed && result.sessionId === state.currentSessionId) sendCompletion(pi, items);\n\t\t\t\t},\n\t\t\t\t...(options.timers ? { timers: options.timers } : {}),\n\t\t\t\tnow: nowFn,\n\t\t\t});\n\t\t\tbatchers.set(batchKey, batcher);\n\t\t}\n\t\tif (details.status !== \"completed\") {\n\t\t\t// Failures and paused runs bypass grouping. Flush any held\n\t\t\t// successes for the same owner first so they are not stranded\n\t\t\t// behind this signal, then emit the non-completion result immediately.\n\t\t\tbatcher.flush();\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tbatcher.push(details);\n\t};\n\n\tconst unsubscribers = [\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_FOREGROUND_COMPLETE_EVENT, handleComplete),\n\t].filter((unsubscribe): unsubscribe is () => void => typeof unsubscribe === \"function\");\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tfor (const batcher of batchers.values()) batcher.dispose();\n\t\tbatchers.clear();\n\t\tfor (const unsubscribe of unsubscribers) unsubscribe();\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/notify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Subagent completion notifications.\n *\n * Successful (completed) async results are held briefly and emitted as a\n * single grouped message when sibling jobs finish within a short window (see\n * `completion-batcher.ts`). Failed and paused results bypass grouping and fire\n * immediately, flushing any held successes first, so failure and attention\n * signals are never delayed.\n */\n\nimport type { ExtensionAPI } from \"@ashx-j/lunr\";\nimport { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from \"./completion-dedupe.ts\";\nimport {\n\ttype CompletionBatchConfig,\n\ttype CompletionBatcher,\n\tcreateCompletionBatcher,\n\tresolveCompletionBatchConfig,\n} from \"./completion-batcher.ts\";\nimport { formatNestedResultLines, resolveSubagentResultStatus } from \"../../intercom/result-intercom.ts\";\nimport { SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT, type AcceptanceLedger, type SubagentResultIntercomChild, type SubagentState } from \"../../shared/types.ts\";\n\ninterface ChainStepResult extends Partial<SubagentResultIntercomChild> {\n\tagent: string;\n\tchildId?: string;\n\tsessionFile?: string;\n\tusage?: import(\"../../shared/types.ts\").Usage;\n\tusageRequests?: import(\"../../../../../core/usage-accounting.ts\").AccountedRequest[];\n\toutput: string;\n\tsummary?: string;\n\terror?: string;\n\tacceptance?: AcceptanceLedger;\n\tsuccess: boolean;\n}\n\nexport interface SubagentNotifyDetails {\n\tagent: string;\n\tchildren?: ChainStepResult[];\n\tstatus: \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsource?: \"async\" | \"foreground\";\n\ttaskInfo?: string;\n\tresultPreview: string;\n\tdurationMs?: number;\n\tsessionLabel?: string;\n\tsessionValue?: string;\n}\n\ninterface SubagentResult {\n\tid: string | null;\n\tsource?: \"async\" | \"foreground\";\n\tagent: string | null;\n\tsuccess: boolean;\n\tsummary: string;\n\texitCode?: number;\n\tstate?: string;\n\ttimestamp: number;\n\tdurationMs?: number;\n\tcwd?: string;\n\tasyncDir?: string;\n\tsessionFile?: string;\n\tshareUrl?: string;\n\tgistUrl?: string;\n\tshareError?: string;\n\tresults?: ChainStepResult[];\n\ttaskIndex?: number;\n\ttotalTasks?: number;\n\tsessionId?: string | null;\n}\n\ninterface NotifyTimerApi {\n\tsetTimeout(handler: () => void, delayMs: number): unknown;\n\tclearTimeout(handle: unknown): void;\n}\n\nexport interface RegisterSubagentNotifyOptions {\n\tbatchConfig?: CompletionBatchConfig;\n\ttimers?: NotifyTimerApi;\n\tnow?: () => number;\n}\n\nfunction formatSessionLine(details: SubagentNotifyDetails): string | undefined {\n\tif (!details.sessionValue) return undefined;\n\treturn details.sessionLabel ? `${details.sessionLabel}: ${details.sessionValue}` : details.sessionValue;\n}\n\nexport function formatSingleCompletion(details: SubagentNotifyDetails): string {\n\tconst sessionLine = formatSessionLine(details);\n\tconst taskKind = details.source === \"foreground\" ? \"Detached foreground task\" : \"Background task\";\n\treturn [\n\t\t`${taskKind} ${details.status}: **${details.agent}**${details.taskInfo ?? \"\"}`,\n\t\t\"\",\n\t\tdetails.resultPreview.trim() ? details.resultPreview : \"(no output)\",\n\t\tsessionLine ? \"\" : undefined,\n\t\tsessionLine,\n\t]\n\t\t.filter((line) => line !== undefined)\n\t\t.join(\"\\n\");\n}\n\nexport function parseSubagentNotifyContent(content: string): SubagentNotifyDetails | undefined {\n\tconst lines = content.split(\"\\n\");\n\tconst match = (lines[0] ?? \"\").match(/^(Background task|Detached foreground task) (completed|failed|paused|stopped): \\*\\*(.+?)\\*\\*(?:\\s+(\\([^)]*\\)))?$/);\n\tif (!match) return undefined;\n\tconst body = lines.slice(2);\n\tlet sessionIndex = -1;\n\tfor (let i = body.length - 1; i >= 1; i--) {\n\t\tif (body[i - 1]?.trim() === \"\" && /^(Session|Session file|Session share error):\\s+/.test(body[i]!)) {\n\t\t\tsessionIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;\n\tconst resultPreview = (sessionIndex >= 0 ? body.slice(0, sessionIndex) : body).join(\"\\n\").trim() || \"(no output)\";\n\tlet sessionLabel: string | undefined;\n\tlet sessionValue: string | undefined;\n\tif (sessionLine) {\n\t\tconst separator = sessionLine.indexOf(\":\");\n\t\tsessionLabel = sessionLine.slice(0, separator).toLowerCase();\n\t\tsessionValue = sessionLine.slice(separator + 1).trim();\n\t}\n\treturn {\n\t\tagent: match[3]!,\n\t\tstatus: match[2] as SubagentNotifyDetails[\"status\"],\n\t\t...(match[1] === \"Detached foreground task\" ? { source: \"foreground\" as const } : {}),\n\t\t...(match[4] ? { taskInfo: match[4] } : {}),\n\t\tresultPreview,\n\t\t...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),\n\t};\n}\n\nexport function formatGroupedCompletion(details: SubagentNotifyDetails[]): string {\n\tconst header = `Background tasks completed (${details.length}): ${details.map((d) => `**${d.agent}**${d.taskInfo ?? \"\"}`).join(\", \")}`;\n\tconst blocks: string[] = [header, \"\"];\n\tfor (let index = 0; index < details.length; index++) {\n\t\tconst detail = details[index];\n\t\tif (!detail) continue;\n\t\tconst sessionLine = formatSessionLine(detail);\n\t\tblocks.push(`${index + 1}. ${detail.agent}${detail.taskInfo ?? \"\"}`);\n\t\tblocks.push(detail.resultPreview.trim() ? detail.resultPreview : \"(no output)\");\n\t\tif (sessionLine) blocks.push(sessionLine);\n\t\tblocks.push(\"\");\n\t}\n\treturn blocks.join(\"\\n\").trimEnd();\n}\n\nfunction sendCompletion(pi: Pick<ExtensionAPI, \"sendMessage\">, details: SubagentNotifyDetails[]): void {\n\tif (details.length === 0) return;\n\tconst content = details.length === 1\n\t\t? formatSingleCompletion(details[0]!)\n\t\t: formatGroupedCompletion(details);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"subagent-notify\",\n\t\t\tcontent,\n\t\t\tdisplay: true,\n\t\t\tdetails: { children: details.flatMap((detail) => detail.children ?? []) },\n\t\t},\n\t\t{ triggerTurn: details.some((detail) => detail.status !== \"stopped\") },\n\t);\n}\n\nfunction completionBatchKey(result: SubagentResult): string {\n\tconst sessionId = typeof result.sessionId === \"string\" ? result.sessionId.trim() : \"\";\n\tif (sessionId) return `session:${sessionId}`;\n\tconst cwd = typeof result.cwd === \"string\" ? result.cwd.trim() : \"\";\n\treturn cwd ? `cwd:${cwd}` : \"unknown\";\n}\n\nexport function buildCompletionDetails(result: SubagentResult): SubagentNotifyDetails {\n\tconst agent = result.agent ?? \"unknown\";\n\tconst summary = typeof result.summary === \"string\" ? result.summary : \"\";\n\tconst paused = !result.success && (\n\t\tresult.exitCode === 0\n\t\t|| result.state === \"paused\"\n\t\t|| summary.startsWith(\"Paused after interrupt.\")\n\t);\n\tconst status = result.state === \"stopped\" ? \"stopped\" : paused ? \"paused\" : result.success ? \"completed\" : \"failed\";\n\n\tconst taskInfo =\n\t\tresult.taskIndex !== undefined && result.totalTasks !== undefined\n\t\t\t? ` (${result.taskIndex + 1}/${result.totalTasks})`\n\t\t\t: undefined;\n\n\tconst session =\n\t\tresult.shareUrl\n\t\t\t? { label: \"Session\", value: result.shareUrl }\n\t\t\t: result.shareError\n\t\t\t\t? { label: \"Session share error\", value: result.shareError }\n\t\t\t\t: result.sessionFile\n\t\t\t\t\t? { label: \"Session file\", value: result.sessionFile }\n\t\t\t\t\t: undefined;\n\n\treturn {\n\t\tagent,\n\t\tstatus,\n\t\tchildren: result.results?.map((child, index) => ({ ...child, childId: child.childId ?? `${result.id}:${index}` })),\n\t\t...(result.source ? { source: result.source } : {}),\n\t\t...(taskInfo ? { taskInfo } : {}),\n\t\tresultPreview: [\n\t\t\tresult.id ? `Run: ${result.id}` : undefined,\n\t\t\tresult.asyncDir ? `Async dir: ${result.asyncDir}` : undefined,\n\t\t\tresult.results?.length\n\t\t\t\t? result.results.map((child, index) => {\n\t\t\t\t\tconst output = child.summary ?? (child.error ? `${child.error}\\n\\nOutput:\\n${child.output}` : child.output);\n\t\t\t\t\tconst report = child.acceptance?.childReport;\n\t\t\t\t\tconst childIndex = child.index ?? index;\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`${childIndex + 1}. ${child.agent} [${child.status ?? resolveSubagentResultStatus({ success: child.success, state: result.state })}]`,\n\t\t\t\t\t\tchild.artifactPath ? `Output artifact: ${child.artifactPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath ? `Session: ${child.sessionPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath && result.id && result.source !== \"foreground\"\n\t\t\t\t\t\t\t? `Revive: subagent({ action: \"resume\", id: ${JSON.stringify(result.id)}, index: ${childIndex}, message: \"...\" })`\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t...formatNestedResultLines(child.children),\n\t\t\t\t\t\toutput,\n\t\t\t\t\t\treport ? `\\`\\`\\`acceptance-report\\n${JSON.stringify(report, null, 2)}\\n\\`\\`\\`` : undefined,\n\t\t\t\t\t].filter((line) => line !== undefined).join(\"\\n\");\n\t\t\t\t}).join(\"\\n\\n\")\n\t\t\t\t: summary,\n\t\t].filter((line) => line !== undefined).join(\"\\n\\n\"),\n\t\t...(typeof result.durationMs === \"number\" ? { durationMs: result.durationMs } : {}),\n\t\t...(session ? { sessionLabel: session.label, sessionValue: session.value } : {}),\n\t};\n}\n\nexport default function registerSubagentNotify(\n\tpi: ExtensionAPI,\n\tstate: Pick<SubagentState, \"currentSessionId\">,\n\toptions: RegisterSubagentNotifyOptions = {},\n): () => void {\n\tlet disposed = false;\n\tconst seen = getGlobalSeenMap(\"__pi_subagents_notify_seen__\");\n\tconst ttlMs = 10 * 60 * 1000;\n\tconst nowFn = options.now ?? Date.now;\n\tconst batchConfig = resolveCompletionBatchConfig(options.batchConfig);\n\tconst batchers = new Map<string, CompletionBatcher<SubagentNotifyDetails>>();\n\tconst handleComplete = (data: unknown) => {\n\t\tif (disposed) return;\n\t\tconst result = data as SubagentResult;\n\t\tif (typeof result.sessionId !== \"string\" || result.sessionId !== state.currentSessionId) return;\n\t\tconst now = nowFn();\n\t\tconst key = `${result.sessionId}:${buildCompletionKey(result, \"notify\")}`;\n\t\tif (markSeenWithTtl(seen, key, now, ttlMs)) return;\n\n\t\tconst details = buildCompletionDetails(result);\n\t\tif (result.source === \"foreground\") {\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tconst batchKey = completionBatchKey(result);\n\t\tlet batcher = batchers.get(batchKey);\n\t\tif (!batcher) {\n\t\t\tbatcher = createCompletionBatcher<SubagentNotifyDetails>({\n\t\t\t\tconfig: batchConfig,\n\t\t\t\temit: (items) => {\n\t\t\t\t\tif (!disposed && result.sessionId === state.currentSessionId) sendCompletion(pi, items);\n\t\t\t\t},\n\t\t\t\t...(options.timers ? { timers: options.timers } : {}),\n\t\t\t\tnow: nowFn,\n\t\t\t});\n\t\t\tbatchers.set(batchKey, batcher);\n\t\t}\n\t\tif (details.status !== \"completed\") {\n\t\t\t// Failures and paused runs bypass grouping. Flush any held\n\t\t\t// successes for the same owner first so they are not stranded\n\t\t\t// behind this signal, then emit the non-completion result immediately.\n\t\t\tbatcher.flush();\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tbatcher.push(details);\n\t};\n\n\tconst unsubscribers = [\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_FOREGROUND_COMPLETE_EVENT, handleComplete),\n\t].filter((unsubscribe): unsubscribe is () => void => typeof unsubscribe === \"function\");\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tfor (const batcher of batchers.values()) batcher.dispose();\n\t\tbatchers.clear();\n\t\tfor (const unsubscribe of unsubscribers) unsubscribe();\n\t};\n}\n"]}
|
|
@@ -87,6 +87,7 @@ function sendCompletion(pi, details) {
|
|
|
87
87
|
customType: "subagent-notify",
|
|
88
88
|
content,
|
|
89
89
|
display: true,
|
|
90
|
+
details: { children: details.flatMap((detail) => detail.children ?? []) },
|
|
90
91
|
}, { triggerTurn: details.some((detail) => detail.status !== "stopped") });
|
|
91
92
|
}
|
|
92
93
|
function completionBatchKey(result) {
|
|
@@ -116,6 +117,7 @@ export function buildCompletionDetails(result) {
|
|
|
116
117
|
return {
|
|
117
118
|
agent,
|
|
118
119
|
status,
|
|
120
|
+
children: result.results?.map((child, index) => ({ ...child, childId: child.childId ?? `${result.id}:${index}` })),
|
|
119
121
|
...(result.source ? { source: result.source } : {}),
|
|
120
122
|
...(taskInfo ? { taskInfo } : {}),
|
|
121
123
|
resultPreview: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/notify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Subagent completion notifications.\n *\n * Successful (completed) async results are held briefly and emitted as a\n * single grouped message when sibling jobs finish within a short window (see\n * `completion-batcher.ts`). Failed and paused results bypass grouping and fire\n * immediately, flushing any held successes first, so failure and attention\n * signals are never delayed.\n */\n\nimport type { ExtensionAPI } from \"@ashx-j/lunr\";\nimport { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from \"./completion-dedupe.ts\";\nimport {\n\ttype CompletionBatchConfig,\n\ttype CompletionBatcher,\n\tcreateCompletionBatcher,\n\tresolveCompletionBatchConfig,\n} from \"./completion-batcher.ts\";\nimport { formatNestedResultLines, resolveSubagentResultStatus } from \"../../intercom/result-intercom.ts\";\nimport { SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT, type AcceptanceLedger, type SubagentResultIntercomChild, type SubagentState } from \"../../shared/types.ts\";\n\ninterface ChainStepResult extends Partial<SubagentResultIntercomChild> {\n\tagent: string;\n\toutput: string;\n\tsummary?: string;\n\terror?: string;\n\tacceptance?: AcceptanceLedger;\n\tsuccess: boolean;\n}\n\nexport interface SubagentNotifyDetails {\n\tagent: string;\n\tstatus: \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsource?: \"async\" | \"foreground\";\n\ttaskInfo?: string;\n\tresultPreview: string;\n\tdurationMs?: number;\n\tsessionLabel?: string;\n\tsessionValue?: string;\n}\n\ninterface SubagentResult {\n\tid: string | null;\n\tsource?: \"async\" | \"foreground\";\n\tagent: string | null;\n\tsuccess: boolean;\n\tsummary: string;\n\texitCode?: number;\n\tstate?: string;\n\ttimestamp: number;\n\tdurationMs?: number;\n\tcwd?: string;\n\tasyncDir?: string;\n\tsessionFile?: string;\n\tshareUrl?: string;\n\tgistUrl?: string;\n\tshareError?: string;\n\tresults?: ChainStepResult[];\n\ttaskIndex?: number;\n\ttotalTasks?: number;\n\tsessionId?: string | null;\n}\n\ninterface NotifyTimerApi {\n\tsetTimeout(handler: () => void, delayMs: number): unknown;\n\tclearTimeout(handle: unknown): void;\n}\n\nexport interface RegisterSubagentNotifyOptions {\n\tbatchConfig?: CompletionBatchConfig;\n\ttimers?: NotifyTimerApi;\n\tnow?: () => number;\n}\n\nfunction formatSessionLine(details: SubagentNotifyDetails): string | undefined {\n\tif (!details.sessionValue) return undefined;\n\treturn details.sessionLabel ? `${details.sessionLabel}: ${details.sessionValue}` : details.sessionValue;\n}\n\nexport function formatSingleCompletion(details: SubagentNotifyDetails): string {\n\tconst sessionLine = formatSessionLine(details);\n\tconst taskKind = details.source === \"foreground\" ? \"Detached foreground task\" : \"Background task\";\n\treturn [\n\t\t`${taskKind} ${details.status}: **${details.agent}**${details.taskInfo ?? \"\"}`,\n\t\t\"\",\n\t\tdetails.resultPreview.trim() ? details.resultPreview : \"(no output)\",\n\t\tsessionLine ? \"\" : undefined,\n\t\tsessionLine,\n\t]\n\t\t.filter((line) => line !== undefined)\n\t\t.join(\"\\n\");\n}\n\nexport function parseSubagentNotifyContent(content: string): SubagentNotifyDetails | undefined {\n\tconst lines = content.split(\"\\n\");\n\tconst match = (lines[0] ?? \"\").match(/^(Background task|Detached foreground task) (completed|failed|paused|stopped): \\*\\*(.+?)\\*\\*(?:\\s+(\\([^)]*\\)))?$/);\n\tif (!match) return undefined;\n\tconst body = lines.slice(2);\n\tlet sessionIndex = -1;\n\tfor (let i = body.length - 1; i >= 1; i--) {\n\t\tif (body[i - 1]?.trim() === \"\" && /^(Session|Session file|Session share error):\\s+/.test(body[i]!)) {\n\t\t\tsessionIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;\n\tconst resultPreview = (sessionIndex >= 0 ? body.slice(0, sessionIndex) : body).join(\"\\n\").trim() || \"(no output)\";\n\tlet sessionLabel: string | undefined;\n\tlet sessionValue: string | undefined;\n\tif (sessionLine) {\n\t\tconst separator = sessionLine.indexOf(\":\");\n\t\tsessionLabel = sessionLine.slice(0, separator).toLowerCase();\n\t\tsessionValue = sessionLine.slice(separator + 1).trim();\n\t}\n\treturn {\n\t\tagent: match[3]!,\n\t\tstatus: match[2] as SubagentNotifyDetails[\"status\"],\n\t\t...(match[1] === \"Detached foreground task\" ? { source: \"foreground\" as const } : {}),\n\t\t...(match[4] ? { taskInfo: match[4] } : {}),\n\t\tresultPreview,\n\t\t...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),\n\t};\n}\n\nexport function formatGroupedCompletion(details: SubagentNotifyDetails[]): string {\n\tconst header = `Background tasks completed (${details.length}): ${details.map((d) => `**${d.agent}**${d.taskInfo ?? \"\"}`).join(\", \")}`;\n\tconst blocks: string[] = [header, \"\"];\n\tfor (let index = 0; index < details.length; index++) {\n\t\tconst detail = details[index];\n\t\tif (!detail) continue;\n\t\tconst sessionLine = formatSessionLine(detail);\n\t\tblocks.push(`${index + 1}. ${detail.agent}${detail.taskInfo ?? \"\"}`);\n\t\tblocks.push(detail.resultPreview.trim() ? detail.resultPreview : \"(no output)\");\n\t\tif (sessionLine) blocks.push(sessionLine);\n\t\tblocks.push(\"\");\n\t}\n\treturn blocks.join(\"\\n\").trimEnd();\n}\n\nfunction sendCompletion(pi: Pick<ExtensionAPI, \"sendMessage\">, details: SubagentNotifyDetails[]): void {\n\tif (details.length === 0) return;\n\tconst content = details.length === 1\n\t\t? formatSingleCompletion(details[0]!)\n\t\t: formatGroupedCompletion(details);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"subagent-notify\",\n\t\t\tcontent,\n\t\t\tdisplay: true,\n\t\t},\n\t\t{ triggerTurn: details.some((detail) => detail.status !== \"stopped\") },\n\t);\n}\n\nfunction completionBatchKey(result: SubagentResult): string {\n\tconst sessionId = typeof result.sessionId === \"string\" ? result.sessionId.trim() : \"\";\n\tif (sessionId) return `session:${sessionId}`;\n\tconst cwd = typeof result.cwd === \"string\" ? result.cwd.trim() : \"\";\n\treturn cwd ? `cwd:${cwd}` : \"unknown\";\n}\n\nexport function buildCompletionDetails(result: SubagentResult): SubagentNotifyDetails {\n\tconst agent = result.agent ?? \"unknown\";\n\tconst summary = typeof result.summary === \"string\" ? result.summary : \"\";\n\tconst paused = !result.success && (\n\t\tresult.exitCode === 0\n\t\t|| result.state === \"paused\"\n\t\t|| summary.startsWith(\"Paused after interrupt.\")\n\t);\n\tconst status = result.state === \"stopped\" ? \"stopped\" : paused ? \"paused\" : result.success ? \"completed\" : \"failed\";\n\n\tconst taskInfo =\n\t\tresult.taskIndex !== undefined && result.totalTasks !== undefined\n\t\t\t? ` (${result.taskIndex + 1}/${result.totalTasks})`\n\t\t\t: undefined;\n\n\tconst session =\n\t\tresult.shareUrl\n\t\t\t? { label: \"Session\", value: result.shareUrl }\n\t\t\t: result.shareError\n\t\t\t\t? { label: \"Session share error\", value: result.shareError }\n\t\t\t\t: result.sessionFile\n\t\t\t\t\t? { label: \"Session file\", value: result.sessionFile }\n\t\t\t\t\t: undefined;\n\n\treturn {\n\t\tagent,\n\t\tstatus,\n\t\t...(result.source ? { source: result.source } : {}),\n\t\t...(taskInfo ? { taskInfo } : {}),\n\t\tresultPreview: [\n\t\t\tresult.id ? `Run: ${result.id}` : undefined,\n\t\t\tresult.asyncDir ? `Async dir: ${result.asyncDir}` : undefined,\n\t\t\tresult.results?.length\n\t\t\t\t? result.results.map((child, index) => {\n\t\t\t\t\tconst output = child.summary ?? (child.error ? `${child.error}\\n\\nOutput:\\n${child.output}` : child.output);\n\t\t\t\t\tconst report = child.acceptance?.childReport;\n\t\t\t\t\tconst childIndex = child.index ?? index;\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`${childIndex + 1}. ${child.agent} [${child.status ?? resolveSubagentResultStatus({ success: child.success, state: result.state })}]`,\n\t\t\t\t\t\tchild.artifactPath ? `Output artifact: ${child.artifactPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath ? `Session: ${child.sessionPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath && result.id && result.source !== \"foreground\"\n\t\t\t\t\t\t\t? `Revive: subagent({ action: \"resume\", id: ${JSON.stringify(result.id)}, index: ${childIndex}, message: \"...\" })`\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t...formatNestedResultLines(child.children),\n\t\t\t\t\t\toutput,\n\t\t\t\t\t\treport ? `\\`\\`\\`acceptance-report\\n${JSON.stringify(report, null, 2)}\\n\\`\\`\\`` : undefined,\n\t\t\t\t\t].filter((line) => line !== undefined).join(\"\\n\");\n\t\t\t\t}).join(\"\\n\\n\")\n\t\t\t\t: summary,\n\t\t].filter((line) => line !== undefined).join(\"\\n\\n\"),\n\t\t...(typeof result.durationMs === \"number\" ? { durationMs: result.durationMs } : {}),\n\t\t...(session ? { sessionLabel: session.label, sessionValue: session.value } : {}),\n\t};\n}\n\nexport default function registerSubagentNotify(\n\tpi: ExtensionAPI,\n\tstate: Pick<SubagentState, \"currentSessionId\">,\n\toptions: RegisterSubagentNotifyOptions = {},\n): () => void {\n\tlet disposed = false;\n\tconst seen = getGlobalSeenMap(\"__pi_subagents_notify_seen__\");\n\tconst ttlMs = 10 * 60 * 1000;\n\tconst nowFn = options.now ?? Date.now;\n\tconst batchConfig = resolveCompletionBatchConfig(options.batchConfig);\n\tconst batchers = new Map<string, CompletionBatcher<SubagentNotifyDetails>>();\n\tconst handleComplete = (data: unknown) => {\n\t\tif (disposed) return;\n\t\tconst result = data as SubagentResult;\n\t\tif (typeof result.sessionId !== \"string\" || result.sessionId !== state.currentSessionId) return;\n\t\tconst now = nowFn();\n\t\tconst key = `${result.sessionId}:${buildCompletionKey(result, \"notify\")}`;\n\t\tif (markSeenWithTtl(seen, key, now, ttlMs)) return;\n\n\t\tconst details = buildCompletionDetails(result);\n\t\tif (result.source === \"foreground\") {\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tconst batchKey = completionBatchKey(result);\n\t\tlet batcher = batchers.get(batchKey);\n\t\tif (!batcher) {\n\t\t\tbatcher = createCompletionBatcher<SubagentNotifyDetails>({\n\t\t\t\tconfig: batchConfig,\n\t\t\t\temit: (items) => {\n\t\t\t\t\tif (!disposed && result.sessionId === state.currentSessionId) sendCompletion(pi, items);\n\t\t\t\t},\n\t\t\t\t...(options.timers ? { timers: options.timers } : {}),\n\t\t\t\tnow: nowFn,\n\t\t\t});\n\t\t\tbatchers.set(batchKey, batcher);\n\t\t}\n\t\tif (details.status !== \"completed\") {\n\t\t\t// Failures and paused runs bypass grouping. Flush any held\n\t\t\t// successes for the same owner first so they are not stranded\n\t\t\t// behind this signal, then emit the non-completion result immediately.\n\t\t\tbatcher.flush();\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tbatcher.push(details);\n\t};\n\n\tconst unsubscribers = [\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_FOREGROUND_COMPLETE_EVENT, handleComplete),\n\t].filter((unsubscribe): unsubscribe is () => void => typeof unsubscribe === \"function\");\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tfor (const batcher of batchers.values()) batcher.dispose();\n\t\tbatchers.clear();\n\t\tfor (const unsubscribe of unsubscribers) unsubscribe();\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/background/notify.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Subagent completion notifications.\n *\n * Successful (completed) async results are held briefly and emitted as a\n * single grouped message when sibling jobs finish within a short window (see\n * `completion-batcher.ts`). Failed and paused results bypass grouping and fire\n * immediately, flushing any held successes first, so failure and attention\n * signals are never delayed.\n */\n\nimport type { ExtensionAPI } from \"@ashx-j/lunr\";\nimport { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from \"./completion-dedupe.ts\";\nimport {\n\ttype CompletionBatchConfig,\n\ttype CompletionBatcher,\n\tcreateCompletionBatcher,\n\tresolveCompletionBatchConfig,\n} from \"./completion-batcher.ts\";\nimport { formatNestedResultLines, resolveSubagentResultStatus } from \"../../intercom/result-intercom.ts\";\nimport { SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT, type AcceptanceLedger, type SubagentResultIntercomChild, type SubagentState } from \"../../shared/types.ts\";\n\ninterface ChainStepResult extends Partial<SubagentResultIntercomChild> {\n\tagent: string;\n\tchildId?: string;\n\tsessionFile?: string;\n\tusage?: import(\"../../shared/types.ts\").Usage;\n\tusageRequests?: import(\"../../../../../core/usage-accounting.ts\").AccountedRequest[];\n\toutput: string;\n\tsummary?: string;\n\terror?: string;\n\tacceptance?: AcceptanceLedger;\n\tsuccess: boolean;\n}\n\nexport interface SubagentNotifyDetails {\n\tagent: string;\n\tchildren?: ChainStepResult[];\n\tstatus: \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsource?: \"async\" | \"foreground\";\n\ttaskInfo?: string;\n\tresultPreview: string;\n\tdurationMs?: number;\n\tsessionLabel?: string;\n\tsessionValue?: string;\n}\n\ninterface SubagentResult {\n\tid: string | null;\n\tsource?: \"async\" | \"foreground\";\n\tagent: string | null;\n\tsuccess: boolean;\n\tsummary: string;\n\texitCode?: number;\n\tstate?: string;\n\ttimestamp: number;\n\tdurationMs?: number;\n\tcwd?: string;\n\tasyncDir?: string;\n\tsessionFile?: string;\n\tshareUrl?: string;\n\tgistUrl?: string;\n\tshareError?: string;\n\tresults?: ChainStepResult[];\n\ttaskIndex?: number;\n\ttotalTasks?: number;\n\tsessionId?: string | null;\n}\n\ninterface NotifyTimerApi {\n\tsetTimeout(handler: () => void, delayMs: number): unknown;\n\tclearTimeout(handle: unknown): void;\n}\n\nexport interface RegisterSubagentNotifyOptions {\n\tbatchConfig?: CompletionBatchConfig;\n\ttimers?: NotifyTimerApi;\n\tnow?: () => number;\n}\n\nfunction formatSessionLine(details: SubagentNotifyDetails): string | undefined {\n\tif (!details.sessionValue) return undefined;\n\treturn details.sessionLabel ? `${details.sessionLabel}: ${details.sessionValue}` : details.sessionValue;\n}\n\nexport function formatSingleCompletion(details: SubagentNotifyDetails): string {\n\tconst sessionLine = formatSessionLine(details);\n\tconst taskKind = details.source === \"foreground\" ? \"Detached foreground task\" : \"Background task\";\n\treturn [\n\t\t`${taskKind} ${details.status}: **${details.agent}**${details.taskInfo ?? \"\"}`,\n\t\t\"\",\n\t\tdetails.resultPreview.trim() ? details.resultPreview : \"(no output)\",\n\t\tsessionLine ? \"\" : undefined,\n\t\tsessionLine,\n\t]\n\t\t.filter((line) => line !== undefined)\n\t\t.join(\"\\n\");\n}\n\nexport function parseSubagentNotifyContent(content: string): SubagentNotifyDetails | undefined {\n\tconst lines = content.split(\"\\n\");\n\tconst match = (lines[0] ?? \"\").match(/^(Background task|Detached foreground task) (completed|failed|paused|stopped): \\*\\*(.+?)\\*\\*(?:\\s+(\\([^)]*\\)))?$/);\n\tif (!match) return undefined;\n\tconst body = lines.slice(2);\n\tlet sessionIndex = -1;\n\tfor (let i = body.length - 1; i >= 1; i--) {\n\t\tif (body[i - 1]?.trim() === \"\" && /^(Session|Session file|Session share error):\\s+/.test(body[i]!)) {\n\t\t\tsessionIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst sessionLine = sessionIndex >= 0 ? body[sessionIndex] : undefined;\n\tconst resultPreview = (sessionIndex >= 0 ? body.slice(0, sessionIndex) : body).join(\"\\n\").trim() || \"(no output)\";\n\tlet sessionLabel: string | undefined;\n\tlet sessionValue: string | undefined;\n\tif (sessionLine) {\n\t\tconst separator = sessionLine.indexOf(\":\");\n\t\tsessionLabel = sessionLine.slice(0, separator).toLowerCase();\n\t\tsessionValue = sessionLine.slice(separator + 1).trim();\n\t}\n\treturn {\n\t\tagent: match[3]!,\n\t\tstatus: match[2] as SubagentNotifyDetails[\"status\"],\n\t\t...(match[1] === \"Detached foreground task\" ? { source: \"foreground\" as const } : {}),\n\t\t...(match[4] ? { taskInfo: match[4] } : {}),\n\t\tresultPreview,\n\t\t...(sessionLabel && sessionValue ? { sessionLabel, sessionValue } : {}),\n\t};\n}\n\nexport function formatGroupedCompletion(details: SubagentNotifyDetails[]): string {\n\tconst header = `Background tasks completed (${details.length}): ${details.map((d) => `**${d.agent}**${d.taskInfo ?? \"\"}`).join(\", \")}`;\n\tconst blocks: string[] = [header, \"\"];\n\tfor (let index = 0; index < details.length; index++) {\n\t\tconst detail = details[index];\n\t\tif (!detail) continue;\n\t\tconst sessionLine = formatSessionLine(detail);\n\t\tblocks.push(`${index + 1}. ${detail.agent}${detail.taskInfo ?? \"\"}`);\n\t\tblocks.push(detail.resultPreview.trim() ? detail.resultPreview : \"(no output)\");\n\t\tif (sessionLine) blocks.push(sessionLine);\n\t\tblocks.push(\"\");\n\t}\n\treturn blocks.join(\"\\n\").trimEnd();\n}\n\nfunction sendCompletion(pi: Pick<ExtensionAPI, \"sendMessage\">, details: SubagentNotifyDetails[]): void {\n\tif (details.length === 0) return;\n\tconst content = details.length === 1\n\t\t? formatSingleCompletion(details[0]!)\n\t\t: formatGroupedCompletion(details);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"subagent-notify\",\n\t\t\tcontent,\n\t\t\tdisplay: true,\n\t\t\tdetails: { children: details.flatMap((detail) => detail.children ?? []) },\n\t\t},\n\t\t{ triggerTurn: details.some((detail) => detail.status !== \"stopped\") },\n\t);\n}\n\nfunction completionBatchKey(result: SubagentResult): string {\n\tconst sessionId = typeof result.sessionId === \"string\" ? result.sessionId.trim() : \"\";\n\tif (sessionId) return `session:${sessionId}`;\n\tconst cwd = typeof result.cwd === \"string\" ? result.cwd.trim() : \"\";\n\treturn cwd ? `cwd:${cwd}` : \"unknown\";\n}\n\nexport function buildCompletionDetails(result: SubagentResult): SubagentNotifyDetails {\n\tconst agent = result.agent ?? \"unknown\";\n\tconst summary = typeof result.summary === \"string\" ? result.summary : \"\";\n\tconst paused = !result.success && (\n\t\tresult.exitCode === 0\n\t\t|| result.state === \"paused\"\n\t\t|| summary.startsWith(\"Paused after interrupt.\")\n\t);\n\tconst status = result.state === \"stopped\" ? \"stopped\" : paused ? \"paused\" : result.success ? \"completed\" : \"failed\";\n\n\tconst taskInfo =\n\t\tresult.taskIndex !== undefined && result.totalTasks !== undefined\n\t\t\t? ` (${result.taskIndex + 1}/${result.totalTasks})`\n\t\t\t: undefined;\n\n\tconst session =\n\t\tresult.shareUrl\n\t\t\t? { label: \"Session\", value: result.shareUrl }\n\t\t\t: result.shareError\n\t\t\t\t? { label: \"Session share error\", value: result.shareError }\n\t\t\t\t: result.sessionFile\n\t\t\t\t\t? { label: \"Session file\", value: result.sessionFile }\n\t\t\t\t\t: undefined;\n\n\treturn {\n\t\tagent,\n\t\tstatus,\n\t\tchildren: result.results?.map((child, index) => ({ ...child, childId: child.childId ?? `${result.id}:${index}` })),\n\t\t...(result.source ? { source: result.source } : {}),\n\t\t...(taskInfo ? { taskInfo } : {}),\n\t\tresultPreview: [\n\t\t\tresult.id ? `Run: ${result.id}` : undefined,\n\t\t\tresult.asyncDir ? `Async dir: ${result.asyncDir}` : undefined,\n\t\t\tresult.results?.length\n\t\t\t\t? result.results.map((child, index) => {\n\t\t\t\t\tconst output = child.summary ?? (child.error ? `${child.error}\\n\\nOutput:\\n${child.output}` : child.output);\n\t\t\t\t\tconst report = child.acceptance?.childReport;\n\t\t\t\t\tconst childIndex = child.index ?? index;\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`${childIndex + 1}. ${child.agent} [${child.status ?? resolveSubagentResultStatus({ success: child.success, state: result.state })}]`,\n\t\t\t\t\t\tchild.artifactPath ? `Output artifact: ${child.artifactPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath ? `Session: ${child.sessionPath}` : undefined,\n\t\t\t\t\t\tchild.sessionPath && result.id && result.source !== \"foreground\"\n\t\t\t\t\t\t\t? `Revive: subagent({ action: \"resume\", id: ${JSON.stringify(result.id)}, index: ${childIndex}, message: \"...\" })`\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t...formatNestedResultLines(child.children),\n\t\t\t\t\t\toutput,\n\t\t\t\t\t\treport ? `\\`\\`\\`acceptance-report\\n${JSON.stringify(report, null, 2)}\\n\\`\\`\\`` : undefined,\n\t\t\t\t\t].filter((line) => line !== undefined).join(\"\\n\");\n\t\t\t\t}).join(\"\\n\\n\")\n\t\t\t\t: summary,\n\t\t].filter((line) => line !== undefined).join(\"\\n\\n\"),\n\t\t...(typeof result.durationMs === \"number\" ? { durationMs: result.durationMs } : {}),\n\t\t...(session ? { sessionLabel: session.label, sessionValue: session.value } : {}),\n\t};\n}\n\nexport default function registerSubagentNotify(\n\tpi: ExtensionAPI,\n\tstate: Pick<SubagentState, \"currentSessionId\">,\n\toptions: RegisterSubagentNotifyOptions = {},\n): () => void {\n\tlet disposed = false;\n\tconst seen = getGlobalSeenMap(\"__pi_subagents_notify_seen__\");\n\tconst ttlMs = 10 * 60 * 1000;\n\tconst nowFn = options.now ?? Date.now;\n\tconst batchConfig = resolveCompletionBatchConfig(options.batchConfig);\n\tconst batchers = new Map<string, CompletionBatcher<SubagentNotifyDetails>>();\n\tconst handleComplete = (data: unknown) => {\n\t\tif (disposed) return;\n\t\tconst result = data as SubagentResult;\n\t\tif (typeof result.sessionId !== \"string\" || result.sessionId !== state.currentSessionId) return;\n\t\tconst now = nowFn();\n\t\tconst key = `${result.sessionId}:${buildCompletionKey(result, \"notify\")}`;\n\t\tif (markSeenWithTtl(seen, key, now, ttlMs)) return;\n\n\t\tconst details = buildCompletionDetails(result);\n\t\tif (result.source === \"foreground\") {\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tconst batchKey = completionBatchKey(result);\n\t\tlet batcher = batchers.get(batchKey);\n\t\tif (!batcher) {\n\t\t\tbatcher = createCompletionBatcher<SubagentNotifyDetails>({\n\t\t\t\tconfig: batchConfig,\n\t\t\t\temit: (items) => {\n\t\t\t\t\tif (!disposed && result.sessionId === state.currentSessionId) sendCompletion(pi, items);\n\t\t\t\t},\n\t\t\t\t...(options.timers ? { timers: options.timers } : {}),\n\t\t\t\tnow: nowFn,\n\t\t\t});\n\t\t\tbatchers.set(batchKey, batcher);\n\t\t}\n\t\tif (details.status !== \"completed\") {\n\t\t\t// Failures and paused runs bypass grouping. Flush any held\n\t\t\t// successes for the same owner first so they are not stranded\n\t\t\t// behind this signal, then emit the non-completion result immediately.\n\t\t\tbatcher.flush();\n\t\t\tsendCompletion(pi, [details]);\n\t\t\treturn;\n\t\t}\n\t\tbatcher.push(details);\n\t};\n\n\tconst unsubscribers = [\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_FOREGROUND_COMPLETE_EVENT, handleComplete),\n\t].filter((unsubscribe): unsubscribe is () => void => typeof unsubscribe === \"function\");\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tfor (const batcher of batchers.values()) batcher.dispose();\n\t\tbatchers.clear();\n\t\tfor (const unsubscribe of unsubscribers) unsubscribe();\n\t};\n}\n"]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Message } from "@ashx-j/lunr-ai";
|
|
2
|
-
import { type ArtifactConfig, type ArtifactPaths, type ChainOutputMap, type ModelAttempt, type NestedRouteInfo, type ResolvedTurnBudget, type ToolBudgetState, type TurnBudgetState } from "../../shared/types.ts";
|
|
2
|
+
import { type ArtifactConfig, type ArtifactPaths, type ChainOutputMap, type ModelAttempt, type NestedRouteInfo, type ResolvedTurnBudget, type ToolBudgetState, type TurnBudgetState, type Usage } from "../../shared/types.ts";
|
|
3
3
|
import { type RunnerSubagentStep as SubagentStep } from "../shared/parallel-utils.ts";
|
|
4
4
|
interface ChildUsage {
|
|
5
|
+
measurement?: "reported" | "partial" | "estimated" | "unknown";
|
|
6
|
+
costSource?: "reported" | "estimated" | "unknown";
|
|
5
7
|
input?: number;
|
|
6
8
|
inputTokens?: number;
|
|
7
9
|
output?: number;
|
|
@@ -92,6 +94,8 @@ export declare function runSingleStep(step: SubagentStep, ctx: SingleStepContext
|
|
|
92
94
|
toolBudget?: ToolBudgetState;
|
|
93
95
|
toolBudgetBlocked?: boolean;
|
|
94
96
|
sessionFile?: string;
|
|
97
|
+
receiptUsage?: Usage;
|
|
98
|
+
usageRequests?: import("../../../../../core/usage-accounting.ts").AccountedRequest[];
|
|
95
99
|
intercomTarget?: string;
|
|
96
100
|
completionGuardTriggered?: boolean;
|
|
97
101
|
structuredOutput?: unknown;
|