@tangle-network/agent-eval 0.120.0 → 0.120.2

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 (171) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/dist/analyst/index.d.ts +0 -3111
  4. package/dist/analyst/index.js +0 -403
  5. package/dist/analyst/index.js.map +0 -1
  6. package/dist/authenticity/index.d.ts +0 -161
  7. package/dist/authenticity/index.js +0 -215
  8. package/dist/authenticity/index.js.map +0 -1
  9. package/dist/belief-state/index.d.ts +0 -1301
  10. package/dist/belief-state/index.js +0 -2152
  11. package/dist/belief-state/index.js.map +0 -1
  12. package/dist/benchmarks/index.d.ts +0 -974
  13. package/dist/benchmarks/index.js +0 -60
  14. package/dist/benchmarks/index.js.map +0 -1
  15. package/dist/builder-eval/index.d.ts +0 -695
  16. package/dist/builder-eval/index.js +0 -366
  17. package/dist/builder-eval/index.js.map +0 -1
  18. package/dist/campaign/index.d.ts +0 -7454
  19. package/dist/campaign/index.js +0 -272
  20. package/dist/campaign/index.js.map +0 -1
  21. package/dist/chunk-32BZXMSO.js +0 -3878
  22. package/dist/chunk-32BZXMSO.js.map +0 -1
  23. package/dist/chunk-3A246TSA.js +0 -998
  24. package/dist/chunk-3A246TSA.js.map +0 -1
  25. package/dist/chunk-3RF76KTD.js +0 -84
  26. package/dist/chunk-3RF76KTD.js.map +0 -1
  27. package/dist/chunk-3YYRZDON.js +0 -45
  28. package/dist/chunk-3YYRZDON.js.map +0 -1
  29. package/dist/chunk-4I2E3LLO.js +0 -1030
  30. package/dist/chunk-4I2E3LLO.js.map +0 -1
  31. package/dist/chunk-ARU2PZFM.js +0 -312
  32. package/dist/chunk-ARU2PZFM.js.map +0 -1
  33. package/dist/chunk-BOD4O7OF.js +0 -40
  34. package/dist/chunk-BOD4O7OF.js.map +0 -1
  35. package/dist/chunk-DPZAEKA6.js +0 -880
  36. package/dist/chunk-DPZAEKA6.js.map +0 -1
  37. package/dist/chunk-DTJ6QUQB.js +0 -131
  38. package/dist/chunk-DTJ6QUQB.js.map +0 -1
  39. package/dist/chunk-GGE4NNQT.js +0 -65
  40. package/dist/chunk-GGE4NNQT.js.map +0 -1
  41. package/dist/chunk-H5UD2323.js +0 -286
  42. package/dist/chunk-H5UD2323.js.map +0 -1
  43. package/dist/chunk-HHWE3POT.js +0 -94
  44. package/dist/chunk-HHWE3POT.js.map +0 -1
  45. package/dist/chunk-HKUCJ437.js +0 -787
  46. package/dist/chunk-HKUCJ437.js.map +0 -1
  47. package/dist/chunk-JHCHEVET.js +0 -274
  48. package/dist/chunk-JHCHEVET.js.map +0 -1
  49. package/dist/chunk-JHOJHHU7.js +0 -867
  50. package/dist/chunk-JHOJHHU7.js.map +0 -1
  51. package/dist/chunk-JM2SKQMS.js +0 -750
  52. package/dist/chunk-JM2SKQMS.js.map +0 -1
  53. package/dist/chunk-JN2FCO5W.js +0 -7958
  54. package/dist/chunk-JN2FCO5W.js.map +0 -1
  55. package/dist/chunk-K4DBDHLK.js +0 -158
  56. package/dist/chunk-K4DBDHLK.js.map +0 -1
  57. package/dist/chunk-K6N6XJJX.js +0 -306
  58. package/dist/chunk-K6N6XJJX.js.map +0 -1
  59. package/dist/chunk-MA6HLL3S.js +0 -65
  60. package/dist/chunk-MA6HLL3S.js.map +0 -1
  61. package/dist/chunk-MAZ26DC7.js +0 -99
  62. package/dist/chunk-MAZ26DC7.js.map +0 -1
  63. package/dist/chunk-MOXWMGPC.js +0 -577
  64. package/dist/chunk-MOXWMGPC.js.map +0 -1
  65. package/dist/chunk-NJC7U437.js +0 -626
  66. package/dist/chunk-NJC7U437.js.map +0 -1
  67. package/dist/chunk-NPCTHQIO.js +0 -91
  68. package/dist/chunk-NPCTHQIO.js.map +0 -1
  69. package/dist/chunk-ONWEPEDO.js +0 -57
  70. package/dist/chunk-ONWEPEDO.js.map +0 -1
  71. package/dist/chunk-OYZAPX5G.js +0 -1526
  72. package/dist/chunk-OYZAPX5G.js.map +0 -1
  73. package/dist/chunk-PC4UYEBM.js +0 -166
  74. package/dist/chunk-PC4UYEBM.js.map +0 -1
  75. package/dist/chunk-PICTDURQ.js +0 -766
  76. package/dist/chunk-PICTDURQ.js.map +0 -1
  77. package/dist/chunk-PJQFMIOX.js +0 -1182
  78. package/dist/chunk-PJQFMIOX.js.map +0 -1
  79. package/dist/chunk-PXD6ZFNY.js +0 -1107
  80. package/dist/chunk-PXD6ZFNY.js.map +0 -1
  81. package/dist/chunk-PXE2VKMX.js +0 -140
  82. package/dist/chunk-PXE2VKMX.js.map +0 -1
  83. package/dist/chunk-PZ5AY32C.js +0 -10
  84. package/dist/chunk-PZ5AY32C.js.map +0 -1
  85. package/dist/chunk-QBRSJK47.js +0 -622
  86. package/dist/chunk-QBRSJK47.js.map +0 -1
  87. package/dist/chunk-QWMPPZ3X.js +0 -550
  88. package/dist/chunk-QWMPPZ3X.js.map +0 -1
  89. package/dist/chunk-S3UZOQ5Y.js +0 -328
  90. package/dist/chunk-S3UZOQ5Y.js.map +0 -1
  91. package/dist/chunk-S5TT5R3L.js +0 -2668
  92. package/dist/chunk-S5TT5R3L.js.map +0 -1
  93. package/dist/chunk-T4SQEITX.js +0 -95
  94. package/dist/chunk-T4SQEITX.js.map +0 -1
  95. package/dist/chunk-TT4KNT67.js +0 -124
  96. package/dist/chunk-TT4KNT67.js.map +0 -1
  97. package/dist/chunk-U5CHZ5M3.js +0 -357
  98. package/dist/chunk-U5CHZ5M3.js.map +0 -1
  99. package/dist/chunk-ULOKLHIQ.js +0 -1937
  100. package/dist/chunk-ULOKLHIQ.js.map +0 -1
  101. package/dist/chunk-VI2UW6B6.js +0 -162
  102. package/dist/chunk-VI2UW6B6.js.map +0 -1
  103. package/dist/chunk-VQMK5FMP.js +0 -247
  104. package/dist/chunk-VQMK5FMP.js.map +0 -1
  105. package/dist/chunk-VSMTAMNK.js +0 -53
  106. package/dist/chunk-VSMTAMNK.js.map +0 -1
  107. package/dist/chunk-VZSRQ272.js +0 -149
  108. package/dist/chunk-VZSRQ272.js.map +0 -1
  109. package/dist/chunk-WW2A73HW.js +0 -159
  110. package/dist/chunk-WW2A73HW.js.map +0 -1
  111. package/dist/chunk-X4UCIOTZ.js +0 -136
  112. package/dist/chunk-X4UCIOTZ.js.map +0 -1
  113. package/dist/chunk-XDIRG3TO.js +0 -1266
  114. package/dist/chunk-XDIRG3TO.js.map +0 -1
  115. package/dist/chunk-XJYR7XFV.js +0 -317
  116. package/dist/chunk-XJYR7XFV.js.map +0 -1
  117. package/dist/chunk-ZET2UAYW.js +0 -89
  118. package/dist/chunk-ZET2UAYW.js.map +0 -1
  119. package/dist/chunk-ZZUXHH3R.js +0 -99
  120. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  121. package/dist/cli.d.ts +0 -1
  122. package/dist/cli.js +0 -112
  123. package/dist/cli.js.map +0 -1
  124. package/dist/contract/index.d.ts +0 -4969
  125. package/dist/contract/index.js +0 -1653
  126. package/dist/contract/index.js.map +0 -1
  127. package/dist/control.d.ts +0 -1013
  128. package/dist/control.js +0 -34
  129. package/dist/control.js.map +0 -1
  130. package/dist/fuzz.d.ts +0 -759
  131. package/dist/fuzz.js +0 -714
  132. package/dist/fuzz.js.map +0 -1
  133. package/dist/hosted/index.d.ts +0 -730
  134. package/dist/hosted/index.js +0 -14
  135. package/dist/hosted/index.js.map +0 -1
  136. package/dist/index.d.ts +0 -16780
  137. package/dist/index.js +0 -12168
  138. package/dist/index.js.map +0 -1
  139. package/dist/matrix/index.d.ts +0 -155
  140. package/dist/matrix/index.js +0 -8
  141. package/dist/matrix/index.js.map +0 -1
  142. package/dist/meta-eval/index.d.ts +0 -1030
  143. package/dist/meta-eval/index.js +0 -417
  144. package/dist/meta-eval/index.js.map +0 -1
  145. package/dist/multishot/index.d.ts +0 -579
  146. package/dist/multishot/index.js +0 -589
  147. package/dist/multishot/index.js.map +0 -1
  148. package/dist/openapi.json +0 -992
  149. package/dist/pipelines/index.d.ts +0 -567
  150. package/dist/pipelines/index.js +0 -515
  151. package/dist/pipelines/index.js.map +0 -1
  152. package/dist/reporting.d.ts +0 -1277
  153. package/dist/reporting.js +0 -48
  154. package/dist/reporting.js.map +0 -1
  155. package/dist/rl.d.ts +0 -4092
  156. package/dist/rl.js +0 -1724
  157. package/dist/rl.js.map +0 -1
  158. package/dist/run-campaign-HNFPJET4.js +0 -14
  159. package/dist/run-campaign-HNFPJET4.js.map +0 -1
  160. package/dist/storyboard/index.d.ts +0 -279
  161. package/dist/storyboard/index.js +0 -767
  162. package/dist/storyboard/index.js.map +0 -1
  163. package/dist/trace-attributes.d.ts +0 -52
  164. package/dist/trace-attributes.js +0 -62
  165. package/dist/trace-attributes.js.map +0 -1
  166. package/dist/traces.d.ts +0 -2343
  167. package/dist/traces.js +0 -249
  168. package/dist/traces.js.map +0 -1
  169. package/dist/wire/index.d.ts +0 -1252
  170. package/dist/wire/index.js +0 -81
  171. package/dist/wire/index.js.map +0 -1
