@duetso/agent 0.2.2 → 0.2.4

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.
Files changed (235) hide show
  1. package/README.md +19 -11
  2. package/dist/package.json +4 -4
  3. package/dist/src/cli/config.d.ts +10 -0
  4. package/dist/src/cli/config.d.ts.map +1 -0
  5. package/dist/src/cli/config.js +24 -0
  6. package/dist/src/cli/config.js.map +1 -0
  7. package/dist/src/cli/help.d.ts.map +1 -1
  8. package/dist/src/cli/help.js +16 -13
  9. package/dist/src/cli/help.js.map +1 -1
  10. package/dist/src/cli/inline-slash.d.ts +2 -1
  11. package/dist/src/cli/inline-slash.d.ts.map +1 -1
  12. package/dist/src/cli/inline-slash.js +14 -5
  13. package/dist/src/cli/inline-slash.js.map +1 -1
  14. package/dist/src/cli/memory-query.d.ts +1 -1
  15. package/dist/src/cli/model.d.ts +1 -1
  16. package/dist/src/cli/model.d.ts.map +1 -1
  17. package/dist/src/cli/model.js +1 -1
  18. package/dist/src/cli/model.js.map +1 -1
  19. package/dist/src/cli/route.d.ts +84 -0
  20. package/dist/src/cli/route.d.ts.map +1 -0
  21. package/dist/src/cli/route.js +261 -0
  22. package/dist/src/cli/route.js.map +1 -0
  23. package/dist/src/cli/rpc.d.ts +52 -9
  24. package/dist/src/cli/rpc.d.ts.map +1 -1
  25. package/dist/src/cli/rpc.js +195 -28
  26. package/dist/src/cli/rpc.js.map +1 -1
  27. package/dist/src/cli/run.d.ts +8 -1
  28. package/dist/src/cli/run.d.ts.map +1 -1
  29. package/dist/src/cli/run.js +24 -7
  30. package/dist/src/cli/run.js.map +1 -1
  31. package/dist/src/cli/shared.d.ts +4 -3
  32. package/dist/src/cli/shared.d.ts.map +1 -1
  33. package/dist/src/cli/shared.js +3 -4
  34. package/dist/src/cli/shared.js.map +1 -1
  35. package/dist/src/cli/shutdown.d.ts +4 -2
  36. package/dist/src/cli/shutdown.d.ts.map +1 -1
  37. package/dist/src/cli/shutdown.js +4 -2
  38. package/dist/src/cli/shutdown.js.map +1 -1
  39. package/dist/src/cli.d.ts +2 -0
  40. package/dist/src/cli.d.ts.map +1 -1
  41. package/dist/src/cli.js +12 -0
  42. package/dist/src/cli.js.map +1 -1
  43. package/dist/src/core/structured-output.d.ts +2 -0
  44. package/dist/src/core/structured-output.d.ts.map +1 -1
  45. package/dist/src/core/structured-output.js +1 -0
  46. package/dist/src/core/structured-output.js.map +1 -1
  47. package/dist/src/lib/system-reminder.d.ts +14 -0
  48. package/dist/src/lib/system-reminder.d.ts.map +1 -0
  49. package/dist/src/lib/system-reminder.js +53 -0
  50. package/dist/src/lib/system-reminder.js.map +1 -0
  51. package/dist/src/lib/walk-ancestors.d.ts +9 -0
  52. package/dist/src/lib/walk-ancestors.d.ts.map +1 -0
  53. package/dist/src/lib/walk-ancestors.js +28 -0
  54. package/dist/src/lib/walk-ancestors.js.map +1 -0
  55. package/dist/src/memory/observational-prompts.d.ts.map +1 -1
  56. package/dist/src/memory/observational-prompts.js +2 -1
  57. package/dist/src/memory/observational-prompts.js.map +1 -1
  58. package/dist/src/memory/observational.d.ts +31 -4
  59. package/dist/src/memory/observational.d.ts.map +1 -1
  60. package/dist/src/memory/observational.js +43 -4
  61. package/dist/src/memory/observational.js.map +1 -1
  62. package/dist/src/model-resolution/catalog.d.ts +2 -2
  63. package/dist/src/model-resolution/catalog.d.ts.map +1 -1
  64. package/dist/src/model-resolution/catalog.js +61 -33
  65. package/dist/src/model-resolution/catalog.js.map +1 -1
  66. package/dist/src/model-resolution/duet-gateway.d.ts +3 -3
  67. package/dist/src/model-resolution/duet-gateway.d.ts.map +1 -1
  68. package/dist/src/model-resolution/duet-gateway.js +119 -19
  69. package/dist/src/model-resolution/duet-gateway.js.map +1 -1
  70. package/dist/src/model-resolution/model-gateway.d.ts.map +1 -0
  71. package/dist/src/{cli → model-resolution}/model-gateway.js +10 -6
  72. package/dist/src/model-resolution/model-gateway.js.map +1 -0
  73. package/dist/src/model-resolution/resolver.d.ts +11 -4
  74. package/dist/src/model-resolution/resolver.d.ts.map +1 -1
  75. package/dist/src/model-resolution/resolver.js +39 -8
  76. package/dist/src/model-resolution/resolver.js.map +1 -1
  77. package/dist/src/model-routing/advisor-transcript.d.ts +36 -0
  78. package/dist/src/model-routing/advisor-transcript.d.ts.map +1 -0
  79. package/dist/src/model-routing/advisor-transcript.js +103 -0
  80. package/dist/src/model-routing/advisor-transcript.js.map +1 -0
  81. package/dist/src/model-routing/advisor.d.ts +27 -0
  82. package/dist/src/model-routing/advisor.d.ts.map +1 -0
  83. package/dist/src/model-routing/advisor.js +20 -0
  84. package/dist/src/model-routing/advisor.js.map +1 -0
  85. package/dist/src/model-routing/classifier.d.ts +57 -0
  86. package/dist/src/model-routing/classifier.d.ts.map +1 -0
  87. package/dist/src/model-routing/classifier.js +63 -0
  88. package/dist/src/model-routing/classifier.js.map +1 -0
  89. package/dist/src/model-routing/loader.d.ts +48 -0
  90. package/dist/src/model-routing/loader.d.ts.map +1 -0
  91. package/dist/src/model-routing/loader.js +79 -0
  92. package/dist/src/model-routing/loader.js.map +1 -0
  93. package/dist/src/model-routing/prompts.d.ts +22 -0
  94. package/dist/src/model-routing/prompts.d.ts.map +1 -0
  95. package/dist/src/model-routing/prompts.js +87 -0
  96. package/dist/src/model-routing/prompts.js.map +1 -0
  97. package/dist/src/model-routing/resolve.d.ts +40 -0
  98. package/dist/src/model-routing/resolve.d.ts.map +1 -0
  99. package/dist/src/model-routing/resolve.js +76 -0
  100. package/dist/src/model-routing/resolve.js.map +1 -0
  101. package/dist/src/model-routing/router.d.ts +149 -0
  102. package/dist/src/model-routing/router.d.ts.map +1 -0
  103. package/dist/src/model-routing/router.js +235 -0
  104. package/dist/src/model-routing/router.js.map +1 -0
  105. package/dist/src/model-routing/step-triggers.d.ts +27 -0
  106. package/dist/src/model-routing/step-triggers.d.ts.map +1 -0
  107. package/dist/src/model-routing/step-triggers.js +20 -0
  108. package/dist/src/model-routing/step-triggers.js.map +1 -0
  109. package/dist/src/model-routing/table.d.ts +126 -0
  110. package/dist/src/model-routing/table.d.ts.map +1 -0
  111. package/dist/src/model-routing/table.js +351 -0
  112. package/dist/src/model-routing/table.js.map +1 -0
  113. package/dist/src/session/session.d.ts +40 -23
  114. package/dist/src/session/session.d.ts.map +1 -1
  115. package/dist/src/session/session.js +173 -97
  116. package/dist/src/session/session.js.map +1 -1
  117. package/dist/src/tasks/quiescence.d.ts +13 -0
  118. package/dist/src/tasks/quiescence.d.ts.map +1 -0
  119. package/dist/src/tasks/quiescence.js +11 -0
  120. package/dist/src/tasks/quiescence.js.map +1 -0
  121. package/dist/src/tasks/task-manager.d.ts +101 -0
  122. package/dist/src/tasks/task-manager.d.ts.map +1 -0
  123. package/dist/src/tasks/task-manager.js +311 -0
  124. package/dist/src/tasks/task-manager.js.map +1 -0
  125. package/dist/src/tasks/types.d.ts +85 -0
  126. package/dist/src/tasks/types.d.ts.map +1 -0
  127. package/dist/src/tasks/types.js +2 -0
  128. package/dist/src/tasks/types.js.map +1 -0
  129. package/dist/src/tui/app.d.ts +1 -1
  130. package/dist/src/tui/app.d.ts.map +1 -1
  131. package/dist/src/tui/app.js +12 -2
  132. package/dist/src/tui/app.js.map +1 -1
  133. package/dist/src/tui/initial-prompt.d.ts.map +1 -1
  134. package/dist/src/tui/initial-prompt.js +0 -3
  135. package/dist/src/tui/initial-prompt.js.map +1 -1
  136. package/dist/src/tui/session-subscription.d.ts +3 -0
  137. package/dist/src/tui/session-subscription.d.ts.map +1 -1
  138. package/dist/src/tui/session-subscription.js +29 -5
  139. package/dist/src/tui/session-subscription.js.map +1 -1
  140. package/dist/src/tui/sidebar.d.ts +3 -0
  141. package/dist/src/tui/sidebar.d.ts.map +1 -1
  142. package/dist/src/tui/sidebar.js +19 -3
  143. package/dist/src/tui/sidebar.js.map +1 -1
  144. package/dist/src/tui/slash-commands.d.ts +12 -9
  145. package/dist/src/tui/slash-commands.d.ts.map +1 -1
  146. package/dist/src/tui/slash-commands.js +48 -10
  147. package/dist/src/tui/slash-commands.js.map +1 -1
  148. package/dist/src/tui/status-controller.d.ts +14 -9
  149. package/dist/src/tui/status-controller.d.ts.map +1 -1
  150. package/dist/src/tui/status-controller.js +26 -7
  151. package/dist/src/tui/status-controller.js.map +1 -1
  152. package/dist/src/tui/task-lane-renderer.d.ts +30 -0
  153. package/dist/src/tui/task-lane-renderer.d.ts.map +1 -0
  154. package/dist/src/tui/task-lane-renderer.js +93 -0
  155. package/dist/src/tui/task-lane-renderer.js.map +1 -0
  156. package/dist/src/tui/task-tree.d.ts +47 -0
  157. package/dist/src/tui/task-tree.d.ts.map +1 -0
  158. package/dist/src/tui/task-tree.js +190 -0
  159. package/dist/src/tui/task-tree.js.map +1 -0
  160. package/dist/src/tui/tool-formatters.js +3 -0
  161. package/dist/src/tui/tool-formatters.js.map +1 -1
  162. package/dist/src/turn-runner/agent-events.d.ts.map +1 -1
  163. package/dist/src/turn-runner/agent-events.js +1 -0
  164. package/dist/src/turn-runner/agent-events.js.map +1 -1
  165. package/dist/src/turn-runner/duration.d.ts +2 -2
  166. package/dist/src/turn-runner/duration.js +3 -3
  167. package/dist/src/turn-runner/duration.js.map +1 -1
  168. package/dist/src/turn-runner/prompts.d.ts +5 -1
  169. package/dist/src/turn-runner/prompts.d.ts.map +1 -1
  170. package/dist/src/turn-runner/prompts.js +30 -6
  171. package/dist/src/turn-runner/prompts.js.map +1 -1
  172. package/dist/src/turn-runner/runtime-clock.d.ts +20 -0
  173. package/dist/src/turn-runner/runtime-clock.d.ts.map +1 -0
  174. package/dist/src/turn-runner/runtime-clock.js +38 -0
  175. package/dist/src/turn-runner/runtime-clock.js.map +1 -0
  176. package/dist/src/turn-runner/shell-state-handle.d.ts +0 -3
  177. package/dist/src/turn-runner/shell-state-handle.d.ts.map +1 -1
  178. package/dist/src/turn-runner/shell-state-handle.js +5 -55
  179. package/dist/src/turn-runner/shell-state-handle.js.map +1 -1
  180. package/dist/src/turn-runner/skill-context.d.ts +6 -7
  181. package/dist/src/turn-runner/skill-context.d.ts.map +1 -1
  182. package/dist/src/turn-runner/skill-context.js +10 -10
  183. package/dist/src/turn-runner/skill-context.js.map +1 -1
  184. package/dist/src/turn-runner/skills.d.ts.map +1 -1
  185. package/dist/src/turn-runner/skills.js +2 -22
  186. package/dist/src/turn-runner/skills.js.map +1 -1
  187. package/dist/src/turn-runner/state-compaction.d.ts +7 -5
  188. package/dist/src/turn-runner/state-compaction.d.ts.map +1 -1
  189. package/dist/src/turn-runner/state-compaction.js +69 -10
  190. package/dist/src/turn-runner/state-compaction.js.map +1 -1
  191. package/dist/src/turn-runner/state-machine-decisions.d.ts +135 -0
  192. package/dist/src/turn-runner/state-machine-decisions.d.ts.map +1 -0
  193. package/dist/src/turn-runner/state-machine-decisions.js +443 -0
  194. package/dist/src/turn-runner/state-machine-decisions.js.map +1 -0
  195. package/dist/src/turn-runner/state-machine-session.d.ts +13 -28
  196. package/dist/src/turn-runner/state-machine-session.d.ts.map +1 -1
  197. package/dist/src/turn-runner/state-machine-session.js +18 -55
  198. package/dist/src/turn-runner/state-machine-session.js.map +1 -1
  199. package/dist/src/turn-runner/subagent.d.ts +156 -0
  200. package/dist/src/turn-runner/subagent.d.ts.map +1 -0
  201. package/dist/src/turn-runner/subagent.js +164 -0
  202. package/dist/src/turn-runner/subagent.js.map +1 -0
  203. package/dist/src/turn-runner/task-tools.d.ts +76 -0
  204. package/dist/src/turn-runner/task-tools.d.ts.map +1 -0
  205. package/dist/src/turn-runner/task-tools.js +370 -0
  206. package/dist/src/turn-runner/task-tools.js.map +1 -0
  207. package/dist/src/turn-runner/tools.d.ts +65 -17
  208. package/dist/src/turn-runner/tools.d.ts.map +1 -1
  209. package/dist/src/turn-runner/tools.js +173 -59
  210. package/dist/src/turn-runner/tools.js.map +1 -1
  211. package/dist/src/turn-runner/turn-runner.d.ts +205 -135
  212. package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
  213. package/dist/src/turn-runner/turn-runner.js +1311 -714
  214. package/dist/src/turn-runner/turn-runner.js.map +1 -1
  215. package/dist/src/turn-runner/usage-accounting.d.ts +4 -0
  216. package/dist/src/turn-runner/usage-accounting.d.ts.map +1 -1
  217. package/dist/src/turn-runner/usage-accounting.js +19 -0
  218. package/dist/src/turn-runner/usage-accounting.js.map +1 -1
  219. package/dist/src/types/config.d.ts +9 -1
  220. package/dist/src/types/config.d.ts.map +1 -1
  221. package/dist/src/types/config.js +2 -1
  222. package/dist/src/types/config.js.map +1 -1
  223. package/dist/src/types/protocol.d.ts +124 -30
  224. package/dist/src/types/protocol.d.ts.map +1 -1
  225. package/dist/src/types/state-machine.d.ts +10 -12
  226. package/dist/src/types/state-machine.d.ts.map +1 -1
  227. package/dist/src/types/state-machine.js.map +1 -1
  228. package/package.json +4 -4
  229. package/dist/src/cli/model-gateway.d.ts.map +0 -1
  230. package/dist/src/cli/model-gateway.js.map +0 -1
  231. package/dist/src/turn-runner/state-machine-controller.d.ts +0 -140
  232. package/dist/src/turn-runner/state-machine-controller.d.ts.map +0 -1
  233. package/dist/src/turn-runner/state-machine-controller.js +0 -501
  234. package/dist/src/turn-runner/state-machine-controller.js.map +0 -1
  235. /package/dist/src/{cli → model-resolution}/model-gateway.d.ts +0 -0
