@obversa/runtime 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +3 -0
- package/dist/api.js +502 -358
- package/dist/api.js.map +1 -1
- package/dist/bin/record.d.ts +2 -0
- package/dist/bin/record.js +24 -0
- package/dist/bin/record.js.map +1 -0
- package/dist/{chunk-DV5P4QLI.js → chunk-G2OIKOUI.js} +277 -66
- package/dist/chunk-G2OIKOUI.js.map +1 -0
- package/dist/chunk-XDMDT67Q.js +598 -0
- package/dist/chunk-XDMDT67Q.js.map +1 -0
- package/dist/core/interaction.d.ts +26 -0
- package/dist/core/job.d.ts +3 -0
- package/dist/core/judge.d.ts +119 -0
- package/dist/core/types.d.ts +93 -3
- package/dist/runtime/monitor.d.ts +8 -5
- package/dist/runtime/persist.d.ts +4 -17
- package/dist/runtime/render-record.d.ts +68 -0
- package/dist/workflow-support.js +1 -1
- package/dist/workflow.d.ts +23 -3
- package/package.json +7 -4
- package/dist/chunk-DV5P4QLI.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/supervisor.ts","../src/runtime/render-record.ts"],"names":["readFileSync"],"mappings":"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","file":"chunk-XDMDT67Q.js","sourcesContent":["/** Filesystem-backed status for a run that another process can inspect. */\n\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n fstatSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n writeFileSync,\n} from 'node:fs';\nimport { randomBytes } from 'node:crypto';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport type {\n JobMeta,\n LoopEvent,\n Outcome,\n ProofRecord,\n UsageTotals,\n} from '../core/types.js';\n\nconst NOISE: ReadonlySet<LoopEvent['kind']> = new Set([\n 'engine:text',\n 'engine:thinking',\n]);\nconst PROGRESS_TAIL = 200;\nconst PROGRESS_TAIL_BYTES = 256 * 1024;\n\nexport function runsHome(): string {\n return join(process.env.OBVERSA_HOME ?? join(homedir(), '.obversa'), 'runs');\n}\n\nfunction slug(value: string): string {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 32) || 'run'\n );\n}\n\nexport function newRunId(title: string): string {\n return `${slug(title)}-${randomBytes(3).toString('hex')}`;\n}\n\nexport interface CurrentWork {\n kind: 'job' | 'dag-node';\n path: string[];\n label?: string;\n node?: string;\n startedAt: number;\n timeoutMs?: number;\n deadlineAt?: number;\n}\n\nexport interface RunLive {\n path: string[];\n iteration: number;\n current?: CurrentWork;\n active?: Record<string, CurrentWork>;\n lastGate?: {\n which: string;\n met: boolean;\n confidence?: number;\n reason: string;\n };\n lastOutcome?: { status: string; summary?: string; late?: boolean };\n usage: {\n inputTokens: number;\n outputTokens: number;\n /** What this run has been served from cache, the figure the line reports. */\n cacheReadInputTokens: number;\n /** What it paid to build that cache, kept separate on purpose. */\n cacheCreationInputTokens: number;\n calls: number;\n unmeasuredCalls: number;\n };\n}\n\nexport interface RunStatus {\n runId: string;\n pid: number;\n cwd: string;\n title: string;\n startedAt: number;\n updatedAt: number;\n endedAt?: number;\n status: 'running' | Outcome['status'];\n alive?: boolean;\n shape?: JobMeta;\n live: RunLive;\n evidence?: {\n count: number;\n indexPath: string;\n latest?: ProofRecord;\n };\n}\n\nexport interface Supervisor {\n runId: string;\n dir: string;\n sink: (event: LoopEvent) => void;\n finish: (outcome: Outcome) => void;\n}\n\nexport function startSupervisor(input: {\n runId: string;\n cwd: string;\n title: string;\n shape?: JobMeta;\n}): Supervisor {\n const dir = join(runsHome(), input.runId);\n const eventsPath = join(dir, 'events.jsonl');\n const proofsPath = join(dir, 'proofs.jsonl');\n const statusPath = join(dir, 'status.json');\n mkdirSync(dir, { recursive: true });\n writeBestEffort(eventsPath, '');\n writeBestEffort(proofsPath, '');\n\n const startedAt = Date.now();\n const status: RunStatus = {\n runId: input.runId,\n pid: process.pid,\n cwd: input.cwd,\n title: input.title,\n startedAt,\n updatedAt: startedAt,\n status: 'running',\n shape: input.shape,\n live: {\n path: [],\n iteration: 0,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n calls: 0,\n unmeasuredCalls: 0,\n },\n },\n };\n const active = new Map<string, CurrentWork>();\n let proofCount = 0;\n\n const writeStatus = () => {\n status.updatedAt = Date.now();\n writeBestEffort(statusPath, JSON.stringify(status, null, 2));\n };\n const refreshCurrent = () => {\n status.live.active = active.size\n ? Object.fromEntries(active.entries())\n : undefined;\n status.live.current = [...active.values()].sort((a, b) => {\n const deadline =\n (a.deadlineAt ?? Number.POSITIVE_INFINITY) -\n (b.deadlineAt ?? Number.POSITIVE_INFINITY);\n return deadline || b.startedAt - a.startedAt;\n })[0];\n };\n const activeKey = (kind: CurrentWork['kind'], path: readonly string[]) =>\n `${kind}:${path.join('\\u0000')}`;\n\n writeStatus();\n\n const sink = (event: LoopEvent) => {\n if (!NOISE.has(event.kind)) appendBestEffort(eventsPath, event);\n\n switch (event.kind) {\n case 'run:end':\n status.live.lastOutcome = outcomeSummary(event.outcome);\n break;\n case 'loop:iteration':\n status.live.path = event.path;\n status.live.iteration = event.iteration;\n break;\n case 'loop:condition':\n status.live.lastGate = {\n which: event.which,\n met: event.result.met,\n confidence: event.result.confidence,\n reason: event.result.reason,\n };\n break;\n case 'condition:result':\n status.live.lastGate = {\n which: event.label,\n met: event.result.met,\n confidence: event.result.confidence,\n reason: event.result.reason,\n };\n break;\n case 'dag:node': {\n const path = [...event.path, event.node];\n status.live.path = path;\n if (event.phase === 'start') {\n active.set(activeKey('dag-node', path), {\n kind: 'dag-node',\n path,\n node: event.node,\n startedAt: event.ts,\n timeoutMs: event.timeoutMs,\n deadlineAt: event.timeoutMs ? event.ts + event.timeoutMs : undefined,\n });\n } else {\n active.delete(activeKey('dag-node', path));\n }\n refreshCurrent();\n break;\n }\n case 'job:start': {\n const path = [...event.path, event.label];\n active.set(activeKey('job', path), {\n kind: 'job',\n path: event.path,\n label: event.label,\n startedAt: event.ts,\n timeoutMs: event.timeoutMs,\n deadlineAt: event.timeoutMs ? event.ts + event.timeoutMs : undefined,\n });\n refreshCurrent();\n break;\n }\n case 'loop:end':\n case 'dag:end':\n case 'job:end':\n status.live.path = event.path;\n status.live.lastOutcome = outcomeSummary(event.outcome);\n if (event.kind === 'job:end') {\n active.delete(activeKey('job', [...event.path, event.label]));\n refreshCurrent();\n }\n break;\n case 'engine:usage':\n status.live.usage.calls += 1;\n if (event.usage.kind === 'unknown') {\n status.live.usage.unmeasuredCalls += 1;\n } else {\n status.live.usage.inputTokens += event.usage.inputTokens;\n status.live.usage.outputTokens += event.usage.outputTokens;\n status.live.usage.cacheReadInputTokens += event.usage.cacheReadInputTokens ?? 0;\n status.live.usage.cacheCreationInputTokens += event.usage.cacheCreationInputTokens ?? 0;\n }\n break;\n case 'proof': {\n const proof: ProofRecord = {\n name: event.name,\n path: event.path,\n artifact: event.artifact,\n };\n proofCount += 1;\n appendBestEffort(proofsPath, proof);\n status.evidence = {\n count: proofCount,\n indexPath: proofsPath,\n latest: proof,\n };\n break;\n }\n }\n\n if (!NOISE.has(event.kind)) writeStatus();\n };\n\n const finish = (outcome: Outcome) => {\n status.status = outcome.status;\n status.endedAt = Date.now();\n status.live.current = undefined;\n status.live.active = undefined;\n status.live.lastOutcome = outcomeSummary(outcome);\n writeStatus();\n };\n\n return { runId: input.runId, dir, sink, finish };\n}\n\nfunction outcomeSummary(outcome: Outcome): RunLive['lastOutcome'] {\n return {\n status: outcome.status,\n summary: outcome.summary,\n late: outcome.late,\n };\n}\n\nfunction writeBestEffort(path: string, text: string): void {\n try {\n writeFileSync(path, text);\n } catch {\n // Supervision must not stop the run.\n }\n}\n\nfunction appendBestEffort(path: string, value: unknown): void {\n try {\n appendFileSync(path, `${JSON.stringify(value)}\\n`);\n } catch {\n // Supervision must not stop the run.\n }\n}\n\nexport function isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nexport function readRunStatus(runId: string): RunStatus | undefined {\n if (!/^[a-z0-9][a-z0-9-]*$/.test(runId)) return undefined;\n try {\n const status = JSON.parse(\n readFileSync(join(runsHome(), runId, 'status.json'), 'utf8'),\n ) as RunStatus;\n status.alive = status.status === 'running' ? isAlive(status.pid) : false;\n return status;\n } catch {\n return undefined;\n }\n}\n\nexport function listRuns(): RunStatus[] {\n if (!existsSync(runsHome())) return [];\n return readdirSync(runsHome())\n .map(readRunStatus)\n .filter((status): status is RunStatus => status !== undefined)\n .sort((a, b) => b.startedAt - a.startedAt);\n}\n\nexport function runEventsPath(runId: string): string {\n return join(runsHome(), runId, 'events.jsonl');\n}\n\nexport function runEvidenceIndexPath(runId: string): string {\n return join(runsHome(), runId, 'proofs.jsonl');\n}\n\nexport interface RunProgress {\n runId: string;\n status: RunStatus['status'];\n alive?: boolean;\n title: string;\n stage: string;\n iteration: number;\n lastGate?: RunLive['lastGate'];\n lastOutcome?: RunLive['lastOutcome'];\n usage: RunLive['usage'];\n current?: RunLive['current'] & {\n elapsedMs: number;\n remainingMs?: number;\n };\n evidence?: RunStatus['evidence'];\n startedAt: number;\n updatedAt: number;\n blocker?: {\n kind: 'gate-failing' | 'limit-pause' | 'error';\n detail: string;\n };\n recent: string[];\n}\n\nfunction readEventTail(runId: string): LoopEvent[] {\n let raw: string;\n try {\n const fd = openSync(runEventsPath(runId), 'r');\n try {\n const size = fstatSync(fd).size;\n // Include the preceding byte so a cut at a newline keeps the next record.\n const start = Math.max(0, size - PROGRESS_TAIL_BYTES - 1);\n const buffer = Buffer.alloc(size - start);\n readSync(fd, buffer, 0, buffer.length, start);\n raw = buffer.toString('utf8');\n if (start > 0) raw = raw.slice(raw.indexOf('\\n') + 1);\n } finally {\n closeSync(fd);\n }\n } catch {\n return [];\n }\n\n const events: LoopEvent[] = [];\n for (const line of raw.split('\\n').slice(-PROGRESS_TAIL)) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as LoopEvent);\n } catch {\n // Ignore a partial last line.\n }\n }\n return events;\n}\n\nfunction deriveBlocker(\n status: RunStatus['status'],\n events: LoopEvent[],\n live: RunLive,\n): RunProgress['blocker'] {\n if (status === 'pass') return undefined;\n let progressSince = false;\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index]!;\n if (event.kind === 'limit:pause')\n return { kind: 'limit-pause', detail: event.reason };\n if (event.kind === 'error' && !progressSince)\n return { kind: 'error', detail: event.message };\n if (\n event.kind === 'loop:iteration' ||\n event.kind === 'dag:node' ||\n ((event.kind === 'loop:end' || event.kind === 'dag:end') &&\n event.outcome.status === 'pass')\n )\n progressSince = true;\n }\n if (live.lastGate?.met === false)\n return { kind: 'gate-failing', detail: live.lastGate.reason };\n return undefined;\n}\n\nexport function readRunProgress(\n runId: string,\n options?: { recent?: number },\n): RunProgress | undefined {\n const status = readRunStatus(runId);\n if (!status) return undefined;\n const events = readEventTail(runId);\n const now = Date.now();\n const current = status.live.current\n ? {\n ...status.live.current,\n elapsedMs: Math.max(0, now - status.live.current.startedAt),\n remainingMs: status.live.current.deadlineAt\n ? Math.max(0, status.live.current.deadlineAt - now)\n : undefined,\n }\n : undefined;\n return {\n runId: status.runId,\n status: status.status,\n alive: status.alive,\n title: status.title,\n stage: status.live.path.length ? status.live.path.join(' / ') : '(root)',\n iteration: status.live.iteration,\n lastGate: status.live.lastGate,\n lastOutcome: status.live.lastOutcome,\n usage: status.live.usage,\n current,\n evidence: status.evidence,\n startedAt: status.startedAt,\n updatedAt: status.updatedAt,\n blocker: deriveBlocker(status.status, events, status.live),\n // Not `.map(formatEvent)`: map passes the index as the second argument,\n // which now lands in `totals`. The compiler caught it, and the same trap\n // waits for any caller who passes this function by reference.\n recent: events.slice(-(options?.recent ?? 10)).map((event) => formatEvent(event, status.live.usage)),\n };\n}\n\nexport function runningTotal(totals: UsageTotals): string {\n // Cache READ only, and named. Creation and read are different things:\n // creation is what was paid to build the cache, read is what was served\n // from it. Summing them under one word makes a reader guess which they are\n // looking at, and a number whose meaning is guessed is worse than none on a\n // page whose whole subject is being transparent about spend. Both figures\n // stay on StatsSnapshot in full; this line is a summary, not the record.\n const read = totals.cacheReadInputTokens ?? 0;\n const unmeasured = totals.unmeasuredCalls ?? 0;\n // Shown only when there is one, so an honest complete run stays clean and an\n // incomplete one says so rather than presenting a total as the whole story.\n // The words are the ones a single call already prints, \"usage unknown\", so a\n // reader who learns the phrase once knows it at both levels instead of\n // meeting two spellings of one idea and wondering if they differ.\n const missing = unmeasured > 0 ? `, usage unknown on ${unmeasured} call${unmeasured === 1 ? '' : 's'}` : '';\n const base = `${totals.inputTokens}/${totals.outputTokens} tok`;\n // The unit stays on the number: a bare 900 beside a labelled pair reads as\n // the same kind of thing as the pair, and it is not.\n return `${base}${read > 0 ? `, ${read} tok from cache` : ''}${missing}`;\n}\n\nexport function toLine(value: string): string {\n return value.replace(/[\\u0000-\\u001f\\u007f]+/g, ' ');\n}\n\n/**\n * Format one event with optional totals the caller already holds.\n *\n * `StatsSnapshot` accumulates the totals and the monitor's live status tracks\n * them, so nothing here remembers anything: the function stays one event in,\n * one string out. Omitting the totals prints exactly what it printed before.\n */\nexport function formatEvent(event: LoopEvent, totals?: UsageTotals): string {\n return toLine(renderEvent(event, totals));\n}\n\nfunction renderEvent(event: LoopEvent, totals?: UsageTotals): string {\n const at = event.path.length ? `${event.path.join(' › ')} ` : '';\n switch (event.kind) {\n case 'run:start':\n return '▸ run';\n case 'run:end':\n return `◂ run ${event.outcome.status}${event.outcome.late ? ' late' : ''} (${runningTotal(event.usage)})`;\n case 'loop:start':\n return `${at}▸ loop${event.max ? ` (max ${event.max})` : ''}`;\n case 'dag:start':\n return `${at}▸ dag (${event.nodes.length} nodes)`;\n case 'loop:iteration':\n return `${at}· iteration ${event.iteration}`;\n case 'loop:condition':\n return `${at}· ${event.which} ${event.result.met ? 'met' : 'not met'}: ${event.result.reason}`;\n case 'condition:result':\n return `${at}· ${event.label} ${event.result.met ? 'met' : 'not met'}: ${event.result.reason}`;\n case 'loop:review':\n return `${at}· review: ${event.outcome.status}${event.outcome.late ? ' late' : ''}`;\n case 'loop:end':\n return `${at}◂ ${event.outcome.status}${event.outcome.late ? ' late' : ''} (${event.iterations} iter)`;\n case 'dag:node':\n return `${at}· node ${event.node}: ${event.phase}${event.outcome ? ` (${event.outcome.status}${event.outcome.late ? ' late' : ''})` : ''}`;\n case 'dag:kickback':\n return `${at}↩ kickback ${event.accepted ? 'accepted' : 'rejected'} ${event.from} -> ${event.to} [${event.count}/${event.limit}]: ${event.reason}${event.note ? ` (${event.note})` : ''}`;\n case 'dag:end':\n return `${at}◂ dag ${event.outcome.status}${event.outcome.late ? ' late' : ''}`;\n case 'job:start':\n return `${at}• ${event.label}`;\n case 'advisor:consult':\n return `${at}◇ advisor ${event.label} #${event.call}: ${event.question}`;\n case 'proof':\n return `${at}◈ proof ${event.name}: ${event.artifact.title ?? event.artifact.path ?? event.artifact.kind}`;\n case 'job:end': {\n const summary = event.outcome.summary ? ` ${event.outcome.summary}` : '';\n return `${at}• ${event.label}: ${event.outcome.status}${event.outcome.late ? ' late' : ''}${summary}`;\n }\n case 'engine:text':\n case 'engine:thinking':\n // Each of these is a streamed chunk, not a message: printed one per\n // event they read as fragments. A person gets the step's summary on its\n // job:end line instead, and the record keeps neither.\n return '';\n case 'engine:tool':\n return `${at} tool ${event.name} ${event.phase}${event.target ? ` ${event.target}` : ''}`;\n case 'engine:usage': {\n const call = event.usage.kind === 'unknown'\n ? 'usage unknown'\n : `${event.usage.inputTokens}/${event.usage.outputTokens} tok`;\n // A person watching wants both: what this call cost, and what the run\n // has cost so far. Without the second, a long run is a wall of numbers\n // that never answers the question being asked.\n return `${at} ${event.model}: ${call}${totals ? ` (run ${runningTotal(totals)})` : ''}`;\n }\n case 'refine:judge':\n return `${at}◆ ${event.reason}`;\n case 'loop:stall':\n return `${at}⏹ stalled after ${event.report.iterations.length} no-progress iterations: ${event.report.reason}`;\n case 'limit:wait':\n return `${at}⏸ limit ${event.code}: waiting ${Math.round(event.waitMs / 1000)}s`;\n case 'limit:pause':\n return `${at}⏸ paused (${event.code}): ${event.reason}`;\n case 'log':\n return `${at}${event.message}`;\n case 'error':\n return `${at}✗ ${event.code}: ${event.message}`;\n default:\n return `${at}${event.kind}`;\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport type { LoopEvent } from '../core/types.js';\nimport { toLine } from './supervisor.js';\n\nexport interface RecordLine {\n readonly kind: string;\n readonly text: string;\n}\n\nexport interface RecordEngineCall {\n readonly model: string;\n readonly inputTokens: number | null;\n readonly outputTokens: number | null;\n}\n\nexport interface RecordToolUse {\n readonly name: string;\n readonly count: number;\n readonly targets: readonly string[];\n}\n\nexport interface RecordKickback {\n readonly from: string;\n readonly to: string;\n readonly reason: string;\n readonly count: number;\n readonly limit: number;\n readonly accepted: boolean;\n readonly note?: string;\n}\n\nexport interface RecordOutcome {\n readonly status: string;\n readonly summary?: string;\n}\n\nexport interface RecordNodeRun {\n readonly attempt: number;\n readonly startedAt: number | null;\n readonly endedAt: number | null;\n readonly outcome: RecordOutcome | null;\n readonly kickback: RecordKickback | null;\n readonly engineCalls: readonly RecordEngineCall[];\n readonly tools: readonly RecordToolUse[];\n readonly lines: readonly RecordLine[];\n}\n\nexport interface RecordNodeSummary {\n readonly node: string;\n readonly runs: readonly RecordNodeRun[];\n}\n\nexport interface RecordUsage {\n readonly inputTokens: number;\n readonly outputTokens: number;\n readonly cacheReadInputTokens: number;\n readonly unmeasuredCalls: number;\n}\n\nexport interface RecordSummary {\n readonly name: string | null;\n readonly startedAt: number | null;\n readonly endedAt: number | null;\n readonly outcome: RecordOutcome | null;\n readonly usage: RecordUsage;\n readonly monitor: string | null;\n readonly nodes: readonly RecordNodeSummary[];\n readonly lines: readonly RecordLine[];\n}\n\nexport interface RenderRecordOptions {\n readonly lineWidth?: number;\n}\n\nconst DEFAULT_WIDTH = 100;\n\ninterface MutableRun {\n attempt: number;\n startedAt: number | null;\n endedAt: number | null;\n outcome: RecordOutcome | null;\n kickback: RecordKickback | null;\n engineCalls: RecordEngineCall[];\n tools: { name: string; count: number; targets: string[] }[];\n lines: RecordLine[];\n}\n\ninterface MutableNode {\n node: string;\n runs: MutableRun[];\n}\n\nfunction firstLine(value: string): string {\n for (const raw of value.split('\\n')) {\n const line = toLine(raw).trim().replace(/^(?:[-*]|\\d+\\.)\\s+/, '');\n if (line.length > 0) return line;\n }\n return '';\n}\n\nfunction outcomeOf(outcome: { status: string; summary?: string } | undefined): RecordOutcome | null {\n return outcome ? { status: outcome.status, summary: outcome.summary } : null;\n}\n\nexport function summarizeRecord(events: readonly LoopEvent[]): RecordSummary {\n const firstDag = events.find((e) => e.kind === 'dag:start');\n const rootDepth = firstDag && firstDag.kind === 'dag:start' ? firstDag.path.length : 0;\n\n let name: string | null = null;\n let startedAt: number | null = null;\n let endedAt: number | null = null;\n let outcome: RecordOutcome | null = null;\n let usage: RecordUsage | null = null;\n let monitor: string | null = null;\n const nodes: MutableNode[] = [];\n const lines: RecordLine[] = [];\n const measured: {\n -readonly [K in keyof RecordUsage]: RecordUsage[K];\n } = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadInputTokens: 0,\n unmeasuredCalls: 0,\n };\n\n const nodeFor = (name_: string): MutableNode => {\n let n = nodes.find((x) => x.node === name_);\n if (!n) {\n n = { node: name_, runs: [] };\n nodes.push(n);\n }\n return n;\n };\n\n const runFor = (nodeName: string, attempt: number): MutableRun => {\n const n = nodeFor(nodeName);\n let r = n.runs.find((x) => x.attempt === attempt);\n if (!r) {\n r = {\n attempt,\n startedAt: null,\n endedAt: null,\n outcome: null,\n kickback: null,\n engineCalls: [],\n tools: [],\n lines: [],\n };\n n.runs.push(r);\n n.runs.sort((a, b) => a.attempt - b.attempt);\n }\n return r;\n };\n\n const latestRun = (nodeName: string): MutableRun => {\n const n = nodeFor(nodeName);\n const last = n.runs[n.runs.length - 1];\n if (last) return last;\n return runFor(nodeName, 1);\n };\n\n for (const event of events) {\n if (startedAt === null) startedAt = event.ts;\n\n if (event.kind === 'dag:node' && event.path.length === rootDepth) {\n const run = runFor(event.node, event.attempt ?? 1);\n if (event.phase === 'start') {\n run.startedAt = event.ts;\n } else {\n run.endedAt = event.ts;\n if (event.phase === 'skip') {\n run.outcome = { status: 'skipped', summary: event.outcome?.summary };\n } else if (event.outcome) {\n run.outcome = outcomeOf(event.outcome) ?? run.outcome;\n if (\n event.outcome.status === 'paused' &&\n event.outcome.summary &&\n !run.lines.some((l) => l.kind === 'paused')\n ) {\n run.lines.push({ kind: 'paused', text: `Paused: ${event.outcome.summary}` });\n }\n }\n }\n continue;\n }\n\n if (event.path.length > rootDepth) {\n const run = latestRun(event.path[rootDepth] ?? '');\n switch (event.kind) {\n case 'engine:usage': {\n if (event.usage.kind === 'reported') {\n run.engineCalls.push({\n model: event.model,\n inputTokens: event.usage.inputTokens,\n outputTokens: event.usage.outputTokens,\n });\n measured.inputTokens += event.usage.inputTokens;\n measured.outputTokens += event.usage.outputTokens;\n measured.cacheReadInputTokens += event.usage.cacheReadInputTokens ?? 0;\n } else {\n run.engineCalls.push({ model: event.model, inputTokens: null, outputTokens: null });\n measured.unmeasuredCalls += 1;\n }\n break;\n }\n case 'engine:tool': {\n if (event.phase === 'use') {\n const existing = run.tools.find((t) => t.name === event.name);\n if (existing) {\n existing.count += 1;\n if (event.target !== undefined && !existing.targets.includes(event.target)) {\n existing.targets.push(event.target);\n }\n } else {\n run.tools.push({\n name: event.name,\n count: 1,\n targets: event.target !== undefined ? [event.target] : [],\n });\n }\n }\n break;\n }\n case 'limit:pause':\n run.lines.push({ kind: event.kind, text: `Paused (${event.code}): ${event.reason}` });\n break;\n case 'dag:node':\n if (event.phase !== 'start') {\n const status =\n event.phase === 'skip'\n ? 'skipped'\n : (event.outcome?.status ?? 'no end recorded');\n const summary = event.outcome?.summary ? firstLine(event.outcome.summary) : '';\n const label = [...event.path.slice(rootDepth + 1), event.node].join('/');\n run.lines.push({ kind: event.kind, text: `${label}: ${status}${summary ? `, ${summary}` : ''}` });\n }\n break;\n case 'log':\n run.lines.push({ kind: event.kind, text: `log: ${event.message}` });\n break;\n case 'error':\n run.lines.push({ kind: event.kind, text: `error ${event.code}: ${event.message}` });\n break;\n case 'job:start':\n case 'job:end':\n case 'engine:text':\n case 'engine:thinking':\n case 'dag:start':\n case 'dag:end':\n break;\n default:\n run.lines.push({ kind: event.kind, text: event.kind });\n }\n continue;\n }\n\n // Record level: path.length <= rootDepth, not a top-level dag:node.\n switch (event.kind) {\n case 'run:start':\n if (name === null && event.runId) name = event.runId;\n break;\n case 'run:end':\n endedAt = event.ts;\n outcome = outcomeOf(event.outcome);\n usage = {\n inputTokens: event.usage.inputTokens,\n outputTokens: event.usage.outputTokens,\n cacheReadInputTokens: event.usage.cacheReadInputTokens ?? 0,\n unmeasuredCalls: event.usage.unmeasuredCalls ?? 0,\n };\n break;\n case 'dag:start':\n if (name === null && event.path.length > 0) name = event.path[0] ?? null;\n break;\n case 'dag:end':\n break;\n case 'monitor':\n monitor = event.url;\n break;\n case 'dag:kickback':\n if (event.accepted) {\n const run = runFor(event.to, event.count + 1);\n run.kickback = {\n from: event.from,\n to: event.to,\n reason: event.reason,\n count: event.count,\n limit: event.limit,\n accepted: true,\n note: event.note,\n };\n } else {\n latestRun(event.to).lines.push({\n kind: event.kind,\n text: `Kickback from ${event.from} rejected${event.note ? ` (${event.note})` : ''}: ${event.reason}`,\n });\n }\n break;\n case 'log':\n lines.push({ kind: event.kind, text: `log: ${event.message}` });\n break;\n case 'error':\n lines.push({ kind: event.kind, text: `error ${event.code}: ${event.message}` });\n break;\n default:\n lines.push({ kind: event.kind, text: event.kind });\n }\n }\n\n if (name === null && firstDag && firstDag.kind === 'dag:start' && firstDag.path.length > 0) {\n name = firstDag.path[0] ?? null;\n }\n\n return {\n name,\n startedAt,\n endedAt,\n outcome,\n usage: usage ?? measured,\n monitor,\n nodes: nodes.map((n) => ({\n node: n.node,\n runs: n.runs.map((r) => ({\n attempt: r.attempt,\n startedAt: r.startedAt,\n endedAt: r.endedAt,\n outcome: r.outcome,\n kickback: r.kickback,\n engineCalls: r.engineCalls,\n tools: r.tools.map((t) => ({ name: t.name, count: t.count, targets: t.targets })),\n lines: r.lines,\n })),\n })),\n lines,\n };\n}\n\nconst commas = (n: number): string => `${n}`.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\nfunction clockTime(ts: number): string {\n return new Date(ts).toISOString().slice(11, 19);\n}\n\nfunction headerTime(ts: number): string {\n return `${new Date(ts).toISOString().slice(0, 19).replace('T', ' ')} UTC`;\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms} ms`;\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${s % 60}s`;\n return `${Math.floor(m / 60)}h ${m % 60}m`;\n}\n\nfunction fit(text: string, width: number): string {\n return text.length > width ? `${text.slice(0, width)}…` : text;\n}\n\nexport function renderRecord(events: readonly LoopEvent[], options?: RenderRecordOptions): string {\n const width = options?.lineWidth ?? DEFAULT_WIDTH;\n const summary = summarizeRecord(events);\n const out: string[] = [];\n\n out.push(`# ${summary.name ?? 'run'}`);\n out.push('');\n\n if (summary.startedAt !== null && summary.endedAt === null) {\n out.push(`- Started ${headerTime(summary.startedAt)}. No end recorded.`);\n } else if (summary.startedAt !== null && summary.endedAt !== null) {\n out.push(\n `- Started ${headerTime(summary.startedAt)}, ended ${headerTime(summary.endedAt)} after ${formatDuration(summary.endedAt - summary.startedAt)}.`,\n );\n if (summary.outcome) {\n const text = summary.outcome.summary\n ? `${summary.outcome.status}. ${fit(firstLine(summary.outcome.summary), width)}`\n : `${summary.outcome.status}.`;\n out.push(`- Outcome: ${text}`);\n }\n }\n\n const usageParts = [`${commas(summary.usage.inputTokens)} in, ${commas(summary.usage.outputTokens)} out`];\n if (summary.usage.cacheReadInputTokens > 0) {\n usageParts.push(`${commas(summary.usage.cacheReadInputTokens)} read from cache`);\n }\n let tokensLine = `- Tokens: ${usageParts.join(', ')}.`;\n if (summary.usage.unmeasuredCalls > 0) {\n tokensLine = `- Tokens: ${usageParts.join(', ')}, usage unknown on ${summary.usage.unmeasuredCalls} calls.`;\n }\n out.push(tokensLine);\n\n if (summary.monitor) out.push(`- Monitor: ${summary.monitor}`);\n for (const line of summary.lines) out.push(`- ${fit(line.text, width)}`);\n\n for (const node of summary.nodes) {\n out.push('');\n out.push(`## ${node.node}`);\n for (const run of node.runs) {\n out.push('');\n if (run.kickback) {\n out.push(\n `Kickback from ${run.kickback.from}, ${run.kickback.count} of ${run.kickback.limit}: ${run.kickback.reason}`,\n );\n out.push('');\n }\n const status = run.endedAt === null ? 'no end recorded' : (run.outcome?.status ?? 'no outcome');\n const parts = [`### Run ${run.attempt}: ${status}`];\n if (run.startedAt !== null && run.endedAt !== null) {\n parts.push(formatDuration(run.endedAt - run.startedAt));\n }\n if (run.startedAt !== null) parts.push(`started ${clockTime(run.startedAt)}`);\n else if (run.endedAt !== null) parts.push(`at ${clockTime(run.endedAt)}`);\n out.push(parts.join(', '));\n\n if (run.outcome?.summary) {\n out.push('');\n out.push(fit(firstLine(run.outcome.summary), width));\n }\n if (run.engineCalls.length > 0 || run.tools.length > 0 || run.lines.length > 0) {\n out.push('');\n for (const call of run.engineCalls) {\n out.push(\n call.inputTokens === null || call.outputTokens === null\n ? `- ${call.model}: usage unknown`\n : `- ${call.model}: ${commas(call.inputTokens)} in, ${commas(call.outputTokens)} out`,\n );\n }\n if (run.tools.length > 0) {\n out.push(\n `- ${run.tools\n .map((t) => `${t.name} ×${t.count}${t.targets.length > 0 ? `: ${t.targets.join(', ')}` : ''}`)\n .join(', ')}`,\n );\n }\n for (const line of run.lines) {\n const uncut = line.kind === 'paused' || line.kind === 'limit:pause';\n out.push(`- ${uncut ? line.text : fit(line.text, width)}`);\n }\n }\n }\n }\n\n return `${out.join('\\n')}\\n`;\n}\n\nexport function readRecordFile(path: string): { events: LoopEvent[]; unreadable: number } {\n const text = readFileSync(path, 'utf8');\n const events: LoopEvent[] = [];\n let unreadable = 0;\n for (const line of text.split(/\\r?\\n/)) {\n if (line.trim().length === 0) continue;\n try {\n events.push(JSON.parse(line) as LoopEvent);\n } catch {\n unreadable += 1;\n }\n }\n return { events, unreadable };\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type JsonObject, type JsonValue } from '../graph/value.js';
|
|
2
|
+
import type { InteractionBinding, InteractionResponse, Job, JobContext, Outcome } from './types.js';
|
|
3
|
+
export type { InteractionBinding, InteractionResponse } from './types.js';
|
|
4
|
+
/** Keep declared job identity separate from an engine's mutable call state. */
|
|
5
|
+
export declare function interactionDeclaration<T extends Function>(job: T, declaration: unknown): T;
|
|
6
|
+
export declare function interactionIdentity(value: unknown): string;
|
|
7
|
+
export declare function jsonSnapshot(value: unknown): JsonObject;
|
|
8
|
+
/** Save only JSON outcome fields; runtime Error objects are not continuation data. */
|
|
9
|
+
export declare function outcomeSnapshot(outcome: Outcome): JsonObject;
|
|
10
|
+
export declare function savedInteraction(ctx: JobContext, path: readonly string[], identity: string): JsonObject | undefined;
|
|
11
|
+
export declare function hasSavedInteraction(ctx: JobContext, path: readonly string[]): boolean;
|
|
12
|
+
export declare function checkpointInteraction(ctx: JobContext, path: readonly string[], identity: string, data: JsonObject | null): void;
|
|
13
|
+
export declare function interactionResponse(value: unknown): InteractionResponse;
|
|
14
|
+
export declare const DEFAULT_INTERACTION: InteractionBinding;
|
|
15
|
+
export declare function requestInteraction(binding: InteractionBinding, question: string, input: JsonObject, ctx: JobContext, humanApproval?: boolean): Promise<{
|
|
16
|
+
response: InteractionResponse;
|
|
17
|
+
} | {
|
|
18
|
+
paused: Outcome;
|
|
19
|
+
}>;
|
|
20
|
+
export interface HumanReviewOptions {
|
|
21
|
+
readonly question: string;
|
|
22
|
+
readonly input: JsonValue | ((ctx: JobContext) => JsonValue | Promise<JsonValue>);
|
|
23
|
+
readonly interaction: InteractionBinding;
|
|
24
|
+
}
|
|
25
|
+
/** A person's explicit approval is the only passing result of this review. */
|
|
26
|
+
export declare function humanReview(name: string, options: HumanReviewOptions): Job;
|
package/dist/core/job.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* an HTTP API, or any framework — swap the engine and the same job runs.
|
|
6
6
|
*/
|
|
7
7
|
import type { Outcome, Job, JobContext, ProofArtifact } from './types.js';
|
|
8
|
+
import { type InteractionBinding } from './interaction.js';
|
|
8
9
|
/** Shared state key holding every engine answer the run recorded so far.
|
|
9
10
|
* Written by the runtime beside each engine:usage event; read by workflow
|
|
10
11
|
* layers that must compare what answered against what was declared. */
|
|
@@ -26,6 +27,8 @@ import { type LoopErrorCode } from './errors.js';
|
|
|
26
27
|
import { type AgentDef } from './agent.js';
|
|
27
28
|
import { kickback, revisionRequest } from './feedback.js';
|
|
28
29
|
export interface AgentJobConfig {
|
|
30
|
+
/** Opt in to requesting a rich interaction and continuing this same model. */
|
|
31
|
+
readonly interaction?: InteractionBinding;
|
|
29
32
|
/** Tag this job's engine answers with the review side and stage they
|
|
30
33
|
* belong to, so a workflow layer can compare recorded sides without
|
|
31
34
|
* inferring them from paths. Untagged answers are outside such gates. */
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A judge: a seat that answers typed questions about a piece of work and the
|
|
3
|
+
* rounds spent on it so far, in place of a plain review-round count. Used on
|
|
4
|
+
* a `workflow()` stage's `refine` and on a `dag()`'s `maxKickbacks`, between
|
|
5
|
+
* a review's verdict and the send-back.
|
|
6
|
+
*
|
|
7
|
+
* The default question set and the routing rule below make a loop that was
|
|
8
|
+
* first hand-wired as dag nodes into a runtime primitive.
|
|
9
|
+
*/
|
|
10
|
+
import { type InteractionBinding, type InteractionResponse } from './interaction.js';
|
|
11
|
+
import type { Outcome } from './types.js';
|
|
12
|
+
import type { FeedbackActionSeverity, FeedbackFinding, Judge, JudgeAnswer, JudgeQuestions, JobContext } from './types.js';
|
|
13
|
+
export type { Judge, JudgeAnswer, JudgeQuestion, JudgeQuestions } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* The default question set: does the work hold for this use case, are the
|
|
16
|
+
* latest findings worth doing, is another round worth it, and why stop. A
|
|
17
|
+
* caller's own set replaces this wholesale (e.g. for a use case this
|
|
18
|
+
* wording doesn't fit); `what` names the thing being judged in the wording.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stopQuestions(what?: string): JudgeQuestions;
|
|
21
|
+
/**
|
|
22
|
+
* A judge for `refine` or `maxKickbacks`: `seat` runs with workspace mode
|
|
23
|
+
* none (it reads no file itself; everything it needs rides in the prompt),
|
|
24
|
+
* `cap` is the hard backstop on rounds regardless of what the judge says,
|
|
25
|
+
* and `questions` defaults to `stopQuestions()`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function judge(seat: Judge['seat'], opts: {
|
|
28
|
+
cap: number;
|
|
29
|
+
questions?: JudgeQuestions;
|
|
30
|
+
interaction?: InteractionBinding;
|
|
31
|
+
}): Judge;
|
|
32
|
+
export declare function isJudge(value: unknown): value is Judge;
|
|
33
|
+
/** A finding tagged block, by any reviewer, in this round's findings. */
|
|
34
|
+
export declare function hasBlockFinding(findings: readonly FeedbackFinding[] | undefined): boolean;
|
|
35
|
+
/** Every finding, counted by severity, the judge reads numbers, not a list to recount itself. */
|
|
36
|
+
export declare function countBySeverity(findings: readonly FeedbackFinding[]): Record<FeedbackActionSeverity, number>;
|
|
37
|
+
/** One round of the work the judge is watching converge. */
|
|
38
|
+
export interface JudgeRound {
|
|
39
|
+
readonly round: number;
|
|
40
|
+
readonly findings: readonly FeedbackFinding[];
|
|
41
|
+
readonly counts: Readonly<Record<FeedbackActionSeverity, number>>;
|
|
42
|
+
/** Lines added or removed since the previous round, when the target is a file. */
|
|
43
|
+
readonly changedLines?: number;
|
|
44
|
+
}
|
|
45
|
+
/** What the judge sees. `cap` rides along so it can reason about how much room is left. */
|
|
46
|
+
export interface JudgeState {
|
|
47
|
+
readonly productFeedback?: readonly InteractionResponse[];
|
|
48
|
+
readonly useCase?: string;
|
|
49
|
+
/** The file being refined, relative to the workspace, when there is one. */
|
|
50
|
+
readonly file?: string;
|
|
51
|
+
/** That file's current content, when there is one. */
|
|
52
|
+
readonly draft?: string;
|
|
53
|
+
readonly latestFindings: readonly FeedbackFinding[];
|
|
54
|
+
readonly rounds: readonly JudgeRound[];
|
|
55
|
+
readonly round: number;
|
|
56
|
+
readonly cap: number;
|
|
57
|
+
}
|
|
58
|
+
export interface JudgeDecision {
|
|
59
|
+
/** Send the work back for another round. */
|
|
60
|
+
readonly again: boolean;
|
|
61
|
+
/** Always names the judge, so a kickback or a stop is traceable to it. */
|
|
62
|
+
readonly reason: string;
|
|
63
|
+
/**
|
|
64
|
+
* What a stop means, when `again` is false. `ship`: the work holds as it
|
|
65
|
+
* is, so it stands as a pass carrying the judge's reason. `fail`: another
|
|
66
|
+
* round will not fix it, so the run stops there and the requesting side's
|
|
67
|
+
* own failure stands. `product_decision` asks a person, then returns the
|
|
68
|
+
* feedback to this judge without advancing the review round. Absent when
|
|
69
|
+
* `again` is true.
|
|
70
|
+
*/
|
|
71
|
+
readonly stop?: 'ship' | 'fail' | 'product_decision';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Route on the judge's answers. The chosen `stop_reason` is read first: in
|
|
75
|
+
* use it moves with the rounds while the probability answers stay flat, so it
|
|
76
|
+
* is the answer that discriminates. A clear yes or no from `holds`,
|
|
77
|
+
* `worth_doing` or `worth_another_round` is the fallback when the choice does
|
|
78
|
+
* not parse. Neither the cap nor a block finding is checked
|
|
79
|
+
* here: the caller enforces the cap itself (a loop's own `maxReviewRestarts`,
|
|
80
|
+
* or a dag's own kickback budget), and a block finding never reaches this
|
|
81
|
+
* function, it always goes back without asking the judge.
|
|
82
|
+
*
|
|
83
|
+
* `product_decision` pauses for rich feedback and another judgment of the
|
|
84
|
+
* same work. For a terminal stop, `holds` and `over_polishing` say the work
|
|
85
|
+
* is good enough as it stands, so it ships as a pass; other stops, including
|
|
86
|
+
* `not_converging` and any choice a custom question set invents of its own,
|
|
87
|
+
* says the run should not ship silently, so it stops there and the
|
|
88
|
+
* requesting side's failure stands. The same split applies to the
|
|
89
|
+
* probability fallback: a clear `holds` or a clear "not worth doing" ships
|
|
90
|
+
* the work; an unclear "another round is not worth it" fails instead of
|
|
91
|
+
* shipping, since its own criteria already blend polish with a stall and
|
|
92
|
+
* cannot tell the two apart.
|
|
93
|
+
*/
|
|
94
|
+
export declare function judgeDecision(answers: Readonly<Record<string, JudgeAnswer>>): JudgeDecision;
|
|
95
|
+
/**
|
|
96
|
+
* Ask the judge, and record its answer. Runs `cfg.seat` as a workspace-mode-
|
|
97
|
+
* none agent turn over `state` and `cfg.questions`, parses the reply as the
|
|
98
|
+
* judge engine's own `{ [question]: JudgeAnswer }` shape, and emits
|
|
99
|
+
* `refine:judge` so a person reading the record sees what it answered and
|
|
100
|
+
* why. A reply that fails to parse becomes an empty answers object ,
|
|
101
|
+
* `judgeDecision` reads that as `stop_reason: 'unknown'`, which is not a
|
|
102
|
+
* chosen stop, so the caller's own cap is what ends the rounds.
|
|
103
|
+
*/
|
|
104
|
+
export declare function askJudge(cfg: Judge, state: JudgeState, ctx: JobContext, path: readonly string[]): Promise<{
|
|
105
|
+
answers: Readonly<Record<string, JudgeAnswer>>;
|
|
106
|
+
decision: JudgeDecision;
|
|
107
|
+
}>;
|
|
108
|
+
/** Resume only the deliberate product question; every returned answer goes back to this judge. */
|
|
109
|
+
export declare function consultJudge(cfg: Judge, initialState: JudgeState, ctx: JobContext, path: readonly string[], options: {
|
|
110
|
+
readonly identity: string;
|
|
111
|
+
readonly pending: boolean;
|
|
112
|
+
readonly save: (state: JudgeState) => void;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
state: JudgeState;
|
|
115
|
+
decision: JudgeDecision;
|
|
116
|
+
} | {
|
|
117
|
+
state: JudgeState;
|
|
118
|
+
paused: Outcome;
|
|
119
|
+
}>;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -15,12 +15,23 @@
|
|
|
15
15
|
* the primitive is the loop, not a pipeline.
|
|
16
16
|
*/
|
|
17
17
|
import type { Engine, EngineRef, UsageReceipt } from '../engines/engine.js';
|
|
18
|
-
import type { Memory } from '@obversa/api';
|
|
18
|
+
import type { Memory, TeamSeat } from '@obversa/api';
|
|
19
19
|
import type { LoopError } from './errors.js';
|
|
20
20
|
import type { EnvHandle, Environment } from '../env/environment.js';
|
|
21
|
-
import type { JsonValue, RunBrief } from '../graph/value.js';
|
|
21
|
+
import type { JsonObject, JsonValue, RunBrief } from '../graph/value.js';
|
|
22
22
|
import type { CallbackEvent, ClaimResult, ReleaseResult, SubmitResult } from '../callback/client.js';
|
|
23
23
|
import type { CallbackRequest } from '../callback/gate.js';
|
|
24
|
+
export type InteractionResponse = JsonObject & {
|
|
25
|
+
readonly feedback: JsonValue;
|
|
26
|
+
readonly prompt: string;
|
|
27
|
+
readonly decision?: 'approved' | 'changes-requested';
|
|
28
|
+
};
|
|
29
|
+
export interface InteractionBinding {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly responseSchema: JsonObject;
|
|
32
|
+
/** Return no answer when the page is cancelled, interrupted or times out. */
|
|
33
|
+
readonly answer?: (request: CallbackRequest, signal: AbortSignal) => Promise<InteractionResponse | undefined>;
|
|
34
|
+
}
|
|
24
35
|
/**
|
|
25
36
|
* The client a run's questions go through: the in-memory `CallbackClient`,
|
|
26
37
|
* or the stored client (`createStoredCallbackClient`) whose questions survive
|
|
@@ -79,6 +90,26 @@ export interface Outcome {
|
|
|
79
90
|
*/
|
|
80
91
|
revision?: RevisionRequest;
|
|
81
92
|
}
|
|
93
|
+
export type RecordedStage = {
|
|
94
|
+
readonly kind: 'interrupted';
|
|
95
|
+
readonly startLine: number;
|
|
96
|
+
} | {
|
|
97
|
+
readonly kind: 'completed';
|
|
98
|
+
readonly outcome: Outcome;
|
|
99
|
+
};
|
|
100
|
+
export interface ResumedStageRecords {
|
|
101
|
+
readonly interactions: ReadonlyMap<string, {
|
|
102
|
+
identity: string;
|
|
103
|
+
workspace: string;
|
|
104
|
+
data: JsonObject;
|
|
105
|
+
}>;
|
|
106
|
+
readonly anchors: ReadonlyMap<string, {
|
|
107
|
+
readonly identity: string;
|
|
108
|
+
readonly workspace: string;
|
|
109
|
+
readonly recordId: string;
|
|
110
|
+
}>;
|
|
111
|
+
readonly stages: ReadonlyMap<string, RecordedStage>;
|
|
112
|
+
}
|
|
82
113
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
83
114
|
/**
|
|
84
115
|
* Where a job's code lives: a working directory and (when it is a git repo) the
|
|
@@ -371,7 +402,51 @@ export interface DagNode {
|
|
|
371
402
|
*/
|
|
372
403
|
acceptsKickbackTo?: string[];
|
|
373
404
|
}
|
|
374
|
-
|
|
405
|
+
/**
|
|
406
|
+
* One question put to a judge, in the judge engine's own shape: `noul` asks
|
|
407
|
+
* for a probability, `choice` asks for one of the named criteria, `score`
|
|
408
|
+
* asks for a 0..1 rating per named criterion. `instructions` is what the
|
|
409
|
+
* judge reads; `criteria` are the standards it answers against.
|
|
410
|
+
*/
|
|
411
|
+
export type JudgeQuestion = {
|
|
412
|
+
readonly type: 'noul';
|
|
413
|
+
readonly instructions: string;
|
|
414
|
+
readonly criteria: {
|
|
415
|
+
readonly true: string;
|
|
416
|
+
readonly false: string;
|
|
417
|
+
};
|
|
418
|
+
} | {
|
|
419
|
+
readonly type: 'choice';
|
|
420
|
+
readonly instructions: string;
|
|
421
|
+
readonly criteria: Readonly<Record<string, string>>;
|
|
422
|
+
} | {
|
|
423
|
+
readonly type: 'score';
|
|
424
|
+
readonly instructions: string;
|
|
425
|
+
readonly criteria: readonly string[];
|
|
426
|
+
};
|
|
427
|
+
export type JudgeQuestions = Readonly<Record<string, JudgeQuestion>>;
|
|
428
|
+
/** One answer, in whichever of these fields its question type fills. */
|
|
429
|
+
export interface JudgeAnswer {
|
|
430
|
+
readonly noul?: number;
|
|
431
|
+
readonly probability?: number;
|
|
432
|
+
readonly choice?: string;
|
|
433
|
+
readonly probabilities?: Readonly<Record<string, number>>;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* A judge, in place of a plain round count, on a `workflow()` stage's
|
|
437
|
+
* `refine` or a `dag()`'s `maxKickbacks`: a seat that answers typed
|
|
438
|
+
* questions about the work and the rounds so far, between a review's
|
|
439
|
+
* verdict and the send-back. `cap` is the hard backstop, reached or not,
|
|
440
|
+
* it always stops the rounds. Built with `judge()`, never by hand.
|
|
441
|
+
*/
|
|
442
|
+
export interface Judge {
|
|
443
|
+
readonly kind: 'judge';
|
|
444
|
+
readonly seat: TeamSeat;
|
|
445
|
+
readonly cap: number;
|
|
446
|
+
readonly questions: JudgeQuestions;
|
|
447
|
+
readonly interaction?: InteractionBinding;
|
|
448
|
+
}
|
|
449
|
+
export type KickbackBudget = number | Readonly<Record<string, number | Judge>>;
|
|
375
450
|
export interface DagConfig {
|
|
376
451
|
name: string;
|
|
377
452
|
/** Node name → a `DagNode`, or a bare `Job` (shorthand for no deps/gates). */
|
|
@@ -626,6 +701,8 @@ export type LoopEvent = {
|
|
|
626
701
|
path: string[];
|
|
627
702
|
name: string;
|
|
628
703
|
phase: 'use' | 'result';
|
|
704
|
+
/** The file, command, URL or pattern the tool acted on, when known. */
|
|
705
|
+
target?: string;
|
|
629
706
|
} | {
|
|
630
707
|
kind: 'engine:usage';
|
|
631
708
|
ts: number;
|
|
@@ -634,6 +711,19 @@ export type LoopEvent = {
|
|
|
634
711
|
usage: UsageReceipt;
|
|
635
712
|
role?: 'writer' | 'reviewer';
|
|
636
713
|
stage?: string;
|
|
714
|
+
} | {
|
|
715
|
+
kind: 'refine:judge';
|
|
716
|
+
ts: number;
|
|
717
|
+
path: string[];
|
|
718
|
+
answers: Readonly<Record<string, JudgeAnswer>>;
|
|
719
|
+
reason: string;
|
|
720
|
+
} | {
|
|
721
|
+
kind: 'interaction:checkpoint';
|
|
722
|
+
ts: number;
|
|
723
|
+
path: string[];
|
|
724
|
+
identity: string;
|
|
725
|
+
workspace: string;
|
|
726
|
+
data: import('../graph/value.js').JsonObject | null;
|
|
637
727
|
} | {
|
|
638
728
|
kind: 'log';
|
|
639
729
|
ts: number;
|
|
@@ -58,13 +58,16 @@ export interface MonitorState {
|
|
|
58
58
|
decisionText: string;
|
|
59
59
|
input: JsonValue;
|
|
60
60
|
}>;
|
|
61
|
+
/**
|
|
62
|
+
* The record, already in the one line `formatEvent` would print for it: the
|
|
63
|
+
* console and this page must never disagree about what an event says, so
|
|
64
|
+
* neither keeps its own partial fields to re-render from. An event with
|
|
65
|
+
* nothing worth telling a person (thinking with no text yet) contributes no
|
|
66
|
+
* line at all, rather than a row that says only its own kind.
|
|
67
|
+
*/
|
|
61
68
|
events: Array<{
|
|
62
|
-
kind: string;
|
|
63
69
|
ts: number;
|
|
64
|
-
|
|
65
|
-
node?: string;
|
|
66
|
-
label?: string;
|
|
67
|
-
summary?: string;
|
|
70
|
+
line: string;
|
|
68
71
|
}>;
|
|
69
72
|
}
|
|
70
73
|
export interface StartedMonitor {
|
|
@@ -1,31 +1,18 @@
|
|
|
1
|
+
import type { UsageReceipt } from '../engines/engine.js';
|
|
1
2
|
import type { RecordedEngineUsage } from '../core/job.js';
|
|
2
|
-
import type { LoopEvent,
|
|
3
|
+
import type { LoopEvent, ResumedStageRecords } from '../core/types.js';
|
|
4
|
+
export type { RecordedStage, ResumedStageRecords } from '../core/types.js';
|
|
3
5
|
interface RecorderOptions {
|
|
4
6
|
thin?: boolean;
|
|
5
7
|
/** Append to the existing record instead of truncating it. */
|
|
6
8
|
resume?: boolean;
|
|
7
9
|
}
|
|
8
|
-
export type RecordedStage = {
|
|
9
|
-
readonly kind: 'interrupted';
|
|
10
|
-
readonly startLine: number;
|
|
11
|
-
} | {
|
|
12
|
-
readonly kind: 'completed';
|
|
13
|
-
readonly outcome: Outcome;
|
|
14
|
-
};
|
|
15
|
-
export interface ResumedStageRecords {
|
|
16
|
-
readonly anchors: ReadonlyMap<string, {
|
|
17
|
-
readonly identity: string;
|
|
18
|
-
readonly workspace: string;
|
|
19
|
-
readonly recordId: string;
|
|
20
|
-
}>;
|
|
21
|
-
readonly stages: ReadonlyMap<string, RecordedStage>;
|
|
22
|
-
}
|
|
23
10
|
/** Read the latest stage state and the engine answers recorded for each stage.
|
|
24
11
|
* A missing record has no stage state, so resume starts fresh. */
|
|
25
12
|
export declare function readResumeRecord(path: string): {
|
|
13
|
+
readonly receipts: readonly UsageReceipt[];
|
|
26
14
|
readonly outcomes: ResumedStageRecords;
|
|
27
15
|
readonly usage: ReadonlyMap<string, readonly RecordedEngineUsage[]>;
|
|
28
16
|
};
|
|
29
17
|
/** Append every durable event as one JSON line. */
|
|
30
18
|
export declare function makeRecorder(path: string, options?: RecorderOptions): (event: LoopEvent) => void;
|
|
31
|
-
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { LoopEvent } from '../core/types.js';
|
|
2
|
+
export interface RecordLine {
|
|
3
|
+
readonly kind: string;
|
|
4
|
+
readonly text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RecordEngineCall {
|
|
7
|
+
readonly model: string;
|
|
8
|
+
readonly inputTokens: number | null;
|
|
9
|
+
readonly outputTokens: number | null;
|
|
10
|
+
}
|
|
11
|
+
export interface RecordToolUse {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly count: number;
|
|
14
|
+
readonly targets: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
export interface RecordKickback {
|
|
17
|
+
readonly from: string;
|
|
18
|
+
readonly to: string;
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
readonly count: number;
|
|
21
|
+
readonly limit: number;
|
|
22
|
+
readonly accepted: boolean;
|
|
23
|
+
readonly note?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface RecordOutcome {
|
|
26
|
+
readonly status: string;
|
|
27
|
+
readonly summary?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface RecordNodeRun {
|
|
30
|
+
readonly attempt: number;
|
|
31
|
+
readonly startedAt: number | null;
|
|
32
|
+
readonly endedAt: number | null;
|
|
33
|
+
readonly outcome: RecordOutcome | null;
|
|
34
|
+
readonly kickback: RecordKickback | null;
|
|
35
|
+
readonly engineCalls: readonly RecordEngineCall[];
|
|
36
|
+
readonly tools: readonly RecordToolUse[];
|
|
37
|
+
readonly lines: readonly RecordLine[];
|
|
38
|
+
}
|
|
39
|
+
export interface RecordNodeSummary {
|
|
40
|
+
readonly node: string;
|
|
41
|
+
readonly runs: readonly RecordNodeRun[];
|
|
42
|
+
}
|
|
43
|
+
export interface RecordUsage {
|
|
44
|
+
readonly inputTokens: number;
|
|
45
|
+
readonly outputTokens: number;
|
|
46
|
+
readonly cacheReadInputTokens: number;
|
|
47
|
+
readonly unmeasuredCalls: number;
|
|
48
|
+
}
|
|
49
|
+
export interface RecordSummary {
|
|
50
|
+
readonly name: string | null;
|
|
51
|
+
readonly startedAt: number | null;
|
|
52
|
+
readonly endedAt: number | null;
|
|
53
|
+
readonly outcome: RecordOutcome | null;
|
|
54
|
+
readonly usage: RecordUsage;
|
|
55
|
+
readonly monitor: string | null;
|
|
56
|
+
readonly nodes: readonly RecordNodeSummary[];
|
|
57
|
+
readonly lines: readonly RecordLine[];
|
|
58
|
+
}
|
|
59
|
+
export interface RenderRecordOptions {
|
|
60
|
+
readonly lineWidth?: number;
|
|
61
|
+
}
|
|
62
|
+
export declare function summarizeRecord(events: readonly LoopEvent[]): RecordSummary;
|
|
63
|
+
export declare function formatDuration(ms: number): string;
|
|
64
|
+
export declare function renderRecord(events: readonly LoopEvent[], options?: RenderRecordOptions): string;
|
|
65
|
+
export declare function readRecordFile(path: string): {
|
|
66
|
+
events: LoopEvent[];
|
|
67
|
+
unreadable: number;
|
|
68
|
+
};
|
package/dist/workflow-support.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { INVALID_TEAM_DECISION, assertDistinctSeats, outcomeFromAgentText, panelReviewers, requireNoFiles, requireNonEmptyFiles, seatIdentity, teamAgent } from './chunk-
|
|
1
|
+
export { INVALID_TEAM_DECISION, assertDistinctSeats, outcomeFromAgentText, panelReviewers, requireNoFiles, requireNonEmptyFiles, seatIdentity, teamAgent } from './chunk-G2OIKOUI.js';
|
|
2
2
|
import './chunk-NIBHM5I5.js';
|
|
3
3
|
import './chunk-5GLEABOU.js';
|
|
4
4
|
//# sourceMappingURL=workflow-support.js.map
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type TeamSeat } from '@obversa/api';
|
|
2
|
-
import type { Job, Outcome, ConditionInput } from './core/types.js';
|
|
2
|
+
import type { Job, Judge, Outcome, ConditionInput } from './core/types.js';
|
|
3
|
+
import { type InteractionBinding } from './core/interaction.js';
|
|
3
4
|
export interface BriefSource {
|
|
4
5
|
readonly brief: string;
|
|
5
6
|
readonly files?: readonly string[];
|
|
@@ -7,6 +8,7 @@ export interface BriefSource {
|
|
|
7
8
|
export interface PersonRole {
|
|
8
9
|
readonly kind: 'person';
|
|
9
10
|
readonly question: string;
|
|
11
|
+
readonly interaction?: InteractionBinding;
|
|
10
12
|
}
|
|
11
13
|
export type WorkflowRole = TeamSeat | readonly TeamSeat[] | PersonRole;
|
|
12
14
|
export interface WorkflowStageBase {
|
|
@@ -17,7 +19,13 @@ export interface WorkflowStageBase {
|
|
|
17
19
|
readonly optional?: boolean;
|
|
18
20
|
readonly needs?: string | readonly string[];
|
|
19
21
|
readonly sendsBackTo?: string;
|
|
20
|
-
|
|
22
|
+
/**
|
|
23
|
+
* How many more rounds a reviewed stage or a kickback target gets: a plain
|
|
24
|
+
* count, or `judge(seat, { cap, questions })` to let a seat decide between
|
|
25
|
+
* a review's verdict and the send-back, with `cap` as the hard backstop
|
|
26
|
+
* that stops it regardless of what the judge says.
|
|
27
|
+
*/
|
|
28
|
+
readonly refine?: number | Judge;
|
|
21
29
|
/** An interrupted attempt may run again without a person's reconciliation. */
|
|
22
30
|
readonly retrySafe?: boolean;
|
|
23
31
|
}
|
|
@@ -27,22 +35,32 @@ export type WorkflowStage = WorkflowStageBase & {} & ({
|
|
|
27
35
|
readonly run?: never;
|
|
28
36
|
readonly panel?: never;
|
|
29
37
|
readonly input?: never;
|
|
38
|
+
readonly fn?: never;
|
|
30
39
|
} | {
|
|
31
40
|
readonly run: string | readonly string[];
|
|
32
41
|
readonly agent?: never;
|
|
33
42
|
readonly panel?: never;
|
|
34
43
|
readonly input?: never;
|
|
44
|
+
readonly fn?: never;
|
|
35
45
|
} | {
|
|
36
46
|
readonly panel: string;
|
|
37
47
|
readonly agree?: number;
|
|
38
48
|
readonly agent?: never;
|
|
39
49
|
readonly run?: never;
|
|
40
50
|
readonly input?: never;
|
|
51
|
+
readonly fn?: never;
|
|
41
52
|
} | {
|
|
42
53
|
readonly input: string;
|
|
43
54
|
readonly agent?: never;
|
|
44
55
|
readonly run?: never;
|
|
45
56
|
readonly panel?: never;
|
|
57
|
+
readonly fn?: never;
|
|
58
|
+
} | {
|
|
59
|
+
readonly fn: Job;
|
|
60
|
+
readonly agent?: never;
|
|
61
|
+
readonly run?: never;
|
|
62
|
+
readonly panel?: never;
|
|
63
|
+
readonly input?: never;
|
|
46
64
|
});
|
|
47
65
|
export interface NamedStage {
|
|
48
66
|
readonly name: string;
|
|
@@ -68,6 +86,8 @@ export interface WorkflowConfig {
|
|
|
68
86
|
};
|
|
69
87
|
}
|
|
70
88
|
export declare function briefFromFile(path: string | URL): BriefSource;
|
|
71
|
-
export declare function person(question: string
|
|
89
|
+
export declare function person(question: string, options?: {
|
|
90
|
+
interaction?: InteractionBinding;
|
|
91
|
+
}): PersonRole;
|
|
72
92
|
export declare function stage(name: string, config: WorkflowStage): NamedStage;
|
|
73
93
|
export declare function workflow(name: string, config: WorkflowConfig): Job;
|