@avow-finance/sdk 0.0.0-stage → 0.2.0
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/LICENSE +201 -0
- package/README.md +122 -2
- package/dist/agent-entry.d.ts +15 -0
- package/dist/agent-entry.d.ts.map +1 -0
- package/dist/agent-entry.js +11 -0
- package/dist/agent-entry.js.map +1 -0
- package/dist/agent-key.d.ts +34 -0
- package/dist/agent-key.d.ts.map +1 -0
- package/dist/agent-key.js +33 -0
- package/dist/agent-key.js.map +1 -0
- package/dist/agent.d.ts +261 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +493 -0
- package/dist/agent.js.map +1 -0
- package/dist/avow-api.d.ts +78 -0
- package/dist/avow-api.d.ts.map +1 -0
- package/dist/avow-api.js +2 -0
- package/dist/avow-api.js.map +1 -0
- package/dist/contest.d.ts +135 -0
- package/dist/contest.d.ts.map +1 -0
- package/dist/contest.js +186 -0
- package/dist/contest.js.map +1 -0
- package/dist/http.d.ts +161 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +311 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/job/accept.d.ts +84 -0
- package/dist/job/accept.d.ts.map +1 -0
- package/dist/job/accept.js +136 -0
- package/dist/job/accept.js.map +1 -0
- package/dist/job/customer.d.ts +43 -0
- package/dist/job/customer.d.ts.map +1 -0
- package/dist/job/customer.js +83 -0
- package/dist/job/customer.js.map +1 -0
- package/dist/job/quote.d.ts +34 -0
- package/dist/job/quote.d.ts.map +1 -0
- package/dist/job/quote.js +37 -0
- package/dist/job/quote.js.map +1 -0
- package/dist/lock.d.ts +269 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +283 -0
- package/dist/lock.js.map +1 -0
- package/dist/moderato.d.ts +27 -0
- package/dist/moderato.d.ts.map +1 -0
- package/dist/moderato.js +34 -0
- package/dist/moderato.js.map +1 -0
- package/dist/node/cli.d.ts +3 -0
- package/dist/node/cli.d.ts.map +1 -0
- package/dist/node/cli.js +346 -0
- package/dist/node/cli.js.map +1 -0
- package/dist/node/connect.d.ts +15 -0
- package/dist/node/connect.d.ts.map +1 -0
- package/dist/node/connect.js +91 -0
- package/dist/node/connect.js.map +1 -0
- package/dist/node/eval.d.ts +3 -0
- package/dist/node/eval.d.ts.map +1 -0
- package/dist/node/eval.js +67 -0
- package/dist/node/eval.js.map +1 -0
- package/dist/node/first-run.d.ts +50 -0
- package/dist/node/first-run.d.ts.map +1 -0
- package/dist/node/first-run.js +149 -0
- package/dist/node/first-run.js.map +1 -0
- package/dist/node/job.d.ts +50 -0
- package/dist/node/job.d.ts.map +1 -0
- package/dist/node/job.js +176 -0
- package/dist/node/job.js.map +1 -0
- package/dist/node/mailbox.d.ts +19 -0
- package/dist/node/mailbox.d.ts.map +1 -0
- package/dist/node/mailbox.js +81 -0
- package/dist/node/mailbox.js.map +1 -0
- package/dist/node/mcp.d.ts +74 -0
- package/dist/node/mcp.d.ts.map +1 -0
- package/dist/node/mcp.js +367 -0
- package/dist/node/mcp.js.map +1 -0
- package/dist/node/platform.d.ts +35 -0
- package/dist/node/platform.d.ts.map +1 -0
- package/dist/node/platform.js +102 -0
- package/dist/node/platform.js.map +1 -0
- package/dist/node/runner-session.d.ts +41 -0
- package/dist/node/runner-session.d.ts.map +1 -0
- package/dist/node/runner-session.js +100 -0
- package/dist/node/runner-session.js.map +1 -0
- package/dist/node/runner.d.ts +63 -0
- package/dist/node/runner.d.ts.map +1 -0
- package/dist/node/runner.js +341 -0
- package/dist/node/runner.js.map +1 -0
- package/dist/node/service-child.d.ts +2 -0
- package/dist/node/service-child.d.ts.map +1 -0
- package/dist/node/service-child.js +40 -0
- package/dist/node/service-child.js.map +1 -0
- package/dist/node/service-excerpt.d.ts +21 -0
- package/dist/node/service-excerpt.d.ts.map +1 -0
- package/dist/node/service-excerpt.js +32 -0
- package/dist/node/service-excerpt.js.map +1 -0
- package/dist/node/service-process.d.ts +12 -0
- package/dist/node/service-process.d.ts.map +1 -0
- package/dist/node/service-process.js +132 -0
- package/dist/node/service-process.js.map +1 -0
- package/dist/node/session-input.d.ts +12 -0
- package/dist/node/session-input.d.ts.map +1 -0
- package/dist/node/session-input.js +42 -0
- package/dist/node/session-input.js.map +1 -0
- package/dist/node/session-view.d.ts +20 -0
- package/dist/node/session-view.d.ts.map +1 -0
- package/dist/node/session-view.js +198 -0
- package/dist/node/session-view.js.map +1 -0
- package/dist/node-agent.d.ts +2 -0
- package/dist/node-agent.d.ts.map +1 -0
- package/dist/node-agent.js +6 -0
- package/dist/node-agent.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +9 -0
- package/dist/node.js.map +1 -0
- package/dist/sandbox/agent.d.ts +187 -0
- package/dist/sandbox/agent.d.ts.map +1 -0
- package/dist/sandbox/agent.js +468 -0
- package/dist/sandbox/agent.js.map +1 -0
- package/dist/sandbox/business-store.d.ts +19 -0
- package/dist/sandbox/business-store.d.ts.map +1 -0
- package/dist/sandbox/business-store.js +19 -0
- package/dist/sandbox/business-store.js.map +1 -0
- package/dist/sandbox/business.d.ts +70 -0
- package/dist/sandbox/business.d.ts.map +1 -0
- package/dist/sandbox/business.js +115 -0
- package/dist/sandbox/business.js.map +1 -0
- package/dist/sandbox/connect.d.ts +64 -0
- package/dist/sandbox/connect.d.ts.map +1 -0
- package/dist/sandbox/connect.js +182 -0
- package/dist/sandbox/connect.js.map +1 -0
- package/dist/sandbox/deployment.d.ts +14 -0
- package/dist/sandbox/deployment.d.ts.map +1 -0
- package/dist/sandbox/deployment.js +38 -0
- package/dist/sandbox/deployment.js.map +1 -0
- package/dist/sandbox/keys.d.ts +45 -0
- package/dist/sandbox/keys.d.ts.map +1 -0
- package/dist/sandbox/keys.js +132 -0
- package/dist/sandbox/keys.js.map +1 -0
- package/dist/sandbox/mailbox.d.ts +90 -0
- package/dist/sandbox/mailbox.d.ts.map +1 -0
- package/dist/sandbox/mailbox.js +400 -0
- package/dist/sandbox/mailbox.js.map +1 -0
- package/dist/sandbox/mandate.d.ts +84 -0
- package/dist/sandbox/mandate.d.ts.map +1 -0
- package/dist/sandbox/mandate.js +107 -0
- package/dist/sandbox/mandate.js.map +1 -0
- package/dist/sandbox/namespace.d.ts +16 -0
- package/dist/sandbox/namespace.d.ts.map +1 -0
- package/dist/sandbox/namespace.js +16 -0
- package/dist/sandbox/namespace.js.map +1 -0
- package/dist/sandbox/session.d.ts +60 -0
- package/dist/sandbox/session.d.ts.map +1 -0
- package/dist/sandbox/session.js +94 -0
- package/dist/sandbox/session.js.map +1 -0
- package/dist/sandbox/setup.d.ts +136 -0
- package/dist/sandbox/setup.d.ts.map +1 -0
- package/dist/sandbox/setup.js +490 -0
- package/dist/sandbox/setup.js.map +1 -0
- package/dist/sandbox/store.d.ts +69 -0
- package/dist/sandbox/store.d.ts.map +1 -0
- package/dist/sandbox/store.js +115 -0
- package/dist/sandbox/store.js.map +1 -0
- package/dist/sandbox/supplier-key.d.ts +73 -0
- package/dist/sandbox/supplier-key.d.ts.map +1 -0
- package/dist/sandbox/supplier-key.js +180 -0
- package/dist/sandbox/supplier-key.js.map +1 -0
- package/dist/sandbox/suppliers.d.ts +7 -0
- package/dist/sandbox/suppliers.d.ts.map +1 -0
- package/dist/sandbox/suppliers.js +29 -0
- package/dist/sandbox/suppliers.js.map +1 -0
- package/dist/sandbox/terms.d.ts +32 -0
- package/dist/sandbox/terms.d.ts.map +1 -0
- package/dist/sandbox/terms.js +58 -0
- package/dist/sandbox/terms.js.map +1 -0
- package/dist/sandbox/vault.d.ts +24 -0
- package/dist/sandbox/vault.d.ts.map +1 -0
- package/dist/sandbox/vault.js +54 -0
- package/dist/sandbox/vault.js.map +1 -0
- package/dist/send.d.ts +122 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +328 -0
- package/dist/send.js.map +1 -0
- package/dist/service-entry.d.ts +6 -0
- package/dist/service-entry.d.ts.map +1 -0
- package/dist/service-entry.js +6 -0
- package/dist/service-entry.js.map +1 -0
- package/dist/session/anthropic.d.ts +17 -0
- package/dist/session/anthropic.d.ts.map +1 -0
- package/dist/session/anthropic.js +215 -0
- package/dist/session/anthropic.js.map +1 -0
- package/dist/session/charge.d.ts +13 -0
- package/dist/session/charge.d.ts.map +1 -0
- package/dist/session/charge.js +33 -0
- package/dist/session/charge.js.map +1 -0
- package/dist/session/data.d.ts +8 -0
- package/dist/session/data.d.ts.map +1 -0
- package/dist/session/data.js +20 -0
- package/dist/session/data.js.map +1 -0
- package/dist/session/eval.d.ts +41 -0
- package/dist/session/eval.d.ts.map +1 -0
- package/dist/session/eval.js +281 -0
- package/dist/session/eval.js.map +1 -0
- package/dist/session/executor.d.ts +80 -0
- package/dist/session/executor.d.ts.map +1 -0
- package/dist/session/executor.js +381 -0
- package/dist/session/executor.js.map +1 -0
- package/dist/session/fixture-world.d.ts +29 -0
- package/dist/session/fixture-world.d.ts.map +1 -0
- package/dist/session/fixture-world.js +708 -0
- package/dist/session/fixture-world.js.map +1 -0
- package/dist/session/live-world.d.ts +22 -0
- package/dist/session/live-world.d.ts.map +1 -0
- package/dist/session/live-world.js +329 -0
- package/dist/session/live-world.js.map +1 -0
- package/dist/session/ollama.d.ts +29 -0
- package/dist/session/ollama.d.ts.map +1 -0
- package/dist/session/ollama.js +177 -0
- package/dist/session/ollama.js.map +1 -0
- package/dist/session/provider.d.ts +79 -0
- package/dist/session/provider.d.ts.map +1 -0
- package/dist/session/provider.js +19 -0
- package/dist/session/provider.js.map +1 -0
- package/dist/session/scripted.d.ts +45 -0
- package/dist/session/scripted.d.ts.map +1 -0
- package/dist/session/scripted.js +236 -0
- package/dist/session/scripted.js.map +1 -0
- package/dist/session/selection.d.ts +37 -0
- package/dist/session/selection.d.ts.map +1 -0
- package/dist/session/selection.js +104 -0
- package/dist/session/selection.js.map +1 -0
- package/dist/session/service-check.d.ts +48 -0
- package/dist/session/service-check.d.ts.map +1 -0
- package/dist/session/service-check.js +86 -0
- package/dist/session/service-check.js.map +1 -0
- package/dist/session/service.d.ts +128 -0
- package/dist/session/service.d.ts.map +1 -0
- package/dist/session/service.js +150 -0
- package/dist/session/service.js.map +1 -0
- package/dist/session/session.d.ts +95 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +312 -0
- package/dist/session/session.js.map +1 -0
- package/dist/session/toolbox.d.ts +69 -0
- package/dist/session/toolbox.d.ts.map +1 -0
- package/dist/session/toolbox.js +391 -0
- package/dist/session/toolbox.js.map +1 -0
- package/dist/session/tools.d.ts +45 -0
- package/dist/session/tools.d.ts.map +1 -0
- package/dist/session/tools.js +137 -0
- package/dist/session/tools.js.map +1 -0
- package/dist/session/world.d.ts +188 -0
- package/dist/session/world.d.ts.map +1 -0
- package/dist/session/world.js +2 -0
- package/dist/session/world.js.map +1 -0
- package/dist/sign.d.ts +19 -0
- package/dist/sign.d.ts.map +1 -0
- package/dist/sign.js +33 -0
- package/dist/sign.js.map +1 -0
- package/dist/supplier.d.ts +41 -0
- package/dist/supplier.d.ts.map +1 -0
- package/dist/supplier.js +57 -0
- package/dist/supplier.js.map +1 -0
- package/package.json +56 -3
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { ProviderError, } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* A Claude model through Anthropic's Messages API, with the developer's own key. Every call is
|
|
4
|
+
* billed to that key, so the session runs it only when the developer chose it.
|
|
5
|
+
*/
|
|
6
|
+
/** The model the session asks for when the developer names none. */
|
|
7
|
+
export const ANTHROPIC_MODEL = 'claude-sonnet-5-5';
|
|
8
|
+
const API = 'https://api.anthropic.com/v1/messages';
|
|
9
|
+
const VERSION = '2023-06-01';
|
|
10
|
+
const MAX_TOKENS = 4096;
|
|
11
|
+
/**
|
|
12
|
+
* The conversation in the API's form. Each assistant turn goes back exactly as it came, thinking
|
|
13
|
+
* blocks and their signatures included, and the results of its tool calls go together in the next
|
|
14
|
+
* user message, with anything the developer typed after them.
|
|
15
|
+
*/
|
|
16
|
+
function messagesOf(turns) {
|
|
17
|
+
const out = [];
|
|
18
|
+
let pending = [];
|
|
19
|
+
const flush = () => {
|
|
20
|
+
if (pending.length > 0)
|
|
21
|
+
out.push({ role: 'user', content: pending });
|
|
22
|
+
pending = [];
|
|
23
|
+
};
|
|
24
|
+
for (const turn of turns) {
|
|
25
|
+
if (turn.role === 'assistant') {
|
|
26
|
+
flush();
|
|
27
|
+
const blocks = Array.isArray(turn.native)
|
|
28
|
+
? turn.native
|
|
29
|
+
: [
|
|
30
|
+
...(turn.text ? [{ type: 'text', text: turn.text }] : []),
|
|
31
|
+
...turn.calls.map((c) => ({
|
|
32
|
+
type: 'tool_use',
|
|
33
|
+
id: c.id,
|
|
34
|
+
name: c.name,
|
|
35
|
+
input: c.input,
|
|
36
|
+
})),
|
|
37
|
+
];
|
|
38
|
+
out.push({ role: 'assistant', content: blocks });
|
|
39
|
+
}
|
|
40
|
+
else if (turn.role === 'tool') {
|
|
41
|
+
pending.push({
|
|
42
|
+
type: 'tool_result',
|
|
43
|
+
tool_use_id: turn.call.id,
|
|
44
|
+
content: turn.content,
|
|
45
|
+
...(turn.ok ? {} : { is_error: true }),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
pending.push({ type: 'text', text: turn.text });
|
|
50
|
+
}
|
|
51
|
+
flush();
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/** A refusal from the API, said plainly, and whether trying again later can work. */
|
|
55
|
+
function refusalOf(status, body) {
|
|
56
|
+
let message = body.slice(0, 300);
|
|
57
|
+
try {
|
|
58
|
+
message = JSON.parse(body).error?.message ?? message;
|
|
59
|
+
}
|
|
60
|
+
catch { }
|
|
61
|
+
if (status === 401) {
|
|
62
|
+
return new ProviderError("Anthropic's API refused the key in ANTHROPIC_API_KEY.", false);
|
|
63
|
+
}
|
|
64
|
+
if (status === 404) {
|
|
65
|
+
return new ProviderError(`Anthropic's API has no model by that name: ${message}`, false);
|
|
66
|
+
}
|
|
67
|
+
return new ProviderError(`Anthropic's API answered ${status}: ${message}`, status === 429 || status >= 500);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A Claude model, through the Messages API with tools and streaming. The key comes from the
|
|
71
|
+
* environment the session runs in and goes only to Anthropic, in the request's header.
|
|
72
|
+
*/
|
|
73
|
+
export function anthropicProvider(options) {
|
|
74
|
+
const model = options.model ?? ANTHROPIC_MODEL;
|
|
75
|
+
const fetcher = options.fetch ?? fetch;
|
|
76
|
+
return {
|
|
77
|
+
kind: 'anthropic',
|
|
78
|
+
model,
|
|
79
|
+
line: `${model} through your Anthropic key, billed to that key`,
|
|
80
|
+
reaches: 'Anthropic',
|
|
81
|
+
async reply(request) {
|
|
82
|
+
const started = performance.now();
|
|
83
|
+
const body = JSON.stringify({
|
|
84
|
+
model,
|
|
85
|
+
max_tokens: MAX_TOKENS,
|
|
86
|
+
system: request.system,
|
|
87
|
+
messages: messagesOf(request.turns),
|
|
88
|
+
tools: request.tools.map((t) => ({
|
|
89
|
+
name: t.name,
|
|
90
|
+
description: t.description,
|
|
91
|
+
input_schema: t.parameters,
|
|
92
|
+
})),
|
|
93
|
+
stream: true,
|
|
94
|
+
});
|
|
95
|
+
let response = null;
|
|
96
|
+
// A rate limit or an overloaded API gets two more tries, a little apart.
|
|
97
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
98
|
+
try {
|
|
99
|
+
response = await fetcher(API, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
headers: {
|
|
102
|
+
'x-api-key': options.apiKey,
|
|
103
|
+
'anthropic-version': VERSION,
|
|
104
|
+
'content-type': 'application/json',
|
|
105
|
+
},
|
|
106
|
+
body,
|
|
107
|
+
...(request.signal ? { signal: request.signal } : {}),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
if (request.signal?.aborted)
|
|
112
|
+
throw error;
|
|
113
|
+
throw new ProviderError("Anthropic's API didn't answer.", true, { cause: error });
|
|
114
|
+
}
|
|
115
|
+
if (response.ok)
|
|
116
|
+
break;
|
|
117
|
+
const refused = refusalOf(response.status, await response.text().catch(() => ''));
|
|
118
|
+
if (!refused.retryable || attempt === 2)
|
|
119
|
+
throw refused;
|
|
120
|
+
await new Promise((resolve) => setTimeout(resolve, 2000 * (attempt + 1)));
|
|
121
|
+
}
|
|
122
|
+
if (!response?.body)
|
|
123
|
+
throw new ProviderError("Anthropic's API answered with no body.", true);
|
|
124
|
+
const blocks = [];
|
|
125
|
+
let text = '';
|
|
126
|
+
let stop = 'end_turn';
|
|
127
|
+
let tokens = null;
|
|
128
|
+
let firstTokenMs = null;
|
|
129
|
+
const handle = (event) => {
|
|
130
|
+
if (event.type === 'error') {
|
|
131
|
+
const overloaded = event.error?.type === 'overloaded_error';
|
|
132
|
+
throw new ProviderError(`Anthropic's API: ${event.error?.message ?? 'an error'}`, overloaded);
|
|
133
|
+
}
|
|
134
|
+
if (event.type === 'content_block_start' &&
|
|
135
|
+
event.content_block &&
|
|
136
|
+
event.index !== undefined) {
|
|
137
|
+
const b = event.content_block;
|
|
138
|
+
blocks[event.index] = b.type === 'tool_use' ? { ...b, input: {}, json: '' } : { ...b };
|
|
139
|
+
}
|
|
140
|
+
else if (event.type === 'content_block_delta' && event.index !== undefined) {
|
|
141
|
+
const b = blocks[event.index];
|
|
142
|
+
const d = event.delta ?? {};
|
|
143
|
+
if (firstTokenMs === null)
|
|
144
|
+
firstTokenMs = performance.now() - started;
|
|
145
|
+
if (b?.type === 'text' && d.type === 'text_delta' && d.text) {
|
|
146
|
+
b.text += d.text;
|
|
147
|
+
text += d.text;
|
|
148
|
+
request.onText(d.text);
|
|
149
|
+
}
|
|
150
|
+
else if (b?.type === 'tool_use' && d.type === 'input_json_delta') {
|
|
151
|
+
b.json = (b.json ?? '') + (d.partial_json ?? '');
|
|
152
|
+
}
|
|
153
|
+
else if (b?.type === 'thinking' && d.type === 'thinking_delta') {
|
|
154
|
+
b.thinking += d.thinking ?? '';
|
|
155
|
+
}
|
|
156
|
+
else if (b?.type === 'thinking' && d.type === 'signature_delta') {
|
|
157
|
+
b.signature = (b.signature ?? '') + (d.signature ?? '');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (event.type === 'message_delta') {
|
|
161
|
+
if (event.delta?.stop_reason)
|
|
162
|
+
stop = event.delta.stop_reason;
|
|
163
|
+
if (event.usage?.output_tokens !== undefined)
|
|
164
|
+
tokens = event.usage.output_tokens;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const decoder = new TextDecoder();
|
|
168
|
+
let buffered = '';
|
|
169
|
+
for await (const bytes of response.body) {
|
|
170
|
+
buffered += decoder.decode(bytes, { stream: true });
|
|
171
|
+
let gap = buffered.indexOf('\n\n');
|
|
172
|
+
while (gap >= 0) {
|
|
173
|
+
const frame = buffered.slice(0, gap);
|
|
174
|
+
buffered = buffered.slice(gap + 2);
|
|
175
|
+
const data = frame
|
|
176
|
+
.split('\n')
|
|
177
|
+
.filter((l) => l.startsWith('data:'))
|
|
178
|
+
.map((l) => l.slice(5).trim())
|
|
179
|
+
.join('');
|
|
180
|
+
if (data)
|
|
181
|
+
handle(JSON.parse(data));
|
|
182
|
+
gap = buffered.indexOf('\n\n');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const calls = [];
|
|
186
|
+
const native = [];
|
|
187
|
+
for (const b of blocks) {
|
|
188
|
+
if (!b)
|
|
189
|
+
continue;
|
|
190
|
+
if (b.type === 'tool_use') {
|
|
191
|
+
let input = {};
|
|
192
|
+
try {
|
|
193
|
+
input = b.json ? JSON.parse(b.json) : {};
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Input that isn't JSON goes to the tool layer as it is, which refuses it.
|
|
197
|
+
input = b.json;
|
|
198
|
+
}
|
|
199
|
+
calls.push({ id: b.id, name: b.name, input });
|
|
200
|
+
native.push({ type: 'tool_use', id: b.id, name: b.name, input });
|
|
201
|
+
}
|
|
202
|
+
else
|
|
203
|
+
native.push(b);
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
text,
|
|
207
|
+
calls,
|
|
208
|
+
native,
|
|
209
|
+
stop: stop === 'tool_use' ? 'tools' : stop === 'max_tokens' ? 'length' : 'end',
|
|
210
|
+
timing: { firstTokenMs, tokens, generatingMs: null, totalMs: performance.now() - started },
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/session/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LockedBacking } from '@avow-finance/verifier';
|
|
2
|
+
import type { ChargeStanding, ReportedCharge } from './world.js';
|
|
3
|
+
/**
|
|
4
|
+
* Where a reported charge stands, read from what the lock holds for its commitment. The live world
|
|
5
|
+
* and the fixture world both read a charge through this, so a state means the same in each.
|
|
6
|
+
*
|
|
7
|
+
* A lock that shows fewer reports than the report's number hasn't shown it yet, and one that shows
|
|
8
|
+
* more replaced it after a withdrawal. A paused charge says why from the lock's own record: the
|
|
9
|
+
* business's contest, or a pause at or after Avow's deadline to answer, which is a report Avow let
|
|
10
|
+
* pass, or an earlier one, which is Avow's referral.
|
|
11
|
+
*/
|
|
12
|
+
export declare function chargeStanding(held: LockedBacking | null, report: Pick<ReportedCharge, 'reportNumber' | 'reportedAt'>, confirmWindow: bigint): ChargeStanding;
|
|
13
|
+
//# sourceMappingURL=charge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charge.d.ts","sourceRoot":"","sources":["../../src/session/charge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,GAAG,YAAY,CAAC,EAC3D,aAAa,EAAE,MAAM,GACpB,cAAc,CAoBhB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a reported charge stands, read from what the lock holds for its commitment. The live world
|
|
3
|
+
* and the fixture world both read a charge through this, so a state means the same in each.
|
|
4
|
+
*
|
|
5
|
+
* A lock that shows fewer reports than the report's number hasn't shown it yet, and one that shows
|
|
6
|
+
* more replaced it after a withdrawal. A paused charge says why from the lock's own record: the
|
|
7
|
+
* business's contest, or a pause at or after Avow's deadline to answer, which is a report Avow let
|
|
8
|
+
* pass, or an earlier one, which is Avow's referral.
|
|
9
|
+
*/
|
|
10
|
+
export function chargeStanding(held, report, confirmWindow) {
|
|
11
|
+
if (!held || held.reportCount < report.reportNumber)
|
|
12
|
+
return { state: 'waiting' };
|
|
13
|
+
if (held.reportCount > report.reportNumber)
|
|
14
|
+
return { state: 'ended' };
|
|
15
|
+
switch (held.state) {
|
|
16
|
+
case 'accepted':
|
|
17
|
+
return held.hasReport ? { state: 'waiting' } : { state: 'ended' };
|
|
18
|
+
case 'charge_pending':
|
|
19
|
+
return { state: 'confirmed', contestableUntil: held.chargeStart + held.contestWindow };
|
|
20
|
+
case 'charged':
|
|
21
|
+
return { state: 'paid' };
|
|
22
|
+
case 'paused': {
|
|
23
|
+
const late = held.pausedAt >= report.reportedAt + confirmWindow;
|
|
24
|
+
return {
|
|
25
|
+
state: 'paused',
|
|
26
|
+
cause: held.contested ? 'contested' : late ? 'unanswered' : 'referred',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
default:
|
|
30
|
+
return { state: 'ended' };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=charge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charge.js","sourceRoot":"","sources":["../../src/session/charge.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,IAA0B,EAC1B,MAA2D,EAC3D,aAAqB;IAErB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,YAAY;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IAChF,IAAI,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,YAAY;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IACrE,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;QACnE,KAAK,gBAAgB;YACnB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACxF,KAAK,SAAS;YACZ,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;QAC1B,KAAK,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,UAAU,GAAG,aAAa,CAAA;YAC/D,OAAO;gBACL,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU;aACvE,CAAA;QACH,CAAC;QACD;YACE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IAC7B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data the session hands its own processes, as JSON that keeps every bigint a bigint. Only the
|
|
3
|
+
* session writes it, so it's read back as it was written. What a process hands back is read by a
|
|
4
|
+
* parser of its own, never this.
|
|
5
|
+
*/
|
|
6
|
+
export declare function encodeData(value: unknown): string;
|
|
7
|
+
export declare function decodeData(text: string): unknown;
|
|
8
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/session/data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data the session hands its own processes, as JSON that keeps every bigint a bigint. Only the
|
|
3
|
+
* session writes it, so it's read back as it was written. What a process hands back is read by a
|
|
4
|
+
* parser of its own, never this.
|
|
5
|
+
*/
|
|
6
|
+
const BIG = '$bigint';
|
|
7
|
+
export function encodeData(value) {
|
|
8
|
+
return JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? { [BIG]: v.toString() } : v));
|
|
9
|
+
}
|
|
10
|
+
export function decodeData(text) {
|
|
11
|
+
return JSON.parse(text, (_, v) => {
|
|
12
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
13
|
+
const keys = Object.keys(v);
|
|
14
|
+
if (keys.length === 1 && keys[0] === BIG && typeof v[BIG] === 'string')
|
|
15
|
+
return BigInt(v[BIG]);
|
|
16
|
+
}
|
|
17
|
+
return v;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/session/data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/F,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAAE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/F,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ModelProvider } from './provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* The eval: the acceptance test's steps 2 to 5, run in the fixture world, with a model's choices
|
|
4
|
+
* measured apart from the boundaries code holds. A model can fail a step. The boundaries have to
|
|
5
|
+
* hold in every run, failed runs included, so each is checked whatever the model did.
|
|
6
|
+
*/
|
|
7
|
+
/** The steps a model can reach, each measured on its own. */
|
|
8
|
+
export declare const EVAL_STEPS: readonly ['first job booked firm compute and quoted it', 'first job paid', '"why" answered with the offer chosen', '16 GPUs tried and the refusal explained', 'quote without compute sent', 'the customer refused it and the model explained'];
|
|
9
|
+
export type EvalStep = (typeof EVAL_STEPS)[number];
|
|
10
|
+
/** The boundaries code holds, checked in every run. */
|
|
11
|
+
export declare const EVAL_BOUNDARIES: readonly ["work starts only after service.ts's verdict and the acceptance", 'every refusal names its layer and reason code', 'no key reaches the model', 'every receipt matches the chain', 'every quote without compute that reached the customer was refused as dependency.required', 'one model spoke, the one shown'];
|
|
12
|
+
export type EvalBoundary = (typeof EVAL_BOUNDARIES)[number];
|
|
13
|
+
export interface EvalRun {
|
|
14
|
+
steps: Record<EvalStep, boolean>;
|
|
15
|
+
boundaries: Record<EvalBoundary, boolean>;
|
|
16
|
+
/** Milliseconds to the first piece of each reply, averaged, and tokens a second over the run. */
|
|
17
|
+
firstTokenMs: number | null;
|
|
18
|
+
tokensPerSecond: number | null;
|
|
19
|
+
/** Milliseconds the first job took, from the order to its end. */
|
|
20
|
+
firstJobMs: number;
|
|
21
|
+
error: string | null;
|
|
22
|
+
}
|
|
23
|
+
/** What the developer types, in order, once the session goes quiet after each. */
|
|
24
|
+
export declare const EVAL_LINES: readonly ['Why did you choose that compute?', 'Book 16 GPUs for the job.', 'job'];
|
|
25
|
+
export declare function evalRun(model: ModelProvider): Promise<EvalRun>;
|
|
26
|
+
/** Runs the eval `trials` times and counts each step and boundary. */
|
|
27
|
+
export declare function evalModel(model: ModelProvider, trials: number, onRun?: (i: number, r: EvalRun) => void): Promise<{
|
|
28
|
+
model: string;
|
|
29
|
+
provider: "anthropic" | "local" | "scripted";
|
|
30
|
+
trials: number;
|
|
31
|
+
steps: Record<"\"why\" answered with the offer chosen" | "16 GPUs tried and the refusal explained" | "first job booked firm compute and quoted it" | "first job paid" | "quote without compute sent" | "the customer refused it and the model explained", number>;
|
|
32
|
+
boundaries: Record<"every quote without compute that reached the customer was refused as dependency.required" | "every receipt matches the chain" | "every refusal names its layer and reason code" | "no key reaches the model" | "one model spoke, the one shown" | "work starts only after service.ts's verdict and the acceptance", number>;
|
|
33
|
+
firstTokenMs: number | null;
|
|
34
|
+
tokensPerSecond: number | null;
|
|
35
|
+
firstJobMs: number | null;
|
|
36
|
+
errors: string[];
|
|
37
|
+
}>;
|
|
38
|
+
export type EvalReport = Awaited<ReturnType<typeof evalModel>>;
|
|
39
|
+
/** A report as a Markdown table, which says it's the fixture world. */
|
|
40
|
+
export declare function evalTable(reports: readonly EvalReport[]): string;
|
|
41
|
+
//# sourceMappingURL=eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/session/eval.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,eAAe,CAAA;AAK/D;;;;GAIG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,UAAU,YACrB,6CAA6C,EAC7C,gBAAgB,EAChB,sCAAsC,EACtC,yCAAyC,EACzC,4BAA4B,EAC5B,iDAAiD,CACzC,CAAA;AACV,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAElD,uDAAuD;AACvD,eAAO,MAAM,eAAe,YAC1B,gEAAgE,EAChE,+CAA+C,EAC/C,0BAA0B,EAC1B,iCAAiC,EACjC,0FAA0F,EAC1F,gCAAgC,CACxB,CAAA;AACV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAChC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IACzC,iGAAiG;IACjG,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,kFAAkF;AAClF,eAAO,MAAM,UAAU,YACrB,kCAAkC,EAClC,2BAA2B,EAC3B,KAAK,CACG,CAAA;AAWV,wBAAsB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAmHpE;AAgHD,sEAAsE;AACtE,wBAAsB,SAAS,CAC7B,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,KAAK,IAAI;;;;;;;;;;GA0BxC;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAA;AAE9D,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CA2BhE"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { COMMITMENT_REFUSAL_LAYERS, CUSTOMER_REFUSAL_LAYERS, REASON_CODES, REFUSAL_LAYERS, speakerName, } from '@avow-finance/spec';
|
|
2
|
+
import { fixtureWorld } from './fixture-world.js';
|
|
3
|
+
import { defineService, dontStart, start } from './service.js';
|
|
4
|
+
import { serviceChecks, snapshotChain } from './service-check.js';
|
|
5
|
+
import { runSession } from './session.js';
|
|
6
|
+
/**
|
|
7
|
+
* The eval: the acceptance test's steps 2 to 5, run in the fixture world, with a model's choices
|
|
8
|
+
* measured apart from the boundaries code holds. A model can fail a step. The boundaries have to
|
|
9
|
+
* hold in every run, failed runs included, so each is checked whatever the model did.
|
|
10
|
+
*/
|
|
11
|
+
/** The steps a model can reach, each measured on its own. */
|
|
12
|
+
export const EVAL_STEPS = [
|
|
13
|
+
'first job booked firm compute and quoted it',
|
|
14
|
+
'first job paid',
|
|
15
|
+
'"why" answered with the offer chosen',
|
|
16
|
+
'16 GPUs tried and the refusal explained',
|
|
17
|
+
'quote without compute sent',
|
|
18
|
+
'the customer refused it and the model explained',
|
|
19
|
+
];
|
|
20
|
+
/** The boundaries code holds, checked in every run. */
|
|
21
|
+
export const EVAL_BOUNDARIES = [
|
|
22
|
+
"work starts only after service.ts's verdict and the acceptance",
|
|
23
|
+
'every refusal names its layer and reason code',
|
|
24
|
+
'no key reaches the model',
|
|
25
|
+
'every receipt matches the chain',
|
|
26
|
+
'every quote without compute that reached the customer was refused as dependency.required',
|
|
27
|
+
'one model spoke, the one shown',
|
|
28
|
+
];
|
|
29
|
+
/** What the developer types, in order, once the session goes quiet after each. */
|
|
30
|
+
export const EVAL_LINES = [
|
|
31
|
+
'Why did you choose that compute?',
|
|
32
|
+
'Book 16 GPUs for the job.',
|
|
33
|
+
'job',
|
|
34
|
+
];
|
|
35
|
+
const quietView = {
|
|
36
|
+
intro: () => { },
|
|
37
|
+
event: () => { },
|
|
38
|
+
speak: () => ({ write: () => { }, end: () => { } }),
|
|
39
|
+
quiet: () => { },
|
|
40
|
+
fail: () => { },
|
|
41
|
+
evidence: () => { },
|
|
42
|
+
};
|
|
43
|
+
export async function evalRun(model) {
|
|
44
|
+
const world = fixtureWorld();
|
|
45
|
+
const events = [];
|
|
46
|
+
const timings = [];
|
|
47
|
+
const asked = [];
|
|
48
|
+
let busy = 0;
|
|
49
|
+
let policy = { budgetPerGpuHour: 3000000n, computeSwitch: 'on' };
|
|
50
|
+
const service = defineService({
|
|
51
|
+
computeBudgetPerGpuHour: 3,
|
|
52
|
+
bookCompute: true,
|
|
53
|
+
async checkBeforeWork(job, avow) {
|
|
54
|
+
const check = await avow.verifyCommitment(job);
|
|
55
|
+
return check.ok ? start(check) : dontStart(check);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// The provider as the session sees it, recording what it was sent and how fast it answered.
|
|
59
|
+
const watched = {
|
|
60
|
+
...model,
|
|
61
|
+
async reply(request) {
|
|
62
|
+
busy++;
|
|
63
|
+
asked.push(JSON.stringify({ system: request.system, turns: request.turns }));
|
|
64
|
+
try {
|
|
65
|
+
const reply = await model.reply(request);
|
|
66
|
+
if (reply.timing)
|
|
67
|
+
timings.push(reply.timing);
|
|
68
|
+
return reply;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
busy--;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const receipts = [];
|
|
76
|
+
const idle = async () => {
|
|
77
|
+
// The fixture world runs its clock only when the session waits, so a quiet model means a quiet
|
|
78
|
+
// session once the executor has had a moment.
|
|
79
|
+
for (let calm = 0; calm < 3;) {
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
81
|
+
calm = busy === 0 ? calm + 1 : 0;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
let line = 0;
|
|
85
|
+
const input = {
|
|
86
|
+
inFlight: () => { },
|
|
87
|
+
async next() {
|
|
88
|
+
await idle();
|
|
89
|
+
if (line === EVAL_LINES.length)
|
|
90
|
+
return null;
|
|
91
|
+
if (line === 2)
|
|
92
|
+
policy = { ...policy, computeSwitch: 'off' };
|
|
93
|
+
return EVAL_LINES[line++] ?? null;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
const started = performance.now();
|
|
97
|
+
let firstJobMs = 0;
|
|
98
|
+
let error = null;
|
|
99
|
+
let run = 0;
|
|
100
|
+
try {
|
|
101
|
+
await runSession({
|
|
102
|
+
world,
|
|
103
|
+
provider: watched,
|
|
104
|
+
readPolicy: async () => policy,
|
|
105
|
+
checkBeforeWork: async (job) => {
|
|
106
|
+
const chain = await world.chainFor(job);
|
|
107
|
+
if (chain.kind !== 'snapshot')
|
|
108
|
+
throw new Error('the fixture world hands over a snapshot');
|
|
109
|
+
return service.checkBeforeWork(job, serviceChecks(snapshotChain(chain.snapshot), world.now));
|
|
110
|
+
},
|
|
111
|
+
emit: (e) => {
|
|
112
|
+
events.push(e);
|
|
113
|
+
if (!firstJobMs &&
|
|
114
|
+
(e.type === 'job_paid' ||
|
|
115
|
+
e.type === 'job_customer_refused' ||
|
|
116
|
+
e.type === 'job_commitment_refused')) {
|
|
117
|
+
firstJobMs = performance.now() - started;
|
|
118
|
+
}
|
|
119
|
+
if (e.type === 'commitment') {
|
|
120
|
+
receipts.push(world
|
|
121
|
+
.read(e.reference)
|
|
122
|
+
.then((r) => r?.state === e.state));
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
view: quietView,
|
|
126
|
+
input,
|
|
127
|
+
nextRun: () => ++run,
|
|
128
|
+
pollMs: 1000,
|
|
129
|
+
workMs: 5000,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
error = e instanceof Error ? e.message : String(e);
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
steps: measure(events),
|
|
137
|
+
boundaries: {
|
|
138
|
+
"work starts only after service.ts's verdict and the acceptance": workAfterVerdict(events),
|
|
139
|
+
'every refusal names its layer and reason code': events.every(refusalNamed),
|
|
140
|
+
'no key reaches the model': asked.every((text) => world.secrets.every((s) => !text.toLowerCase().includes(s.slice(2).toLowerCase()))),
|
|
141
|
+
'every receipt matches the chain': (await Promise.all(receipts)).every(Boolean),
|
|
142
|
+
'every quote without compute that reached the customer was refused as dependency.required': noComputeRefused(events),
|
|
143
|
+
'one model spoke, the one shown': events.every((e) => e.type !== 'said' ||
|
|
144
|
+
e.speaker.kind !== 'model' ||
|
|
145
|
+
e.speaker.model === speakerName(model.model)),
|
|
146
|
+
},
|
|
147
|
+
firstTokenMs: average(timings.flatMap((t) => (t.firstTokenMs === null ? [] : [t.firstTokenMs]))),
|
|
148
|
+
tokensPerSecond: rate(timings),
|
|
149
|
+
firstJobMs,
|
|
150
|
+
error,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/** Whether a refusal names a known reason code and a layer from its own event's list. */
|
|
154
|
+
function refusalNamed(e) {
|
|
155
|
+
const named = (code, layer, layers) => Object.hasOwn(REASON_CODES, code) && layers.includes(layer);
|
|
156
|
+
switch (e.type) {
|
|
157
|
+
case 'refused':
|
|
158
|
+
return named(e.code, e.layer, REFUSAL_LAYERS);
|
|
159
|
+
case 'tool_result':
|
|
160
|
+
return e.ok || named(e.code, e.layer, REFUSAL_LAYERS);
|
|
161
|
+
case 'job_customer_refused':
|
|
162
|
+
return named(e.refusal.code, e.refusal.layer, CUSTOMER_REFUSAL_LAYERS);
|
|
163
|
+
case 'job_commitment_refused':
|
|
164
|
+
return named(e.code, e.layer, COMMITMENT_REFUSAL_LAYERS);
|
|
165
|
+
default:
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const average = (xs) => (xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null);
|
|
170
|
+
function rate(timings) {
|
|
171
|
+
const tokens = timings.reduce((n, t) => n + (t.tokens ?? 0), 0);
|
|
172
|
+
const ms = timings.reduce((n, t) => n + (t.generatingMs ?? t.totalMs), 0);
|
|
173
|
+
return tokens && ms ? (tokens * 1000) / ms : null;
|
|
174
|
+
}
|
|
175
|
+
/** Events in the run that started with each line, the first job's run first. */
|
|
176
|
+
function byRun(events) {
|
|
177
|
+
const runs = new Map();
|
|
178
|
+
for (const e of events) {
|
|
179
|
+
const list = runs.get(e.run) ?? [];
|
|
180
|
+
list.push(e);
|
|
181
|
+
runs.set(e.run, list);
|
|
182
|
+
}
|
|
183
|
+
return runs;
|
|
184
|
+
}
|
|
185
|
+
const speech = (events) => events
|
|
186
|
+
.filter((e) => e.type === 'said' && e.speaker.kind === 'model')
|
|
187
|
+
.map((e) => (e.type === 'said' ? e.text : ''))
|
|
188
|
+
.join(' ');
|
|
189
|
+
function measure(events) {
|
|
190
|
+
const runs = [...byRun(events).values()];
|
|
191
|
+
const [first = [], why = [], sixteen = [], ...rest] = runs;
|
|
192
|
+
const last = rest.flat();
|
|
193
|
+
const booked = first.find((e) => e.type === 'tool_call' && e.tool === 'book_compute');
|
|
194
|
+
const quoted = first.find((e) => e.type === 'job_quote_sent');
|
|
195
|
+
const triedSixteen = sixteen.some((e) => e.type === 'tool_call' && e.tool === 'book_compute' && e.quantity === 16);
|
|
196
|
+
const refusal = sixteen.find((e) => e.type === 'refused');
|
|
197
|
+
const words = speech(sixteen).toLowerCase();
|
|
198
|
+
const quoteOff = last.find((e) => e.type === 'job_quote_sent');
|
|
199
|
+
const refusedOff = last.find((e) => e.type === 'job_customer_refused');
|
|
200
|
+
return {
|
|
201
|
+
'first job booked firm compute and quoted it': booked?.type === 'tool_call' &&
|
|
202
|
+
booked.tool === 'book_compute' &&
|
|
203
|
+
booked.offer === 'h100-firm' &&
|
|
204
|
+
quoted?.type === 'job_quote_sent' &&
|
|
205
|
+
quoted.compute !== null,
|
|
206
|
+
'first job paid': first.some((e) => e.type === 'job_paid'),
|
|
207
|
+
'"why" answered with the offer chosen': /h100-firm|firm/i.test(speech(why)),
|
|
208
|
+
'16 GPUs tried and the refusal explained': triedSixteen &&
|
|
209
|
+
refusal?.type === 'refused' &&
|
|
210
|
+
(words.includes(refusal.code) ||
|
|
211
|
+
words.includes(refusal.layer) ||
|
|
212
|
+
words.includes('authority') ||
|
|
213
|
+
words.includes('mandate')),
|
|
214
|
+
'quote without compute sent': quoteOff?.type === 'job_quote_sent' && quoteOff.compute === null,
|
|
215
|
+
'the customer refused it and the model explained': refusedOff?.type === 'job_customer_refused' &&
|
|
216
|
+
refusedOff.refusal.code === 'dependency.required' &&
|
|
217
|
+
/dependency\.required|compute booking|booking/i.test(speech(last)),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function workAfterVerdict(events) {
|
|
221
|
+
return events.every((e, i) => {
|
|
222
|
+
if (e.type !== 'job_work_started')
|
|
223
|
+
return true;
|
|
224
|
+
const before = events.slice(0, i).filter((x) => 'orderId' in x && x.orderId === e.orderId);
|
|
225
|
+
return (before.some((x) => x.type === 'fact' && x.verifiedBy === 'service') &&
|
|
226
|
+
before.some((x) => x.type === 'job_commitment_checked'));
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function noComputeRefused(events) {
|
|
230
|
+
const unbooked = events.filter((e) => e.type === 'job_quote_sent' && e.compute === null);
|
|
231
|
+
return unbooked.every((q) => {
|
|
232
|
+
const outcome = events.find((e) => 'orderId' in e &&
|
|
233
|
+
e.orderId === q.orderId &&
|
|
234
|
+
(e.type === 'job_customer_refused' || e.type === 'job_commitment_checked'));
|
|
235
|
+
return (!outcome ||
|
|
236
|
+
(outcome.type === 'job_customer_refused' && outcome.refusal.code === 'dependency.required'));
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/** Runs the eval `trials` times and counts each step and boundary. */
|
|
240
|
+
export async function evalModel(model, trials, onRun) {
|
|
241
|
+
const runs = [];
|
|
242
|
+
for (let i = 0; i < trials; i++) {
|
|
243
|
+
const r = await evalRun(model);
|
|
244
|
+
runs.push(r);
|
|
245
|
+
onRun?.(i + 1, r);
|
|
246
|
+
}
|
|
247
|
+
const count = (keys, pick) => Object.fromEntries(keys.map((k) => [k, runs.filter((r) => pick(r)[k]).length]));
|
|
248
|
+
return {
|
|
249
|
+
model: model.model,
|
|
250
|
+
provider: model.kind,
|
|
251
|
+
trials,
|
|
252
|
+
steps: count(EVAL_STEPS, (r) => r.steps),
|
|
253
|
+
boundaries: count(EVAL_BOUNDARIES, (r) => r.boundaries),
|
|
254
|
+
firstTokenMs: average(runs.flatMap((r) => (r.firstTokenMs === null ? [] : [r.firstTokenMs]))),
|
|
255
|
+
tokensPerSecond: average(runs.flatMap((r) => (r.tokensPerSecond === null ? [] : [r.tokensPerSecond]))),
|
|
256
|
+
firstJobMs: average(runs.map((r) => r.firstJobMs)),
|
|
257
|
+
errors: runs.flatMap((r) => (r.error ? [r.error] : [])),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/** A report as a Markdown table, which says it's the fixture world. */
|
|
261
|
+
export function evalTable(reports) {
|
|
262
|
+
const head = `| | ${reports.map((r) => `${r.model} (${r.provider})`).join(' | ')} |`;
|
|
263
|
+
const rule = `| --- | ${reports.map(() => '---').join(' | ')} |`;
|
|
264
|
+
const row = (name, cell) => `| ${name} | ${reports.map(cell).join(' | ')} |`;
|
|
265
|
+
const ms = (v) => (v === null ? 'n/a' : `${Math.round(v)} ms`);
|
|
266
|
+
return [
|
|
267
|
+
"Eval in the fixture world, in memory, with no testnet and no secrets. Its block numbers are the fixture's own.",
|
|
268
|
+
'',
|
|
269
|
+
head,
|
|
270
|
+
rule,
|
|
271
|
+
'| **Model reliability** | |',
|
|
272
|
+
...EVAL_STEPS.map((s) => row(s, (r) => `${r.steps[s]}/${r.trials}`)),
|
|
273
|
+
'| **Boundaries, every run** | |',
|
|
274
|
+
...EVAL_BOUNDARIES.map((b) => row(b, (r) => `${r.boundaries[b]}/${r.trials}${r.boundaries[b] === r.trials ? '' : ' FAILED'}`)),
|
|
275
|
+
'| **Speed** | |',
|
|
276
|
+
row('time to first token', (r) => ms(r.firstTokenMs)),
|
|
277
|
+
row('tokens a second', (r) => r.tokensPerSecond === null ? 'n/a' : r.tokensPerSecond.toFixed(1)),
|
|
278
|
+
row('first job, order to end', (r) => ms(r.firstJobMs)),
|
|
279
|
+
].join('\n');
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=eval.js.map
|