@opengeni/react 0.34.1 → 0.34.3
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/{chunk-A2WITZTI.js → chunk-4NMH6UJ3.js} +2 -2
- package/dist/{chunk-GZ4KR67U.js → chunk-ALA3UGWB.js} +2 -2
- package/dist/chunk-ATSTR5P3.js +138 -0
- package/dist/chunk-ATSTR5P3.js.map +1 -0
- package/dist/{chunk-KZRUYCL4.js → chunk-FT2TXNGZ.js} +5 -2
- package/dist/chunk-FT2TXNGZ.js.map +1 -0
- package/dist/{chunk-4QOQ2DSR.js → chunk-LAKLF4PA.js} +14 -1
- package/dist/chunk-LAKLF4PA.js.map +1 -0
- package/dist/{chunk-TCCE5ZU5.js → chunk-MEGI4FS6.js} +38 -9
- package/dist/chunk-MEGI4FS6.js.map +1 -0
- package/dist/{chunk-MS3FBZ6A.js → chunk-PVW56EVR.js} +105 -62
- package/dist/chunk-PVW56EVR.js.map +1 -0
- package/dist/{chunk-L7R5RK6A.js → chunk-QRYJCWGD.js} +1199 -897
- package/dist/chunk-QRYJCWGD.js.map +1 -0
- package/dist/components/chat-composer.d.ts +2 -1
- package/dist/components/composer.d.ts +8 -2
- package/dist/components/copy-button.d.ts +4 -2
- package/dist/components/tip-follow.d.ts +3 -0
- package/dist/composer.d.ts +2 -1
- package/dist/composer.js +4 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +106 -101
- package/dist/index.js.map +1 -1
- package/dist/lib/format.d.ts +2 -0
- package/dist/machines.js +2 -2
- package/dist/session-ui.js +4 -3
- package/dist/session.js +4 -4
- package/dist/timeline/index.d.ts +1 -1
- package/dist/timeline/parsers.d.ts +5 -0
- package/dist/timeline/projection.d.ts +1 -12
- package/dist/timeline/tool-display-name.d.ts +17 -6
- package/dist/workstream-control-event.d.ts +6 -0
- package/package.json +1 -1
- package/src/components/chat-composer.tsx +1 -1
- package/src/components/composer-transcription-control.tsx +70 -57
- package/src/components/composer.tsx +197 -126
- package/src/components/copy-button.tsx +27 -8
- package/src/components/message-timeline.tsx +236 -39
- package/src/components/tip-follow.ts +15 -0
- package/src/composer.ts +1 -1
- package/src/hooks/use-composer.ts +7 -1
- package/src/hooks/use-workspace-capture.ts +6 -0
- package/src/index.ts +2 -1
- package/src/lib/format.ts +14 -0
- package/src/timeline/index.ts +2 -0
- package/src/timeline/parsers.ts +18 -1
- package/src/timeline/projection.ts +50 -20
- package/src/timeline/registry.ts +15 -2
- package/src/timeline/shared.tsx +30 -28
- package/src/timeline/tool-display-name.ts +30 -11
- package/src/timeline/tool-renderers.tsx +347 -16
- package/src/timeline/turn-summary.tsx +5 -2
- package/src/workstream-control-event.ts +6 -0
- package/dist/chunk-4QOQ2DSR.js.map +0 -1
- package/dist/chunk-KZRUYCL4.js.map +0 -1
- package/dist/chunk-L7R5RK6A.js.map +0 -1
- package/dist/chunk-MS3FBZ6A.js.map +0 -1
- package/dist/chunk-TCCE5ZU5.js.map +0 -1
- /package/dist/{chunk-A2WITZTI.js.map → chunk-4NMH6UJ3.js.map} +0 -0
- /package/dist/{chunk-GZ4KR67U.js.map → chunk-ALA3UGWB.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/timeline/tool-display-name.ts","../src/timeline/projection.ts"],"sourcesContent":["/**\n * MCP / first-party tool naming helpers.\n *\n * Wire names are often `<serverId>__<toolName>` (see prefixedMcpToolName).\n * Matching and titles must use the leaf tool name so `opengeni__session_create`\n * and bare `session_create` resolve the same UI — without inventing previews\n * from argument JSON.\n */\n\n/** Leaf tool name after the first `__` server boundary (or the whole name). */\nexport function mcpToolLeaf(name: string): string {\n const boundary = name.indexOf(\"__\");\n return boundary >= 0 ? name.slice(boundary + 2) : name;\n}\n\n/**\n * True when `wireName` is exactly `leaf` or ends with `__${leaf}` (MCP prefix).\n * Does not treat arbitrary suffixes as matches — the leaf must be the full\n * right-hand side after `__`.\n */\nexport function toolMatchesLeaf(wireName: string, leaf: string): boolean {\n return wireName === leaf || wireName.endsWith(`__${leaf}`);\n}\n\n/**\n * Readable label for a tool call (\"session_create\" / \"opengeni__session_create\"\n * → \"Session create\"). Title-cases the first character of the leaf phrase.\n */\nexport function toolDisplayName(name: string): string {\n const phrase = mcpToolLeaf(name).replace(/[_-]+/g, \" \").trim();\n if (!phrase) {\n return name;\n }\n return phrase.charAt(0).toUpperCase() + phrase.slice(1);\n}\n","import type { SessionEvent, SessionStatus } from \"@opengeni/sdk\";\nconst { default: fleetDecisionItem } = await import(\"./fleet-decision-projection\");\nimport {\n CREDIT_EXHAUSTION_MESSAGE,\n humanizeFailureReason,\n isCreditExhaustion,\n tryParseJson,\n} from \"../lib/format\";\nimport { mcpToolLeaf, toolMatchesLeaf } from \"./tool-display-name\";\nimport type {\n AgentMessageItem,\n ActivityItem,\n AuthNeededItem,\n ContextCompactionItem,\n GoalItem,\n MachineInputBatchItem,\n MemoryItem,\n SandboxItem,\n SessionStatusItem,\n TimelineGroup,\n TimelineItem,\n TurnEndItem,\n ToolCallItem,\n WorkerItem,\n} from \"./types\";\n\nexport { toolDisplayName, mcpToolLeaf, toolMatchesLeaf } from \"./tool-display-name\";\n\n/* ----------------------------------------------------------------------------\n Timeline projection\n\n `buildTimeline` folds a session's raw event log (replayed + live, ordered by\n sequence) into renderable items: chat messages with accumulated streaming\n deltas, reasoning summaries, tool calls matched to their outputs, sandbox\n operations with command output, spawned-worker status (the manager's\n `session_create` / `session_send_message` orchestration calls), goal\n markers, status changes, and turn failures.\n\n It is a pure function — same events in, same items out — so it can be\n memoized, unit-tested, and re-run incrementally as new events stream in.\n -------------------------------------------------------------------------- */\n\n/** Tool leaves on the first-party OpenGeni MCP server that operate on sessions. */\nconst WORKER_SPAWN_TOOL = \"session_create\";\nconst WORKER_MESSAGE_TOOL = \"session_send_message\";\n\n/**\n * Tools whose durable side-effect events already own the timeline (MemoryRow).\n * Emitting a generic tool-call too is double chrome — skip the call.\n *\n * Goal tools are intentionally NOT landmark-only: an agent `goal_set` /\n * `goal_update` / `goal_complete` / `goal_pause` stays an in-cluster tool row,\n * and the matching `goal.*` session event is suppressed below when `actor` is\n * `\"agent\"`. That keeps mid-turn goal tools from splitting the step rail with\n * a breakaway GoalRow pill. Non-agent goal events (API, create-session,\n * system auto-pause, continuations) still render as landmarks.\n */\nconst LANDMARK_ONLY_TOOL_LEAVES = new Set([\"memory_save\", \"memory_correct\"]);\n\nexport function buildTimeline(events: SessionEvent[]): TimelineItem[] {\n const items: TimelineItem[] = [];\n const prescan = prescanTurnAnchors(events);\n const ordered = orderTimelineEvents(events, prescan);\n\n const last = (): TimelineItem | undefined => items[items.length - 1];\n\n /** A new item of a different kind ends whatever was streaming at the tail. */\n const closeStreamingTail = (): void => {\n const open = last();\n if ((open?.kind === \"agent-message\" || open?.kind === \"reasoning\") && open.streaming) {\n open.streaming = false;\n }\n };\n\n const finalizeOpen = (\n turnId?: string | null,\n disposition: \"complete\" | \"failed\" | \"cancelled\" = \"complete\",\n ): void => {\n for (const item of items) {\n if (\n turnId !== undefined &&\n \"turnId\" in item &&\n item.turnId &&\n turnId &&\n item.turnId !== turnId\n ) {\n continue;\n }\n if ((item.kind === \"agent-message\" || item.kind === \"reasoning\") && item.streaming) {\n item.streaming = false;\n }\n if ((item.kind === \"tool-call\" || item.kind === \"worker\") && item.status === \"running\") {\n item.status = disposition;\n }\n if (item.kind === \"sandbox\" && item.status === \"running\") {\n item.status = disposition;\n }\n }\n };\n\n for (const event of ordered) {\n const payload = asRecord(event.payload);\n const turnId = event.turnId ?? null;\n\n switch (event.type) {\n case \"user.message\": {\n // A steering message must not mark in-flight tools complete; it only\n // ends whatever text was streaming. Turn lifecycle events finalize.\n closeStreamingTail();\n const childCompletion = workerCompletionPayload(payload.childCompletion);\n if (childCompletion) {\n items.push({\n kind: \"worker-completion\",\n id: event.id,\n turnId,\n occurredAt: event.occurredAt,\n childSessionId: childCompletion.childSessionId,\n childStatus: childCompletion.childStatus,\n goalStatus: childCompletion.goalStatus,\n goalText: childCompletion.goalText,\n evidence: childCompletion.evidence,\n pausedReason: childCompletion.pausedReason,\n text: stringValue(payload.text),\n });\n break;\n }\n items.push({\n kind: \"user-message\",\n id: event.id,\n text: stringValue(payload.text),\n resources: resourceRefs(payload.resources),\n tools: toolRefs(payload.tools),\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"system.update.delivered\": {\n const inputs = machineInputMembers(payload.members);\n if (inputs.length === 0) break;\n closeStreamingTail();\n items.push({\n kind: \"machine-input-batch\",\n id: event.id,\n turnId,\n members: inputs,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"agent.message.delta\": {\n const text = stringValue(payload.text);\n if (!text) {\n break;\n }\n const open = last();\n if (open?.kind === \"agent-message\" && open.streaming && open.turnId === turnId) {\n open.text += text;\n break;\n }\n closeStreamingTail();\n items.push({\n kind: \"agent-message\",\n id: event.id,\n turnId,\n text,\n streaming: true,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"agent.message.completed\": {\n const text = stringValue(payload.text);\n // Reconcile the most recent same-turn agent message — even when\n // activity (tool calls, reasoning) landed after its deltas — so the\n // completed text never duplicates the streamed one.\n let openIndex = -1;\n for (let index = items.length - 1; index >= 0; index -= 1) {\n const candidate = items[index];\n if (candidate?.kind === \"agent-message\" && candidate.turnId === turnId) {\n openIndex = index;\n break;\n }\n }\n const candidate = openIndex >= 0 ? items[openIndex] : undefined;\n const open: AgentMessageItem | undefined =\n candidate?.kind === \"agent-message\" ? candidate : undefined;\n if (\n open &&\n (open.streaming || !open.text || text === open.text || text.startsWith(open.text))\n ) {\n // The completed text is authoritative when it extends what streamed.\n if (!open.text || (text && text.startsWith(open.text))) {\n open.text = text || open.text;\n }\n open.streaming = false;\n // Completion time is what the footer shows (\"finished at\"); keep the\n // first-delta stamp only until this event arrives.\n open.occurredAt = event.occurredAt;\n // The SDK can emit a hosted-tool item only after its provider-native\n // operation has completed, even though answer deltas were already\n // streamed. The completed message event is the durable ordering\n // authority, so move the reconciled row after any intervening tool\n // activity instead of leaving completed web searches below the answer.\n if (openIndex < items.length - 1) {\n items.splice(openIndex, 1);\n items.push(open);\n }\n break;\n }\n if (text) {\n items.push({\n kind: \"agent-message\",\n id: event.id,\n turnId,\n text,\n streaming: false,\n occurredAt: event.occurredAt,\n });\n }\n break;\n }\n\n case \"agent.reasoning.delta\": {\n const text = reasoningText(event.payload);\n if (!text) {\n break;\n }\n const open = last();\n if (open?.kind === \"reasoning\" && open.streaming && open.turnId === turnId) {\n open.text += text;\n break;\n }\n closeStreamingTail();\n items.push({\n kind: \"reasoning\",\n id: event.id,\n turnId,\n text,\n streaming: true,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"agent.toolCall.created\": {\n const name = typeof payload.name === \"string\" ? payload.name : \"tool\";\n const callId = typeof payload.id === \"string\" ? payload.id : null;\n const args = payload.arguments ?? null;\n closeStreamingTail();\n if (\n toolMatchesLeaf(name, WORKER_SPAWN_TOOL) ||\n toolMatchesLeaf(name, WORKER_MESSAGE_TOOL)\n ) {\n items.push({\n kind: \"worker\",\n id: event.id,\n turnId,\n callId,\n action: toolMatchesLeaf(name, WORKER_SPAWN_TOOL) ? \"spawn\" : \"message\",\n prompt: workerPrompt(args),\n workerSessionId: extractSessionRef(args),\n status: \"running\",\n occurredAt: event.occurredAt,\n });\n break;\n }\n if (LANDMARK_ONLY_TOOL_LEAVES.has(mcpToolLeaf(name))) {\n // Goal/memory landmarks arrive as goal.* / memory.* events.\n break;\n }\n // Live Responses `web_search_call` events and the later SDK\n // `RunToolCallItem` share the same item id. Merge so mid-stream cards\n // do not duplicate when the step finally materializes.\n if (callId) {\n const existing = [...items]\n .reverse()\n .find(\n (item): item is ToolCallItem => item.kind === \"tool-call\" && item.callId === callId,\n );\n if (existing) {\n if (args != null) {\n existing.arguments = args;\n }\n if (payload.raw !== undefined) {\n existing.raw = mergeToolCallRaw(existing.raw, payload.raw);\n }\n existing.status = providerNativeToolStatus(existing.raw);\n break;\n }\n }\n items.push({\n kind: \"tool-call\",\n id: event.id,\n turnId,\n callId,\n name,\n arguments: args,\n output: undefined,\n // The provider-native item drives the per-tool renderers (apply_patch\n // operation, computer_call action, web_search providerData, …).\n raw: payload.raw,\n status: providerNativeToolStatus(payload.raw),\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"agent.toolCall.output\": {\n const callId = typeof payload.id === \"string\" ? payload.id : null;\n const target = findOpenCall(items, callId);\n if (!target) {\n break;\n }\n if (target.kind === \"worker\") {\n // A worker spawn/message that returns an error flag (or an MCP\n // isError result) settles to \"failed\" too, so WorkerRow surfaces it.\n target.status = isErrorOutput(payload) ? \"failed\" : \"complete\";\n target.workerSessionId = target.workerSessionId ?? extractSessionRef(payload.output);\n break;\n }\n // An output carrying an explicit error flag (or an MCP isError result)\n // settles the tool to \"failed\" so the renderer can surface it loudly.\n target.status = isErrorOutput(payload) ? \"failed\" : \"complete\";\n target.output = payload.output;\n break;\n }\n\n case \"sandbox.operation.started\":\n case \"sandbox.operation.completed\":\n case \"sandbox.operation.failed\": {\n const name = typeof payload.name === \"string\" ? payload.name : \"sandbox\";\n const status = event.type.endsWith(\".failed\")\n ? \"failed\"\n : event.type.endsWith(\".completed\")\n ? \"complete\"\n : \"running\";\n // Routine per-turn platform plumbing that runs before EVERY turn to\n // guarantee box contents survive a re-warm — NOT the agent redoing work:\n // - repository-clone: idempotent clone check + off-manifest token re-seed;\n // - file-resource-download: idempotent `if [ ! -f ] then curl` (skips\n // when the attached file is already on the box — see\n // sandboxFileDownloadCommand), so an uploaded image is not re-fetched;\n // the operation still emits every turn even when it does nothing.\n // Rendering either every turn reads as churn. Only FAILURES surface, and\n // they surface loudly — the failed event below creates its own item even\n // without a started row.\n if (\n (name === \"repository-clone\" || name === \"file-resource-download\") &&\n status !== \"failed\"\n ) {\n break;\n }\n const existing = findOpenSandbox(items, name);\n if (existing && status !== \"running\") {\n existing.status = status;\n if (\n payload.origin === \"created\" ||\n payload.origin === \"restored\" ||\n payload.origin === \"resumed\"\n ) {\n existing.origin = payload.origin;\n }\n const message = failureMessage(payload);\n if (message) {\n existing.output = existing.output ? `${existing.output}\\n${message}` : message;\n }\n break;\n }\n if (!existing) {\n closeStreamingTail();\n items.push({\n kind: \"sandbox\",\n id: event.id,\n turnId,\n name,\n command: typeof payload.command === \"string\" ? payload.command : null,\n output: failureMessage(payload) ?? \"\",\n origin:\n payload.origin === \"created\" ||\n payload.origin === \"restored\" ||\n payload.origin === \"resumed\"\n ? payload.origin\n : null,\n status,\n occurredAt: event.occurredAt,\n });\n }\n break;\n }\n\n case \"sandbox.command.output.delta\": {\n // `chunk` is the canonical wire field; text/output are legacy shapes.\n const text =\n typeof payload.chunk === \"string\"\n ? payload.chunk\n : typeof payload.text === \"string\"\n ? payload.text\n : typeof payload.output === \"string\"\n ? payload.output\n : \"\";\n if (!text) {\n break;\n }\n // Attach to the named operation when the payload carries one;\n // otherwise the latest running operation is the best available owner.\n const open =\n (typeof payload.name === \"string\" ? findOpenSandbox(items, payload.name) : undefined) ??\n [...items]\n .reverse()\n .find(\n (item): item is SandboxItem => item.kind === \"sandbox\" && item.status === \"running\",\n );\n if (open) {\n open.output += text;\n }\n break;\n }\n\n case \"session.status.changed\": {\n const status = payload.status;\n if (!isSessionStatus(status)) {\n break;\n }\n // Only attention-worthy statuses earn a timeline divider. queued /\n // running / idle are machinery telemetry: the header pill carries the\n // live status, the shimmer says \"running\", and the turn chip's duration\n // facet says how long — a stale \"idle · 27s\" row is pure noise,\n // especially in historical traces.\n if (!ATTENTION_STATUSES.has(status)) {\n break;\n }\n const previous = [...items]\n .reverse()\n .find((item): item is SessionStatusItem => item.kind === \"session-status\");\n if (previous?.status === status) {\n break;\n }\n items.push({\n kind: \"session-status\",\n id: event.id,\n status,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"session.requiresAction\": {\n finalizeOpen(turnId);\n items.push({\n kind: \"notice\",\n id: event.id,\n tone: \"waiting\",\n text: \"Approval needed — the turn is paused until someone decides.\",\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"session.context.compaction.requested\":\n case \"session.context.compaction.started\": {\n closeStreamingTail();\n settleOrPushContextCompaction(items, {\n id: event.id,\n turnId,\n phase: \"started\",\n trigger: compactionTrigger(payload),\n estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),\n estimatedTokensAfter: null,\n skipReason: null,\n implementation:\n typeof payload.implementation === \"string\" ? payload.implementation : null,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"session.context.compacted\": {\n closeStreamingTail();\n settleOrPushContextCompaction(items, {\n id: event.id,\n turnId,\n phase: \"compacted\",\n trigger: compactionTrigger(payload),\n estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),\n estimatedTokensAfter: numberOrNull(payload.estimatedTokensAfter),\n skipReason: null,\n implementation:\n typeof payload.implementation === \"string\" ? payload.implementation : null,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"session.context.compaction.skipped\": {\n closeStreamingTail();\n settleOrPushContextCompaction(items, {\n id: event.id,\n turnId,\n phase: \"skipped\",\n trigger: compactionTrigger(payload),\n estimatedTokensBefore: numberOrNull(payload.estimatedTokensBefore),\n estimatedTokensAfter: null,\n skipReason: typeof payload.reason === \"string\" ? payload.reason : null,\n implementation:\n typeof payload.implementation === \"string\" ? payload.implementation : null,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"turn.recovery.requested\": {\n // Recovery requests are durable control-plane evidence, not a user\n // message or proof that recovery succeeded. Live state already exposes\n // a genuinely recovering session; keep the raw event in Debug/audit.\n break;\n }\n\n case \"turn.event.rejected_late\": {\n // Attempt-fence rejections prove stale callbacks did not alter current\n // truth. They are useful diagnostics but never actionable chat content,\n // regardless of the rejected event type. Debug/audit retains the event.\n break;\n }\n\n case \"tool.auth_needed\":\n case \"credential.auth_needed\": {\n // Keep the whole structured payload — the renderer turns it into a clean\n // inline reconnect card, and the app starts the recovery flow off the\n // connectionId/resource. Losing it to a plain-text notice was the ugly\n // \"linear.app needs to be reconnected.\" line users complained about.\n closeStreamingTail();\n items.push({\n kind: \"auth-needed\",\n id: event.id,\n turnId,\n providerDomain: stringValue(payload.providerDomain),\n connectionId: typeof payload.connectionId === \"string\" ? payload.connectionId : null,\n reason: authNeededReason(payload.reason),\n scopes: stringList(payload.scopes),\n resource: typeof payload.resource === \"string\" ? payload.resource : null,\n toolName: typeof payload.toolName === \"string\" ? payload.toolName : null,\n authorizationUrl:\n typeof payload.authorizationUrl === \"string\" ? payload.authorizationUrl : null,\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n case \"turn.completed\": {\n // A standalone manual compaction uses the turn ledger for fencing and\n // recovery, but it is maintenance rather than a conversational turn.\n // The dedicated context-compaction landmark is the complete UI truth;\n // adding a generic turn chip would falsely make it look like an\n // extra agent response.\n if (payload.maintenance === \"context_compaction\") {\n finalizeOpen(turnId);\n break;\n }\n // Credit exhaustion arrives as a NOMINALLY completed turn (`detail:\n // \"insufficient OpenGeni credits\"`, `segmentLimit: \"budget_exhausted\"`)\n // — the engine ended the segment early, it did not finish the work.\n // Rendering it as a clean \"complete\" turn is a lie that leaves the\n // session looking healthy while every future turn silently dies, so it\n // projects exactly like a failed turn plus an explicit notice.\n if (isCreditExhaustionPayload(payload)) {\n finalizeOpen(turnId);\n items.push(turnEndItem(event, \"failed\", CREDIT_EXHAUSTION_MESSAGE));\n items.push({\n kind: \"notice\",\n id: event.id,\n tone: \"failed\",\n text: CREDIT_EXHAUSTION_MESSAGE,\n occurredAt: event.occurredAt,\n });\n break;\n }\n finalizeOpen(turnId);\n items.push(turnEndItem(event, \"complete\", null));\n break;\n }\n\n case \"turn.failed\": {\n const hadActivity = hasTurnActivity(items, turnId);\n // Credit death can hide behind fields `failureMessage` doesn't read\n // (detail/segmentLimit), so classify the whole payload before falling\n // back to the generic error/message extraction.\n const failureText = isCreditExhaustionPayload(payload)\n ? CREDIT_EXHAUSTION_MESSAGE\n : failureMessage(payload);\n // The TURN failed — the in-flight items did not. Chip doctrine: red is\n // spent once, on the turn-level outcome. Items caught mid-flight read\n // as calm \"interrupted\" (same as turn.cancelled); an item that itself\n // failed keeps its own failed status from its output event.\n finalizeOpen(turnId, \"cancelled\");\n items.push(turnEndItem(event, \"failed\", failureText));\n if (!hadActivity) {\n items.push({\n kind: \"notice\",\n id: event.id,\n tone: \"failed\",\n text: failureText ?? \"The turn failed.\",\n occurredAt: event.occurredAt,\n });\n }\n break;\n }\n\n case \"turn.cancelled\": {\n // A retraction of a never-started queued turn is not a turn ending —\n // the message was withdrawn before any work happened; show nothing.\n // A null turnId proves nothing, so it keeps the legacy finalize path.\n if (turnId && !prescan.startedTurnIds.has(turnId)) {\n break;\n }\n const hadActivity = hasTurnActivity(items, turnId);\n finalizeOpen(turnId, \"cancelled\");\n items.push(turnEndItem(event, \"cancelled\", null));\n if (!hadActivity) {\n items.push({\n kind: \"notice\",\n id: event.id,\n tone: \"cancelled\",\n text: \"Interrupted.\",\n occurredAt: event.occurredAt,\n });\n }\n break;\n }\n\n case \"memory.saved\":\n case \"memory.corrected\": {\n // A first-party memory write is a discrete step, not streamed text, so it\n // ends whatever was streaming (mirrors tool/sandbox pushes). A payload\n // missing the memory id is malformed and dropped rather than shown blank.\n const memory = memoryItem(event.id, event.type, turnId, payload, event.occurredAt);\n if (memory) {\n closeStreamingTail();\n items.push(memory);\n }\n break;\n }\n\n case \"codex.fleet.decision\": {\n const decision = fleetDecisionItem(event, payload);\n if (decision) {\n closeStreamingTail();\n items.push(decision);\n }\n break;\n }\n\n case \"goal.set\":\n case \"goal.updated\":\n case \"goal.completed\":\n case \"goal.paused\":\n case \"goal.resumed\":\n case \"goal.cleared\":\n case \"goal.continuation\": {\n // Agent tool mutations already appear as tool-call rows in the activity\n // cluster. Re-emitting them as GoalRow landmarks splits \"N steps\" mid-turn.\n if (shouldSuppressAgentGoalLandmark(event.type, payload)) {\n break;\n }\n items.push({\n kind: \"goal\",\n id: event.id,\n action: event.type.slice(\"goal.\".length) as GoalItem[\"action\"],\n text: goalText(payload),\n occurredAt: event.occurredAt,\n });\n break;\n }\n\n default:\n break;\n }\n }\n\n for (const item of items) {\n if (item.kind === \"agent-message\") {\n item.text = stripOpaqueCitationTokens(item.text);\n }\n }\n return items;\n}\n\nfunction providerNativeToolStatus(rawValue: unknown): ToolCallItem[\"status\"] {\n const raw = asRecord(rawValue);\n if (raw.type !== \"hosted_tool_call\") {\n return \"running\";\n }\n switch (raw.status) {\n case \"completed\":\n return \"complete\";\n case \"failed\":\n case \"incomplete\":\n return \"failed\";\n case \"cancelled\":\n return \"cancelled\";\n default:\n return \"running\";\n }\n}\n\n/**\n * Prefer newer status/fields, but keep earlier providerData.action when a\n * progress-only Responses event arrives without the search query payload.\n */\nfunction mergeToolCallRaw(existingValue: unknown, nextValue: unknown): unknown {\n const existing = asRecord(existingValue);\n const next = asRecord(nextValue);\n if (Object.keys(next).length === 0) {\n return existingValue;\n }\n const existingProvider = asRecord(existing.providerData);\n const nextProvider = asRecord(next.providerData);\n const providerData = {\n ...existingProvider,\n ...nextProvider,\n };\n if (\n existingProvider.action != null &&\n (nextProvider.action == null ||\n (typeof nextProvider.action === \"object\" &&\n nextProvider.action !== null &&\n Object.keys(nextProvider.action as object).length === 0))\n ) {\n providerData.action = existingProvider.action;\n }\n return {\n ...existing,\n ...next,\n ...(Object.keys(providerData).length > 0 ? { providerData } : {}),\n };\n}\n\n/**\n * Codex subscription web search can return private citation handles without\n * the URL annotation table that would make them resolvable. Keep the canonical\n * model-history item untouched, but never expose those unusable handles in the\n * human timeline. Ordinary markdown links and structured URL citations remain.\n */\nexport function stripOpaqueCitationTokens(text: string): string {\n return text.replace(/\\s*cite(?:[^]+)+/gu, \"\");\n}\n\n/** The turn-end payload shape, as `isCreditExhaustion` wants it. */\nfunction isCreditExhaustionPayload(payload: Record<string, unknown>): boolean {\n return isCreditExhaustion({\n error: typeof payload.error === \"string\" ? payload.error : null,\n detail: typeof payload.detail === \"string\" ? payload.detail : null,\n segmentLimit: typeof payload.segmentLimit === \"string\" ? payload.segmentLimit : null,\n });\n}\n\n/**\n * Whether the session's most recent turn ended in credit exhaustion — the\n * terminal credit state apps key their \"add credits\" affordances on. Derived\n * from the LAST turn-end event (completed/failed/cancelled): a later turn that\n * settles any other way (someone topped up and kept working) clears it.\n */\nexport function creditExhaustedFromEvents(events: SessionEvent[]): boolean {\n const ordered = [...events].sort((a, b) => a.sequence - b.sequence);\n for (let index = ordered.length - 1; index >= 0; index -= 1) {\n const event = ordered[index];\n if (\n event?.type !== \"turn.completed\" &&\n event?.type !== \"turn.failed\" &&\n event?.type !== \"turn.cancelled\"\n ) {\n continue;\n }\n return isCreditExhaustionPayload(asRecord(event.payload));\n }\n return false;\n}\n\n/** The latest session status carried in the event log, if any. */\nexport function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus | null {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n if (event?.type !== \"session.status.changed\") {\n continue;\n }\n const status = asRecord(event.payload).status;\n if (isSessionStatus(status)) {\n return status;\n }\n }\n return null;\n}\n\n/* ----------------------------------------------------------------------------\n Visual grouping: consecutive activity items (reasoning / tools / workers /\n sandbox) cluster into collapsible blocks. Once a turn settles, the full\n non-user span folds behind a turn group, with activity blocks nested inside.\n -------------------------------------------------------------------------- */\n\n/**\n * Whether an item clusters into an activity block. A `switch` (not a stringly-\n * typed set) so adding an {@link ActivityItem} kind is a compile-time prompt to\n * decide its grouping — and it narrows `item` to `ActivityItem` with no cast.\n */\nfunction isActivityItem(item: TimelineItem): item is ActivityItem {\n switch (item.kind) {\n case \"reasoning\":\n case \"tool-call\":\n case \"worker\":\n case \"sandbox\":\n case \"memory\":\n case \"fleet-decision\":\n return true;\n default:\n return false;\n }\n}\n\nexport function groupTimeline(items: TimelineItem[]): TimelineGroup[] {\n const groups: TimelineGroup[] = [];\n for (const item of items) {\n if (isActivityItem(item)) {\n const open = groups[groups.length - 1];\n if (open?.kind === \"activity\" && open.outcome === undefined) {\n open.items.push(item);\n } else {\n groups.push({\n kind: \"activity\",\n id: `activity-${item.id}`,\n items: [item],\n });\n }\n continue;\n }\n if (item.kind === \"turn-end\") {\n stampTurnOutcome(groups, item);\n foldSettledTurn(groups, item);\n continue;\n }\n groups.push({ kind: \"item\", item });\n }\n return groups;\n}\n\n/* --- helpers ---------------------------------------------------------------- */\n\ntype TurnAnchorPrescan = {\n queuedTurnByTrigger: Map<string, string>;\n startSeqByTrigger: Map<string, number>;\n cancelledBeforeStartTriggers: Set<string>;\n startedTurnIds: Set<string>;\n};\n\nfunction prescanTurnAnchors(events: SessionEvent[]): TurnAnchorPrescan {\n const ordered = [...events].sort((a, b) => a.sequence - b.sequence);\n const queuedTurnByTrigger = new Map<string, string>();\n const startSeqByTrigger = new Map<string, number>();\n const cancelledTurnIds = new Set<string>();\n const fallbackSeqByTurn = new Map<string, number>();\n const startedTurnIds = new Set<string>();\n\n for (const event of ordered) {\n const payload = asRecord(event.payload);\n const turnId = event.turnId ?? null;\n if (event.type === \"turn.queued\") {\n const triggerEventId =\n typeof payload.triggerEventId === \"string\" ? payload.triggerEventId : null;\n const queuedTurnId = typeof payload.turnId === \"string\" ? payload.turnId : turnId;\n if (triggerEventId && queuedTurnId) {\n queuedTurnByTrigger.set(triggerEventId, queuedTurnId);\n }\n continue;\n }\n if (event.type === \"turn.started\") {\n const triggerEventId =\n typeof payload.triggerEventId === \"string\" ? payload.triggerEventId : null;\n if (triggerEventId && !startSeqByTrigger.has(triggerEventId)) {\n startSeqByTrigger.set(triggerEventId, event.sequence);\n }\n if (turnId) {\n startedTurnIds.add(turnId);\n }\n } else if (event.type === \"turn.cancelled\" && turnId) {\n cancelledTurnIds.add(turnId);\n }\n\n if (turnId && isTurnExecutionEvidence(event.type)) {\n const previous = fallbackSeqByTurn.get(turnId);\n if (previous === undefined || event.sequence < previous) {\n fallbackSeqByTurn.set(turnId, event.sequence);\n }\n }\n if (turnId && isTurnExecutionEvidence(event.type)) {\n startedTurnIds.add(turnId);\n }\n }\n\n for (const [triggerEventId, turnId] of queuedTurnByTrigger) {\n if (!startSeqByTrigger.has(triggerEventId)) {\n const fallbackSeq = fallbackSeqByTurn.get(turnId);\n if (fallbackSeq !== undefined) {\n startSeqByTrigger.set(triggerEventId, fallbackSeq);\n }\n }\n }\n\n const cancelledBeforeStartTriggers = new Set<string>();\n for (const [triggerEventId, turnId] of queuedTurnByTrigger) {\n if (\n cancelledTurnIds.has(turnId) &&\n !startSeqByTrigger.has(triggerEventId) &&\n !fallbackSeqByTurn.has(turnId)\n ) {\n cancelledBeforeStartTriggers.add(triggerEventId);\n }\n }\n\n return {\n queuedTurnByTrigger,\n startSeqByTrigger,\n cancelledBeforeStartTriggers,\n startedTurnIds,\n };\n}\n\nfunction orderTimelineEvents(events: SessionEvent[], prescan: TurnAnchorPrescan): SessionEvent[] {\n const ordered = [...events].sort((a, b) => a.sequence - b.sequence);\n const insertions = new Map<number, SessionEvent[]>();\n\n for (const event of ordered) {\n if (event.type !== \"user.message\") {\n continue;\n }\n const queuedTurnId = prescan.queuedTurnByTrigger.get(event.id);\n if (!queuedTurnId) {\n pushInsertion(insertions, event.sequence, event);\n continue;\n }\n if (prescan.cancelledBeforeStartTriggers.has(event.id)) {\n continue;\n }\n const startSeq = prescan.startSeqByTrigger.get(event.id);\n if (startSeq !== undefined) {\n pushInsertion(insertions, startSeq, event);\n continue;\n }\n // A waiting prompt belongs only in the prompt queue. It enters the\n // timeline at turn.started (or the first same-turn activity fallback),\n // never as a second queued representation.\n }\n\n const projected: SessionEvent[] = [];\n for (const event of ordered) {\n const before = insertions.get(event.sequence);\n if (before) {\n projected.push(...before);\n }\n if (event.type !== \"user.message\") {\n projected.push(event);\n }\n }\n return projected;\n}\n\nfunction pushInsertion(\n insertions: Map<number, SessionEvent[]>,\n sequence: number,\n event: SessionEvent,\n): void {\n const bucket = insertions.get(sequence);\n if (bucket) {\n bucket.push(event);\n } else {\n insertions.set(sequence, [event]);\n }\n}\n\nfunction isAgentActivityEvent(type: string): boolean {\n return type.startsWith(\"agent.\") || type.startsWith(\"sandbox.\");\n}\n\n/**\n * Evidence that a queued prompt crossed the execution boundary when an older\n * or partially recovered ledger is missing its canonical `turn.started`.\n * Queue/control bookkeeping intentionally does not qualify: moving, editing,\n * steering, or deleting a waiting row must never make its prompt appear in the\n * transcript as though inference had begun.\n */\nfunction isTurnExecutionEvidence(type: string): boolean {\n return (\n isAgentActivityEvent(type) ||\n type === \"turn.completed\" ||\n type === \"turn.failed\" ||\n type === \"turn.recovery.requested\" ||\n type === \"turn.capacity_waiting\" ||\n type === \"session.requiresAction\" ||\n type === \"tool.auth_needed\" ||\n type === \"credential.auth_needed\" ||\n type.startsWith(\"rig.setup.\") ||\n type === \"codex.capacity.waiting\" ||\n type === \"codex.capacity.resumed\" ||\n type === \"codex.fleet.decision\"\n );\n}\n\nfunction turnEndItem(\n event: SessionEvent,\n outcome: TurnEndItem[\"outcome\"],\n failureText: string | null,\n): TurnEndItem {\n return {\n kind: \"turn-end\",\n id: `${event.id}-turn-end`,\n turnId: event.turnId ?? null,\n outcome,\n failureText,\n occurredAt: event.occurredAt,\n };\n}\n\nfunction hasTurnActivity(items: TimelineItem[], turnId: string | null): boolean {\n if (turnId) {\n return items.some((item) => isActivityItem(item) && item.turnId === turnId);\n }\n for (let index = items.length - 1; index >= 0; index -= 1) {\n const item = items[index];\n if (!item || item.kind === \"turn-end\" || item.kind === \"user-message\") {\n return false;\n }\n if (isActivityItem(item)) {\n return true;\n }\n }\n return false;\n}\n\nfunction stampTurnOutcome(groups: TimelineGroup[], turnEnd: TurnEndItem): void {\n if (turnEnd.turnId === null) {\n const trailing = groups[groups.length - 1];\n if (trailing?.kind === \"activity\" && trailing.outcome === undefined) {\n applyTurnOutcome(trailing, turnEnd);\n }\n return;\n }\n for (const group of groups) {\n if (group.kind !== \"activity\" || group.outcome !== undefined) {\n continue;\n }\n if (group.items.some((activity) => activity.turnId === turnEnd.turnId)) {\n applyTurnOutcome(group, turnEnd);\n }\n }\n}\n\nfunction applyTurnOutcome(\n group: Extract<TimelineGroup, { kind: \"activity\" }>,\n turnEnd: TurnEndItem,\n): void {\n // A sub-cluster reports ITS OWN outcome, not the turn's. When a turn fails\n // at step 7, clusters 1–6 completed — painting them all red says \"everything\n // broke\" when one thing did. The turn-level fold carries the turn outcome;\n // a cluster goes red only if an item inside it actually failed, and reads\n // \"cancelled\" (interrupted) only when it holds the items cut off mid-flight.\n if (turnEnd.outcome === \"complete\") {\n group.outcome = \"complete\";\n return;\n }\n const hasFailed = group.items.some((item) => \"status\" in item && item.status === \"failed\");\n const hasInterrupted = group.items.some(\n (item) => \"status\" in item && item.status === \"cancelled\",\n );\n group.outcome = hasFailed ? \"failed\" : hasInterrupted ? \"cancelled\" : \"complete\";\n if (turnEnd.failureText && hasFailed) {\n group.failureText = turnEnd.failureText;\n }\n}\n\nfunction foldSettledTurn(groups: TimelineGroup[], turnEnd: TurnEndItem): void {\n let startIndex = groups.length;\n let stoppedAtForeignTurn = false;\n while (startIndex > 0) {\n const previous = groups[startIndex - 1];\n if (isTurnBoundary(previous)) {\n break;\n }\n if (belongsToDifferentTurn(previous, turnEnd.turnId)) {\n stoppedAtForeignTurn = true;\n break;\n }\n startIndex -= 1;\n }\n if (stoppedAtForeignTurn) {\n while (startIndex < groups.length && isBetweenTurnDivider(groups[startIndex])) {\n startIndex += 1;\n }\n }\n\n const collected = groups.slice(startIndex);\n if (collected.length === 0) {\n return;\n }\n\n const finalMessage = extractFinalAgentMessage(collected, turnEnd);\n const body = finalMessage ? collected.slice(0, -1) : collected;\n if (body.length === 0) {\n return;\n }\n\n const firstOccurredAt = groupStartedAt(body[0]) ?? turnEnd.occurredAt;\n const prior = startIndex > 0 ? groups[startIndex - 1] : undefined;\n const contextCompactionCount =\n prior?.kind === \"item\" &&\n prior.item.kind === \"context-compaction\" &&\n prior.item.phase === \"compacted\"\n ? 1\n : 0;\n const turnGroup: TimelineGroup = {\n kind: \"turn\",\n id: `turn-${turnEnd.turnId ?? turnEnd.id}`,\n outcome: turnEnd.outcome,\n startedAt: firstOccurredAt,\n endedAt: turnEnd.occurredAt,\n groups: body,\n ...(contextCompactionCount > 0 ? { contextCompactionCount } : {}),\n };\n if (turnEnd.failureText) {\n turnGroup.failureText = turnEnd.failureText;\n }\n\n groups.splice(\n startIndex,\n collected.length,\n ...(finalMessage ? [turnGroup, finalMessage] : [turnGroup]),\n );\n}\n\nfunction isTurnBoundary(group: TimelineGroup | undefined): boolean {\n return (\n group?.kind === \"turn\" ||\n (group?.kind === \"item\" &&\n (group.item.kind === \"user-message\" ||\n group.item.kind === \"context-compaction\" ||\n (group.item.kind === \"notice\" && group.item.tone === \"input\")))\n );\n}\n\nfunction belongsToDifferentTurn(group: TimelineGroup | undefined, turnId: string | null): boolean {\n if (!group || !turnId) {\n return false;\n }\n if (group.kind === \"activity\") {\n return (\n group.items.length > 0 &&\n group.items.every((item) => item.turnId !== null && item.turnId !== turnId)\n );\n }\n return (\n group.kind === \"item\" &&\n group.item.kind === \"agent-message\" &&\n group.item.turnId !== null &&\n group.item.turnId !== turnId\n );\n}\n\nfunction isBetweenTurnDivider(group: TimelineGroup | undefined): boolean {\n return (\n group?.kind === \"item\" &&\n group.item.kind === \"session-status\" &&\n group.item.status !== \"running\"\n );\n}\n\nfunction extractFinalAgentMessage(\n groups: TimelineGroup[],\n turnEnd: TurnEndItem,\n): Extract<TimelineGroup, { kind: \"item\" }> | null {\n const tail = groups[groups.length - 1];\n if (tail?.kind !== \"item\" || tail.item.kind !== \"agent-message\" || tail.item.streaming) {\n return null;\n }\n if (tail.item.turnId && turnEnd.turnId && tail.item.turnId !== turnEnd.turnId) {\n return null;\n }\n return tail;\n}\n\nfunction groupStartedAt(group: TimelineGroup | undefined): string | undefined {\n if (!group) {\n return undefined;\n }\n switch (group.kind) {\n case \"item\":\n return group.item.occurredAt;\n case \"activity\":\n return group.items[0]?.occurredAt;\n case \"turn\":\n return group.startedAt;\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n}\n\nfunction stringValue(value: unknown): string {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction numberOrNull(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction compactionTrigger(payload: Record<string, unknown>): ContextCompactionItem[\"trigger\"] {\n const trigger = payload.trigger;\n return trigger === \"auto\" ||\n trigger === \"operator\" ||\n trigger === \"proactive\" ||\n trigger === \"overflow\"\n ? trigger\n : null;\n}\n\n/**\n * Keep one landmark per turn: a later started/compacted/skipped settles the\n * open started row instead of stacking notices.\n */\nfunction settleOrPushContextCompaction(\n items: TimelineItem[],\n next: Omit<ContextCompactionItem, \"kind\">,\n): void {\n const openIndex = findOpenContextCompactionIndex(items, next.turnId);\n if (openIndex >= 0) {\n const open = items[openIndex];\n if (open?.kind === \"context-compaction\") {\n items[openIndex] = {\n ...open,\n ...next,\n // Prefer the settled event id so keys stay stable with the finish row.\n id: next.phase === \"started\" ? open.id : next.id,\n trigger: next.trigger ?? open.trigger,\n estimatedTokensBefore: next.estimatedTokensBefore ?? open.estimatedTokensBefore,\n implementation: next.implementation ?? open.implementation,\n };\n return;\n }\n }\n items.push({ kind: \"context-compaction\", ...next });\n}\n\nfunction findOpenContextCompactionIndex(items: TimelineItem[], turnId: string | null): number {\n for (let index = items.length - 1; index >= 0; index -= 1) {\n const item = items[index];\n if (item?.kind !== \"context-compaction\" || item.phase !== \"started\") {\n continue;\n }\n if (turnId && item.turnId && item.turnId !== turnId) {\n continue;\n }\n return index;\n }\n return -1;\n}\n\nfunction machineInputMembers(value: unknown): MachineInputBatchItem[\"members\"] {\n const kinds = new Set<MachineInputBatchItem[\"members\"][number][\"kind\"]>([\n \"scheduled_occurrence\",\n \"goal_continuation\",\n \"agent_message\",\n \"agent_steer_instruction\",\n \"child_terminal_result\",\n ]);\n const classifications = new Set<MachineInputBatchItem[\"members\"][number][\"classification\"]>([\n \"success\",\n \"failure\",\n \"action_required\",\n \"info\",\n ]);\n return Array.isArray(value)\n ? value.flatMap((candidate) => {\n const member = asRecord(candidate);\n return typeof member.id === \"string\" &&\n typeof member.kind === \"string\" &&\n kinds.has(member.kind as MachineInputBatchItem[\"members\"][number][\"kind\"]) &&\n typeof member.classification === \"string\" &&\n classifications.has(\n member.classification as MachineInputBatchItem[\"members\"][number][\"classification\"],\n ) &&\n typeof member.sourceId === \"string\"\n ? [\n {\n id: member.id,\n kind: member.kind as MachineInputBatchItem[\"members\"][number][\"kind\"],\n classification:\n member.classification as MachineInputBatchItem[\"members\"][number][\"classification\"],\n sourceId: member.sourceId,\n summary: stringValue(member.summary),\n },\n ]\n : [];\n })\n : [];\n}\n\nconst SESSION_STATUSES: readonly SessionStatus[] = [\n \"queued\",\n \"running\",\n \"idle\",\n \"requires_action\",\n \"failed\",\n \"cancelled\",\n];\n\n/** Statuses that demand the reader's attention and so earn a timeline divider. */\nconst ATTENTION_STATUSES: ReadonlySet<SessionStatus> = new Set([\n \"requires_action\",\n \"failed\",\n \"cancelled\",\n]);\n\n/** Keep only entries that match the wire shapes; user payloads are untyped. */\nfunction resourceRefs(value: unknown): import(\"@opengeni/sdk\").ResourceRef[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.filter((entry): entry is import(\"@opengeni/sdk\").ResourceRef => {\n const record = asRecord(entry);\n if (record.kind === \"repository\") {\n return typeof record.uri === \"string\" && typeof record.ref === \"string\";\n }\n return record.kind === \"file\" && typeof record.fileId === \"string\";\n });\n}\n\nfunction toolRefs(value: unknown): import(\"@opengeni/sdk\").ToolRef[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.filter((entry): entry is import(\"@opengeni/sdk\").ToolRef => {\n const record = asRecord(entry);\n return record.kind === \"mcp\" && typeof record.id === \"string\";\n });\n}\n\nfunction workerCompletionPayload(value: unknown): {\n childSessionId: string;\n childStatus: string;\n goalStatus: string | null;\n goalText: string | null;\n evidence: string | null;\n pausedReason: string | null;\n} | null {\n const payload = asRecord(value);\n const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n if (\n typeof payload.childSessionId !== \"string\" ||\n !uuidPattern.test(payload.childSessionId) ||\n typeof payload.status !== \"string\" ||\n payload.status.trim() === \"\"\n ) {\n return null;\n }\n const goal = asRecord(payload.goal);\n return {\n childSessionId: payload.childSessionId,\n childStatus: payload.status,\n goalStatus: typeof goal.status === \"string\" ? goal.status : null,\n goalText: typeof goal.text === \"string\" ? goal.text : null,\n evidence: typeof goal.evidence === \"string\" ? goal.evidence : null,\n // Console pauses and several server paths put the human explanation on\n // `rationale`, not `pausedReason` — same fallback the goal pill uses, so a\n // paused worker card never shows \"Worker paused\" with the reason missing.\n pausedReason:\n typeof goal.pausedReason === \"string\"\n ? goal.pausedReason\n : typeof goal.rationale === \"string\"\n ? goal.rationale\n : null,\n };\n}\n\nfunction isSessionStatus(value: unknown): value is SessionStatus {\n return typeof value === \"string\" && (SESSION_STATUSES as readonly string[]).includes(value);\n}\n\n/** Does this tool output represent an error (explicit flag or MCP `isError`)? */\nfunction isErrorOutput(payload: Record<string, unknown>): boolean {\n if (payload.error === true || payload.failed === true) {\n return true;\n }\n const output = payload.output;\n return (\n !!output && typeof output === \"object\" && (output as { isError?: unknown }).isError === true\n );\n}\n\nfunction findOpenCall(\n items: TimelineItem[],\n callId: string | null,\n): ToolCallItem | WorkerItem | undefined {\n const reversed = [...items].reverse();\n const isCall = (item: TimelineItem): item is ToolCallItem | WorkerItem =>\n item.kind === \"tool-call\" || item.kind === \"worker\";\n if (callId) {\n const byId = reversed.find((item) => isCall(item) && item.callId === callId);\n if (byId) {\n return byId as ToolCallItem | WorkerItem;\n }\n }\n return reversed.find(\n (item): item is ToolCallItem | WorkerItem => isCall(item) && item.status === \"running\",\n );\n}\n\nfunction findOpenSandbox(items: TimelineItem[], name: string): SandboxItem | undefined {\n return [...items]\n .reverse()\n .find(\n (item): item is SandboxItem =>\n item.kind === \"sandbox\" && item.name === name && item.status === \"running\",\n );\n}\n\nfunction failureMessage(payload: Record<string, unknown>): string | null {\n for (const key of [\"error\", \"message\"] as const) {\n const value = payload[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n // Auth/quota provider errors are rewritten for the right audience\n // (raw text remains in the event payload for debug surfaces).\n return humanizeFailureReason(value);\n }\n }\n return null;\n}\n\nfunction goalText(payload: Record<string, unknown>): string | null {\n if (typeof payload.text === \"string\" && payload.text) {\n return payload.text;\n }\n const goal = asRecord(payload.goal);\n if (typeof goal.text === \"string\" && goal.text) {\n return goal.text;\n }\n if (typeof payload.prompt === \"string\" && payload.prompt) {\n return payload.prompt;\n }\n return null;\n}\n\n/**\n * Agent-owned goal mutations already have an in-cluster tool row. Suppress the\n * breakaway landmark for those only. `goal.completed` has no actor field today\n * and is only emitted by the agent tool, so it is always suppressed. API /\n * system / create-session / continuation landmarks stay visible.\n */\nfunction shouldSuppressAgentGoalLandmark(type: string, payload: Record<string, unknown>): boolean {\n if (type === \"goal.completed\") {\n return true;\n }\n if (type === \"goal.set\" || type === \"goal.updated\" || type === \"goal.paused\") {\n return payload.actor === \"agent\";\n }\n return false;\n}\n\n/**\n * Fold a `memory.saved` / `memory.corrected` event into a {@link MemoryItem}.\n * Reads DEFENSIVELY (the payload is untyped `unknown`, no Zod schema): a missing\n * memory id means a malformed event, so we return null and the case drops it.\n */\nfunction memoryItem(\n id: string,\n type: string,\n turnId: string | null,\n payload: Record<string, unknown>,\n occurredAt: string,\n): MemoryItem | null {\n const memoryId =\n typeof payload.memoryId === \"string\" && payload.memoryId ? payload.memoryId : null;\n if (!memoryId) {\n return null;\n }\n const replacementPreview =\n typeof payload.replacementPreview === \"string\" ? payload.replacementPreview : undefined;\n const replacementMemoryId =\n typeof payload.replacementMemoryId === \"string\" ? payload.replacementMemoryId : undefined;\n const action = typeof payload.action === \"string\" ? payload.action : undefined;\n return {\n kind: \"memory\",\n id,\n turnId,\n variant: type === \"memory.corrected\" ? \"corrected\" : \"saved\",\n memoryKind: stringValue(payload.kind),\n preview: stringValue(payload.preview),\n ...(payload.deduped === true ? { deduped: true } : {}),\n ...(replacementPreview ? { replacementPreview } : {}),\n ...(action ? { action } : {}),\n memoryId,\n ...(replacementMemoryId ? { replacementMemoryId } : {}),\n occurredAt,\n };\n}\n\nconst AUTH_NEEDED_REASONS: ReadonlySet<string> = new Set([\n \"missing_connection\",\n \"expired\",\n \"insufficient_scope\",\n \"refresh_failed\",\n \"unsupported_auth\",\n \"resource_scope_unavailable\",\n]);\n\nfunction authNeededReason(value: unknown): AuthNeededItem[\"reason\"] {\n return typeof value === \"string\" && AUTH_NEEDED_REASONS.has(value)\n ? (value as AuthNeededItem[\"reason\"])\n : null;\n}\n\nfunction stringList(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0)\n : [];\n}\n\nfunction reasoningText(payload: unknown): string {\n const record = asRecord(payload);\n if (typeof record.text === \"string\") {\n return record.text;\n }\n const content = asRecord(asRecord(record.item).rawItem).content;\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .map((part) => {\n const text = asRecord(part).text;\n return stringValue(text);\n })\n .join(\"\");\n}\n\n/** The worker's initial/sent message from `session_create`/`session_send_message` args. */\nfunction workerPrompt(args: unknown): string | null {\n const record = asRecord(typeof args === \"string\" ? tryParseJson(args) : args);\n for (const key of [\"initialMessage\", \"message\", \"text\", \"prompt\"] as const) {\n const value = record[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n }\n return null;\n}\n\n/**\n * Find a session id in orchestration tool arguments or output. Handles raw\n * objects, JSON strings, and MCP tool results (`{ content: [{ type: \"text\",\n * text: \"{...}\" }], structuredContent? }`).\n */\nexport function extractSessionRef(value: unknown, depth = 0): string | null {\n if (depth > 6 || value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\") {\n return extractSessionRef(tryParseJson(value), depth + 1);\n }\n if (Array.isArray(value)) {\n for (const entry of value) {\n const found = extractSessionRef(entry, depth + 1);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (typeof value !== \"object\") {\n return null;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.sessionId === \"string\" && looksLikeId(record.sessionId)) {\n return record.sessionId;\n }\n if (\n typeof record.id === \"string\" &&\n looksLikeId(record.id) &&\n (\"status\" in record || \"workspaceId\" in record || \"initialMessage\" in record)\n ) {\n return record.id;\n }\n for (const key of [\"structuredContent\", \"session\", \"result\", \"content\"] as const) {\n if (key in record) {\n const found = extractSessionRef(record[key], depth + 1);\n if (found) {\n return found;\n }\n }\n }\n if (typeof record.text === \"string\") {\n return extractSessionRef(tryParseJson(record.text), depth + 1);\n }\n return null;\n}\n\nfunction looksLikeId(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);\n}\n"],"mappings":"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","names":["candidate"]}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shouldSteerOnKey,
|
|
3
3
|
shouldSubmitOnKey
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FT2TXNGZ.js";
|
|
5
5
|
import {
|
|
6
6
|
groupPickerRowsByBillingClass
|
|
7
7
|
} from "./chunk-U255M5EZ.js";
|
|
8
|
+
import {
|
|
9
|
+
Tooltip,
|
|
10
|
+
TooltipContent,
|
|
11
|
+
TooltipProvider,
|
|
12
|
+
TooltipTrigger
|
|
13
|
+
} from "./chunk-ATSTR5P3.js";
|
|
8
14
|
import {
|
|
9
15
|
cn
|
|
10
16
|
} from "./chunk-TK7G6XLT.js";
|
|
@@ -12,7 +18,7 @@ import {
|
|
|
12
18
|
composerSubmissionErrorMessage,
|
|
13
19
|
formatBytes,
|
|
14
20
|
formatRelativeTime
|
|
15
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-LAKLF4PA.js";
|
|
16
22
|
|
|
17
23
|
// src/hooks/use-transcription.ts
|
|
18
24
|
import {
|
|
@@ -751,6 +757,9 @@ function errorCode(error) {
|
|
|
751
757
|
return "unknown";
|
|
752
758
|
}
|
|
753
759
|
|
|
760
|
+
// src/workstream-control-event.ts
|
|
761
|
+
var OPEN_WORKSTREAM_CONTROL_EVENT = "opengeni:open-workstream-control";
|
|
762
|
+
|
|
754
763
|
// src/commands/registry.ts
|
|
755
764
|
function parseCommandLine(value) {
|
|
756
765
|
if (value[0] !== "/") {
|
|
@@ -1340,6 +1349,7 @@ import {
|
|
|
1340
1349
|
} from "lucide-react";
|
|
1341
1350
|
import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
|
|
1342
1351
|
import {
|
|
1352
|
+
cloneElement,
|
|
1343
1353
|
createContext,
|
|
1344
1354
|
forwardRef,
|
|
1345
1355
|
useCallback as useCallback4,
|
|
@@ -1351,7 +1361,13 @@ import {
|
|
|
1351
1361
|
useState as useState4
|
|
1352
1362
|
} from "react";
|
|
1353
1363
|
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1354
|
-
|
|
1364
|
+
function ComposerTip({
|
|
1365
|
+
tip,
|
|
1366
|
+
children
|
|
1367
|
+
}) {
|
|
1368
|
+
if (!tip) return children;
|
|
1369
|
+
return cloneElement(children, { title: tip });
|
|
1370
|
+
}
|
|
1355
1371
|
var defaultChatComposerMessages = {
|
|
1356
1372
|
messagePlaceholder: "Message the agent\u2026",
|
|
1357
1373
|
pausedPlaceholder: "Sending will resume this workstream\u2026",
|
|
@@ -1413,6 +1429,20 @@ var defaultChatComposerMessages = {
|
|
|
1413
1429
|
formatBytes,
|
|
1414
1430
|
formatRelativeTime
|
|
1415
1431
|
};
|
|
1432
|
+
function applyComposerTextareaHeight(textarea, maxPx = 220) {
|
|
1433
|
+
if (textarea.scrollHeight > textarea.clientHeight + 1) {
|
|
1434
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, maxPx)}px`;
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
const before = textarea.offsetHeight;
|
|
1438
|
+
textarea.style.height = "auto";
|
|
1439
|
+
const nextPx = Math.min(textarea.scrollHeight, maxPx);
|
|
1440
|
+
if (Math.abs(nextPx - before) < 1) {
|
|
1441
|
+
textarea.style.height = `${before}px`;
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
textarea.style.height = `${nextPx}px`;
|
|
1445
|
+
}
|
|
1416
1446
|
function useChatComposerController({
|
|
1417
1447
|
delivery,
|
|
1418
1448
|
draft,
|
|
@@ -1516,13 +1546,30 @@ function useChatComposerController({
|
|
|
1516
1546
|
},
|
|
1517
1547
|
[]
|
|
1518
1548
|
);
|
|
1549
|
+
const resizeInputRafRef = useRef4(null);
|
|
1519
1550
|
const resizeInput = useCallback4(() => {
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1551
|
+
if (resizeInputRafRef.current !== null) {
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
resizeInputRafRef.current = requestAnimationFrame(() => {
|
|
1555
|
+
resizeInputRafRef.current = null;
|
|
1556
|
+
const textarea = textareaRef.current;
|
|
1557
|
+
if (!textarea) {
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
applyComposerTextareaHeight(textarea, 220);
|
|
1561
|
+
});
|
|
1524
1562
|
}, []);
|
|
1525
1563
|
useEffect3(() => resizeInput(), [delivery.value, resizeInput]);
|
|
1564
|
+
useEffect3(
|
|
1565
|
+
() => () => {
|
|
1566
|
+
if (resizeInputRafRef.current !== null) {
|
|
1567
|
+
cancelAnimationFrame(resizeInputRafRef.current);
|
|
1568
|
+
resizeInputRafRef.current = null;
|
|
1569
|
+
}
|
|
1570
|
+
},
|
|
1571
|
+
[]
|
|
1572
|
+
);
|
|
1526
1573
|
const handlers = useMemo4(
|
|
1527
1574
|
() => ({
|
|
1528
1575
|
notice: (next) => {
|
|
@@ -1729,7 +1776,7 @@ function isRecord2(value) {
|
|
|
1729
1776
|
return typeof value === "object" && value !== null;
|
|
1730
1777
|
}
|
|
1731
1778
|
var Root = forwardRef(function ComposerRoot({ controller, children, className, style, ...props }, forwardedRef) {
|
|
1732
|
-
return /* @__PURE__ */ jsx3(ComposerContext.Provider, { value: controller, children: /* @__PURE__ */ jsxs3(
|
|
1779
|
+
return /* @__PURE__ */ jsx3(ComposerContext.Provider, { value: controller, children: /* @__PURE__ */ jsx3(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs3(
|
|
1733
1780
|
"div",
|
|
1734
1781
|
{
|
|
1735
1782
|
...props,
|
|
@@ -1742,7 +1789,7 @@ var Root = forwardRef(function ComposerRoot({ controller, children, className, s
|
|
|
1742
1789
|
/* @__PURE__ */ jsx3(ComposerAnnouncements, {})
|
|
1743
1790
|
]
|
|
1744
1791
|
}
|
|
1745
|
-
) });
|
|
1792
|
+
) }) });
|
|
1746
1793
|
});
|
|
1747
1794
|
var Frame = forwardRef(function ComposerFrame({ className, ...props }, ref) {
|
|
1748
1795
|
return /* @__PURE__ */ jsx3("div", { ...props, ref, className: cn("relative", className) });
|
|
@@ -1947,6 +1994,7 @@ var AttachButton = forwardRef(
|
|
|
1947
1994
|
function ComposerAttachButton({ accept, multiple = true, className, "aria-label": ariaLabel, title, children, ...props }, ref) {
|
|
1948
1995
|
const controller = useComposerController();
|
|
1949
1996
|
if (!controller.attachments) return null;
|
|
1997
|
+
const tip = title ?? controller.messages.attachFiles;
|
|
1950
1998
|
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1951
1999
|
/* @__PURE__ */ jsx3(
|
|
1952
2000
|
"input",
|
|
@@ -1959,7 +2007,7 @@ var AttachButton = forwardRef(
|
|
|
1959
2007
|
onChange: controller.handleFileChange
|
|
1960
2008
|
}
|
|
1961
2009
|
),
|
|
1962
|
-
/* @__PURE__ */ jsx3(
|
|
2010
|
+
/* @__PURE__ */ jsx3(ComposerTip, { tip, children: /* @__PURE__ */ jsx3(
|
|
1963
2011
|
"button",
|
|
1964
2012
|
{
|
|
1965
2013
|
...props,
|
|
@@ -1967,8 +2015,7 @@ var AttachButton = forwardRef(
|
|
|
1967
2015
|
type: "button",
|
|
1968
2016
|
disabled: controller.disabled,
|
|
1969
2017
|
onClick: () => controller.fileInputRef.current?.click(),
|
|
1970
|
-
"aria-label": ariaLabel ??
|
|
1971
|
-
title: title ?? controller.messages.attachFiles,
|
|
2018
|
+
"aria-label": ariaLabel ?? tip,
|
|
1972
2019
|
className: cn(
|
|
1973
2020
|
"inline-flex size-8 items-center justify-center rounded-og-md",
|
|
1974
2021
|
"text-og-fg-muted transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
|
|
@@ -1977,7 +2024,7 @@ var AttachButton = forwardRef(
|
|
|
1977
2024
|
),
|
|
1978
2025
|
children: children ?? /* @__PURE__ */ jsx3(PaperclipIcon, { className: "size-4" })
|
|
1979
2026
|
}
|
|
1980
|
-
)
|
|
2027
|
+
) })
|
|
1981
2028
|
] });
|
|
1982
2029
|
}
|
|
1983
2030
|
);
|
|
@@ -2010,7 +2057,8 @@ var PauseButton = forwardRef(
|
|
|
2010
2057
|
const controller = useComposerController();
|
|
2011
2058
|
if (!controller.effectiveControl || controller.paused || !controller.hasControl) return null;
|
|
2012
2059
|
const busy = controller.pausing || controller.resuming;
|
|
2013
|
-
|
|
2060
|
+
const tip = title ?? controller.messages.pauseTitle;
|
|
2061
|
+
return /* @__PURE__ */ jsx3(ComposerTip, { tip, children: /* @__PURE__ */ jsx3(
|
|
2014
2062
|
"button",
|
|
2015
2063
|
{
|
|
2016
2064
|
...props,
|
|
@@ -2019,7 +2067,6 @@ var PauseButton = forwardRef(
|
|
|
2019
2067
|
onClick: () => void controller.pause(),
|
|
2020
2068
|
disabled: busy,
|
|
2021
2069
|
"aria-label": ariaLabel ?? controller.messages.pauseAriaLabel,
|
|
2022
|
-
title: title ?? controller.messages.pauseTitle,
|
|
2023
2070
|
className: cn(
|
|
2024
2071
|
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-11",
|
|
2025
2072
|
"bg-og-surface-2 text-og-fg-muted transition-colors duration-150",
|
|
@@ -2029,13 +2076,14 @@ var PauseButton = forwardRef(
|
|
|
2029
2076
|
),
|
|
2030
2077
|
children: children ?? (busy ? /* @__PURE__ */ jsx3(LoaderCircleIcon, { className: "size-3.5 animate-og-spin" }) : /* @__PURE__ */ jsx3(PauseIcon, { className: "size-3.5 fill-current" }))
|
|
2031
2078
|
}
|
|
2032
|
-
);
|
|
2079
|
+
) });
|
|
2033
2080
|
}
|
|
2034
2081
|
);
|
|
2035
2082
|
var SendButton = forwardRef(
|
|
2036
2083
|
function ComposerSendButton({ className, "aria-label": ariaLabel, title, children, ...props }, ref) {
|
|
2037
2084
|
const controller = useComposerController();
|
|
2038
|
-
|
|
2085
|
+
const tip = title ?? (controller.paused ? controller.messages.sendAndResumeTitle : controller.messages.sendTitle);
|
|
2086
|
+
return /* @__PURE__ */ jsx3(ComposerTip, { tip, children: /* @__PURE__ */ jsx3(
|
|
2039
2087
|
"button",
|
|
2040
2088
|
{
|
|
2041
2089
|
...props,
|
|
@@ -2043,8 +2091,8 @@ var SendButton = forwardRef(
|
|
|
2043
2091
|
type: "button",
|
|
2044
2092
|
onClick: () => void controller.submit("queue"),
|
|
2045
2093
|
disabled: !controller.canSubmit,
|
|
2094
|
+
"data-og-tip": tip,
|
|
2046
2095
|
"aria-label": ariaLabel ?? (controller.paused ? controller.messages.sendAndResumeAriaLabel : controller.messages.sendMessageAriaLabel),
|
|
2047
|
-
title: title ?? (controller.paused ? controller.messages.sendAndResumeTitle : controller.messages.sendTitle),
|
|
2048
2096
|
className: cn(
|
|
2049
2097
|
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-11",
|
|
2050
2098
|
"bg-og-accent text-og-accent-fg shadow-og-sm",
|
|
@@ -2055,7 +2103,7 @@ var SendButton = forwardRef(
|
|
|
2055
2103
|
),
|
|
2056
2104
|
children: children ?? (controller.sending ? /* @__PURE__ */ jsx3(LoaderCircleIcon, { className: "size-4 animate-og-spin" }) : /* @__PURE__ */ jsx3(ArrowUpIcon, { className: "size-4" }))
|
|
2057
2105
|
}
|
|
2058
|
-
);
|
|
2106
|
+
) });
|
|
2059
2107
|
}
|
|
2060
2108
|
);
|
|
2061
2109
|
function Help() {
|
|
@@ -2216,20 +2264,25 @@ function WorkstreamPausedStrip({
|
|
|
2216
2264
|
},
|
|
2217
2265
|
`${entry.kind}-${entry.sessionId ?? "workspace"}-${entry.revision}`
|
|
2218
2266
|
)) }),
|
|
2219
|
-
broaderOptions.length > 0 ? /* @__PURE__ */ jsx3("div", { className: "mt-2 flex flex-wrap gap-1.5", children: broaderOptions.map((option) => /* @__PURE__ */
|
|
2220
|
-
|
|
2267
|
+
broaderOptions.length > 0 ? /* @__PURE__ */ jsx3("div", { className: "mt-2 flex flex-wrap gap-1.5", children: broaderOptions.map((option) => /* @__PURE__ */ jsx3(
|
|
2268
|
+
ComposerTip,
|
|
2221
2269
|
{
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2270
|
+
tip: option.impactCopy,
|
|
2271
|
+
children: /* @__PURE__ */ jsxs3(
|
|
2272
|
+
"button",
|
|
2273
|
+
{
|
|
2274
|
+
type: "button",
|
|
2275
|
+
disabled: busy,
|
|
2276
|
+
onClick: () => onResumeOption(option),
|
|
2277
|
+
className: "rounded-og-md border border-og-border bg-og-surface-1 px-2 py-1 text-og-xs text-og-fg-muted hover:bg-og-surface-2 hover:text-og-fg pointer-coarse:min-h-10",
|
|
2278
|
+
children: [
|
|
2279
|
+
/* @__PURE__ */ jsx3("span", { className: "block font-medium", children: option.scope === "workspace" ? messages.resumeWorkspace : messages.resumeFromSession }),
|
|
2280
|
+
/* @__PURE__ */ jsx3("span", { className: "block text-[10px] text-og-fg-subtle", children: option.selectedStateAfter === "active" ? messages.sessionCanRun : messages.stillPausedBy(
|
|
2281
|
+
option.remainingPrimaryBlocker?.displayName ?? messages.narrowerPause
|
|
2282
|
+
) })
|
|
2283
|
+
]
|
|
2284
|
+
}
|
|
2285
|
+
)
|
|
2233
2286
|
},
|
|
2234
2287
|
`${option.scope}-${option.targetId ?? "selected"}`
|
|
2235
2288
|
)) }) : null
|
|
@@ -2357,30 +2410,19 @@ function AttachmentChips({
|
|
|
2357
2410
|
) : attachment.contentType.startsWith("image/") ? /* @__PURE__ */ jsx3(ImageIcon, { className: "size-4 shrink-0 text-og-fg-muted" }) : /* @__PURE__ */ jsx3(FileIcon, { className: "size-4 shrink-0 text-og-fg-muted" }),
|
|
2358
2411
|
/* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
|
|
2359
2412
|
/* @__PURE__ */ jsx3("div", { className: "truncate font-medium text-og-fg", children: attachment.name }),
|
|
2360
|
-
/* @__PURE__ */ jsx3(
|
|
2361
|
-
"div",
|
|
2362
|
-
{
|
|
2363
|
-
className: cn(
|
|
2364
|
-
"truncate text-og-xs",
|
|
2365
|
-
failed ? "text-og-status-failed" : "text-og-fg-subtle"
|
|
2366
|
-
),
|
|
2367
|
-
title: failed ? statusText : void 0,
|
|
2368
|
-
children: statusText
|
|
2369
|
-
}
|
|
2370
|
-
)
|
|
2413
|
+
failed ? /* @__PURE__ */ jsx3(ComposerTip, { tip: statusText, children: /* @__PURE__ */ jsx3("div", { className: "truncate text-og-xs text-og-status-failed", children: statusText }) }) : /* @__PURE__ */ jsx3("div", { className: "truncate text-og-xs text-og-fg-subtle", children: statusText })
|
|
2371
2414
|
] }),
|
|
2372
2415
|
attachment.status === "uploading" ? /* @__PURE__ */ jsx3(LoaderCircleIcon, { className: "size-3.5 shrink-0 animate-og-spin" }) : null,
|
|
2373
|
-
failed && onRetry ? /* @__PURE__ */ jsx3(
|
|
2416
|
+
failed && onRetry ? /* @__PURE__ */ jsx3(ComposerTip, { tip: messages.retryUpload, children: /* @__PURE__ */ jsx3(
|
|
2374
2417
|
"button",
|
|
2375
2418
|
{
|
|
2376
2419
|
type: "button",
|
|
2377
2420
|
onClick: () => onRetry(attachment.id),
|
|
2378
2421
|
className: "shrink-0 rounded-og-xs p-1 text-og-fg-muted hover:bg-og-surface-1 hover:text-og-fg pointer-coarse:size-10",
|
|
2379
2422
|
"aria-label": messages.retryAttachment(attachment.name),
|
|
2380
|
-
title: messages.retryUpload,
|
|
2381
2423
|
children: /* @__PURE__ */ jsx3(RotateCwIcon, { className: "size-3.5" })
|
|
2382
2424
|
}
|
|
2383
|
-
) : null,
|
|
2425
|
+
) }) : null,
|
|
2384
2426
|
/* @__PURE__ */ jsx3(
|
|
2385
2427
|
"button",
|
|
2386
2428
|
{
|
|
@@ -2444,6 +2486,12 @@ import { LoaderCircleIcon as LoaderCircleIcon2, MicIcon, SquareIcon, XIcon as XI
|
|
|
2444
2486
|
import { AnimatePresence as AnimatePresence3, motion as motion3 } from "motion/react";
|
|
2445
2487
|
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
2446
2488
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2489
|
+
function Tip({ tip, children }) {
|
|
2490
|
+
return /* @__PURE__ */ jsxs4(Tooltip, { children: [
|
|
2491
|
+
/* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children }),
|
|
2492
|
+
/* @__PURE__ */ jsx4(TooltipContent, { side: "top", children: tip })
|
|
2493
|
+
] });
|
|
2494
|
+
}
|
|
2447
2495
|
var defaultMessages = {
|
|
2448
2496
|
start: "Start voice input",
|
|
2449
2497
|
stop: "Stop and transcribe",
|
|
@@ -2540,14 +2588,13 @@ function ComposerTranscriptionControl({
|
|
|
2540
2588
|
)
|
|
2541
2589
|
] }),
|
|
2542
2590
|
status === "recording" ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2543
|
-
/* @__PURE__ */ jsx4(
|
|
2591
|
+
/* @__PURE__ */ jsx4(Tip, { tip: messages.cancel, children: /* @__PURE__ */ jsx4(
|
|
2544
2592
|
"button",
|
|
2545
2593
|
{
|
|
2546
2594
|
type: "button",
|
|
2547
2595
|
onClick: () => transcription.cancel(),
|
|
2548
2596
|
"aria-label": messages.cancel,
|
|
2549
2597
|
"aria-keyshortcuts": "Escape",
|
|
2550
|
-
title: messages.cancel,
|
|
2551
2598
|
className: cn(
|
|
2552
2599
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
2553
2600
|
"text-og-fg-muted transition-colors duration-150 motion-reduce:transition-none",
|
|
@@ -2555,14 +2602,13 @@ function ComposerTranscriptionControl({
|
|
|
2555
2602
|
),
|
|
2556
2603
|
children: /* @__PURE__ */ jsx4(XIcon2, { className: "size-3.5" })
|
|
2557
2604
|
}
|
|
2558
|
-
),
|
|
2559
|
-
/* @__PURE__ */ jsx4(
|
|
2605
|
+
) }),
|
|
2606
|
+
/* @__PURE__ */ jsx4(Tip, { tip: messages.stop, children: /* @__PURE__ */ jsx4(
|
|
2560
2607
|
"button",
|
|
2561
2608
|
{
|
|
2562
2609
|
type: "button",
|
|
2563
2610
|
onClick: () => transcription.stop(),
|
|
2564
2611
|
"aria-label": messages.stop,
|
|
2565
|
-
title: messages.stop,
|
|
2566
2612
|
className: cn(
|
|
2567
2613
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
2568
2614
|
"bg-og-fg text-og-bg transition-colors duration-150 motion-reduce:transition-none",
|
|
@@ -2570,12 +2616,12 @@ function ComposerTranscriptionControl({
|
|
|
2570
2616
|
),
|
|
2571
2617
|
children: /* @__PURE__ */ jsx4(SquareIcon, { className: "size-2.5 fill-current" })
|
|
2572
2618
|
}
|
|
2573
|
-
)
|
|
2619
|
+
) })
|
|
2574
2620
|
] }) : status === "transcribing" ? /* @__PURE__ */ jsx4("span", { className: "og-shimmer-text px-1.5 text-og-xs font-medium whitespace-nowrap", children: messages.transcribing }) : /* @__PURE__ */ jsx4("span", { className: "px-1.5 text-og-xs text-og-fg-muted whitespace-nowrap", children: messages.requestingPermission })
|
|
2575
2621
|
]
|
|
2576
2622
|
},
|
|
2577
2623
|
status === "transcribing" ? "transcribing" : "capture"
|
|
2578
|
-
) : /* @__PURE__ */ jsx4(
|
|
2624
|
+
) : /* @__PURE__ */ jsx4(Tip, { tip: idleLabel, children: /* @__PURE__ */ jsx4(
|
|
2579
2625
|
motion3.button,
|
|
2580
2626
|
{
|
|
2581
2627
|
type: "button",
|
|
@@ -2587,25 +2633,22 @@ function ComposerTranscriptionControl({
|
|
|
2587
2633
|
"aria-label": idleLabel,
|
|
2588
2634
|
"aria-pressed": false,
|
|
2589
2635
|
"aria-disabled": unavailableMessage !== null,
|
|
2590
|
-
title: idleLabel,
|
|
2591
2636
|
className: cn(
|
|
2592
2637
|
"inline-flex size-8 shrink-0 items-center justify-center rounded-og-md pointer-coarse:size-11",
|
|
2593
2638
|
"text-og-fg-muted transition-colors duration-150 motion-reduce:transition-none",
|
|
2594
2639
|
unavailableMessage ? "cursor-not-allowed opacity-45" : "hover:bg-og-surface-2 hover:text-og-fg"
|
|
2595
2640
|
),
|
|
2596
2641
|
children: /* @__PURE__ */ jsx4(MicIcon, { className: "size-4" })
|
|
2597
|
-
}
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
status === "error" && errorMessage3 ? /* @__PURE__ */ jsx4(
|
|
2642
|
+
}
|
|
2643
|
+
) }, "idle") }),
|
|
2644
|
+
status === "error" && errorMessage3 ? /* @__PURE__ */ jsx4(Tip, { tip: errorMessage3, children: /* @__PURE__ */ jsx4(
|
|
2601
2645
|
"span",
|
|
2602
2646
|
{
|
|
2603
2647
|
"aria-hidden": "true",
|
|
2604
|
-
title: errorMessage3,
|
|
2605
2648
|
className: "max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24",
|
|
2606
2649
|
children: errorMessage3
|
|
2607
2650
|
}
|
|
2608
|
-
) : null,
|
|
2651
|
+
) }) : null,
|
|
2609
2652
|
/* @__PURE__ */ jsx4("span", { className: "sr-only", role: status === "error" ? "alert" : "status", "aria-live": "polite", children: announcement })
|
|
2610
2653
|
]
|
|
2611
2654
|
}
|
|
@@ -2721,6 +2764,7 @@ export {
|
|
|
2721
2764
|
appendFinalTranscript,
|
|
2722
2765
|
useTranscription,
|
|
2723
2766
|
useVoiceInput,
|
|
2767
|
+
OPEN_WORKSTREAM_CONTROL_EVENT,
|
|
2724
2768
|
parseCommandLine,
|
|
2725
2769
|
hasPermission,
|
|
2726
2770
|
matchCommand,
|
|
@@ -2731,7 +2775,6 @@ export {
|
|
|
2731
2775
|
useSlashCommands,
|
|
2732
2776
|
CommandPalette,
|
|
2733
2777
|
ModelPicker,
|
|
2734
|
-
OPEN_WORKSTREAM_CONTROL_EVENT,
|
|
2735
2778
|
defaultChatComposerMessages,
|
|
2736
2779
|
useChatComposerController,
|
|
2737
2780
|
useChatComposer,
|
|
@@ -2756,4 +2799,4 @@ export {
|
|
|
2756
2799
|
Status,
|
|
2757
2800
|
ComposerTranscriptionControl
|
|
2758
2801
|
};
|
|
2759
|
-
//# sourceMappingURL=chunk-
|
|
2802
|
+
//# sourceMappingURL=chunk-PVW56EVR.js.map
|