@iowarp/clio-coder 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +16 -5
- package/dist/{acp-2BEHC4DL.js → acp-SK4MD6MM.js} +10 -10
- package/dist/{agents-LNNFTM53.js → agents-2FN2K6ME.js} +30 -25
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-QIYZWM5I.js} +13 -13
- package/dist/{chunk-KHSFENX2.js → chunk-3HAPLH5M.js} +10 -10
- package/dist/{chunk-24I7BN55.js → chunk-465YSENW.js} +2 -2
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CYQKWTG3.js → chunk-4DWFMQDR.js} +4 -4
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-K7T3E2SR.js → chunk-5UJ6ECTS.js} +10 -9
- package/dist/{chunk-6US73PDB.js → chunk-6M7VS3J3.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-6TUKSZVF.js} +5 -5
- package/dist/{chunk-5JGRAMKL.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-R46L2BIR.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-XXQNGV4M.js → chunk-CEYBNUGC.js} +243 -63
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-DMD2AGVS.js} +5 -4
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-XF5N4U5A.js → chunk-EBEFWSGL.js} +6 -5
- package/dist/{chunk-EYPA3EGJ.js → chunk-EELBMBT6.js} +120 -13
- package/dist/{chunk-CKXWIANG.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-LYF7OHWH.js → chunk-J7PIKKWC.js} +8 -463
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-6XXKFVSN.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-QNQHSOLF.js → chunk-LADCF22A.js} +12 -12
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-XYDYPRZI.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-G7MUEIGA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-EKY57CSP.js → chunk-OBMAI2DP.js} +61 -767
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ZRGEBJ4T.js → chunk-QCTRSGHQ.js} +21 -21
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QM3F2GKX.js → chunk-UUANF5CR.js} +2247 -2096
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-DJVECN66.js → chunk-VQNODYQ4.js} +14 -14
- package/dist/{chunk-3BPUFZDL.js → chunk-VREKEFLL.js} +3 -3
- package/dist/{chunk-PBTHKCPN.js → chunk-WJHBC77E.js} +6 -6
- package/dist/{chunk-XE2VEJHX.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-ZXF4XRKW.js → chunk-XEGB6BCN.js} +157 -7
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-NCBTHHN2.js → chunk-YTYFXUI3.js} +65 -322
- package/dist/{chunk-OH3TOQTB.js → chunk-ZGH7FGS5.js} +13 -7
- package/dist/cli/index.js +32 -30
- package/dist/{clio-M2KGYUFZ.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +3 -3
- package/dist/{components-5TTYYX6G.js → components-F7OEATSO.js} +4 -4
- package/dist/{config-XUUYQIWO.js → config-TRBL3RCF.js} +34 -29
- package/dist/{configure-IHJ7YOMV.js → configure-OLCVPHNM.js} +15 -15
- package/dist/{context-74JLXAWD.js → context-MJIJ6GOX.js} +11 -11
- package/dist/{context-ZQ7SIFJV.js → context-WFPKQSM6.js} +19 -3
- package/dist/{context-75MIWW3U.js → context-XEWE3MOJ.js} +31 -26
- package/dist/{context-clear-GYKWNUML.js → context-clear-KNOS2JPB.js} +31 -26
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-EUXAZI6N.js} +8 -8
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-B7MTOVKL.js} +313 -53
- package/dist/{docs-6FZSCG5B.js → docs-FLJTIDSE.js} +4 -4
- package/dist/{doctor-SVJ5BZCW.js → doctor-RN4YKO2X.js} +14 -14
- package/dist/{eval-CG6LLBLD.js → eval-RUBJVSNQ.js} +8 -7
- package/dist/{evidence-ZYFIEN42.js → evidence-JZNBUOQZ.js} +30 -25
- package/dist/{evolve-QGEXEMDW.js → evolve-FJVC4KKI.js} +30 -25
- package/dist/{extensions-ADGNCJJD.js → extensions-IQL36S7K.js} +4 -4
- package/dist/{fleet-S5R4ZOQY.js → fleet-BDKYJFCP.js} +214 -360
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-5DRU55YR.js → init-LQUB5COQ.js} +44 -37
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-OG6HOYKM.js} +31 -26
- package/dist/{models-ZPOLRU2C.js → models-5ZG5XY7J.js} +21 -20
- package/dist/{monitor-US5F5YGZ.js → monitor-TJ7AMTGB.js} +49 -30
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-WZYB54DM.js} +3827 -581
- package/dist/{paths-E7KYAQWE.js → paths-XUC7GS6E.js} +4 -4
- package/dist/{reset-KZ652EK6.js → reset-PXQT45IY.js} +7 -7
- package/dist/{run-SRNBKDWD.js → run-FQ74YF62.js} +53 -45
- package/dist/{share-CGZE33UP.js → share-FW7SVCL3.js} +33 -9
- package/dist/{skills-S2X4DLY5.js → skills-7E7IRB3R.js} +24 -8
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-LI75W6OK.js} +34 -27
- package/dist/{targets-54SWINWB.js → targets-4CIFKCTW.js} +23 -22
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WUZY7ZV5.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-7FV7IP4E.js} +4 -4
- package/dist/{upgrade-JKAR27XC.js → upgrade-K2HVIVMQ.js} +20 -19
- package/dist/{usage-MSAWCLX4.js → usage-GTZELZQX.js} +116 -49
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-ASIFASCN.js} +45 -37
- package/dist/worker/entry.js +38 -35
- package/docs/README.md +3 -2
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +82 -2
- package/docs/configuration-and-targets.md +79 -2
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +3 -3
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +5 -5
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +197 -10
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +2 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +79 -64
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +1 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +173 -335
- package/src/cli/index.ts +3 -1
- package/src/cli/library.ts +190 -0
- package/src/cli/share.ts +13 -1
- package/src/cli/usage.ts +111 -19
- package/src/core/bus-events.ts +4 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/domains/agents/builtins/architect.md +1 -0
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +13 -1
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/result-contract.ts +235 -1
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +34 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +258 -9
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/receipt-integrity.ts +8 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +51 -6
- package/src/domains/dispatch/validation.ts +66 -6
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +3 -1
- package/src/domains/observability/cost.ts +12 -1
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/entry/orchestrator.ts +37 -0
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop.ts +235 -1
- package/src/interactive/chat-renderer.ts +22 -0
- package/src/interactive/cost-overlay.ts +31 -3
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +260 -16
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +43 -1
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
- package/src/interactive/overlay-general-openers.ts +190 -1
- package/src/interactive/overlay-key-routing.ts +17 -1
- package/src/interactive/overlay-lifecycle.ts +41 -1
- package/src/interactive/overlay-permission-lifecycle.ts +10 -0
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +432 -5
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-middleware.ts +15 -1
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +7 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +57 -1
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +16 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +61 -1
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +2 -1
- package/src/worker/spec-contract.ts +1 -0
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/btw`: one model round beside the session, never inside it.
|
|
3
|
+
*
|
|
4
|
+
* A fleet run briefs its workers from the transcript, so every question the
|
|
5
|
+
* operator asks mid-run to orient themselves ("which file did that land in
|
|
6
|
+
* again?") becomes context the workers inherit. This round reads the compiled
|
|
7
|
+
* history the next turn would send and answers into an overlay; nothing it
|
|
8
|
+
* produces reaches the session JSONL, the transcript panel, the context ledger,
|
|
9
|
+
* or the task board, and it never becomes a turn.
|
|
10
|
+
*
|
|
11
|
+
* The call goes through the same `src/engine/ai.ts` stream seam compaction uses
|
|
12
|
+
* for its summarization call, which is what keeps this outside the turn state
|
|
13
|
+
* machine without adding an engine seam of its own. Tools are never sent.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { stream } from "../engine/ai.js";
|
|
17
|
+
import type { AgentMessage, EngineModel, Usage } from "../engine/types.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The whole system prompt for the round. The session's own compiled prompt is
|
|
21
|
+
* deliberately not reused: it carries the working agreement for a turn that
|
|
22
|
+
* edits files and calls tools, and this round does neither.
|
|
23
|
+
*/
|
|
24
|
+
export const SIDE_QUESTION_SYSTEM_PROMPT = [
|
|
25
|
+
"You are answering a side question from the operator of a coding session.",
|
|
26
|
+
"The conversation above is read-only context. Answer the question directly and briefly.",
|
|
27
|
+
"Do not continue the conversation, do not propose edits, and do not call tools.",
|
|
28
|
+
].join(" ");
|
|
29
|
+
|
|
30
|
+
/** Default output budget for the round. A side question wants an answer, not an essay. */
|
|
31
|
+
export const SIDE_QUESTION_MAX_TOKENS = 2048;
|
|
32
|
+
|
|
33
|
+
export interface SideQuestionUsage {
|
|
34
|
+
input: number;
|
|
35
|
+
output: number;
|
|
36
|
+
cacheRead: number;
|
|
37
|
+
cacheWrite: number;
|
|
38
|
+
reasoning: number;
|
|
39
|
+
totalTokens: number;
|
|
40
|
+
costUsd: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface SideQuestionInput {
|
|
44
|
+
/** Live model the next turn would use, taken from the session's active runtime. */
|
|
45
|
+
model: EngineModel;
|
|
46
|
+
/**
|
|
47
|
+
* The compiled message history the next turn would send. Treated as
|
|
48
|
+
* read-only: the round copies it and appends its own user message to the
|
|
49
|
+
* copy, so the live agent's message list is never mutated.
|
|
50
|
+
*/
|
|
51
|
+
messages: ReadonlyArray<AgentMessage>;
|
|
52
|
+
question: string;
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
maxTokens?: number;
|
|
56
|
+
/** Streamed answer text, delivered as the provider produces it. */
|
|
57
|
+
onDelta?: (partialText: string) => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* One out-of-turn round against the session's live runtime. `/btw` and
|
|
62
|
+
* `/handoff` are both this: read the compiled history the next turn would see,
|
|
63
|
+
* append one instruction, send no tools, and never touch the turn state
|
|
64
|
+
* machine. Only the system prompt and the appended message differ.
|
|
65
|
+
*/
|
|
66
|
+
export interface OutOfTurnRoundInput extends Omit<SideQuestionInput, "question"> {
|
|
67
|
+
systemPrompt: string;
|
|
68
|
+
/** The one message appended to the read-only copy of the history. */
|
|
69
|
+
userText: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface SideQuestionResult {
|
|
73
|
+
text: string;
|
|
74
|
+
usage: SideQuestionUsage | null;
|
|
75
|
+
/** True when the operator cancelled the round with Esc or Ctrl+C. */
|
|
76
|
+
aborted: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function positive(value: unknown): number {
|
|
80
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function sideQuestionUsage(raw: unknown): SideQuestionUsage | null {
|
|
84
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
85
|
+
const usage = raw as Partial<Usage> & { reasoning?: number };
|
|
86
|
+
const input = positive(usage.input);
|
|
87
|
+
const output = positive(usage.output);
|
|
88
|
+
const cacheRead = positive(usage.cacheRead);
|
|
89
|
+
const cacheWrite = positive(usage.cacheWrite);
|
|
90
|
+
const totalTokens = positive(usage.totalTokens) || input + output + cacheRead + cacheWrite;
|
|
91
|
+
if (totalTokens === 0) return null;
|
|
92
|
+
return {
|
|
93
|
+
input,
|
|
94
|
+
output,
|
|
95
|
+
cacheRead,
|
|
96
|
+
cacheWrite,
|
|
97
|
+
reasoning: positive(usage.reasoning),
|
|
98
|
+
totalTokens,
|
|
99
|
+
costUsd: positive(usage.cost?.total),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function textFromMessage(message: unknown): string {
|
|
104
|
+
if (!message || typeof message !== "object" || !("content" in message)) return "";
|
|
105
|
+
const content = (message as { content: unknown }).content;
|
|
106
|
+
if (typeof content === "string") return content;
|
|
107
|
+
if (!Array.isArray(content)) return "";
|
|
108
|
+
return content
|
|
109
|
+
.filter(
|
|
110
|
+
(block): block is { type: "text"; text: string } =>
|
|
111
|
+
!!block &&
|
|
112
|
+
typeof block === "object" &&
|
|
113
|
+
(block as { type?: unknown }).type === "text" &&
|
|
114
|
+
typeof (block as { text?: unknown }).text === "string",
|
|
115
|
+
)
|
|
116
|
+
.map((block) => block.text)
|
|
117
|
+
.join("");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Run the side-question round. Resolves with the answer, the provider usage
|
|
122
|
+
* (which is still real money and is reported to `/cost`), and whether the
|
|
123
|
+
* operator aborted it. Provider failures reject; the caller renders the reason
|
|
124
|
+
* in the overlay.
|
|
125
|
+
*/
|
|
126
|
+
export async function runSideQuestion(input: SideQuestionInput): Promise<SideQuestionResult> {
|
|
127
|
+
const { question, ...rest } = input;
|
|
128
|
+
return runOutOfTurnRound({ ...rest, systemPrompt: SIDE_QUESTION_SYSTEM_PROMPT, userText: question });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The shared round. See {@link OutOfTurnRoundInput}. */
|
|
132
|
+
export async function runOutOfTurnRound(input: OutOfTurnRoundInput): Promise<SideQuestionResult> {
|
|
133
|
+
const options: Record<string, unknown> = { maxTokens: input.maxTokens ?? SIDE_QUESTION_MAX_TOKENS };
|
|
134
|
+
if (input.apiKey !== undefined) options.apiKey = input.apiKey;
|
|
135
|
+
if (input.signal !== undefined) options.signal = input.signal;
|
|
136
|
+
|
|
137
|
+
const context = {
|
|
138
|
+
systemPrompt: input.systemPrompt,
|
|
139
|
+
messages: [
|
|
140
|
+
...input.messages,
|
|
141
|
+
{ role: "user", content: [{ type: "text", text: input.userText }], timestamp: Date.now() },
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const events = stream(
|
|
146
|
+
input.model,
|
|
147
|
+
context as unknown as Parameters<typeof stream>[1],
|
|
148
|
+
options as unknown as Parameters<typeof stream>[2],
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
let text = "";
|
|
152
|
+
for await (const event of events) {
|
|
153
|
+
if (event.type === "text_delta") {
|
|
154
|
+
text = textFromMessage(event.partial);
|
|
155
|
+
input.onDelta?.(text);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (event.type === "done") {
|
|
159
|
+
const answer = textFromMessage(event.message).trim();
|
|
160
|
+
return { text: answer, usage: sideQuestionUsage((event.message as { usage?: unknown }).usage), aborted: false };
|
|
161
|
+
}
|
|
162
|
+
if (event.type === "error") {
|
|
163
|
+
const failed = event.error as { stopReason?: unknown; usage?: unknown; errorMessage?: unknown };
|
|
164
|
+
if (event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true) {
|
|
165
|
+
return { text: text.trim(), usage: sideQuestionUsage(failed.usage), aborted: true };
|
|
166
|
+
}
|
|
167
|
+
throw new Error(typeof failed.errorMessage === "string" ? failed.errorMessage : "side question failed");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { text: text.trim(), usage: null, aborted: input.signal?.aborted === true };
|
|
171
|
+
}
|