@jmanuelcorral/openteam 0.20.0 → 0.21.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/README.es.md +1 -1
- package/README.md +1 -1
- package/dist/certificates/graph-release-certificate.json +2 -2
- package/dist/certificates/graph-shadow-certificate.json +2 -2
- package/dist/cli/consoleServe.d.ts +1 -0
- package/dist/cli/consoleServe.d.ts.map +1 -1
- package/dist/cli.js +2120 -587
- package/dist/config/errors.d.ts.map +1 -1
- package/dist/config/historyEndpoint.d.ts +3 -0
- package/dist/config/historyEndpoint.d.ts.map +1 -0
- package/dist/config/schema.d.ts +12 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/console/assets.d.ts +3 -3
- package/dist/console/assets.d.ts.map +1 -1
- package/dist/console/conversation.d.ts +75 -0
- package/dist/console/conversation.d.ts.map +1 -0
- package/dist/console/historyBoundary.d.ts +6 -0
- package/dist/console/historyBoundary.d.ts.map +1 -0
- package/dist/console/inspector.d.ts +3 -0
- package/dist/console/inspector.d.ts.map +1 -0
- package/dist/console/labels.d.ts +12 -0
- package/dist/console/labels.d.ts.map +1 -0
- package/dist/console/opencodeClient.d.ts.map +1 -1
- package/dist/console/refresh.d.ts +3 -0
- package/dist/console/refresh.d.ts.map +1 -0
- package/dist/console/render.d.ts +7 -0
- package/dist/console/render.d.ts.map +1 -1
- package/dist/console/rootAssociation.d.ts +7 -0
- package/dist/console/rootAssociation.d.ts.map +1 -0
- package/dist/index.js +89 -7
- package/dist/messages/consoleDetail.d.ts +54 -0
- package/dist/messages/consoleDetail.d.ts.map +1 -0
- package/dist/messages/orchestration.d.ts +3 -0
- package/dist/messages/orchestration.d.ts.map +1 -1
- package/dist/plugin/orchestrateTool.d.ts.map +1 -1
- package/dist/web/configApi.d.ts +1 -1
- package/dist/web/configApi.d.ts.map +1 -1
- package/dist/web/console.d.ts.map +1 -1
- package/dist/web/conversationRoute.d.ts +16 -0
- package/dist/web/conversationRoute.d.ts.map +1 -0
- package/dist/web/server.d.ts +5 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/start.d.ts +6 -0
- package/dist/web/start.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { exec, execFile as execFile2 } from "node:child_process";
|
|
|
7
7
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
8
8
|
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
9
9
|
import { createRequire as createRequire2 } from "node:module";
|
|
10
|
-
import { dirname as dirname7, resolve as
|
|
10
|
+
import { dirname as dirname7, resolve as resolve10 } from "node:path";
|
|
11
11
|
import { promisify as promisify2 } from "node:util";
|
|
12
12
|
import {
|
|
13
13
|
confirm as clackConfirm,
|
|
@@ -419,6 +419,72 @@ function migrateConfig(raw) {
|
|
|
419
419
|
};
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
+
// src/messages/consoleDetail.ts
|
|
423
|
+
var consoleDetailMessages = {
|
|
424
|
+
follow: "Follow new activity",
|
|
425
|
+
metadataOnly: "Lifecycle and telemetry stay metadata-only.",
|
|
426
|
+
filter: "Filter sessions",
|
|
427
|
+
incoming: "New activity available — show updates",
|
|
428
|
+
refreshError: "Live updates unavailable; retrying.",
|
|
429
|
+
inspectConversation: "Show messages and tool calls",
|
|
430
|
+
refresh: "Refresh conversation",
|
|
431
|
+
close: "Hide messages and tool calls",
|
|
432
|
+
title: "Recorded messages and tool calls",
|
|
433
|
+
orchestrator: "Orchestrator",
|
|
434
|
+
worker: "Worker",
|
|
435
|
+
session: "Session",
|
|
436
|
+
runStarted: "Run started",
|
|
437
|
+
sessionCreated: "Session created",
|
|
438
|
+
firstObserved: "First observed",
|
|
439
|
+
timeUnknown: "Time unknown",
|
|
440
|
+
utc: "UTC",
|
|
441
|
+
technicalID: "Technical ID",
|
|
442
|
+
currentMetadata: "Current opencode title; not historical metadata",
|
|
443
|
+
partialMetadata: "Some current session titles are unavailable or outside the bounded batch; fallback labels remain.",
|
|
444
|
+
rootCurrent: "Current whole orchestrator session; may contain multiple batches. Not a historical or batch-only transcript.",
|
|
445
|
+
recovered: "Read-only association verified from current opencode history; not an immutable lifecycle event.",
|
|
446
|
+
rootUnlinked: "Orchestrator session not recorded. Reveal to try a bounded, read-only relationship search.",
|
|
447
|
+
rootUnavailable: "Orchestrator session unavailable: no unique, verifiable relationship was found in local history.",
|
|
448
|
+
rootAmbiguous: "Orchestrator session unavailable: conflicting or copied relationships are ambiguous.",
|
|
449
|
+
searchIncomplete: "Orchestrator association search incomplete or exceeded its bounded budget. No session was guessed.",
|
|
450
|
+
prompt: "Received prompts",
|
|
451
|
+
assistant: "Visible agent responses",
|
|
452
|
+
tools: "Tool calls ({count})",
|
|
453
|
+
noPrompts: "No received prompt text retained.",
|
|
454
|
+
noOutput: "No visible agent response text retained.",
|
|
455
|
+
noTools: "No tool calls retained.",
|
|
456
|
+
arguments: "Arguments",
|
|
457
|
+
result: "Result",
|
|
458
|
+
loading: "Loading local conversation…",
|
|
459
|
+
current: "Present-day session, not a timeline reconstruction. May include later messages and tools. Refresh explicitly for updates.",
|
|
460
|
+
historical: "Historical cursor: conversation content is hidden to avoid showing future mutable text. Return to live before revealing this operation.",
|
|
461
|
+
disabled: "Content is disabled. Set console.sessionHistory.contentEnabled to true in .opencode/openteam.json and restart the Console. Then reveal content here.",
|
|
462
|
+
unavailable: "Conversation unavailable. Start an operator-owned local opencode serve against the same workspace and user history, configure console.sessionHistory.endpoint, then retry. No inference was requested.",
|
|
463
|
+
empty: "No readable user messages, assistant output or tool calls remain in this session.",
|
|
464
|
+
invalid: "This attempt has no recorded session in the selected run, or its history is incomplete.",
|
|
465
|
+
unauthorized: "Conversation access denied.",
|
|
466
|
+
pending: "Still streaming or unavailable.",
|
|
467
|
+
compacted: "Tool result was compacted by opencode.",
|
|
468
|
+
invalidEndpoint: "Expected a loopback HTTP origin without credentials, path, query or fragment.",
|
|
469
|
+
readFailed: "Local session history could not be read.",
|
|
470
|
+
oversized: "Conversation exceeds the local size limit (4 MiB). No content was loaded.",
|
|
471
|
+
truncated: "Conversation display is truncated by local safety limits; omitted content is not empty history.",
|
|
472
|
+
truncatedMarker: `
|
|
473
|
+
[truncated]`,
|
|
474
|
+
terminalGap: "Live collection was interrupted; events during the gap are unavailable. This is not complete session history.",
|
|
475
|
+
terminalTrimmed: "Older live output was discarded by the local display limit."
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// src/config/historyEndpoint.ts
|
|
479
|
+
function isLocalHistoryEndpoint(value) {
|
|
480
|
+
try {
|
|
481
|
+
const url = new URL(value);
|
|
482
|
+
return url.protocol === "http:" && ["127.0.0.1", "[::1]"].includes(url.hostname) && !url.username && !url.password && url.pathname === "/" && !url.search && !url.hash;
|
|
483
|
+
} catch {
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
422
488
|
// src/config/schema.ts
|
|
423
489
|
var ModelRefSchema = z2.object({
|
|
424
490
|
providerID: z2.string().min(1),
|
|
@@ -478,6 +544,10 @@ var ConsoleConfigSchema = z2.object({
|
|
|
478
544
|
recentRoutes: z2.number().int().positive().default(50),
|
|
479
545
|
openBrowser: z2.boolean().default(false),
|
|
480
546
|
remoteStorage: z2.boolean().default(false),
|
|
547
|
+
sessionHistory: z2.object({
|
|
548
|
+
contentEnabled: z2.boolean().default(false),
|
|
549
|
+
endpoint: z2.string().refine(isLocalHistoryEndpoint, consoleDetailMessages.invalidEndpoint).optional()
|
|
550
|
+
}).strict().optional(),
|
|
481
551
|
terminal: z2.object({
|
|
482
552
|
enabled: z2.boolean().default(true),
|
|
483
553
|
pty: z2.boolean().optional()
|
|
@@ -815,11 +885,638 @@ function resolveMemorySemantic(config) {
|
|
|
815
885
|
return config.memory?.semantic ?? MemorySemanticSchema.parse(undefined);
|
|
816
886
|
}
|
|
817
887
|
|
|
888
|
+
// src/console/conversation.ts
|
|
889
|
+
import { isAbsolute, normalize, parse, resolve, sep } from "node:path";
|
|
890
|
+
import { createOpencodeClient } from "@opencode-ai/sdk";
|
|
891
|
+
import { z as z4 } from "zod";
|
|
892
|
+
|
|
893
|
+
// src/console/historyBoundary.ts
|
|
894
|
+
function only(keys) {
|
|
895
|
+
return (value) => {
|
|
896
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
897
|
+
return value;
|
|
898
|
+
const record = value;
|
|
899
|
+
return Object.fromEntries(keys.filter((key) => Object.hasOwn(record, key)).map((key) => [key, record[key]]));
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
class AssociationError extends Error {
|
|
904
|
+
reason;
|
|
905
|
+
constructor(reason) {
|
|
906
|
+
super(reason === "ambiguous" ? consoleDetailMessages.rootAmbiguous : reason === "incomplete" ? consoleDetailMessages.searchIncomplete : consoleDetailMessages.rootUnavailable);
|
|
907
|
+
this.reason = reason;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// src/console/labels.ts
|
|
912
|
+
function labelFormatters(msg) {
|
|
913
|
+
function boundedTitle(value) {
|
|
914
|
+
if (typeof value !== "string")
|
|
915
|
+
return;
|
|
916
|
+
const title = value.replace(/\p{Cc}|[\u202a-\u202e\u2066-\u2069]/gu, " ").replace(/\s+/g, " ").trim().slice(0, 160);
|
|
917
|
+
return title || undefined;
|
|
918
|
+
}
|
|
919
|
+
function utcTime(value) {
|
|
920
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
921
|
+
return msg.timeUnknown;
|
|
922
|
+
const date = new Date(value);
|
|
923
|
+
return Number.isNaN(date.getTime()) ? msg.timeUnknown : `${date.toISOString().slice(0, -5).replace("T", " ")} ${msg.utc}`;
|
|
924
|
+
}
|
|
925
|
+
function runLabel(run, title) {
|
|
926
|
+
return `${boundedTitle(title) ?? (run.executionAuthority === "coordinator" ? msg.orchestrator : msg.worker)} · ${msg.runStarted}: ${utcTime(run.startedAt)} · ${run.runID}`;
|
|
927
|
+
}
|
|
928
|
+
return { boundedTitle, utcTime, runLabel };
|
|
929
|
+
}
|
|
930
|
+
var { boundedTitle, utcTime, runLabel } = labelFormatters(consoleDetailMessages);
|
|
931
|
+
var LABELS_CLIENT_JS = `
|
|
932
|
+
var consoleLabels=(function(){
|
|
933
|
+
var msg=${JSON.stringify(consoleDetailMessages)};
|
|
934
|
+
var formatters=(${labelFormatters.toString()})(msg);
|
|
935
|
+
var boundedTitle=formatters.boundedTitle,utcTime=formatters.utcTime,runLabel=formatters.runLabel;
|
|
936
|
+
var sessions=new Map(),roots=new Map(),request=null,lastRun=null,lastRead=0;
|
|
937
|
+
function update(data,run){
|
|
938
|
+
(data||[]).slice(0,64).forEach(function(session){
|
|
939
|
+
if(typeof session.id!=='string'||session.id.length>256){return}
|
|
940
|
+
sessions.delete(session.id);sessions.set(session.id,{id:session.id,title:boundedTitle(session.title),createdAt:session.createdAt});
|
|
941
|
+
if(sessions.size>128){sessions.delete(sessions.keys().next().value)}
|
|
942
|
+
if(run){roots.set(run,session.id);if(roots.size>128){roots.delete(roots.keys().next().value)}}
|
|
943
|
+
});
|
|
944
|
+
apply();
|
|
945
|
+
}
|
|
946
|
+
function apply(){
|
|
947
|
+
document.querySelectorAll('[data-session-name]').forEach(function(node){
|
|
948
|
+
var label=sessions.get(node.getAttribute('data-session-name'));
|
|
949
|
+
if(!node.hasAttribute('data-label-fallback')){node.setAttribute('data-label-fallback',node.textContent)}
|
|
950
|
+
if(label){var text=label.title||node.getAttribute('data-label-fallback');if(node.textContent!==text){node.textContent=text}if(node.title!==msg.currentMetadata){node.title=msg.currentMetadata}}
|
|
951
|
+
});
|
|
952
|
+
document.querySelectorAll('[data-session-time]').forEach(function(node){
|
|
953
|
+
var label=sessions.get(node.getAttribute('data-session-time'));
|
|
954
|
+
if(!node.hasAttribute('data-label-fallback')){node.setAttribute('data-label-fallback',node.textContent)}
|
|
955
|
+
if(label){var text=utcTime(label.createdAt)!==msg.timeUnknown?msg.sessionCreated+': '+utcTime(label.createdAt):node.getAttribute('data-label-fallback');if(node.textContent!==text){node.textContent=text}}
|
|
956
|
+
});
|
|
957
|
+
document.querySelectorAll('[data-run-name]').forEach(function(node){
|
|
958
|
+
var id=roots.get(node.getAttribute('data-run-name')),label=sessions.get(id);
|
|
959
|
+
if(label&&label.title){if(node.textContent!==label.title){node.textContent=label.title}if(node.title!==msg.currentMetadata){node.title=msg.currentMetadata}}
|
|
960
|
+
});
|
|
961
|
+
document.querySelectorAll('[data-lifecycle-run-select] option').forEach(function(option){
|
|
962
|
+
var session=sessions.get(option.getAttribute('data-run-session')||roots.get(option.value));
|
|
963
|
+
var raw=option.getAttribute('data-run-started');
|
|
964
|
+
var text=runLabel({runID:option.value,startedAt:raw?Number(raw):null,executionAuthority:option.getAttribute('data-run-authority')},session&&session.title);
|
|
965
|
+
if(option.textContent!==text){option.textContent=text}
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
function load(){
|
|
969
|
+
apply();
|
|
970
|
+
var mount=document.getElementById('lifecycle-timeline-mount');
|
|
971
|
+
if(!mount||mount.getAttribute('data-conversation-transition')==='1'||mount.getAttribute('data-conversation-cursor')){return}
|
|
972
|
+
var run=mount.getAttribute('data-lifecycle-run')||null;
|
|
973
|
+
if(lastRead&&lastRun===run&&Date.now()-lastRead<30000){return}
|
|
974
|
+
if(request){request.abort()}
|
|
975
|
+
lastRun=run;lastRead=Date.now();
|
|
976
|
+
var controller=new AbortController();request=controller;
|
|
977
|
+
var timeout=setTimeout(function(){controller.abort()},15000);
|
|
978
|
+
var query=new URLSearchParams({diagnostic:'1',token:document.documentElement.getAttribute('data-token')||''});
|
|
979
|
+
if(run){query.set('run',run)}
|
|
980
|
+
fetch('/api/graph/session-labels?'+query,{signal:controller.signal,cache:'no-store'}).then(function(r){return r.json()}).then(function(data){
|
|
981
|
+
if(request===controller&&data.kind==='labels'&&data.runID===run){update(data.sessions)}
|
|
982
|
+
}).catch(function(){}).finally(function(){clearTimeout(timeout);if(request===controller){request=null}});
|
|
983
|
+
}
|
|
984
|
+
document.addEventListener('conversation-tree-committed',load);
|
|
985
|
+
document.addEventListener('console-session-metadata',function(event){update([event.detail.session],event.detail.target==='root'?event.detail.runID:null)});
|
|
986
|
+
window.addEventListener('pagehide',function(){if(request){request.abort()}});
|
|
987
|
+
return {apply:apply,refresh:load,runLabel:runLabel,utcTime:utcTime};
|
|
988
|
+
})();
|
|
989
|
+
`;
|
|
990
|
+
|
|
991
|
+
// src/console/rootAssociation.ts
|
|
992
|
+
import { z as z3 } from "zod";
|
|
993
|
+
var Identity = z3.object({
|
|
994
|
+
id: z3.string().min(1).max(256),
|
|
995
|
+
sessionID: z3.string().min(1).max(256)
|
|
996
|
+
}).strict();
|
|
997
|
+
var ObjectField = z3.custom((value) => typeof value === "object" && value !== null && !Array.isArray(value));
|
|
998
|
+
var Row = z3.preprocess(only(["info", "parts"]), z3.object({
|
|
999
|
+
info: z3.preprocess(only(["id", "sessionID", "role"]), Identity.extend({ role: z3.enum(["user", "assistant"]) })),
|
|
1000
|
+
parts: z3.array(z3.unknown()).max(1000)
|
|
1001
|
+
}).strict());
|
|
1002
|
+
var ResultPart = z3.preprocess(only(["id", "sessionID", "messageID", "type", "tool", "callID", "state"]), Identity.extend({
|
|
1003
|
+
messageID: z3.string(),
|
|
1004
|
+
type: z3.literal("tool"),
|
|
1005
|
+
tool: z3.literal("openteam-orchestrate"),
|
|
1006
|
+
callID: z3.string().min(1),
|
|
1007
|
+
state: z3.preprocess(only(["status", "input", "output", "title", "metadata", "time"]), z3.object({
|
|
1008
|
+
status: z3.literal("completed"),
|
|
1009
|
+
input: ObjectField,
|
|
1010
|
+
output: z3.string().max(262144),
|
|
1011
|
+
title: z3.string(),
|
|
1012
|
+
metadata: ObjectField,
|
|
1013
|
+
time: z3.preprocess(only(["start", "end", "compacted"]), z3.object({
|
|
1014
|
+
start: z3.number().finite(),
|
|
1015
|
+
end: z3.number().finite(),
|
|
1016
|
+
compacted: z3.number().finite().optional()
|
|
1017
|
+
}).strict())
|
|
1018
|
+
}).strict())
|
|
1019
|
+
}));
|
|
1020
|
+
function references(raw, sessionID, expected) {
|
|
1021
|
+
const rows = z3.array(Row).max(2000).parse(raw);
|
|
1022
|
+
let matched = false;
|
|
1023
|
+
for (const row of rows) {
|
|
1024
|
+
if (row.info.sessionID !== sessionID)
|
|
1025
|
+
throw new AssociationError("incomplete");
|
|
1026
|
+
for (const rawPart of row.parts) {
|
|
1027
|
+
const part = z3.object({ type: z3.string() }).strict().parse(only(["type"])(rawPart));
|
|
1028
|
+
if (part.type !== "tool")
|
|
1029
|
+
continue;
|
|
1030
|
+
const identity = Identity.extend({
|
|
1031
|
+
messageID: z3.string(),
|
|
1032
|
+
tool: z3.string()
|
|
1033
|
+
}).parse(only(["id", "sessionID", "messageID", "tool"])(rawPart));
|
|
1034
|
+
if (identity.sessionID !== sessionID || identity.messageID !== row.info.id)
|
|
1035
|
+
throw new AssociationError("incomplete");
|
|
1036
|
+
if (row.info.role !== "assistant" || identity.tool !== "openteam-orchestrate")
|
|
1037
|
+
continue;
|
|
1038
|
+
const status = z3.object({
|
|
1039
|
+
state: z3.preprocess(only(["status"]), z3.object({
|
|
1040
|
+
status: z3.enum(["pending", "running", "completed", "error"])
|
|
1041
|
+
}).strict())
|
|
1042
|
+
}).strict().parse(only(["state"])(rawPart)).state.status;
|
|
1043
|
+
if (status !== "completed")
|
|
1044
|
+
continue;
|
|
1045
|
+
const parsed = ResultPart.safeParse(rawPart);
|
|
1046
|
+
if (!parsed.success || parsed.data.state.time?.compacted !== undefined)
|
|
1047
|
+
throw new AssociationError("incomplete");
|
|
1048
|
+
const lines = parsed.data.state.output.split(/\r?\n/);
|
|
1049
|
+
const heading = /^orchestration (?:completed|incomplete) \((\d+) role\(s\)\):$/.exec(lines[0] ?? "");
|
|
1050
|
+
if (!heading)
|
|
1051
|
+
continue;
|
|
1052
|
+
const count = Number(heading[1]);
|
|
1053
|
+
if (count < expected.length || count > 64)
|
|
1054
|
+
continue;
|
|
1055
|
+
const actual = lines.slice(1, 1 + count).map((line) => {
|
|
1056
|
+
const result = /^([A-Za-z0-9_-]+): (ok|failed) → (\S+)(?: \(session ([^\s()]+)\))?(?: \[report: [^\r\n]*\])?(?: — [^\r\n]*)?$/.exec(line);
|
|
1057
|
+
return !result ? undefined : result[4] ? `${result[1]}\x00${result[2]}\x00${result[3]}\x00${result[4]}` : null;
|
|
1058
|
+
});
|
|
1059
|
+
if (actual.length !== count || actual.some((row2) => row2 === undefined))
|
|
1060
|
+
continue;
|
|
1061
|
+
const sessionRows = actual.filter((row2) => row2 !== null);
|
|
1062
|
+
if (sessionRows.length === expected.length && expected.every((key) => sessionRows.filter((item) => item === key).length === 1))
|
|
1063
|
+
matched = true;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
return matched;
|
|
1067
|
+
}
|
|
1068
|
+
async function recoverRootSession(port, projection) {
|
|
1069
|
+
const workers = projection.operations.filter((op) => op.parentOperationID === projection.rootOperationID && op.kind === "role");
|
|
1070
|
+
const last = workers.flatMap((op) => {
|
|
1071
|
+
const attempt = op.attempts.at(-1);
|
|
1072
|
+
return attempt?.sessionID ? [{ op, attempt, sessionID: attempt.sessionID }] : [];
|
|
1073
|
+
});
|
|
1074
|
+
if (!last.length)
|
|
1075
|
+
throw new AssociationError("unavailable");
|
|
1076
|
+
if (last.length > 32)
|
|
1077
|
+
throw new AssociationError("incomplete");
|
|
1078
|
+
const children = [];
|
|
1079
|
+
for (const { sessionID } of last)
|
|
1080
|
+
children.push(await port.get(sessionID));
|
|
1081
|
+
const first = children[0];
|
|
1082
|
+
if (!first)
|
|
1083
|
+
throw new AssociationError("unavailable");
|
|
1084
|
+
const projectID = first.projectID;
|
|
1085
|
+
if (children.some((child) => child.projectID !== projectID))
|
|
1086
|
+
throw new AssociationError("ambiguous");
|
|
1087
|
+
const parents = new Set(children.flatMap((child) => child.parentID ? [child.parentID] : []));
|
|
1088
|
+
if (parents.size > 1)
|
|
1089
|
+
throw new AssociationError("ambiguous");
|
|
1090
|
+
if (first.parentID && children.every((child) => child.parentID)) {
|
|
1091
|
+
const session = await port.get(first.parentID);
|
|
1092
|
+
if (session.projectID !== projectID || children.some((child) => child.id === session.id))
|
|
1093
|
+
throw new AssociationError("ambiguous");
|
|
1094
|
+
return { session, association: "sdk-parent" };
|
|
1095
|
+
}
|
|
1096
|
+
const expected = last.map(({ op, attempt }) => {
|
|
1097
|
+
if (!attempt?.model || !["succeeded", "failed"].includes(attempt.state))
|
|
1098
|
+
throw new AssociationError("unavailable");
|
|
1099
|
+
return `${op.roleID}\x00${attempt.state === "succeeded" ? "ok" : "failed"}\x00${attempt.model.providerID}/${attempt.model.modelID}\x00${attempt.sessionID}`;
|
|
1100
|
+
});
|
|
1101
|
+
let match;
|
|
1102
|
+
try {
|
|
1103
|
+
const candidates = await port.primaries(projectID);
|
|
1104
|
+
for (const listed of candidates) {
|
|
1105
|
+
const session = await port.get(listed.id);
|
|
1106
|
+
if (session.projectID !== projectID || session.parentID !== listed.parentID)
|
|
1107
|
+
throw new AssociationError("incomplete");
|
|
1108
|
+
if (await references(await port.messages(session.id), session.id, expected)) {
|
|
1109
|
+
if (match)
|
|
1110
|
+
throw new AssociationError("ambiguous");
|
|
1111
|
+
match = session;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
} catch (error) {
|
|
1115
|
+
if (error instanceof AssociationError)
|
|
1116
|
+
throw error;
|
|
1117
|
+
throw new AssociationError("incomplete");
|
|
1118
|
+
}
|
|
1119
|
+
if (!match)
|
|
1120
|
+
throw new AssociationError("unavailable");
|
|
1121
|
+
if (parents.size && !parents.has(match.id))
|
|
1122
|
+
throw new AssociationError("ambiguous");
|
|
1123
|
+
return { session: match, association: "tool-result" };
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/console/conversation.ts
|
|
1127
|
+
var CONVERSATION_LIMITS = {
|
|
1128
|
+
bytes: 4 * 1024 * 1024,
|
|
1129
|
+
messages: 200,
|
|
1130
|
+
parts: 100,
|
|
1131
|
+
tools: 200,
|
|
1132
|
+
fieldChars: 16384,
|
|
1133
|
+
totalChars: 262144,
|
|
1134
|
+
argumentDepth: 8,
|
|
1135
|
+
argumentEntries: 512
|
|
1136
|
+
};
|
|
1137
|
+
var SESSION_HISTORY_LIMITS = {
|
|
1138
|
+
bytes: 32 * 1024 * 1024,
|
|
1139
|
+
timeoutMs: 1e4,
|
|
1140
|
+
labels: 64
|
|
1141
|
+
};
|
|
1142
|
+
var SESSION_LIST_WINDOW = 100;
|
|
1143
|
+
|
|
1144
|
+
class ConversationTooLargeError extends Error {
|
|
1145
|
+
constructor() {
|
|
1146
|
+
super(consoleDetailMessages.oversized);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
var Info = z4.preprocess(only(["id", "sessionID", "role", "time"]), z4.object({
|
|
1150
|
+
id: z4.string(),
|
|
1151
|
+
sessionID: z4.string(),
|
|
1152
|
+
role: z4.enum(["user", "assistant"]),
|
|
1153
|
+
time: z4.preprocess(only(["created", "completed"]), z4.object({
|
|
1154
|
+
created: z4.number().finite(),
|
|
1155
|
+
completed: z4.number().finite().optional()
|
|
1156
|
+
}).strict())
|
|
1157
|
+
}).strict());
|
|
1158
|
+
var PartIdentity = z4.object({
|
|
1159
|
+
id: z4.string(),
|
|
1160
|
+
messageID: z4.string(),
|
|
1161
|
+
sessionID: z4.string()
|
|
1162
|
+
}).strict();
|
|
1163
|
+
var Text = PartIdentity.extend({
|
|
1164
|
+
type: z4.literal("text"),
|
|
1165
|
+
text: z4.string(),
|
|
1166
|
+
ignored: z4.boolean().optional()
|
|
1167
|
+
});
|
|
1168
|
+
var Tool = PartIdentity.extend({
|
|
1169
|
+
type: z4.literal("tool"),
|
|
1170
|
+
callID: z4.string(),
|
|
1171
|
+
tool: z4.string(),
|
|
1172
|
+
state: z4.preprocess(only(["status", "input", "output", "error", "time"]), z4.object({
|
|
1173
|
+
status: z4.enum(["pending", "running", "completed", "error"]),
|
|
1174
|
+
input: z4.unknown().refine((value) => typeof value === "object" && value !== null && !Array.isArray(value)),
|
|
1175
|
+
output: z4.string().optional(),
|
|
1176
|
+
error: z4.string().optional(),
|
|
1177
|
+
time: z4.preprocess(only(["start", "end", "compacted"]), z4.object({
|
|
1178
|
+
start: z4.number().finite(),
|
|
1179
|
+
end: z4.number().finite().optional(),
|
|
1180
|
+
compacted: z4.number().finite().optional()
|
|
1181
|
+
}).strict()).optional()
|
|
1182
|
+
}).strict())
|
|
1183
|
+
});
|
|
1184
|
+
var Message = z4.preprocess(only(["info", "parts"]), z4.object({ info: Info, parts: z4.custom(Array.isArray) }).strict());
|
|
1185
|
+
function projectConversation(raw, sessionID) {
|
|
1186
|
+
if (!Array.isArray(raw))
|
|
1187
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1188
|
+
const limits = CONVERSATION_LIMITS;
|
|
1189
|
+
let truncated = raw.length > limits.messages;
|
|
1190
|
+
let remaining = limits.totalChars;
|
|
1191
|
+
let toolsRemaining = limits.tools;
|
|
1192
|
+
function text(value) {
|
|
1193
|
+
const length = Math.min(value.length, limits.fieldChars, remaining);
|
|
1194
|
+
remaining -= length;
|
|
1195
|
+
if (length === value.length)
|
|
1196
|
+
return value;
|
|
1197
|
+
truncated = true;
|
|
1198
|
+
return value.slice(0, length) + consoleDetailMessages.truncatedMarker;
|
|
1199
|
+
}
|
|
1200
|
+
function argumentsText(input) {
|
|
1201
|
+
let entries = limits.argumentEntries;
|
|
1202
|
+
const seen = new Set;
|
|
1203
|
+
function bounded(value, depth) {
|
|
1204
|
+
if (typeof value === "string")
|
|
1205
|
+
return text(value);
|
|
1206
|
+
if (value === null || typeof value === "boolean" || typeof value === "number")
|
|
1207
|
+
return value;
|
|
1208
|
+
if (typeof value !== "object")
|
|
1209
|
+
return null;
|
|
1210
|
+
if (depth >= limits.argumentDepth || entries <= 0 || seen.has(value)) {
|
|
1211
|
+
truncated = true;
|
|
1212
|
+
return consoleDetailMessages.truncatedMarker;
|
|
1213
|
+
}
|
|
1214
|
+
seen.add(value);
|
|
1215
|
+
const result = Object.create(null);
|
|
1216
|
+
const array = [];
|
|
1217
|
+
for (const key in value) {
|
|
1218
|
+
if (!Object.hasOwn(value, key))
|
|
1219
|
+
continue;
|
|
1220
|
+
if (entries-- <= 0 || remaining <= 0) {
|
|
1221
|
+
truncated = true;
|
|
1222
|
+
break;
|
|
1223
|
+
}
|
|
1224
|
+
const child = bounded(value[key], depth + 1);
|
|
1225
|
+
if (Array.isArray(value))
|
|
1226
|
+
array.push(child);
|
|
1227
|
+
else
|
|
1228
|
+
result[text(key)] = child;
|
|
1229
|
+
}
|
|
1230
|
+
return Array.isArray(value) ? array : result;
|
|
1231
|
+
}
|
|
1232
|
+
return text(JSON.stringify(bounded(input, 0), null, 2));
|
|
1233
|
+
}
|
|
1234
|
+
const messages = [];
|
|
1235
|
+
for (const rawRow of raw.slice(0, limits.messages)) {
|
|
1236
|
+
if (remaining <= 0) {
|
|
1237
|
+
truncated = true;
|
|
1238
|
+
break;
|
|
1239
|
+
}
|
|
1240
|
+
const row = Message.parse(rawRow);
|
|
1241
|
+
if (row.info.sessionID !== sessionID)
|
|
1242
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1243
|
+
const message = {
|
|
1244
|
+
id: text(row.info.id),
|
|
1245
|
+
role: row.info.role,
|
|
1246
|
+
createdAt: row.info.time.created,
|
|
1247
|
+
...row.info.time.completed !== undefined ? { completedAt: row.info.time.completed } : {},
|
|
1248
|
+
text: [],
|
|
1249
|
+
tools: []
|
|
1250
|
+
};
|
|
1251
|
+
if (row.parts.length > limits.parts)
|
|
1252
|
+
truncated = true;
|
|
1253
|
+
for (const rawPart of row.parts.slice(0, limits.parts)) {
|
|
1254
|
+
if (remaining <= 0) {
|
|
1255
|
+
truncated = true;
|
|
1256
|
+
break;
|
|
1257
|
+
}
|
|
1258
|
+
const kind = rawPart?.type;
|
|
1259
|
+
if (kind !== "text" && kind !== "tool")
|
|
1260
|
+
continue;
|
|
1261
|
+
const part = kind === "text" ? Text.parse(only(["id", "messageID", "sessionID", "type", "text", "ignored"])(rawPart)) : Tool.parse(only([
|
|
1262
|
+
"id",
|
|
1263
|
+
"messageID",
|
|
1264
|
+
"sessionID",
|
|
1265
|
+
"type",
|
|
1266
|
+
"callID",
|
|
1267
|
+
"tool",
|
|
1268
|
+
"state"
|
|
1269
|
+
])(rawPart));
|
|
1270
|
+
if (part.sessionID !== sessionID || part.messageID !== row.info.id)
|
|
1271
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1272
|
+
if (part.type === "text") {
|
|
1273
|
+
if (!part.ignored)
|
|
1274
|
+
message.text.push(text(part.text));
|
|
1275
|
+
} else {
|
|
1276
|
+
if (toolsRemaining-- <= 0) {
|
|
1277
|
+
truncated = true;
|
|
1278
|
+
continue;
|
|
1279
|
+
}
|
|
1280
|
+
const state = part.state;
|
|
1281
|
+
message.tools.push({
|
|
1282
|
+
id: text(part.callID),
|
|
1283
|
+
name: text(part.tool),
|
|
1284
|
+
status: state.status,
|
|
1285
|
+
arguments: argumentsText(state.input),
|
|
1286
|
+
...state.time !== undefined ? { startedAt: state.time.start } : {},
|
|
1287
|
+
...state.time?.end !== undefined ? { endedAt: state.time.end } : {},
|
|
1288
|
+
...state.time?.compacted !== undefined ? { result: consoleDetailMessages.compacted } : state.status === "completed" && state.output !== undefined ? { result: text(state.output) } : state.status === "error" && state.error !== undefined ? { result: text(state.error) } : {}
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
if (message.text.length || message.tools.length)
|
|
1293
|
+
messages.push(message);
|
|
1294
|
+
}
|
|
1295
|
+
return {
|
|
1296
|
+
...truncated ? { truncated: true } : {},
|
|
1297
|
+
messages: messages.sort((a, b) => a.createdAt - b.createdAt || a.id.localeCompare(b.id))
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
var SessionScope = z4.preprocess(only(["id", "directory", "projectID", "parentID", "title", "time"]), z4.object({
|
|
1301
|
+
id: z4.string().min(1).max(256),
|
|
1302
|
+
directory: z4.string().min(1),
|
|
1303
|
+
projectID: z4.string().min(1),
|
|
1304
|
+
parentID: z4.string().min(1).max(256).optional(),
|
|
1305
|
+
title: z4.unknown().optional(),
|
|
1306
|
+
time: z4.unknown().optional()
|
|
1307
|
+
}).strict());
|
|
1308
|
+
function workspaceKey(directory) {
|
|
1309
|
+
if (!isAbsolute(directory) || directory.includes("\x00"))
|
|
1310
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1311
|
+
const normalized = normalize(directory);
|
|
1312
|
+
const root = parse(normalized).root;
|
|
1313
|
+
const key = normalized.length > root.length && normalized.endsWith(sep) ? normalized.slice(0, -1) : normalized;
|
|
1314
|
+
return process.platform === "win32" ? key.toLowerCase() : key;
|
|
1315
|
+
}
|
|
1316
|
+
async function boundedResponse(response, controller, budget) {
|
|
1317
|
+
const fail = async (error) => {
|
|
1318
|
+
await response.body?.cancel().catch(() => {});
|
|
1319
|
+
controller.abort();
|
|
1320
|
+
throw error;
|
|
1321
|
+
};
|
|
1322
|
+
if (!response.ok || !response.body) {
|
|
1323
|
+
await response.body?.cancel().catch(() => {});
|
|
1324
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1325
|
+
}
|
|
1326
|
+
if (Number(response.headers.get("content-length")) > CONVERSATION_LIMITS.bytes)
|
|
1327
|
+
return fail(new ConversationTooLargeError);
|
|
1328
|
+
const reader = response.body.getReader();
|
|
1329
|
+
const cancel = () => {
|
|
1330
|
+
reader.cancel().catch(() => {});
|
|
1331
|
+
};
|
|
1332
|
+
controller.signal.addEventListener("abort", cancel, { once: true });
|
|
1333
|
+
const bytes = new Uint8Array(CONVERSATION_LIMITS.bytes);
|
|
1334
|
+
let length = 0;
|
|
1335
|
+
try {
|
|
1336
|
+
while (true) {
|
|
1337
|
+
controller.signal.throwIfAborted();
|
|
1338
|
+
const chunk = await reader.read();
|
|
1339
|
+
if (chunk.done)
|
|
1340
|
+
break;
|
|
1341
|
+
if (length + chunk.value.byteLength > CONVERSATION_LIMITS.bytes)
|
|
1342
|
+
throw new ConversationTooLargeError;
|
|
1343
|
+
budget.remaining -= chunk.value.byteLength;
|
|
1344
|
+
if (budget.remaining < 0)
|
|
1345
|
+
throw new AssociationError("incomplete");
|
|
1346
|
+
bytes.set(chunk.value, length);
|
|
1347
|
+
length += chunk.value.byteLength;
|
|
1348
|
+
}
|
|
1349
|
+
controller.signal.throwIfAborted();
|
|
1350
|
+
const headers = new Headers(response.headers);
|
|
1351
|
+
headers.delete("content-length");
|
|
1352
|
+
headers.delete("content-encoding");
|
|
1353
|
+
return new Response(bytes.subarray(0, length), {
|
|
1354
|
+
status: response.status,
|
|
1355
|
+
headers
|
|
1356
|
+
});
|
|
1357
|
+
} catch (error) {
|
|
1358
|
+
await reader.cancel().catch(() => {});
|
|
1359
|
+
controller.abort();
|
|
1360
|
+
throw error;
|
|
1361
|
+
} finally {
|
|
1362
|
+
controller.signal.removeEventListener("abort", cancel);
|
|
1363
|
+
reader.releaseLock();
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
function createConversationReader(deps) {
|
|
1367
|
+
const directory = resolve(deps.directory);
|
|
1368
|
+
const labels = new Map;
|
|
1369
|
+
async function withHistory(endpoint, signal, work, options) {
|
|
1370
|
+
if (!isLocalHistoryEndpoint(endpoint))
|
|
1371
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1372
|
+
const controller = new AbortController;
|
|
1373
|
+
const abort = () => controller.abort();
|
|
1374
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1375
|
+
if (signal?.aborted)
|
|
1376
|
+
controller.abort();
|
|
1377
|
+
const timeout = setTimeout(() => controller.abort(), Math.min(options?.timeoutMs ?? SESSION_HISTORY_LIMITS.timeoutMs, SESSION_HISTORY_LIMITS.timeoutMs));
|
|
1378
|
+
const budget = options?.budget ?? {
|
|
1379
|
+
remaining: SESSION_HISTORY_LIMITS.bytes
|
|
1380
|
+
};
|
|
1381
|
+
try {
|
|
1382
|
+
let scoped = function(raw) {
|
|
1383
|
+
const session = SessionScope.parse(raw);
|
|
1384
|
+
if (workspaceKey(session.directory) !== workspaceKey(directory))
|
|
1385
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1386
|
+
const time = z4.preprocess(only(["created"]), z4.object({ created: z4.number().finite().min(0).max(8640000000000000) }).strict()).safeParse(session.time);
|
|
1387
|
+
const title = boundedTitle(session.title);
|
|
1388
|
+
return {
|
|
1389
|
+
id: session.id,
|
|
1390
|
+
directory: session.directory,
|
|
1391
|
+
projectID: session.projectID,
|
|
1392
|
+
...session.parentID === undefined ? {} : { parentID: session.parentID },
|
|
1393
|
+
label: {
|
|
1394
|
+
id: session.id,
|
|
1395
|
+
...title ? { title } : {},
|
|
1396
|
+
...time.success ? { createdAt: time.data.created } : {}
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
};
|
|
1400
|
+
const client = createOpencodeClient({
|
|
1401
|
+
baseUrl: endpoint,
|
|
1402
|
+
directory,
|
|
1403
|
+
...deps.password ? {
|
|
1404
|
+
headers: {
|
|
1405
|
+
authorization: `Basic ${Buffer.from(`opencode:${deps.password}`).toString("base64")}`
|
|
1406
|
+
}
|
|
1407
|
+
} : {},
|
|
1408
|
+
fetch: async (request) => {
|
|
1409
|
+
controller.signal.throwIfAborted();
|
|
1410
|
+
if (budget.remaining <= 0)
|
|
1411
|
+
throw new AssociationError("incomplete");
|
|
1412
|
+
const response = await (deps.fetch ?? fetch)(request, {
|
|
1413
|
+
signal: controller.signal,
|
|
1414
|
+
redirect: "error"
|
|
1415
|
+
});
|
|
1416
|
+
return boundedResponse(response, controller, budget);
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1419
|
+
const verified = new Map;
|
|
1420
|
+
return await work({
|
|
1421
|
+
get: async (id) => {
|
|
1422
|
+
const result = await client.session.get({ path: { id } });
|
|
1423
|
+
if (!result.response.ok || result.error !== undefined)
|
|
1424
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1425
|
+
const session = scoped(result.data);
|
|
1426
|
+
if (session.id !== id)
|
|
1427
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1428
|
+
verified.set(id, session);
|
|
1429
|
+
const key = JSON.stringify([endpoint, id]);
|
|
1430
|
+
labels.delete(key);
|
|
1431
|
+
labels.set(key, { at: Date.now(), label: session.label });
|
|
1432
|
+
const oldest = labels.keys().next().value;
|
|
1433
|
+
if (labels.size > 128 && oldest !== undefined)
|
|
1434
|
+
labels.delete(oldest);
|
|
1435
|
+
return session;
|
|
1436
|
+
},
|
|
1437
|
+
messages: async (id) => {
|
|
1438
|
+
if (!verified.has(id))
|
|
1439
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1440
|
+
const result = await client.session.messages({ path: { id } });
|
|
1441
|
+
if (!result.response.ok || result.error !== undefined)
|
|
1442
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1443
|
+
return result.data;
|
|
1444
|
+
},
|
|
1445
|
+
primaries: async (projectID) => {
|
|
1446
|
+
const result = await client.session.list({ query: { directory } });
|
|
1447
|
+
if (!result.response.ok || result.error !== undefined || !Array.isArray(result.data) || result.data.length >= SESSION_LIST_WINDOW)
|
|
1448
|
+
throw new AssociationError("incomplete");
|
|
1449
|
+
const candidates = [];
|
|
1450
|
+
const ids = new Set;
|
|
1451
|
+
for (const raw of result.data) {
|
|
1452
|
+
const session = SessionScope.parse(raw);
|
|
1453
|
+
if (workspaceKey(session.directory) !== workspaceKey(directory) || session.projectID !== projectID || session.parentID)
|
|
1454
|
+
continue;
|
|
1455
|
+
if (ids.has(session.id))
|
|
1456
|
+
throw new AssociationError("ambiguous");
|
|
1457
|
+
ids.add(session.id);
|
|
1458
|
+
candidates.push(scoped(raw));
|
|
1459
|
+
}
|
|
1460
|
+
if (candidates.length > 64)
|
|
1461
|
+
throw new AssociationError("incomplete");
|
|
1462
|
+
return candidates;
|
|
1463
|
+
}
|
|
1464
|
+
}, controller.signal);
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
if (error instanceof ConversationTooLargeError || error instanceof AssociationError)
|
|
1467
|
+
throw error;
|
|
1468
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1469
|
+
} finally {
|
|
1470
|
+
clearTimeout(timeout);
|
|
1471
|
+
signal?.removeEventListener("abort", abort);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
const read = async (endpoint, sessionID, signal) => withHistory(endpoint, signal, async (port) => {
|
|
1475
|
+
const session = await port.get(sessionID);
|
|
1476
|
+
return {
|
|
1477
|
+
...projectConversation(await port.messages(sessionID), sessionID),
|
|
1478
|
+
session: session.label
|
|
1479
|
+
};
|
|
1480
|
+
});
|
|
1481
|
+
read.root = (endpoint, projection, signal) => withHistory(endpoint, signal, async (port) => {
|
|
1482
|
+
const recovered = await recoverRootSession(port, projection);
|
|
1483
|
+
return {
|
|
1484
|
+
...projectConversation(await port.messages(recovered.session.id), recovered.session.id),
|
|
1485
|
+
session: recovered.session.label,
|
|
1486
|
+
association: recovered.association
|
|
1487
|
+
};
|
|
1488
|
+
});
|
|
1489
|
+
read.labels = (endpoint, ids, signal, options) => withHistory(endpoint, signal, async (port, historySignal) => {
|
|
1490
|
+
if (ids.length > SESSION_HISTORY_LIMITS.labels)
|
|
1491
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1492
|
+
const result = [];
|
|
1493
|
+
for (const id of new Set(ids)) {
|
|
1494
|
+
controllerCheck(signal);
|
|
1495
|
+
if (historySignal.aborted)
|
|
1496
|
+
break;
|
|
1497
|
+
const cached = labels.get(JSON.stringify([endpoint, id]));
|
|
1498
|
+
if (cached && Date.now() - cached.at < 30000)
|
|
1499
|
+
result.push(cached.label);
|
|
1500
|
+
else {
|
|
1501
|
+
try {
|
|
1502
|
+
result.push((await port.get(id)).label);
|
|
1503
|
+
} catch {}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
controllerCheck(signal);
|
|
1507
|
+
return result;
|
|
1508
|
+
}, options);
|
|
1509
|
+
return read;
|
|
1510
|
+
}
|
|
1511
|
+
function controllerCheck(signal) {
|
|
1512
|
+
signal?.throwIfAborted();
|
|
1513
|
+
}
|
|
1514
|
+
|
|
818
1515
|
// src/console/protocol.ts
|
|
819
|
-
import { z as
|
|
1516
|
+
import { z as z9 } from "zod";
|
|
820
1517
|
|
|
821
1518
|
// src/orchestrator/coordinator.ts
|
|
822
|
-
import { z as
|
|
1519
|
+
import { z as z8 } from "zod";
|
|
823
1520
|
|
|
824
1521
|
// src/context/redaction.ts
|
|
825
1522
|
import { createHash } from "node:crypto";
|
|
@@ -919,41 +1616,41 @@ function splitVirtualPath(path) {
|
|
|
919
1616
|
}
|
|
920
1617
|
|
|
921
1618
|
// src/telemetry/events.ts
|
|
922
|
-
import { z as
|
|
1619
|
+
import { z as z6 } from "zod";
|
|
923
1620
|
|
|
924
1621
|
// src/capabilities/types.ts
|
|
925
|
-
import { z as
|
|
926
|
-
var CapabilityTierSchema =
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1622
|
+
import { z as z5 } from "zod";
|
|
1623
|
+
var CapabilityTierSchema = z5.union([
|
|
1624
|
+
z5.literal(0),
|
|
1625
|
+
z5.literal(1),
|
|
1626
|
+
z5.literal(2),
|
|
1627
|
+
z5.literal(3),
|
|
1628
|
+
z5.literal(4),
|
|
1629
|
+
z5.literal(5)
|
|
933
1630
|
]);
|
|
934
|
-
var ComplexityTierSchema =
|
|
1631
|
+
var ComplexityTierSchema = z5.enum([
|
|
935
1632
|
"trivial",
|
|
936
1633
|
"simple",
|
|
937
1634
|
"moderate",
|
|
938
1635
|
"hard"
|
|
939
1636
|
]);
|
|
940
|
-
var ModelCapabilityProfileSchema =
|
|
941
|
-
ref:
|
|
942
|
-
providerID:
|
|
943
|
-
modelID:
|
|
1637
|
+
var ModelCapabilityProfileSchema = z5.object({
|
|
1638
|
+
ref: z5.object({
|
|
1639
|
+
providerID: z5.string().min(1),
|
|
1640
|
+
modelID: z5.string().min(1)
|
|
944
1641
|
}).strict(),
|
|
945
|
-
kind:
|
|
946
|
-
contextWindow:
|
|
947
|
-
maxOutputTokens:
|
|
948
|
-
supportsToolCalling:
|
|
949
|
-
supportsVision:
|
|
1642
|
+
kind: z5.enum(["local", "frontier", "router"]),
|
|
1643
|
+
contextWindow: z5.number().int().positive(),
|
|
1644
|
+
maxOutputTokens: z5.number().int().positive(),
|
|
1645
|
+
supportsToolCalling: z5.boolean(),
|
|
1646
|
+
supportsVision: z5.boolean(),
|
|
950
1647
|
reasoningTier: CapabilityTierSchema,
|
|
951
1648
|
codeQualityTier: CapabilityTierSchema,
|
|
952
|
-
costPer1M:
|
|
953
|
-
inputUSD:
|
|
954
|
-
outputUSD:
|
|
1649
|
+
costPer1M: z5.object({
|
|
1650
|
+
inputUSD: z5.number().min(0),
|
|
1651
|
+
outputUSD: z5.number().min(0)
|
|
955
1652
|
}).strict(),
|
|
956
|
-
availability:
|
|
1653
|
+
availability: z5.enum(["available", "degraded", "unavailable"])
|
|
957
1654
|
}).strict();
|
|
958
1655
|
|
|
959
1656
|
// src/telemetry/diagnostics.ts
|
|
@@ -1008,97 +1705,97 @@ function diagnosticDescription(code) {
|
|
|
1008
1705
|
|
|
1009
1706
|
// src/telemetry/events.ts
|
|
1010
1707
|
var EVENT_SCHEMA_VERSION = 1;
|
|
1011
|
-
var EventBaseSchema =
|
|
1012
|
-
v:
|
|
1013
|
-
ts:
|
|
1014
|
-
sessionID:
|
|
1708
|
+
var EventBaseSchema = z6.object({
|
|
1709
|
+
v: z6.literal(EVENT_SCHEMA_VERSION),
|
|
1710
|
+
ts: z6.number().finite(),
|
|
1711
|
+
sessionID: z6.string().min(1)
|
|
1015
1712
|
}).strict();
|
|
1016
1713
|
var RouteEventSchema = EventBaseSchema.extend({
|
|
1017
|
-
type:
|
|
1018
|
-
promptHash:
|
|
1019
|
-
promptChars:
|
|
1714
|
+
type: z6.literal("route"),
|
|
1715
|
+
promptHash: z6.string().min(1),
|
|
1716
|
+
promptChars: z6.number().int().min(0),
|
|
1020
1717
|
tier: ComplexityTierSchema,
|
|
1021
|
-
routeKind:
|
|
1718
|
+
routeKind: z6.enum(["local", "frontier", "blocked"]),
|
|
1022
1719
|
selected: ModelRefSchema,
|
|
1023
|
-
rationale:
|
|
1024
|
-
estimatedCostUSD:
|
|
1025
|
-
baselineCostUSD:
|
|
1026
|
-
estimatedSavingsUSD:
|
|
1027
|
-
budgetAction:
|
|
1028
|
-
tokensIn:
|
|
1029
|
-
tokensOut:
|
|
1030
|
-
decisionID:
|
|
1031
|
-
agent:
|
|
1032
|
-
success:
|
|
1033
|
-
batchID:
|
|
1034
|
-
taskID:
|
|
1035
|
-
failureReason:
|
|
1036
|
-
failureStage:
|
|
1720
|
+
rationale: z6.string(),
|
|
1721
|
+
estimatedCostUSD: z6.number().finite().min(0).nullable(),
|
|
1722
|
+
baselineCostUSD: z6.number().finite().min(0).nullable(),
|
|
1723
|
+
estimatedSavingsUSD: z6.number().finite().nullable(),
|
|
1724
|
+
budgetAction: z6.string().min(1),
|
|
1725
|
+
tokensIn: z6.number().int().min(0).optional(),
|
|
1726
|
+
tokensOut: z6.number().int().min(0).optional(),
|
|
1727
|
+
decisionID: z6.string().min(1).optional(),
|
|
1728
|
+
agent: z6.string().min(1).optional(),
|
|
1729
|
+
success: z6.boolean().optional(),
|
|
1730
|
+
batchID: z6.string().min(1).optional(),
|
|
1731
|
+
taskID: z6.string().min(1).optional(),
|
|
1732
|
+
failureReason: z6.string().min(1).optional(),
|
|
1733
|
+
failureStage: z6.string().min(1).optional()
|
|
1037
1734
|
});
|
|
1038
1735
|
var MessageEventSchema = EventBaseSchema.extend({
|
|
1039
|
-
type:
|
|
1040
|
-
providerID:
|
|
1041
|
-
modelID:
|
|
1042
|
-
agent:
|
|
1043
|
-
mode:
|
|
1044
|
-
messageID:
|
|
1045
|
-
costUSD:
|
|
1046
|
-
tokensIn:
|
|
1047
|
-
tokensOut:
|
|
1048
|
-
tokensReasoning:
|
|
1049
|
-
tokensCacheRead:
|
|
1050
|
-
tokensCacheWrite:
|
|
1051
|
-
durationMs:
|
|
1736
|
+
type: z6.literal("message"),
|
|
1737
|
+
providerID: z6.string().min(1),
|
|
1738
|
+
modelID: z6.string().min(1),
|
|
1739
|
+
agent: z6.string().min(1).optional(),
|
|
1740
|
+
mode: z6.string().min(1).optional(),
|
|
1741
|
+
messageID: z6.string().min(1).optional(),
|
|
1742
|
+
costUSD: z6.number().finite().min(0),
|
|
1743
|
+
tokensIn: z6.number().int().min(0),
|
|
1744
|
+
tokensOut: z6.number().int().min(0),
|
|
1745
|
+
tokensReasoning: z6.number().int().min(0),
|
|
1746
|
+
tokensCacheRead: z6.number().int().min(0),
|
|
1747
|
+
tokensCacheWrite: z6.number().int().min(0),
|
|
1748
|
+
durationMs: z6.number().int().min(0)
|
|
1052
1749
|
});
|
|
1053
1750
|
var ToolcallEventSchema = EventBaseSchema.extend({
|
|
1054
|
-
type:
|
|
1055
|
-
tool:
|
|
1056
|
-
callID:
|
|
1057
|
-
agent:
|
|
1058
|
-
durationMs:
|
|
1059
|
-
ok:
|
|
1060
|
-
title:
|
|
1751
|
+
type: z6.literal("toolcall"),
|
|
1752
|
+
tool: z6.string().min(1),
|
|
1753
|
+
callID: z6.string().min(1),
|
|
1754
|
+
agent: z6.string().min(1).optional(),
|
|
1755
|
+
durationMs: z6.number().int().min(0),
|
|
1756
|
+
ok: z6.boolean(),
|
|
1757
|
+
title: z6.string().optional()
|
|
1061
1758
|
});
|
|
1062
1759
|
var MeetingEventSchema = EventBaseSchema.extend({
|
|
1063
|
-
type:
|
|
1064
|
-
batchID:
|
|
1065
|
-
purpose:
|
|
1066
|
-
roles:
|
|
1067
|
-
decisionIDs:
|
|
1760
|
+
type: z6.literal("meeting"),
|
|
1761
|
+
batchID: z6.string().min(1),
|
|
1762
|
+
purpose: z6.string().optional(),
|
|
1763
|
+
roles: z6.array(z6.string().min(1)),
|
|
1764
|
+
decisionIDs: z6.array(z6.string().min(1)).optional()
|
|
1068
1765
|
});
|
|
1069
1766
|
var QueueEventSchema = EventBaseSchema.extend({
|
|
1070
|
-
type:
|
|
1071
|
-
runtimeId:
|
|
1072
|
-
waitedMs:
|
|
1073
|
-
activeCount:
|
|
1074
|
-
queuedCount:
|
|
1075
|
-
decisionID:
|
|
1076
|
-
agent:
|
|
1077
|
-
batchID:
|
|
1767
|
+
type: z6.literal("queue"),
|
|
1768
|
+
runtimeId: z6.string().min(1),
|
|
1769
|
+
waitedMs: z6.number().finite().min(0),
|
|
1770
|
+
activeCount: z6.number().int().min(0),
|
|
1771
|
+
queuedCount: z6.number().int().min(0),
|
|
1772
|
+
decisionID: z6.string().min(1).optional(),
|
|
1773
|
+
agent: z6.string().min(1).optional(),
|
|
1774
|
+
batchID: z6.string().min(1).optional()
|
|
1078
1775
|
});
|
|
1079
1776
|
var DecisionEventSchema = EventBaseSchema.extend({
|
|
1080
|
-
type:
|
|
1081
|
-
agent:
|
|
1082
|
-
summary:
|
|
1083
|
-
tags:
|
|
1777
|
+
type: z6.literal("decision"),
|
|
1778
|
+
agent: z6.string().min(1).optional(),
|
|
1779
|
+
summary: z6.string().min(1),
|
|
1780
|
+
tags: z6.array(z6.string().min(1)).optional()
|
|
1084
1781
|
});
|
|
1085
1782
|
var ActivityEventSchema = EventBaseSchema.extend({
|
|
1086
|
-
type:
|
|
1087
|
-
kind:
|
|
1088
|
-
agent:
|
|
1089
|
-
summary:
|
|
1783
|
+
type: z6.literal("activity"),
|
|
1784
|
+
kind: z6.enum(["route", "agent", "decision", "commit"]),
|
|
1785
|
+
agent: z6.string().min(1).optional(),
|
|
1786
|
+
summary: z6.string().min(1)
|
|
1090
1787
|
});
|
|
1091
1788
|
var SessionEndpointEventSchema = EventBaseSchema.extend({
|
|
1092
|
-
type:
|
|
1093
|
-
url:
|
|
1094
|
-
directory:
|
|
1095
|
-
worktree:
|
|
1096
|
-
title:
|
|
1789
|
+
type: z6.literal("session-endpoint"),
|
|
1790
|
+
url: z6.string().url(),
|
|
1791
|
+
directory: z6.string().min(1).optional(),
|
|
1792
|
+
worktree: z6.string().min(1).optional(),
|
|
1793
|
+
title: z6.string().min(1).optional()
|
|
1097
1794
|
});
|
|
1098
1795
|
var ShadowDiagnosticEventSchema = EventBaseSchema.extend({
|
|
1099
|
-
type:
|
|
1100
|
-
batchID:
|
|
1101
|
-
failureClass:
|
|
1796
|
+
type: z6.literal("shadow-diagnostic"),
|
|
1797
|
+
batchID: z6.string().min(1),
|
|
1798
|
+
failureClass: z6.enum([
|
|
1102
1799
|
"invalid-node-id",
|
|
1103
1800
|
"journal-create-failed",
|
|
1104
1801
|
"journal-append-failed",
|
|
@@ -1109,16 +1806,16 @@ var ShadowDiagnosticEventSchema = EventBaseSchema.extend({
|
|
|
1109
1806
|
"unknown"
|
|
1110
1807
|
])
|
|
1111
1808
|
});
|
|
1112
|
-
var DiagnosticLevelSchema =
|
|
1113
|
-
var DiagnosticCodeSchema =
|
|
1809
|
+
var DiagnosticLevelSchema = z6.enum(["debug", "info", "warn", "error"]);
|
|
1810
|
+
var DiagnosticCodeSchema = z6.enum(DIAGNOSTIC_CODES);
|
|
1114
1811
|
var DiagnosticEventSchema = EventBaseSchema.extend({
|
|
1115
|
-
type:
|
|
1812
|
+
type: z6.literal("diagnostic"),
|
|
1116
1813
|
level: DiagnosticLevelSchema,
|
|
1117
1814
|
code: DiagnosticCodeSchema,
|
|
1118
|
-
roleID:
|
|
1119
|
-
passCount:
|
|
1815
|
+
roleID: z6.string().min(1).optional(),
|
|
1816
|
+
passCount: z6.number().int().min(0).optional()
|
|
1120
1817
|
});
|
|
1121
|
-
var OpenTeamEventSchema =
|
|
1818
|
+
var OpenTeamEventSchema = z6.discriminatedUnion("type", [
|
|
1122
1819
|
RouteEventSchema,
|
|
1123
1820
|
MessageEventSchema,
|
|
1124
1821
|
ToolcallEventSchema,
|
|
@@ -1227,22 +1924,22 @@ function createFsStorageProvider(root) {
|
|
|
1227
1924
|
}
|
|
1228
1925
|
|
|
1229
1926
|
// src/telemetry/types.ts
|
|
1230
|
-
import { z as
|
|
1231
|
-
var CostRecordSchema =
|
|
1232
|
-
ts:
|
|
1233
|
-
sessionID:
|
|
1234
|
-
promptHash:
|
|
1235
|
-
promptChars:
|
|
1927
|
+
import { z as z7 } from "zod";
|
|
1928
|
+
var CostRecordSchema = z7.object({
|
|
1929
|
+
ts: z7.number().finite(),
|
|
1930
|
+
sessionID: z7.string().min(1).optional(),
|
|
1931
|
+
promptHash: z7.string().min(1),
|
|
1932
|
+
promptChars: z7.number().int().min(0),
|
|
1236
1933
|
tier: ComplexityTierSchema,
|
|
1237
|
-
routeKind:
|
|
1934
|
+
routeKind: z7.enum(["local", "frontier", "blocked"]),
|
|
1238
1935
|
selected: ModelRefSchema,
|
|
1239
|
-
rationale:
|
|
1240
|
-
estimatedCostUSD:
|
|
1241
|
-
baselineCostUSD:
|
|
1242
|
-
estimatedSavingsUSD:
|
|
1243
|
-
budgetAction:
|
|
1244
|
-
tokensIn:
|
|
1245
|
-
tokensOut:
|
|
1936
|
+
rationale: z7.string(),
|
|
1937
|
+
estimatedCostUSD: z7.number().finite().min(0).nullable(),
|
|
1938
|
+
baselineCostUSD: z7.number().finite().min(0).nullable(),
|
|
1939
|
+
estimatedSavingsUSD: z7.number().finite().nullable(),
|
|
1940
|
+
budgetAction: z7.string().min(1),
|
|
1941
|
+
tokensIn: z7.number().int().min(0).optional(),
|
|
1942
|
+
tokensOut: z7.number().int().min(0).optional()
|
|
1246
1943
|
}).strict();
|
|
1247
1944
|
|
|
1248
1945
|
// src/telemetry/read.ts
|
|
@@ -1430,7 +2127,7 @@ function hashPrompt(prompt) {
|
|
|
1430
2127
|
}
|
|
1431
2128
|
|
|
1432
2129
|
// src/orchestrator/coordinator.ts
|
|
1433
|
-
var TelemetryFailureClassSchema =
|
|
2130
|
+
var TelemetryFailureClassSchema = z8.enum([
|
|
1434
2131
|
"create-rejected",
|
|
1435
2132
|
"create-no-id",
|
|
1436
2133
|
"prompt-rejected",
|
|
@@ -1581,8 +2278,8 @@ function redactFrameText(text) {
|
|
|
1581
2278
|
return `[redacted · ${text.length} chars · ${hashPrompt(text)}]`;
|
|
1582
2279
|
}
|
|
1583
2280
|
var MAX_INPUT_CHARS = 1e5;
|
|
1584
|
-
var SessionInputSchema =
|
|
1585
|
-
text:
|
|
2281
|
+
var SessionInputSchema = z9.object({
|
|
2282
|
+
text: z9.string().min(1).max(MAX_INPUT_CHARS)
|
|
1586
2283
|
}).strict();
|
|
1587
2284
|
function parseSessionInput(raw) {
|
|
1588
2285
|
const result = SessionInputSchema.safeParse(raw);
|
|
@@ -1768,13 +2465,20 @@ function createConsoleClient(deps) {
|
|
|
1768
2465
|
await post(`/session/${encodeURIComponent(sessionID)}/permissions/${encodeURIComponent(permissionID)}`, { response });
|
|
1769
2466
|
},
|
|
1770
2467
|
async listMessages(sessionID, options) {
|
|
1771
|
-
const res = await doFetch(`${base}/session/${encodeURIComponent(sessionID)}/message`, {
|
|
2468
|
+
const res = await doFetch(`${base}/session/${encodeURIComponent(sessionID)}/message`, {
|
|
2469
|
+
headers: { accept: "application/json", ...authHeaders },
|
|
2470
|
+
signal: AbortSignal.timeout(1e4)
|
|
2471
|
+
});
|
|
2472
|
+
if (!res.ok)
|
|
2473
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1772
2474
|
let raw;
|
|
1773
2475
|
try {
|
|
1774
2476
|
raw = await res.json();
|
|
1775
2477
|
} catch {
|
|
1776
|
-
|
|
2478
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1777
2479
|
}
|
|
2480
|
+
if (!Array.isArray(raw))
|
|
2481
|
+
throw new Error(consoleDetailMessages.readFailed);
|
|
1778
2482
|
return messagesToFrames(raw, sessionID, options ?? {});
|
|
1779
2483
|
},
|
|
1780
2484
|
async streamFrames(sessionID, onFrame, signal, options) {
|
|
@@ -2302,7 +3006,7 @@ async function buildSqliteIndexFromConfig(path, sessionsDir, deps) {
|
|
|
2302
3006
|
}
|
|
2303
3007
|
|
|
2304
3008
|
// src/config/errors.ts
|
|
2305
|
-
import { z as
|
|
3009
|
+
import { z as z10 } from "zod";
|
|
2306
3010
|
var ROOT_PATH = "<root>";
|
|
2307
3011
|
var MODEL_REF_KEYS = ["providerID", "modelID"];
|
|
2308
3012
|
var KNOWN_CONFIG_KEYS_BY_PATH = new Map([
|
|
@@ -2377,11 +3081,13 @@ var KNOWN_CONFIG_KEYS_BY_PATH = new Map([
|
|
|
2377
3081
|
"openBrowser",
|
|
2378
3082
|
"remoteStorage",
|
|
2379
3083
|
"terminal",
|
|
2380
|
-
"graphView"
|
|
3084
|
+
"graphView",
|
|
3085
|
+
"sessionHistory"
|
|
2381
3086
|
]
|
|
2382
3087
|
],
|
|
2383
3088
|
["console.terminal", ["enabled", "pty"]],
|
|
2384
3089
|
["console.graphView", ["enabled"]],
|
|
3090
|
+
["console.sessionHistory", ["contentEnabled", "endpoint"]],
|
|
2385
3091
|
["storage", ["sqliteIndex"]],
|
|
2386
3092
|
["storage.sqliteIndex", ["enabled", "path"]],
|
|
2387
3093
|
["memory", ["semantic"]],
|
|
@@ -2506,7 +3212,7 @@ function formatUnrecognizedKeys(issues, knownKeysByPath) {
|
|
|
2506
3212
|
return messages;
|
|
2507
3213
|
}
|
|
2508
3214
|
function formatZodBoundaryError(error, options = {}) {
|
|
2509
|
-
if (error instanceof
|
|
3215
|
+
if (error instanceof z10.ZodError) {
|
|
2510
3216
|
const unknownKeys = formatUnrecognizedKeys(error.issues, options.knownKeysByPath ?? KNOWN_CONFIG_KEYS_BY_PATH);
|
|
2511
3217
|
const otherIssues = error.issues.filter((issue) => !isUnrecognizedKeysIssue(issue)).map((issue) => {
|
|
2512
3218
|
const path = formatConfigPath(issue.path);
|
|
@@ -2656,17 +3362,17 @@ function compareRoleIDs([left], [right]) {
|
|
|
2656
3362
|
return left === right ? 0 : left < right ? -1 : 1;
|
|
2657
3363
|
}
|
|
2658
3364
|
function policyModelReferences(policy, path) {
|
|
2659
|
-
const
|
|
3365
|
+
const references2 = [];
|
|
2660
3366
|
if (policy?.model !== undefined && policy.model !== "auto") {
|
|
2661
|
-
|
|
3367
|
+
references2.push({ path: `${path}.model`, model: policy.model });
|
|
2662
3368
|
}
|
|
2663
3369
|
for (const [index, fallback] of (policy?.fallbacks ?? []).entries()) {
|
|
2664
|
-
|
|
3370
|
+
references2.push({
|
|
2665
3371
|
path: `${path}.fallbacks.${index}`,
|
|
2666
3372
|
model: fallback
|
|
2667
3373
|
});
|
|
2668
3374
|
}
|
|
2669
|
-
return
|
|
3375
|
+
return references2;
|
|
2670
3376
|
}
|
|
2671
3377
|
function configuredPolicies(config) {
|
|
2672
3378
|
const policies = [
|
|
@@ -2829,7 +3535,7 @@ async function writeOpenTeamConfigFile(config, path = DEFAULT_CONFIG_PATH, stora
|
|
|
2829
3535
|
}
|
|
2830
3536
|
|
|
2831
3537
|
// src/config/runtime.ts
|
|
2832
|
-
import { z as
|
|
3538
|
+
import { z as z11 } from "zod";
|
|
2833
3539
|
var CONFIG_KEYS = [
|
|
2834
3540
|
"baseline",
|
|
2835
3541
|
"router",
|
|
@@ -2845,18 +3551,18 @@ var CONFIG_KEYS = [
|
|
|
2845
3551
|
];
|
|
2846
3552
|
var CONFIG_KEY_SET = new Set(CONFIG_KEYS);
|
|
2847
3553
|
var TELEMETRY_PLUGIN_OPTION_KEY = "telemetry";
|
|
2848
|
-
var configOptionSchemas = Object.fromEntries(CONFIG_KEYS.map((key) => [key,
|
|
2849
|
-
var TelemetryPluginOptionsObjectSchema =
|
|
2850
|
-
enabled:
|
|
2851
|
-
path:
|
|
2852
|
-
sessionsDir:
|
|
3554
|
+
var configOptionSchemas = Object.fromEntries(CONFIG_KEYS.map((key) => [key, z11.unknown().optional()]));
|
|
3555
|
+
var TelemetryPluginOptionsObjectSchema = z11.object({
|
|
3556
|
+
enabled: z11.boolean().default(true),
|
|
3557
|
+
path: z11.string().min(1).default(DEFAULT_TELEMETRY_PATH),
|
|
3558
|
+
sessionsDir: z11.string().min(1).default(DEFAULT_SESSIONS_DIR)
|
|
2853
3559
|
}).strict();
|
|
2854
3560
|
var TelemetryPluginOptionsSchema = TelemetryPluginOptionsObjectSchema.default({
|
|
2855
3561
|
enabled: true,
|
|
2856
3562
|
path: DEFAULT_TELEMETRY_PATH,
|
|
2857
3563
|
sessionsDir: DEFAULT_SESSIONS_DIR
|
|
2858
3564
|
});
|
|
2859
|
-
var PluginOptionsObjectSchema =
|
|
3565
|
+
var PluginOptionsObjectSchema = z11.object({
|
|
2860
3566
|
...configOptionSchemas,
|
|
2861
3567
|
[TELEMETRY_PLUGIN_OPTION_KEY]: TelemetryPluginOptionsObjectSchema.optional()
|
|
2862
3568
|
}).strict();
|
|
@@ -2978,7 +3684,8 @@ function isJsonObject2(value) {
|
|
|
2978
3684
|
var MACHINE_SPECIFIC_KEYS = [
|
|
2979
3685
|
"local.runtimes",
|
|
2980
3686
|
"console.host",
|
|
2981
|
-
"console.port"
|
|
3687
|
+
"console.port",
|
|
3688
|
+
"console.sessionHistory"
|
|
2982
3689
|
];
|
|
2983
3690
|
var HOT_RELOADABLE_KEYS = ["console.refreshMs"];
|
|
2984
3691
|
var KNOWN_ENV_SECRETS = [
|
|
@@ -3531,10 +4238,411 @@ async function handleLifecycleHistoryRoute(request, response, url, deps) {
|
|
|
3531
4238
|
return true;
|
|
3532
4239
|
}
|
|
3533
4240
|
|
|
4241
|
+
// src/console/inspector.ts
|
|
4242
|
+
var CONVERSATION_CLIENT_JS = `
|
|
4243
|
+
function wireConversationInspector(){
|
|
4244
|
+
var mount=document.getElementById('lifecycle-timeline-mount');
|
|
4245
|
+
if(!mount){return}
|
|
4246
|
+
var msg=${JSON.stringify(consoleDetailMessages)};
|
|
4247
|
+
var limits=${JSON.stringify(CONVERSATION_LIMITS)};
|
|
4248
|
+
var panel=document.createElement('section');panel.className='lc-conversation';panel.hidden=true;panel.id='lc-attempt-conversation';
|
|
4249
|
+
panel.setAttribute('data-conversation-inspector','');
|
|
4250
|
+
panel.setAttribute('aria-labelledby','lc-conversation-heading');
|
|
4251
|
+
mount.appendChild(panel);
|
|
4252
|
+
var selection=null,request=null,epoch=0,retained=null;
|
|
4253
|
+
function element(tag,text){var e=document.createElement(tag);if(text!==undefined){e.textContent=text}return e}
|
|
4254
|
+
function selectedButton(){
|
|
4255
|
+
if(!selection||mount.getAttribute('data-conversation-transition')==='1'||
|
|
4256
|
+
mount.getAttribute('data-lifecycle-run')!==selection.run||
|
|
4257
|
+
(mount.getAttribute('data-conversation-cursor')||null)!==selection.cursor){return null}
|
|
4258
|
+
return Array.from(mount.querySelectorAll('[data-inspect-attempt],[data-inspect-root]')).find(function(button){
|
|
4259
|
+
var attempt=button.closest('[data-lifecycle-attempt-id]');
|
|
4260
|
+
var operation=button.closest('[data-lifecycle-operation-id]');
|
|
4261
|
+
var session=button.closest(selection.target==='root'?'[data-root-session-id]':'[data-lifecycle-session-id]');
|
|
4262
|
+
return !button.disabled&&operation&&session&&
|
|
4263
|
+
(selection.target==='root'?button.hasAttribute('data-inspect-root'):attempt&&attempt.getAttribute('data-lifecycle-attempt-id')===selection.attempt&&
|
|
4264
|
+
button.getAttribute('data-inspect-attempt')===selection.attempt)&&
|
|
4265
|
+
operation.getAttribute('data-lifecycle-operation-id')===selection.operation&&
|
|
4266
|
+
button.getAttribute('data-inspect-operation')===selection.operation&&
|
|
4267
|
+
session.getAttribute(selection.target==='root'?'data-root-session-id':'data-lifecycle-session-id')===selection.session;
|
|
4268
|
+
})||null;
|
|
4269
|
+
}
|
|
4270
|
+
function expanded(button,open){
|
|
4271
|
+
if(button.getAttribute('aria-expanded')!==String(open)){button.setAttribute('aria-expanded',String(open))}
|
|
4272
|
+
var label=open?msg.close:msg.inspectConversation;
|
|
4273
|
+
if(button.textContent!==label){button.textContent=label}
|
|
4274
|
+
}
|
|
4275
|
+
function cancel(){
|
|
4276
|
+
epoch++;if(request){request.abort();request=null}
|
|
4277
|
+
}
|
|
4278
|
+
function close(focus){
|
|
4279
|
+
var button=selectedButton();
|
|
4280
|
+
cancel();selection=null;retained=null;
|
|
4281
|
+
mount.querySelectorAll('[data-inspect-attempt],[data-inspect-root]').forEach(function(control){expanded(control,false)});
|
|
4282
|
+
panel.textContent='';panel.hidden=true;
|
|
4283
|
+
['data-conversation-kind','data-conversation-run','data-conversation-operation','data-conversation-attempt','data-conversation-session','data-conversation-target','aria-busy'].forEach(function(name){panel.removeAttribute(name)});
|
|
4284
|
+
mount.appendChild(panel);
|
|
4285
|
+
if(focus===true&&button){button.focus({preventScroll:true})}
|
|
4286
|
+
}
|
|
4287
|
+
// The renderer replaces metadata, not retained content. Restore only after
|
|
4288
|
+
// the real run/cursor commits and the same attempt/session is still visible.
|
|
4289
|
+
function retain(){
|
|
4290
|
+
if(!selection||panel.hidden||!selectedButton()){return}
|
|
4291
|
+
var scrolls=[],ancestor=panel.parentElement;
|
|
4292
|
+
while(ancestor){scrolls.push([ancestor,ancestor.scrollTop,ancestor.scrollLeft]);ancestor=ancestor.parentElement}
|
|
4293
|
+
panel.querySelectorAll('pre,[data-conversation-tool-list]').forEach(function(node){scrolls.push([node,node.scrollTop,node.scrollLeft])});
|
|
4294
|
+
retained={scrolls:scrolls,top:panel.getBoundingClientRect().top,focus:panel.contains(document.activeElement)?document.activeElement:null};
|
|
4295
|
+
}
|
|
4296
|
+
function reanchor(){
|
|
4297
|
+
if(!selection){return}
|
|
4298
|
+
var button=selectedButton();
|
|
4299
|
+
if(!button){close();return}
|
|
4300
|
+
var attempt=selection.target==='root'?button.closest('.lct-operation-card'):button.closest('[data-lifecycle-attempt-id]');
|
|
4301
|
+
if(panel.parentElement!==attempt){attempt.appendChild(panel)}
|
|
4302
|
+
expanded(button,true);
|
|
4303
|
+
if(retained){
|
|
4304
|
+
retained.scrolls.forEach(function(item){if(item[0].isConnected){item[0].scrollTop=item[1];item[0].scrollLeft=item[2]}});
|
|
4305
|
+
var tree=mount.querySelector('[data-lifecycle-tree-mount]');
|
|
4306
|
+
if(tree){tree.scrollTop+=panel.getBoundingClientRect().top-retained.top}
|
|
4307
|
+
if(retained.focus){retained.focus.focus({preventScroll:true})}
|
|
4308
|
+
retained=null;
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
function reset(){
|
|
4312
|
+
panel.textContent='';
|
|
4313
|
+
var header=element('header');header.className='lc-conversation-head';
|
|
4314
|
+
var heading=element('h3',msg.title);heading.id='lc-conversation-heading';heading.tabIndex=-1;header.appendChild(heading);
|
|
4315
|
+
var closeBtn=element('button',msg.close);closeBtn.type='button';
|
|
4316
|
+
closeBtn.setAttribute('data-conversation-close','');
|
|
4317
|
+
closeBtn.addEventListener('click',function(){close(true)});header.appendChild(closeBtn);panel.appendChild(header);
|
|
4318
|
+
}
|
|
4319
|
+
function showHeading(){
|
|
4320
|
+
var heading=panel.querySelector('h3');
|
|
4321
|
+
heading.focus({preventScroll:true});
|
|
4322
|
+
heading.scrollIntoView({block:'start',inline:'nearest'});
|
|
4323
|
+
}
|
|
4324
|
+
function load(reveal){
|
|
4325
|
+
if(!selectedButton()){return}
|
|
4326
|
+
cancel();var current=epoch,selected=selection;
|
|
4327
|
+
reset();
|
|
4328
|
+
panel.setAttribute('data-conversation-kind','loading');
|
|
4329
|
+
panel.setAttribute('aria-busy','true');
|
|
4330
|
+
var status=element('p',msg.loading);status.setAttribute('role','status');panel.appendChild(status);
|
|
4331
|
+
var opening=null;
|
|
4332
|
+
if(reveal===true){
|
|
4333
|
+
showHeading();
|
|
4334
|
+
opening={focus:document.activeElement,scrolls:[mount.querySelector('[data-lifecycle-tree-mount]'),mount.closest('.scroll')].filter(Boolean).map(function(node){return [node,node.scrollTop,node.scrollLeft]})};
|
|
4335
|
+
}
|
|
4336
|
+
var controller=new AbortController();request=controller;
|
|
4337
|
+
var query=new URLSearchParams({run:selected.run,operation:selected.operation,diagnostic:'1'});
|
|
4338
|
+
if(selected.target==='root'){query.set('target','root')}else{query.set('attempt',selected.attempt)}
|
|
4339
|
+
query.set('token',document.documentElement.getAttribute('data-token')||'');
|
|
4340
|
+
if(selected.cursor!==null){query.set('cursor',selected.cursor)}
|
|
4341
|
+
var timeout=setTimeout(function(){controller.abort()},15000);
|
|
4342
|
+
fetch('/api/graph/conversation?'+query.toString(),{signal:controller.signal,cache:'no-store'})
|
|
4343
|
+
.then(function(r){return r.json()}).then(function(data){
|
|
4344
|
+
if(epoch!==current||selection!==selected||!selectedButton()){return}
|
|
4345
|
+
var bringIntoView=opening&&document.activeElement===opening.focus&&opening.scrolls.every(function(item){return item[0].scrollTop===item[1]&&item[0].scrollLeft===item[2]});
|
|
4346
|
+
if((data.kind==='conversation'||data.kind==='empty')&&(data.runID!==selected.run||data.operationID!==selected.operation||
|
|
4347
|
+
(selected.target==='root'?(data.target!=='root'||data.attemptID!==undefined||!data.sessionID||(!selected.session&&!['sdk-parent','tool-result'].includes(data.association))):(data.target!=='attempt'||data.attemptID!==selected.attempt))||
|
|
4348
|
+
(selected.session&&data.sessionID!==selected.session))){
|
|
4349
|
+
data={kind:'unavailable',message:msg.unavailable};
|
|
4350
|
+
}
|
|
4351
|
+
status.textContent=data.message||msg.unavailable;
|
|
4352
|
+
panel.setAttribute('data-conversation-kind',data.kind||'unavailable');
|
|
4353
|
+
if(data.kind==='conversation'||data.kind==='empty'){
|
|
4354
|
+
panel.setAttribute('data-conversation-session',data.sessionID);
|
|
4355
|
+
var source=element('p');source.appendChild(element('strong',data.session&&data.session.title|| (selected.target==='root'?msg.orchestrator:msg.session)));
|
|
4356
|
+
var created=consoleLabels.utcTime(data.session&&data.session.createdAt);
|
|
4357
|
+
source.appendChild(element('small',' · '+(created===msg.timeUnknown?msg.timeUnknown:msg.sessionCreated+': '+created)));
|
|
4358
|
+
source.appendChild(element('code',' · '+data.sessionID));panel.appendChild(source);
|
|
4359
|
+
if(data.session&&data.session.id===data.sessionID){document.dispatchEvent(new CustomEvent('console-session-metadata',{detail:{session:data.session,runID:data.runID,target:selected.target}}))}
|
|
4360
|
+
}
|
|
4361
|
+
if(data.kind==='conversation'){
|
|
4362
|
+
renderMessages(data.messages||[]);
|
|
4363
|
+
}else if(data.kind==='empty'){
|
|
4364
|
+
renderMessages([]);
|
|
4365
|
+
}
|
|
4366
|
+
// The short loading card may not have enough scroll range. Complete
|
|
4367
|
+
// the explicit reveal after layout grows, unless the reader moved on.
|
|
4368
|
+
if(bringIntoView){panel.querySelector('h3').scrollIntoView({block:'start',inline:'nearest'})}
|
|
4369
|
+
}).catch(function(){
|
|
4370
|
+
if(epoch===current){status.textContent=msg.unavailable;panel.setAttribute('data-conversation-kind','unavailable')}
|
|
4371
|
+
}).finally(function(){
|
|
4372
|
+
clearTimeout(timeout);
|
|
4373
|
+
if(epoch!==current){return}
|
|
4374
|
+
request=null;
|
|
4375
|
+
panel.setAttribute('aria-busy','false');
|
|
4376
|
+
var refresh=element('button',msg.refresh);refresh.type='button';refresh.setAttribute('data-conversation-refresh','');
|
|
4377
|
+
refresh.addEventListener('click',load);panel.appendChild(refresh);
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
4380
|
+
function renderMessages(messages){
|
|
4381
|
+
var truncated=messages.length>limits.messages,remaining=limits.totalChars,toolCount=0;
|
|
4382
|
+
messages=messages.slice(0,limits.messages);
|
|
4383
|
+
var tools=element('details');tools.setAttribute('data-conversation-tools','');tools.open=true;
|
|
4384
|
+
var count=messages.reduce(function(total,m){return total+(m.tools||[]).length},0);
|
|
4385
|
+
tools.appendChild(element('summary',msg.tools.replace('{count}',String(count))));
|
|
4386
|
+
var calls=element('div');calls.setAttribute('data-conversation-tool-list','');tools.appendChild(calls);
|
|
4387
|
+
panel.appendChild(tools);
|
|
4388
|
+
function text(value){
|
|
4389
|
+
value=String(value);
|
|
4390
|
+
var size=Math.min(value.length,limits.fieldChars+msg.truncatedMarker.length,remaining);
|
|
4391
|
+
remaining-=size;
|
|
4392
|
+
if(size<value.length){truncated=true}
|
|
4393
|
+
return value.slice(0,size);
|
|
4394
|
+
}
|
|
4395
|
+
['user','assistant'].forEach(function(role){
|
|
4396
|
+
var section=element('section');section.setAttribute('data-conversation-role',role);
|
|
4397
|
+
section.appendChild(element('h4',role==='user'?msg.prompt:msg.assistant));
|
|
4398
|
+
var hasText=false;
|
|
4399
|
+
messages.filter(function(m){return m.role===role}).forEach(function(m){
|
|
4400
|
+
var item=element('article');item.appendChild(element('time',consoleLabels.utcTime(m.createdAt)));
|
|
4401
|
+
if((m.text||[]).length>limits.parts){truncated=true}
|
|
4402
|
+
(m.text||[]).slice(0,limits.parts).forEach(function(value){
|
|
4403
|
+
if(!value){return}
|
|
4404
|
+
hasText=true;
|
|
4405
|
+
if(remaining>0){item.appendChild(element('pre',text(value)))}else{truncated=true}
|
|
4406
|
+
});
|
|
4407
|
+
if(item.querySelector('pre')){section.appendChild(item)}
|
|
4408
|
+
});panel.appendChild(section);
|
|
4409
|
+
if(!hasText){section.appendChild(element('p',role==='user'?msg.noPrompts:msg.noOutput))}
|
|
4410
|
+
});
|
|
4411
|
+
messages.forEach(function(m){
|
|
4412
|
+
if((m.tools||[]).length>limits.parts){truncated=true}
|
|
4413
|
+
(m.tools||[]).slice(0,limits.parts).forEach(function(tool){
|
|
4414
|
+
if(toolCount++>=limits.tools||remaining<=0){truncated=true;return}
|
|
4415
|
+
var call=element('details');call.setAttribute('data-tool-call',tool.id);
|
|
4416
|
+
call.appendChild(element('summary',text(tool.name)+' · '+text(tool.status)));
|
|
4417
|
+
if(tool.startedAt!==undefined){call.appendChild(element('time',consoleLabels.utcTime(tool.startedAt)))}
|
|
4418
|
+
call.appendChild(element('h5',msg.arguments));call.appendChild(element('pre',text(tool.arguments)));
|
|
4419
|
+
call.appendChild(element('h5',msg.result));call.appendChild(element('pre',text(tool.result===undefined?msg.pending:tool.result)));
|
|
4420
|
+
calls.appendChild(call);
|
|
4421
|
+
});
|
|
4422
|
+
});
|
|
4423
|
+
if(count===0){calls.appendChild(element('p',msg.noTools))}
|
|
4424
|
+
if(truncated){panel.appendChild(element('p',msg.truncated))}
|
|
4425
|
+
}
|
|
4426
|
+
mount.addEventListener('click',function(event){
|
|
4427
|
+
var button=event.target.closest('[data-inspect-attempt],[data-inspect-root]');
|
|
4428
|
+
if(!button||button.disabled||mount.getAttribute('data-conversation-transition')==='1'){return}
|
|
4429
|
+
if(button===selectedButton()){close(true);return}
|
|
4430
|
+
close();
|
|
4431
|
+
var root=button.hasAttribute('data-inspect-root');
|
|
4432
|
+
var session=button.closest(root?'[data-root-session-id]':'[data-lifecycle-session-id]');
|
|
4433
|
+
if(!session){return}
|
|
4434
|
+
selection={
|
|
4435
|
+
run:mount.getAttribute('data-lifecycle-run'),
|
|
4436
|
+
operation:button.getAttribute('data-inspect-operation'),
|
|
4437
|
+
attempt:button.getAttribute('data-inspect-attempt'),
|
|
4438
|
+
target:root?'root':'attempt',
|
|
4439
|
+
session:session.getAttribute(root?'data-root-session-id':'data-lifecycle-session-id'),
|
|
4440
|
+
cursor:mount.getAttribute('data-conversation-cursor')||null
|
|
4441
|
+
};
|
|
4442
|
+
if(!selectedButton()){close();return}
|
|
4443
|
+
panel.setAttribute('data-conversation-run',selection.run);
|
|
4444
|
+
panel.setAttribute('data-conversation-operation',selection.operation);
|
|
4445
|
+
if(selection.attempt){panel.setAttribute('data-conversation-attempt',selection.attempt)}
|
|
4446
|
+
panel.setAttribute('data-conversation-target',selection.target);
|
|
4447
|
+
panel.setAttribute('data-conversation-session',selection.session);
|
|
4448
|
+
reanchor();
|
|
4449
|
+
panel.hidden=false;
|
|
4450
|
+
if(selection.cursor!==null){reset();panel.setAttribute('data-conversation-kind','historical');panel.appendChild(element('p',msg.historical));showHeading()}
|
|
4451
|
+
else{load(true)}
|
|
4452
|
+
});
|
|
4453
|
+
document.addEventListener('conversation-selection',close);
|
|
4454
|
+
document.addEventListener('conversation-tree-replacing',retain);
|
|
4455
|
+
document.addEventListener('conversation-tree-committed',reanchor);
|
|
4456
|
+
window.addEventListener('pagehide',close);
|
|
4457
|
+
}
|
|
4458
|
+
`;
|
|
4459
|
+
var CONVERSATION_STYLE = `
|
|
4460
|
+
.lc-conversation{margin-top:12px;padding:12px;min-width:0;border:1px solid var(--cp-border);border-radius:16px;background:var(--cp-surface);color:var(--cp-text);overflow-anchor:none}
|
|
4461
|
+
.lc-conversation[hidden]{display:none}
|
|
4462
|
+
.lc-conversation-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px}
|
|
4463
|
+
.lc-conversation h3,.lc-conversation h4,.lc-conversation p{margin:8px 0}
|
|
4464
|
+
.lc-conversation h3{scroll-margin-top:12px}
|
|
4465
|
+
.lc-conversation pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:400px;overflow:auto;background:var(--cp-surface-soft);padding:12px;font-family:Consolas,"Courier New",Courier,monospace}
|
|
4466
|
+
.lc-conversation [data-conversation-role="user"] pre{max-height:180px}
|
|
4467
|
+
.lc-conversation [data-conversation-tool-list]{max-height:160px;overflow:auto}
|
|
4468
|
+
.lc-conversation details{margin-top:12px;padding:8px;border:1px solid var(--cp-border);border-radius:.625rem}
|
|
4469
|
+
.lc-conversation summary{cursor:pointer;color:var(--cp-accent)}
|
|
4470
|
+
.lc-conversation time{font-size:11px;color:var(--cp-text-muted)}
|
|
4471
|
+
.lc-conversation button,[data-inspect-attempt],[data-inspect-root]{padding:6px 10px;margin:6px;border:1px solid var(--cp-border);border-radius:.625rem;background:var(--cp-surface);color:var(--cp-accent)}
|
|
4472
|
+
.lct-operation-name{display:block;font-size:16px}
|
|
4473
|
+
.lct-operation-head details,.lct-session details{font-size:11px;color:var(--cp-text-muted)}
|
|
4474
|
+
.lct-session small,.session-btn small{display:block;color:var(--cp-text-muted)}
|
|
4475
|
+
.lc-run-select{max-width:650px}
|
|
4476
|
+
`;
|
|
4477
|
+
|
|
4478
|
+
// src/console/refresh.ts
|
|
4479
|
+
var CONSOLE_REFRESH_JS = `
|
|
4480
|
+
var viewRevision='',viewRequest=null,viewPending=false,viewStopped=false,latestView=null;
|
|
4481
|
+
var appliedRouting='',appliedLogs='',appliedTree='';
|
|
4482
|
+
function protectedContent(element){
|
|
4483
|
+
var active=document.activeElement;
|
|
4484
|
+
if(active&&element.contains(active)&&/^(INPUT|TEXTAREA|SELECT)$/.test(active.tagName)){return true}
|
|
4485
|
+
var selection=window.getSelection&&window.getSelection();
|
|
4486
|
+
return !!(selection&&!selection.isCollapsed&&element.contains(selection.anchorNode));
|
|
4487
|
+
}
|
|
4488
|
+
function nodeKey(node){
|
|
4489
|
+
if(node.nodeType!==1){return ''}
|
|
4490
|
+
return (node.hasAttribute('data-session-target')?'session-target:'+node.getAttribute('data-session-target'):
|
|
4491
|
+
node.hasAttribute('data-session-view')?'session-view:'+node.getAttribute('data-session-view'):node.id)||
|
|
4492
|
+
((node.tagName==='LI'||node.tagName==='TR')?node.outerHTML:'');
|
|
4493
|
+
}
|
|
4494
|
+
function patchNode(old,next){
|
|
4495
|
+
if(old.isEqualNode(next)){return}
|
|
4496
|
+
if(old.nodeType!==next.nodeType||old.nodeName!==next.nodeName){
|
|
4497
|
+
old.replaceWith(next.cloneNode(true));return;
|
|
4498
|
+
}
|
|
4499
|
+
if(old.nodeType===3){old.nodeValue=next.nodeValue;return}
|
|
4500
|
+
if(old.nodeType!==1){return}
|
|
4501
|
+
if(old.matches('[data-session-name],[data-session-time]')){
|
|
4502
|
+
if(old.getAttribute('data-label-fallback')!==next.textContent){old.setAttribute('data-label-fallback',next.textContent)}
|
|
4503
|
+
return;
|
|
4504
|
+
}
|
|
4505
|
+
if(old.matches('input,textarea,select,.term,.pty,.graph-drill,[data-config-mount]')){return}
|
|
4506
|
+
Array.from(old.attributes).forEach(function(a){
|
|
4507
|
+
if(a.name!=='open'&&a.name!=='hidden'&&a.name!=='aria-selected'&&!next.hasAttribute(a.name)){old.removeAttribute(a.name)}
|
|
4508
|
+
});
|
|
4509
|
+
Array.from(next.attributes).forEach(function(a){
|
|
4510
|
+
if(a.name!=='open'&&a.name!=='hidden'&&a.name!=='aria-selected'&&old.getAttribute(a.name)!==a.value){old.setAttribute(a.name,a.value)}
|
|
4511
|
+
});
|
|
4512
|
+
var originals=Array.from(old.childNodes),used=new Set();
|
|
4513
|
+
Array.from(next.childNodes).forEach(function(child,index){
|
|
4514
|
+
var key=nodeKey(child),match;
|
|
4515
|
+
if(key){match=originals.find(function(n){return !used.has(n)&&nodeKey(n)===key})}
|
|
4516
|
+
else{match=originals.find(function(n){return !used.has(n)&&!nodeKey(n)&&n.nodeName===child.nodeName})}
|
|
4517
|
+
if(match){used.add(match);patchNode(match,child)}
|
|
4518
|
+
else{match=child.cloneNode(true)}
|
|
4519
|
+
if(old.childNodes[index]!==match){
|
|
4520
|
+
var scrolls=match.nodeType===1?[match].concat(Array.from(match.querySelectorAll('*'))).map(function(n){return [n,n.scrollTop,n.scrollLeft]}):[];
|
|
4521
|
+
old.insertBefore(match,old.childNodes[index]||null);
|
|
4522
|
+
scrolls.forEach(function(s){s[0].scrollTop=s[1];s[0].scrollLeft=s[2]});
|
|
4523
|
+
}
|
|
4524
|
+
});
|
|
4525
|
+
originals.forEach(function(n){
|
|
4526
|
+
if(!used.has(n)&&n.parentNode===old){
|
|
4527
|
+
if(n.nodeType===1){
|
|
4528
|
+
disconnectTerminal(n);
|
|
4529
|
+
n.querySelectorAll('[data-session-view]').forEach(disconnectTerminal);
|
|
4530
|
+
}
|
|
4531
|
+
old.removeChild(n);
|
|
4532
|
+
}
|
|
4533
|
+
});
|
|
4534
|
+
}
|
|
4535
|
+
function patchHtml(element,html){
|
|
4536
|
+
var next=document.createElement('div');
|
|
4537
|
+
next.innerHTML=html;
|
|
4538
|
+
var shell=element.cloneNode(false);
|
|
4539
|
+
while(next.firstChild){shell.appendChild(next.firstChild)}
|
|
4540
|
+
patchNode(element,shell);
|
|
4541
|
+
}
|
|
4542
|
+
function applyView(forceLogs){
|
|
4543
|
+
if(!latestView){return}
|
|
4544
|
+
var tree=document.querySelector('#screen-tree > .graph-panel');
|
|
4545
|
+
if(tree&&latestView.tree&&latestView.tree!==appliedTree&&!protectedContent(tree)){
|
|
4546
|
+
var graph=document.createElement('div');graph.innerHTML=latestView.tree;
|
|
4547
|
+
if(graph.firstElementChild){patchNode(tree,graph.firstElementChild)}
|
|
4548
|
+
appliedTree=latestView.tree;
|
|
4549
|
+
}
|
|
4550
|
+
var routing=document.querySelector('#screen-routing > .screen-grid');
|
|
4551
|
+
if(routing&&latestView.routing!==appliedRouting&&!protectedContent(routing)){
|
|
4552
|
+
var next=document.createElement('div');next.innerHTML=latestView.routing;
|
|
4553
|
+
if(next.firstElementChild){patchNode(routing,next.firstElementChild)}
|
|
4554
|
+
appliedRouting=latestView.routing;
|
|
4555
|
+
}
|
|
4556
|
+
var logs=document.getElementById('screen-logs');
|
|
4557
|
+
var content=logs&&logs.querySelector('[data-log-content]');
|
|
4558
|
+
var follow=logs&&logs.querySelector('[data-log-follow]');
|
|
4559
|
+
var incoming=logs&&logs.querySelector('[data-log-incoming]');
|
|
4560
|
+
var scroll=document.querySelector('.scroll');
|
|
4561
|
+
if(content&&latestView.logs!==appliedLogs){
|
|
4562
|
+
if(appliedLogs===''&&content.innerHTML===latestView.logs){appliedLogs=latestView.logs}
|
|
4563
|
+
else{
|
|
4564
|
+
var atBottom=!scroll||scroll.scrollHeight-scroll.scrollTop-scroll.clientHeight<40;
|
|
4565
|
+
var safe=logs.hidden||(follow&&follow.checked&&atBottom);
|
|
4566
|
+
if((forceLogs||safe)&&!protectedContent(content)){
|
|
4567
|
+
var top=scroll&&scroll.scrollTop;
|
|
4568
|
+
patchHtml(content,latestView.logs);
|
|
4569
|
+
appliedLogs=latestView.logs;
|
|
4570
|
+
wireLogsScreen(logs);
|
|
4571
|
+
if(scroll&&!logs.hidden){scroll.scrollTop=follow&&follow.checked?scroll.scrollHeight:top}
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
if(incoming){incoming.hidden=latestView.logs===appliedLogs&&!Array.from(content.querySelectorAll('.termlog')).some(function(log){return log.__incoming})}
|
|
4575
|
+
}
|
|
4576
|
+
var count=document.querySelector('[data-screen="logs"] .count');
|
|
4577
|
+
if(count&&count.textContent!==String(latestView.sessionCount)){count.textContent=String(latestView.sessionCount)}
|
|
4578
|
+
if(typeof consoleLabels!=='undefined'){consoleLabels.refresh()}
|
|
4579
|
+
}
|
|
4580
|
+
function refreshView(){
|
|
4581
|
+
if(viewStopped){return}
|
|
4582
|
+
applyView(false);
|
|
4583
|
+
if(viewRequest){viewPending=true;return}
|
|
4584
|
+
viewPending=false;
|
|
4585
|
+
var controller=new AbortController();
|
|
4586
|
+
viewRequest=controller;
|
|
4587
|
+
var timeout=setTimeout(function(){controller.abort()},15000);
|
|
4588
|
+
fetch('/api/view'+authTok,{headers:viewRevision?{'If-None-Match':viewRevision}:{},signal:controller.signal})
|
|
4589
|
+
.then(function(r){
|
|
4590
|
+
var error=document.querySelector('[data-refresh-error]');
|
|
4591
|
+
if(error){error.hidden=r.ok||r.status===304}
|
|
4592
|
+
if(r.status===304){return null}
|
|
4593
|
+
if(!r.ok){throw new Error()}
|
|
4594
|
+
var revision=r.headers.get('etag')||'';
|
|
4595
|
+
return r.json().then(function(d){return {data:d,revision:revision}});
|
|
4596
|
+
}).then(function(result){
|
|
4597
|
+
if(viewStopped||viewRequest!==controller||!result){return}
|
|
4598
|
+
if(typeof result.data.routing!=='string'||typeof result.data.logs!=='string'){return}
|
|
4599
|
+
latestView=result.data;viewRevision=result.revision;
|
|
4600
|
+
var updated=document.querySelector('.token-chip b');
|
|
4601
|
+
if(updated&&typeof latestView.updatedAt==='string'){updated.textContent=latestView.updatedAt}
|
|
4602
|
+
if(Number.isInteger(latestView.refreshMs)&&latestView.refreshMs>=250&&latestView.refreshMs!==ms){
|
|
4603
|
+
ms=latestView.refreshMs;document.documentElement.setAttribute('data-refresh',String(ms));
|
|
4604
|
+
clearInterval(refreshTimer);refreshTimer=null;startRefresh();
|
|
4605
|
+
document.dispatchEvent(new CustomEvent('console-refresh-changed',{detail:ms}));
|
|
4606
|
+
}
|
|
4607
|
+
applyView(false);
|
|
4608
|
+
}).catch(function(){
|
|
4609
|
+
var error=document.querySelector('[data-refresh-error]');
|
|
4610
|
+
if(error&&!viewStopped){error.hidden=false}
|
|
4611
|
+
}).finally(function(){
|
|
4612
|
+
clearTimeout(timeout);
|
|
4613
|
+
if(viewRequest!==controller){return}
|
|
4614
|
+
viewRequest=null;
|
|
4615
|
+
if(viewPending&&!viewStopped){refreshView()}
|
|
4616
|
+
});
|
|
4617
|
+
}
|
|
4618
|
+
var refreshTimer=null;
|
|
4619
|
+
function startRefresh(){
|
|
4620
|
+
if(refreshTimer!==null){return}
|
|
4621
|
+
viewStopped=false;
|
|
4622
|
+
refreshTimer=setInterval(refreshView,isNaN(ms)?2000:Math.max(250,ms));
|
|
4623
|
+
}
|
|
4624
|
+
window.addEventListener('pagehide',function(){
|
|
4625
|
+
viewStopped=true;clearInterval(refreshTimer);refreshTimer=null;
|
|
4626
|
+
if(viewRequest){viewRequest.abort();viewRequest=null}
|
|
4627
|
+
if(es){es.close();es=null}
|
|
4628
|
+
document.querySelectorAll('[data-session-view]').forEach(disconnectTerminal);
|
|
4629
|
+
});
|
|
4630
|
+
window.addEventListener('pageshow',function(e){
|
|
4631
|
+
if(e.persisted){
|
|
4632
|
+
startRefresh();openStateStream();refreshView();
|
|
4633
|
+
var logs=document.getElementById('screen-logs');
|
|
4634
|
+
if(logs&&!logs.hidden){wireLogsScreen(logs)}
|
|
4635
|
+
}
|
|
4636
|
+
});
|
|
4637
|
+
`;
|
|
4638
|
+
|
|
3534
4639
|
// src/console/assets.ts
|
|
3535
4640
|
var CONSOLE_STYLE = `
|
|
3536
4641
|
:root{color-scheme:dark;--bg:#0f0f0f;--surface:#17181b;--surface-2:#1e2024;--panel:var(--surface);--fg:#eceef1;--muted:#a2a8b2;--faint:#6b7079;--border:rgba(255,255,255,.08);--border-strong:rgba(255,255,255,.16);--line:var(--border);--accent:#35c07a;--accent-bg:rgba(53,192,122,.12);--accent-fg:#57d492;--good:var(--accent-fg);--local:#6aa6f5;--frontier:#e0a53a;--warn:#e0a53a;--warn-bg:rgba(224,165,58,.12);--danger:#f0687f;--danger-bg:rgba(240,104,127,.12);--info:#6aa6f5;--info-bg:rgba(106,166,245,.12);--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;--font-mono:"JetBrains Mono","IBM Plex Mono",ui-monospace,"SFMono-Regular",Consolas,monospace;--shadow-pop:0 8px 28px rgba(0,0,0,.5);--sidebar-w:248px}
|
|
3537
4642
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
4643
|
+
[data-log-controls]{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:16px}
|
|
4644
|
+
[data-log-controls] input,[data-log-controls] button{padding:6px;border:1px solid var(--cp-border);border-radius:.625rem;background:var(--cp-surface);color:var(--cp-text)}
|
|
4645
|
+
[data-session-target][hidden]{display:none}
|
|
3538
4646
|
html,body{height:100%}
|
|
3539
4647
|
body{background:var(--bg);color:var(--fg);font:14px/1.55 var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-variant-numeric:tabular-nums}
|
|
3540
4648
|
.mono,code,.hash{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
|
|
@@ -3609,25 +4717,21 @@ svg.graph{display:block}
|
|
|
3609
4717
|
`;
|
|
3610
4718
|
var CONSOLE_CLIENT_JS = `
|
|
3611
4719
|
(function(){
|
|
4720
|
+
var detailMsg=${JSON.stringify(consoleDetailMessages)};
|
|
4721
|
+
var terminalCollectors=[];
|
|
3612
4722
|
var authTok='';
|
|
3613
4723
|
try{
|
|
3614
4724
|
var qp=new URLSearchParams(window.location.search).get('token');
|
|
3615
4725
|
if(qp){authTok='?token='+encodeURIComponent(qp)}
|
|
3616
4726
|
}catch(e){/* ignore */}
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
}).catch(function(){});
|
|
3621
|
-
}
|
|
3622
|
-
var current=document.documentElement.getAttribute('data-generated')||'';
|
|
4727
|
+
${CONSOLE_REFRESH_JS}
|
|
4728
|
+
var es=null;
|
|
4729
|
+
function openStateStream(){
|
|
3623
4730
|
if('EventSource' in window){
|
|
3624
4731
|
try{
|
|
3625
|
-
|
|
4732
|
+
es=new EventSource('/events'+authTok);
|
|
3626
4733
|
es.addEventListener('state',function(ev){
|
|
3627
|
-
|
|
3628
|
-
var d=JSON.parse(ev.data||'{}');
|
|
3629
|
-
if(d.generatedAt&&d.generatedAt!==current&&!configActive()&&!lifecycleActive()){location.reload()}
|
|
3630
|
-
}catch(e){}
|
|
4734
|
+
refreshView();
|
|
3631
4735
|
});
|
|
3632
4736
|
es.addEventListener('graph-append',function(ev){
|
|
3633
4737
|
try{
|
|
@@ -3638,26 +4742,22 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3638
4742
|
es.onerror=function(){/* fallback below */};
|
|
3639
4743
|
}catch(e){/* ignore */}
|
|
3640
4744
|
}
|
|
4745
|
+
}
|
|
3641
4746
|
var ms=parseInt(document.documentElement.getAttribute('data-refresh')||'2000',10);
|
|
3642
|
-
|
|
4747
|
+
startRefresh();
|
|
4748
|
+
openStateStream();
|
|
3643
4749
|
|
|
3644
|
-
function configActive(){
|
|
3645
|
-
var s=document.getElementById('screen-config');
|
|
3646
|
-
return !!(s&&!s.hidden);
|
|
3647
|
-
}
|
|
3648
|
-
// Only the visible timeline owns incremental refresh. Other screens still
|
|
3649
|
-
// need state reloads; their navigation preserves the timeline URL selection.
|
|
3650
|
-
function lifecycleActive(){
|
|
3651
|
-
var mount=document.getElementById('lifecycle-timeline-mount');
|
|
3652
|
-
var screen=mount&&mount.closest('.screen');
|
|
3653
|
-
return !!(screen&&!screen.hidden);
|
|
3654
|
-
}
|
|
3655
4750
|
function wireLogsScreen(screen){
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
4751
|
+
function filterSessions(){
|
|
4752
|
+
var filter=screen.querySelector('[data-log-filter]');
|
|
4753
|
+
var value=filter?filter.value.toLowerCase():'';
|
|
4754
|
+
var buttons=screen.querySelectorAll('[data-session-target]');
|
|
4755
|
+
for(var i=0;i<buttons.length;i++){buttons[i].hidden=buttons[i].getAttribute('data-session-target').toLowerCase().indexOf(value)===-1}
|
|
4756
|
+
}
|
|
3660
4757
|
function showSession(id){
|
|
4758
|
+
var buttons=screen.querySelectorAll('[data-session-target]');
|
|
4759
|
+
var cards=screen.querySelectorAll('[data-session-view]');
|
|
4760
|
+
screen.__selectedSession=id;
|
|
3661
4761
|
var matched=false;
|
|
3662
4762
|
for(var i=0;i<buttons.length;i++){
|
|
3663
4763
|
var on=buttons[i].getAttribute('data-session-target')===id;
|
|
@@ -3667,19 +4767,41 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3667
4767
|
for(var j=0;j<cards.length;j++){
|
|
3668
4768
|
var show=cards[j].getAttribute('data-session-view')===id;
|
|
3669
4769
|
cards[j].hidden=!show;
|
|
3670
|
-
if(show){matched=true;connectTerminal(cards[j],id)}
|
|
4770
|
+
if(show){matched=true;if(!screen.hidden){connectTerminal(cards[j],id)}}
|
|
3671
4771
|
}
|
|
4772
|
+
updateTerminalLeases();
|
|
3672
4773
|
return matched;
|
|
3673
4774
|
}
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
4775
|
+
if(!screen.__logsWired){
|
|
4776
|
+
screen.__logsWired=true;
|
|
4777
|
+
screen.addEventListener('click',function(e){
|
|
4778
|
+
var button=e.target.closest('[data-session-target]');
|
|
4779
|
+
if(button){showSession(button.getAttribute('data-session-target'))}
|
|
4780
|
+
if(e.target.closest('[data-log-incoming]')){applyView(true);followTerminalOutput(screen)}
|
|
3678
4781
|
});
|
|
4782
|
+
var follow=screen.querySelector('[data-log-follow]');
|
|
4783
|
+
if(follow){follow.addEventListener('change',function(){
|
|
4784
|
+
if(follow.checked){
|
|
4785
|
+
applyView(true);followTerminalOutput(screen);
|
|
4786
|
+
var viewport=document.querySelector('.scroll');if(viewport){viewport.scrollTop=viewport.scrollHeight}
|
|
4787
|
+
}
|
|
4788
|
+
})}
|
|
4789
|
+
var filter=screen.querySelector('[data-log-filter]');
|
|
4790
|
+
if(filter){filter.addEventListener('input',filterSessions)}
|
|
4791
|
+
var scroll=document.querySelector('.scroll');
|
|
4792
|
+
if(scroll&&follow){
|
|
4793
|
+
scroll.addEventListener('scroll',function(){if(!screen.hidden&&scroll.scrollHeight-scroll.scrollTop-scroll.clientHeight>40){follow.checked=false}});
|
|
4794
|
+
screen.addEventListener('scroll',function(e){
|
|
4795
|
+
var target=e.target;
|
|
4796
|
+
if(target.scrollHeight-target.scrollTop-target.clientHeight>40){follow.checked=false}
|
|
4797
|
+
},true);
|
|
4798
|
+
}
|
|
3679
4799
|
}
|
|
4800
|
+
var buttons=screen.querySelectorAll('[data-session-target]');
|
|
3680
4801
|
if(buttons.length>0){
|
|
3681
|
-
showSession(buttons[0].getAttribute('data-session-target'))
|
|
4802
|
+
if(!showSession(screen.__selectedSession)){showSession(buttons[0].getAttribute('data-session-target'))}
|
|
3682
4803
|
}
|
|
4804
|
+
filterSessions();
|
|
3683
4805
|
}
|
|
3684
4806
|
function selectScreen(name){
|
|
3685
4807
|
var screens=document.querySelectorAll('.screen');
|
|
@@ -3707,6 +4829,7 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3707
4829
|
if(title){title.textContent=titleText}
|
|
3708
4830
|
if(name==='config'&&activeScreen){loadConfig(activeScreen)}
|
|
3709
4831
|
if(name==='logs'&&activeScreen){wireLogsScreen(activeScreen)}
|
|
4832
|
+
updateTerminalLeases();
|
|
3710
4833
|
try{localStorage.setItem('openteam.screen',name)}catch(e){}
|
|
3711
4834
|
document.body.classList.remove('nav-open');
|
|
3712
4835
|
return true;
|
|
@@ -3754,28 +4877,74 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3754
4877
|
.catch(function(){if(btn){btn.disabled=false}out.innerHTML='<div class="config-summary"><p class="config-err">Save failed.</p></div>'});
|
|
3755
4878
|
});
|
|
3756
4879
|
}
|
|
4880
|
+
function disconnectTerminal(view){
|
|
4881
|
+
clearTimeout(view.__lease);view.__lease=null;
|
|
4882
|
+
terminalCollectors=terminalCollectors.filter(function(item){return item!==view});
|
|
4883
|
+
if(view.__stream){
|
|
4884
|
+
view.__stream.close();view.__stream=null;
|
|
4885
|
+
if(view.__append){view.__append('status',detailMsg.terminalGap)}
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
function updateTerminalLeases(){
|
|
4889
|
+
terminalCollectors.forEach(function(view){
|
|
4890
|
+
var screen=view.closest('.screen');
|
|
4891
|
+
if(!view.hidden&&screen&&!screen.hidden){clearTimeout(view.__lease);view.__lease=null}
|
|
4892
|
+
else if(!view.__lease){view.__lease=setTimeout(function(){disconnectTerminal(view)},300000)}
|
|
4893
|
+
});
|
|
4894
|
+
}
|
|
4895
|
+
function followTerminalOutput(screen){
|
|
4896
|
+
screen.querySelectorAll('.termlog').forEach(function(log){
|
|
4897
|
+
log.scrollTop=log.scrollHeight;log.__incoming=false;
|
|
4898
|
+
});
|
|
4899
|
+
var incoming=screen.querySelector('[data-log-incoming]');
|
|
4900
|
+
if(incoming&&(!latestView||latestView.logs===appliedLogs)){incoming.hidden=true}
|
|
4901
|
+
}
|
|
3757
4902
|
function connectTerminal(view,id){
|
|
3758
|
-
if(view.__wired){return}
|
|
3759
4903
|
var root=document.documentElement;
|
|
3760
4904
|
var token=root.getAttribute('data-token');
|
|
3761
4905
|
if(root.getAttribute('data-terminal')!=='1'||!token){return}
|
|
3762
4906
|
var log=view.querySelector('.termlog');
|
|
3763
4907
|
if(!log){return}
|
|
3764
|
-
view.__wired=true;
|
|
3765
4908
|
function append(cls,text){
|
|
4909
|
+
var atBottom=log.scrollHeight-log.scrollTop-log.clientHeight<40;
|
|
4910
|
+
var screen=view.closest('.screen');
|
|
4911
|
+
var follow=screen&&screen.querySelector('[data-log-follow]');
|
|
3766
4912
|
var line=document.createElement('div');
|
|
3767
|
-
line.className='tl '+cls;line.textContent=text;
|
|
3768
|
-
log.appendChild(line);
|
|
4913
|
+
line.className='tl '+cls;line.textContent=String(text).slice(0,16384);
|
|
4914
|
+
log.appendChild(line);
|
|
4915
|
+
var removed=false;
|
|
4916
|
+
while(log.children.length>1000||log.textContent.length>262144){log.removeChild(log.firstChild);removed=true}
|
|
4917
|
+
if(removed){
|
|
4918
|
+
var notice=view.querySelector('[data-terminal-truncated]');
|
|
4919
|
+
if(!notice){notice=document.createElement('p');notice.setAttribute('data-terminal-truncated','');log.before(notice)}
|
|
4920
|
+
notice.textContent=detailMsg.terminalTrimmed;
|
|
4921
|
+
}
|
|
4922
|
+
if(cls==='input'||(atBottom&&follow&&follow.checked)){log.scrollTop=log.scrollHeight}
|
|
4923
|
+
else{
|
|
4924
|
+
log.__incoming=true;
|
|
4925
|
+
var incoming=screen&&screen.querySelector('[data-log-incoming]');
|
|
4926
|
+
if(incoming){incoming.hidden=false}
|
|
4927
|
+
}
|
|
3769
4928
|
}
|
|
3770
4929
|
var q='/console/session/'+encodeURIComponent(id);
|
|
3771
4930
|
var tk='token='+encodeURIComponent(token);
|
|
3772
|
-
|
|
4931
|
+
view.__append=append;
|
|
4932
|
+
if(!view.__stream&&'EventSource' in window){
|
|
3773
4933
|
try{
|
|
4934
|
+
while(terminalCollectors.length>=2){disconnectTerminal(terminalCollectors[0])}
|
|
3774
4935
|
var es=new EventSource(q+'/stream?'+tk);
|
|
3775
|
-
|
|
3776
|
-
|
|
4936
|
+
view.__stream=es;
|
|
4937
|
+
terminalCollectors.push(view);
|
|
4938
|
+
es.addEventListener('frame',function(e){if(view.__stream!==es){return}try{var f=JSON.parse(e.data);append(f.kind,f.text)}catch(_){}});
|
|
4939
|
+
es.onerror=function(){if(view.__stream===es){append('status',detailMsg.terminalGap)}};
|
|
3777
4940
|
}catch(_){/* ignore */}
|
|
3778
4941
|
}
|
|
4942
|
+
// Two recently selected sessions collect bounded output across tabs; hidden
|
|
4943
|
+
// collectors expire after five minutes and never occupy unbounded sockets.
|
|
4944
|
+
if(view.__stream){terminalCollectors=terminalCollectors.filter(function(item){return item!==view}).concat(view)}
|
|
4945
|
+
updateTerminalLeases();
|
|
4946
|
+
if(view.__wired){return}
|
|
4947
|
+
view.__wired=true;
|
|
3779
4948
|
var form=view.querySelector('form.terminput');
|
|
3780
4949
|
if(form){
|
|
3781
4950
|
form.addEventListener('submit',function(e){
|
|
@@ -3847,29 +5016,41 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3847
5016
|
var title=drill.querySelector('.drill-title');
|
|
3848
5017
|
if(!log){return}
|
|
3849
5018
|
var es=null;
|
|
5019
|
+
var epoch=0,request=null;
|
|
5020
|
+
function closeDrill(){
|
|
5021
|
+
epoch++;
|
|
5022
|
+
if(es){es.close();es=null}
|
|
5023
|
+
if(request){request.abort();request=null}
|
|
5024
|
+
}
|
|
5025
|
+
window.addEventListener('pagehide',closeDrill);
|
|
5026
|
+
document.addEventListener('conversation-selection',function(){closeDrill();log.textContent='';drill.hidden=true});
|
|
3850
5027
|
function append(cls,text){
|
|
3851
5028
|
var line=document.createElement('div');
|
|
3852
5029
|
line.className='tl '+cls;line.textContent=text;
|
|
3853
5030
|
log.appendChild(line);log.scrollTop=log.scrollHeight;
|
|
3854
5031
|
}
|
|
3855
5032
|
function open(id){
|
|
3856
|
-
|
|
5033
|
+
closeDrill();
|
|
5034
|
+
var current=epoch;
|
|
5035
|
+
request=new AbortController();
|
|
3857
5036
|
log.textContent='';drill.hidden=false;
|
|
3858
5037
|
if(title){title.textContent='Conversation · '+id}
|
|
3859
5038
|
var tk='token='+encodeURIComponent(token);
|
|
3860
5039
|
var base='/console/session/'+encodeURIComponent(id);
|
|
3861
|
-
fetch(base+'/messages?'+tk).then(function(r){return r.ok?r.json():Promise.reject(r.status)})
|
|
3862
|
-
.then(function(d){(d&&d.frames||[]).forEach(function(f){append(f.kind,f.text)})})
|
|
3863
|
-
.catch(function(s){append('error','✖ could not load conversation ('+s+')')});
|
|
5040
|
+
fetch(base+'/messages?'+tk,{signal:request.signal}).then(function(r){return r.ok?r.json():Promise.reject(r.status)})
|
|
5041
|
+
.then(function(d){if(epoch===current){(d&&d.frames||[]).forEach(function(f){append(f.kind,f.text)})}})
|
|
5042
|
+
.catch(function(s){if(epoch===current){append('error','✖ could not load conversation ('+s+')')}});
|
|
3864
5043
|
if('EventSource' in window){
|
|
3865
5044
|
try{
|
|
3866
5045
|
es=new EventSource(base+'/stream?'+tk);
|
|
3867
|
-
es.addEventListener('frame',function(e){try{var f=JSON.parse(e.data);append(f.kind,f.text)}catch(_){}});
|
|
5046
|
+
es.addEventListener('frame',function(e){if(epoch!==current){return}try{var f=JSON.parse(e.data);append(f.kind,f.text)}catch(_){}});
|
|
3868
5047
|
es.onerror=function(){/* reconnects on its own */};
|
|
3869
5048
|
}catch(_){/* ignore */}
|
|
3870
5049
|
}
|
|
3871
5050
|
}
|
|
3872
5051
|
gview.addEventListener('click',function(e){
|
|
5052
|
+
var timeline=document.getElementById('lifecycle-timeline-mount');
|
|
5053
|
+
if(timeline&&timeline.getAttribute('data-conversation-transition')==='1'){return}
|
|
3873
5054
|
var t=e.target;
|
|
3874
5055
|
while(t&&t!==gview&&!(t.getAttribute&&t.getAttribute('data-session'))){t=t.parentNode}
|
|
3875
5056
|
if(t&&t.getAttribute&&t.getAttribute('data-session')){open(t.getAttribute('data-session'))}
|
|
@@ -3891,7 +5072,8 @@ var CONSOLE_CLIENT_JS = `
|
|
|
3891
5072
|
try{saved=localStorage.getItem('openteam.screen')||'tree'}catch(e){}
|
|
3892
5073
|
if(!selectScreen(saved)){selectScreen('tree')}
|
|
3893
5074
|
wireGraphDrill();
|
|
3894
|
-
wireLifecycleTimeline()
|
|
5075
|
+
if(typeof wireLifecycleTimeline==='function'){wireLifecycleTimeline()}
|
|
5076
|
+
if(typeof wireConversationInspector==='function'){wireConversationInspector()}
|
|
3895
5077
|
})();
|
|
3896
5078
|
`;
|
|
3897
5079
|
var LIFECYCLE_STYLE = `
|
|
@@ -4049,6 +5231,8 @@ var LIFECYCLE_THEME_BOOT = `
|
|
|
4049
5231
|
})();
|
|
4050
5232
|
`;
|
|
4051
5233
|
var LIFECYCLE_CLIENT_JS = `
|
|
5234
|
+
${LABELS_CLIENT_JS}
|
|
5235
|
+
${CONVERSATION_CLIENT_JS}
|
|
4052
5236
|
function wireLifecycleTimeline(){
|
|
4053
5237
|
var mount=document.getElementById('lifecycle-timeline-mount');
|
|
4054
5238
|
if(!mount){return}
|
|
@@ -4087,6 +5271,28 @@ function wireLifecycleTimeline(){
|
|
|
4087
5271
|
lastSseHead:new Map()
|
|
4088
5272
|
};
|
|
4089
5273
|
var projectionKey='';
|
|
5274
|
+
var committedRun=mount.getAttribute('data-lifecycle-run')||null,committedCursor=urlCursor();
|
|
5275
|
+
|
|
5276
|
+
function invalidateConversation(){
|
|
5277
|
+
mount.setAttribute('data-conversation-transition','1');
|
|
5278
|
+
if(treeMountEl){
|
|
5279
|
+
treeMountEl.setAttribute('inert','');
|
|
5280
|
+
treeMountEl.querySelectorAll('[data-inspect-attempt],[data-inspect-root]').forEach(function(button){button.disabled=true});
|
|
5281
|
+
}
|
|
5282
|
+
document.dispatchEvent(new CustomEvent('conversation-selection'));
|
|
5283
|
+
}
|
|
5284
|
+
function commitConversation(run,cursor){
|
|
5285
|
+
cursor=cursor===null?null:String(cursor);
|
|
5286
|
+
if(run!==committedRun||cursor!==committedCursor){invalidateConversation()}
|
|
5287
|
+
committedRun=run;committedCursor=cursor;
|
|
5288
|
+
mount.setAttribute('data-conversation-cursor',cursor===null?'':String(cursor));
|
|
5289
|
+
mount.removeAttribute('data-conversation-transition');
|
|
5290
|
+
if(treeMountEl){
|
|
5291
|
+
treeMountEl.removeAttribute('inert');
|
|
5292
|
+
treeMountEl.querySelectorAll('[data-inspect-attempt],[data-inspect-root]').forEach(function(button){button.disabled=false});
|
|
5293
|
+
}
|
|
5294
|
+
document.dispatchEvent(new CustomEvent('conversation-tree-committed'));
|
|
5295
|
+
}
|
|
4090
5296
|
|
|
4091
5297
|
function urlCursor(){
|
|
4092
5298
|
try{
|
|
@@ -4168,6 +5374,7 @@ function wireLifecycleTimeline(){
|
|
|
4168
5374
|
}
|
|
4169
5375
|
|
|
4170
5376
|
function navigateFromUrl(initial){
|
|
5377
|
+
invalidateConversation();
|
|
4171
5378
|
state.generation++;
|
|
4172
5379
|
cancelRequest();
|
|
4173
5380
|
state.pending=false;
|
|
@@ -4181,6 +5388,9 @@ function wireLifecycleTimeline(){
|
|
|
4181
5388
|
}
|
|
4182
5389
|
|
|
4183
5390
|
function handleResponse(d,requestedCursor){
|
|
5391
|
+
if(!d||(d.kind!=='view'&&d.kind!=='legacy')||(d.selection&&(d.selection.runID!==committedRun||(requestedCursor===null?null:String(requestedCursor))!==committedCursor))){
|
|
5392
|
+
invalidateConversation();
|
|
5393
|
+
}
|
|
4184
5394
|
if(!d||d.version!==1){showError();return}
|
|
4185
5395
|
if(d.kind==='error'){showApiError(d.error);return}
|
|
4186
5396
|
if(d.kind==='disabled'){showDisabled(d);return}
|
|
@@ -4385,6 +5595,7 @@ function wireLifecycleTimeline(){
|
|
|
4385
5595
|
mount.setAttribute('data-lifecycle-state', state.followLive?'live':'paused');
|
|
4386
5596
|
mount.setAttribute('data-lifecycle-run', d.selection.runID||'');
|
|
4387
5597
|
mount.setAttribute('data-lifecycle-head', String(state.head));
|
|
5598
|
+
commitConversation(d.selection.runID,requestedCursor);
|
|
4388
5599
|
}
|
|
4389
5600
|
|
|
4390
5601
|
function syncRunOptions(runs,selectedID){
|
|
@@ -4399,12 +5610,16 @@ function wireLifecycleTimeline(){
|
|
|
4399
5610
|
for(var i=0;i<runs.length;i++){
|
|
4400
5611
|
var opt=document.createElement('option');
|
|
4401
5612
|
opt.value=runs[i].runID;
|
|
4402
|
-
|
|
4403
|
-
opt.textContent=label;
|
|
5613
|
+
opt.textContent=consoleLabels.runLabel(runs[i]);
|
|
4404
5614
|
runSelect.appendChild(opt);
|
|
4405
5615
|
}
|
|
4406
5616
|
}
|
|
5617
|
+
runs.forEach(function(run){
|
|
5618
|
+
var opt=Array.from(runSelect.options).find(function(option){return option.value===run.runID});
|
|
5619
|
+
if(opt){opt.title=run.runID;opt.setAttribute('data-run-started',run.startedAt===null?'':String(run.startedAt));opt.setAttribute('data-run-authority',run.executionAuthority);opt.setAttribute('data-run-session',run.rootSessionID||'')}
|
|
5620
|
+
});
|
|
4407
5621
|
runSelect.value=selectedID;
|
|
5622
|
+
var technical=mount.querySelector('[data-lifecycle-run-id]');if(technical&&technical.textContent!==selectedID){technical.textContent=selectedID}
|
|
4408
5623
|
}
|
|
4409
5624
|
|
|
4410
5625
|
function renderLegacy(d){
|
|
@@ -4441,14 +5656,17 @@ function wireLifecycleTimeline(){
|
|
|
4441
5656
|
mount.setAttribute('data-lifecycle-state','legacy');
|
|
4442
5657
|
mount.setAttribute('data-lifecycle-run',d.selection.runID||'');
|
|
4443
5658
|
mount.setAttribute('data-lifecycle-head','0');
|
|
5659
|
+
commitConversation(d.selection.runID,null);
|
|
4444
5660
|
}
|
|
4445
5661
|
|
|
4446
5662
|
function renderProjection(proj,recording){
|
|
4447
5663
|
if(!proj||!treeMountEl){return}
|
|
4448
5664
|
var degraded=recording&&recording.state==='degraded';
|
|
4449
|
-
var
|
|
5665
|
+
var option=runSelect&&Array.from(runSelect.options).find(function(o){return o.value===proj.runID});
|
|
5666
|
+
var key=JSON.stringify([proj.runID,proj.cursor,proj.rootOperationID,proj.operations,degraded,option&&option.getAttribute('data-run-session')]);
|
|
4450
5667
|
if(key===projectionKey){return}
|
|
4451
5668
|
projectionKey=key;
|
|
5669
|
+
document.dispatchEvent(new CustomEvent('conversation-tree-replacing'));
|
|
4452
5670
|
treeMountEl.textContent='';
|
|
4453
5671
|
if(degraded){
|
|
4454
5672
|
var note=makeElement('div','lc-partial-note',message('partial-tail'));
|
|
@@ -4507,7 +5725,7 @@ function wireLifecycleTimeline(){
|
|
|
4507
5725
|
parent.appendChild(box);
|
|
4508
5726
|
}
|
|
4509
5727
|
|
|
4510
|
-
function appendSession(parent,attempt){
|
|
5728
|
+
function appendSession(parent,attempt,role){
|
|
4511
5729
|
if(!attempt.sessionID){
|
|
4512
5730
|
parent.appendChild(makeElement('div','lct-session-empty',message('no-session')));
|
|
4513
5731
|
return;
|
|
@@ -4515,7 +5733,16 @@ function wireLifecycleTimeline(){
|
|
|
4515
5733
|
var session=makeElement('div','lct-session');
|
|
4516
5734
|
session.setAttribute('data-lifecycle-session-id',attempt.sessionID);
|
|
4517
5735
|
session.appendChild(makeElement('span','',message('session')));
|
|
4518
|
-
|
|
5736
|
+
var name=makeElement('span','',role);name.setAttribute('data-session-name',attempt.sessionID);session.appendChild(name);
|
|
5737
|
+
var time=makeElement('small','',${JSON.stringify(consoleDetailMessages.timeUnknown)});time.setAttribute('data-session-time',attempt.sessionID);session.appendChild(time);
|
|
5738
|
+
var technical=makeElement('details','');technical.appendChild(makeElement('summary','',${JSON.stringify(consoleDetailMessages.technicalID)}));technical.appendChild(makeElement('code','',attempt.sessionID));session.appendChild(technical);
|
|
5739
|
+
var inspect=makeElement('button','',message('inspect'));
|
|
5740
|
+
inspect.type='button';
|
|
5741
|
+
inspect.setAttribute('aria-expanded','false');
|
|
5742
|
+
inspect.setAttribute('aria-controls','lc-attempt-conversation');
|
|
5743
|
+
inspect.setAttribute('data-inspect-attempt',attempt.attemptID);
|
|
5744
|
+
inspect.setAttribute('data-inspect-operation',attempt.operationID);
|
|
5745
|
+
session.appendChild(inspect);
|
|
4519
5746
|
if(attempt.parentSessionID){
|
|
4520
5747
|
var parentSession=makeElement('span','lct-parent-session',message('parent-session')+' ');
|
|
4521
5748
|
parentSession.appendChild(makeElement('code','',attempt.parentSessionID));
|
|
@@ -4524,7 +5751,7 @@ function wireLifecycleTimeline(){
|
|
|
4524
5751
|
parent.appendChild(session);
|
|
4525
5752
|
}
|
|
4526
5753
|
|
|
4527
|
-
function buildAttempt(attempt){
|
|
5754
|
+
function buildAttempt(attempt,role){
|
|
4528
5755
|
var article=makeElement('article','lct-attempt');
|
|
4529
5756
|
article.setAttribute('data-lifecycle-attempt-id',attempt.attemptID);
|
|
4530
5757
|
article.setAttribute('data-lifecycle-attempt-state',attempt.state);
|
|
@@ -4557,7 +5784,7 @@ function wireLifecycleTimeline(){
|
|
|
4557
5784
|
model.appendChild(makeElement('code','',identity));
|
|
4558
5785
|
article.appendChild(model);
|
|
4559
5786
|
}
|
|
4560
|
-
appendSession(article,attempt);
|
|
5787
|
+
appendSession(article,attempt,role);
|
|
4561
5788
|
return article;
|
|
4562
5789
|
}
|
|
4563
5790
|
|
|
@@ -4604,7 +5831,9 @@ function wireLifecycleTimeline(){
|
|
|
4604
5831
|
var header=makeElement('header','lct-operation-head');
|
|
4605
5832
|
var identity=makeElement('div','');
|
|
4606
5833
|
identity.appendChild(makeElement('span','lct-operation-label',message('operation')));
|
|
4607
|
-
|
|
5834
|
+
var name=makeElement('strong','lct-operation-name',op.agentID||op.roleID);
|
|
5835
|
+
identity.appendChild(name);
|
|
5836
|
+
var technical=makeElement('details','');technical.appendChild(makeElement('summary','',${JSON.stringify(consoleDetailMessages.technicalID)}));technical.appendChild(makeElement('code','lct-operation-id',op.operationID));identity.appendChild(technical);
|
|
4608
5837
|
header.appendChild(identity);
|
|
4609
5838
|
header.appendChild(stateBadge(op.state));
|
|
4610
5839
|
card.appendChild(header);
|
|
@@ -4624,7 +5853,7 @@ function wireLifecycleTimeline(){
|
|
|
4624
5853
|
if(attemptList.length===0){
|
|
4625
5854
|
attempts.appendChild(makeElement('div','lct-no-attempts',message('no-attempts')));
|
|
4626
5855
|
}else{
|
|
4627
|
-
attemptList.forEach(function(attempt){attempts.appendChild(buildAttempt(attempt))});
|
|
5856
|
+
attemptList.forEach(function(attempt){attempts.appendChild(buildAttempt(attempt,op.agentID||op.roleID))});
|
|
4628
5857
|
}
|
|
4629
5858
|
card.appendChild(attempts);
|
|
4630
5859
|
article.appendChild(card);
|
|
@@ -4652,6 +5881,21 @@ function wireLifecycleTimeline(){
|
|
|
4652
5881
|
if(visited.has(op.operationID)){return null}
|
|
4653
5882
|
visited.add(op.operationID);
|
|
4654
5883
|
var article=buildOperation(op,known,depth);
|
|
5884
|
+
if(op.operationID===proj.rootOperationID&&op.kind==='coordinator'){
|
|
5885
|
+
var option=runSelect&&Array.from(runSelect.options).find(function(o){return o.value===proj.runID});
|
|
5886
|
+
var rootID=option&&option.getAttribute('data-run-session')||'';
|
|
5887
|
+
var card=article.querySelector('.lct-operation-card'),name=card.querySelector('.lct-operation-name');
|
|
5888
|
+
name.setAttribute('data-run-name',proj.runID);
|
|
5889
|
+
if(rootID){name.setAttribute('data-session-name',rootID)}
|
|
5890
|
+
var rootSession=makeElement('div','lct-session');rootSession.setAttribute('data-root-session-id',rootID);
|
|
5891
|
+
if(rootID){
|
|
5892
|
+
var rootName=makeElement('span','',${JSON.stringify(consoleDetailMessages.orchestrator)});rootName.setAttribute('data-session-name',rootID);rootSession.appendChild(rootName);
|
|
5893
|
+
var time=makeElement('small','',${JSON.stringify(consoleDetailMessages.timeUnknown)});time.setAttribute('data-session-time',rootID);rootSession.appendChild(time);
|
|
5894
|
+
var id=makeElement('code','',rootID);rootSession.appendChild(id);
|
|
5895
|
+
}else{rootSession.appendChild(makeElement('span','',${JSON.stringify(consoleDetailMessages.rootUnlinked)}))}
|
|
5896
|
+
var inspect=makeElement('button','',message('inspect'));inspect.type='button';inspect.setAttribute('data-inspect-root','');inspect.setAttribute('data-inspect-operation',op.operationID);inspect.setAttribute('aria-expanded','false');inspect.setAttribute('aria-controls','lc-attempt-conversation');rootSession.appendChild(inspect);
|
|
5897
|
+
card.insertBefore(rootSession,card.querySelector('.lct-attempts'));
|
|
5898
|
+
}
|
|
4655
5899
|
var children=childrenByParent.get(op.operationID)||[];
|
|
4656
5900
|
var childNodes=[];
|
|
4657
5901
|
children.forEach(function(child){
|
|
@@ -4761,6 +6005,7 @@ function wireLifecycleTimeline(){
|
|
|
4761
6005
|
}
|
|
4762
6006
|
|
|
4763
6007
|
function showError(){
|
|
6008
|
+
invalidateConversation();
|
|
4764
6009
|
projectionKey='';
|
|
4765
6010
|
mount.setAttribute('data-lifecycle-state','error');
|
|
4766
6011
|
updateScreenCopy('unavailable',false,null);
|
|
@@ -4873,6 +6118,11 @@ function wireLifecycleTimeline(){
|
|
|
4873
6118
|
var lcRefreshMs=parseInt(document.documentElement.getAttribute('data-refresh')||'2000',10);
|
|
4874
6119
|
if(isNaN(lcRefreshMs)||lcRefreshMs<500){lcRefreshMs=2000;}
|
|
4875
6120
|
var pollTimer=setInterval(fetchHistory,lcRefreshMs);
|
|
6121
|
+
document.addEventListener('console-refresh-changed',function(e){
|
|
6122
|
+
lcRefreshMs=e.detail;
|
|
6123
|
+
clearInterval(pollTimer);
|
|
6124
|
+
if(!state.stopped){pollTimer=setInterval(fetchHistory,lcRefreshMs)}
|
|
6125
|
+
});
|
|
4876
6126
|
window.addEventListener('pagehide',function(){
|
|
4877
6127
|
state.stopped=true;
|
|
4878
6128
|
state.generation++;
|
|
@@ -4920,8 +6170,7 @@ function agentModel(agent) {
|
|
|
4920
6170
|
return agent.model === undefined ? "inherits default" : `${agent.model.providerID}/${agent.model.modelID}`;
|
|
4921
6171
|
}
|
|
4922
6172
|
function domIdPart(value) {
|
|
4923
|
-
|
|
4924
|
-
return cleaned.length === 0 ? "session" : cleaned;
|
|
6173
|
+
return Array.from({ length: value.length }, (_, index) => value.charCodeAt(index).toString(16).padStart(4, "0")).join("");
|
|
4925
6174
|
}
|
|
4926
6175
|
function panelId(base, idSuffix) {
|
|
4927
6176
|
return idSuffix === undefined ? base : `${base}-${idSuffix}`;
|
|
@@ -5065,11 +6314,20 @@ function totalsPanel(totals) {
|
|
|
5065
6314
|
"</section>"
|
|
5066
6315
|
].join("");
|
|
5067
6316
|
}
|
|
6317
|
+
function sessionName(session) {
|
|
6318
|
+
return boundedTitle(session.endpoint?.title) ?? boundedTitle(session.agents.join(", ")) ?? consoleDetailMessages.session;
|
|
6319
|
+
}
|
|
6320
|
+
function sessionNameHtml(id, fallback) {
|
|
6321
|
+
return `<span data-session-name="${escapeHtml(id)}">${escapeHtml(fallback)}</span>`;
|
|
6322
|
+
}
|
|
6323
|
+
function observedTimeHtml(session) {
|
|
6324
|
+
return `<small data-session-time="${escapeHtml(session.sessionID)}">${escapeHtml(consoleDetailMessages.firstObserved)}: ${escapeHtml(utcTime(session.firstTs))}</small>`;
|
|
6325
|
+
}
|
|
5068
6326
|
function sessionRow(session) {
|
|
5069
6327
|
const models = session.models.map(escapeHtml).join("<br>") || "—";
|
|
5070
6328
|
return [
|
|
5071
6329
|
"<tr>",
|
|
5072
|
-
`<td
|
|
6330
|
+
`<td>${sessionNameHtml(session.sessionID, sessionName(session))}<br>${observedTimeHtml(session)}<br><code>${escapeHtml(session.sessionID)}</code></td>`,
|
|
5073
6331
|
`<td>${models}</td>`,
|
|
5074
6332
|
`<td><span class="local">${session.localCount}</span>/<span class="frontier">${session.frontierCount}</span></td>`,
|
|
5075
6333
|
`<td>${usd(session.realCostUSD)}</td>`,
|
|
@@ -5181,7 +6439,7 @@ function sidebarNav(liveCount, logCount) {
|
|
|
5181
6439
|
"</nav>",
|
|
5182
6440
|
'<div class="sidebar-foot">',
|
|
5183
6441
|
'<div class="host-row"><span class="dot live"></span><span>loopback console</span></div>',
|
|
5184
|
-
|
|
6442
|
+
`<div class="host-row faint"><span>${escapeHtml(consoleDetailMessages.metadataOnly)}</span></div>`,
|
|
5185
6443
|
"</div>",
|
|
5186
6444
|
"</aside>"
|
|
5187
6445
|
].join("");
|
|
@@ -5199,11 +6457,13 @@ function screenSection(screen, label, heading, description, body, active = false
|
|
|
5199
6457
|
function sessionHeaderPanel(tab) {
|
|
5200
6458
|
const endpoint = tab.endpoint === undefined ? '<span class="muted">endpoint not announced</span>' : `<code>${escapeHtml(tab.endpoint.url)}</code>`;
|
|
5201
6459
|
const dir = tab.endpoint?.directory === undefined ? "" : `<div class="stat"><span class="k">Directory</span><span class="v mono">${escapeHtml(tab.endpoint.directory)}</span></div>`;
|
|
5202
|
-
const title = tab.endpoint?.title === undefined ? "" : `<div class="stat"><span class="k">Title</span><span class="v">${escapeHtml(tab.endpoint.title)}</span></div>`;
|
|
6460
|
+
const title = tab.endpoint?.title === undefined ? "" : `<div class="stat"><span class="k">Title</span><span class="v">${escapeHtml(boundedTitle(tab.endpoint.title) ?? consoleDetailMessages.session)}</span></div>`;
|
|
5203
6461
|
const s = tab.summary;
|
|
5204
6462
|
return [
|
|
5205
6463
|
'<section class="panel">',
|
|
5206
|
-
`<h2
|
|
6464
|
+
`<h2>${sessionNameHtml(tab.sessionID, sessionName(s))} ${statusBadge(tab.status)}</h2>`,
|
|
6465
|
+
observedTimeHtml(s),
|
|
6466
|
+
`<div>${escapeHtml(consoleDetailMessages.technicalID)}: <code>${escapeHtml(tab.sessionID)}</code></div>`,
|
|
5207
6467
|
'<div class="grid">',
|
|
5208
6468
|
`<div class="stat"><span class="k">Endpoint</span><span class="v">${endpoint}</span></div>`,
|
|
5209
6469
|
dir,
|
|
@@ -5241,8 +6501,8 @@ function ptyPanel(tab) {
|
|
|
5241
6501
|
"</section>"
|
|
5242
6502
|
].join("");
|
|
5243
6503
|
}
|
|
5244
|
-
function sessionDetailCard(tab, terminalEnabled, ptyEnabled, visible
|
|
5245
|
-
const idSuffix =
|
|
6504
|
+
function sessionDetailCard(tab, terminalEnabled, ptyEnabled, visible) {
|
|
6505
|
+
const idSuffix = domIdPart(tab.sessionID);
|
|
5246
6506
|
const body = [
|
|
5247
6507
|
sessionHeaderPanel(tab),
|
|
5248
6508
|
terminalEnabled ? terminalPanel(tab) : "",
|
|
@@ -5484,6 +6744,7 @@ function lcDataAttrs() {
|
|
|
5484
6744
|
["data-msg-selection", lifecycleMessages.selectionLabel],
|
|
5485
6745
|
["data-msg-runtime", lifecycleMessages.runtimeLabel],
|
|
5486
6746
|
["data-msg-session", lifecycleMessages.sessionLabel],
|
|
6747
|
+
["data-msg-inspect", consoleDetailMessages.inspectConversation],
|
|
5487
6748
|
["data-msg-no-session", lifecycleMessages.noSession],
|
|
5488
6749
|
["data-msg-parent-session", lifecycleMessages.parentSessionLabel],
|
|
5489
6750
|
["data-msg-depends-on", lifecycleMessages.dependsOnLabel],
|
|
@@ -5509,9 +6770,9 @@ function lcRunOptions(runs, selectedID) {
|
|
|
5509
6770
|
if (runs.length === 0)
|
|
5510
6771
|
return "";
|
|
5511
6772
|
return runs.map((r) => {
|
|
5512
|
-
const label =
|
|
6773
|
+
const label = runLabel(r);
|
|
5513
6774
|
const sel = r.runID === selectedID ? " selected" : "";
|
|
5514
|
-
return `<option value="${escapeHtml(r.runID)}"${sel}>${escapeHtml(label)}</option>`;
|
|
6775
|
+
return `<option value="${escapeHtml(r.runID)}" title="${escapeHtml(r.runID)}" data-run-started="${r.startedAt ?? ""}" data-run-authority="${r.executionAuthority}" data-run-session="${escapeHtml(r.rootSessionID ?? "")}"${sel}>${escapeHtml(label)}</option>`;
|
|
5515
6776
|
}).join("");
|
|
5516
6777
|
}
|
|
5517
6778
|
function lcActivityBadge(activity) {
|
|
@@ -5550,6 +6811,7 @@ function lcControls(runs, selectedID, followLive, activity, liveDisabled = false
|
|
|
5550
6811
|
"</button>",
|
|
5551
6812
|
lcActivityBadge(activity),
|
|
5552
6813
|
`<span class="lc-incoming-badge" data-lifecycle-incoming hidden></span>`,
|
|
6814
|
+
`<details><summary>${escapeHtml(consoleDetailMessages.technicalID)}</summary><code data-lifecycle-run-id>${escapeHtml(selectedID ?? "")}</code></details>`,
|
|
5553
6815
|
"</div>"
|
|
5554
6816
|
].join("");
|
|
5555
6817
|
}
|
|
@@ -5618,19 +6880,22 @@ function lcFailureHtml(failure) {
|
|
|
5618
6880
|
"</div>"
|
|
5619
6881
|
].join("");
|
|
5620
6882
|
}
|
|
5621
|
-
function lcSessionHtml(attempt) {
|
|
6883
|
+
function lcSessionHtml(attempt, role) {
|
|
5622
6884
|
if (attempt.sessionID === undefined) {
|
|
5623
6885
|
return `<div class="lct-session-empty">${escapeHtml(lifecycleMessages.noSession)}</div>`;
|
|
5624
6886
|
}
|
|
5625
6887
|
return [
|
|
5626
6888
|
`<div class="lct-session" data-lifecycle-session-id="${escapeHtml(attempt.sessionID)}">`,
|
|
5627
6889
|
`<span>${escapeHtml(lifecycleMessages.sessionLabel)}</span>`,
|
|
5628
|
-
|
|
6890
|
+
sessionNameHtml(attempt.sessionID, role),
|
|
6891
|
+
`<small data-session-time="${escapeHtml(attempt.sessionID)}">${escapeHtml(consoleDetailMessages.timeUnknown)}</small>`,
|
|
6892
|
+
`<details><summary>${escapeHtml(consoleDetailMessages.technicalID)}</summary><code>${escapeHtml(attempt.sessionID)}</code></details>`,
|
|
6893
|
+
`<button type="button" aria-expanded="false" aria-controls="lc-attempt-conversation" data-inspect-operation="${escapeHtml(attempt.operationID)}" data-inspect-attempt="${escapeHtml(attempt.attemptID)}">${escapeHtml(consoleDetailMessages.inspectConversation)}</button>`,
|
|
5629
6894
|
attempt.parentSessionID === undefined ? "" : `<span class="lct-parent-session">${escapeHtml(lifecycleMessages.parentSessionLabel)} <code>${escapeHtml(attempt.parentSessionID)}</code></span>`,
|
|
5630
6895
|
"</div>"
|
|
5631
6896
|
].join("");
|
|
5632
6897
|
}
|
|
5633
|
-
function lcAttemptHtml(attempt) {
|
|
6898
|
+
function lcAttemptHtml(attempt, role) {
|
|
5634
6899
|
const model = attempt.model === undefined ? undefined : `${attempt.model.providerID}/${attempt.model.modelID}`;
|
|
5635
6900
|
const route = attempt.routeKind ?? lifecycleMessages.noRoute;
|
|
5636
6901
|
return [
|
|
@@ -5659,7 +6924,7 @@ function lcAttemptHtml(attempt) {
|
|
|
5659
6924
|
`<code>${escapeHtml(model)}</code>`,
|
|
5660
6925
|
"</div>"
|
|
5661
6926
|
].join(""),
|
|
5662
|
-
lcSessionHtml(attempt),
|
|
6927
|
+
lcSessionHtml(attempt, role),
|
|
5663
6928
|
"</article>"
|
|
5664
6929
|
].join("");
|
|
5665
6930
|
}
|
|
@@ -5687,16 +6952,17 @@ function lcParentReferenceHtml(operation, operationIDs) {
|
|
|
5687
6952
|
"</div>"
|
|
5688
6953
|
].join("");
|
|
5689
6954
|
}
|
|
5690
|
-
function lcOperationHtml(operation, operationIDs, childrenHtml, depth) {
|
|
6955
|
+
function lcOperationHtml(operation, operationIDs, childrenHtml, depth, rootSessionID, isRoot = false) {
|
|
5691
6956
|
const parentAttr = operation.parentOperationID === undefined ? "" : ` data-lifecycle-parent-operation-id="${escapeHtml(operation.parentOperationID)}"`;
|
|
5692
|
-
const attempts = operation.attempts.length === 0 ? `<div class="lct-no-attempts">${escapeHtml(lifecycleMessages.noAttempts)}</div>` : operation.attempts.map(lcAttemptHtml).join("");
|
|
6957
|
+
const attempts = operation.attempts.length === 0 ? `<div class="lct-no-attempts">${escapeHtml(lifecycleMessages.noAttempts)}</div>` : operation.attempts.map((attempt) => lcAttemptHtml(attempt, operation.agentID ?? operation.roleID)).join("");
|
|
5693
6958
|
return [
|
|
5694
6959
|
`<article class="lct-operation" role="treeitem" aria-level="${depth}" data-lifecycle-operation-id="${escapeHtml(operation.operationID)}"${parentAttr} data-lifecycle-operation-state="${escapeHtml(operation.state)}" data-op-id="${escapeHtml(operation.operationID)}" data-op-state="${escapeHtml(operation.state)}">`,
|
|
5695
6960
|
'<div class="lct-operation-card">',
|
|
5696
6961
|
'<header class="lct-operation-head">',
|
|
5697
6962
|
"<div>",
|
|
5698
6963
|
`<span class="lct-operation-label">${escapeHtml(lifecycleMessages.operationLabel)}</span>`,
|
|
5699
|
-
`<
|
|
6964
|
+
`<strong class="lct-operation-name">${rootSessionID ? sessionNameHtml(rootSessionID, operation.agentID ?? operation.roleID) : escapeHtml(operation.agentID ?? operation.roleID)}</strong>`,
|
|
6965
|
+
`<details><summary>${escapeHtml(consoleDetailMessages.technicalID)}</summary><code class="lct-operation-id">${escapeHtml(operation.operationID)}</code></details>`,
|
|
5700
6966
|
"</div>",
|
|
5701
6967
|
`<span class="lct-state" data-state="${escapeHtml(operation.state)}"><span class="sr-only">${escapeHtml(lifecycleMessages.stateLabel)}: </span>${escapeHtml(operation.state)}</span>`,
|
|
5702
6968
|
"</header>",
|
|
@@ -5708,13 +6974,19 @@ function lcOperationHtml(operation, operationIDs, childrenHtml, depth) {
|
|
|
5708
6974
|
"</dl>",
|
|
5709
6975
|
lcParentReferenceHtml(operation, operationIDs),
|
|
5710
6976
|
lcDependenciesHtml(operation, operationIDs),
|
|
6977
|
+
isRoot && operation.kind === "coordinator" ? [
|
|
6978
|
+
`<div class="lct-session" data-root-session-id="${escapeHtml(rootSessionID ?? "")}">`,
|
|
6979
|
+
rootSessionID ? `${sessionNameHtml(rootSessionID, consoleDetailMessages.orchestrator)} <small data-session-time="${escapeHtml(rootSessionID)}">${escapeHtml(consoleDetailMessages.timeUnknown)}</small><details><summary>${escapeHtml(consoleDetailMessages.technicalID)}</summary><code>${escapeHtml(rootSessionID)}</code></details>` : `<span>${escapeHtml(consoleDetailMessages.rootUnlinked)}</span>`,
|
|
6980
|
+
`<button type="button" data-inspect-root data-inspect-operation="${escapeHtml(operation.operationID)}" aria-expanded="false" aria-controls="lc-attempt-conversation">${escapeHtml(consoleDetailMessages.inspectConversation)}</button>`,
|
|
6981
|
+
"</div>"
|
|
6982
|
+
].join("") : "",
|
|
5711
6983
|
`<section class="lct-attempts" aria-label="${escapeHtml(lifecycleMessages.attemptsLabel)}">${attempts}</section>`,
|
|
5712
6984
|
"</div>",
|
|
5713
6985
|
childrenHtml === "" ? "" : `<div class="lct-operation-children" role="group">${childrenHtml}</div>`,
|
|
5714
6986
|
"</article>"
|
|
5715
6987
|
].join("");
|
|
5716
6988
|
}
|
|
5717
|
-
function renderLifecycleOperationTree(projection) {
|
|
6989
|
+
function renderLifecycleOperationTree(projection, rootSessionID) {
|
|
5718
6990
|
if (projection.operations.length === 0) {
|
|
5719
6991
|
return `<div class="lc-empty" role="status">${escapeHtml(lifecycleMessages.noOperationsAtCursor)}</div>`;
|
|
5720
6992
|
}
|
|
@@ -5738,7 +7010,8 @@ function renderLifecycleOperationTree(projection) {
|
|
|
5738
7010
|
return "";
|
|
5739
7011
|
visited.add(operation.operationID);
|
|
5740
7012
|
const childHtml = (childrenByParent.get(operation.operationID) ?? []).map((child) => renderBranch(child, depth + 1)).join("");
|
|
5741
|
-
|
|
7013
|
+
const isRoot = operation.operationID === projection.rootOperationID;
|
|
7014
|
+
return lcOperationHtml(operation, operationIDs, childHtml, depth, isRoot ? rootSessionID : undefined, isRoot);
|
|
5742
7015
|
};
|
|
5743
7016
|
const root = byID.get(projection.rootOperationID);
|
|
5744
7017
|
const rootHtml = root === undefined ? "" : renderBranch(root, 1);
|
|
@@ -5854,7 +7127,7 @@ function renderLifecycleTimelinePanel(lifecycleView) {
|
|
|
5854
7127
|
const followLive = selection.followLive;
|
|
5855
7128
|
const cursor = selection.cursor;
|
|
5856
7129
|
const head = selection.head;
|
|
5857
|
-
const projectionHtml = renderLifecycleOperationTree(projection);
|
|
7130
|
+
const projectionHtml = renderLifecycleOperationTree(projection, runs.find((run) => run.runID === selection.runID)?.rootSessionID);
|
|
5858
7131
|
const stateAttr = followLive ? "live" : "paused";
|
|
5859
7132
|
return [
|
|
5860
7133
|
`<div id="lifecycle-timeline-mount" class="lc-host" role="region" aria-label="${escapeHtml(lifecycleMessages.timelineRegionLabel)}" ${mountAttrs} data-lifecycle-state="${stateAttr}" data-lifecycle-run="${escapeHtml(selection.runID)}" data-lifecycle-head="${head}">`,
|
|
@@ -6026,7 +7299,7 @@ function sessionList(sessions) {
|
|
|
6026
7299
|
return [
|
|
6027
7300
|
`<button type="button" class="session-btn${selected ? " sel" : ""}" role="tab" aria-selected="${selected ? "true" : "false"}" data-session-target="${escapeHtml(tab.sessionID)}">`,
|
|
6028
7301
|
`<span class="dot status-${tab.status}"></span>`,
|
|
6029
|
-
`<span class="sid">${
|
|
7302
|
+
`<span class="sid">${sessionNameHtml(tab.sessionID, sessionName(tab.summary))}<br>${observedTimeHtml(tab.summary)}<br><small class="mono">${escapeHtml(tab.sessionID)}</small></span>`,
|
|
6030
7303
|
`<span class="n">${tab.summary.messageCount}</span>`,
|
|
6031
7304
|
"</button>"
|
|
6032
7305
|
].join("");
|
|
@@ -6044,7 +7317,7 @@ function sessionDetailList(sessions, terminalEnabled, ptyEnabled) {
|
|
|
6044
7317
|
if (sessions.length === 0) {
|
|
6045
7318
|
return '<div class="card empty-state">No session activity recorded yet.</div>';
|
|
6046
7319
|
}
|
|
6047
|
-
return sessions.map((tab, index) => sessionDetailCard(tab, terminalEnabled, ptyEnabled, index === 0
|
|
7320
|
+
return sessions.map((tab, index) => sessionDetailCard(tab, terminalEnabled, ptyEnabled, index === 0)).join("");
|
|
6048
7321
|
}
|
|
6049
7322
|
function logsScreenBody(state, terminalEnabled, ptyEnabled) {
|
|
6050
7323
|
return [
|
|
@@ -6083,11 +7356,11 @@ function renderConsoleHtml(state, options = {}) {
|
|
|
6083
7356
|
const body = [
|
|
6084
7357
|
screenSection("tree", treeCopy.label, treeCopy.heading, treeCopy.description, treeBody, true),
|
|
6085
7358
|
screenSection("routing", "Routing and telemetry", "Routing + telemetry", "Aggregate routing and cost telemetry from <code>GET /api/state</code> across all sessions.", routingScreenBody(state)),
|
|
6086
|
-
screenSection("logs", "Logs and session activity", "Logs / activity", "Per-session activity. Prompts are referenced by hash only and never rendered in clear text.", logsScreenBody(state, terminalEnabled, ptyEnabled)),
|
|
7359
|
+
screenSection("logs", "Logs and session activity", "Logs / activity", "Per-session activity. Prompts are referenced by hash only and never rendered in clear text.", `<div data-log-controls><label>${escapeHtml(consoleDetailMessages.filter)} <input type="search" data-log-filter></label> <label><input type="checkbox" data-log-follow> ${escapeHtml(consoleDetailMessages.follow)}</label> <button type="button" data-log-incoming hidden>${escapeHtml(consoleDetailMessages.incoming)}</button></div><div data-log-content>${logsScreenBody(state, terminalEnabled, ptyEnabled)}</div>`),
|
|
6087
7360
|
screenSection("config", "Editable configuration", 'Configuration <span class="pill warn">editable</span>', "Edit the whole openteam JSON configuration. Roles are editable inside the JSON when present; unsupported surfaces are not shown.", configScreenBody(options.configEditor?.hasToken === true))
|
|
6088
7361
|
].join("");
|
|
6089
7362
|
const session = state.session.id === undefined ? "" : ` · session ${escapeHtml(state.session.id)}`;
|
|
6090
|
-
const tokenAttr = (terminalEnabled || graphDrilldown || configEnabled) && options.consoleToken !== undefined ? ` data-token="${escapeHtml(options.consoleToken)}"${terminalEnabled ? ' data-terminal="1"' : ""}${ptyEnabled ? ' data-pty="1"' : ""}${graphDrilldown ? ' data-drilldown="1"' : ""}${configEnabled ? ' data-config="1"' : ""}` : "";
|
|
7363
|
+
const tokenAttr = (terminalEnabled || graphDrilldown || configEnabled || lifecycleEnabled) && options.consoleToken !== undefined ? ` data-token="${escapeHtml(options.consoleToken)}"${terminalEnabled ? ' data-terminal="1"' : ""}${ptyEnabled ? ' data-pty="1"' : ""}${graphDrilldown ? ' data-drilldown="1"' : ""}${configEnabled ? ' data-config="1"' : ""}` : "";
|
|
6091
7364
|
return [
|
|
6092
7365
|
"<!doctype html>",
|
|
6093
7366
|
`<html lang="en" data-generated="${escapeHtml(state.generatedAt)}" data-refresh="${refreshMs}"${tokenAttr}>`,
|
|
@@ -6096,7 +7369,7 @@ function renderConsoleHtml(state, options = {}) {
|
|
|
6096
7369
|
'<meta name="viewport" content="width=device-width,initial-scale=1">',
|
|
6097
7370
|
"<title>openteam console</title>",
|
|
6098
7371
|
lifecycleEnabled ? `<script>${LIFECYCLE_THEME_BOOT}</script>` : "",
|
|
6099
|
-
`<style>${CONSOLE_STYLE}${graphOptionProvided ? GRAPH_STYLE : ""}${lifecycleEnabled ? LIFECYCLE_STYLE : ""}</style>`,
|
|
7372
|
+
`<style>${CONSOLE_STYLE}${graphOptionProvided ? GRAPH_STYLE : ""}${lifecycleEnabled ? LIFECYCLE_STYLE + CONVERSATION_STYLE : ""}</style>`,
|
|
6100
7373
|
"</head>",
|
|
6101
7374
|
"<body>",
|
|
6102
7375
|
'<div class="app">',
|
|
@@ -6107,6 +7380,7 @@ function renderConsoleHtml(state, options = {}) {
|
|
|
6107
7380
|
'<button type="button" class="icon-btn menu-btn" data-toggle-nav aria-label="Open navigation"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 6h16M4 12h16M4 18h16"></path></svg></button>',
|
|
6108
7381
|
'<h1 id="screen-title">Agent tree</h1>',
|
|
6109
7382
|
`<span class="refresh" title="SSE + polling"><span class="beat"></span> ${refreshMs} ms · SSE</span>`,
|
|
7383
|
+
`<span data-refresh-error role="status" hidden>${escapeHtml(consoleDetailMessages.refreshError)}</span>`,
|
|
6110
7384
|
'<div class="spacer"></div>',
|
|
6111
7385
|
`<span class="token-chip" title="Page status"><span class="lbl">updated</span> <b class="mono">${escapeHtml(state.generatedAt)}${session}</b></span>`,
|
|
6112
7386
|
"</header>",
|
|
@@ -6120,6 +7394,16 @@ function renderConsoleHtml(state, options = {}) {
|
|
|
6120
7394
|
"</html>"
|
|
6121
7395
|
].join("");
|
|
6122
7396
|
}
|
|
7397
|
+
function renderConsoleUpdate(state, options = {}) {
|
|
7398
|
+
return {
|
|
7399
|
+
routing: routingScreenBody(state),
|
|
7400
|
+
logs: logsScreenBody(state, options.terminalEnabled === true, options.ptyEnabled === true),
|
|
7401
|
+
sessionCount: state.sessionsDetail.length,
|
|
7402
|
+
...options.graphView ? {
|
|
7403
|
+
tree: treeGraphPanel(options.graphView.projection, options.drilldownEnabled === true, false, options.graphView.mode ?? "active")
|
|
7404
|
+
} : {}
|
|
7405
|
+
};
|
|
7406
|
+
}
|
|
6123
7407
|
|
|
6124
7408
|
// src/console/configView.ts
|
|
6125
7409
|
var OVERLAY_PATH = ".opencode/openteam-local/config.local.json";
|
|
@@ -6268,7 +7552,7 @@ function isCrossOriginMutation(request) {
|
|
|
6268
7552
|
}
|
|
6269
7553
|
}
|
|
6270
7554
|
async function readJsonBody(request, limit) {
|
|
6271
|
-
return new Promise((
|
|
7555
|
+
return new Promise((resolve2) => {
|
|
6272
7556
|
let raw = "";
|
|
6273
7557
|
let aborted = false;
|
|
6274
7558
|
request.on("data", (chunk) => {
|
|
@@ -6278,7 +7562,7 @@ async function readJsonBody(request, limit) {
|
|
|
6278
7562
|
raw += chunk.toString("utf8");
|
|
6279
7563
|
if (raw.length > limit) {
|
|
6280
7564
|
aborted = true;
|
|
6281
|
-
|
|
7565
|
+
resolve2({ ok: false });
|
|
6282
7566
|
}
|
|
6283
7567
|
});
|
|
6284
7568
|
request.on("end", () => {
|
|
@@ -6286,12 +7570,12 @@ async function readJsonBody(request, limit) {
|
|
|
6286
7570
|
return;
|
|
6287
7571
|
}
|
|
6288
7572
|
try {
|
|
6289
|
-
|
|
7573
|
+
resolve2({ ok: true, value: JSON.parse(raw) });
|
|
6290
7574
|
} catch {
|
|
6291
|
-
|
|
7575
|
+
resolve2({ ok: false });
|
|
6292
7576
|
}
|
|
6293
7577
|
});
|
|
6294
|
-
request.on("error", () =>
|
|
7578
|
+
request.on("error", () => resolve2({ ok: false }));
|
|
6295
7579
|
});
|
|
6296
7580
|
}
|
|
6297
7581
|
async function handleConfigRoute(request, response, url, deps) {
|
|
@@ -6361,6 +7645,7 @@ var DEFAULT_BACKLOG_PATH = ".opencode/openteam/backlog.md";
|
|
|
6361
7645
|
var DEFAULT_DECISIONS_PATH = ".opencode/openteam/decisions.md";
|
|
6362
7646
|
|
|
6363
7647
|
// src/web/server.ts
|
|
7648
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6364
7649
|
import {
|
|
6365
7650
|
createServer as createHttpServer
|
|
6366
7651
|
} from "node:http";
|
|
@@ -6671,7 +7956,7 @@ function authorized2(request, query, token) {
|
|
|
6671
7956
|
return provided !== undefined && safeEqualToken(provided, token);
|
|
6672
7957
|
}
|
|
6673
7958
|
async function readJsonBody2(request, limit) {
|
|
6674
|
-
return new Promise((
|
|
7959
|
+
return new Promise((resolve2) => {
|
|
6675
7960
|
let raw = "";
|
|
6676
7961
|
let aborted = false;
|
|
6677
7962
|
request.on("data", (chunk) => {
|
|
@@ -6681,7 +7966,7 @@ async function readJsonBody2(request, limit) {
|
|
|
6681
7966
|
raw += chunk.toString("utf8");
|
|
6682
7967
|
if (raw.length > limit) {
|
|
6683
7968
|
aborted = true;
|
|
6684
|
-
|
|
7969
|
+
resolve2(undefined);
|
|
6685
7970
|
}
|
|
6686
7971
|
});
|
|
6687
7972
|
request.on("end", () => {
|
|
@@ -6689,12 +7974,12 @@ async function readJsonBody2(request, limit) {
|
|
|
6689
7974
|
return;
|
|
6690
7975
|
}
|
|
6691
7976
|
try {
|
|
6692
|
-
|
|
7977
|
+
resolve2(JSON.parse(raw));
|
|
6693
7978
|
} catch {
|
|
6694
|
-
|
|
7979
|
+
resolve2(undefined);
|
|
6695
7980
|
}
|
|
6696
7981
|
});
|
|
6697
|
-
request.on("error", () =>
|
|
7982
|
+
request.on("error", () => resolve2(undefined));
|
|
6698
7983
|
});
|
|
6699
7984
|
}
|
|
6700
7985
|
function parseConsolePath(path) {
|
|
@@ -6734,8 +8019,12 @@ async function handleMessages(_request, response, sessionID, deps, diagnostic) {
|
|
|
6734
8019
|
response.writeHead(404, JSON_HEADERS3).end(JSON.stringify({ error: "no endpoint" }));
|
|
6735
8020
|
return;
|
|
6736
8021
|
}
|
|
6737
|
-
|
|
6738
|
-
|
|
8022
|
+
try {
|
|
8023
|
+
const frames = await deps.createClient(endpoint).listMessages(sessionID, { diagnostic });
|
|
8024
|
+
response.writeHead(200, { ...JSON_HEADERS3, "cache-control": "no-store" }).end(JSON.stringify({ frames }));
|
|
8025
|
+
} catch {
|
|
8026
|
+
response.writeHead(503, JSON_HEADERS3).end(JSON.stringify({ error: consoleDetailMessages.readFailed }));
|
|
8027
|
+
}
|
|
6739
8028
|
}
|
|
6740
8029
|
async function handleInput(request, response, sessionID, deps) {
|
|
6741
8030
|
const endpoint = await deps.resolveEndpoint(sessionID);
|
|
@@ -6839,6 +8128,201 @@ async function handleConsoleRoute(request, response, url, deps) {
|
|
|
6839
8128
|
return true;
|
|
6840
8129
|
}
|
|
6841
8130
|
|
|
8131
|
+
// src/web/conversationRoute.ts
|
|
8132
|
+
async function untilAborted(read, signal) {
|
|
8133
|
+
let cancel = () => {};
|
|
8134
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
8135
|
+
cancel = () => reject(signal.reason);
|
|
8136
|
+
if (signal.aborted)
|
|
8137
|
+
cancel();
|
|
8138
|
+
else
|
|
8139
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
8140
|
+
});
|
|
8141
|
+
try {
|
|
8142
|
+
return await Promise.race([read, aborted]);
|
|
8143
|
+
} finally {
|
|
8144
|
+
signal.removeEventListener("abort", cancel);
|
|
8145
|
+
}
|
|
8146
|
+
}
|
|
8147
|
+
async function handleConversationRoute(request, response, url, deps) {
|
|
8148
|
+
const labelsOnly = url.pathname === "/api/graph/session-labels";
|
|
8149
|
+
if (url.pathname !== "/api/graph/conversation" && !labelsOnly)
|
|
8150
|
+
return false;
|
|
8151
|
+
const send = (status, kind, message, extra = {}) => {
|
|
8152
|
+
response.writeHead(status, {
|
|
8153
|
+
"content-type": "application/json",
|
|
8154
|
+
"cache-control": "no-store",
|
|
8155
|
+
"referrer-policy": "no-referrer"
|
|
8156
|
+
}).end(JSON.stringify({ version: 1, kind, message, ...extra }));
|
|
8157
|
+
};
|
|
8158
|
+
const authorization = request.headers.authorization;
|
|
8159
|
+
const bearer = authorization?.startsWith("Bearer ") ? authorization.slice(7) : undefined;
|
|
8160
|
+
const token = url.searchParams.get("token") ?? bearer;
|
|
8161
|
+
if (!token || !safeEqualToken(token, deps.token)) {
|
|
8162
|
+
send(401, "unauthorized", consoleDetailMessages.unauthorized);
|
|
8163
|
+
return true;
|
|
8164
|
+
}
|
|
8165
|
+
if (request.method !== "GET") {
|
|
8166
|
+
send(405, "unavailable", consoleDetailMessages.unauthorized);
|
|
8167
|
+
return true;
|
|
8168
|
+
}
|
|
8169
|
+
if (!deps.enabled || !deps.contentEnabled || url.searchParams.get("diagnostic") !== "1") {
|
|
8170
|
+
send(403, "disabled", consoleDetailMessages.disabled);
|
|
8171
|
+
return true;
|
|
8172
|
+
}
|
|
8173
|
+
const params = url.searchParams;
|
|
8174
|
+
const rootTarget = params.get("target") === "root";
|
|
8175
|
+
if ((labelsOnly ? params.has("run") ? ["run"] : [] : rootTarget ? ["run", "operation"] : ["run", "operation", "attempt"]).some((key) => params.getAll(key).length !== 1 || !params.get(key)) || params.has("session") || params.getAll("target").length > 1 || params.has("target") && !rootTarget && params.get("target") !== "attempt" || rootTarget && params.has("attempt") || labelsOnly && (params.has("operation") || params.has("attempt") || params.has("target"))) {
|
|
8176
|
+
send(400, "invalid", consoleDetailMessages.invalid);
|
|
8177
|
+
return true;
|
|
8178
|
+
}
|
|
8179
|
+
if (labelsOnly) {
|
|
8180
|
+
const selected = params.has("run") ? await readLifecycleHistoryQuery(deps.reader, params) : undefined;
|
|
8181
|
+
if (selected && (selected.kind !== "view" || selected.selection.runID !== params.get("run"))) {
|
|
8182
|
+
send(409, "invalid", consoleDetailMessages.invalid);
|
|
8183
|
+
return true;
|
|
8184
|
+
}
|
|
8185
|
+
if (params.has("cursor")) {
|
|
8186
|
+
send(409, "historical", consoleDetailMessages.historical);
|
|
8187
|
+
return true;
|
|
8188
|
+
}
|
|
8189
|
+
const controller2 = new AbortController;
|
|
8190
|
+
const cancel2 = () => controller2.abort();
|
|
8191
|
+
response.on("close", cancel2);
|
|
8192
|
+
request.on("aborted", cancel2);
|
|
8193
|
+
request.socket.on("close", cancel2);
|
|
8194
|
+
if (request.aborted || request.socket.destroyed)
|
|
8195
|
+
cancel2();
|
|
8196
|
+
const deadline = Date.now() + SESSION_HISTORY_LIMITS.timeoutMs;
|
|
8197
|
+
const timeout = setTimeout(cancel2, SESSION_HISTORY_LIMITS.timeoutMs);
|
|
8198
|
+
try {
|
|
8199
|
+
const history2 = selected?.kind === "view" ? selected : undefined;
|
|
8200
|
+
const selectedRoot = history2?.runs.find((run) => run.runID === history2.selection.runID)?.rootSessionID;
|
|
8201
|
+
const eligibleIDs = [
|
|
8202
|
+
...new Set([
|
|
8203
|
+
...selectedRoot ? [selectedRoot] : [],
|
|
8204
|
+
...history2?.projection.operations.flatMap((op) => op.attempts.flatMap((attempt2) => attempt2.sessionID ? [attempt2.sessionID] : [])) ?? [],
|
|
8205
|
+
...history2?.runs.flatMap((run) => run.rootSessionID ? [run.rootSessionID] : []) ?? [],
|
|
8206
|
+
...deps.observedSessionIDs ? await untilAborted(deps.observedSessionIDs(), controller2.signal) : []
|
|
8207
|
+
])
|
|
8208
|
+
];
|
|
8209
|
+
const ids = eligibleIDs.slice(0, SESSION_HISTORY_LIMITS.labels);
|
|
8210
|
+
const groups = new Map;
|
|
8211
|
+
for (const id of ids) {
|
|
8212
|
+
if (controller2.signal.aborted)
|
|
8213
|
+
break;
|
|
8214
|
+
try {
|
|
8215
|
+
const endpoint = await untilAborted(deps.resolveEndpoint(id), controller2.signal);
|
|
8216
|
+
if (!endpoint)
|
|
8217
|
+
continue;
|
|
8218
|
+
const group = groups.get(endpoint) ?? [];
|
|
8219
|
+
group.push(id);
|
|
8220
|
+
groups.set(endpoint, group);
|
|
8221
|
+
} catch {}
|
|
8222
|
+
}
|
|
8223
|
+
const sessions = [];
|
|
8224
|
+
const budget = { remaining: SESSION_HISTORY_LIMITS.bytes };
|
|
8225
|
+
let groupsLeft = groups.size;
|
|
8226
|
+
for (const [endpoint, group] of groups) {
|
|
8227
|
+
if (controller2.signal.aborted || !deps.readConversation.labels)
|
|
8228
|
+
break;
|
|
8229
|
+
try {
|
|
8230
|
+
sessions.push(...await untilAborted(deps.readConversation.labels(endpoint, group, controller2.signal, {
|
|
8231
|
+
budget,
|
|
8232
|
+
timeoutMs: Math.max(1, Math.floor((deadline - Date.now()) / groupsLeft))
|
|
8233
|
+
}), controller2.signal));
|
|
8234
|
+
} catch {}
|
|
8235
|
+
groupsLeft--;
|
|
8236
|
+
}
|
|
8237
|
+
const found = new Set(sessions.map((session) => session.id));
|
|
8238
|
+
const unavailableSessionIDs = ids.filter((id) => !found.has(id));
|
|
8239
|
+
const truncated = eligibleIDs.length > ids.length;
|
|
8240
|
+
const partial = truncated || unavailableSessionIDs.length > 0;
|
|
8241
|
+
if (response.destroyed || request.socket.destroyed)
|
|
8242
|
+
return true;
|
|
8243
|
+
if (ids.length && !sessions.length) {
|
|
8244
|
+
send(503, "unavailable", consoleDetailMessages.readFailed, {
|
|
8245
|
+
completeness: "partial",
|
|
8246
|
+
unavailableSessionIDs,
|
|
8247
|
+
...truncated ? { truncated: true } : {}
|
|
8248
|
+
});
|
|
8249
|
+
return true;
|
|
8250
|
+
}
|
|
8251
|
+
send(200, "labels", partial ? `${consoleDetailMessages.currentMetadata}
|
|
8252
|
+
${consoleDetailMessages.partialMetadata}` : consoleDetailMessages.currentMetadata, {
|
|
8253
|
+
runID: history2?.selection.runID ?? null,
|
|
8254
|
+
sessions,
|
|
8255
|
+
completeness: partial ? "partial" : "complete",
|
|
8256
|
+
unavailableSessionIDs,
|
|
8257
|
+
...truncated ? { truncated: true } : {}
|
|
8258
|
+
});
|
|
8259
|
+
} catch {
|
|
8260
|
+
if (!response.destroyed && !request.socket.destroyed)
|
|
8261
|
+
send(503, "unavailable", consoleDetailMessages.unavailable);
|
|
8262
|
+
} finally {
|
|
8263
|
+
clearTimeout(timeout);
|
|
8264
|
+
response.off("close", cancel2);
|
|
8265
|
+
request.off("aborted", cancel2);
|
|
8266
|
+
request.socket.off("close", cancel2);
|
|
8267
|
+
}
|
|
8268
|
+
return true;
|
|
8269
|
+
}
|
|
8270
|
+
const history = await readLifecycleHistoryQuery(deps.reader, params);
|
|
8271
|
+
if (history.kind !== "view" || history.selection.runID !== params.get("run")) {
|
|
8272
|
+
send(409, "invalid", consoleDetailMessages.invalid);
|
|
8273
|
+
return true;
|
|
8274
|
+
}
|
|
8275
|
+
const operation = history.projection.operations.find((item) => item.operationID === params.get("operation"));
|
|
8276
|
+
const attempt = operation?.attempts.find((item) => item.attemptID === params.get("attempt"));
|
|
8277
|
+
if (!labelsOnly && (rootTarget ? !operation || operation.operationID !== history.projection.rootOperationID || operation.kind !== "coordinator" : !attempt?.sessionID)) {
|
|
8278
|
+
send(404, "invalid", consoleDetailMessages.invalid);
|
|
8279
|
+
return true;
|
|
8280
|
+
}
|
|
8281
|
+
if (params.has("cursor") || !history.selection.followLive) {
|
|
8282
|
+
send(409, "historical", consoleDetailMessages.historical);
|
|
8283
|
+
return true;
|
|
8284
|
+
}
|
|
8285
|
+
const controller = new AbortController;
|
|
8286
|
+
const cancel = () => controller.abort();
|
|
8287
|
+
response.on("close", cancel);
|
|
8288
|
+
try {
|
|
8289
|
+
const run = history.runs.find((item) => item.runID === history.selection.runID);
|
|
8290
|
+
const recordedRoot = run?.rootSessionID;
|
|
8291
|
+
const sessionID = rootTarget ? recordedRoot : attempt?.sessionID;
|
|
8292
|
+
const endpointID = sessionID ?? history.projection.operations.flatMap((op) => op.attempts).filter((item) => item.sessionID).at(-1)?.sessionID ?? "";
|
|
8293
|
+
const endpoint = await deps.resolveEndpoint(endpointID);
|
|
8294
|
+
if (!endpoint) {
|
|
8295
|
+
send(503, "unavailable", consoleDetailMessages.unavailable);
|
|
8296
|
+
return true;
|
|
8297
|
+
}
|
|
8298
|
+
const recovered = !sessionID && rootTarget && deps.readConversation.root ? await deps.readConversation.root(endpoint, history.projection, controller.signal) : undefined;
|
|
8299
|
+
const resolvedID = sessionID ?? recovered?.session.id;
|
|
8300
|
+
if (!resolvedID)
|
|
8301
|
+
throw new AssociationError("unavailable");
|
|
8302
|
+
const conversation = recovered ?? await deps.readConversation(endpoint, resolvedID, controller.signal);
|
|
8303
|
+
const current = rootTarget ? `${consoleDetailMessages.rootCurrent}
|
|
8304
|
+
${consoleDetailMessages.current}${recovered ? `
|
|
8305
|
+
${consoleDetailMessages.recovered}` : ""}` : consoleDetailMessages.current;
|
|
8306
|
+
send(200, conversation.messages.length || conversation.truncated ? "conversation" : "empty", conversation.truncated ? `${current}
|
|
8307
|
+
${consoleDetailMessages.truncated}` : conversation.messages.length ? current : `${current}
|
|
8308
|
+
${consoleDetailMessages.empty}`, {
|
|
8309
|
+
scope: "present-day-session",
|
|
8310
|
+
runID: history.selection.runID,
|
|
8311
|
+
operationID: operation?.operationID,
|
|
8312
|
+
target: rootTarget ? "root" : "attempt",
|
|
8313
|
+
...rootTarget ? {} : { attemptID: attempt?.attemptID },
|
|
8314
|
+
sessionID: resolvedID,
|
|
8315
|
+
...conversation
|
|
8316
|
+
});
|
|
8317
|
+
} catch (error) {
|
|
8318
|
+
if (!controller.signal.aborted)
|
|
8319
|
+
send(error instanceof ConversationTooLargeError ? 413 : 503, error instanceof ConversationTooLargeError ? "oversized" : "unavailable", error instanceof AssociationError ? error.message : error instanceof ConversationTooLargeError ? consoleDetailMessages.oversized : consoleDetailMessages.unavailable);
|
|
8320
|
+
} finally {
|
|
8321
|
+
response.off("close", cancel);
|
|
8322
|
+
}
|
|
8323
|
+
return true;
|
|
8324
|
+
}
|
|
8325
|
+
|
|
6842
8326
|
// src/web/storageRoute.ts
|
|
6843
8327
|
var JSON_HEADERS4 = { "content-type": "application/json" };
|
|
6844
8328
|
var READ_OPS = new Set(["read", "exists", "list", "isDirectory", "stat"]);
|
|
@@ -6868,7 +8352,7 @@ function pathAllowed(path, allowPrefixes) {
|
|
|
6868
8352
|
});
|
|
6869
8353
|
}
|
|
6870
8354
|
async function readJsonBody3(request, limit) {
|
|
6871
|
-
return new Promise((
|
|
8355
|
+
return new Promise((resolve2) => {
|
|
6872
8356
|
let raw = "";
|
|
6873
8357
|
let aborted = false;
|
|
6874
8358
|
request.on("data", (chunk) => {
|
|
@@ -6878,19 +8362,19 @@ async function readJsonBody3(request, limit) {
|
|
|
6878
8362
|
raw += chunk.toString("utf8");
|
|
6879
8363
|
if (raw.length > limit) {
|
|
6880
8364
|
aborted = true;
|
|
6881
|
-
|
|
8365
|
+
resolve2(undefined);
|
|
6882
8366
|
}
|
|
6883
8367
|
});
|
|
6884
8368
|
request.on("end", () => {
|
|
6885
8369
|
if (!aborted) {
|
|
6886
8370
|
try {
|
|
6887
|
-
|
|
8371
|
+
resolve2(JSON.parse(raw));
|
|
6888
8372
|
} catch {
|
|
6889
|
-
|
|
8373
|
+
resolve2(undefined);
|
|
6890
8374
|
}
|
|
6891
8375
|
}
|
|
6892
8376
|
});
|
|
6893
|
-
request.on("error", () =>
|
|
8377
|
+
request.on("error", () => resolve2(undefined));
|
|
6894
8378
|
});
|
|
6895
8379
|
}
|
|
6896
8380
|
function sendJson(response, status, body) {
|
|
@@ -7068,18 +8552,18 @@ data: ${json}
|
|
|
7068
8552
|
`;
|
|
7069
8553
|
}
|
|
7070
8554
|
function tryListen(server, host, port) {
|
|
7071
|
-
return new Promise((
|
|
8555
|
+
return new Promise((resolve2, reject) => {
|
|
7072
8556
|
const onError = (error) => {
|
|
7073
8557
|
server.removeListener("listening", onListening);
|
|
7074
8558
|
if (isAddressInUse(error)) {
|
|
7075
|
-
|
|
8559
|
+
resolve2(false);
|
|
7076
8560
|
} else {
|
|
7077
8561
|
reject(error);
|
|
7078
8562
|
}
|
|
7079
8563
|
};
|
|
7080
8564
|
const onListening = () => {
|
|
7081
8565
|
server.removeListener("error", onError);
|
|
7082
|
-
|
|
8566
|
+
resolve2(true);
|
|
7083
8567
|
};
|
|
7084
8568
|
server.once("error", onError);
|
|
7085
8569
|
server.once("listening", onListening);
|
|
@@ -7114,6 +8598,20 @@ async function createConsoleServer(deps) {
|
|
|
7114
8598
|
};
|
|
7115
8599
|
const handle = async (request, response) => {
|
|
7116
8600
|
const url2 = new URL(request.url ?? "/", "http://localhost");
|
|
8601
|
+
if (["/api/graph/conversation", "/api/graph/session-labels"].includes(url2.pathname) && deps.storageApi && !readAuthorized2(request, url2, deps.storageApi.token)) {
|
|
8602
|
+
response.writeHead(401, { ...JSON_HEADERS5, "cache-control": "no-store" }).end(JSON.stringify({ version: 1, kind: "unauthorized" }));
|
|
8603
|
+
return;
|
|
8604
|
+
}
|
|
8605
|
+
if (deps.console?.readConversation && deps.lifecycleHistoryApi && await handleConversationRoute(request, response, url2, {
|
|
8606
|
+
token: deps.console.token,
|
|
8607
|
+
enabled: deps.config.graphView?.enabled === true,
|
|
8608
|
+
contentEnabled: deps.console.conversationContentEnabled === true,
|
|
8609
|
+
reader: deps.lifecycleHistoryApi.reader,
|
|
8610
|
+
resolveEndpoint: async (id) => deps.console?.historyEndpoint ?? await resolveEndpoint(id),
|
|
8611
|
+
observedSessionIDs: async () => buildConsoleState(await deps.readSnapshot()).sessions.map((session) => session.sessionID),
|
|
8612
|
+
readConversation: deps.console.readConversation
|
|
8613
|
+
}))
|
|
8614
|
+
return;
|
|
7117
8615
|
if (consoleDeps !== undefined && await handleConsoleRoute(request, response, url2, consoleDeps)) {
|
|
7118
8616
|
return;
|
|
7119
8617
|
}
|
|
@@ -7143,7 +8641,7 @@ async function createConsoleServer(deps) {
|
|
|
7143
8641
|
}
|
|
7144
8642
|
const path = url2.pathname;
|
|
7145
8643
|
const remoteToken = deps.storageApi?.token;
|
|
7146
|
-
if (remoteToken !== undefined && (path === "/" || path === "/index.html" || path === "/api/state" || path === "/events") && !readAuthorized2(request, url2, remoteToken)) {
|
|
8644
|
+
if (remoteToken !== undefined && (path === "/" || path === "/index.html" || path === "/api/state" || path === "/api/view" || path === "/events") && !readAuthorized2(request, url2, remoteToken)) {
|
|
7147
8645
|
response.writeHead(401, JSON_HEADERS5).end(JSON.stringify({ error: "unauthorized" }));
|
|
7148
8646
|
return;
|
|
7149
8647
|
}
|
|
@@ -7155,6 +8653,34 @@ async function createConsoleServer(deps) {
|
|
|
7155
8653
|
response.writeHead(200, JSON_HEADERS5).end(await stateJson(deps));
|
|
7156
8654
|
return;
|
|
7157
8655
|
}
|
|
8656
|
+
if (path === "/api/view") {
|
|
8657
|
+
const state = buildConsoleState(await deps.readSnapshot());
|
|
8658
|
+
const view = {
|
|
8659
|
+
...renderConsoleUpdate(state, {
|
|
8660
|
+
...deps.console,
|
|
8661
|
+
...deps.graphApi && !deps.lifecycleHistoryApi ? {
|
|
8662
|
+
graphView: {
|
|
8663
|
+
projection: await deps.graphApi.readView(),
|
|
8664
|
+
mode: deps.graphMode ?? "active"
|
|
8665
|
+
}
|
|
8666
|
+
} : {}
|
|
8667
|
+
}),
|
|
8668
|
+
refreshMs: (deps.getConsoleConfig?.() ?? deps.config).refreshMs
|
|
8669
|
+
};
|
|
8670
|
+
const json = JSON.stringify(view);
|
|
8671
|
+
const revision = `"${createHash2("sha256").update(json).digest("hex")}"`;
|
|
8672
|
+
const headers = {
|
|
8673
|
+
...JSON_HEADERS5,
|
|
8674
|
+
etag: revision,
|
|
8675
|
+
"cache-control": "no-store"
|
|
8676
|
+
};
|
|
8677
|
+
if (request.headers["if-none-match"] === revision) {
|
|
8678
|
+
response.writeHead(304, headers).end();
|
|
8679
|
+
} else {
|
|
8680
|
+
response.writeHead(200, headers).end(JSON.stringify({ ...view, updatedAt: state.generatedAt }));
|
|
8681
|
+
}
|
|
8682
|
+
return;
|
|
8683
|
+
}
|
|
7158
8684
|
if (path === "/healthz") {
|
|
7159
8685
|
response.writeHead(200, JSON_HEADERS5).end(JSON.stringify({ ok: true }));
|
|
7160
8686
|
return;
|
|
@@ -7719,19 +9245,19 @@ import { readdirSync, readFileSync } from "node:fs";
|
|
|
7719
9245
|
import { join as join2 } from "node:path";
|
|
7720
9246
|
|
|
7721
9247
|
// src/storage/lifecycle/codec.ts
|
|
7722
|
-
import { z as
|
|
9248
|
+
import { z as z13 } from "zod";
|
|
7723
9249
|
|
|
7724
9250
|
// src/lifecycle/schema.ts
|
|
7725
|
-
import { z as
|
|
7726
|
-
var nonEmptyString =
|
|
7727
|
-
var nonNegativeInteger =
|
|
7728
|
-
var positiveInteger =
|
|
7729
|
-
var modelSelectionSchema2 =
|
|
9251
|
+
import { z as z12 } from "zod";
|
|
9252
|
+
var nonEmptyString = z12.string().min(1);
|
|
9253
|
+
var nonNegativeInteger = z12.number().int().nonnegative();
|
|
9254
|
+
var positiveInteger = z12.number().int().positive();
|
|
9255
|
+
var modelSelectionSchema2 = z12.object({
|
|
7730
9256
|
providerID: nonEmptyString,
|
|
7731
9257
|
modelID: nonEmptyString
|
|
7732
9258
|
}).strict();
|
|
7733
|
-
var lifecycleFailureSchema =
|
|
7734
|
-
class:
|
|
9259
|
+
var lifecycleFailureSchema = z12.object({
|
|
9260
|
+
class: z12.enum([
|
|
7735
9261
|
"routing-blocked",
|
|
7736
9262
|
"create-rejected",
|
|
7737
9263
|
"create-no-id",
|
|
@@ -7753,25 +9279,25 @@ var lifecycleFailureSchema = z10.object({
|
|
|
7753
9279
|
"interrupted",
|
|
7754
9280
|
"unknown"
|
|
7755
9281
|
]),
|
|
7756
|
-
statusCode:
|
|
7757
|
-
retryable:
|
|
9282
|
+
statusCode: z12.number().int().min(100).max(599).optional(),
|
|
9283
|
+
retryable: z12.boolean().optional()
|
|
7758
9284
|
}).strict();
|
|
7759
|
-
var lifecycleRootOperationSchema =
|
|
9285
|
+
var lifecycleRootOperationSchema = z12.object({
|
|
7760
9286
|
operationID: nonEmptyString,
|
|
7761
9287
|
taskID: nonEmptyString,
|
|
7762
|
-
kind:
|
|
9288
|
+
kind: z12.enum(["coordinator", "graph-node"]),
|
|
7763
9289
|
roleID: nonEmptyString,
|
|
7764
9290
|
agentID: nonEmptyString.optional(),
|
|
7765
9291
|
sessionID: nonEmptyString.optional()
|
|
7766
9292
|
}).strict();
|
|
7767
|
-
var lifecycleRunStartInputSchema =
|
|
9293
|
+
var lifecycleRunStartInputSchema = z12.object({
|
|
7768
9294
|
runID: nonEmptyString,
|
|
7769
|
-
source:
|
|
7770
|
-
executionAuthority:
|
|
9295
|
+
source: z12.enum(["plugin", "cli"]),
|
|
9296
|
+
executionAuthority: z12.enum(["coordinator", "graph"]),
|
|
7771
9297
|
root: lifecycleRootOperationSchema
|
|
7772
9298
|
}).strict();
|
|
7773
9299
|
var LifecycleRunMetadataSchema = lifecycleRunStartInputSchema.extend({
|
|
7774
|
-
version:
|
|
9300
|
+
version: z12.literal(1),
|
|
7775
9301
|
createdAt: nonNegativeInteger
|
|
7776
9302
|
}).strict();
|
|
7777
9303
|
var attemptRefShape = {
|
|
@@ -7783,34 +9309,34 @@ var attemptRefShape = {
|
|
|
7783
9309
|
retryIndex: nonNegativeInteger
|
|
7784
9310
|
};
|
|
7785
9311
|
var eventEnvelopeShape = {
|
|
7786
|
-
v:
|
|
9312
|
+
v: z12.literal(1),
|
|
7787
9313
|
seq: nonNegativeInteger,
|
|
7788
9314
|
runID: nonEmptyString,
|
|
7789
9315
|
at: nonNegativeInteger
|
|
7790
9316
|
};
|
|
7791
9317
|
var runStartedBodyShape = {
|
|
7792
|
-
type:
|
|
7793
|
-
source:
|
|
7794
|
-
executionAuthority:
|
|
9318
|
+
type: z12.literal("run.started"),
|
|
9319
|
+
source: z12.enum(["plugin", "cli"]),
|
|
9320
|
+
executionAuthority: z12.enum(["coordinator", "graph"]),
|
|
7795
9321
|
root: lifecycleRootOperationSchema
|
|
7796
9322
|
};
|
|
7797
9323
|
var operationQueuedBodyShape = {
|
|
7798
|
-
type:
|
|
9324
|
+
type: z12.literal("operation.queued"),
|
|
7799
9325
|
operationID: nonEmptyString,
|
|
7800
9326
|
taskID: nonEmptyString,
|
|
7801
|
-
kind:
|
|
9327
|
+
kind: z12.enum(["role", "graph-node"]),
|
|
7802
9328
|
roleID: nonEmptyString,
|
|
7803
9329
|
agentID: nonEmptyString.optional(),
|
|
7804
9330
|
parentOperationID: nonEmptyString,
|
|
7805
|
-
dependsOnOperationIDs:
|
|
9331
|
+
dependsOnOperationIDs: z12.array(nonEmptyString).readonly()
|
|
7806
9332
|
};
|
|
7807
9333
|
var modelSelectedBodyShape = {
|
|
7808
|
-
type:
|
|
9334
|
+
type: z12.literal("attempt.model-selected"),
|
|
7809
9335
|
...attemptRefShape,
|
|
7810
9336
|
decisionID: nonEmptyString,
|
|
7811
9337
|
model: modelSelectionSchema2,
|
|
7812
|
-
routeKind:
|
|
7813
|
-
selectionCause:
|
|
9338
|
+
routeKind: z12.enum(["local", "frontier"]),
|
|
9339
|
+
selectionCause: z12.enum([
|
|
7814
9340
|
"initial",
|
|
7815
9341
|
"retry-incomplete",
|
|
7816
9342
|
"retry-transport",
|
|
@@ -7820,31 +9346,31 @@ var modelSelectedBodyShape = {
|
|
|
7820
9346
|
runtimeID: nonEmptyString.optional()
|
|
7821
9347
|
};
|
|
7822
9348
|
var attemptQueuedBodyShape = {
|
|
7823
|
-
type:
|
|
9349
|
+
type: z12.literal("attempt.queued"),
|
|
7824
9350
|
...attemptRefShape,
|
|
7825
9351
|
runtimeID: nonEmptyString.optional()
|
|
7826
9352
|
};
|
|
7827
9353
|
var attemptStartedBodyShape = {
|
|
7828
|
-
type:
|
|
9354
|
+
type: z12.literal("attempt.started"),
|
|
7829
9355
|
...attemptRefShape
|
|
7830
9356
|
};
|
|
7831
9357
|
var sessionCreatedBodyShape = {
|
|
7832
|
-
type:
|
|
9358
|
+
type: z12.literal("session.created"),
|
|
7833
9359
|
...attemptRefShape,
|
|
7834
9360
|
sessionID: nonEmptyString,
|
|
7835
9361
|
parentSessionID: nonEmptyString.optional()
|
|
7836
9362
|
};
|
|
7837
9363
|
var attemptTerminalBodyShape = {
|
|
7838
|
-
type:
|
|
9364
|
+
type: z12.literal("attempt.terminal"),
|
|
7839
9365
|
...attemptRefShape,
|
|
7840
|
-
outcome:
|
|
9366
|
+
outcome: z12.enum([
|
|
7841
9367
|
"succeeded",
|
|
7842
9368
|
"failed",
|
|
7843
9369
|
"cancelled",
|
|
7844
9370
|
"interrupted",
|
|
7845
9371
|
"unknown"
|
|
7846
9372
|
]),
|
|
7847
|
-
continuation:
|
|
9373
|
+
continuation: z12.enum([
|
|
7848
9374
|
"none",
|
|
7849
9375
|
"retry-same-model",
|
|
7850
9376
|
"fallback-next-model",
|
|
@@ -7854,10 +9380,10 @@ var attemptTerminalBodyShape = {
|
|
|
7854
9380
|
failure: lifecycleFailureSchema.optional()
|
|
7855
9381
|
};
|
|
7856
9382
|
var operationTerminalBodyShape = {
|
|
7857
|
-
type:
|
|
9383
|
+
type: z12.literal("operation.terminal"),
|
|
7858
9384
|
operationID: nonEmptyString,
|
|
7859
9385
|
taskID: nonEmptyString,
|
|
7860
|
-
outcome:
|
|
9386
|
+
outcome: z12.enum([
|
|
7861
9387
|
"succeeded",
|
|
7862
9388
|
"failed",
|
|
7863
9389
|
"cancelled",
|
|
@@ -7870,8 +9396,8 @@ var operationTerminalBodyShape = {
|
|
|
7870
9396
|
failure: lifecycleFailureSchema.optional()
|
|
7871
9397
|
};
|
|
7872
9398
|
var runTerminalBodyShape = {
|
|
7873
|
-
type:
|
|
7874
|
-
outcome:
|
|
9399
|
+
type: z12.literal("run.terminal"),
|
|
9400
|
+
outcome: z12.enum([
|
|
7875
9401
|
"succeeded",
|
|
7876
9402
|
"failed",
|
|
7877
9403
|
"cancelled",
|
|
@@ -7882,39 +9408,39 @@ var runTerminalBodyShape = {
|
|
|
7882
9408
|
failure: lifecycleFailureSchema.optional()
|
|
7883
9409
|
};
|
|
7884
9410
|
var bodySchemas = [
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
9411
|
+
z12.object(runStartedBodyShape).strict(),
|
|
9412
|
+
z12.object(operationQueuedBodyShape).strict(),
|
|
9413
|
+
z12.object(modelSelectedBodyShape).strict(),
|
|
9414
|
+
z12.object(attemptQueuedBodyShape).strict(),
|
|
9415
|
+
z12.object(attemptStartedBodyShape).strict(),
|
|
9416
|
+
z12.object(sessionCreatedBodyShape).strict(),
|
|
9417
|
+
z12.object(attemptTerminalBodyShape).strict(),
|
|
9418
|
+
z12.object(operationTerminalBodyShape).strict(),
|
|
9419
|
+
z12.object(runTerminalBodyShape).strict()
|
|
7894
9420
|
];
|
|
7895
9421
|
var appendBodySchemas = bodySchemas.slice(1);
|
|
7896
|
-
var LifecycleAppendEventSchema =
|
|
7897
|
-
var LifecycleEventSchema =
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
9422
|
+
var LifecycleAppendEventSchema = z12.discriminatedUnion("type", appendBodySchemas);
|
|
9423
|
+
var LifecycleEventSchema = z12.discriminatedUnion("type", [
|
|
9424
|
+
z12.object({ ...eventEnvelopeShape, ...runStartedBodyShape }).strict(),
|
|
9425
|
+
z12.object({ ...eventEnvelopeShape, ...operationQueuedBodyShape }).strict(),
|
|
9426
|
+
z12.object({ ...eventEnvelopeShape, ...modelSelectedBodyShape }).strict(),
|
|
9427
|
+
z12.object({ ...eventEnvelopeShape, ...attemptQueuedBodyShape }).strict(),
|
|
9428
|
+
z12.object({ ...eventEnvelopeShape, ...attemptStartedBodyShape }).strict(),
|
|
9429
|
+
z12.object({ ...eventEnvelopeShape, ...sessionCreatedBodyShape }).strict(),
|
|
9430
|
+
z12.object({ ...eventEnvelopeShape, ...attemptTerminalBodyShape }).strict(),
|
|
9431
|
+
z12.object({ ...eventEnvelopeShape, ...operationTerminalBodyShape }).strict(),
|
|
9432
|
+
z12.object({ ...eventEnvelopeShape, ...runTerminalBodyShape }).strict()
|
|
7907
9433
|
]);
|
|
7908
|
-
var LifecycleWriterLeaseInputSchema =
|
|
7909
|
-
writer:
|
|
9434
|
+
var LifecycleWriterLeaseInputSchema = z12.object({
|
|
9435
|
+
writer: z12.object({
|
|
7910
9436
|
processID: positiveInteger,
|
|
7911
9437
|
processInstanceID: nonEmptyString
|
|
7912
9438
|
}).strict(),
|
|
7913
9439
|
now: nonNegativeInteger,
|
|
7914
9440
|
leaseDurationMs: positiveInteger
|
|
7915
9441
|
}).strict();
|
|
7916
|
-
var LifecycleWriterLeaseSchema =
|
|
7917
|
-
version:
|
|
9442
|
+
var LifecycleWriterLeaseSchema = z12.object({
|
|
9443
|
+
version: z12.literal(1),
|
|
7918
9444
|
runID: nonEmptyString,
|
|
7919
9445
|
writerToken: nonEmptyString,
|
|
7920
9446
|
processID: positiveInteger,
|
|
@@ -7990,12 +9516,12 @@ var LIFECYCLE_GENESIS_DIGEST = sha256Hex("openteam/lifecycle-journal/genesis/v1"
|
|
|
7990
9516
|
var NUL2 = "\x00";
|
|
7991
9517
|
var NEWLINE = `
|
|
7992
9518
|
`;
|
|
7993
|
-
var frameSchema =
|
|
7994
|
-
v:
|
|
7995
|
-
seq:
|
|
7996
|
-
prev:
|
|
7997
|
-
sum:
|
|
7998
|
-
event:
|
|
9519
|
+
var frameSchema = z13.object({
|
|
9520
|
+
v: z13.literal(LIFECYCLE_CODEC_VERSION),
|
|
9521
|
+
seq: z13.number().int().nonnegative(),
|
|
9522
|
+
prev: z13.string().min(1),
|
|
9523
|
+
sum: z13.string().min(1),
|
|
9524
|
+
event: z13.unknown()
|
|
7999
9525
|
}).strict();
|
|
8000
9526
|
function canonical(value) {
|
|
8001
9527
|
if (Array.isArray(value)) {
|
|
@@ -8513,94 +10039,94 @@ function replay(spec, events) {
|
|
|
8513
10039
|
}
|
|
8514
10040
|
|
|
8515
10041
|
// src/graph/schema.ts
|
|
8516
|
-
import { z as
|
|
10042
|
+
import { z as z15 } from "zod";
|
|
8517
10043
|
|
|
8518
10044
|
// src/context/schema.ts
|
|
8519
|
-
import { z as
|
|
8520
|
-
var PrivacyClassSchema =
|
|
8521
|
-
var Sha256Schema =
|
|
8522
|
-
var IdentifierSchema =
|
|
8523
|
-
var TaskAnchorSchema =
|
|
10045
|
+
import { z as z14 } from "zod";
|
|
10046
|
+
var PrivacyClassSchema = z14.enum(["public", "internal", "sensitive"]);
|
|
10047
|
+
var Sha256Schema = z14.string().regex(/^[0-9a-f]{64}$/, "expected lowercase hex sha-256");
|
|
10048
|
+
var IdentifierSchema = z14.string().min(1).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/, "invalid identifier");
|
|
10049
|
+
var TaskAnchorSchema = z14.object({
|
|
8524
10050
|
taskID: IdentifierSchema,
|
|
8525
10051
|
specDigest: Sha256Schema
|
|
8526
10052
|
}).strict();
|
|
8527
|
-
var ContextRefSchema =
|
|
8528
|
-
uri:
|
|
10053
|
+
var ContextRefSchema = z14.object({
|
|
10054
|
+
uri: z14.string().min(1).max(1024),
|
|
8529
10055
|
sha256: Sha256Schema,
|
|
8530
|
-
bytes:
|
|
8531
|
-
mediaType:
|
|
10056
|
+
bytes: z14.number().int().nonnegative(),
|
|
10057
|
+
mediaType: z14.string().min(1).max(128).optional()
|
|
8532
10058
|
}).strict();
|
|
8533
|
-
var ManifestEntrySchema =
|
|
10059
|
+
var ManifestEntrySchema = z14.object({
|
|
8534
10060
|
label: IdentifierSchema,
|
|
8535
10061
|
sha256: Sha256Schema,
|
|
8536
|
-
bytes:
|
|
10062
|
+
bytes: z14.number().int().nonnegative(),
|
|
8537
10063
|
ref: ContextRefSchema.optional()
|
|
8538
10064
|
}).strict();
|
|
8539
|
-
var ArtifactManifestSchema =
|
|
8540
|
-
version:
|
|
10065
|
+
var ArtifactManifestSchema = z14.object({
|
|
10066
|
+
version: z14.literal(1),
|
|
8541
10067
|
taskID: IdentifierSchema,
|
|
8542
10068
|
privacyClass: PrivacyClassSchema,
|
|
8543
|
-
entries:
|
|
10069
|
+
entries: z14.array(ManifestEntrySchema)
|
|
8544
10070
|
}).strict();
|
|
8545
|
-
var NodeContextContractSchema =
|
|
8546
|
-
version:
|
|
8547
|
-
refs:
|
|
10071
|
+
var NodeContextContractSchema = z14.object({
|
|
10072
|
+
version: z14.literal(1),
|
|
10073
|
+
refs: z14.array(ContextRefSchema),
|
|
8548
10074
|
privacyClass: PrivacyClassSchema,
|
|
8549
|
-
maxInputTokens:
|
|
10075
|
+
maxInputTokens: z14.number().int().positive().optional()
|
|
8550
10076
|
}).strict();
|
|
8551
10077
|
|
|
8552
10078
|
// src/graph/schema.ts
|
|
8553
10079
|
var GRAPH_SPEC_VERSION = 1;
|
|
8554
10080
|
var GRAPH_EVENT_VERSION = 1;
|
|
8555
|
-
var NodeIDSchema =
|
|
8556
|
-
var NodeRoleSchema =
|
|
8557
|
-
var OperationIDSchema =
|
|
8558
|
-
var AttemptIDSchema =
|
|
8559
|
-
var ErrorClassSchema =
|
|
10081
|
+
var NodeIDSchema = z15.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "invalid node id");
|
|
10082
|
+
var NodeRoleSchema = z15.enum(["implementer", "reviewer"]);
|
|
10083
|
+
var OperationIDSchema = z15.string().regex(/^[0-9a-f]{8,64}$/, "invalid operation id");
|
|
10084
|
+
var AttemptIDSchema = z15.string().regex(/^[0-9a-f]{8,64}$/, "invalid attempt id");
|
|
10085
|
+
var ErrorClassSchema = z15.enum([
|
|
8560
10086
|
"transient",
|
|
8561
10087
|
"permanent",
|
|
8562
10088
|
"timeout",
|
|
8563
10089
|
"cancelled",
|
|
8564
10090
|
"unknown"
|
|
8565
10091
|
]);
|
|
8566
|
-
var GraphNodeSchema =
|
|
10092
|
+
var GraphNodeSchema = z15.object({
|
|
8567
10093
|
id: NodeIDSchema,
|
|
8568
10094
|
role: NodeRoleSchema,
|
|
8569
|
-
dependsOn:
|
|
10095
|
+
dependsOn: z15.array(NodeIDSchema).default([]),
|
|
8570
10096
|
anchor: TaskAnchorSchema,
|
|
8571
10097
|
reviews: NodeIDSchema.optional()
|
|
8572
10098
|
}).strict();
|
|
8573
|
-
var GraphSpecV1Schema =
|
|
8574
|
-
version:
|
|
10099
|
+
var GraphSpecV1Schema = z15.object({
|
|
10100
|
+
version: z15.literal(GRAPH_SPEC_VERSION),
|
|
8575
10101
|
runID: NodeIDSchema,
|
|
8576
|
-
nodes:
|
|
10102
|
+
nodes: z15.array(GraphNodeSchema).min(1)
|
|
8577
10103
|
}).strict();
|
|
8578
10104
|
var eventEnvelope = {
|
|
8579
|
-
v:
|
|
8580
|
-
seq:
|
|
10105
|
+
v: z15.literal(GRAPH_EVENT_VERSION),
|
|
10106
|
+
seq: z15.number().int().nonnegative(),
|
|
8581
10107
|
runID: NodeIDSchema
|
|
8582
10108
|
};
|
|
8583
|
-
var RunStartedEventSchema =
|
|
10109
|
+
var RunStartedEventSchema = z15.object({
|
|
8584
10110
|
...eventEnvelope,
|
|
8585
|
-
type:
|
|
10111
|
+
type: z15.literal("run.started"),
|
|
8586
10112
|
specDigest: Sha256Schema
|
|
8587
10113
|
}).strict();
|
|
8588
|
-
var NodeDispatchedEventSchema =
|
|
10114
|
+
var NodeDispatchedEventSchema = z15.object({
|
|
8589
10115
|
...eventEnvelope,
|
|
8590
|
-
type:
|
|
10116
|
+
type: z15.literal("node.dispatched"),
|
|
8591
10117
|
nodeID: NodeIDSchema,
|
|
8592
10118
|
operationID: OperationIDSchema,
|
|
8593
10119
|
attemptID: AttemptIDSchema
|
|
8594
10120
|
}).strict();
|
|
8595
|
-
var NodeSucceededEventSchema =
|
|
10121
|
+
var NodeSucceededEventSchema = z15.object({
|
|
8596
10122
|
...eventEnvelope,
|
|
8597
|
-
type:
|
|
10123
|
+
type: z15.literal("node.succeeded"),
|
|
8598
10124
|
nodeID: NodeIDSchema,
|
|
8599
10125
|
operationID: OperationIDSchema,
|
|
8600
10126
|
attemptID: AttemptIDSchema,
|
|
8601
10127
|
artifact: ContextRefSchema
|
|
8602
10128
|
}).strict();
|
|
8603
|
-
var NodeFailureClassSchema =
|
|
10129
|
+
var NodeFailureClassSchema = z15.enum([
|
|
8604
10130
|
"create-rejected",
|
|
8605
10131
|
"create-no-id",
|
|
8606
10132
|
"prompt-rejected",
|
|
@@ -8614,24 +10140,24 @@ var NodeFailureClassSchema = z13.enum([
|
|
|
8614
10140
|
"prompt-server",
|
|
8615
10141
|
"unknown"
|
|
8616
10142
|
]);
|
|
8617
|
-
var NodeFailedEventSchema =
|
|
10143
|
+
var NodeFailedEventSchema = z15.object({
|
|
8618
10144
|
...eventEnvelope,
|
|
8619
|
-
type:
|
|
10145
|
+
type: z15.literal("node.failed"),
|
|
8620
10146
|
nodeID: NodeIDSchema,
|
|
8621
10147
|
operationID: OperationIDSchema,
|
|
8622
10148
|
attemptID: AttemptIDSchema,
|
|
8623
10149
|
errorClass: ErrorClassSchema,
|
|
8624
10150
|
failureClass: NodeFailureClassSchema.optional()
|
|
8625
10151
|
}).strict();
|
|
8626
|
-
var NodeCancelledEventSchema =
|
|
10152
|
+
var NodeCancelledEventSchema = z15.object({
|
|
8627
10153
|
...eventEnvelope,
|
|
8628
|
-
type:
|
|
10154
|
+
type: z15.literal("node.cancelled"),
|
|
8629
10155
|
nodeID: NodeIDSchema
|
|
8630
10156
|
}).strict();
|
|
8631
|
-
var RunCompletedEventSchema =
|
|
8632
|
-
var RunFailedEventSchema =
|
|
8633
|
-
var RunCancelledEventSchema =
|
|
8634
|
-
var GraphEventV1Schema =
|
|
10157
|
+
var RunCompletedEventSchema = z15.object({ ...eventEnvelope, type: z15.literal("run.completed") }).strict();
|
|
10158
|
+
var RunFailedEventSchema = z15.object({ ...eventEnvelope, type: z15.literal("run.failed") }).strict();
|
|
10159
|
+
var RunCancelledEventSchema = z15.object({ ...eventEnvelope, type: z15.literal("run.cancelled") }).strict();
|
|
10160
|
+
var GraphEventV1Schema = z15.discriminatedUnion("type", [
|
|
8635
10161
|
RunStartedEventSchema,
|
|
8636
10162
|
NodeDispatchedEventSchema,
|
|
8637
10163
|
NodeSucceededEventSchema,
|
|
@@ -8781,7 +10307,7 @@ import {
|
|
|
8781
10307
|
realpathSync,
|
|
8782
10308
|
writeSync
|
|
8783
10309
|
} from "node:fs";
|
|
8784
|
-
import { basename, dirname as dirname2, join as join3, parse, resolve } from "node:path";
|
|
10310
|
+
import { basename, dirname as dirname2, join as join3, parse as parse2, resolve as resolve2 } from "node:path";
|
|
8785
10311
|
function ensureDir(dir) {
|
|
8786
10312
|
mkdirSync(dir, { recursive: true });
|
|
8787
10313
|
}
|
|
@@ -8820,8 +10346,8 @@ function tryRealPath(path) {
|
|
|
8820
10346
|
}
|
|
8821
10347
|
}
|
|
8822
10348
|
function realPathDeep(target) {
|
|
8823
|
-
const absolute =
|
|
8824
|
-
const root =
|
|
10349
|
+
const absolute = resolve2(target);
|
|
10350
|
+
const root = parse2(absolute).root;
|
|
8825
10351
|
let current = absolute;
|
|
8826
10352
|
let suffix = "";
|
|
8827
10353
|
while (current !== root) {
|
|
@@ -9279,6 +10805,13 @@ async function runConsoleServe(deps, options) {
|
|
|
9279
10805
|
terminalEnabled,
|
|
9280
10806
|
ptyEnabled,
|
|
9281
10807
|
createClient: makeClient,
|
|
10808
|
+
drilldownEnabled: graphViewEnabled,
|
|
10809
|
+
conversationContentEnabled: config.console.sessionHistory?.contentEnabled === true,
|
|
10810
|
+
...config.console.sessionHistory?.endpoint !== undefined ? { historyEndpoint: config.console.sessionHistory.endpoint } : {},
|
|
10811
|
+
readConversation: createConversationReader({
|
|
10812
|
+
directory: deps.directory ?? process.cwd(),
|
|
10813
|
+
...deps.serverPassword !== undefined ? { password: deps.serverPassword } : {}
|
|
10814
|
+
}),
|
|
9282
10815
|
createPtyClient: makePtyClient
|
|
9283
10816
|
},
|
|
9284
10817
|
...graphViewProvider !== undefined ? { graphView: graphViewProvider } : {},
|
|
@@ -9407,13 +10940,13 @@ async function invokeStateGraph(definition, input, deps) {
|
|
|
9407
10940
|
}
|
|
9408
10941
|
|
|
9409
10942
|
// src/graph/langgraph/checkpointer.ts
|
|
9410
|
-
import { z as
|
|
10943
|
+
import { z as z16 } from "zod";
|
|
9411
10944
|
var EPHEMERAL_CHECKPOINT_DIR = ".opencode/openteam-local/langgraph-checkpoints";
|
|
9412
10945
|
var COMMITTED_CHECKPOINT_DIR = ".opencode/openteam/graph/checkpoints";
|
|
9413
|
-
var PersistedCheckpointSchema =
|
|
9414
|
-
runID:
|
|
9415
|
-
nodeID:
|
|
9416
|
-
route:
|
|
10946
|
+
var PersistedCheckpointSchema = z16.object({
|
|
10947
|
+
runID: z16.string().min(1),
|
|
10948
|
+
nodeID: z16.string().min(1),
|
|
10949
|
+
route: z16.enum(["local", "frontier"]),
|
|
9417
10950
|
stateHash: Sha256Schema
|
|
9418
10951
|
}).strict();
|
|
9419
10952
|
function createReferenceOnlySaver(location = COMMITTED_CHECKPOINT_DIR) {
|
|
@@ -9544,13 +11077,13 @@ function runCancelled(runID, seq) {
|
|
|
9544
11077
|
|
|
9545
11078
|
// src/storage/graph/workspaceLease.ts
|
|
9546
11079
|
import { join as join7 } from "node:path";
|
|
9547
|
-
import { z as
|
|
11080
|
+
import { z as z18 } from "zod";
|
|
9548
11081
|
|
|
9549
11082
|
// src/storage/graph/runRegistry.ts
|
|
9550
11083
|
import { join as join6 } from "node:path";
|
|
9551
|
-
import { z as
|
|
11084
|
+
import { z as z17 } from "zod";
|
|
9552
11085
|
var REGISTRY_FILE = "active-runs.json";
|
|
9553
|
-
var registrySchema =
|
|
11086
|
+
var registrySchema = z17.object({ runs: z17.array(z17.string().min(1)) }).strict();
|
|
9554
11087
|
|
|
9555
11088
|
class RunRegistryError extends Error {
|
|
9556
11089
|
code = "corrupt";
|
|
@@ -9606,11 +11139,11 @@ function createRunRegistry(root) {
|
|
|
9606
11139
|
|
|
9607
11140
|
// src/storage/graph/workspaceLease.ts
|
|
9608
11141
|
var NUL5 = "\x00";
|
|
9609
|
-
var leaseRecordSchema =
|
|
9610
|
-
runID:
|
|
9611
|
-
holder:
|
|
9612
|
-
token:
|
|
9613
|
-
released:
|
|
11142
|
+
var leaseRecordSchema = z18.object({
|
|
11143
|
+
runID: z18.string().min(1),
|
|
11144
|
+
holder: z18.string().min(1),
|
|
11145
|
+
token: z18.string().length(32),
|
|
11146
|
+
released: z18.boolean()
|
|
9614
11147
|
}).strict();
|
|
9615
11148
|
|
|
9616
11149
|
class LeaseError extends Error {
|
|
@@ -9626,7 +11159,7 @@ class LeaseError extends Error {
|
|
|
9626
11159
|
function createWorkspaceLease(root, registry = createRunRegistry(root)) {
|
|
9627
11160
|
const leasePath = (runID) => join7(root, `lease-${runID}.json`);
|
|
9628
11161
|
const deriveToken = (runID, holder) => sha256Hex(`lease${NUL5}${runID}${NUL5}${holder}`).slice(0, 32);
|
|
9629
|
-
const
|
|
11162
|
+
const parse3 = (text) => {
|
|
9630
11163
|
let raw;
|
|
9631
11164
|
try {
|
|
9632
11165
|
raw = JSON.parse(text);
|
|
@@ -9641,7 +11174,7 @@ function createWorkspaceLease(root, registry = createRunRegistry(root)) {
|
|
|
9641
11174
|
};
|
|
9642
11175
|
const readRecord = (runID) => {
|
|
9643
11176
|
const text = readText(leasePath(runID));
|
|
9644
|
-
return text === undefined ? undefined :
|
|
11177
|
+
return text === undefined ? undefined : parse3(text);
|
|
9645
11178
|
};
|
|
9646
11179
|
const grant = async (runID, holder, token) => {
|
|
9647
11180
|
const record2 = { runID, holder, token, released: false };
|
|
@@ -9704,7 +11237,7 @@ function planCancellation(state) {
|
|
|
9704
11237
|
}
|
|
9705
11238
|
|
|
9706
11239
|
// src/orchestrator/graphReview.ts
|
|
9707
|
-
import { z as
|
|
11240
|
+
import { z as z19 } from "zod";
|
|
9708
11241
|
|
|
9709
11242
|
// src/graph/policies.ts
|
|
9710
11243
|
var DEFAULT_RETRY_LIMIT = 3;
|
|
@@ -9727,11 +11260,11 @@ function retryAllowed(errorClass, attempts, limit = DEFAULT_RETRY_LIMIT) {
|
|
|
9727
11260
|
}
|
|
9728
11261
|
|
|
9729
11262
|
// src/orchestrator/graphReview.ts
|
|
9730
|
-
var ReviewInputSchema =
|
|
9731
|
-
decision:
|
|
11263
|
+
var ReviewInputSchema = z19.object({
|
|
11264
|
+
decision: z19.enum(["approve", "reject"]),
|
|
9732
11265
|
anchor: TaskAnchorSchema.optional(),
|
|
9733
11266
|
artifactSha256: Sha256Schema.optional(),
|
|
9734
|
-
reason:
|
|
11267
|
+
reason: z19.string().min(1).max(500).optional()
|
|
9735
11268
|
}).strict();
|
|
9736
11269
|
function planRevision(input) {
|
|
9737
11270
|
const limit = input.limit ?? DEFAULT_REVISION_LIMIT;
|
|
@@ -11079,15 +12612,15 @@ function createGraphOperator(options) {
|
|
|
11079
12612
|
}
|
|
11080
12613
|
|
|
11081
12614
|
// src/cli/graphStatusSnapshot.ts
|
|
11082
|
-
import { z as
|
|
11083
|
-
var activeRunRegistrySchema =
|
|
11084
|
-
runs:
|
|
12615
|
+
import { z as z20 } from "zod";
|
|
12616
|
+
var activeRunRegistrySchema = z20.object({
|
|
12617
|
+
runs: z20.array(z20.string().min(1))
|
|
11085
12618
|
}).strict();
|
|
11086
|
-
var leaseRecordSchema2 =
|
|
11087
|
-
runID:
|
|
11088
|
-
holder:
|
|
11089
|
-
token:
|
|
11090
|
-
released:
|
|
12619
|
+
var leaseRecordSchema2 = z20.object({
|
|
12620
|
+
runID: z20.string().min(1),
|
|
12621
|
+
holder: z20.string().min(1),
|
|
12622
|
+
token: z20.string().length(32),
|
|
12623
|
+
released: z20.boolean()
|
|
11091
12624
|
}).strict();
|
|
11092
12625
|
|
|
11093
12626
|
class BoundaryJsonError extends Error {
|
|
@@ -11768,7 +13301,7 @@ import {
|
|
|
11768
13301
|
statSync as statSync2,
|
|
11769
13302
|
unlinkSync as unlinkSync2
|
|
11770
13303
|
} from "node:fs";
|
|
11771
|
-
import { join as join11, resolve as
|
|
13304
|
+
import { join as join11, resolve as resolve4 } from "node:path";
|
|
11772
13305
|
import { ZodError } from "zod";
|
|
11773
13306
|
|
|
11774
13307
|
// src/storage/lifecycle/fsLifecycleSupport.ts
|
|
@@ -11789,7 +13322,7 @@ import {
|
|
|
11789
13322
|
unlinkSync,
|
|
11790
13323
|
writeSync as writeSync2
|
|
11791
13324
|
} from "node:fs";
|
|
11792
|
-
import { basename as basename2, dirname as dirname3, join as join10, relative, resolve as
|
|
13325
|
+
import { basename as basename2, dirname as dirname3, join as join10, relative, resolve as resolve3 } from "node:path";
|
|
11793
13326
|
var SAFE_RUN_ID = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?$/u;
|
|
11794
13327
|
|
|
11795
13328
|
class LifecycleFsError extends Error {
|
|
@@ -11813,7 +13346,7 @@ function validateRunID(runID) {
|
|
|
11813
13346
|
}
|
|
11814
13347
|
function resolvedLifecycleRoot(root) {
|
|
11815
13348
|
try {
|
|
11816
|
-
const absolute =
|
|
13349
|
+
const absolute = resolve3(root);
|
|
11817
13350
|
mkdirSync2(absolute, { recursive: true });
|
|
11818
13351
|
const rootStat = lstatSync(absolute);
|
|
11819
13352
|
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {
|
|
@@ -11856,7 +13389,7 @@ function assertExistingSafeRun(root, runID) {
|
|
|
11856
13389
|
throw new LifecycleFsError("unavailable");
|
|
11857
13390
|
}
|
|
11858
13391
|
const child = relative(root, real);
|
|
11859
|
-
if (child === "" || child.startsWith("..") ||
|
|
13392
|
+
if (child === "" || child.startsWith("..") || resolve3(root, child) !== real || dirname3(real) !== root) {
|
|
11860
13393
|
throw new LifecycleFsError("corrupt");
|
|
11861
13394
|
}
|
|
11862
13395
|
return real;
|
|
@@ -11989,9 +13522,9 @@ function mapFsFailure(error, runID) {
|
|
|
11989
13522
|
}
|
|
11990
13523
|
return failure("unavailable", { recoverable: true, ...context });
|
|
11991
13524
|
}
|
|
11992
|
-
function parseJson(text,
|
|
13525
|
+
function parseJson(text, parse3) {
|
|
11993
13526
|
try {
|
|
11994
|
-
return
|
|
13527
|
+
return parse3(JSON.parse(text));
|
|
11995
13528
|
} catch {
|
|
11996
13529
|
throw new LifecycleFsError("corrupt");
|
|
11997
13530
|
}
|
|
@@ -12096,7 +13629,7 @@ function canDeleteTerminalRun(runDir, runID, now) {
|
|
|
12096
13629
|
return now >= lease.expiresAt;
|
|
12097
13630
|
}
|
|
12098
13631
|
var createFsLifecycleJournal = (options) => {
|
|
12099
|
-
const configuredRoot =
|
|
13632
|
+
const configuredRoot = resolve4(options.root);
|
|
12100
13633
|
const now = options.now ?? Date.now;
|
|
12101
13634
|
const mutateRun = options.withMutationLock ?? withRunMutationLock;
|
|
12102
13635
|
return {
|
|
@@ -12619,9 +14152,9 @@ var createLifecycleHistoryProvider = (options, legacyFs = legacyReadFs) => {
|
|
|
12619
14152
|
|
|
12620
14153
|
// src/cli/migrateAdapter.ts
|
|
12621
14154
|
import * as fs from "node:fs";
|
|
12622
|
-
import { dirname as dirname4, join as join14, resolve as
|
|
14155
|
+
import { dirname as dirname4, join as join14, resolve as resolve5 } from "node:path";
|
|
12623
14156
|
function createMigrateAdapter(root) {
|
|
12624
|
-
const rootAbs =
|
|
14157
|
+
const rootAbs = resolve5(root);
|
|
12625
14158
|
const toDisk = (relPath) => join14(rootAbs, ...splitVirtualPath(relPath));
|
|
12626
14159
|
return {
|
|
12627
14160
|
async exists(relPath) {
|
|
@@ -12715,7 +14248,7 @@ async function resolveOpencodeVersionBestEffort(deps) {
|
|
|
12715
14248
|
// src/cli/purgeAdapter.ts
|
|
12716
14249
|
import { execFile } from "node:child_process";
|
|
12717
14250
|
import * as fs2 from "node:fs";
|
|
12718
|
-
import { dirname as dirname5, join as join15, resolve as
|
|
14251
|
+
import { dirname as dirname5, join as join15, resolve as resolve6 } from "node:path";
|
|
12719
14252
|
import { promisify } from "node:util";
|
|
12720
14253
|
|
|
12721
14254
|
// src/opencodeArtifacts/orchestratorAgent.ts
|
|
@@ -13125,7 +14658,7 @@ var REFUSAL_MARKERS = [
|
|
|
13125
14658
|
"cannot remove a locked"
|
|
13126
14659
|
];
|
|
13127
14660
|
function createPurgeAdapter(root) {
|
|
13128
|
-
const repoRootAbs =
|
|
14661
|
+
const repoRootAbs = resolve6(root);
|
|
13129
14662
|
const worktreesDir = join15(repoRootAbs, ...DEFAULT_GRAPH_WORKTREES_DIR.split("/"));
|
|
13130
14663
|
const agentDirAbs = join15(repoRootAbs, ...AGENT_DIR_POSIX.split("/"));
|
|
13131
14664
|
const exec = nodeExec();
|
|
@@ -13134,7 +14667,7 @@ function createPurgeAdapter(root) {
|
|
|
13134
14667
|
repoRoot: repoRootAbs,
|
|
13135
14668
|
worktreesDir
|
|
13136
14669
|
});
|
|
13137
|
-
const toDisk = (relPath) =>
|
|
14670
|
+
const toDisk = (relPath) => resolve6(repoRootAbs, relPath);
|
|
13138
14671
|
const runGit2 = async (rest) => exec("git", ["-C", repoRootAbs, ...GIT_TOP_FLAGS2, ...rest]);
|
|
13139
14672
|
return {
|
|
13140
14673
|
repoRoot() {
|
|
@@ -14334,11 +15867,11 @@ function planWorktreeReconciliation(input) {
|
|
|
14334
15867
|
}
|
|
14335
15868
|
|
|
14336
15869
|
// src/telemetry/otelConfig.ts
|
|
14337
|
-
import { z as
|
|
14338
|
-
var OtelBackendConfigSchema =
|
|
14339
|
-
backend:
|
|
14340
|
-
connectionEnv:
|
|
14341
|
-
serviceName:
|
|
15870
|
+
import { z as z21 } from "zod";
|
|
15871
|
+
var OtelBackendConfigSchema = z21.object({
|
|
15872
|
+
backend: z21.literal("opentelemetry"),
|
|
15873
|
+
connectionEnv: z21.string().min(1),
|
|
15874
|
+
serviceName: z21.string().min(1).optional()
|
|
14342
15875
|
}).strict();
|
|
14343
15876
|
function parseConnectionString(raw) {
|
|
14344
15877
|
const pairs = new Map;
|
|
@@ -15317,31 +16850,31 @@ function mergeOpencodeConfigs(base, override) {
|
|
|
15317
16850
|
}
|
|
15318
16851
|
|
|
15319
16852
|
// src/graph/soakLedger.ts
|
|
15320
|
-
import { z as
|
|
15321
|
-
var Sha256Schema2 =
|
|
15322
|
-
var SoakPlatformSchema =
|
|
15323
|
-
var PrivacyPairSchema =
|
|
15324
|
-
surfacesScanned:
|
|
15325
|
-
rawFindings:
|
|
16853
|
+
import { z as z22 } from "zod";
|
|
16854
|
+
var Sha256Schema2 = z22.string().regex(/^[0-9a-f]{64}$/);
|
|
16855
|
+
var SoakPlatformSchema = z22.enum(["linux", "win32", "darwin"]);
|
|
16856
|
+
var PrivacyPairSchema = z22.object({
|
|
16857
|
+
surfacesScanned: z22.number().int().nonnegative(),
|
|
16858
|
+
rawFindings: z22.number().int().nonnegative()
|
|
15326
16859
|
}).strict();
|
|
15327
|
-
var DuplicateEffectPairSchema =
|
|
15328
|
-
effectsExamined:
|
|
15329
|
-
duplicatesFound:
|
|
16860
|
+
var DuplicateEffectPairSchema = z22.object({
|
|
16861
|
+
effectsExamined: z22.number().int().nonnegative(),
|
|
16862
|
+
duplicatesFound: z22.number().int().nonnegative()
|
|
15330
16863
|
}).strict();
|
|
15331
|
-
var ModelVerificationPairSchema =
|
|
15332
|
-
nodesChecked:
|
|
15333
|
-
unverified:
|
|
15334
|
-
mismatched:
|
|
16864
|
+
var ModelVerificationPairSchema = z22.object({
|
|
16865
|
+
nodesChecked: z22.number().int().nonnegative(),
|
|
16866
|
+
unverified: z22.number().int().nonnegative(),
|
|
16867
|
+
mismatched: z22.number().int().nonnegative()
|
|
15335
16868
|
}).strict();
|
|
15336
|
-
var SoakObservationSchema =
|
|
15337
|
-
version:
|
|
15338
|
-
seq:
|
|
15339
|
-
timestamp:
|
|
16869
|
+
var SoakObservationSchema = z22.object({
|
|
16870
|
+
version: z22.literal(1),
|
|
16871
|
+
seq: z22.number().int().nonnegative(),
|
|
16872
|
+
timestamp: z22.string().datetime(),
|
|
15340
16873
|
platform: SoakPlatformSchema,
|
|
15341
|
-
opencodeVersion:
|
|
15342
|
-
provenance:
|
|
16874
|
+
opencodeVersion: z22.string().min(1),
|
|
16875
|
+
provenance: z22.enum(["genuine-usage", "ci-synthetic"]),
|
|
15343
16876
|
traceDigest: Sha256Schema2,
|
|
15344
|
-
criticalDivergences:
|
|
16877
|
+
criticalDivergences: z22.number().int().nonnegative().nullable(),
|
|
15345
16878
|
privacy: PrivacyPairSchema.nullable(),
|
|
15346
16879
|
duplicateEffects: DuplicateEffectPairSchema.nullable(),
|
|
15347
16880
|
modelVerification: ModelVerificationPairSchema.nullable(),
|
|
@@ -17762,14 +19295,14 @@ ${HELP}`
|
|
|
17762
19295
|
}
|
|
17763
19296
|
|
|
17764
19297
|
// src/orchestrator/roster.ts
|
|
17765
|
-
import { z as
|
|
17766
|
-
var RosterEntrySchema =
|
|
17767
|
-
roleID:
|
|
17768
|
-
agentName:
|
|
19298
|
+
import { z as z23 } from "zod";
|
|
19299
|
+
var RosterEntrySchema = z23.object({
|
|
19300
|
+
roleID: z23.string().min(1),
|
|
19301
|
+
agentName: z23.string().min(1)
|
|
17769
19302
|
}).strict();
|
|
17770
|
-
var RosterSchema =
|
|
17771
|
-
universe:
|
|
17772
|
-
entries:
|
|
19303
|
+
var RosterSchema = z23.object({
|
|
19304
|
+
universe: z23.string().min(1),
|
|
19305
|
+
entries: z23.array(RosterEntrySchema)
|
|
17773
19306
|
}).strict();
|
|
17774
19307
|
var ROSTER_JSON_FENCE = /```json\s*([\s\S]*?)```/;
|
|
17775
19308
|
|
|
@@ -18323,7 +19856,7 @@ import { readFile as readFile2 } from "node:fs/promises";
|
|
|
18323
19856
|
import { basename as basename3, dirname as dirname6 } from "node:path";
|
|
18324
19857
|
|
|
18325
19858
|
// src/graph/certificate.ts
|
|
18326
|
-
import { z as
|
|
19859
|
+
import { z as z24 } from "zod";
|
|
18327
19860
|
|
|
18328
19861
|
// src/contract/opencode.ts
|
|
18329
19862
|
var SUPPORTED_OPENCODE_VERSIONS = [
|
|
@@ -18364,7 +19897,7 @@ function isCertificateVersionCompatible(certifiedVersion, liveVersion) {
|
|
|
18364
19897
|
|
|
18365
19898
|
// src/graph/certificate.ts
|
|
18366
19899
|
var SHADOW_CERTIFICATE_MIN_RUNS = 1000;
|
|
18367
|
-
var DivergenceCodeSchema =
|
|
19900
|
+
var DivergenceCodeSchema = z24.enum([
|
|
18368
19901
|
"status",
|
|
18369
19902
|
"order",
|
|
18370
19903
|
"roles",
|
|
@@ -18372,50 +19905,50 @@ var DivergenceCodeSchema = z22.enum([
|
|
|
18372
19905
|
"fixes",
|
|
18373
19906
|
"outcome"
|
|
18374
19907
|
]);
|
|
18375
|
-
var ProvenanceSchema =
|
|
19908
|
+
var ProvenanceSchema = z24.enum([
|
|
18376
19909
|
"recomputed",
|
|
18377
19910
|
"compiled",
|
|
18378
19911
|
"validated",
|
|
18379
19912
|
"carried"
|
|
18380
19913
|
]);
|
|
18381
|
-
var EvidenceSchema =
|
|
18382
|
-
opencodeVersion:
|
|
18383
|
-
parity:
|
|
18384
|
-
runs:
|
|
18385
|
-
match:
|
|
18386
|
-
divergent:
|
|
18387
|
-
inconclusive:
|
|
18388
|
-
divergences:
|
|
19914
|
+
var EvidenceSchema = z24.object({
|
|
19915
|
+
opencodeVersion: z24.string().min(1),
|
|
19916
|
+
parity: z24.object({
|
|
19917
|
+
runs: z24.number().int().nonnegative(),
|
|
19918
|
+
match: z24.number().int().nonnegative(),
|
|
19919
|
+
divergent: z24.number().int().nonnegative(),
|
|
19920
|
+
inconclusive: z24.number().int().nonnegative(),
|
|
19921
|
+
divergences: z24.array(DivergenceCodeSchema)
|
|
18389
19922
|
}).strict(),
|
|
18390
|
-
legacy:
|
|
18391
|
-
observed:
|
|
18392
|
-
duplicated:
|
|
19923
|
+
legacy: z24.object({
|
|
19924
|
+
observed: z24.number().int().nonnegative(),
|
|
19925
|
+
duplicated: z24.number().int().nonnegative()
|
|
18393
19926
|
}).strict(),
|
|
18394
|
-
privacy:
|
|
18395
|
-
surfacesScanned:
|
|
18396
|
-
rawFindings:
|
|
19927
|
+
privacy: z24.object({
|
|
19928
|
+
surfacesScanned: z24.number().int().nonnegative(),
|
|
19929
|
+
rawFindings: z24.number().int().nonnegative()
|
|
18397
19930
|
}).strict(),
|
|
18398
|
-
overhead:
|
|
18399
|
-
p95Millis:
|
|
18400
|
-
budgetMillis:
|
|
18401
|
-
samples:
|
|
19931
|
+
overhead: z24.object({
|
|
19932
|
+
p95Millis: z24.number().nonnegative(),
|
|
19933
|
+
budgetMillis: z24.number().positive(),
|
|
19934
|
+
samples: z24.number().int().nonnegative()
|
|
18402
19935
|
}).strict(),
|
|
18403
|
-
provenance:
|
|
19936
|
+
provenance: z24.record(DivergenceCodeSchema, ProvenanceSchema)
|
|
18404
19937
|
}).strict();
|
|
18405
|
-
var CertificateSchema =
|
|
18406
|
-
version:
|
|
18407
|
-
certificate:
|
|
18408
|
-
opencodeVersion:
|
|
19938
|
+
var CertificateSchema = z24.object({
|
|
19939
|
+
version: z24.literal(1),
|
|
19940
|
+
certificate: z24.literal("graph-shadow"),
|
|
19941
|
+
opencodeVersion: z24.string().min(1),
|
|
18409
19942
|
evidence: EvidenceSchema,
|
|
18410
|
-
verdict:
|
|
18411
|
-
failedGates:
|
|
19943
|
+
verdict: z24.enum(["pass", "fail"]),
|
|
19944
|
+
failedGates: z24.array(z24.enum([
|
|
18412
19945
|
"sample",
|
|
18413
19946
|
"parity",
|
|
18414
19947
|
"one-legacy-execution",
|
|
18415
19948
|
"privacy",
|
|
18416
19949
|
"overhead"
|
|
18417
19950
|
])),
|
|
18418
|
-
digest:
|
|
19951
|
+
digest: z24.string().regex(/^[0-9a-f]{64}$/)
|
|
18419
19952
|
}).strict();
|
|
18420
19953
|
|
|
18421
19954
|
class ShadowCertificateError extends Error {
|
|
@@ -18530,37 +20063,37 @@ function parseShadowCertificate(value, opencodeVersion) {
|
|
|
18530
20063
|
}
|
|
18531
20064
|
return certificate;
|
|
18532
20065
|
}
|
|
18533
|
-
var ReleaseDeterminismSchema =
|
|
18534
|
-
var ReleaseCrashRecoverySchema =
|
|
18535
|
-
scenarios:
|
|
18536
|
-
allConverge:
|
|
20066
|
+
var ReleaseDeterminismSchema = z24.object({ runs: z24.number().int().nonnegative(), allMatch: z24.boolean() }).strict();
|
|
20067
|
+
var ReleaseCrashRecoverySchema = z24.object({
|
|
20068
|
+
scenarios: z24.number().int().nonnegative(),
|
|
20069
|
+
allConverge: z24.boolean()
|
|
18537
20070
|
}).strict();
|
|
18538
|
-
var ReleaseReplayEquivalenceSchema =
|
|
18539
|
-
checks:
|
|
18540
|
-
allEquivalent:
|
|
20071
|
+
var ReleaseReplayEquivalenceSchema = z24.object({
|
|
20072
|
+
checks: z24.number().int().nonnegative(),
|
|
20073
|
+
allEquivalent: z24.boolean()
|
|
18541
20074
|
}).strict();
|
|
18542
|
-
var ReleasePrivacySchema =
|
|
18543
|
-
surfacesScanned:
|
|
18544
|
-
rawFindings:
|
|
20075
|
+
var ReleasePrivacySchema = z24.object({
|
|
20076
|
+
surfacesScanned: z24.number().int().nonnegative(),
|
|
20077
|
+
rawFindings: z24.number().int().nonnegative()
|
|
18545
20078
|
}).strict();
|
|
18546
|
-
var ReleaseContractSchema =
|
|
18547
|
-
roundTrips:
|
|
18548
|
-
allSettled:
|
|
20079
|
+
var ReleaseContractSchema = z24.object({
|
|
20080
|
+
roundTrips: z24.number().int().nonnegative(),
|
|
20081
|
+
allSettled: z24.boolean()
|
|
18549
20082
|
}).strict();
|
|
18550
|
-
var ReleaseHealthSchema =
|
|
18551
|
-
samples:
|
|
18552
|
-
bounded:
|
|
18553
|
-
idempotent:
|
|
20083
|
+
var ReleaseHealthSchema = z24.object({
|
|
20084
|
+
samples: z24.number().int().nonnegative(),
|
|
20085
|
+
bounded: z24.boolean(),
|
|
20086
|
+
idempotent: z24.boolean()
|
|
18554
20087
|
}).strict();
|
|
18555
|
-
var ReleasePerformanceSchema =
|
|
18556
|
-
p95Millis:
|
|
18557
|
-
budgetMillis:
|
|
18558
|
-
samples:
|
|
20088
|
+
var ReleasePerformanceSchema = z24.object({
|
|
20089
|
+
p95Millis: z24.number().nonnegative(),
|
|
20090
|
+
budgetMillis: z24.number().positive(),
|
|
20091
|
+
samples: z24.number().int().nonnegative()
|
|
18559
20092
|
}).strict();
|
|
18560
|
-
var ReleaseEvidenceSchema =
|
|
18561
|
-
opencodeVersion:
|
|
18562
|
-
platform:
|
|
18563
|
-
shadowCertificateDigest:
|
|
20093
|
+
var ReleaseEvidenceSchema = z24.object({
|
|
20094
|
+
opencodeVersion: z24.string().min(1),
|
|
20095
|
+
platform: z24.enum(["linux", "win32"]),
|
|
20096
|
+
shadowCertificateDigest: z24.string().regex(/^[0-9a-f]{64}$/),
|
|
18564
20097
|
determinism: ReleaseDeterminismSchema,
|
|
18565
20098
|
crashRecovery: ReleaseCrashRecoverySchema,
|
|
18566
20099
|
replayEquivalence: ReleaseReplayEquivalenceSchema,
|
|
@@ -18569,15 +20102,15 @@ var ReleaseEvidenceSchema = z22.object({
|
|
|
18569
20102
|
health: ReleaseHealthSchema,
|
|
18570
20103
|
performance: ReleasePerformanceSchema
|
|
18571
20104
|
}).strict();
|
|
18572
|
-
var ReleaseCertificateSchema =
|
|
18573
|
-
version:
|
|
18574
|
-
certificate:
|
|
18575
|
-
platform:
|
|
18576
|
-
opencodeVersion:
|
|
18577
|
-
shadowCertificateDigest:
|
|
20105
|
+
var ReleaseCertificateSchema = z24.object({
|
|
20106
|
+
version: z24.literal(2),
|
|
20107
|
+
certificate: z24.literal("graph-release"),
|
|
20108
|
+
platform: z24.enum(["linux", "win32"]),
|
|
20109
|
+
opencodeVersion: z24.string().min(1),
|
|
20110
|
+
shadowCertificateDigest: z24.string().regex(/^[0-9a-f]{64}$/),
|
|
18578
20111
|
evidence: ReleaseEvidenceSchema,
|
|
18579
|
-
verdict:
|
|
18580
|
-
failedGates:
|
|
20112
|
+
verdict: z24.enum(["pass", "fail"]),
|
|
20113
|
+
failedGates: z24.array(z24.enum([
|
|
18581
20114
|
"shadow-valid",
|
|
18582
20115
|
"determinism",
|
|
18583
20116
|
"crash-recovery",
|
|
@@ -18587,7 +20120,7 @@ var ReleaseCertificateSchema = z22.object({
|
|
|
18587
20120
|
"health",
|
|
18588
20121
|
"performance"
|
|
18589
20122
|
])),
|
|
18590
|
-
digest:
|
|
20123
|
+
digest: z24.string().regex(/^[0-9a-f]{64}$/)
|
|
18591
20124
|
}).strict();
|
|
18592
20125
|
|
|
18593
20126
|
class ReleaseCertificateError extends Error {
|
|
@@ -18715,7 +20248,7 @@ function parseReleaseCertificate(value, opencodeVersion, expectedShadowDigest) {
|
|
|
18715
20248
|
}
|
|
18716
20249
|
return certificate;
|
|
18717
20250
|
}
|
|
18718
|
-
var ShadowDivergenceCodeSchema =
|
|
20251
|
+
var ShadowDivergenceCodeSchema = z24.enum([
|
|
18719
20252
|
"status",
|
|
18720
20253
|
"order",
|
|
18721
20254
|
"roles",
|
|
@@ -18724,13 +20257,13 @@ var ShadowDivergenceCodeSchema = z22.enum([
|
|
|
18724
20257
|
"outcome"
|
|
18725
20258
|
]);
|
|
18726
20259
|
var RECOMPUTED_DIVERGENCE_CODES = ["fixes"];
|
|
18727
|
-
var RecomputedDivergenceCodeSchema =
|
|
18728
|
-
var SoakPolicySchema =
|
|
18729
|
-
minimumGenuineObservations:
|
|
18730
|
-
minimumDistinctDays:
|
|
18731
|
-
requireGenuineUsageOnAllPlatforms:
|
|
18732
|
-
supportedOpencodeVersions:
|
|
18733
|
-
criticalDivergenceCodes:
|
|
20260
|
+
var RecomputedDivergenceCodeSchema = z24.enum(RECOMPUTED_DIVERGENCE_CODES);
|
|
20261
|
+
var SoakPolicySchema = z24.object({
|
|
20262
|
+
minimumGenuineObservations: z24.number().int().positive(),
|
|
20263
|
+
minimumDistinctDays: z24.number().int().positive(),
|
|
20264
|
+
requireGenuineUsageOnAllPlatforms: z24.boolean(),
|
|
20265
|
+
supportedOpencodeVersions: z24.array(z24.string().min(1)).min(1),
|
|
20266
|
+
criticalDivergenceCodes: z24.array(RecomputedDivergenceCodeSchema).min(1)
|
|
18734
20267
|
}).strict();
|
|
18735
20268
|
var DEFAULT_SOAK_POLICY = {
|
|
18736
20269
|
minimumGenuineObservations: 100,
|
|
@@ -18739,46 +20272,46 @@ var DEFAULT_SOAK_POLICY = {
|
|
|
18739
20272
|
supportedOpencodeVersions: [...SUPPORTED_OPENCODE_VERSIONS],
|
|
18740
20273
|
criticalDivergenceCodes: ["fixes"]
|
|
18741
20274
|
};
|
|
18742
|
-
var SoakPlatformEnumSchema =
|
|
18743
|
-
var SoakPrivacyPairEvidenceSchema =
|
|
18744
|
-
surfacesScanned:
|
|
18745
|
-
rawFindings:
|
|
20275
|
+
var SoakPlatformEnumSchema = z24.enum(["linux", "win32", "darwin"]);
|
|
20276
|
+
var SoakPrivacyPairEvidenceSchema = z24.object({
|
|
20277
|
+
surfacesScanned: z24.number().int().nonnegative(),
|
|
20278
|
+
rawFindings: z24.number().int().nonnegative()
|
|
18746
20279
|
}).strict();
|
|
18747
|
-
var SoakDuplicateEffectPairEvidenceSchema =
|
|
18748
|
-
effectsExamined:
|
|
18749
|
-
duplicatesFound:
|
|
20280
|
+
var SoakDuplicateEffectPairEvidenceSchema = z24.object({
|
|
20281
|
+
effectsExamined: z24.number().int().nonnegative(),
|
|
20282
|
+
duplicatesFound: z24.number().int().nonnegative()
|
|
18750
20283
|
}).strict();
|
|
18751
|
-
var SoakModelVerificationPairEvidenceSchema =
|
|
18752
|
-
nodesChecked:
|
|
18753
|
-
unverified:
|
|
18754
|
-
mismatched:
|
|
20284
|
+
var SoakModelVerificationPairEvidenceSchema = z24.object({
|
|
20285
|
+
nodesChecked: z24.number().int().nonnegative(),
|
|
20286
|
+
unverified: z24.number().int().nonnegative(),
|
|
20287
|
+
mismatched: z24.number().int().nonnegative()
|
|
18755
20288
|
}).strict();
|
|
18756
|
-
var SoakEvidenceSchema =
|
|
18757
|
-
totalObservations:
|
|
18758
|
-
genuineUsageObservations:
|
|
18759
|
-
ciSyntheticObservations:
|
|
18760
|
-
recorderCount:
|
|
18761
|
-
ineligibleObservations:
|
|
18762
|
-
firstTimestamp:
|
|
18763
|
-
lastTimestamp:
|
|
18764
|
-
distinctDays:
|
|
18765
|
-
criticalDivergences:
|
|
20289
|
+
var SoakEvidenceSchema = z24.object({
|
|
20290
|
+
totalObservations: z24.number().int().nonnegative(),
|
|
20291
|
+
genuineUsageObservations: z24.number().int().nonnegative(),
|
|
20292
|
+
ciSyntheticObservations: z24.number().int().nonnegative(),
|
|
20293
|
+
recorderCount: z24.number().int().nonnegative(),
|
|
20294
|
+
ineligibleObservations: z24.number().int().nonnegative(),
|
|
20295
|
+
firstTimestamp: z24.string().datetime().nullable(),
|
|
20296
|
+
lastTimestamp: z24.string().datetime().nullable(),
|
|
20297
|
+
distinctDays: z24.number().int().nonnegative(),
|
|
20298
|
+
criticalDivergences: z24.number().int().nonnegative().nullable(),
|
|
18766
20299
|
privacy: SoakPrivacyPairEvidenceSchema.nullable(),
|
|
18767
20300
|
duplicateEffects: SoakDuplicateEffectPairEvidenceSchema.nullable(),
|
|
18768
20301
|
modelVerification: SoakModelVerificationPairEvidenceSchema.nullable(),
|
|
18769
|
-
platformsGenuine:
|
|
18770
|
-
platformsSynthetic:
|
|
18771
|
-
opencodeVersionsObserved:
|
|
18772
|
-
invalidChains:
|
|
20302
|
+
platformsGenuine: z24.array(SoakPlatformEnumSchema),
|
|
20303
|
+
platformsSynthetic: z24.array(SoakPlatformEnumSchema),
|
|
20304
|
+
opencodeVersionsObserved: z24.array(z24.string().min(1)),
|
|
20305
|
+
invalidChains: z24.number().int().nonnegative()
|
|
18773
20306
|
}).strict();
|
|
18774
|
-
var SoakCertificateSchema =
|
|
18775
|
-
version:
|
|
18776
|
-
certificate:
|
|
18777
|
-
trustBoundary:
|
|
20307
|
+
var SoakCertificateSchema = z24.object({
|
|
20308
|
+
version: z24.literal(1),
|
|
20309
|
+
certificate: z24.literal("graph-soak"),
|
|
20310
|
+
trustBoundary: z24.literal("contributors"),
|
|
18778
20311
|
policy: SoakPolicySchema,
|
|
18779
20312
|
evidence: SoakEvidenceSchema,
|
|
18780
|
-
verdict:
|
|
18781
|
-
failedGates:
|
|
20313
|
+
verdict: z24.enum(["pass", "fail"]),
|
|
20314
|
+
failedGates: z24.array(z24.enum([
|
|
18782
20315
|
"minimum-observations",
|
|
18783
20316
|
"minimum-duration",
|
|
18784
20317
|
"chain-integrity",
|
|
@@ -18789,8 +20322,8 @@ var SoakCertificateSchema = z22.object({
|
|
|
18789
20322
|
"os-diversity",
|
|
18790
20323
|
"opencode-pin"
|
|
18791
20324
|
])),
|
|
18792
|
-
ledgerDigest:
|
|
18793
|
-
digest:
|
|
20325
|
+
ledgerDigest: z24.string().regex(/^[0-9a-f]{64}$/),
|
|
20326
|
+
digest: z24.string().regex(/^[0-9a-f]{64}$/)
|
|
18794
20327
|
}).strict();
|
|
18795
20328
|
|
|
18796
20329
|
class SoakCertificateError extends Error {
|
|
@@ -18916,7 +20449,7 @@ function parseSoakCertificate(value, expectedPolicy, expectedLedgerDigest) {
|
|
|
18916
20449
|
}
|
|
18917
20450
|
|
|
18918
20451
|
// src/lifecycle/root.ts
|
|
18919
|
-
import { isAbsolute, normalize, relative as relative2, resolve as
|
|
20452
|
+
import { isAbsolute as isAbsolute2, normalize as normalize2, relative as relative2, resolve as resolve9 } from "node:path";
|
|
18920
20453
|
|
|
18921
20454
|
// src/messages/lifecycleStorage.ts
|
|
18922
20455
|
var lifecycleStorageMessages = {
|
|
@@ -18925,16 +20458,16 @@ var lifecycleStorageMessages = {
|
|
|
18925
20458
|
|
|
18926
20459
|
// src/lifecycle/root.ts
|
|
18927
20460
|
var resolveLifecycleRoot = (options) => {
|
|
18928
|
-
const workspaceRoot =
|
|
18929
|
-
if (
|
|
18930
|
-
return
|
|
20461
|
+
const workspaceRoot = resolve9(options.workspaceRoot);
|
|
20462
|
+
if (isAbsolute2(options.configuredRoot)) {
|
|
20463
|
+
return normalize2(resolve9(options.configuredRoot));
|
|
18931
20464
|
}
|
|
18932
|
-
const resolved =
|
|
20465
|
+
const resolved = resolve9(workspaceRoot, options.configuredRoot);
|
|
18933
20466
|
const workspaceRelative = relative2(workspaceRoot, resolved);
|
|
18934
|
-
if (workspaceRelative === ".." || workspaceRelative.startsWith(`..\\`) || workspaceRelative.startsWith("../") ||
|
|
20467
|
+
if (workspaceRelative === ".." || workspaceRelative.startsWith(`..\\`) || workspaceRelative.startsWith("../") || isAbsolute2(workspaceRelative)) {
|
|
18935
20468
|
throw new Error(lifecycleStorageMessages.configuredRootEscapesWorkspace);
|
|
18936
20469
|
}
|
|
18937
|
-
return
|
|
20470
|
+
return normalize2(resolved);
|
|
18938
20471
|
};
|
|
18939
20472
|
|
|
18940
20473
|
// src/lifecycle/runtimeRecorder.ts
|
|
@@ -19438,62 +20971,62 @@ var realCacheAdapter = {
|
|
|
19438
20971
|
};
|
|
19439
20972
|
|
|
19440
20973
|
// src/memory/types.ts
|
|
19441
|
-
import { z as
|
|
20974
|
+
import { z as z25 } from "zod";
|
|
19442
20975
|
var SHARED_OWNER_KEY = "*";
|
|
19443
|
-
var OwnerKeySchema =
|
|
19444
|
-
var MemoryKindSchema =
|
|
19445
|
-
var MemoryBaseSchema =
|
|
19446
|
-
id:
|
|
20976
|
+
var OwnerKeySchema = z25.string().min(1);
|
|
20977
|
+
var MemoryKindSchema = z25.enum(["fact", "preference", "entity"]);
|
|
20978
|
+
var MemoryBaseSchema = z25.object({
|
|
20979
|
+
id: z25.string().min(1),
|
|
19447
20980
|
ownerKey: OwnerKeySchema,
|
|
19448
|
-
confidence:
|
|
19449
|
-
validFrom:
|
|
19450
|
-
validUntil:
|
|
19451
|
-
createdAt:
|
|
19452
|
-
invalidatedAt:
|
|
19453
|
-
sourceHash:
|
|
19454
|
-
supersededBy:
|
|
20981
|
+
confidence: z25.number().min(0).max(1),
|
|
20982
|
+
validFrom: z25.number().finite(),
|
|
20983
|
+
validUntil: z25.number().finite().nullable().default(null),
|
|
20984
|
+
createdAt: z25.number().finite(),
|
|
20985
|
+
invalidatedAt: z25.number().finite().nullable().default(null),
|
|
20986
|
+
sourceHash: z25.string().min(1),
|
|
20987
|
+
supersededBy: z25.string().min(1).nullable().default(null)
|
|
19455
20988
|
}).strict();
|
|
19456
20989
|
var FactSchema = MemoryBaseSchema.extend({
|
|
19457
|
-
kind:
|
|
19458
|
-
subject:
|
|
19459
|
-
predicate:
|
|
19460
|
-
object:
|
|
19461
|
-
category:
|
|
20990
|
+
kind: z25.literal("fact"),
|
|
20991
|
+
subject: z25.string().min(1),
|
|
20992
|
+
predicate: z25.string().min(1),
|
|
20993
|
+
object: z25.string().min(1),
|
|
20994
|
+
category: z25.string().min(1).nullable().default(null)
|
|
19462
20995
|
});
|
|
19463
20996
|
var PreferenceSchema = MemoryBaseSchema.extend({
|
|
19464
|
-
kind:
|
|
19465
|
-
category:
|
|
19466
|
-
preference:
|
|
19467
|
-
context:
|
|
19468
|
-
lastAccessedAt:
|
|
19469
|
-
accessCount:
|
|
20997
|
+
kind: z25.literal("preference"),
|
|
20998
|
+
category: z25.string().min(1),
|
|
20999
|
+
preference: z25.string().min(1),
|
|
21000
|
+
context: z25.string().min(1).nullable().default(null),
|
|
21001
|
+
lastAccessedAt: z25.number().finite().nullable().default(null),
|
|
21002
|
+
accessCount: z25.number().int().min(0).default(0)
|
|
19470
21003
|
});
|
|
19471
21004
|
var EntitySchema = MemoryBaseSchema.extend({
|
|
19472
|
-
kind:
|
|
19473
|
-
canonicalName:
|
|
19474
|
-
type:
|
|
19475
|
-
aliases:
|
|
21005
|
+
kind: z25.literal("entity"),
|
|
21006
|
+
canonicalName: z25.string().min(1),
|
|
21007
|
+
type: z25.string().min(1),
|
|
21008
|
+
aliases: z25.array(z25.string().min(1)).default([])
|
|
19476
21009
|
});
|
|
19477
21010
|
var RelationSchema = MemoryBaseSchema.extend({
|
|
19478
|
-
kind:
|
|
19479
|
-
from:
|
|
19480
|
-
to:
|
|
19481
|
-
predicate:
|
|
19482
|
-
annotation:
|
|
21011
|
+
kind: z25.literal("relation"),
|
|
21012
|
+
from: z25.string().min(1),
|
|
21013
|
+
to: z25.string().min(1),
|
|
21014
|
+
predicate: z25.string().min(1),
|
|
21015
|
+
annotation: z25.string().min(1).nullable().default(null)
|
|
19483
21016
|
});
|
|
19484
|
-
var MemoryRecordSchema =
|
|
21017
|
+
var MemoryRecordSchema = z25.discriminatedUnion("kind", [
|
|
19485
21018
|
FactSchema,
|
|
19486
21019
|
PreferenceSchema,
|
|
19487
21020
|
EntitySchema,
|
|
19488
21021
|
RelationSchema
|
|
19489
21022
|
]);
|
|
19490
|
-
var RecallQuerySchema =
|
|
21023
|
+
var RecallQuerySchema = z25.object({
|
|
19491
21024
|
ownerKey: OwnerKeySchema,
|
|
19492
|
-
kinds:
|
|
19493
|
-
asOf:
|
|
19494
|
-
limit:
|
|
19495
|
-
minSimilarity:
|
|
19496
|
-
includeShared:
|
|
21025
|
+
kinds: z25.array(MemoryKindSchema).default(["fact", "preference", "entity"]),
|
|
21026
|
+
asOf: z25.number().finite().nullable().default(null),
|
|
21027
|
+
limit: z25.number().int().positive().default(8),
|
|
21028
|
+
minSimilarity: z25.number().min(0).max(1).default(0.2),
|
|
21029
|
+
includeShared: z25.boolean().default(true)
|
|
19497
21030
|
}).strict();
|
|
19498
21031
|
|
|
19499
21032
|
// src/memory/rank.ts
|
|
@@ -20102,12 +21635,12 @@ function createLocalEmbedder(request, deps) {
|
|
|
20102
21635
|
}
|
|
20103
21636
|
|
|
20104
21637
|
// src/memory/embedText.ts
|
|
20105
|
-
function
|
|
21638
|
+
function normalize3(parts) {
|
|
20106
21639
|
return parts.map((part) => part.trim()).filter((part) => part.length > 0).join(" ");
|
|
20107
21640
|
}
|
|
20108
21641
|
function recordEmbeddingText(record2) {
|
|
20109
21642
|
if (record2.kind === "fact") {
|
|
20110
|
-
return
|
|
21643
|
+
return normalize3([
|
|
20111
21644
|
record2.subject,
|
|
20112
21645
|
record2.predicate,
|
|
20113
21646
|
record2.object,
|
|
@@ -20115,21 +21648,21 @@ function recordEmbeddingText(record2) {
|
|
|
20115
21648
|
]);
|
|
20116
21649
|
}
|
|
20117
21650
|
if (record2.kind === "preference") {
|
|
20118
|
-
return
|
|
21651
|
+
return normalize3([
|
|
20119
21652
|
record2.category,
|
|
20120
21653
|
record2.preference,
|
|
20121
21654
|
record2.context ?? ""
|
|
20122
21655
|
]);
|
|
20123
21656
|
}
|
|
20124
21657
|
if (record2.kind === "relation") {
|
|
20125
|
-
return
|
|
21658
|
+
return normalize3([
|
|
20126
21659
|
record2.from,
|
|
20127
21660
|
record2.predicate,
|
|
20128
21661
|
record2.to,
|
|
20129
21662
|
record2.annotation ?? ""
|
|
20130
21663
|
]);
|
|
20131
21664
|
}
|
|
20132
|
-
return
|
|
21665
|
+
return normalize3([record2.canonicalName, record2.type, ...record2.aliases]);
|
|
20133
21666
|
}
|
|
20134
21667
|
|
|
20135
21668
|
// src/storage/index/memoryEmbeddings.ts
|
|
@@ -20211,7 +21744,7 @@ async function buildMemoryRuntimeFromConfig(config, deps, options = {}) {
|
|
|
20211
21744
|
// package.json
|
|
20212
21745
|
var package_default = {
|
|
20213
21746
|
name: "@jmanuelcorral/openteam",
|
|
20214
|
-
version: "0.
|
|
21747
|
+
version: "0.21.0",
|
|
20215
21748
|
packageManager: "bun@1.3.14",
|
|
20216
21749
|
description: "Cost-aware, local-first routing plugin for opencode with cheapest-capable frontier fallback and multi-agent orchestration.",
|
|
20217
21750
|
license: "MIT",
|
|
@@ -20338,14 +21871,14 @@ async function readPackagedCertificate(path4) {
|
|
|
20338
21871
|
return;
|
|
20339
21872
|
}
|
|
20340
21873
|
}
|
|
20341
|
-
async function readAndParseCertificate(storage, path4,
|
|
21874
|
+
async function readAndParseCertificate(storage, path4, parse3, digestExtractor, fallbackRead) {
|
|
20342
21875
|
try {
|
|
20343
21876
|
const content = await storage.read(path4) ?? (fallbackRead === undefined ? undefined : await fallbackRead(path4));
|
|
20344
21877
|
if (content === undefined) {
|
|
20345
21878
|
return { status: "absent" };
|
|
20346
21879
|
}
|
|
20347
21880
|
const raw = JSON.parse(content);
|
|
20348
|
-
const cert =
|
|
21881
|
+
const cert = parse3(raw);
|
|
20349
21882
|
return { status: "valid", digest: digestExtractor(cert) };
|
|
20350
21883
|
} catch (error) {
|
|
20351
21884
|
if (isMissingFile(error)) {
|
|
@@ -21104,7 +22637,7 @@ async function readConfigFile(path4, resolution) {
|
|
|
21104
22637
|
return storage.read(path4);
|
|
21105
22638
|
}
|
|
21106
22639
|
try {
|
|
21107
|
-
return await readFile3(
|
|
22640
|
+
return await readFile3(resolve10(path4), "utf8");
|
|
21108
22641
|
} catch (error) {
|
|
21109
22642
|
throw new Error(`[openteam] config file named by --config could not be read: ${path4} (${describeFileReadError(error)})`);
|
|
21110
22643
|
}
|
|
@@ -21127,7 +22660,7 @@ async function saveConfig(config, path4, resolution = { explicit: false }) {
|
|
|
21127
22660
|
return;
|
|
21128
22661
|
}
|
|
21129
22662
|
const contents = serializeOpenTeamConfig(config);
|
|
21130
|
-
const diskPath =
|
|
22663
|
+
const diskPath = resolve10(path4);
|
|
21131
22664
|
await mkdir2(dirname7(diskPath), { recursive: true });
|
|
21132
22665
|
await writeFile2(diskPath, contents, "utf8");
|
|
21133
22666
|
}
|
|
@@ -21173,8 +22706,8 @@ async function openBrowser(url) {
|
|
|
21173
22706
|
}
|
|
21174
22707
|
}
|
|
21175
22708
|
function waitForSignal() {
|
|
21176
|
-
return new Promise((
|
|
21177
|
-
const done = () =>
|
|
22709
|
+
return new Promise((resolve11) => {
|
|
22710
|
+
const done = () => resolve11();
|
|
21178
22711
|
process.once("SIGINT", done);
|
|
21179
22712
|
process.once("SIGTERM", done);
|
|
21180
22713
|
});
|
|
@@ -21363,7 +22896,7 @@ async function main() {
|
|
|
21363
22896
|
workspaceRoot,
|
|
21364
22897
|
configuredRoot: initialConsoleConfig.lifecycle?.root ?? DEFAULT_LIFECYCLE_ROOT
|
|
21365
22898
|
});
|
|
21366
|
-
const legacyGraphRoot =
|
|
22899
|
+
const legacyGraphRoot = resolve10(workspaceRoot, initialConsoleConfig.graph?.journalRoot ?? DEFAULT_GRAPH_JOURNAL_ROOT);
|
|
21367
22900
|
const lifecycleAvailability = initialConsoleConfig.console.graphView?.enabled === true ? "enabled" : "history-disabled";
|
|
21368
22901
|
const lifecycleHistoryReader = createLifecycleHistoryProvider({
|
|
21369
22902
|
lifecycleRoot,
|