pi-fabric 0.116.1 → 0.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{chunk-HZGQ7XYM.js → chunk-3FJUP3GV.js} +2 -2
- package/dist/chunks/{chunk-U2UBUKNQ.js → chunk-3UGN25XS.js} +2 -2
- package/dist/chunks/{chunk-2UZIQQ7P.js → chunk-5UBRGTVN.js} +7 -7
- package/dist/chunks/{chunk-4GNFBZPR.js → chunk-ASSLHWZS.js} +2 -2
- package/dist/chunks/{chunk-DLXPTBPL.js → chunk-AV36PBKH.js} +9 -1
- package/dist/chunks/chunk-AV36PBKH.js.map +7 -0
- package/dist/chunks/{chunk-QGP7AY2R.js → chunk-C7Z6F3SO.js} +2 -2
- package/dist/chunks/{chunk-7EYJE4TW.js → chunk-EKODKR6Y.js} +55 -6
- package/dist/chunks/chunk-EKODKR6Y.js.map +7 -0
- package/dist/chunks/{chunk-4GGBND7V.js → chunk-FSYAGCGA.js} +2 -2
- package/dist/chunks/{chunk-PTZ5DKAB.js → chunk-G54PEZ44.js} +4 -3
- package/dist/chunks/chunk-G54PEZ44.js.map +7 -0
- package/dist/chunks/{chunk-7C5IEIQK.js → chunk-GEQMQVNS.js} +2 -2
- package/dist/chunks/{chunk-MOJBW5X2.js → chunk-GO32KSEZ.js} +5 -3
- package/dist/chunks/chunk-GO32KSEZ.js.map +7 -0
- package/dist/chunks/{chunk-BQWJ5ZR7.js → chunk-K7J2ABAZ.js} +3 -3
- package/dist/chunks/{chunk-HQXCRJHU.js → chunk-LEU5CDSL.js} +2 -2
- package/dist/chunks/{chunk-O55AYN4I.js → chunk-UOM37PE4.js} +3 -3
- package/dist/chunks/{chunk-EQYQICUY.js → chunk-UXIBKMUM.js} +3 -3
- package/dist/chunks/{chunk-HD4P4FNE.js → chunk-X4HNDAZS.js} +312 -33
- package/dist/chunks/chunk-X4HNDAZS.js.map +7 -0
- package/dist/chunks/{chunk-4DENE7WN.js → chunk-XWWV6TKV.js} +2 -2
- package/dist/chunks/{chunk-YG7JJEEE.js → chunk-ZPPNWB64.js} +2 -2
- package/dist/commands/fabric.d.ts.map +1 -1
- package/dist/components/configuration.js +4 -4
- package/dist/extension-bootstrap.js +9 -9
- package/dist/fabric-runtime-state.js +9 -9
- package/dist/index.js +9 -9
- package/dist/jev/client.js +3 -3
- package/dist/jev/decision-types.d.ts +16 -0
- package/dist/jev/decision-types.d.ts.map +1 -1
- package/dist/jev/guest-types.d.ts +1 -1
- package/dist/jev/guest-types.d.ts.map +1 -1
- package/dist/jev/observation.js +3 -3
- package/dist/jev/routes.d.ts +1 -1
- package/dist/jev/routes.d.ts.map +1 -1
- package/dist/jev.js +7 -7
- package/dist/providers/jev-provider.js +7 -7
- package/dist/residency/host.js +5 -5
- package/dist/residency/pi-entry.js +5 -5
- package/dist/runtime/core-override-guest-types.js +2 -2
- package/dist/runtime/guest-types.d.ts +1 -1
- package/dist/runtime/guest-types.d.ts.map +1 -1
- package/dist/runtime/guest-types.js +1 -1
- package/dist/runtime/monty-runtime.js +3 -3
- package/dist/runtime/typescript-kernel.js +2 -2
- package/dist/type-error-guidance.js +1 -1
- package/dist/ui/controller.d.ts +2 -0
- package/dist/ui/controller.d.ts.map +1 -1
- package/dist/ui/conversation.js +1 -1
- package/dist/ui/dashboard-detail.d.ts.map +1 -1
- package/dist/ui/dashboard.js +6 -5
- package/dist/ui/dashboard.js.map +2 -2
- package/dist/ui/settings.js +3 -3
- package/dist/ui/transcript-parser.d.ts.map +1 -1
- package/dist/ui/transcript-reader.d.ts +1 -0
- package/dist/ui/transcript-reader.d.ts.map +1 -1
- package/dist/ui/transcript-sanitization.d.ts +2 -0
- package/dist/ui/transcript-sanitization.d.ts.map +1 -1
- package/dist/ui/transcript.d.ts +1 -1
- package/dist/ui/transcript.d.ts.map +1 -1
- package/dist/ui/widget-activity.d.ts +21 -0
- package/dist/ui/widget-activity.d.ts.map +1 -0
- package/dist/ui/widget.d.ts +40 -3
- package/dist/ui/widget.d.ts.map +1 -1
- package/docs/configuration.md +1 -1
- package/docs/interface.md +4 -0
- package/docs/jev.md +2 -2
- package/package.json +2 -2
- package/dist/chunks/chunk-7EYJE4TW.js.map +0 -7
- package/dist/chunks/chunk-DLXPTBPL.js.map +0 -7
- package/dist/chunks/chunk-HD4P4FNE.js.map +0 -7
- package/dist/chunks/chunk-MOJBW5X2.js.map +0 -7
- package/dist/chunks/chunk-PTZ5DKAB.js.map +0 -7
- /package/dist/chunks/{chunk-HZGQ7XYM.js.map → chunk-3FJUP3GV.js.map} +0 -0
- /package/dist/chunks/{chunk-U2UBUKNQ.js.map → chunk-3UGN25XS.js.map} +0 -0
- /package/dist/chunks/{chunk-2UZIQQ7P.js.map → chunk-5UBRGTVN.js.map} +0 -0
- /package/dist/chunks/{chunk-4GNFBZPR.js.map → chunk-ASSLHWZS.js.map} +0 -0
- /package/dist/chunks/{chunk-QGP7AY2R.js.map → chunk-C7Z6F3SO.js.map} +0 -0
- /package/dist/chunks/{chunk-4GGBND7V.js.map → chunk-FSYAGCGA.js.map} +0 -0
- /package/dist/chunks/{chunk-7C5IEIQK.js.map → chunk-GEQMQVNS.js.map} +0 -0
- /package/dist/chunks/{chunk-BQWJ5ZR7.js.map → chunk-K7J2ABAZ.js.map} +0 -0
- /package/dist/chunks/{chunk-HQXCRJHU.js.map → chunk-LEU5CDSL.js.map} +0 -0
- /package/dist/chunks/{chunk-O55AYN4I.js.map → chunk-UOM37PE4.js.map} +0 -0
- /package/dist/chunks/{chunk-EQYQICUY.js.map → chunk-UXIBKMUM.js.map} +0 -0
- /package/dist/chunks/{chunk-4DENE7WN.js.map → chunk-XWWV6TKV.js.map} +0 -0
- /package/dist/chunks/{chunk-YG7JJEEE.js.map → chunk-ZPPNWB64.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PI_CORE_COMPATIBILITY_ARGUMENT_TYPE_NAMES,
|
|
3
3
|
PI_CORE_NUMERIC_FIELDS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GO32KSEZ.js";
|
|
5
5
|
import {
|
|
6
6
|
PI_CORE_TOOL_NAMES
|
|
7
7
|
} from "./chunk-YU62DDKK.js";
|
|
@@ -284,4 +284,4 @@ var buildCoreOverrideGuestDeclarations = (sources) => {
|
|
|
284
284
|
export {
|
|
285
285
|
buildCoreOverrideGuestDeclarations
|
|
286
286
|
};
|
|
287
|
-
//# sourceMappingURL=chunk-
|
|
287
|
+
//# sourceMappingURL=chunk-3FJUP3GV.js.map
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
selectPreviewTextLines,
|
|
18
18
|
shouldSkipWriteDiffBytes,
|
|
19
19
|
shouldSkipWriteDiffComplexity
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EKODKR6Y.js";
|
|
21
21
|
import {
|
|
22
22
|
fabricStringLiterals
|
|
23
23
|
} from "./chunk-SZUXWOO7.js";
|
|
@@ -4196,4 +4196,4 @@ export {
|
|
|
4196
4196
|
formatJsonAsYaml,
|
|
4197
4197
|
formatFabricValue
|
|
4198
4198
|
};
|
|
4199
|
-
//# sourceMappingURL=chunk-
|
|
4199
|
+
//# sourceMappingURL=chunk-3UGN25XS.js.map
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JevClient,
|
|
3
3
|
JevCredentials
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UXIBKMUM.js";
|
|
5
5
|
import {
|
|
6
6
|
checkObserve,
|
|
7
7
|
jevObserveSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LEU5CDSL.js";
|
|
9
9
|
import {
|
|
10
10
|
JevBilledError,
|
|
11
11
|
checkSchema,
|
|
12
12
|
checkValue,
|
|
13
13
|
jsonText,
|
|
14
14
|
object
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-FSYAGCGA.js";
|
|
16
16
|
import {
|
|
17
17
|
validationMessage
|
|
18
18
|
} from "./chunk-G4TLWHRS.js";
|
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
ApprovalController,
|
|
24
24
|
FabricAutoApprovalClassifier,
|
|
25
25
|
FabricSessionApprovals
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-UOM37PE4.js";
|
|
27
27
|
import {
|
|
28
28
|
DECISION_APIS,
|
|
29
29
|
DECISION_MAX_BYTES
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-GEQMQVNS.js";
|
|
31
31
|
import {
|
|
32
32
|
resolveJevModelRoute
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-G54PEZ44.js";
|
|
34
34
|
|
|
35
35
|
// src/providers/jev-provider.ts
|
|
36
36
|
import { Type as Type2 } from "typebox";
|
|
@@ -851,4 +851,4 @@ export {
|
|
|
851
851
|
JEV_ACTION_DESCRIPTORS,
|
|
852
852
|
JevProvider
|
|
853
853
|
};
|
|
854
|
-
//# sourceMappingURL=chunk-
|
|
854
|
+
//# sourceMappingURL=chunk-5UBRGTVN.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
writeJsonAtomic
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-K7J2ABAZ.js";
|
|
4
4
|
import {
|
|
5
5
|
stableJsonHash
|
|
6
6
|
} from "./chunk-3YZUQESG.js";
|
|
@@ -131,4 +131,4 @@ export {
|
|
|
131
131
|
FabricComponentConfiguration,
|
|
132
132
|
watchComponentConfiguration
|
|
133
133
|
};
|
|
134
|
-
//# sourceMappingURL=chunk-
|
|
134
|
+
//# sourceMappingURL=chunk-ASSLHWZS.js.map
|
|
@@ -35,6 +35,13 @@ var contentText = (value) => {
|
|
|
35
35
|
if (record.content !== void 0) return contentText(record.content);
|
|
36
36
|
return "";
|
|
37
37
|
};
|
|
38
|
+
var contentThinking = (value) => {
|
|
39
|
+
if (!Array.isArray(value)) return "";
|
|
40
|
+
return value.map((part) => {
|
|
41
|
+
const record = recordOf(part);
|
|
42
|
+
return record?.type === "thinking" && typeof record.thinking === "string" ? record.thinking : "";
|
|
43
|
+
}).filter(Boolean).join("\n");
|
|
44
|
+
};
|
|
38
45
|
var messageError = (message) => {
|
|
39
46
|
if (message.role !== "assistant" || message.stopReason !== "error") return "";
|
|
40
47
|
const details = [];
|
|
@@ -142,10 +149,11 @@ export {
|
|
|
142
149
|
terminalSafe,
|
|
143
150
|
clip,
|
|
144
151
|
contentText,
|
|
152
|
+
contentThinking,
|
|
145
153
|
messageError,
|
|
146
154
|
redact,
|
|
147
155
|
redactRecord,
|
|
148
156
|
compactRedactedValue,
|
|
149
157
|
unwrapActorEnvelopeText
|
|
150
158
|
};
|
|
151
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-AV36PBKH.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/transcript-sanitization.ts", "../../src/ui/conversation-transcript.ts"],
|
|
4
|
+
"sourcesContent": ["const MAX_TOOL_SUMMARY_CHARS = 500;\nconst MAX_ENCODED_STRING_CHARS = 160;\nconst MAX_TRANSCRIPT_VALUE_CHARS = 40_000;\nconst MAX_TRANSCRIPT_STRING_CHARS = 12_000;\nconst MAX_TRANSCRIPT_VALUE_NODES = 400;\nconst secretKey = /authorization|api[-_]?key|token|password|secret|cookie|credential|private[-_]?key/i;\n\ninterface RedactionBudget {\n chars: number;\n nodes: number;\n}\n\nexport const recordOf = (value: unknown): Record<string, unknown> | undefined =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n\nexport const terminalSafe = (value: string, trim = true): string => {\n const safe = value\n .replace(/\\x1b\\][^\\x07]*(?:\\x07|\\x1b\\\\)/g, \"\")\n .replace(/\\x1b\\[[0-?]*[ -/]*[@-~]/g, \"\")\n .replace(/[\\u202a-\\u202e\\u2066-\\u2069\\u200e\\u200f]/gi, \"\")\n .replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]/g, \" \")\n .replace(/\\r\\n?/g, \"\\n\");\n return trim ? safe.trim() : safe;\n};\n\nconst graphemeSegmenter = Intl.Segmenter\n ? new Intl.Segmenter(undefined, { granularity: \"grapheme\" })\n : undefined;\n\nconst graphemes = (value: string): string[] =>\n graphemeSegmenter\n ? [...graphemeSegmenter.segment(value)].map((entry) => entry.segment)\n : Array.from(value);\n\nexport const clip = (value: string, max: number, trim = true): string => {\n const normalized = terminalSafe(value, trim);\n if (normalized.length <= max) return normalized;\n const parts = graphemes(normalized);\n if (parts.length <= max) return normalized;\n const tail = Math.min(1_000, Math.floor(max * 0.25));\n return `${parts.slice(0, max - tail - 2).join(\"\")}\u2026\\n${parts.slice(-tail).join(\"\")}`;\n};\n\nexport const contentText = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) {\n return value\n .map((part) => {\n const record = recordOf(part);\n return record?.type === \"text\" && typeof record.text === \"string\" ? record.text : \"\";\n })\n .filter(Boolean)\n .join(\"\");\n }\n const record = recordOf(value);\n if (!record) return \"\";\n if (typeof record.text === \"string\") return record.text;\n if (record.content !== undefined) return contentText(record.content);\n return \"\";\n};\n\n/** Concatenated reasoning text from assistant `thinking` content blocks. */\nexport const contentThinking = (value: unknown): string => {\n if (!Array.isArray(value)) return \"\";\n return value\n .map((part) => {\n const record = recordOf(part);\n return record?.type === \"thinking\" && typeof record.thinking === \"string\" ? record.thinking : \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n};\n\nexport const messageError = (message: Record<string, unknown>): string => {\n if (message.role !== \"assistant\" || message.stopReason !== \"error\") return \"\";\n const details: string[] = [];\n if (typeof message.errorMessage === \"string\") details.push(message.errorMessage);\n else if (typeof message.error === \"string\") details.push(message.error);\n if (Array.isArray(message.diagnostics)) {\n for (const value of message.diagnostics) {\n const diagnostic = recordOf(value);\n const nested = recordOf(diagnostic?.error);\n const detail =\n typeof nested?.message === \"string\"\n ? nested.message\n : typeof diagnostic?.message === \"string\"\n ? diagnostic.message\n : undefined;\n if (detail) details.push(detail);\n }\n }\n return clip([...new Set(details)].join(\" \u00B7 \") || \"Agent response failed\", MAX_TOOL_SUMMARY_CHARS);\n};\n\nconst redactInlineSecrets = (value: string): string =>\n value\n .replace(/\\bBearer\\s+[A-Za-z0-9._~+\\/-]+=*/gi, \"Bearer [redacted]\")\n .replace(/\\bBasic\\s+[A-Za-z0-9+/=]{8,}/gi, \"Basic [redacted]\")\n .replace(/\\b(?:sk|pk|ghp|github_pat|xox[baprs])[-_][A-Za-z0-9_-]{12,}\\b/g, \"[redacted]\")\n .replace(\n /\\b(Authorization|Proxy-Authorization|Cookie|Set-Cookie|X-Api-Key)\\s*:\\s*[^\\r\\n;]+/gi,\n \"$1: [redacted]\",\n )\n .replace(\n /\\b([A-Z0-9_]*(?:PASSWORD|PASSWD|TOKEN|SECRET|API_KEY|ACCESS_KEY|PRIVATE_KEY|CREDENTIAL|COOKIE)[A-Z0-9_]*)\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s;&|]+)/gi,\n \"$1=[redacted]\",\n )\n .replace(\n /(--?(?:password|passwd|token|secret|api[-_]?key|access[-_]?key|credential|cookie))(?:=|\\s+)(?:\"[^\"]*\"|'[^']*'|[^\\s;&|]+)/gi,\n \"$1=[redacted]\",\n )\n .replace(/(https?:\\/\\/)[^\\s/:@]+:[^\\s/@]+@/gi, \"$1[redacted]@\");\n\nexport const redact = (\n value: unknown,\n key = \"\",\n depth = 0,\n budget: RedactionBudget = {\n chars: MAX_TRANSCRIPT_VALUE_CHARS,\n nodes: MAX_TRANSCRIPT_VALUE_NODES,\n },\n): unknown => {\n if (secretKey.test(key)) return \"[redacted]\";\n if (depth > 12) return \"[nested value]\";\n if (budget.nodes <= 0) return \"[value omitted]\";\n budget.nodes--;\n if (typeof value === \"string\") {\n const safe = terminalSafe(value, false);\n if (safe.length >= MAX_ENCODED_STRING_CHARS && /^[A-Za-z0-9+/=_-]+$/.test(safe)) {\n return `[large encoded value \u00B7 ${safe.length} chars]`;\n }\n const available = Math.max(0, Math.min(MAX_TRANSCRIPT_STRING_CHARS, budget.chars));\n if (available === 0) return \"[text omitted]\";\n const hidden = redactInlineSecrets(clip(safe, available, false));\n budget.chars = Math.max(0, budget.chars - hidden.length);\n return hidden;\n }\n if (Array.isArray(value)) {\n const entries: unknown[] = [];\n for (const entry of value) {\n if (budget.nodes <= 0) {\n entries.push(`[${value.length - entries.length} entries omitted]`);\n break;\n }\n entries.push(redact(entry, key, depth + 1, budget));\n }\n return entries;\n }\n const record = recordOf(value);\n if (!record) return value;\n const entries = Object.entries(record);\n const redacted: Record<string, unknown> = {};\n for (let index = 0; index < entries.length; index++) {\n if (budget.nodes <= 0) {\n redacted[\"\u2026\"] = `[${entries.length - index} fields omitted]`;\n break;\n }\n const [name, entry] = entries[index]!;\n redacted[name] = redact(entry, name, depth + 1, budget);\n }\n return redacted;\n};\n\nexport const redactRecord = (value: unknown): Record<string, unknown> | undefined => {\n const record = recordOf(value);\n if (!record) return undefined;\n return recordOf(redact(record));\n};\n\nexport const compactRedactedValue = (value: unknown): string => {\n try {\n return clip(JSON.stringify(value).replace(/\\s+/g, \" \"), MAX_TOOL_SUMMARY_CHARS);\n } catch {\n return clip(String(value ?? \"\").replace(/\\s+/g, \" \"), MAX_TOOL_SUMMARY_CHARS);\n }\n};\n", "import type { FabricTranscriptEntry } from \"./transcript.js\";\nimport { recordOf } from \"./transcript-sanitization.js\";\n\nconst DIRECT_ENVELOPE_PREFIX = \"Fabric actor message from direct:\";\n\n/**\n * Display-only unwrapping of a Fabric direct actor message envelope.\n *\n * Actors receive messages as `Fabric actor message from <source>:` followed by\n * a JSON envelope. When that envelope is a validated direct actor message, this\n * returns the human payload text so transcripts show a normal user bubble.\n * Everything else \u2014 ordinary user JSON, code, malformed input, host-event\n * envelopes, non-direct sources \u2014 is preserved untouched by returning undefined.\n */\nexport const unwrapActorEnvelopeText = (text: string): string | undefined => {\n if (!text.startsWith(DIRECT_ENVELOPE_PREFIX)) return undefined;\n const body = text.slice(DIRECT_ENVELOPE_PREFIX.length).trimStart();\n if (!body.startsWith(\"{\")) return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n return undefined;\n }\n const envelope = recordOf(parsed);\n if (!envelope || envelope.source !== \"direct\") return undefined;\n const payload = recordOf(envelope.payload);\n if (!payload || typeof payload.message !== \"string\") return undefined;\n const message = payload.message;\n return message.trim() ? message : undefined;\n};\n\nexport interface FocusedTranscriptView {\n /** Entries to render in the focused (collapsed) view. */\n entries: FabricTranscriptEntry[];\n /** Raw diagnostics hidden by collapse; render these when expanded. */\n hiddenDiagnostics: FabricTranscriptEntry[];\n}\n\nconst workerWarningCount = (entry: FabricTranscriptEntry): number => {\n if (entry.kind !== \"error\" || entry.label !== \"Worker stderr\" || typeof entry.text !== \"string\") return 0;\n if (entry.warningCount !== undefined) return entry.warningCount;\n const lines = entry.text.split(/\\r?\\n/).filter((line) => line.trim());\n // Never collapse a mixed warning/error chunk just because its first line is a warning.\n return lines.length > 0 && lines.every((line) => /^\\s*Warning:/.test(line)) ? lines.length : 0;\n};\n\n/**\n * Pure focused-view projection: collapses runs of worker stderr warnings into\n * one diagnostics summary entry without discarding anything \u2014 hidden originals\n * come back in `hiddenDiagnostics` so an expand toggle can render them. Real\n * errors (non-warning stderr) always stay visible.\n */\nexport const focusTranscriptDiagnostics = (\n entries: FabricTranscriptEntry[],\n expandHint = \"Ctrl+O\",\n): FocusedTranscriptView => {\n const focused: FabricTranscriptEntry[] = [];\n const hidden: FabricTranscriptEntry[] = [];\n let run: FabricTranscriptEntry[] = [];\n\n const flushRun = (): void => {\n if (run.length === 0) return;\n const count = run.reduce((sum, entry) => sum + workerWarningCount(entry), 0);\n if (count === 1) {\n focused.push(run[0]!);\n } else {\n focused.push({\n id: `diagnostics-${run[0]!.id}`,\n kind: \"status\",\n label: \"Diagnostics\",\n text: `${count} worker warnings collapsed (${expandHint} to expand)`,\n status: \"completed\",\n });\n hidden.push(...run);\n }\n run = [];\n };\n\n for (const entry of entries) {\n if (workerWarningCount(entry) > 0) run.push(entry);\n else {\n flushRun();\n focused.push(entry);\n }\n }\n flushRun();\n return { entries: focused, hiddenDiagnostics: hidden };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["record", "entries"]
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
headlineArg,
|
|
3
3
|
truncateMiddle
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EKODKR6Y.js";
|
|
5
5
|
import {
|
|
6
6
|
CONFIG_DIR_NAME
|
|
7
7
|
} from "./chunk-PBDDXBHY.js";
|
|
@@ -1843,4 +1843,4 @@ export {
|
|
|
1843
1843
|
captureLoadedFileIdentity,
|
|
1844
1844
|
runtimeIdentityStatus
|
|
1845
1845
|
};
|
|
1846
|
-
//# sourceMappingURL=chunk-
|
|
1846
|
+
//# sourceMappingURL=chunk-C7Z6F3SO.js.map
|
|
@@ -2,13 +2,14 @@ import {
|
|
|
2
2
|
clip,
|
|
3
3
|
compactRedactedValue,
|
|
4
4
|
contentText,
|
|
5
|
+
contentThinking,
|
|
5
6
|
messageError,
|
|
6
7
|
recordOf,
|
|
7
8
|
redact,
|
|
8
9
|
redactRecord,
|
|
9
10
|
terminalSafe,
|
|
10
11
|
unwrapActorEnvelopeText
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AV36PBKH.js";
|
|
12
13
|
import {
|
|
13
14
|
readJsonlPageFromDescriptor
|
|
14
15
|
} from "./chunk-CGPK5WHX.js";
|
|
@@ -117,6 +118,7 @@ var TranscriptAccumulator = class {
|
|
|
117
118
|
#anonymousTools = /* @__PURE__ */ new Map();
|
|
118
119
|
#activeTools = [];
|
|
119
120
|
#assistant;
|
|
121
|
+
#thinking;
|
|
120
122
|
#retry;
|
|
121
123
|
#compaction;
|
|
122
124
|
#userMessages = /* @__PURE__ */ new Map();
|
|
@@ -141,7 +143,30 @@ var TranscriptAccumulator = class {
|
|
|
141
143
|
if (typeof event.id === "string") return event.id;
|
|
142
144
|
return `${prefix}-${this.#sequence++}`;
|
|
143
145
|
}
|
|
146
|
+
/** Keep the latest assistant reasoning as one entry that grows while it streams. */
|
|
147
|
+
#trackThinking(id, content) {
|
|
148
|
+
const text = terminalSafe(contentThinking(content), false);
|
|
149
|
+
if (!text) return;
|
|
150
|
+
if (!this.#thinking) {
|
|
151
|
+
this.#thinking = {
|
|
152
|
+
id: `${id}-thinking`,
|
|
153
|
+
kind: "thinking",
|
|
154
|
+
label: "Thinking",
|
|
155
|
+
text: clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS, false),
|
|
156
|
+
status: "running"
|
|
157
|
+
};
|
|
158
|
+
this.entries.push(this.#thinking);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.#thinking.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS, false);
|
|
162
|
+
}
|
|
163
|
+
#finishThinking(status) {
|
|
164
|
+
if (!this.#thinking) return;
|
|
165
|
+
this.#thinking.status = status;
|
|
166
|
+
this.#thinking = void 0;
|
|
167
|
+
}
|
|
144
168
|
#finishAssistant(status) {
|
|
169
|
+
this.#finishThinking(status);
|
|
145
170
|
if (!this.#assistant) return;
|
|
146
171
|
this.#assistant.status = status;
|
|
147
172
|
this.#assistant = void 0;
|
|
@@ -249,6 +274,9 @@ var TranscriptAccumulator = class {
|
|
|
249
274
|
}
|
|
250
275
|
if (message.role === "assistant") {
|
|
251
276
|
const error = messageError(message);
|
|
277
|
+
this.#finishThinking("completed");
|
|
278
|
+
this.#trackThinking(id, message.content);
|
|
279
|
+
this.#finishThinking(error ? "failed" : "completed");
|
|
252
280
|
const text = contentText(message.content);
|
|
253
281
|
if (text) this.#pushMessage("assistant", id, text, error ? "failed" : "completed");
|
|
254
282
|
if (error) {
|
|
@@ -416,6 +444,14 @@ var TranscriptAccumulator = class {
|
|
|
416
444
|
});
|
|
417
445
|
return;
|
|
418
446
|
}
|
|
447
|
+
if (event.type === "message_update" && event.message === void 0) {
|
|
448
|
+
const update = recordOf(event.assistantMessageEvent);
|
|
449
|
+
if (update?.type === "thinking_delta" && typeof update.delta === "string") {
|
|
450
|
+
const previous = this.#thinking?.text ?? "";
|
|
451
|
+
this.#trackThinking(id, [{ type: "thinking", thinking: `${previous}${update.delta}` }]);
|
|
452
|
+
}
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
419
455
|
if (event.type === "message_start") this.#finishAssistant("completed");
|
|
420
456
|
if (event.type === "message_start" || event.type === "message_update") {
|
|
421
457
|
const message = recordOf(event.message);
|
|
@@ -427,6 +463,7 @@ var TranscriptAccumulator = class {
|
|
|
427
463
|
return;
|
|
428
464
|
}
|
|
429
465
|
if (message.role !== "assistant") return;
|
|
466
|
+
this.#trackThinking(id, message.content);
|
|
430
467
|
const text = terminalSafe(contentText(message.content));
|
|
431
468
|
if (!text) return;
|
|
432
469
|
if (!this.#assistant) {
|
|
@@ -452,6 +489,7 @@ var TranscriptAccumulator = class {
|
|
|
452
489
|
return;
|
|
453
490
|
}
|
|
454
491
|
if (message.role !== "assistant") return;
|
|
492
|
+
this.#trackThinking(id, message.content);
|
|
455
493
|
const error = messageError(message);
|
|
456
494
|
if (error) {
|
|
457
495
|
this.#finishAssistant("failed");
|
|
@@ -463,8 +501,10 @@ var TranscriptAccumulator = class {
|
|
|
463
501
|
this.#finishAssistant("completed");
|
|
464
502
|
return;
|
|
465
503
|
}
|
|
466
|
-
if (!this.#assistant)
|
|
467
|
-
|
|
504
|
+
if (!this.#assistant) {
|
|
505
|
+
this.#pushMessage("assistant", id, text);
|
|
506
|
+
this.#finishThinking("completed");
|
|
507
|
+
} else {
|
|
468
508
|
this.#assistant.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS);
|
|
469
509
|
this.#finishAssistant("completed");
|
|
470
510
|
}
|
|
@@ -685,6 +725,15 @@ var readForwardPage = (descriptor, start, end) => {
|
|
|
685
725
|
};
|
|
686
726
|
var AgentTranscriptReader = class {
|
|
687
727
|
#cache = /* @__PURE__ */ new Map();
|
|
728
|
+
/**
|
|
729
|
+
* Log lines per latest/older page. Streaming writes one line per delta, so a
|
|
730
|
+
* caller that needs the start of a long turn (the widget's activity pane)
|
|
731
|
+
* asks for a deeper page than the dashboard default.
|
|
732
|
+
*/
|
|
733
|
+
#pageLines;
|
|
734
|
+
constructor(pageLines = PAGE_LINES) {
|
|
735
|
+
this.#pageLines = Math.max(1, Math.floor(pageLines));
|
|
736
|
+
}
|
|
688
737
|
read(source, followLatest = true) {
|
|
689
738
|
const filePath = source.logFile;
|
|
690
739
|
if (!filePath) {
|
|
@@ -764,7 +813,7 @@ var AgentTranscriptReader = class {
|
|
|
764
813
|
const pageEnd = Math.min(cached.pageStart, completeEnd);
|
|
765
814
|
const page = readJsonlPageFromDescriptor(
|
|
766
815
|
descriptor,
|
|
767
|
-
|
|
816
|
+
this.#pageLines,
|
|
768
817
|
pageEnd,
|
|
769
818
|
stat.size,
|
|
770
819
|
MAX_PAGE_BYTES
|
|
@@ -864,7 +913,7 @@ var AgentTranscriptReader = class {
|
|
|
864
913
|
const completeEnd = knownCompleteEnd ?? completeLogEnd(descriptor, stat.size);
|
|
865
914
|
const page = readJsonlPageFromDescriptor(
|
|
866
915
|
descriptor,
|
|
867
|
-
|
|
916
|
+
this.#pageLines,
|
|
868
917
|
completeEnd,
|
|
869
918
|
stat.size,
|
|
870
919
|
MAX_PAGE_BYTES
|
|
@@ -1122,4 +1171,4 @@ export {
|
|
|
1122
1171
|
isFabricAgentToolPreview,
|
|
1123
1172
|
recentTranscriptTools
|
|
1124
1173
|
};
|
|
1125
|
-
//# sourceMappingURL=chunk-
|
|
1174
|
+
//# sourceMappingURL=chunk-EKODKR6Y.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/util.ts", "../../src/core/call-preview.ts", "../../src/ui/transcript-reader.ts", "../../src/ui/transcript-parser.ts", "../../src/ui/transcript.ts", "../../src/ui/preview-lines.ts", "../../src/providers/write-diff-limits.ts"],
|
|
4
|
+
"sourcesContent": ["export const countNewlines = (value: string): number => {\n let count = 0;\n for (let index = 0; index < value.length; index++) {\n if (value.charCodeAt(index) === 10) count++;\n }\n return count;\n};\n\nexport const truncateMiddle = (value: string, maxChars: number): string => {\n if (value.length <= maxChars) return value;\n const marker = `\\n\\n... ${value.length - maxChars} characters omitted by Pi Fabric ...\\n\\n`;\n const available = Math.max(0, maxChars - marker.length);\n const head = Math.ceil(available / 2);\n const tail = Math.floor(available / 2);\n return `${value.slice(0, head)}${marker}${value.slice(value.length - tail)}`;\n};\n", "// A shared, provider-agnostic heuristic for the one-line \"headline\" argument\n// of a nested Fabric call \u2014 the value shown beside a tool's name in the chat\n// preview (e.g. `recall <query>`) and appended to its ref in the dashboard\n// (e.g. `extensions.vcc_recall \u00B7 <query>`). Pi core tools and the first-class\n// Fabric providers (agents/mesh/mcp management) keep their bespoke, tuned\n// previews; this picks up everything else \u2014 captured extension tools and\n// arbitrary MCP tools \u2014 so they no longer render as a bare tool name.\n//\n// The key order preserves the dashboard's prior task -> path -> query ->\n// message preference for the fields it already recognized, then extends to\n// other common payload names. The final first-string fallback covers tools\n// whose argument names are unfamiliar, skipping structural/metadata keys\n// (label/title/mode/limit/...) that describe the call rather than its\n// payload. Control characters are not stripped here: the inline preview\n// already tolerates them (matching the existing task fallback) and the\n// dashboard sanitizes labels via safeText at render time.\nexport const HEADLINE_ARG_KEYS = [\n \"task\", \"path\", \"query\", \"message\", \"search\", \"pattern\", \"command\", \"text\",\n \"prompt\", \"question\", \"input\", \"content\", \"expression\", \"url\", \"topic\",\n \"key\", \"filter\", \"name\", \"q\",\n] as const;\n\nconst HEADLINE_SKIP_KEYS = new Set([\n \"label\", \"title\", \"type\", \"kind\", \"mode\", \"format\", \"resultFormat\",\n \"limit\", \"max\", \"offset\", \"start\", \"concurrency\", \"overwrite\", \"id\",\n \"provider\", \"namespace\", \"server\", \"tool\", \"ref\", \"recursive\", \"synthesize\",\n \"commandDigest\",\n]);\n\nconst cleanOneLine = (value: string, max: number): string => {\n const single = value.replace(/\\s+/g, \" \").trim();\n if (!single) return \"\";\n return single.length <= max ? single : `${single.slice(0, Math.max(1, max - 1))}\u2026`;\n};\n\n/**\n * Pick the best single-line argument value to display beside a nested call's\n * tool name, for tools that have no bespoke preview. Returns `undefined`\n * when no string payload argument is present.\n */\nexport const headlineArg = (\n args: Record<string, unknown> | undefined,\n max = 96,\n): string | undefined => {\n if (!args) return undefined;\n for (const key of HEADLINE_ARG_KEYS) {\n const value = args[key];\n if (typeof value === \"string\") {\n const cleaned = cleanOneLine(value, max);\n if (cleaned) return cleaned;\n }\n }\n for (const [key, value] of Object.entries(args)) {\n if (HEADLINE_SKIP_KEYS.has(key)) continue;\n if (typeof value === \"string\") {\n const cleaned = cleanOneLine(value, max);\n if (cleaned) return cleaned;\n }\n }\n return undefined;\n};\n", "import fs from \"node:fs\";\nimport { readJsonlPageFromDescriptor } from \"../log-tail.js\";\nimport type { FabricLogLine } from \"../agents/types.js\";\nimport {\n missingToolStartIds,\n normalizedToolStarts,\n parsedEvents,\n parseRaw,\n TranscriptAccumulator,\n} from \"./transcript-parser.js\";\nimport type { FabricAgentTranscript, FabricTranscriptSource } from \"./transcript.js\";\n\nconst PAGE_LINES = 40;\nconst TOOL_LIFECYCLE_CONTEXT_LINES = PAGE_LINES * 4;\nconst MAX_PAGE_BYTES = 512 * 1024;\nconst MAX_CACHE_ENTRIES = 32;\nconst FORWARD_READ_CHUNK_BYTES = 64 * 1024;\n\ninterface CachedTranscript {\n device: number;\n inode: number;\n modifiedAt: number;\n offset: number;\n completeEnd: number;\n pageStart: number;\n pageEnd: number;\n hasMore: boolean;\n transcript: FabricAgentTranscript;\n}\n\ninterface ForwardTranscriptPage {\n lines: FabricLogLine[];\n end: number;\n}\n\nconst completeLogEnd = (descriptor: number, size: number, fallback = 0): number => {\n if (size <= 0) return 0;\n const scanFloor = Math.max(0, size - MAX_PAGE_BYTES);\n let scanEnd = size;\n while (scanEnd > scanFloor) {\n const scanStart = Math.max(scanFloor, scanEnd - FORWARD_READ_CHUNK_BYTES);\n const chunk = Buffer.allocUnsafe(scanEnd - scanStart);\n const bytesRead = fs.readSync(descriptor, chunk, 0, chunk.length, scanStart);\n if (bytesRead <= 0) return 0;\n for (let index = bytesRead - 1; index >= 0; index--) {\n if (chunk[index] === 0x0a) return scanStart + index + 1;\n }\n scanEnd = scanStart;\n }\n return Math.min(fallback, size);\n};\n\nconst readForwardPage = (\n descriptor: number,\n start: number,\n end: number,\n): ForwardTranscriptPage => {\n const lines: FabricLogLine[] = [];\n const readLimit = Math.min(end, Math.max(0, start) + MAX_PAGE_BYTES);\n let readOffset = Math.max(0, start);\n let pending = Buffer.alloc(0);\n let pendingOffset = readOffset;\n let pageEnd = readOffset;\n\n while (readOffset < readLimit && lines.length < PAGE_LINES) {\n const chunkSize = Math.min(FORWARD_READ_CHUNK_BYTES, readLimit - readOffset);\n const chunk = Buffer.allocUnsafe(chunkSize);\n const bytesRead = fs.readSync(descriptor, chunk, 0, chunkSize, readOffset);\n if (bytesRead <= 0) break;\n const data = pending.length > 0\n ? Buffer.concat([pending, chunk.subarray(0, bytesRead)])\n : chunk.subarray(0, bytesRead);\n const dataOffset = pending.length > 0 ? pendingOffset : readOffset;\n let lineStart = 0;\n for (let index = 0; index < data.length; index++) {\n if (data[index] !== 0x0a) continue;\n const raw = data.subarray(lineStart, index).toString(\"utf8\").replace(/\\r$/, \"\");\n pageEnd = dataOffset + index + 1;\n if (raw) {\n const offset = dataOffset + lineStart;\n const parsed = parseRaw(raw);\n lines.push({ offset, raw, ...(parsed ? { parsed } : {}) });\n if (lines.length >= PAGE_LINES) return { lines, end: pageEnd };\n }\n lineStart = index + 1;\n }\n pending = Buffer.from(data.subarray(lineStart));\n pendingOffset = dataOffset + lineStart;\n readOffset += bytesRead;\n }\n\n return { lines, end: readOffset >= end ? end : pageEnd };\n};\n\nexport class AgentTranscriptReader {\n readonly #cache = new Map<string, CachedTranscript>();\n /**\n * Log lines per latest/older page. Streaming writes one line per delta, so a\n * caller that needs the start of a long turn (the widget's activity pane)\n * asks for a deeper page than the dashboard default.\n */\n readonly #pageLines: number;\n\n constructor(pageLines = PAGE_LINES) {\n this.#pageLines = Math.max(1, Math.floor(pageLines));\n }\n\n read(\n source: FabricTranscriptSource,\n followLatest = true,\n ): FabricAgentTranscript {\n const filePath = source.logFile;\n if (!filePath) {\n return { entries: [], truncated: false, hasMore: false, hasNewer: false };\n }\n const cached = this.#cache.get(filePath);\n let descriptor: number | undefined;\n try {\n const noFollow = typeof fs.constants.O_NOFOLLOW === \"number\" ? fs.constants.O_NOFOLLOW : 0;\n descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | noFollow);\n const stat = fs.fstatSync(descriptor);\n if (!stat.isFile()) {\n return cached?.transcript ?? {\n entries: [],\n truncated: false,\n hasMore: false,\n hasNewer: false,\n };\n }\n const sameFile = cached?.device === stat.dev && cached.inode === stat.ino;\n const sameSizeRewrite =\n sameFile && cached.offset === stat.size && cached.modifiedAt !== stat.mtimeMs;\n let state: CachedTranscript;\n if (!cached || !sameFile || stat.size < cached.offset || sameSizeRewrite) {\n state = this.#latestState(descriptor, stat);\n } else if (stat.size !== cached.offset || stat.mtimeMs !== cached.modifiedAt) {\n const wasAtTail = cached.pageEnd >= cached.completeEnd;\n const completeEnd = completeLogEnd(descriptor, stat.size, cached.completeEnd);\n if (\n cached.pageEnd > completeEnd ||\n (followLatest && wasAtTail && completeEnd > cached.completeEnd)\n ) {\n state = this.#latestState(descriptor, stat, completeEnd);\n } else {\n state = {\n ...cached,\n modifiedAt: stat.mtimeMs,\n offset: stat.size,\n completeEnd,\n transcript: {\n ...cached.transcript,\n hasNewer: cached.pageEnd < completeEnd,\n updatedAt: stat.mtimeMs,\n },\n };\n }\n } else {\n state = cached;\n }\n this.#remember(filePath, state);\n return state.transcript;\n } catch {\n return cached?.transcript ?? {\n entries: [],\n truncated: false,\n hasMore: false,\n hasNewer: false,\n };\n } finally {\n if (descriptor !== undefined) {\n try { fs.closeSync(descriptor); } catch {}\n }\n }\n }\n\n loadOlder(source: FabricTranscriptSource): boolean {\n const filePath = source.logFile;\n if (!filePath) return false;\n this.read(source, false);\n const cached = this.#cache.get(filePath);\n if (!cached?.hasMore || cached.pageStart <= 0) return false;\n let descriptor: number | undefined;\n try {\n const noFollow = typeof fs.constants.O_NOFOLLOW === \"number\" ? fs.constants.O_NOFOLLOW : 0;\n descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | noFollow);\n const stat = fs.fstatSync(descriptor);\n if (!stat.isFile() || stat.dev !== cached.device || stat.ino !== cached.inode) return false;\n const completeEnd = completeLogEnd(descriptor, stat.size, cached.completeEnd);\n const pageEnd = Math.min(cached.pageStart, completeEnd);\n const page = readJsonlPageFromDescriptor(\n descriptor,\n this.#pageLines,\n pageEnd,\n stat.size,\n MAX_PAGE_BYTES,\n );\n const pageStart = page.lines[0]?.offset;\n if (pageStart === undefined) return false;\n const state = this.#stateForPage(\n descriptor,\n stat,\n completeEnd,\n page.lines,\n pageStart,\n pageEnd,\n page.hasMore,\n );\n this.#remember(filePath, state);\n return true;\n } catch {\n return false;\n } finally {\n if (descriptor !== undefined) {\n try { fs.closeSync(descriptor); } catch {}\n }\n }\n }\n\n loadNewer(source: FabricTranscriptSource): boolean {\n const filePath = source.logFile;\n if (!filePath) return false;\n this.read(source, false);\n const cached = this.#cache.get(filePath);\n if (!cached || cached.pageEnd >= cached.completeEnd) return false;\n let descriptor: number | undefined;\n try {\n const noFollow = typeof fs.constants.O_NOFOLLOW === \"number\" ? fs.constants.O_NOFOLLOW : 0;\n descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | noFollow);\n const stat = fs.fstatSync(descriptor);\n if (!stat.isFile() || stat.dev !== cached.device || stat.ino !== cached.inode) return false;\n const completeEnd = completeLogEnd(descriptor, stat.size, cached.completeEnd);\n const page = readForwardPage(descriptor, cached.pageEnd, completeEnd);\n if (page.lines.length === 0 || page.end <= cached.pageEnd) return false;\n const state = this.#stateForPage(\n descriptor,\n stat,\n completeEnd,\n page.lines,\n cached.pageEnd,\n page.end,\n cached.pageEnd > 0,\n );\n this.#remember(filePath, state);\n return true;\n } catch {\n return false;\n } finally {\n if (descriptor !== undefined) {\n try { fs.closeSync(descriptor); } catch {}\n }\n }\n }\n\n loadLatest(source: FabricTranscriptSource): boolean {\n const filePath = source.logFile;\n if (!filePath) return false;\n this.read(source, false);\n const cached = this.#cache.get(filePath);\n let descriptor: number | undefined;\n try {\n const noFollow = typeof fs.constants.O_NOFOLLOW === \"number\" ? fs.constants.O_NOFOLLOW : 0;\n descriptor = fs.openSync(filePath, fs.constants.O_RDONLY | noFollow);\n const stat = fs.fstatSync(descriptor);\n if (!stat.isFile()) return false;\n if (cached && (stat.dev !== cached.device || stat.ino !== cached.inode)) return false;\n const completeEnd = completeLogEnd(descriptor, stat.size, cached?.completeEnd ?? 0);\n const state = this.#latestState(descriptor, stat, completeEnd);\n this.#remember(filePath, state);\n return true;\n } catch {\n return false;\n } finally {\n if (descriptor !== undefined) {\n try { fs.closeSync(descriptor); } catch {}\n }\n }\n }\n\n clear(): void {\n this.#cache.clear();\n }\n\n #latestState(\n descriptor: number,\n stat: fs.Stats,\n knownCompleteEnd?: number,\n ): CachedTranscript {\n const completeEnd = knownCompleteEnd ?? completeLogEnd(descriptor, stat.size);\n const page = readJsonlPageFromDescriptor(\n descriptor,\n this.#pageLines,\n completeEnd,\n stat.size,\n MAX_PAGE_BYTES,\n );\n return this.#stateForPage(\n descriptor,\n stat,\n completeEnd,\n page.lines,\n page.lines[0]?.offset ?? completeEnd,\n completeEnd,\n page.hasMore,\n );\n }\n\n #stateForPage(\n descriptor: number,\n stat: fs.Stats,\n completeEnd: number,\n lines: FabricLogLine[],\n pageStart: number,\n pageEnd: number,\n hasMore: boolean,\n ): CachedTranscript {\n const events = parsedEvents(lines);\n const missingStarts = missingToolStartIds(events);\n const lifecycleContext: Array<Record<string, unknown>> = [];\n if (missingStarts.size > 0 && pageStart > 0) {\n const contextPage = readJsonlPageFromDescriptor(\n descriptor,\n TOOL_LIFECYCLE_CONTEXT_LINES,\n pageStart,\n stat.size,\n MAX_PAGE_BYTES,\n );\n const contextEvents = parsedEvents(contextPage.lines);\n for (let index = contextEvents.length - 1; index >= 0 && missingStarts.size > 0; index--) {\n const starts = normalizedToolStarts(contextEvents[index]!);\n for (let startIndex = starts.length - 1; startIndex >= 0; startIndex--) {\n const start = starts[startIndex]!;\n if (!missingStarts.delete(start.id)) continue;\n lifecycleContext.unshift(start.event);\n }\n }\n }\n const accumulator = new TranscriptAccumulator();\n accumulator.append([...lifecycleContext, ...events]);\n const transcript = {\n ...accumulator.snapshot(hasMore, stat.mtimeMs, Number.MAX_SAFE_INTEGER),\n hasNewer: pageEnd < completeEnd,\n };\n return {\n device: stat.dev,\n inode: stat.ino,\n modifiedAt: stat.mtimeMs,\n offset: stat.size,\n completeEnd,\n pageStart,\n pageEnd,\n hasMore: transcript.hasMore ?? false,\n transcript,\n };\n }\n\n #remember(filePath: string, state: CachedTranscript): void {\n this.#cache.delete(filePath);\n this.#cache.set(filePath, state);\n while (this.#cache.size > MAX_CACHE_ENTRIES) {\n const oldest = this.#cache.keys().next().value as string | undefined;\n if (!oldest) break;\n this.#cache.delete(oldest);\n }\n }\n}\n", "import type { FabricLogLine } from \"../agents/types.js\";\nimport type { FabricAgentTranscript, FabricTranscriptEntry } from \"./transcript.js\";\nimport { unwrapActorEnvelopeText } from \"./conversation-transcript.js\";\nimport {\n clip,\n compactRedactedValue,\n contentText,\n contentThinking,\n messageError,\n recordOf,\n redact,\n redactRecord,\n terminalSafe,\n} from \"./transcript-sanitization.js\";\n\nconst MAX_TOOL_SUMMARY_CHARS = 500;\nconst MAX_TRANSCRIPT_MESSAGE_CHARS = 40_000;\nconst TRANSCRIPT_ENTRY_LIMIT = 80;\n\ntype FabricTranscriptEntryStatus = \"running\" | \"completed\" | \"failed\";\n\nexport class TranscriptAccumulator {\n readonly entries: FabricTranscriptEntry[] = [];\n readonly #tools = new Map<string, FabricTranscriptEntry>();\n readonly #anonymousTools = new Map<string, FabricTranscriptEntry[]>();\n readonly #activeTools: FabricTranscriptEntry[] = [];\n #assistant: FabricTranscriptEntry | undefined;\n #thinking: FabricTranscriptEntry | undefined;\n #retry: FabricTranscriptEntry | undefined;\n #compaction: FabricTranscriptEntry | undefined;\n readonly #userMessages = new Map<string, FabricTranscriptEntry>();\n readonly #userBoundaries = new Map<string, { serial: number; ended: boolean }>();\n #sequence = 0;\n\n append(events: Array<Record<string, unknown>>): void {\n for (const event of events) this.#append(event);\n }\n\n snapshot(\n olderAvailable = false,\n updatedAt?: number,\n maxEntries = TRANSCRIPT_ENTRY_LIMIT,\n ): FabricAgentTranscript {\n const entries = maxEntries > 0 && this.entries.length > maxEntries\n ? this.entries.slice(-maxEntries)\n : this.entries;\n const omitted = entries.length < this.entries.length;\n return {\n entries: entries.map((entry) => ({ ...entry })),\n truncated: olderAvailable || omitted,\n hasMore: olderAvailable || omitted,\n ...(updatedAt !== undefined ? { updatedAt } : {}),\n };\n }\n\n #nextId(event: Record<string, unknown>, prefix = \"event\"): string {\n if (typeof event.toolCallId === \"string\") return event.toolCallId;\n if (typeof event.uuid === \"string\") return event.uuid;\n if (typeof event.id === \"string\") return event.id;\n return `${prefix}-${this.#sequence++}`;\n }\n\n /** Keep the latest assistant reasoning as one entry that grows while it streams. */\n #trackThinking(id: string, content: unknown): void {\n const text = terminalSafe(contentThinking(content), false);\n if (!text) return;\n if (!this.#thinking) {\n this.#thinking = {\n id: `${id}-thinking`,\n kind: \"thinking\",\n label: \"Thinking\",\n text: clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS, false),\n status: \"running\",\n };\n this.entries.push(this.#thinking);\n return;\n }\n this.#thinking.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS, false);\n }\n\n #finishThinking(status: \"completed\" | \"failed\"): void {\n if (!this.#thinking) return;\n this.#thinking.status = status;\n this.#thinking = undefined;\n }\n\n #finishAssistant(status: \"completed\" | \"failed\"): void {\n this.#finishThinking(status);\n if (!this.#assistant) return;\n this.#assistant.status = status;\n this.#assistant = undefined;\n }\n\n #pushMessage(\n kind: \"user\" | \"assistant\",\n id: string,\n text: string,\n status: FabricTranscriptEntryStatus = \"completed\",\n label = kind === \"assistant\" ? \"Agent\" : \"User\",\n identity?: string,\n ): void {\n const display = kind === \"user\" ? (unwrapActorEnvelopeText(text) ?? text) : text;\n const safe = clip(display, MAX_TRANSCRIPT_MESSAGE_CHARS, kind !== \"user\");\n if (!safe) return;\n const entry: FabricTranscriptEntry = { id, kind, label, text: safe, status };\n if (kind === \"user\" && identity) {\n // Identity-aware start/end correlation: message_start and message_end\n // carry the same timestamp/content within one lifecycle. The boundary\n // serial distinguishes repeated turns even if their timestamps collide.\n const existing = this.#userMessages.get(identity);\n if (existing) {\n existing.text = safe;\n return;\n }\n this.#userMessages.set(identity, entry);\n }\n this.entries.push(entry);\n }\n\n #userIdentity(event: Record<string, unknown>, message: Record<string, unknown>): string | undefined {\n if (event.type === \"message_start\" || event.type === \"message_end\" || event.type === \"message\") {\n const timestamp = message.timestamp;\n if (typeof timestamp === \"number\" && Number.isFinite(timestamp)) {\n const base = JSON.stringify([timestamp, contentText(message.content)]);\n let boundary = this.#userBoundaries.get(base);\n if (!boundary || (event.type === \"message_start\" && boundary.ended)) {\n boundary = { serial: (boundary?.serial ?? -1) + 1, ended: false };\n this.#userBoundaries.set(base, boundary);\n }\n if (event.type === \"message_end\") boundary.ended = true;\n return `user:${base}:${boundary.serial}`;\n }\n }\n return undefined;\n }\n\n #toolParent(id: string): FabricTranscriptEntry | undefined {\n if (!id.startsWith(\"fabric_\")) return undefined;\n for (let index = this.#activeTools.length - 1; index >= 0; index--) {\n const candidate = this.#activeTools[index];\n if (candidate?.toolName === \"fabric_exec\" && candidate.status === \"running\") return candidate;\n }\n return undefined;\n }\n\n #startTool(\n id: string,\n label: string,\n args: unknown,\n ): FabricTranscriptEntry {\n const existing = this.#tools.get(id);\n const safeArgs = args === undefined ? undefined : redactRecord(args);\n if (existing) {\n if (safeArgs !== undefined) existing.args = safeArgs;\n if (args !== undefined) existing.text = compactRedactedValue(safeArgs ?? redact(args));\n return existing;\n }\n const parent = this.#toolParent(id);\n const safeLabel = terminalSafe(label) || \"tool\";\n const entry: FabricTranscriptEntry = {\n id,\n kind: \"tool\",\n label: safeLabel,\n toolName: safeLabel,\n status: \"running\",\n ...(safeArgs !== undefined ? { args: safeArgs } : {}),\n ...(args !== undefined\n ? { text: compactRedactedValue(safeArgs ?? redact(args)) }\n : {}),\n ...(parent ? { parentId: parent.id, depth: (parent.depth ?? 0) + 1 } : {}),\n };\n this.entries.push(entry);\n this.#tools.set(id, entry);\n this.#activeTools.push(entry);\n return entry;\n }\n\n #finishTool(id: string | undefined, label: string, result: unknown, failed: boolean): void {\n const safeLabel = terminalSafe(label) || \"tool\";\n const anonymous = this.#anonymousTools.get(safeLabel);\n const entry = id ? this.#tools.get(id) : anonymous?.shift();\n if (anonymous?.length === 0) this.#anonymousTools.delete(safeLabel);\n const safeResult = result === undefined ? undefined : redact(result);\n if (entry) {\n entry.status = failed ? \"failed\" : \"completed\";\n if (safeResult !== undefined) entry.result = safeResult;\n if (failed && result !== undefined) {\n const failure = compactRedactedValue(safeResult);\n entry.text = clip(\n `${entry.text ? `${entry.text} \u00B7 ` : \"\"}error: ${failure}`,\n MAX_TOOL_SUMMARY_CHARS,\n );\n }\n this.#tools.delete(entry.id);\n const activeIndex = this.#activeTools.indexOf(entry);\n if (activeIndex >= 0) this.#activeTools.splice(activeIndex, 1);\n return;\n }\n this.entries.push({\n id: id ?? `tool-${this.#sequence++}`,\n kind: \"tool\",\n label: safeLabel,\n toolName: safeLabel,\n status: failed ? \"failed\" : \"completed\",\n ...(safeResult !== undefined ? { result: safeResult } : {}),\n ...(failed && safeResult !== undefined ? { text: compactRedactedValue(safeResult) } : {}),\n });\n }\n\n #appendSessionMessage(event: Record<string, unknown>, message: Record<string, unknown>): void {\n const id = this.#nextId(event, \"message\");\n if (message.role === \"user\") {\n this.#pushMessage(\"user\", id, contentText(message.content), \"completed\", \"User\", this.#userIdentity(event, message));\n return;\n }\n if (message.role === \"assistant\") {\n const error = messageError(message);\n // A retained message is complete: close any streamed reasoning, then keep this one's as its own entry.\n this.#finishThinking(\"completed\");\n this.#trackThinking(id, message.content);\n this.#finishThinking(error ? \"failed\" : \"completed\");\n const text = contentText(message.content);\n if (text) this.#pushMessage(\"assistant\", id, text, error ? \"failed\" : \"completed\");\n if (error) {\n this.entries.push({\n id: `${id}-error`,\n kind: \"error\",\n label: \"Agent error\",\n text: error,\n status: \"failed\",\n });\n }\n if (Array.isArray(message.content)) {\n for (const value of message.content) {\n const part = recordOf(value);\n if (part?.type !== \"toolCall\" || typeof part.name !== \"string\") continue;\n const toolId = typeof part.id === \"string\" ? part.id : `session-tool-${this.#sequence++}`;\n this.#startTool(toolId, part.name, part.arguments);\n }\n }\n return;\n }\n if (message.role === \"toolResult\") {\n const toolId = typeof message.toolCallId === \"string\" ? message.toolCallId : undefined;\n const label = typeof message.toolName === \"string\" ? message.toolName : \"tool\";\n this.#finishTool(\n toolId,\n label,\n { content: message.content, ...(message.details !== undefined ? { details: message.details } : {}) },\n message.isError === true,\n );\n }\n }\n\n #append(event: Record<string, unknown>): void {\n if (typeof event.type !== \"string\") return;\n const id = this.#nextId(event);\n\n if (event.type === \"message\") {\n const message = recordOf(event.message);\n if (message) this.#appendSessionMessage(event, message);\n return;\n }\n\n if (event.type === \"model_change\") {\n const provider = typeof event.provider === \"string\" ? event.provider : \"\";\n const model = typeof event.modelId === \"string\" ? event.modelId : \"\";\n this.entries.push({\n id,\n kind: \"status\",\n label: \"Model changed\",\n ...(provider || model ? { text: [provider, model].filter(Boolean).join(\"/\") } : {}),\n status: \"completed\",\n });\n return;\n }\n\n if (event.type === \"thinking_level_change\") {\n this.entries.push({\n id,\n kind: \"status\",\n label: \"Thinking changed\",\n ...(typeof event.thinkingLevel === \"string\" ? { text: event.thinkingLevel } : {}),\n status: \"completed\",\n });\n return;\n }\n\n if (event.type === \"compaction\") {\n this.entries.push({\n id,\n kind: \"status\",\n label: \"Compacted context\",\n ...(typeof event.summary === \"string\" ? { text: terminalSafe(event.summary) } : {}),\n status: \"completed\",\n });\n return;\n }\n\n if (event.type === \"stream_event\") {\n const stream = recordOf(event.event);\n const delta = recordOf(stream?.delta);\n if (stream?.type === \"content_block_delta\" && delta?.type === \"text_delta\") {\n const text = typeof delta.text === \"string\" ? terminalSafe(delta.text, false) : \"\";\n if (!text) return;\n if (!this.#assistant) {\n this.#assistant = {\n id,\n kind: \"assistant\",\n label: \"Claude\",\n text: clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS, false),\n status: \"running\",\n };\n this.entries.push(this.#assistant);\n } else {\n this.#assistant.text = clip(\n `${this.#assistant.text ?? \"\"}${text}`,\n MAX_TRANSCRIPT_MESSAGE_CHARS,\n false,\n );\n }\n }\n return;\n }\n\n if (event.type === \"assistant\") {\n const message = recordOf(event.message);\n if (!message || message.role !== \"assistant\") return;\n if (Array.isArray(message.content)) {\n for (const value of message.content) {\n const part = recordOf(value);\n if (part?.type !== \"tool_use\") continue;\n const toolId = typeof part.id === \"string\" ? part.id : `claude-tool-${this.#sequence++}`;\n const label = typeof part.name === \"string\" ? part.name : \"tool\";\n this.#startTool(toolId, label, part.input);\n }\n }\n const text = terminalSafe(contentText(message.content));\n if (text) {\n if (this.#assistant) {\n this.#assistant.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS);\n this.#finishAssistant(\"completed\");\n } else {\n this.#pushMessage(\"assistant\", id, text, \"completed\", \"Claude\");\n }\n }\n if (typeof event.error === \"string\") {\n this.entries.push({\n id: `${id}-error`,\n kind: \"error\",\n label: \"Claude error\",\n text: clip(event.error, MAX_TOOL_SUMMARY_CHARS),\n status: \"failed\",\n });\n }\n return;\n }\n\n if (event.type === \"user\") {\n const message = recordOf(event.message);\n if (!message || !Array.isArray(message.content)) return;\n let hasToolResult = false;\n for (const value of message.content) {\n const part = recordOf(value);\n if (part?.type !== \"tool_result\" || typeof part.tool_use_id !== \"string\") continue;\n hasToolResult = true;\n this.#finishTool(part.tool_use_id, \"tool\", part.content, part.is_error === true);\n }\n if (!hasToolResult) this.#pushMessage(\"user\", id, contentText(message.content));\n return;\n }\n\n if (event.type === \"result\") {\n this.#finishAssistant(event.is_error === true ? \"failed\" : \"completed\");\n if (event.is_error === true || event.subtype !== \"success\") {\n const errors = Array.isArray(event.errors)\n ? event.errors.filter((value): value is string => typeof value === \"string\").join(\" \u00B7 \")\n : \"\";\n const text = errors || (typeof event.result === \"string\" ? event.result : \"Claude run failed\");\n this.entries.push({\n id,\n kind: \"error\",\n label: \"Claude result\",\n text: clip(text, MAX_TOOL_SUMMARY_CHARS),\n status: \"failed\",\n });\n }\n return;\n }\n\n if (event.type === \"system\" && event.subtype === \"api_retry\") {\n this.entries.push({\n id,\n kind: \"status\",\n label: \"Claude API retry\",\n status: \"running\",\n ...(typeof event.error === \"string\"\n ? { text: clip(event.error, MAX_TOOL_SUMMARY_CHARS) }\n : {}),\n });\n return;\n }\n\n // Worker RPC logs stream reasoning as bare deltas without a message body.\n if (event.type === \"message_update\" && event.message === undefined) {\n const update = recordOf(event.assistantMessageEvent);\n if (update?.type === \"thinking_delta\" && typeof update.delta === \"string\") {\n const previous = this.#thinking?.text ?? \"\";\n this.#trackThinking(id, [{ type: \"thinking\", thinking: `${previous}${update.delta}` }]);\n }\n return;\n }\n if (event.type === \"message_start\") this.#finishAssistant(\"completed\");\n if (event.type === \"message_start\" || event.type === \"message_update\") {\n const message = recordOf(event.message);\n if (!message) return;\n if (message.role === \"user\") {\n if (event.type === \"message_start\") {\n this.#pushMessage(\"user\", id, contentText(message.content), \"completed\", \"User\", this.#userIdentity(event, message));\n }\n return;\n }\n if (message.role !== \"assistant\") return;\n this.#trackThinking(id, message.content);\n const text = terminalSafe(contentText(message.content));\n if (!text) return;\n if (!this.#assistant) {\n this.#assistant = {\n id,\n kind: \"assistant\",\n label: \"Agent\",\n text: clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS),\n status: \"running\",\n };\n this.entries.push(this.#assistant);\n } else {\n this.#assistant.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS);\n if (!this.entries.includes(this.#assistant)) this.entries.push(this.#assistant);\n }\n return;\n }\n\n if (event.type === \"message_end\") {\n const message = recordOf(event.message);\n if (!message) return;\n if (message.role === \"user\") {\n this.#pushMessage(\"user\", id, contentText(message.content), \"completed\", \"User\", this.#userIdentity(event, message));\n return;\n }\n if (message.role !== \"assistant\") return;\n this.#trackThinking(id, message.content);\n const error = messageError(message);\n if (error) {\n this.#finishAssistant(\"failed\");\n this.entries.push({ id, kind: \"error\", label: \"Agent error\", text: error, status: \"failed\" });\n return;\n }\n const text = terminalSafe(contentText(message.content));\n if (!text) {\n this.#finishAssistant(\"completed\");\n return;\n }\n if (!this.#assistant) {\n this.#pushMessage(\"assistant\", id, text);\n this.#finishThinking(\"completed\");\n } else {\n this.#assistant.text = clip(text, MAX_TRANSCRIPT_MESSAGE_CHARS);\n this.#finishAssistant(\"completed\");\n }\n return;\n }\n\n if (event.type === \"response\" && event.command === \"prompt\" && event.success === false) {\n const text = typeof event.error === \"string\" ? event.error : \"Pi rejected the prompt\";\n this.entries.push({\n id,\n kind: \"error\",\n label: \"Prompt rejected\",\n text: clip(text, MAX_TOOL_SUMMARY_CHARS),\n status: \"failed\",\n });\n return;\n }\n\n if (event.type === \"tool_execution_start\") {\n const label = typeof event.toolName === \"string\" ? event.toolName : \"tool\";\n const entry = this.#startTool(id, label, event.args);\n if (typeof event.toolCallId !== \"string\") {\n const key = terminalSafe(label) || \"tool\";\n this.#tools.delete(entry.id);\n this.#anonymousTools.set(key, [...(this.#anonymousTools.get(key) ?? []), entry]);\n }\n return;\n }\n\n if (event.type === \"tool_execution_end\") {\n const label = typeof event.toolName === \"string\" ? event.toolName : \"tool\";\n this.#finishTool(\n typeof event.toolCallId === \"string\" ? event.toolCallId : undefined,\n label,\n event.result,\n event.isError === true,\n );\n return;\n }\n\n if (event.type === \"auto_retry_start\") {\n const attempt = typeof event.attempt === \"number\" ? ` ${event.attempt}` : \"\";\n this.#retry = {\n id,\n kind: \"status\",\n label: `Retry${attempt}`,\n status: \"running\",\n ...(typeof event.errorMessage === \"string\"\n ? { text: clip(event.errorMessage, MAX_TOOL_SUMMARY_CHARS) }\n : {}),\n };\n this.entries.push(this.#retry);\n return;\n }\n if (event.type === \"auto_retry_end\") {\n const failed = event.success === false;\n if (this.#retry) {\n this.#retry.status = failed ? \"failed\" : \"completed\";\n if (failed && typeof event.finalError === \"string\") {\n this.#retry.text = clip(event.finalError, MAX_TOOL_SUMMARY_CHARS);\n }\n this.#retry = undefined;\n }\n return;\n }\n\n if (event.type === \"compaction_start\") {\n this.#compaction = {\n id,\n kind: \"status\",\n label: \"Compacting context\",\n status: \"running\",\n };\n this.entries.push(this.#compaction);\n return;\n }\n if (event.type === \"compaction_end\") {\n if (this.#compaction) {\n const failed = event.aborted === true || typeof event.errorMessage === \"string\";\n this.#compaction.status = failed ? \"failed\" : \"completed\";\n if (typeof event.errorMessage === \"string\") {\n this.#compaction.text = clip(event.errorMessage, MAX_TOOL_SUMMARY_CHARS);\n }\n this.#compaction = undefined;\n }\n return;\n }\n\n if (event.type === \"extension_error\" || event.type === \"worker_stderr\") {\n const text =\n typeof event.error === \"string\"\n ? event.error\n : typeof event.text === \"string\"\n ? event.text\n : \"Extension error\";\n const warningLines = text.split(/\\r?\\n/).filter((line) => line.trim());\n const warningCount = event.type === \"worker_stderr\" && warningLines.length > 0 &&\n warningLines.every((line) => /^\\s*Warning:/.test(line)) ? warningLines.length : 0;\n this.entries.push({\n id,\n kind: \"error\",\n label: event.type === \"worker_stderr\" ? \"Worker stderr\" : \"Error\",\n text: clip(text, warningCount > 0 ? MAX_TRANSCRIPT_MESSAGE_CHARS : MAX_TOOL_SUMMARY_CHARS),\n ...(event.type === \"worker_stderr\" ? { warningCount } : {}),\n status: \"failed\",\n });\n }\n }\n}\n\nexport const parseRaw = (raw: string): Record<string, unknown> | undefined => {\n try {\n return recordOf(JSON.parse(raw));\n } catch {\n return undefined;\n }\n};\n\nexport const parsedEvents = (lines: FabricLogLine[]): Array<Record<string, unknown>> =>\n lines\n .map((line) => recordOf(line.parsed) ?? parseRaw(line.raw))\n .filter((event): event is Record<string, unknown> => event !== undefined);\n\ninterface ToolLifecycleStart {\n id: string;\n event: Record<string, unknown>;\n}\n\nexport const normalizedToolStarts = (event: Record<string, unknown>): ToolLifecycleStart[] => {\n if (\n event.type === \"tool_execution_start\" &&\n typeof event.toolCallId === \"string\"\n ) {\n return [{ id: event.toolCallId, event }];\n }\n\n const starts: ToolLifecycleStart[] = [];\n const appendContentStarts = (\n content: unknown,\n type: \"toolCall\" | \"tool_use\",\n ): void => {\n if (!Array.isArray(content)) return;\n for (const value of content) {\n const part = recordOf(value);\n if (part?.type !== type || typeof part.id !== \"string\") continue;\n const name = typeof part.name === \"string\" ? part.name : \"tool\";\n starts.push({\n id: part.id,\n event: {\n type: \"tool_execution_start\",\n toolCallId: part.id,\n toolName: name,\n args: type === \"toolCall\" ? part.arguments : part.input,\n },\n });\n }\n };\n\n if (event.type === \"message\") {\n const message = recordOf(event.message);\n if (message?.role === \"assistant\") appendContentStarts(message.content, \"toolCall\");\n } else if (event.type === \"assistant\") {\n const message = recordOf(event.message);\n if (message?.role === \"assistant\") appendContentStarts(message.content, \"tool_use\");\n }\n return starts;\n};\n\nconst toolLifecycleEndIds = (event: Record<string, unknown>): string[] => {\n if (event.type === \"tool_execution_end\" && typeof event.toolCallId === \"string\") {\n return [event.toolCallId];\n }\n if (event.type === \"message\") {\n const message = recordOf(event.message);\n return message?.role === \"toolResult\" && typeof message.toolCallId === \"string\"\n ? [message.toolCallId]\n : [];\n }\n if (event.type !== \"user\") return [];\n const message = recordOf(event.message);\n if (!Array.isArray(message?.content)) return [];\n return message.content.flatMap((value) => {\n const part = recordOf(value);\n return part?.type === \"tool_result\" && typeof part.tool_use_id === \"string\"\n ? [part.tool_use_id]\n : [];\n });\n};\n\nexport const missingToolStartIds = (events: Array<Record<string, unknown>>): Set<string> => {\n const active = new Set<string>();\n const missing = new Set<string>();\n for (const event of events) {\n for (const start of normalizedToolStarts(event)) active.add(start.id);\n for (const id of toolLifecycleEndIds(event)) {\n if (active.has(id)) active.delete(id);\n else missing.add(id);\n }\n }\n return missing;\n};\n", "import type { FabricAgentRunner } from \"../config.js\";\nimport { TranscriptAccumulator } from \"./transcript-parser.js\";\nimport { AgentTranscriptReader } from \"./transcript-reader.js\";\nimport { recordOf } from \"./transcript-sanitization.js\";\n\ntype FabricTranscriptEntryStatus = \"running\" | \"completed\" | \"failed\";\n\nexport interface FabricTranscriptEntry {\n id: string;\n kind: \"user\" | \"assistant\" | \"thinking\" | \"tool\" | \"error\" | \"status\";\n label: string;\n text?: string;\n status?: FabricTranscriptEntryStatus;\n toolName?: string;\n args?: Record<string, unknown>;\n result?: unknown;\n parentId?: string;\n depth?: number;\n /** Count only when the original stderr chunk contains warnings exclusively. */\n warningCount?: number;\n}\n\nexport interface FabricAgentTranscript {\n entries: FabricTranscriptEntry[];\n /** Kept for compatibility; true means older pages are available. */\n truncated: boolean;\n hasMore?: boolean;\n hasNewer?: boolean;\n updatedAt?: number;\n}\n\nexport interface FabricTranscriptSource {\n id: string;\n status: string;\n logFile?: string;\n}\n\nexport interface FabricAgentToolPreviewNode {\n id: string;\n name: string;\n status?: string;\n runner?: FabricAgentRunner;\n owner?: \"agent\" | \"actor\";\n /** Most recent tool the agent was observed running, when known. */\n currentTool?: string;\n text?: string;\n tools: FabricTranscriptEntry[];\n /** Descendant previews, one branch per spawned nested agent run. */\n agents?: FabricAgentToolPreviewNode[];\n /** True when descendant previews were cut by the preview tree budget. */\n agentsTruncated?: boolean;\n}\n\nexport interface FabricAgentToolPreview extends FabricAgentToolPreviewNode {\n kind: \"fabric-agent-tools\";\n}\n\nexport const projectAgentTranscript = (\n events: Array<Record<string, unknown>>,\n olderAvailable = false,\n): FabricAgentTranscript => {\n const accumulator = new TranscriptAccumulator();\n accumulator.append(events);\n return accumulator.snapshot(olderAvailable);\n};\n\nconst PREVIEW_TREE_GUARD_MAX_DEPTH = 8;\n\nconst isFabricAgentToolPreviewNode = (\n value: unknown,\n depth: number,\n): value is FabricAgentToolPreviewNode => {\n const record = recordOf(value);\n if (\n !record ||\n typeof record.id !== \"string\" ||\n typeof record.name !== \"string\" ||\n (record.text !== undefined && typeof record.text !== \"string\") ||\n (record.currentTool !== undefined && typeof record.currentTool !== \"string\") ||\n !Array.isArray(record.tools)\n ) {\n return false;\n }\n if (record.agents === undefined) return true;\n if (depth >= PREVIEW_TREE_GUARD_MAX_DEPTH || !Array.isArray(record.agents)) return false;\n return record.agents.every((child) => isFabricAgentToolPreviewNode(child, depth + 1));\n};\n\nexport const isFabricAgentToolPreview = (value: unknown): value is FabricAgentToolPreview =>\n recordOf(value)?.kind === \"fabric-agent-tools\" && isFabricAgentToolPreviewNode(value, 0);\n\nexport const recentTranscriptTools = (\n transcript: FabricAgentTranscript,\n limit = 2,\n): FabricTranscriptEntry[] => {\n const tools = transcript.entries.filter((entry) => entry.kind === \"tool\");\n const boundedLimit = Math.max(1, limit);\n const running = tools.filter((entry) => entry.status === \"running\");\n const completed = tools.filter((entry) => entry.status !== \"running\");\n const completedSlots = Math.max(0, boundedLimit - Math.min(running.length, boundedLimit));\n const retained = new Set([\n ...running.slice(-boundedLimit),\n ...completed.slice(-completedSlots),\n ]);\n return tools\n .filter((entry) => retained.has(entry))\n .slice(-boundedLimit)\n .map((entry) => ({ ...entry }));\n};\n\nexport { AgentTranscriptReader };\n", "// Adapted from pi-code-previews; see THIRD_PARTY_NOTICES.md.\n\nexport type PreviewLineEntry<T> =\n | { kind: \"line\"; line: T; index: number }\n | { kind: \"hidden\"; hidden: number };\n\nexport function countContentLines(content: string): number {\n if (!content) return 0;\n let terminators = 0;\n for (let index = 0; index < content.length; index++) {\n const code = content.charCodeAt(index);\n if (code === 13) {\n terminators++;\n if (content.charCodeAt(index + 1) === 10) index++;\n } else if (code === 10) {\n terminators++;\n }\n }\n const finalCode = content.charCodeAt(content.length - 1);\n return terminators + (finalCode === 10 || finalCode === 13 ? 0 : 1);\n}\n\nexport function selectPreviewTextLines(\n text: string,\n limit: number,\n): { entries: Array<PreviewLineEntry<string>>; shown: number; hidden: number; total: number } {\n if (!Number.isInteger(limit)) {\n const lines = collectPreviewTextLines(text);\n return { ...selectPreviewLines(lines, limit), total: lines.length };\n }\n\n const entries: Array<PreviewLineEntry<string>> = [];\n const split = limit >= 8;\n const head = split ? Math.ceil(limit * 0.65) : limit;\n const tailLimit = split ? Math.max(1, limit - head - 1) : 0;\n const tail: Array<string | undefined> = [];\n let tailSize = 0;\n let tailCursor = 0;\n let total = 0;\n forEachPreviewTextLine(text, (line, index) => {\n total++;\n if (limit <= 0 || index < limit) entries.push({ kind: \"line\", line, index });\n if (!split || index < head) return;\n tail[tailCursor] = line;\n if (++tailCursor === tailLimit) tailCursor = 0;\n if (tailSize < tailLimit) tailSize++;\n });\n\n if (limit <= 0 || total <= limit) return { entries, shown: total, hidden: 0, total };\n if (!split) return { entries, shown: limit, hidden: total - limit, total };\n const hidden = total - head - tailLimit;\n const selected = entries.slice(0, head);\n selected.push({ kind: \"hidden\", hidden });\n let tailSlot = tailSize === tailLimit ? tailCursor : 0;\n for (let offset = 0; offset < tailSize; offset++) {\n const line = tail[tailSlot];\n if (line === undefined) throw new RangeError(`Missing preview tail line ${offset}`);\n selected.push({ kind: \"line\", line, index: total - tailSize + offset });\n if (++tailSlot === tailLimit) tailSlot = 0;\n }\n return { entries: selected, shown: head + tailLimit, hidden, total };\n}\n\nfunction selectPreviewLines<T>(\n lines: T[],\n limit: number,\n): { entries: Array<PreviewLineEntry<T>>; shown: number; hidden: number } {\n if (lines.length <= limit || limit <= 0) {\n return {\n entries: lines.map((line, index) => ({ kind: \"line\", line, index })),\n shown: lines.length,\n hidden: 0,\n };\n }\n if (limit < 8) {\n return {\n entries: lines.slice(0, limit).map((line, index) => ({ kind: \"line\", line, index })),\n shown: limit,\n hidden: lines.length - limit,\n };\n }\n const head = Math.ceil(limit * 0.65);\n const tail = Math.max(1, limit - head - 1);\n const hidden = lines.length - head - tail;\n return {\n entries: [\n ...lines.slice(0, head).map((line, index) => ({ kind: \"line\" as const, line, index })),\n { kind: \"hidden\", hidden },\n ...lines.slice(-tail).map((line, offset) => ({\n kind: \"line\" as const,\n line,\n index: lines.length - tail + offset,\n })),\n ],\n shown: head + tail,\n hidden,\n };\n}\n\nfunction collectPreviewTextLines(text: string): string[] {\n const lines: string[] = [];\n forEachPreviewTextLine(text, (line) => lines.push(line));\n return lines;\n}\n\nfunction forEachPreviewTextLine(\n text: string,\n callback: (line: string, index: number) => void,\n): void {\n let index = 0;\n let pendingEmpty = 0;\n forEachRawTextLine(text, (line) => {\n if (line === \"\") {\n pendingEmpty++;\n return;\n }\n while (pendingEmpty > 0) {\n callback(\"\", index++);\n pendingEmpty--;\n }\n callback(line, index++);\n });\n if (index === 0 && pendingEmpty > 0 && text.length > 0) callback(\"\", index);\n}\n\nfunction forEachRawTextLine(text: string, callback: (line: string) => void): void {\n let start = 0;\n while (start <= text.length) {\n const newline = text.indexOf(\"\\n\", start);\n if (newline < 0) {\n callback(text.slice(start));\n break;\n }\n callback(text.slice(start, newline));\n start = newline + 1;\n }\n}\n", "// Pure write-diff size guards shared by the write-preview tool wrapper and the\n// dashboard's core-tool-render. Keep this module free of imports from\n// \"@earendil-works/pi-coding-agent\": it is part of the lazily imported\n// dashboard graph, which cannot resolve pi's host package in managed\n// installs (issue #13).\n\nconst configuredMaxBytes = Number.parseInt(\n process.env.CODE_PREVIEW_MAX_WRITE_DIFF_BYTES ?? \"\",\n 10,\n);\nexport const MAX_WRITE_DIFF_BYTES =\n Number.isFinite(configuredMaxBytes) && configuredMaxBytes > 0\n ? configuredMaxBytes\n : 200_000;\n\nconst configuredMaxChangedLineCells = Number.parseInt(\n process.env.CODE_PREVIEW_MAX_WRITE_DIFF_CHANGED_LINE_CELLS ?? \"\",\n 10,\n);\nconst MAX_WRITE_DIFF_CHANGED_LINE_CELLS =\n Number.isFinite(configuredMaxChangedLineCells) && configuredMaxChangedLineCells > 0\n ? configuredMaxChangedLineCells\n : 1_000_000;\n\nexport const writeContentForPreview = (content: string): string | undefined =>\n Buffer.byteLength(content, \"utf8\") <= MAX_WRITE_DIFF_BYTES ? content : undefined;\n\nexport const shouldSkipWriteDiffBytes = (...texts: string[]): boolean => {\n let total = 0;\n for (const text of texts) {\n total += Buffer.byteLength(text, \"utf8\");\n if (total > MAX_WRITE_DIFF_BYTES) return true;\n }\n return false;\n};\n\nexport const shouldSkipWriteDiffComplexity = (before: string, after: string): boolean => {\n const beforeLines = before.split(\"\\n\");\n const afterLines = after.split(\"\\n\");\n const sharedLimit = Math.min(beforeLines.length, afterLines.length);\n let prefix = 0;\n while (prefix < sharedLimit && beforeLines[prefix] === afterLines[prefix]) prefix++;\n\n let suffix = 0;\n const suffixLimit = sharedLimit - prefix;\n while (\n suffix < suffixLimit &&\n beforeLines[beforeLines.length - suffix - 1] ===\n afterLines[afterLines.length - suffix - 1]\n ) {\n suffix++;\n }\n\n const changedBefore = beforeLines.length - prefix - suffix;\n const changedAfter = afterLines.length - prefix - suffix;\n return changedBefore * changedAfter > MAX_WRITE_DIFF_CHANGED_LINE_CELLS;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["message"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isJevModelId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-G54PEZ44.js";
|
|
4
4
|
|
|
5
5
|
// src/jev/validation.ts
|
|
6
6
|
import { Value } from "typebox/value";
|
|
@@ -149,4 +149,4 @@ export {
|
|
|
149
149
|
checkSchema,
|
|
150
150
|
checkValue
|
|
151
151
|
};
|
|
152
|
-
//# sourceMappingURL=chunk-
|
|
152
|
+
//# sourceMappingURL=chunk-FSYAGCGA.js.map
|
|
@@ -21,7 +21,7 @@ var parseJevApprovalModel = (key) => {
|
|
|
21
21
|
var isJevApprovalModel = (key) => parseJevApprovalModel(key) !== void 0;
|
|
22
22
|
|
|
23
23
|
// src/jev/routes.ts
|
|
24
|
-
var JEV_TYPESAFE_MODELS = ["jev-latest", "jev-1.13", "jev-1.13.0", "jev-preview"];
|
|
24
|
+
var JEV_TYPESAFE_MODELS = ["jev-latest", "jev-1.13", "jev-1.13.0", "jev-1.14.0", "jev-preview"];
|
|
25
25
|
var JEV_TYPESAFE_ROUTE = {
|
|
26
26
|
id: "typesafe",
|
|
27
27
|
label: "TypeSafe",
|
|
@@ -33,7 +33,8 @@ var JEV_TYPESAFE_ROUTE = {
|
|
|
33
33
|
};
|
|
34
34
|
var JEV_OPENROUTER_MODELS = {
|
|
35
35
|
"jev-latest": "~typesafe/jev-latest",
|
|
36
|
-
"jev-1.13": "typesafe/jev-1.13"
|
|
36
|
+
"jev-1.13": "typesafe/jev-1.13",
|
|
37
|
+
"jev-1.14": "typesafe/jev-1.14"
|
|
37
38
|
};
|
|
38
39
|
var JEV_OPENROUTER_ROUTE = {
|
|
39
40
|
id: "openrouter",
|
|
@@ -144,4 +145,4 @@ export {
|
|
|
144
145
|
resolveJevClassifierTarget,
|
|
145
146
|
jevClassifierModels
|
|
146
147
|
};
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
148
|
+
//# sourceMappingURL=chunk-G54PEZ44.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/jev/model-key.ts", "../../src/jev/routes.ts"],
|
|
4
|
+
"sourcesContent": ["/** Fabric classifier keys, not Pi chat-provider or upstream TypeSafe/OpenRouter/Vercel/SubQ model IDs. */\nexport const JEV_TYPESAFE_MODEL_PREFIX = \"pi-fabric/typesafe/\";\nexport const JEV_OPENROUTER_MODEL_PREFIX = \"pi-fabric/openrouter/\";\nexport const JEV_VERCEL_MODEL_PREFIX = \"pi-fabric/vercel-ai-gateway/\";\nexport const JEV_SUBQ_MODEL_PREFIX = \"pi-fabric/subq/\";\n\nexport type JevClassifierRoute = \"typesafe\" | \"openrouter\" | \"vercel-ai-gateway\" | \"subq\";\n\nconst ROUTE_PREFIXES: ReadonlyArray<readonly [route: JevClassifierRoute, prefix: string]> = [\n [\"typesafe\", JEV_TYPESAFE_MODEL_PREFIX],\n [\"openrouter\", JEV_OPENROUTER_MODEL_PREFIX],\n [\"vercel-ai-gateway\", JEV_VERCEL_MODEL_PREFIX],\n [\"subq\", JEV_SUBQ_MODEL_PREFIX],\n];\n\n/** Keep saved pre-namespace overrides usable without moving /login jev credentials. */\nexport const normalizeJevApprovalModel = (key: string | undefined): string | undefined =>\n key?.startsWith(\"jev/\") ? `${JEV_TYPESAFE_MODEL_PREFIX}${key.slice(4)}` : key;\n\nexport const parseJevApprovalModel = (\n key: string | undefined,\n): { route: JevClassifierRoute; model: string } | undefined => {\n const normalized = normalizeJevApprovalModel(key);\n if (!normalized) return undefined;\n for (const [route, prefix] of ROUTE_PREFIXES) {\n if (normalized.startsWith(prefix)) return { route, model: normalized.slice(prefix.length) };\n }\n return undefined;\n};\n\nexport const isJevApprovalModel = (key: string | undefined): boolean =>\n parseJevApprovalModel(key) !== undefined;\n", "import {\n JEV_OPENROUTER_MODEL_PREFIX,\n JEV_SUBQ_MODEL_PREFIX,\n JEV_TYPESAFE_MODEL_PREFIX,\n JEV_VERCEL_MODEL_PREFIX,\n parseJevApprovalModel,\n type JevClassifierRoute,\n} from \"./model-key.js\";\n\nexport interface JevRoute {\n readonly id: JevClassifierRoute;\n /** Human label used in host-visible errors and status. */\n readonly label: string;\n /** Fixed HTTPS endpoint receiving the typed System One request. */\n readonly endpoint: string;\n /** Pi auth provider whose auth.json login and environment keys authenticate this route. */\n readonly providerId: string;\n /** Environment fallbacks, checked when Pi provider auth is not configured. */\n readonly envKeys: readonly string[];\n /** Classifier key prefix stored in `approvals.model` for this route. */\n readonly modelPrefix: string;\n /** Aliases offered in host pickers and accepted as upstream overrides. */\n readonly aliases: readonly string[];\n}\n\n/** Direct TypeSafe aliases. `jev-latest` is `jev-1.13.0` until TypeSafe moves it to 1.14; `jev-preview` is `jev-1.14.0`. */\nexport const JEV_TYPESAFE_MODELS: readonly string[] = [\"jev-latest\", \"jev-1.13\", \"jev-1.13.0\", \"jev-1.14.0\", \"jev-preview\"];\n\nexport const JEV_TYPESAFE_ROUTE: JevRoute = {\n id: \"typesafe\",\n label: \"TypeSafe\",\n endpoint: \"https://api.typesafe.ai/v1/systemone\",\n providerId: \"jev\",\n envKeys: [\"TYPESAFE_API_KEY\"],\n modelPrefix: JEV_TYPESAFE_MODEL_PREFIX,\n aliases: JEV_TYPESAFE_MODELS,\n};\n\n/** OpenRouter decisions model IDs by alias. OpenRouter has no `jev-preview` alias. */\nexport const JEV_OPENROUTER_MODELS: Readonly<Record<string, string>> = {\n \"jev-latest\": \"~typesafe/jev-latest\",\n \"jev-1.13\": \"typesafe/jev-1.13\",\n \"jev-1.14\": \"typesafe/jev-1.14\",\n};\n\n/**\n * OpenRouter serves decisions models on its Decisions API, not chat completions.\n * The user's existing openrouter auth (`/login openrouter`, `OPENROUTER_API_KEY`)\n * is the primary credential; `TYPESAFE_OPENROUTER_API_KEY` is an explicit fallback.\n */\nexport const JEV_OPENROUTER_ROUTE: JevRoute = {\n id: \"openrouter\",\n label: \"OpenRouter\",\n endpoint: \"https://openrouter.ai/api/alpha/decisions\",\n providerId: \"openrouter\",\n envKeys: [\"OPENROUTER_API_KEY\", \"TYPESAFE_OPENROUTER_API_KEY\"],\n modelPrefix: JEV_OPENROUTER_MODEL_PREFIX,\n aliases: Object.keys(JEV_OPENROUTER_MODELS),\n};\n\n/** Vercel AI Gateway evaluation model IDs by alias. The gateway serves one Jev build today. */\nexport const JEV_VERCEL_MODELS: Readonly<Record<string, string>> = {\n \"jev-latest\": \"typesafe-ai/jev\",\n};\n\n/**\n * Vercel AI Gateway exposes a TypeSafe-compatible endpoint, so request and\n * response shapes stay TypeSafe's own and only the base URL and credential\n * change. The existing Pi `vercel-ai-gateway` login authenticates it.\n */\nexport const JEV_VERCEL_ROUTE: JevRoute = {\n id: \"vercel-ai-gateway\",\n label: \"Vercel AI Gateway\",\n endpoint: \"https://ai-gateway.vercel.sh/typesafe/v1/systemone\",\n providerId: \"vercel-ai-gateway\",\n envKeys: [\"AI_GATEWAY_API_KEY\"],\n modelPrefix: JEV_VERCEL_MODEL_PREFIX,\n aliases: Object.keys(JEV_VERCEL_MODELS),\n};\n\n/** SubQ's System One models. Their IDs are their own: SubQ has no Jev aliases. */\nexport const JEV_SUBQ_MODELS: readonly string[] = [\"subq-snap-preview\"];\n\n/**\n * SubQ Snap is a System One model served by SubQ itself, with TypeSafe's request\n * and response shapes at its own base URL. `/login subq` or `SUBQ_API_KEY`\n * authenticates it.\n */\nexport const JEV_SUBQ_ROUTE: JevRoute = {\n id: \"subq\",\n label: \"SubQ\",\n endpoint: \"https://api.subq.ai/v1/systemone\",\n providerId: \"subq\",\n envKeys: [\"SUBQ_API_KEY\"],\n modelPrefix: JEV_SUBQ_MODEL_PREFIX,\n aliases: JEV_SUBQ_MODELS,\n};\n\nconst JEV_ROUTES: Readonly<Record<JevClassifierRoute, JevRoute>> = {\n \"typesafe\": JEV_TYPESAFE_ROUTE,\n \"openrouter\": JEV_OPENROUTER_ROUTE,\n \"vercel-ai-gateway\": JEV_VERCEL_ROUTE,\n \"subq\": JEV_SUBQ_ROUTE,\n};\n\n/** Picker order: direct TypeSafe aliases, then OpenRouter, Vercel AI Gateway, and SubQ. */\nconst JEV_ROUTE_ORDER: readonly JevRoute[] = [JEV_TYPESAFE_ROUTE, JEV_OPENROUTER_ROUTE, JEV_VERCEL_ROUTE, JEV_SUBQ_ROUTE];\n\nconst JEV_PROVIDER_PREFIX = \"pi-fabric/\";\n\n/** Classifier key stored in `approvals.model` for one route and upstream model. */\nexport const jevClassifierKey = (route: JevRoute, model: string): string => `${route.modelPrefix}${model}`;\n\nconst TYPESAFE_MODEL = /^[a-zA-Z0-9._-]{1,128}$/;\n/** OpenRouter decisions IDs are `~typesafe/<family>` or `typesafe/<build>`. */\nexport const isJevOpenRouterModelId = (model: string): boolean =>\n /^~?typesafe\\/[a-zA-Z0-9._-]{1,120}$/.test(model);\n/** Vercel AI Gateway model IDs are `typesafe-ai/<family>`. */\nexport const isJevVercelModelId = (model: string): boolean =>\n /^typesafe-ai\\/[a-zA-Z0-9._-]{1,120}$/.test(model);\n/** SubQ model IDs are `subq-<name>`. They also fit a bare alias, so they are checked first. */\nexport const isJevSubqModelId = (model: string): boolean =>\n /^subq-[a-zA-Z0-9._-]{1,120}$/.test(model);\n/** A bare TypeSafe alias or a routable OpenRouter/Vercel AI Gateway/SubQ model ID. */\nexport const isJevModelId = (model: string): boolean =>\n TYPESAFE_MODEL.test(model) || isJevOpenRouterModelId(model) || isJevVercelModelId(model);\n\nexport interface JevRouteTarget {\n readonly route: JevRoute;\n readonly model: string;\n}\n\n/** Route and upstream model ID for a raw `jev.model` value. */\nexport const resolveJevModelRoute = (model: string): JevRouteTarget => {\n if (isJevOpenRouterModelId(model)) return { route: JEV_OPENROUTER_ROUTE, model };\n if (isJevVercelModelId(model)) return { route: JEV_VERCEL_ROUTE, model };\n if (isJevSubqModelId(model)) return { route: JEV_SUBQ_ROUTE, model };\n return { route: JEV_TYPESAFE_ROUTE, model };\n};\n\n/** Upstream model ID for an alias or override on an already-selected route. */\nexport const resolveJevUpstreamModel = (route: JevRoute, model: string): string | undefined => {\n if (route.id === \"openrouter\") return JEV_OPENROUTER_MODELS[model] ?? (isJevOpenRouterModelId(model) ? model : undefined);\n if (route.id === \"vercel-ai-gateway\") return JEV_VERCEL_MODELS[model] ?? (isJevVercelModelId(model) ? model : undefined);\n if (route.id === \"subq\") return isJevSubqModelId(model) ? model : undefined;\n return TYPESAFE_MODEL.test(model) ? model : undefined;\n};\n\nexport type JevClassifierTarget =\n | { readonly ok: true; readonly route: JevRoute; readonly model: string }\n | { readonly ok: false; readonly message: string };\n\nconst unavailableModelMessage = (route: JevRoute, model: string): string => {\n if (route.id === \"openrouter\") return `OpenRouter serves ${Object.keys(JEV_OPENROUTER_MODELS).join(\", \")}; \"${model}\" is not available`;\n if (route.id === \"vercel-ai-gateway\") return `Vercel AI Gateway serves ${Object.keys(JEV_VERCEL_MODELS).join(\", \")}; \"${model}\" is not available`;\n if (route.id === \"subq\") return `SubQ serves ${JEV_SUBQ_MODELS.join(\", \")}; \"${model}\" is not a SubQ model ID`;\n return `Invalid Jev auto-approval model; use ${JEV_TYPESAFE_MODEL_PREFIX}<model-id>`;\n};\n\n/** Route and upstream model ID for a stored `pi-fabric/<route>/<model>` approvals key. */\nexport const resolveJevClassifierTarget = (key: string): JevClassifierTarget => {\n const parsed = parseJevApprovalModel(key);\n if (!parsed) {\n return {\n ok: false,\n message: `Invalid Jev auto-approval model; use ${JEV_TYPESAFE_MODEL_PREFIX}<model-id>, ${JEV_OPENROUTER_MODEL_PREFIX}<model-id>, ${JEV_VERCEL_MODEL_PREFIX}<model-id>, or ${JEV_SUBQ_MODEL_PREFIX}<model-id>`,\n };\n }\n const route = JEV_ROUTES[parsed.route];\n const model = resolveJevUpstreamModel(route, parsed.model);\n return model ? { ok: true, route, model } : { ok: false, message: unavailableModelMessage(route, parsed.model) };\n};\n\nexport interface JevClassifierPickerModel {\n readonly provider: \"pi-fabric\";\n readonly id: string;\n readonly name: string;\n}\n\n/** Approvals picker entries: every supported classifier key plus the configured model. */\nexport const jevClassifierModels = (configuredModel?: string): JevClassifierPickerModel[] => {\n const configured = configuredModel ? resolveJevModelRoute(configuredModel) : undefined;\n return JEV_ROUTE_ORDER.flatMap((route) => {\n const models = new Set(route.aliases);\n if (configured?.route.id === route.id && configuredModel) models.add(configuredModel);\n return [...models].map((model): JevClassifierPickerModel => ({\n provider: \"pi-fabric\", id: jevClassifierKey(route, model).slice(JEV_PROVIDER_PREFIX.length),\n name: `Jev (${route.label} safety classifier \u00B7 ${model})`,\n }));\n });\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isJevModelId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-G54PEZ44.js";
|
|
4
4
|
|
|
5
5
|
// src/jev/decision-profiles.ts
|
|
6
6
|
var DECISION_MAX_BYTES = 16 * 1024 * 1024;
|
|
@@ -154,4 +154,4 @@ export {
|
|
|
154
154
|
approvalActionOverridesValue,
|
|
155
155
|
actionApprovalOverride
|
|
156
156
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-GEQMQVNS.js.map
|