@buoy-gg/agent-core 7.0.33
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 +58 -0
- package/README.md +42 -0
- package/lib/commonjs/blocks/receipts.js +702 -0
- package/lib/commonjs/blocks/receipts.js.map +1 -0
- package/lib/commonjs/blocks/types.js +119 -0
- package/lib/commonjs/blocks/types.js.map +1 -0
- package/lib/commonjs/blocks/uiTool.js +994 -0
- package/lib/commonjs/blocks/uiTool.js.map +1 -0
- package/lib/commonjs/catalog/catalog.g.js +4044 -0
- package/lib/commonjs/catalog/catalog.g.js.map +1 -0
- package/lib/commonjs/catalog/catalog.source.json +4956 -0
- package/lib/commonjs/catalog/snapshotReads.js +256 -0
- package/lib/commonjs/catalog/snapshotReads.js.map +1 -0
- package/lib/commonjs/catalog/toProviderTools.js +107 -0
- package/lib/commonjs/catalog/toProviderTools.js.map +1 -0
- package/lib/commonjs/catalog/validateParams.js +129 -0
- package/lib/commonjs/catalog/validateParams.js.map +1 -0
- package/lib/commonjs/context/buildContextPack.js +141 -0
- package/lib/commonjs/context/buildContextPack.js.map +1 -0
- package/lib/commonjs/effects/ledger.js +229 -0
- package/lib/commonjs/effects/ledger.js.map +1 -0
- package/lib/commonjs/engine/effectFor.js +95 -0
- package/lib/commonjs/engine/effectFor.js.map +1 -0
- package/lib/commonjs/engine/runAgentTurn.js +667 -0
- package/lib/commonjs/engine/runAgentTurn.js.map +1 -0
- package/lib/commonjs/engine/systemPrompt.js +86 -0
- package/lib/commonjs/engine/systemPrompt.js.map +1 -0
- package/lib/commonjs/index.js +288 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/policy/labels.js +303 -0
- package/lib/commonjs/policy/labels.js.map +1 -0
- package/lib/commonjs/policy/policy.js +143 -0
- package/lib/commonjs/policy/policy.js.map +1 -0
- package/lib/commonjs/policy/redact.js +135 -0
- package/lib/commonjs/policy/redact.js.map +1 -0
- package/lib/commonjs/providers/anthropic.js +272 -0
- package/lib/commonjs/providers/anthropic.js.map +1 -0
- package/lib/commonjs/providers/openai.js +193 -0
- package/lib/commonjs/providers/openai.js.map +1 -0
- package/lib/commonjs/providers/sse.js +104 -0
- package/lib/commonjs/providers/sse.js.map +1 -0
- package/lib/commonjs/providers/types.js +6 -0
- package/lib/commonjs/providers/types.js.map +1 -0
- package/lib/commonjs/session.js +173 -0
- package/lib/commonjs/session.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/blocks/receipts.js +696 -0
- package/lib/module/blocks/receipts.js.map +1 -0
- package/lib/module/blocks/types.js +113 -0
- package/lib/module/blocks/types.js.map +1 -0
- package/lib/module/blocks/uiTool.js +987 -0
- package/lib/module/blocks/uiTool.js.map +1 -0
- package/lib/module/catalog/catalog.g.js +4040 -0
- package/lib/module/catalog/catalog.g.js.map +1 -0
- package/lib/module/catalog/catalog.source.json +4956 -0
- package/lib/module/catalog/snapshotReads.js +252 -0
- package/lib/module/catalog/snapshotReads.js.map +1 -0
- package/lib/module/catalog/toProviderTools.js +101 -0
- package/lib/module/catalog/toProviderTools.js.map +1 -0
- package/lib/module/catalog/validateParams.js +124 -0
- package/lib/module/catalog/validateParams.js.map +1 -0
- package/lib/module/context/buildContextPack.js +138 -0
- package/lib/module/context/buildContextPack.js.map +1 -0
- package/lib/module/effects/ledger.js +223 -0
- package/lib/module/effects/ledger.js.map +1 -0
- package/lib/module/engine/effectFor.js +91 -0
- package/lib/module/engine/effectFor.js.map +1 -0
- package/lib/module/engine/runAgentTurn.js +663 -0
- package/lib/module/engine/runAgentTurn.js.map +1 -0
- package/lib/module/engine/systemPrompt.js +82 -0
- package/lib/module/engine/systemPrompt.js.map +1 -0
- package/lib/module/index.js +30 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/policy/labels.js +296 -0
- package/lib/module/policy/labels.js.map +1 -0
- package/lib/module/policy/policy.js +137 -0
- package/lib/module/policy/policy.js.map +1 -0
- package/lib/module/policy/redact.js +128 -0
- package/lib/module/policy/redact.js.map +1 -0
- package/lib/module/providers/anthropic.js +268 -0
- package/lib/module/providers/anthropic.js.map +1 -0
- package/lib/module/providers/openai.js +189 -0
- package/lib/module/providers/openai.js.map +1 -0
- package/lib/module/providers/sse.js +99 -0
- package/lib/module/providers/sse.js.map +1 -0
- package/lib/module/providers/types.js +4 -0
- package/lib/module/providers/types.js.map +1 -0
- package/lib/module/session.js +168 -0
- package/lib/module/session.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/blocks/receipts.d.ts +32 -0
- package/lib/typescript/blocks/receipts.d.ts.map +1 -0
- package/lib/typescript/blocks/types.d.ts +576 -0
- package/lib/typescript/blocks/types.d.ts.map +1 -0
- package/lib/typescript/blocks/uiTool.d.ts +15 -0
- package/lib/typescript/blocks/uiTool.d.ts.map +1 -0
- package/lib/typescript/catalog/catalog.g.d.ts +11 -0
- package/lib/typescript/catalog/catalog.g.d.ts.map +1 -0
- package/lib/typescript/catalog/snapshotReads.d.ts +37 -0
- package/lib/typescript/catalog/snapshotReads.d.ts.map +1 -0
- package/lib/typescript/catalog/toProviderTools.d.ts +52 -0
- package/lib/typescript/catalog/toProviderTools.d.ts.map +1 -0
- package/lib/typescript/catalog/validateParams.d.ts +33 -0
- package/lib/typescript/catalog/validateParams.d.ts.map +1 -0
- package/lib/typescript/context/buildContextPack.d.ts +32 -0
- package/lib/typescript/context/buildContextPack.d.ts.map +1 -0
- package/lib/typescript/effects/ledger.d.ts +119 -0
- package/lib/typescript/effects/ledger.d.ts.map +1 -0
- package/lib/typescript/engine/effectFor.d.ts +21 -0
- package/lib/typescript/engine/effectFor.d.ts.map +1 -0
- package/lib/typescript/engine/runAgentTurn.d.ts +140 -0
- package/lib/typescript/engine/runAgentTurn.d.ts.map +1 -0
- package/lib/typescript/engine/systemPrompt.d.ts +49 -0
- package/lib/typescript/engine/systemPrompt.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +29 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/policy/labels.d.ts +10 -0
- package/lib/typescript/policy/labels.d.ts.map +1 -0
- package/lib/typescript/policy/policy.d.ts +106 -0
- package/lib/typescript/policy/policy.d.ts.map +1 -0
- package/lib/typescript/policy/redact.d.ts +37 -0
- package/lib/typescript/policy/redact.d.ts.map +1 -0
- package/lib/typescript/providers/anthropic.d.ts +22 -0
- package/lib/typescript/providers/anthropic.d.ts.map +1 -0
- package/lib/typescript/providers/openai.d.ts +19 -0
- package/lib/typescript/providers/openai.d.ts.map +1 -0
- package/lib/typescript/providers/sse.d.ts +18 -0
- package/lib/typescript/providers/sse.d.ts.map +1 -0
- package/lib/typescript/providers/types.d.ts +129 -0
- package/lib/typescript/providers/types.d.ts.map +1 -0
- package/lib/typescript/session.d.ts +58 -0
- package/lib/typescript/session.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +119 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SNAPSHOT_ACTION = void 0;
|
|
7
|
+
exports.projectSnapshot = projectSnapshot;
|
|
8
|
+
var _redact = require("../policy/redact");
|
|
9
|
+
/**
|
|
10
|
+
* The other half of Buoy's read surface.
|
|
11
|
+
*
|
|
12
|
+
* Every Buoy adapter answers in two ways, and only one of them is an action.
|
|
13
|
+
* `listQueries`, `async.getAllKeys` and `getState` are actions; console
|
|
14
|
+
* entries, network events, the route sitemap and the env table are NOT — they
|
|
15
|
+
* exist only inside the adapter's `getSnapshot`, which the sync layer polls and
|
|
16
|
+
* puts on the wire for MCP's `get_snapshot` / `get_console` /
|
|
17
|
+
* `get_network_requests` / `get_routes`.
|
|
18
|
+
*
|
|
19
|
+
* `dispatchToolAction` reaches only the first half. So an agent driving tools
|
|
20
|
+
* on the device could read storage, stores and the query cache, and was blind
|
|
21
|
+
* to the app's logs, its HTTP traffic, its routes and its environment — the
|
|
22
|
+
* four things a QA person is most likely to ask about, and two of which the
|
|
23
|
+
* empty state advertises as suggestions. The catalog even tells the model to
|
|
24
|
+
* "use get_console", which is an MCP tool that does not exist on this path.
|
|
25
|
+
*
|
|
26
|
+
* This module closes that half. `getSnapshot` is a RESERVED action name: the
|
|
27
|
+
* engine intercepts it before dispatch and routes it to the registry's
|
|
28
|
+
* snapshot reader instead.
|
|
29
|
+
*
|
|
30
|
+
* WHY THE PROJECTIONS. A raw snapshot is the heaviest payload in the system —
|
|
31
|
+
* measured at ~1.1KB per console entry with up to 1000 retained, and network
|
|
32
|
+
* events carry bodies. Handing that to a token-metered model truncated at 24K
|
|
33
|
+
* chars produces a torn JSON object and a wasted turn. Each projector here
|
|
34
|
+
* does what the matching MCP tool does: newest-first, filtered, and only the
|
|
35
|
+
* fields worth spending tokens on. Bodies stay behind `network.getEventBody`,
|
|
36
|
+
* which already exists.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/** Reserved action name. Not a real adapter action anywhere. */
|
|
40
|
+
const SNAPSHOT_ACTION = exports.SNAPSHOT_ACTION = "getSnapshot";
|
|
41
|
+
const SEVERITY = {
|
|
42
|
+
verbose: 0,
|
|
43
|
+
debug: 0,
|
|
44
|
+
trace: 0,
|
|
45
|
+
log: 1,
|
|
46
|
+
info: 1,
|
|
47
|
+
warn: 2,
|
|
48
|
+
warning: 2,
|
|
49
|
+
error: 3
|
|
50
|
+
};
|
|
51
|
+
function asArray(value) {
|
|
52
|
+
return Array.isArray(value) ? value : [];
|
|
53
|
+
}
|
|
54
|
+
function rec(value) {
|
|
55
|
+
return value && typeof value === "object" ? value : {};
|
|
56
|
+
}
|
|
57
|
+
function num(value, fallback) {
|
|
58
|
+
return typeof value === "number" && value > 0 ? value : fallback;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Newest N, matching the way every Buoy store appends. */
|
|
62
|
+
function tail(items, limit) {
|
|
63
|
+
return items.length <= limit ? items : items.slice(items.length - limit);
|
|
64
|
+
}
|
|
65
|
+
function projectConsole(payload, params) {
|
|
66
|
+
const entries = asArray(rec(payload).entries);
|
|
67
|
+
const minSeverity = typeof params.level === "string" ? SEVERITY[params.level] ?? 0 : 0;
|
|
68
|
+
const pattern = typeof params.pattern === "string" ? params.pattern.toLowerCase() : undefined;
|
|
69
|
+
const matched = entries.filter(raw => {
|
|
70
|
+
const e = rec(raw);
|
|
71
|
+
const level = String(e.level ?? "log");
|
|
72
|
+
if ((SEVERITY[level] ?? 1) < minSeverity) return false;
|
|
73
|
+
if (!pattern) return true;
|
|
74
|
+
return String(e.message ?? "").toLowerCase().includes(pattern);
|
|
75
|
+
});
|
|
76
|
+
const shown = tail(matched, num(params.limit, 40));
|
|
77
|
+
return {
|
|
78
|
+
totalCaptured: entries.length,
|
|
79
|
+
shown: shown.length,
|
|
80
|
+
// Pre-rendered message only. Full args and stacks stay on the device;
|
|
81
|
+
// `get_snapshot('console')` is the MCP escape hatch and has no equivalent
|
|
82
|
+
// here on purpose — it is the payload that blows the prompt.
|
|
83
|
+
entries: shown.map(raw => {
|
|
84
|
+
const e = rec(raw);
|
|
85
|
+
return {
|
|
86
|
+
at: e.timestamp,
|
|
87
|
+
level: e.level,
|
|
88
|
+
message: e.message
|
|
89
|
+
};
|
|
90
|
+
})
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function projectNetwork(payload, params) {
|
|
94
|
+
const p = rec(payload);
|
|
95
|
+
// The agent's own POSTs to the model endpoint are dropped HERE, not only by
|
|
96
|
+
// the engine's later pass, so the counts the model is given match the rows
|
|
97
|
+
// it is given. Reporting "4 requests" above a list of 3 is its own small lie.
|
|
98
|
+
const events = asArray(p.events).filter(raw => !(0, _redact.isSelfTraffic)(rec(raw).url));
|
|
99
|
+
const failedOnly = params.failedOnly === true;
|
|
100
|
+
const pattern = typeof params.pattern === "string" ? params.pattern.toLowerCase() : undefined;
|
|
101
|
+
const matched = events.filter(raw => {
|
|
102
|
+
const e = rec(raw);
|
|
103
|
+
const status = typeof e.status === "number" ? e.status : undefined;
|
|
104
|
+
if (failedOnly && !(e.error || status !== undefined && status >= 400)) return false;
|
|
105
|
+
if (!pattern) return true;
|
|
106
|
+
return String(e.url ?? "").toLowerCase().includes(pattern);
|
|
107
|
+
});
|
|
108
|
+
const shown = tail(matched, num(params.limit, 25));
|
|
109
|
+
return {
|
|
110
|
+
totalCaptured: events.length,
|
|
111
|
+
shown: shown.length,
|
|
112
|
+
// No bodies. `network.getEventBody` fetches one on demand, which is the
|
|
113
|
+
// difference between a readable list and a truncated blob.
|
|
114
|
+
requests: shown.map(raw => {
|
|
115
|
+
const e = rec(raw);
|
|
116
|
+
return {
|
|
117
|
+
id: e.id,
|
|
118
|
+
method: e.method,
|
|
119
|
+
url: e.url,
|
|
120
|
+
status: e.status,
|
|
121
|
+
durationMs: e.duration,
|
|
122
|
+
error: e.error,
|
|
123
|
+
// An override rule served this response. Carried through so neither
|
|
124
|
+
// the model nor the receipt can present mocked data as live.
|
|
125
|
+
overridden: e.override ? true : undefined
|
|
126
|
+
};
|
|
127
|
+
}),
|
|
128
|
+
hint: "Read one response with network.getEventBody({ id })."
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The sitemap arrives as a NESTED RouteInfo tree, not a list. A model asked
|
|
134
|
+
* "what screens exist" needs the leaf paths, so flatten and keep the paths.
|
|
135
|
+
*/
|
|
136
|
+
function flattenRoutes(nodes, out = [], cap = 80) {
|
|
137
|
+
for (const raw of asArray(nodes)) {
|
|
138
|
+
if (out.length >= cap) break;
|
|
139
|
+
const node = rec(raw);
|
|
140
|
+
if (node.isInternal !== true && typeof node.path === "string") out.push(node.path);
|
|
141
|
+
flattenRoutes(node.children, out, cap);
|
|
142
|
+
}
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
function projectRoutes(payload, params) {
|
|
146
|
+
const p = rec(payload);
|
|
147
|
+
const sitemap = rec(p.sitemap);
|
|
148
|
+
|
|
149
|
+
// Route events are stored newest-FIRST, and a stack item's screen path is
|
|
150
|
+
// `pathname` (`path` does not exist on it). Getting either wrong is not a
|
|
151
|
+
// crash, it is a confident wrong answer: an early version of this read told
|
|
152
|
+
// the user they were on the Pokedex while the shop was on screen.
|
|
153
|
+
const stackRaw = asArray(p.stack).map(rec);
|
|
154
|
+
const eventsRaw = asArray(p.events).map(rec);
|
|
155
|
+
const stack = stackRaw.map(s => ({
|
|
156
|
+
name: s.name,
|
|
157
|
+
path: s.pathname,
|
|
158
|
+
focused: s.isFocused === true ? true : undefined
|
|
159
|
+
}));
|
|
160
|
+
const recentNavigations = eventsRaw.slice(0, num(params.limit, 15)).map(e => ({
|
|
161
|
+
at: e.timestamp,
|
|
162
|
+
from: e.previousPathname,
|
|
163
|
+
to: e.pathname
|
|
164
|
+
}));
|
|
165
|
+
|
|
166
|
+
// Mirrors the adapter's own `getCurrentRoute`: the newest navigation event
|
|
167
|
+
// wins, and with no history yet — a freshly launched app — the FOCUSED stack
|
|
168
|
+
// item does, which is not always the last one in the array.
|
|
169
|
+
const focused = stackRaw.find(s => s.isFocused === true) ?? stackRaw[stackRaw.length - 1];
|
|
170
|
+
const currentRoute = eventsRaw.length ? {
|
|
171
|
+
path: eventsRaw[0].pathname,
|
|
172
|
+
source: "event"
|
|
173
|
+
} : typeof focused?.pathname === "string" ? {
|
|
174
|
+
path: focused.pathname,
|
|
175
|
+
source: "stack"
|
|
176
|
+
} : undefined;
|
|
177
|
+
return {
|
|
178
|
+
currentRoute,
|
|
179
|
+
stack,
|
|
180
|
+
routes: flattenRoutes(sitemap.routes),
|
|
181
|
+
sitemapSource: sitemap.source,
|
|
182
|
+
recentNavigations
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function projectEnv(payload) {
|
|
186
|
+
const p = rec(payload);
|
|
187
|
+
return {
|
|
188
|
+
env: p.env ?? p.variables,
|
|
189
|
+
requiredEnvVars: p.requiredEnvVars
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Sentry envelopes are the fattest payloads any Buoy tool captures (a single
|
|
195
|
+
* event with breadcrumbs is tens of KB), so only the item SUMMARIES travel —
|
|
196
|
+
* the one-line human read the adapter already computes. The status field is
|
|
197
|
+
* load-bearing: an empty list with "sdk-not-found" means the app has no
|
|
198
|
+
* Sentry client, which is a different answer from "nothing errored".
|
|
199
|
+
*/
|
|
200
|
+
function projectSentry(payload, params) {
|
|
201
|
+
const p = rec(payload);
|
|
202
|
+
const envelopes = asArray(p.envelopes).map(rec);
|
|
203
|
+
const typeFilter = typeof params.type === "string" ? params.type : undefined;
|
|
204
|
+
const pattern = typeof params.pattern === "string" ? params.pattern.toLowerCase() : undefined;
|
|
205
|
+
const matched = envelopes.filter(e => {
|
|
206
|
+
const items = asArray(e.items).map(rec);
|
|
207
|
+
if (typeFilter && !items.some(i => i.type === typeFilter)) return false;
|
|
208
|
+
if (!pattern) return true;
|
|
209
|
+
return items.some(i => String(i.summary ?? "").toLowerCase().includes(pattern));
|
|
210
|
+
});
|
|
211
|
+
const shown = tail(matched, num(params.limit, 10));
|
|
212
|
+
return {
|
|
213
|
+
status: p.status,
|
|
214
|
+
totalCaptured: envelopes.length,
|
|
215
|
+
shown: shown.length,
|
|
216
|
+
envelopes: shown.map(e => ({
|
|
217
|
+
id: e.id,
|
|
218
|
+
at: e.timestamp,
|
|
219
|
+
origin: e.origin,
|
|
220
|
+
eventId: e.eventId,
|
|
221
|
+
totalBytes: e.totalBytes,
|
|
222
|
+
items: asArray(e.items).map(raw => {
|
|
223
|
+
const i = rec(raw);
|
|
224
|
+
return {
|
|
225
|
+
type: i.type,
|
|
226
|
+
summary: i.summary,
|
|
227
|
+
spanCount: i.spanCount,
|
|
228
|
+
bytes: i.bytes
|
|
229
|
+
};
|
|
230
|
+
})
|
|
231
|
+
})),
|
|
232
|
+
hint: "For crash stack traces, console's [FATAL] entries carry the component stacks."
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Trim one snapshot to something worth sending. Unknown tools pass through —
|
|
238
|
+
* the engine's 24K truncation is still the backstop.
|
|
239
|
+
*/
|
|
240
|
+
function projectSnapshot(toolId, payload, params = {}) {
|
|
241
|
+
switch (toolId) {
|
|
242
|
+
case "console":
|
|
243
|
+
return projectConsole(payload, params);
|
|
244
|
+
case "network":
|
|
245
|
+
return projectNetwork(payload, params);
|
|
246
|
+
case "route-events":
|
|
247
|
+
return projectRoutes(payload, params);
|
|
248
|
+
case "env":
|
|
249
|
+
return projectEnv(payload);
|
|
250
|
+
case "sentry":
|
|
251
|
+
return projectSentry(payload, params);
|
|
252
|
+
default:
|
|
253
|
+
return payload;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=snapshotReads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_redact","require","SNAPSHOT_ACTION","exports","SEVERITY","verbose","debug","trace","log","info","warn","warning","error","asArray","value","Array","isArray","rec","num","fallback","tail","items","limit","length","slice","projectConsole","payload","params","entries","minSeverity","level","pattern","toLowerCase","undefined","matched","filter","raw","e","String","message","includes","shown","totalCaptured","map","at","timestamp","projectNetwork","p","events","isSelfTraffic","url","failedOnly","status","requests","id","method","durationMs","duration","overridden","override","hint","flattenRoutes","nodes","out","cap","node","isInternal","path","push","children","projectRoutes","sitemap","stackRaw","stack","eventsRaw","s","name","pathname","focused","isFocused","recentNavigations","from","previousPathname","to","find","currentRoute","source","routes","sitemapSource","projectEnv","env","variables","requiredEnvVars","projectSentry","envelopes","typeFilter","type","some","i","summary","origin","eventId","totalBytes","spanCount","bytes","projectSnapshot","toolId"],"sourceRoot":"../../../src","sources":["catalog/snapshotReads.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.fromProviderToolName = fromProviderToolName;
|
|
7
|
+
exports.toProviderToolName = toProviderToolName;
|
|
8
|
+
exports.toProviderTools = toProviderTools;
|
|
9
|
+
/**
|
|
10
|
+
* Catalog -> provider tool definitions.
|
|
11
|
+
*
|
|
12
|
+
* WHY ONE TOOL PER BUOY TOOL, NOT ONE PER ACTION: tool-selection accuracy
|
|
13
|
+
* degrades past roughly 30-50 tools. Buoy has ~179 actions across 22 tools, so
|
|
14
|
+
* a 1:1 mapping is far past the point where the model starts picking wrong.
|
|
15
|
+
* Each Buoy tool therefore becomes ONE provider tool whose `action` property is
|
|
16
|
+
* an enum, with the per-action summaries folded into that enum's description.
|
|
17
|
+
*
|
|
18
|
+
* `params` stays an open object at the provider boundary — a discriminated
|
|
19
|
+
* union across 179 branches is unusable by any model and unreadable by a human.
|
|
20
|
+
* The real per-action schema is enforced one layer in, by `validateParams`,
|
|
21
|
+
* which returns a structured error the model can correct on the next turn.
|
|
22
|
+
* That is strictly stronger than the MCP server's `z.record(z.unknown())`,
|
|
23
|
+
* which validates nothing.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/** Provider-agnostic tool definition; the adapters reshape it per protocol. */
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Both Anthropic and OpenAI cap tool names at `[a-zA-Z0-9_-]`, so Buoy's
|
|
30
|
+
* dashed ids survive but the `custom:<id>` sync namespace does not. Anthropic's
|
|
31
|
+
* docs say 64 chars while its reference schema says 128 — we code to 64.
|
|
32
|
+
*/
|
|
33
|
+
const MAX_TOOL_NAME = 64;
|
|
34
|
+
function toProviderToolName(toolId) {
|
|
35
|
+
return `buoy_${toolId.replace(/[^a-zA-Z0-9_-]/g, "_")}`.slice(0, MAX_TOOL_NAME);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Reverse of {@link toProviderToolName}, resolved against the live catalog. */
|
|
39
|
+
function fromProviderToolName(name, catalog) {
|
|
40
|
+
return catalog.find(t => toProviderToolName(t.toolId) === name)?.toolId;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* One line per action, in the `action` enum's description. This is where the
|
|
45
|
+
* model actually learns what each action does, so it carries the effect and
|
|
46
|
+
* the release caveat inline rather than hiding them in a separate field the
|
|
47
|
+
* model never sees.
|
|
48
|
+
*/
|
|
49
|
+
function actionLine(a, isRelease) {
|
|
50
|
+
const bits = [`${a.action} — ${a.summary}`];
|
|
51
|
+
if (a.effect === "destructive") bits.push("[DESTRUCTIVE]");else if (a.effect === "write") bits.push("[changes state]");
|
|
52
|
+
if (isRelease && a.release !== "works") {
|
|
53
|
+
bits.push(`[UNAVAILABLE in this build: ${a.release}]`);
|
|
54
|
+
}
|
|
55
|
+
if (a.requires?.length) bits.push(`[needs: ${a.requires.join(", ")}]`);
|
|
56
|
+
return bits.join(" ");
|
|
57
|
+
}
|
|
58
|
+
function toProviderTools(catalog, opts = {}) {
|
|
59
|
+
const {
|
|
60
|
+
availableToolIds,
|
|
61
|
+
availableActions,
|
|
62
|
+
isRelease = false,
|
|
63
|
+
hideUnavailable = false
|
|
64
|
+
} = opts;
|
|
65
|
+
const tools = [];
|
|
66
|
+
for (const tool of catalog) {
|
|
67
|
+
if (availableToolIds && !availableToolIds.includes(tool.toolId)) continue;
|
|
68
|
+
const live = availableActions?.[tool.toolId];
|
|
69
|
+
let actions = live ? tool.actions.filter(a => live.includes(a.action)) : tool.actions;
|
|
70
|
+
if (isRelease && hideUnavailable) {
|
|
71
|
+
actions = actions.filter(a => a.release === "works");
|
|
72
|
+
}
|
|
73
|
+
if (actions.length === 0) continue;
|
|
74
|
+
const desc = [tool.summary, tool.unavailableWhen ? `Unavailable when: ${tool.unavailableWhen}` : "", "",
|
|
75
|
+
// These prose lines look like the expensive part of the catalog and are
|
|
76
|
+
// the CHEAPEST part of it. Measured against a real tokenizer (fal ->
|
|
77
|
+
// gpt-4o-mini): the whole catalog is 79,601 chars but only 7,902 tokens
|
|
78
|
+
// — 10.1 chars/token, because English prose is what BPE compresses best.
|
|
79
|
+
// An index that replaced these lines with a bare list of action names
|
|
80
|
+
// sent 48% fewer characters and cost MORE tokens (7,986), since dotted
|
|
81
|
+
// camelCase identifiers tokenize at ~5 chars/token. Do not "shrink" this
|
|
82
|
+
// by counting characters; measure tokens or leave it alone.
|
|
83
|
+
"Actions:", ...actions.map(a => `- ${actionLine(a, isRelease)}`)].filter(Boolean).join("\n");
|
|
84
|
+
tools.push({
|
|
85
|
+
name: toProviderToolName(tool.toolId),
|
|
86
|
+
description: desc,
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: "object",
|
|
89
|
+
properties: {
|
|
90
|
+
action: {
|
|
91
|
+
type: "string",
|
|
92
|
+
enum: actions.map(a => a.action),
|
|
93
|
+
description: "Which action to run. See the list in this tool's description."
|
|
94
|
+
},
|
|
95
|
+
params: {
|
|
96
|
+
type: "object",
|
|
97
|
+
description: "Arguments for the action. The shape depends on `action`; if you get it wrong the error will tell you the expected schema."
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
required: ["action"],
|
|
101
|
+
additionalProperties: false
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return tools;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=toProviderTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MAX_TOOL_NAME","toProviderToolName","toolId","replace","slice","fromProviderToolName","name","catalog","find","t","actionLine","a","isRelease","bits","action","summary","effect","push","release","requires","length","join","toProviderTools","opts","availableToolIds","availableActions","hideUnavailable","tools","tool","includes","live","actions","filter","desc","unavailableWhen","map","Boolean","description","inputSchema","type","properties","enum","params","required","additionalProperties"],"sourceRoot":"../../../src","sources":["catalog/toProviderTools.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.applyDefaults = applyDefaults;
|
|
7
|
+
exports.validateParams = validateParams;
|
|
8
|
+
/**
|
|
9
|
+
* A deliberately small JSON Schema validator.
|
|
10
|
+
*
|
|
11
|
+
* Buoy's adapters validate nothing — every handler takes `params?: unknown` and
|
|
12
|
+
* hand-casts (`(params as { id?: string })?.id`), so a wrong shape becomes an
|
|
13
|
+
* undefined read, and an LLM omitting an optional flag can do real damage:
|
|
14
|
+
* `zustand.setState` defaults `replace ?? true`, so calling it without
|
|
15
|
+
* `replace` REPLACES the entire store rather than merging it.
|
|
16
|
+
*
|
|
17
|
+
* So the agent validates before it dispatches. The point is not spec
|
|
18
|
+
* compliance — it is that a rejection comes back to the model as a readable
|
|
19
|
+
* error naming the expected schema, which it can fix on the next turn. That is
|
|
20
|
+
* why this covers exactly the subset `JsonSchema` describes and nothing more:
|
|
21
|
+
* a rule the validator silently skips is a rule that isn't enforced.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
function typeOf(v) {
|
|
25
|
+
if (v === null) return "null";
|
|
26
|
+
if (Array.isArray(v)) return "array";
|
|
27
|
+
return typeof v;
|
|
28
|
+
}
|
|
29
|
+
function checkType(value, type) {
|
|
30
|
+
switch (type) {
|
|
31
|
+
case "integer":
|
|
32
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
33
|
+
case "number":
|
|
34
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
35
|
+
case "null":
|
|
36
|
+
return value === null;
|
|
37
|
+
case "array":
|
|
38
|
+
return Array.isArray(value);
|
|
39
|
+
case "object":
|
|
40
|
+
return typeOf(value) === "object";
|
|
41
|
+
default:
|
|
42
|
+
return typeof value === type;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function validate(value, schema, path, errors) {
|
|
46
|
+
if (schema.anyOf?.length) {
|
|
47
|
+
const anyOk = schema.anyOf.some(s => {
|
|
48
|
+
const sub = [];
|
|
49
|
+
validate(value, s, path, sub);
|
|
50
|
+
return sub.length === 0;
|
|
51
|
+
});
|
|
52
|
+
if (!anyOk) {
|
|
53
|
+
const kinds = schema.anyOf.map(s => s.type ?? "?").join(" | ");
|
|
54
|
+
errors.push(`${path}: expected ${kinds}, got ${typeOf(value)}`);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (schema.type && !checkType(value, schema.type)) {
|
|
59
|
+
errors.push(`${path}: expected ${schema.type}, got ${typeOf(value)}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
63
|
+
errors.push(`${path}: expected one of ${schema.enum.map(e => JSON.stringify(e)).join(", ")}, got ${JSON.stringify(value)}`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (schema.type === "array" && Array.isArray(value)) {
|
|
67
|
+
if (schema.minItems !== undefined && value.length < schema.minItems) {
|
|
68
|
+
errors.push(`${path}: expected at least ${schema.minItems} item(s), got ${value.length}`);
|
|
69
|
+
}
|
|
70
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems) {
|
|
71
|
+
errors.push(`${path}: expected at most ${schema.maxItems} item(s), got ${value.length}`);
|
|
72
|
+
}
|
|
73
|
+
if (schema.items) {
|
|
74
|
+
value.forEach((item, i) => validate(item, schema.items, `${path}[${i}]`, errors));
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (schema.type === "object" && typeOf(value) === "object") {
|
|
79
|
+
const obj = value;
|
|
80
|
+
for (const key of schema.required ?? []) {
|
|
81
|
+
if (obj[key] === undefined) errors.push(`${path}.${key}: required`);
|
|
82
|
+
}
|
|
83
|
+
if (schema.properties) {
|
|
84
|
+
for (const [key, sub] of Object.entries(schema.properties)) {
|
|
85
|
+
if (obj[key] !== undefined) validate(obj[key], sub, `${path}.${key}`, errors);
|
|
86
|
+
}
|
|
87
|
+
// Only flag unknown keys when the schema says so. Several adapters read
|
|
88
|
+
// params they never documented, and rejecting an extra key the handler
|
|
89
|
+
// happens to use would break a call that would have worked.
|
|
90
|
+
if (schema.additionalProperties === false) {
|
|
91
|
+
const known = new Set(Object.keys(schema.properties));
|
|
92
|
+
for (const key of Object.keys(obj)) {
|
|
93
|
+
if (!known.has(key)) errors.push(`${path}.${key}: unexpected property`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function validateParams(params, schema) {
|
|
100
|
+
const errors = [];
|
|
101
|
+
// A no-param action called with nothing is the common case, not an error.
|
|
102
|
+
const value = params === undefined || params === null ? {} : params;
|
|
103
|
+
validate(value, schema, "params", errors);
|
|
104
|
+
return {
|
|
105
|
+
ok: errors.length === 0,
|
|
106
|
+
errors
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Fill in documented defaults the model left out.
|
|
112
|
+
*
|
|
113
|
+
* This is the counter-measure to the omitted-flag class of bug. Several Buoy
|
|
114
|
+
* actions invert the usual assumption — `focus-inspector.setTracking` reads
|
|
115
|
+
* `params?.enabled !== false`, so calling it with `{}` turns tracking ON — and
|
|
116
|
+
* the catalog records the real default. Applying it explicitly means the model
|
|
117
|
+
* omitting a flag produces the documented behaviour rather than the accidental
|
|
118
|
+
* one.
|
|
119
|
+
*/
|
|
120
|
+
function applyDefaults(params, schema) {
|
|
121
|
+
const out = typeOf(params) === "object" ? {
|
|
122
|
+
...params
|
|
123
|
+
} : {};
|
|
124
|
+
for (const [key, sub] of Object.entries(schema.properties ?? {})) {
|
|
125
|
+
if (out[key] === undefined && sub.default !== undefined) out[key] = sub.default;
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=validateParams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["typeOf","v","Array","isArray","checkType","value","type","Number","isInteger","isFinite","validate","schema","path","errors","anyOf","length","anyOk","some","s","sub","kinds","map","join","push","enum","includes","e","JSON","stringify","minItems","undefined","maxItems","items","forEach","item","i","obj","key","required","properties","Object","entries","additionalProperties","known","Set","keys","has","validateParams","params","ok","applyDefaults","out","default"],"sourceRoot":"../../../src","sources":["catalog/validateParams.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildContextDigest = buildContextDigest;
|
|
7
|
+
var _snapshotReads = require("../catalog/snapshotReads");
|
|
8
|
+
/**
|
|
9
|
+
* The grounding digest — "here is what this app looks like".
|
|
10
|
+
*
|
|
11
|
+
* Composed entirely from readers that already exist. Most Buoy adapters ship a
|
|
12
|
+
* compact action written explicitly for a remote driver (`listQueries`,
|
|
13
|
+
* `listStores`, `listAtoms`, `getState`, `async.getAllKeys`), and those are
|
|
14
|
+
* exactly the right size: measured on a live idle device the whole digest is
|
|
15
|
+
* ~5.7KB (~1.5K tokens) covering routes, env, query keys, redux slices,
|
|
16
|
+
* zustand stores, jotai atoms, storage keys and API hosts.
|
|
17
|
+
*
|
|
18
|
+
* What this does NOT do, and why:
|
|
19
|
+
* - No `getSnapshot('query')`. It returns the full dehydrated cache — 8.3KB for
|
|
20
|
+
* ten queries in that same measurement, growing with every cached payload.
|
|
21
|
+
* `listQueries` covers the same ground in 1.8KB.
|
|
22
|
+
* - No console. It is the fattest payload in the system at ~1.1KB per entry
|
|
23
|
+
* with up to 1000 retained; a naive "include recent logs" is a 1MB prompt.
|
|
24
|
+
* - No values, only shapes and keys. `includeValues`/`includeData` are
|
|
25
|
+
* unbounded on the action path — no adapter applies a size guard — and the
|
|
26
|
+
* whole point of the digest is to tell the model where to look, not to
|
|
27
|
+
* pre-fetch everything it might want.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** Per-probe budget. A slow tool must not hold up the first message. */
|
|
31
|
+
const PROBE_TIMEOUT_MS = 2500;
|
|
32
|
+
const list = value => Array.isArray(value) ? value : Array.isArray(value?.items) ? value.items : [];
|
|
33
|
+
const names = (value, keys, cap = 40) => list(value).slice(0, cap).map(item => {
|
|
34
|
+
if (!item || typeof item !== "object") return item;
|
|
35
|
+
const rec = item;
|
|
36
|
+
for (const k of keys) {
|
|
37
|
+
if (rec[k] !== undefined) return rec[k];
|
|
38
|
+
}
|
|
39
|
+
return rec.id ?? rec.name ?? rec.key;
|
|
40
|
+
});
|
|
41
|
+
const PROBES = [{
|
|
42
|
+
// `getSitemap` was never an action — the sitemap lives in the adapter's
|
|
43
|
+
// snapshot, so this probe could only ever have been filtered out or
|
|
44
|
+
// thrown. Same for env below.
|
|
45
|
+
key: "routes",
|
|
46
|
+
toolId: "route-events",
|
|
47
|
+
action: _snapshotReads.SNAPSHOT_ACTION,
|
|
48
|
+
// projectSnapshot already flattened the nested route tree to paths.
|
|
49
|
+
shape: v => list(v?.routes).slice(0, 60)
|
|
50
|
+
}, {
|
|
51
|
+
key: "queryKeys",
|
|
52
|
+
toolId: "query",
|
|
53
|
+
action: "listQueries",
|
|
54
|
+
shape: v => names(v, ["queryHash", "queryKey", "key"], 40)
|
|
55
|
+
}, {
|
|
56
|
+
key: "reduxSlices",
|
|
57
|
+
toolId: "redux",
|
|
58
|
+
action: "getState",
|
|
59
|
+
params: {
|
|
60
|
+
includeValues: false
|
|
61
|
+
},
|
|
62
|
+
shape: v => v && typeof v === "object" ? Object.keys(v.state ?? v).slice(0, 40) : v
|
|
63
|
+
}, {
|
|
64
|
+
// Carries `persists to <key>` for persisted stores. That mapping is the
|
|
65
|
+
// only way the model can tell that an innocent-looking storage key is
|
|
66
|
+
// actually a hydrated store's saved copy — write the key directly and the
|
|
67
|
+
// screen does not change, then the store overwrites you. `listStores`
|
|
68
|
+
// already reports `persistName`; nothing else surfaces it.
|
|
69
|
+
key: "zustandStores",
|
|
70
|
+
toolId: "zustand",
|
|
71
|
+
action: "listStores",
|
|
72
|
+
// Structured, not a display string: `session` reads `persistsTo` back out
|
|
73
|
+
// to build the owner map the engine uses at dispatch time, and the digest
|
|
74
|
+
// is JSON-stringified into the prompt anyway, so the model loses nothing.
|
|
75
|
+
shape: v => list(v?.stores ?? v).slice(0, 30).map(raw => {
|
|
76
|
+
const s = raw ?? {};
|
|
77
|
+
const name = typeof s.name === "string" ? s.name : s.id;
|
|
78
|
+
return typeof s.persistName === "string" ? {
|
|
79
|
+
name,
|
|
80
|
+
persistsTo: s.persistName
|
|
81
|
+
} : {
|
|
82
|
+
name
|
|
83
|
+
};
|
|
84
|
+
})
|
|
85
|
+
}, {
|
|
86
|
+
key: "jotaiAtoms",
|
|
87
|
+
toolId: "jotai",
|
|
88
|
+
action: "listAtoms",
|
|
89
|
+
shape: v => names(v, ["debugLabel", "label", "id"], 40)
|
|
90
|
+
}, {
|
|
91
|
+
key: "storageKeys",
|
|
92
|
+
toolId: "storage",
|
|
93
|
+
action: "async.getAllKeys",
|
|
94
|
+
shape: v => list(v).slice(0, 60)
|
|
95
|
+
}, {
|
|
96
|
+
key: "env",
|
|
97
|
+
toolId: "env",
|
|
98
|
+
action: _snapshotReads.SNAPSHOT_ACTION,
|
|
99
|
+
// Names only. Env values are baked into the bundle and can hold anything
|
|
100
|
+
// the app author put in an EXPO_PUBLIC_ var, so the digest lists the keys
|
|
101
|
+
// and leaves reading a value to an explicit ask.
|
|
102
|
+
shape: v => {
|
|
103
|
+
const env = v?.env;
|
|
104
|
+
return env && typeof env === "object" ? Object.keys(env).slice(0, 40) : undefined;
|
|
105
|
+
}
|
|
106
|
+
}];
|
|
107
|
+
async function withTimeout(p, ms) {
|
|
108
|
+
return await Promise.race([p.catch(() => undefined), new Promise(resolve => setTimeout(() => resolve(undefined), ms))]);
|
|
109
|
+
}
|
|
110
|
+
async function buildContextDigest({
|
|
111
|
+
dispatch,
|
|
112
|
+
readSnapshot,
|
|
113
|
+
availableToolIds,
|
|
114
|
+
availableActions
|
|
115
|
+
}) {
|
|
116
|
+
const runnable = PROBES.filter(p => {
|
|
117
|
+
if (!availableToolIds.includes(p.toolId)) return false;
|
|
118
|
+
const actions = availableActions?.[p.toolId];
|
|
119
|
+
return !actions || actions.includes(p.action);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// All at once — these are independent reads and the first message should not
|
|
123
|
+
// wait on the slowest one twice over.
|
|
124
|
+
const settled = await Promise.all(runnable.map(async probe => {
|
|
125
|
+
const read = probe.action === _snapshotReads.SNAPSHOT_ACTION ? readSnapshot ? Promise.resolve(readSnapshot(probe.toolId)).then(payload => (0, _snapshotReads.projectSnapshot)(probe.toolId, payload)) : Promise.resolve(undefined) : Promise.resolve(dispatch(probe.toolId, probe.action, probe.params));
|
|
126
|
+
const value = await withTimeout(read, PROBE_TIMEOUT_MS);
|
|
127
|
+
if (value === undefined) return [probe.key, undefined];
|
|
128
|
+
try {
|
|
129
|
+
return [probe.key, probe.shape(value)];
|
|
130
|
+
} catch {
|
|
131
|
+
return [probe.key, undefined];
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
134
|
+
const digest = {};
|
|
135
|
+
for (const [key, value] of settled) {
|
|
136
|
+
const empty = value === undefined || value === null || Array.isArray(value) && value.length === 0;
|
|
137
|
+
if (!empty) digest[key] = value;
|
|
138
|
+
}
|
|
139
|
+
return digest;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=buildContextPack.js.map
|