@@ -0,0 +1,261 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { buildAdvisorTranscript } from "../model-routing/advisor-transcript.js";
4
+ import { classifyRoute } from "../model-routing/classifier.js";
5
+ import { loadRoutingTable } from "../model-routing/loader.js";
6
+ import { resolveRoute } from "../model-routing/resolve.js";
7
+ import { serializeMessageForObserver } from "../memory/observational.js";
8
+ import { MemorySession } from "../memory/session.js";
9
+ import { readSessionObservations } from "../memory/storage.js";
10
+ import { resolveProviderApiKey } from "../model-resolution/duet-gateway.js";
11
+ import { pinnedModelReference, resolveModelName, routingCatalogAdapter, } from "../model-resolution/resolver.js";
12
+ import { DEFAULT_MEMORY_DB_PATH, DEFAULT_SESSION_STORAGE_DIR } from "../session/session-manager.js";
13
+ import { listRecentSessions } from "../tui/recent-sessions.js";
14
+ import { TurnRunner } from "../turn-runner/turn-runner.js";
15
+ import { loadCliEnvFiles } from "./shared.js";
16
+ function printRouteHelp(write) {
17
+ write(`duet route — Probe model routing and advisor context\n\nUSAGE\n duet route [--model <tier>] [--images] [--json] "<prompt>"\n duet route advisor-preview [--session <id>]\n`);
18
+ }
19
+ /** Parse route flags while preserving a natural multi-word positional prompt. */
20
+ export function parseRouteArgs(args) {
21
+ const parsed = { images: false, json: false, help: false };
22
+ if (args[0] === "advisor-preview") {
23
+ parsed.advisorPreview = true;
24
+ for (let index = 1; index < args.length; index++) {
25
+ const arg = args[index];
26
+ if (arg === "--session") {
27
+ const value = args[++index];
28
+ if (!value || value.startsWith("-"))
29
+ throw new Error("Missing value for --session");
30
+ parsed.session = value;
31
+ }
32
+ else if (arg === "--help" || arg === "-h") {
33
+ parsed.help = true;
34
+ }
35
+ else {
36
+ throw new Error(`Unknown advisor-preview option: ${arg}`);
37
+ }
38
+ }
39
+ return parsed;
40
+ }
41
+ const prompt = [];
42
+ for (let index = 0; index < args.length; index++) {
43
+ const arg = args[index];
44
+ if (arg === "--model" || arg === "-m") {
45
+ const value = args[++index];
46
+ if (!value || value.startsWith("-"))
47
+ throw new Error(`Missing value for ${arg}`);
48
+ parsed.model = value;
49
+ }
50
+ else if (arg === "--images") {
51
+ parsed.images = true;
52
+ }
53
+ else if (arg === "--json") {
54
+ parsed.json = true;
55
+ }
56
+ else if (arg === "--help" || arg === "-h") {
57
+ parsed.help = true;
58
+ }
59
+ else if (arg.startsWith("-")) {
60
+ throw new Error(`Unknown route option: ${arg}`);
61
+ }
62
+ else {
63
+ prompt.push(arg);
64
+ }
65
+ }
66
+ if (prompt.length > 0)
67
+ parsed.prompt = prompt.join(" ");
68
+ return parsed;
69
+ }
70
+ function tableSource(loaded) {
71
+ return loaded.source === "built-in" ? loaded.source : loaded.path;
72
+ }
73
+ function classifierModelReference(modelName) {
74
+ const reference = pinnedModelReference(modelName);
75
+ const provider = reference.slice(0, reference.indexOf(":"));
76
+ if (!resolveProviderApiKey(provider)) {
77
+ throw new Error(`No API key configured for classifier provider "${provider}".`);
78
+ }
79
+ return reference;
80
+ }
81
+ function renderHuman(result) {
82
+ return [
83
+ `Tier: ${result.tier}`,
84
+ `Route: ${result.route}`,
85
+ `Model: ${result.model}`,
86
+ `Effort: ${result.effort}`,
87
+ `Rationale: ${result.rationale}`,
88
+ `Resolution chain: ${result.resolutionChain.join(" -> ")}`,
89
+ `Table source: ${result.tableSource}`,
90
+ `Latency: ${result.latencyMs} ms`,
91
+ ].join("\n");
92
+ }
93
+ /** Run one live route probe against the effective project routing table. */
94
+ export async function runRouteCommand(args, options = {}) {
95
+ const parsed = parseRouteArgs(args);
96
+ const write = options.write ?? ((text) => process.stdout.write(text));
97
+ if (parsed.help) {
98
+ printRouteHelp(write);
99
+ return undefined;
100
+ }
101
+ if (parsed.advisorPreview) {
102
+ return runAdvisorPreview(parsed, options, write);
103
+ }
104
+ if (!parsed.prompt?.trim())
105
+ throw new Error("Missing route prompt.");
106
+ const cwd = options.cwd ?? process.cwd();
107
+ loadCliEnvFiles(cwd);
108
+ const loaded = await loadRoutingTable({ cwd, catalogAdapter: routingCatalogAdapter });
109
+ const tierName = parsed.model ?? loaded.table.defaultTier;
110
+ const tier = loaded.table.tiers[tierName];
111
+ if (!tier)
112
+ throw new Error(`Unknown virtual model tier "${tierName}".`);
113
+ const now = options.now ?? Date.now;
114
+ const startedAt = now();
115
+ const facts = { hasImages: parsed.images };
116
+ const decision = await (options.classify ?? classifyRoute)({
117
+ tierName,
118
+ tier,
119
+ guidance: loaded.table.classifier.guidance,
120
+ lastStepDelta: parsed.prompt,
121
+ hasImages: facts.hasImages,
122
+ trigger: "turn_start",
123
+ }, {
124
+ model: classifierModelReference(loaded.table.classifier.target.modelName),
125
+ thinkingLevel: loaded.table.classifier.target.thinkingLevel,
126
+ });
127
+ const resolved = resolveRoute(loaded.table, tierName, decision.route, facts, routingCatalogAdapter);
128
+ const result = {
129
+ tier: tierName,
130
+ route: decision.route,
131
+ model: resolved.modelName,
132
+ effort: resolved.thinkingLevel,
133
+ rationale: decision.rationale,
134
+ resolutionChain: resolved.chain,
135
+ tableSource: tableSource(loaded),
136
+ latencyMs: Math.max(0, now() - startedAt),
137
+ };
138
+ write(`${parsed.json ? JSON.stringify(result) : renderHuman(result)}\n`);
139
+ return result;
140
+ }
141
+ async function runAdvisorPreview(parsed, options, write) {
142
+ const cwd = options.cwd ?? process.cwd();
143
+ loadCliEnvFiles(cwd);
144
+ const sessionsRoot = options.sessionsRoot ?? DEFAULT_SESSION_STORAGE_DIR;
145
+ const sessionId = parsed.session ?? listRecentSessions({ sessionsRoot, limit: 1 })[0]?.sessionId;
146
+ if (!sessionId)
147
+ throw new Error("No stored sessions found for advisor preview.");
148
+ if (sanitizeSessionId(sessionId) !== sessionId) {
149
+ throw new Error(`Invalid session id "${sessionId}".`);
150
+ }
151
+ const statePath = join(sessionsRoot, sessionId, "state.json");
152
+ const stored = JSON.parse(await readFile(statePath, "utf8"));
153
+ if (!stored.state)
154
+ throw new Error(`Stored session "${sessionId}" has no turn state.`);
155
+ const messages = stored.state.agent?.messages;
156
+ if (!Array.isArray(messages))
157
+ throw new Error(`Stored session "${sessionId}" has no transcript.`);
158
+ const firstUserMessage = messages.find((message) => message.role === "user");
159
+ if (!firstUserMessage)
160
+ throw new Error(`Stored session "${sessionId}" has no user message.`);
161
+ const loaded = await loadRoutingTable({ cwd, catalogAdapter: routingCatalogAdapter });
162
+ const selectedTier = stored.state.options?.model;
163
+ const tier = selectedTier && loaded.table.tiers[selectedTier] ? selectedTier : loaded.table.defaultTier;
164
+ const policy = loaded.table.tiers[tier].advisor;
165
+ const [executorSystemPrompt, observations] = await Promise.all([
166
+ rebuildExecutorSystemPrompt(stored.state, sessionId, cwd),
167
+ options.readObservations
168
+ ? options.readObservations(sessionId)
169
+ : readPreviewObservations(options.memoryDbPath ?? DEFAULT_MEMORY_DB_PATH, sessionId),
170
+ ]);
171
+ const transcript = buildAdvisorTranscript({
172
+ firstUserMessage: serializeMessageForObserver(firstUserMessage),
173
+ executorSystemPrompt,
174
+ observations,
175
+ tailMessages: messages.map(serializeMessageForObserver),
176
+ budgetTokens: policy.transcriptTokens,
177
+ });
178
+ const estimates = Object.entries(loaded.table.tiers).map(([tierName, definition]) => {
179
+ const model = definition.advisor.target.modelName;
180
+ // Derived from the catalog's per-model cost (the same source the sidebar
181
+ // and usage accounting bill from); zero means the catalog has no price.
182
+ const price = resolveModelName(model).cost?.input;
183
+ return {
184
+ tier: tierName,
185
+ model,
186
+ enabled: definition.advisor.enabled,
187
+ inputUsd: price ? (transcript.tokens / 1_000_000) * price : undefined,
188
+ };
189
+ });
190
+ const result = {
191
+ sessionId,
192
+ tier,
193
+ transcript: transcript.text,
194
+ tokens: transcript.tokens,
195
+ truncated: transcript.truncated,
196
+ estimates,
197
+ };
198
+ write(renderAdvisorPreview(result));
199
+ return result;
200
+ }
201
+ function renderAdvisorPreview(result) {
202
+ const estimates = result.estimates.map((estimate) => {
203
+ const cost = estimate.inputUsd === undefined ? "price unavailable" : `$${estimate.inputUsd.toFixed(4)}`;
204
+ return `- ${estimate.tier}: ${estimate.model}${estimate.enabled ? "" : " (disabled)"} — ${cost}`;
205
+ });
206
+ return [
207
+ `Session: ${result.sessionId}`,
208
+ `Tier: ${result.tier}`,
209
+ `Transcript tokens: ${result.tokens}${result.truncated ? " (truncated)" : ""}`,
210
+ "Estimated advisor input cost:",
211
+ ...estimates,
212
+ "",
213
+ result.transcript,
214
+ "",
215
+ ].join("\n");
216
+ }
217
+ class AdvisorPreviewTurnRunner extends TurnRunner {
218
+ systemPrompt() {
219
+ return this.requireParentAgent().state.systemPrompt;
220
+ }
221
+ }
222
+ async function rebuildExecutorSystemPrompt(state, sessionId, cwd) {
223
+ const runner = new AdvisorPreviewTurnRunner({
224
+ cwd,
225
+ sessionId,
226
+ memoryDbPath: false,
227
+ skillDiscovery: { includeDefaults: true },
228
+ });
229
+ try {
230
+ await runner.start({ type: "start", mode: state.mode, state });
231
+ return runner.systemPrompt();
232
+ }
233
+ finally {
234
+ await runner.dispose();
235
+ }
236
+ }
237
+ async function readPreviewObservations(memoryDbPath, sessionId) {
238
+ if (!memoryDbPath || !(await pathExists(memoryDbPath)))
239
+ return [];
240
+ const session = new MemorySession({ path: memoryDbPath, openOptions: {} });
241
+ try {
242
+ const snapshot = await readSessionObservations(session, sessionId);
243
+ return snapshot.observations.map((observation) => observation.content);
244
+ }
245
+ finally {
246
+ await session.dispose();
247
+ }
248
+ }
249
+ async function pathExists(path) {
250
+ try {
251
+ await stat(path);
252
+ return true;
253
+ }
254
+ catch {
255
+ return false;
256
+ }
257
+ }
258
+ function sanitizeSessionId(sessionId) {
259
+ return sessionId.replace(/[^A-Za-z0-9_.-]/g, "_");
260
+ }
261
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../src/cli/route.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,46 @@
1
- import type { TurnCompactCommand, TurnEditFollowUpQueueCommand, TurnInterruptCommand, TurnRunnerCommand, TurnSystemEvent, TurnTerminalEvent } from "../types/protocol.js";
1
+ import { type RuntimeClock } from "../turn-runner/runtime-clock.js";
2
+ import type { RpcCommandAcceptedEvent, RpcEvent, RpcRunnerCommand, TurnCompactCommand, TurnEditFollowUpQueueCommand, TurnInterruptCommand, TurnRunnerCommand, TurnState, TurnSystemEvent, TurnTerminalEvent } from "../types/protocol.js";
2
3
  import type { PackageMetadata } from "./run.js";