@@ -1,589 +0,0 @@
1
- import {
2
- runAgentMatrix
3
- } from "../chunk-JHCHEVET.js";
4
- import "../chunk-PZ5AY32C.js";
5
-
6
- // src/multishot/router.ts
7
- async function routerCompletion(req) {
8
- const body = {
9
- model: req.model,
10
- messages: req.messages,
11
- temperature: req.temperature ?? 0.7,
12
- max_tokens: req.maxTokens ?? 2e3
13
- };
14
- if (req.tools?.length) body.tools = req.tools;
15
- const url = `${req.baseUrl.replace(/\/+$/, "")}/chat/completions`;
16
- const res = await fetch(url, {
17
- method: "POST",
18
- headers: { Authorization: `Bearer ${req.apiKey}`, "Content-Type": "application/json" },
19
- body: JSON.stringify(body),
20
- signal: req.signal
21
- });
22
- if (!res.ok) {
23
- const text = await res.text();
24
- throw new Error(`router ${res.status}: ${text.slice(0, 300)}`);
25
- }
26
- const json = await res.json();
27
- const choice = json.choices[0];
28
- if (!choice) throw new Error(`router returned no choices: ${JSON.stringify(json).slice(0, 200)}`);
29
- return { message: choice.message, usage: json.usage };
30
- }
31
- function estimateRouterCost(model, usage) {
32
- if (!usage) return 0;
33
- const inputTok = usage.prompt_tokens ?? 0;
34
- const outputTok = usage.completion_tokens ?? 0;
35
- let inPer1k = 3e-3;
36
- let outPer1k = 0.015;
37
- if (model.includes("gpt-4o-mini")) {
38
- inPer1k = 15e-5;
39
- outPer1k = 6e-4;
40
- } else if (model.includes("gpt-5.4") || model.includes("claude-sonnet")) {
41
- inPer1k = 3e-3;
42
- outPer1k = 0.015;
43
- } else if (model.includes("kimi") || model.includes("glm") || model.includes("deepseek")) {
44
- inPer1k = 5e-4;
45
- outPer1k = 2e-3;
46
- }
47
- return (inputTok * inPer1k + outputTok * outPer1k) / 1e3;
48
- }
49
- function defaultRouterBaseUrl() {
50
- return (process.env.TANGLE_ROUTER_BASE_URL ?? "https://router.tangle.tools/v1").replace(
51
- /\/+$/,
52
- ""
53
- );
54
- }
55
- function requireRouterApiKey() {
56
- const key = process.env.TANGLE_API_KEY;
57
- if (!key) throw new Error("multishot requires TANGLE_API_KEY (router-scoped sk-tan-* key)");
58
- return key;
59
- }
60
-
61
- // src/multishot/default-tools.ts
62
- var DEFAULT_RESEARCHER_MODEL = "openai/gpt-4o-mini";
63
- var DEFAULT_CODER_MODEL = "openai/gpt-4o-mini";
64
- var GENERIC_RESEARCHER_SYSTEM = "You are a research specialist. Return a markdown brief with 3-5 findings. Each finding cites a specific source by name. Add a confidence level (high/medium/low) per finding. No fluff, no preamble.";
65
- var GENERIC_CODER_SYSTEM = "You are an expert engineer. Output ONE fenced code block containing the complete solution. Inline-comment non-obvious decisions. No explanation outside the block.";
66
- var DEFAULT_DELEGATE_RESEARCH_TOOL = {
67
- type: "function",
68
- function: {
69
- name: "delegate_research",
70
- description: "Research a topic deeply via specialist. Returns evidence-bearing items with citations. Use for audience research, competitive intel, regulatory landscape, market data, citation-grounded analysis.",
71
- parameters: {
72
- type: "object",
73
- properties: {
74
- question: { type: "string", description: "Specific question to research" },
75
- scope: {
76
- type: "string",
77
- description: "Optional scope: time window, geography, jurisdiction, segment"
78
- }
79
- },
80
- required: ["question"]
81
- }
82
- }
83
- };
84
- var DEFAULT_DELEGATE_CODE_TOOL = {
85
- type: "function",
86
- function: {
87
- name: "delegate_code",
88
- description: "Generate a runnable script, template, pipeline, or tool via specialist. Returns complete working code or structured markdown. Use for content pipelines, calc snippets, dashboards, compliance checklists, deadline trackers.",
89
- parameters: {
90
- type: "object",
91
- properties: {
92
- goal: { type: "string", description: "What the code must accomplish" },
93
- language: {
94
- type: "string",
95
- description: "Optional language preference (default: TypeScript)"
96
- }
97
- },
98
- required: ["goal"]
99
- }
100
- }
101
- };
102
- function createResearchExecutor(config = {}) {
103
- const systemPrompt = config.systemPrompt ?? GENERIC_RESEARCHER_SYSTEM;
104
- const model = config.model ?? DEFAULT_RESEARCHER_MODEL;
105
- return async (args, ctx) => {
106
- const question = String(args.question ?? "");
107
- const scope = args.scope ? String(args.scope) : void 0;
108
- const { message, usage } = await routerCompletion({
109
- apiKey: ctx.apiKey,
110
- baseUrl: ctx.baseUrl,
111
- model,
112
- temperature: 0.3,
113
- maxTokens: 1800,
114
- messages: [
115
- { role: "system", content: systemPrompt },
116
- { role: "user", content: `Research: ${question}${scope ? `
117
- Scope: ${scope}` : ""}` }
118
- ],
119
- signal: ctx.signal
120
- });
121
- return { content: message.content ?? "", costUsd: estimateRouterCost(model, usage) };
122
- };
123
- }
124
- function createCodeExecutor(config = {}) {
125
- const systemPrompt = config.systemPrompt ?? GENERIC_CODER_SYSTEM;
126
- const model = config.model ?? DEFAULT_CODER_MODEL;
127
- return async (args, ctx) => {
128
- const goal = String(args.goal ?? "");
129
- const language = args.language ? String(args.language) : "TypeScript";
130
- const { message, usage } = await routerCompletion({
131
- apiKey: ctx.apiKey,
132
- baseUrl: ctx.baseUrl,
133
- model,
134
- temperature: 0.2,
135
- maxTokens: 2e3,
136
- messages: [
137
- { role: "system", content: `${systemPrompt}
138
-
139
- Language: ${language}` },
140
- { role: "user", content: `Produce: ${goal}` }
141
- ],
142
- signal: ctx.signal
143
- });
144
- return { content: message.content ?? "", costUsd: estimateRouterCost(model, usage) };
145
- };
146
- }
147
- function defaultDelegationTools(config = {}) {
148
- return {
149
- tools: [DEFAULT_DELEGATE_RESEARCH_TOOL, DEFAULT_DELEGATE_CODE_TOOL],
150
- executors: {
151
- delegate_research: createResearchExecutor(config.research),
152
- delegate_code: createCodeExecutor(config.code)
153
- },
154
- artifactTypeFor: (name) => name === "delegate_research" ? "research" : name === "delegate_code" ? "code" : void 0
155
- };
156
- }
157
-
158
- // src/multishot/judges.ts
159
- var DEFAULT_JUDGE_MODEL = "openai/gpt-4o-mini";
160
- async function runJudge(judge, input) {
161
- const apiKey = judge.apiKey ?? requireRouterApiKey();
162
- const baseUrl = judge.baseUrl ?? defaultRouterBaseUrl();
163
- const model = judge.model ?? process.env.JUDGE_MODEL ?? DEFAULT_JUDGE_MODEL;
164
- const prompt = judge.buildPrompt(input);
165
- let raw = "";
166
- try {
167
- const { message } = await routerCompletion({
168
- apiKey,
169
- baseUrl,
170
- model,
171
- temperature: 0,
172
- maxTokens: judge.maxTokens ?? 1500,
173
- messages: [
174
- { role: "system", content: judge.systemPrompt },
175
- { role: "user", content: prompt }
176
- ]
177
- });
178
- raw = (message.content ?? "").trim();
179
- } catch (err) {
180
- return {
181
- dimensions: {},
182
- composite: 0,
183
- failed: true,
184
- notes: `judge ${judge.name} call failed: ${err instanceof Error ? err.message : String(err)}`
185
- };
186
- }
187
- let parsed = null;
188
- try {
189
- const cleaned = raw.replace(/^```json\s*/i, "").replace(/```\s*$/, "").trim();
190
- parsed = JSON.parse(cleaned);
191
- } catch {
192
- return {
193
- dimensions: {},
194
- composite: 0,
195
- failed: true,
196
- notes: `judge ${judge.name} returned non-JSON: ${raw.slice(0, 200)}`
197
- };
198
- }
199
- const dimensions = {};
200
- let sum = 0;
201
- for (const dim of judge.dimensions) {
202
- const v = Number(parsed[dim.key] ?? 0);
203
- const clamped = Number.isFinite(v) ? Math.max(0, Math.min(10, v)) : 0;
204
- dimensions[dim.key] = clamped;
205
- sum += clamped;
206
- }
207
- return {
208
- dimensions,
209
- composite: judge.dimensions.length === 0 ? 0 : sum / judge.dimensions.length,
210
- notes: typeof parsed.notes === "string" ? parsed.notes : ""
211
- };
212
- }
213
- function renderDimensions(dims) {
214
- return dims.map((d) => `- ${d.key}: ${d.description}`).join("\n");
215
- }
216
- function renderJsonFooter(dims) {
217
- const fields = dims.map((d) => `"${d.key}":N`).join(",");
218
- return `Respond with ONLY this JSON (no markdown, no preamble):
219
- {${fields},"notes":"1-2 sentence critique"}`;
220
- }
221
-
222
- // src/multishot/matrix.ts
223
- import { mkdirSync, writeFileSync } from "fs";
224
- import { join } from "path";
225
-
226
- // src/multishot/types.ts
227
- var MultishotDriverEmptyError = class extends Error {
228
- constructor(turn) {
229
- super(`multishot: driver returned empty content twice at turn ${turn} \u2014 failing loud`);
230
- this.turn = turn;
231
- this.name = "MultishotDriverEmptyError";
232
- }
233
- turn;
234
- };
235
- var MultishotFatalToolError = class extends Error {
236
- constructor(message) {
237
- super(message);
238
- this.name = "MultishotFatalToolError";
239
- }
240
- };
241
-
242
- // src/multishot/multishot.ts
243
- async function runMultishot(opts) {
244
- const apiKey = opts.apiKey ?? requireRouterApiKey();
245
- const baseUrl = opts.baseUrl ?? defaultRouterBaseUrl();
246
- const maxTurns = opts.maxTurns ?? 10;
247
- const maxToolDispatches = opts.maxToolDispatches ?? 4;
248
- const agentModel = opts.agentModel ?? "openai/gpt-5.4";
249
- const driverModel = opts.driverModel ?? "openai/gpt-4o-mini";
250
- const driverModels = [driverModel, ...opts.driverFallbackModels ?? []];
251
- const agentMaxTokens = opts.agentMaxTokens ?? 2500;
252
- const toolFollowupMaxTokens = opts.toolFollowupMaxTokens ?? 2e3;
253
- const driverMaxTokens = opts.driverMaxTokens ?? 600;
254
- const bundle = opts.tools && opts.toolExecutors ? {
255
- tools: opts.tools,
256
- executors: opts.toolExecutors,
257
- artifactTypeFor: opts.artifactTypeFor ?? (() => void 0)
258
- } : defaultDelegationTools();
259
- const tools = opts.tools ?? bundle.tools;
260
- const executors = opts.toolExecutors ?? bundle.executors;
261
- const artifactTypeFor = opts.artifactTypeFor ?? bundle.artifactTypeFor;
262
- const routerTransport = (req) => routerCompletion({ apiKey, baseUrl, ...req });
263
- const agentTransport = opts.agentTransport ?? routerTransport;
264
- const driverTransport = opts.driverTransport ?? routerTransport;
265
- const start = Date.now();
266
- const transcript = [];
267
- const artifacts = [];
268
- let toolCalls = 0;
269
- let totalCostUsd = 0;
270
- const opener = opts.shape.buildOpener(opts.persona);
271
- transcript.push({ role: "user", content: opener });
272
- const systemPrompt = opts.profile.prompt?.systemPrompt ?? "";
273
- const agentMessages = [
274
- { role: "system", content: systemPrompt },
275
- { role: "user", content: opener }
276
- ];
277
- for (let turn = 0; turn < maxTurns; turn++) {
278
- if (opts.signal?.aborted) throw new Error("multishot aborted");
279
- let dispatchesThisTurn = 0;
280
- while (true) {
281
- const {
282
- message: agentMsg,
283
- usage: agentUsage,
284
- costUsd: agentCostUsd
285
- } = await agentTransport({
286
- model: agentModel,
287
- messages: agentMessages,
288
- tools,
289
- temperature: 0.7,
290
- maxTokens: dispatchesThisTurn === 0 ? agentMaxTokens : toolFollowupMaxTokens,
291
- signal: opts.signal
292
- });
293
- totalCostUsd += agentCostUsd ?? estimateRouterCost(agentModel, agentUsage);
294
- const agentText = (agentMsg.content ?? "").trim();
295
- const agentToolCalls = (agentMsg.tool_calls ?? []).map((tc) => ({
296
- id: tc.id,
297
- name: tc.function.name,
298
- args: (() => {
299
- try {
300
- return JSON.parse(tc.function.arguments);
301
- } catch {
302
- return {};
303
- }
304
- })()
305
- }));
306
- agentMessages.push({
307
- role: "assistant",
308
- content: agentText || null,
309
- ...agentMsg.tool_calls?.length ? { tool_calls: agentMsg.tool_calls } : {}
310
- });
311
- transcript.push({
312
- role: "assistant",
313
- content: agentText,
314
- toolCalls: agentToolCalls.length > 0 ? agentToolCalls : void 0
315
- });
316
- if (agentToolCalls.length === 0) break;
317
- dispatchesThisTurn += agentToolCalls.length;
318
- if (dispatchesThisTurn > maxToolDispatches) {
319
- throw new Error(
320
- `multishot: tool dispatch cap exceeded (${dispatchesThisTurn}/${maxToolDispatches}) on turn ${turn}`
321
- );
322
- }
323
- for (const tc of agentToolCalls) {
324
- toolCalls++;
325
- let toolResult = "";
326
- try {
327
- const executor = executors[tc.name];
328
- if (!executor) {
329
- toolResult = JSON.stringify({ error: `unknown tool ${tc.name}` });
330
- } else {
331
- const r = await executor(tc.args, { apiKey, baseUrl, signal: opts.signal });
332
- toolResult = r.content;
333
- totalCostUsd += r.costUsd;
334
- const artifactType = artifactTypeFor(tc.name);
335
- if (artifactType) {
336
- artifacts.push({
337
- type: artifactType,
338
- turn,
339
- invocation: { name: tc.name, args: tc.args },
340
- content: toolResult
341
- });
342
- }
343
- }
344
- } catch (err) {
345
- if (err instanceof MultishotFatalToolError) throw err;
346
- toolResult = JSON.stringify({ error: err instanceof Error ? err.message : String(err) });
347
- }
348
- agentMessages.push({ role: "tool", tool_call_id: tc.id, content: toolResult || "done" });
349
- transcript.push({ role: "tool", content: toolResult || "done", toolCallId: tc.id });
350
- }
351
- }
352
- if (turn < maxTurns - 1) {
353
- const driver = await driverTurn({
354
- transport: driverTransport,
355
- persona: opts.persona,
356
- shape: opts.shape,
357
- transcript,
358
- turn,
359
- models: driverModels,
360
- maxTokens: driverMaxTokens,
361
- signal: opts.signal
362
- });
363
- totalCostUsd += driver.costUsd;
364
- agentMessages.push({ role: "user", content: driver.content });
365
- transcript.push({ role: "user", content: driver.content });
366
- }
367
- }
368
- return { transcript, artifacts, toolCalls, durationMs: Date.now() - start, costUsd: totalCostUsd };
369
- }
370
- async function driverTurn(opts) {
371
- const driverSystem = opts.shape.buildDriverSystemPrompt(opts.persona);
372
- const driverMessages = [{ role: "system", content: driverSystem }];
373
- for (const msg of opts.transcript) {
374
- if (msg.role === "tool") continue;
375
- const content = driverVisibleContent(msg);
376
- if (!content) continue;
377
- if (msg.role === "assistant") driverMessages.push({ role: "user", content });
378
- else if (msg.role === "user") driverMessages.push({ role: "assistant", content });
379
- }
380
- for (const model of opts.models) {
381
- for (let attempt = 0; attempt < 2; attempt++) {
382
- const { message, usage, costUsd } = await opts.transport({
383
- model,
384
- messages: driverMessages,
385
- temperature: 0.9,
386
- maxTokens: opts.maxTokens,
387
- signal: opts.signal
388
- });
389
- const content = (message.content ?? "").trim();
390
- if (content.length > 0)
391
- return { content, costUsd: costUsd ?? estimateRouterCost(model, usage) };
392
- }
393
- }
394
- throw new MultishotDriverEmptyError(opts.turn);
395
- }
396
- function driverVisibleContent(msg) {
397
- const text = msg.content.trim();
398
- if (text.length > 0) return text;
399
- if (msg.role !== "assistant" || !msg.toolCalls?.length) return null;
400
- const toolNames = msg.toolCalls.map((call) => call.name.trim()).filter(Boolean);
401
- if (toolNames.length === 0) return "Agent called tools.";
402
- return `Agent called ${toolNames.length === 1 ? "tool" : "tools"}: ${toolNames.join(", ")}.`;
403
- }
404
-
405
- // src/multishot/matrix.ts
406
- function meanCompositeExcludingFailed(scores) {
407
- if (scores.length === 0) return 0;
408
- const live = scores.filter((s) => !s.failed);
409
- if (live.length === 0) return null;
410
- return live.reduce((sum, s) => sum + s.composite, 0) / live.length;
411
- }
412
- function computeCellComposite(input) {
413
- const contributions = [];
414
- if (!input.conversation.failed) contributions.push(input.conversation.composite);
415
- const codeMean = input.codeReviews ? meanCompositeExcludingFailed(input.codeReviews) : void 0;
416
- if (typeof codeMean === "number") contributions.push(codeMean);
417
- const contentMean = input.contentReviews ? meanCompositeExcludingFailed(input.contentReviews) : void 0;
418
- if (typeof contentMean === "number") contributions.push(contentMean);
419
- return {
420
- composite: contributions.length === 0 ? 0 : contributions.reduce((s, v) => s + v, 0) / contributions.length,
421
- codeComposite: codeMean ?? 0,
422
- contentComposite: contentMean ?? 0,
423
- allJudgesFailed: contributions.length === 0
424
- };
425
- }
426
- async function runMultishotMatrix(opts) {
427
- const codeTypes = new Set(opts.judges.codeArtifactTypes ?? ["code"]);
428
- const contentTypes = new Set(opts.judges.contentArtifactTypes ?? ["research"]);
429
- mkdirSync(opts.runDir, { recursive: true });
430
- const matrix = await runAgentMatrix({
431
- axes: [
432
- { name: "profile", values: opts.profiles },
433
- { name: "persona", values: opts.personas.map((p) => ({ id: p.id, value: p })) }
434
- ],
435
- reps: opts.reps ?? 1,
436
- maxConcurrency: opts.maxConcurrency ?? 2,
437
- costCeiling: opts.costCeiling,
438
- async runCell(cell) {
439
- const profile = cell.axes.profile?.value;
440
- const persona = cell.axes.persona?.value;
441
- const profileId = String(cell.axes.profile?.id ?? "unknown");
442
- const personaId = String(cell.axes.persona?.id ?? "unknown");
443
- const sim = await runMultishot({
444
- profile,
445
- persona,
446
- shape: opts.shape,
447
- tools: opts.tools,
448
- toolExecutors: opts.toolExecutors,
449
- artifactTypeFor: opts.artifactTypeFor,
450
- maxTurns: opts.maxTurns,
451
- maxToolDispatches: opts.maxToolDispatches,
452
- agentModel: opts.agentModel,
453
- driverModel: opts.driverModel,
454
- driverFallbackModels: opts.driverFallbackModels,
455
- agentMaxTokens: opts.agentMaxTokens,
456
- toolFollowupMaxTokens: opts.toolFollowupMaxTokens,
457
- driverMaxTokens: opts.driverMaxTokens,
458
- agentTransport: opts.agentTransport,
459
- driverTransport: opts.driverTransport,
460
- apiKey: opts.apiKey,
461
- baseUrl: opts.baseUrl
462
- });
463
- const codeArtifacts = sim.artifacts.filter((a) => codeTypes.has(a.type));
464
- const contentArtifacts = sim.artifacts.filter((a) => contentTypes.has(a.type));
465
- const [conversation, codeReviews, contentReviews] = await Promise.all([
466
- runJudge(withJudgeMaxTokens(opts.judges.conversation, opts.judgeMaxTokens), {
467
- transcript: sim.transcript,
468
- persona
469
- }),
470
- opts.judges.codeReview ? Promise.all(
471
- codeArtifacts.map(
472
- (artifact) => runJudge(withJudgeMaxTokens(opts.judges.codeReview, opts.judgeMaxTokens), {
473
- artifact,
474
- persona
475
- }).then((s) => ({
476
- ...s,
477
- turn: artifact.turn,
478
- type: artifact.type
479
- }))
480
- )
481
- ) : Promise.resolve([]),
482
- opts.judges.contentQuality ? Promise.all(
483
- contentArtifacts.map(
484
- (artifact) => runJudge(withJudgeMaxTokens(opts.judges.contentQuality, opts.judgeMaxTokens), {
485
- artifact,
486
- persona
487
- }).then((s) => ({
488
- ...s,
489
- turn: artifact.turn,
490
- type: artifact.type
491
- }))
492
- )
493
- ) : Promise.resolve([])
494
- ]);
495
- const { composite, codeComposite, contentComposite, allJudgesFailed } = computeCellComposite({
496
- conversation,
497
- codeReviews: opts.judges.codeReview ? codeReviews : void 0,
498
- contentReviews: opts.judges.contentQuality ? contentReviews : void 0
499
- });
500
- const cellScore = { composite, conversation };
501
- if (opts.judges.codeReview)
502
- cellScore.codeReview = { perArtifact: codeReviews, composite: codeComposite };
503
- if (opts.judges.contentQuality)
504
- cellScore.contentQuality = { perArtifact: contentReviews, composite: contentComposite };
505
- const cellDir = join(opts.runDir, profileId, personaId, `rep-${cell.rep}`);
506
- mkdirSync(cellDir, { recursive: true });
507
- writeFileSync(join(cellDir, "transcript.json"), JSON.stringify(sim.transcript, null, 2));
508
- writeFileSync(join(cellDir, "artifacts.json"), JSON.stringify(sim.artifacts, null, 2));
509
- writeFileSync(join(cellDir, "scores.json"), JSON.stringify(cellScore, null, 2));
510
- const notes = [`convo=${conversation.composite.toFixed(1)}`];
511
- if (opts.judges.codeReview) notes.push(`code=${codeComposite.toFixed(1)}`);
512
- if (opts.judges.contentQuality) notes.push(`content=${contentComposite.toFixed(1)}`);
513
- if (allJudgesFailed) notes.push("all-judges-failed");
514
- return {
515
- output: {
516
- turns: sim.transcript.length,
517
- toolCalls: sim.toolCalls,
518
- artifactCount: sim.artifacts.length
519
- },
520
- verdict: { valid: composite >= 5, score: composite, notes: notes.join(" ") },
521
- costUsd: sim.costUsd,
522
- durationMs: sim.durationMs
523
- };
524
- }
525
- });
526
- const summary = {
527
- cells: matrix.summary.totalCells,
528
- passRate: matrix.summary.overallPassRate,
529
- meanScore: matrix.summary.overallMeanScore,
530
- totalCostUsd: matrix.summary.totalCostUsd,
531
- durationMs: matrix.summary.durationMs,
532
- runsExecuted: matrix.summary.runsExecuted,
533
- cellsSkipped: matrix.summary.cellsSkipped,
534
- byProfile: matrix.byAxis.profile,
535
- byPersona: matrix.byAxis.persona
536
- };
537
- writeFileSync(join(opts.runDir, "summary.json"), JSON.stringify(summary, null, 2));
538
- const md = [
539
- `# Multishot matrix`,
540
- ``,
541
- `**Cells**: ${matrix.summary.totalCells} | **Pass rate**: ${(matrix.summary.overallPassRate * 100).toFixed(0)}% | **Mean**: ${matrix.summary.overallMeanScore.toFixed(2)} | **Cost**: $${matrix.summary.totalCostUsd.toFixed(2)} | **Duration**: ${(matrix.summary.durationMs / 1e3).toFixed(0)}s`,
542
- ``,
543
- `## By profile`,
544
- ``,
545
- "| profile | pass | mean | cost |",
546
- "|---|---|---|---|",
547
- ...Object.entries(matrix.byAxis.profile ?? {}).map(
548
- ([id, s]) => `| ${id} | ${(s.passRate * 100).toFixed(0)}% | ${s.meanScore.toFixed(2)} | $${s.totalCostUsd.toFixed(2)} |`
549
- ),
550
- ``,
551
- `## By persona`,
552
- ``,
553
- "| persona | pass | mean | cost |",
554
- "|---|---|---|---|",
555
- ...Object.entries(matrix.byAxis.persona ?? {}).map(
556
- ([id, s]) => `| ${id} | ${(s.passRate * 100).toFixed(0)}% | ${s.meanScore.toFixed(2)} | $${s.totalCostUsd.toFixed(2)} |`
557
- ),
558
- ``
559
- ];
560
- writeFileSync(join(opts.runDir, "summary.md"), md.join("\n"));
561
- return { matrix };
562
- }
563
- function withJudgeMaxTokens(judge, maxTokens) {
564
- if (maxTokens === void 0 || judge.maxTokens !== void 0) return judge;
565
- return { ...judge, maxTokens };
566
- }
567
- export {
568
- DEFAULT_CODER_MODEL,
569
- DEFAULT_DELEGATE_CODE_TOOL,
570
- DEFAULT_DELEGATE_RESEARCH_TOOL,
571
- DEFAULT_JUDGE_MODEL,
572
- DEFAULT_RESEARCHER_MODEL,
573
- MultishotDriverEmptyError,
574
- MultishotFatalToolError,
575
- computeCellComposite,
576
- createCodeExecutor,
577
- createResearchExecutor,
578
- defaultDelegationTools,
579
- defaultRouterBaseUrl,
580
- estimateRouterCost,
581
- renderDimensions,
582
- renderJsonFooter,
583
- requireRouterApiKey,
584
- routerCompletion,
585
- runJudge,
586
- runMultishot,
587
- runMultishotMatrix
588
- };
589
- //# sourceMappingURL=index.js.map