4
+ /** Stdout operations needed by the RPC event writer. */
5
+ export interface RpcWritable {
6
+ /** Queue one NDJSON line; false means subsequent writes must wait for `drain`. */
7
+ write(chunk: string): boolean;
8
+ /** Register the one-shot notification that stream backpressure has cleared. */
9
+ once(event: "drain", listener: () => void): unknown;
10
+ }
11
+ /**
12
+ * Ordered NDJSON writer for the RPC transport.
13
+ *
14
+ * Runner events are lossless and keep subscription order. Heartbeats are a
15
+ * separate best-effort lane: at most one waits behind backpressure, newer
16
+ * heartbeats replace it, and any real event is always written first.
17
+ */
18
+ export declare class RpcEventWriter {
19
+ private readonly stream;
20
+ private readonly clock;
21
+ private readonly losslessLines;
22
+ private readonly activeTaskIds;
23
+ private pendingHeartbeat?;
24
+ private pumping;
25
+ private heartbeatCancel?;
26
+ private failure?;
27
+ private readonly flushWaiters;
28
+ constructor(stream: RpcWritable, clock?: RuntimeClock);
29
+ /** Accept a runner event synchronously while its serialized value is stable. */
30
+ emit(event: RpcEvent): void;
31
+ /** Resolve after every accepted lossless event has crossed the stream boundary. */
32
+ flush(): Promise<void>;
33
+ /** Stop transport-owned liveness work, then flush every accepted event. */
34
+ close(): Promise<void>;
35
+ private startHeartbeats;
36
+ private stopHeartbeats;
37
+ private emitHeartbeat;
38
+ private pump;
39
+ private runPump;
40
+ private takeHeartbeat;
41
+ }
42
+ /** Fatal errors may synthesize a terminal only when the captured state is quiescent. */
43
+ export declare function shouldEmitFatalTerminal(state: TurnState | undefined): state is TurnState;
3
44
  /**
4
45
  * Minimal contract the RPC loop expects from a turn runner. The full
5
46
  * {@link TurnRunner} satisfies it; tests pass a stub so the dispatch loop
@@ -11,7 +52,7 @@ export interface RpcRunner {
11
52
  }>): Promise<unknown>;
12
53
  turn(command: Extract<TurnRunnerCommand, {
13
54
  type: "prompt" | "answer" | "wake";
14
- }>): Promise<TurnTerminalEvent>;
55
+ }>, onAccepted?: () => void): Promise<TurnTerminalEvent>;
15
56
  interrupt(command: TurnInterruptCommand): void;
16
57
  editFollowUpQueue(command: TurnEditFollowUpQueueCommand): void;
17
58
  compact(command: TurnCompactCommand): void | Promise<void>;
@@ -19,9 +60,11 @@ export interface RpcRunner {
19
60
  /**
20
61
  * `duet --rpc` — bare turn-runner control surface.
21
62
  *
22
- * Reads newline-delimited JSON {@link TurnRunnerCommand} values from stdin and
23
- * writes newline-delimited {@link import("../types/protocol.js").TurnEvent}
24
- * values to stdout. The first command must be `start`; the runner emits
63
+ * Reads newline-delimited JSON {@link RpcRunnerCommand} values from stdin and
64
+ * writes newline-delimited {@link RpcEvent} values to stdout. Prompt, answer,
65
+ * and wake commands carry a caller-owned `requestId`; the RPC transport emits
66
+ * `command_accepted` after the command enters the runner. The first command
67
+ * must be `start`; the runner emits
25
68
  * `turn_started` and then waits for a turn-driving command (`prompt`,
26
69
  * `answer`, or `wake`). Additional turn-driving commands sent before the
27
70
  * terminal event are forwarded into the runner, which queues them onto the
@@ -57,7 +100,7 @@ export interface ParsedRpcArgs {
57
100
  envFilePath?: string;
58
101
  /**
59
102
  * Explicit memory database file path passed via `--db`. When omitted,
60
- * `buildCliTurnConfig` falls back to the shared `~/.duet/memory.db`
103
+ * Project-aware config resolution falls back to the shared `~/.duet/memory.db`
61
104
  * default so RPC mode persists memory just like the TUI/run path.
62
105
  */
63
106
  dbPath?: string;
@@ -86,7 +129,7 @@ export interface DriveRpcLoopOptions {
86
129
  * about soft errors stay terse. The CLI wires this to stdout so hosts
87
130
  * see the same event stream they get from the runner.
88
131
  */
89
- emit?: (event: TurnSystemEvent) => void;
132
+ emit?: (event: TurnSystemEvent | RpcCommandAcceptedEvent) => void;
90
133
  }
91
134
  /**
92
135
  * RPC dispatch loop. Drives one turn chain to completion and returns once
@@ -102,7 +145,7 @@ export interface DriveRpcLoopOptions {
102
145
  * the runner whether or not a chain is already in flight — the runner is
103
146
  * the source of truth for how repeated `turn()` calls compose.
104
147
  */
105
- export declare function driveRpcLoop(runner: RpcRunner, commands: AsyncIterable<TurnRunnerCommand>, options?: DriveRpcLoopOptions): Promise<void>;
148
+ export declare function driveRpcLoop(runner: RpcRunner, commands: AsyncIterable<RpcRunnerCommand>, options?: DriveRpcLoopOptions): Promise<void>;
106
149
  /**
107
150
  * Discriminated outcome of parsing one stdin line. The dispatch loop
108
151
  * forwards `error` results to its emit sink and skips `skip` results so a
@@ -111,7 +154,7 @@ export declare function driveRpcLoop(runner: RpcRunner, commands: AsyncIterable<
111
154
  */
112
155
  export type ParseRpcCommandLineResult = {
113
156
  kind: "command";
114
- command: TurnRunnerCommand;
157
+ command: RpcRunnerCommand;
115
158
  } | {
116
159
  kind: "error";
117
160
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/cli/rpc.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAClB,4BAA4B,EAE5B,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAKhD;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,IAAI,CACF,OAAO,EAAE,OAAO,CAAC,iBAAiB,EAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;KAAE,CAAC,GAC1E,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9B,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC/C,iBAAiB,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAC/D,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEvF;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAoG1D;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CACzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC1C,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAsFf;AA0BD;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,yBAAyB,CAuB9E"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/cli/rpc.ts"],"names":[],"mappings":"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"}