@openbkn/bkn-sdk 0.1.4 → 0.1.5-rc.1

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.
@@ -4,6 +4,68 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
+ // src/utils/dry-run.ts
8
+ var enabled = false;
9
+ var suppressed = 0;
10
+ function enableDryRun() {
11
+ enabled = true;
12
+ }
13
+ function isDryRun() {
14
+ return enabled;
15
+ }
16
+ async function withoutPreview(fn) {
17
+ suppressed += 1;
18
+ try {
19
+ return await fn();
20
+ } finally {
21
+ suppressed -= 1;
22
+ }
23
+ }
24
+ var DryRunSignal = class extends Error {
25
+ request;
26
+ constructor(request2) {
27
+ super("dry run: request not sent");
28
+ this.name = "DryRunSignal";
29
+ this.request = request2;
30
+ }
31
+ };
32
+ function redact(headers2) {
33
+ const out = {};
34
+ const entries = headers2 instanceof Headers ? [...headers2.entries()] : Array.isArray(headers2) ? headers2 : Object.entries(headers2 ?? {});
35
+ for (const [k, v] of entries) {
36
+ const key = String(k);
37
+ out[key] = /authorization|cookie|token|api-key/i.test(key) ? "<redacted>" : String(v);
38
+ }
39
+ return out;
40
+ }
41
+ var SECRET_FIELD = /^(bkn_token|token|access_token|refresh_token|password|secret|api_key)$/i;
42
+ function redactBody(body) {
43
+ if (Array.isArray(body)) return body.map(redactBody);
44
+ if (!body || typeof body !== "object") return body;
45
+ const out = {};
46
+ for (const [k, v] of Object.entries(body)) {
47
+ out[k] = SECRET_FIELD.test(k) ? "<redacted>" : redactBody(v);
48
+ }
49
+ return out;
50
+ }
51
+ function previewRequest(input) {
52
+ if (!enabled || suppressed > 0) return;
53
+ let body = input.body;
54
+ if (typeof body === "string") {
55
+ try {
56
+ body = JSON.parse(body);
57
+ } catch {
58
+ }
59
+ }
60
+ throw new DryRunSignal({
61
+ dryRun: true,
62
+ method: input.method,
63
+ url: String(input.url),
64
+ headers: redact(input.headers),
65
+ ...body === void 0 ? {} : { body: redactBody(body) }
66
+ });
67
+ }
68
+
7
69
  // src/utils/errors.ts
8
70
  var HttpError = class extends Error {
9
71
  status;
@@ -93,7 +155,7 @@ function formatError(err2) {
93
155
  const next2 = err2.hint ? ` ${err2.hint}` : "";
94
156
  return `Forbidden (HTTP 403)${serverMsg ? `: ${serverMsg}` : " \u2014 admin privileges required"}.${next2}`;
95
157
  }
96
- const detail = err2.body ? `: ${truncate(err2.body, 500)}` : "";
158
+ const detail = serverMsg ? `: ${serverMsg}` : err2.body ? `: ${truncate(err2.body, 500)}` : "";
97
159
  const next = err2.hint ? ` ${err2.hint}` : "";
98
160
  return `Request failed (HTTP ${err2.status} ${err2.statusText})${detail}${next}`;
99
161
  }
@@ -109,12 +171,40 @@ function formatError(err2) {
109
171
  }
110
172
  return String(err2);
111
173
  }
174
+ function readableServerError(body) {
175
+ return serverError(body);
176
+ }
112
177
  function serverError(body) {
113
178
  if (!body) return "";
114
179
  try {
115
- const j = JSON.parse(body);
116
- const m = j.error ?? j.detail ?? j.description ?? j.message;
117
- return typeof m === "string" ? m : "";
180
+ return describeEnvelope(JSON.parse(body));
181
+ } catch {
182
+ return "";
183
+ }
184
+ }
185
+ function describeEnvelope(j, depth = 0) {
186
+ const text = (v) => typeof v === "string" && v.trim() ? v.trim() : "";
187
+ const description = text(j.description) || text(j.error) || text(j.detail) || text(j.message);
188
+ const code = text(j.error_code) || text(j.code);
189
+ const solution = text(j.solution);
190
+ const details = text(j.error_details) || text(j.details);
191
+ const inner = depth < 2 ? innerEnvelope(details) : "";
192
+ const parts = [
193
+ description || code,
194
+ description && code ? `[${code}]` : "",
195
+ inner || (details && details !== description ? truncate(details, 200) : ""),
196
+ solution && solution !== description ? `\u2014 ${solution}` : ""
197
+ ].filter(Boolean);
198
+ return parts.join(" ");
199
+ }
200
+ function innerEnvelope(details, depth = 0) {
201
+ const start = details.indexOf("{");
202
+ const end = details.lastIndexOf("}");
203
+ if (start === -1 || end <= start) return "";
204
+ try {
205
+ const nested = JSON.parse(details.slice(start, end + 1));
206
+ const rendered = describeEnvelope(nested, depth + 1);
207
+ return rendered ? `(${rendered})` : "";
118
208
  } catch {
119
209
  return "";
120
210
  }
@@ -133,7 +223,7 @@ var rawJSON = JSON.rawJSON;
133
223
  function assertNativeJSONSupport() {
134
224
  if (typeof rawJSON !== "function") {
135
225
  throw new Error(
136
- "Lossless BIGINT JSON support requires Node.js >=24.19.0 (missing JSON.rawJSON)."
226
+ "Lossless BIGINT JSON support requires Node.js >=22.19.0 (missing JSON.rawJSON)."
137
227
  );
138
228
  }
139
229
  let source;
@@ -143,7 +233,7 @@ function assertNativeJSONSupport() {
143
233
  });
144
234
  if (source !== "1") {
145
235
  throw new Error(
146
- "Lossless BIGINT JSON support requires Node.js >=24.19.0 (missing JSON.parse source text access)."
236
+ "Lossless BIGINT JSON support requires Node.js >=22.19.0 (missing JSON.parse source text access)."
147
237
  );
148
238
  }
149
239
  }
@@ -200,6 +290,12 @@ function toUndiciBody(body) {
200
290
  return form2;
201
291
  }
202
292
  function tlsFetch(insecure, url, init, headersTimeoutMs) {
293
+ previewRequest({
294
+ method: String(init?.method ?? "GET"),
295
+ url,
296
+ headers: init?.headers,
297
+ body: typeof init?.body === "string" ? init.body : init?.body ? "<binary or multipart>" : void 0
298
+ });
203
299
  const needsAgent = headersTimeoutMs !== void 0 && headersTimeoutMs > UNDICI_HEADERS_TIMEOUT_MS;
204
300
  if (!insecure && !needsAgent) return fetch(url, init);
205
301
  return undiciFetch(url, {
@@ -209,9 +305,16 @@ function tlsFetch(insecure, url, init, headersTimeoutMs) {
209
305
  });
210
306
  }
211
307
 
308
+ // src/utils/base-url.ts
309
+ function trimTrailingSlashes(value) {
310
+ let end = value.length;
311
+ while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
312
+ return value.slice(0, end);
313
+ }
314
+
212
315
  // src/auth/oauth.ts
213
316
  function normalizeBaseUrl(value) {
214
- return value.replace(/\/+$/, "");
317
+ return trimTrailingSlashes(value);
215
318
  }
216
319
  function mapToken(data) {
217
320
  return {
@@ -528,15 +631,17 @@ async function request(ctx, path, init = {}) {
528
631
  const hasBody = init.body !== void 0;
529
632
  const controller = new AbortController();
530
633
  const timer = setTimeout(() => controller.abort(), init.timeoutMs ?? DEFAULT_TIMEOUT_MS);
634
+ const method = init.method ?? (hasBody ? "POST" : "GET");
635
+ const headers2 = buildHeaders(ctx, {
636
+ ...hasBody ? { "content-type": "application/json" } : {},
637
+ ...init.headers
638
+ });
531
639
  const send = () => tlsFetch(
532
640
  ctx.insecure,
533
641
  url,
534
642
  {
535
- method: init.method ?? (hasBody ? "POST" : "GET"),
536
- headers: buildHeaders(ctx, {
537
- ...hasBody ? { "content-type": "application/json" } : {},
538
- ...init.headers
539
- }),
643
+ method,
644
+ headers: headers2,
540
645
  body: hasBody ? stringifyBigIntJSON(init.body) : void 0,
541
646
  redirect: init.redirect,
542
647
  signal: controller.signal
@@ -551,7 +656,7 @@ async function request(ctx, path, init = {}) {
551
656
  const text = await res.text();
552
657
  const contentType = res.headers.get("content-type") ?? "";
553
658
  if (!res.ok) {
554
- const gateway = gatewayHint(url, contentType, text);
659
+ const gateway = gatewayHint(url, res.status, contentType, text);
555
660
  const hints = [gateway, hintFor(ctx, res.status, text)].filter(Boolean);
556
661
  throw new HttpError(
557
662
  res.status,
@@ -565,7 +670,7 @@ async function request(ctx, path, init = {}) {
565
670
  try {
566
671
  return (init.responseParser ?? JSON.parse)(text);
567
672
  } catch {
568
- const gateway = gatewayHint(url, contentType, text);
673
+ const gateway = gatewayHint(url, res.status, contentType, text);
569
674
  throw new NonJsonResponseError(
570
675
  res.status,
571
676
  contentType,
@@ -578,9 +683,16 @@ async function request(ctx, path, init = {}) {
578
683
  clearTimeout(timer);
579
684
  }
580
685
  }
581
- function gatewayHint(url, contentType, body) {
686
+ function gatewayHint(url, status2, contentType, body) {
582
687
  const looksHtml = contentType.includes("html") || /^\s*(<!doctype html|<html)/i.test(body.slice(0, 200));
583
688
  if (!looksHtml) return void 0;
689
+ if (status2 === 504 || status2 === 408) {
690
+ return [
691
+ "The gateway timed out waiting for the service behind",
692
+ `${url.pathname} \u2014 it is routed, it did not answer in time. Long-running work`,
693
+ "(a sandbox run, a build) may still be going; retry the read rather than the write."
694
+ ].join(" ");
695
+ }
584
696
  return [
585
697
  "The response is an HTML error page, not JSON \u2014 the request did not reach the service",
586
698
  `behind ${url.pathname}. That backend is likely not deployed or not routed on this`,
@@ -818,7 +930,7 @@ function resolveContext(opts = {}) {
818
930
  "No base URL. Pass --base-url, set BKN_BASE_URL, or run `openbkn auth login`."
819
931
  );
820
932
  }
821
- const normalized = baseUrl.replace(/\/+$/, "");
933
+ const normalized = trimTrailingSlashes(baseUrl);
822
934
  const user = opts.user ?? process.env.BKN_USER;
823
935
  const stored = user ? readToken(normalized, resolveUserId(normalized, user)) : readToken(normalized);
824
936
  const explicit = opts.token ?? process.env.BKN_TOKEN;
@@ -1140,6 +1252,9 @@ function admin(ctx) {
1140
1252
  };
1141
1253
  }
1142
1254
 
1255
+ // src/api/lifecycle.ts
1256
+ import { createHash, randomUUID as randomUUID2 } from "crypto";
1257
+
1143
1258
  // src/api/auth-fetch.ts
1144
1259
  async function authFetch(ctx, send) {
1145
1260
  let res = await send();
@@ -1149,267 +1264,6 @@ async function authFetch(ctx, send) {
1149
1264
  return res;
1150
1265
  }
1151
1266
 
1152
- // src/api/agent-chat.ts
1153
- var FACTORY = "/api/agent-factory";
1154
- async function fetchAgentInfo(ctx, agentId, version = "v0") {
1155
- const data = await request(
1156
- ctx,
1157
- `${FACTORY}/v3/agent-market/agent/${encodeURIComponent(agentId)}/version/${encodeURIComponent(version)}`,
1158
- { query: { is_visit: true } }
1159
- );
1160
- const id = data.id;
1161
- const key = data.key;
1162
- if (typeof id !== "string" || !id || typeof key !== "string" || !key) {
1163
- throw new Error("Agent info response did not include id and key.");
1164
- }
1165
- return { id, key, version: typeof data.version === "string" ? data.version : version };
1166
- }
1167
- function getByPath(obj, path) {
1168
- let cur = obj;
1169
- for (const k of path) {
1170
- if (cur === null || typeof cur !== "object") return void 0;
1171
- cur = cur[k];
1172
- }
1173
- return cur;
1174
- }
1175
- function setByPath(obj, path, value) {
1176
- let cur = obj;
1177
- for (let i = 0; i < path.length - 1; i += 1) {
1178
- const k = path[i];
1179
- if (!(k in cur) || typeof cur[k] !== "object" || cur[k] === null) cur[k] = {};
1180
- cur = cur[k];
1181
- }
1182
- cur[path[path.length - 1]] = value;
1183
- }
1184
- function applyPatch(data, result) {
1185
- const path = data.key;
1186
- if (!path || path.length === 0) return;
1187
- if (data.action === "upsert" && data.content !== void 0) {
1188
- setByPath(result, path, data.content);
1189
- } else if (data.action === "append") {
1190
- const existing = getByPath(result, path);
1191
- const add = typeof data.content === "string" ? data.content : String(data.content ?? "");
1192
- setByPath(result, path, typeof existing === "string" ? existing + add : add);
1193
- } else if (data.action === "remove" && path.length === 1) {
1194
- delete result[path[0]];
1195
- }
1196
- }
1197
- function extractText(result) {
1198
- const content = getByPath(result, ["message", "content"]);
1199
- if (content) {
1200
- if (typeof content.text === "string" && content.text) return content.text;
1201
- const fa = content.final_answer;
1202
- const ans = fa?.answer;
1203
- if (typeof ans?.text === "string" && ans.text) return ans.text;
1204
- if (typeof fa?.text === "string" && fa.text) return fa.text;
1205
- }
1206
- const msg = result.message;
1207
- if (typeof msg?.text === "string" && msg.text) return msg.text;
1208
- return "";
1209
- }
1210
- async function sendChat(ctx, info, query, opts = {}) {
1211
- const body = {
1212
- agent_id: info.id,
1213
- agent_key: info.key,
1214
- agent_version: info.version,
1215
- query,
1216
- stream: Boolean(opts.stream)
1217
- };
1218
- if (opts.conversationId) body.conversation_id = opts.conversationId;
1219
- const res = await authFetch(
1220
- ctx,
1221
- () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${FACTORY}/v1/app/${info.key}/chat/completion`, {
1222
- method: "POST",
1223
- headers: {
1224
- ...buildHeaders(ctx),
1225
- "content-type": "application/json",
1226
- accept: opts.stream ? "text/event-stream" : "application/json",
1227
- "x-language": "zh-CN"
1228
- },
1229
- body: stringifyBigIntJSON(body)
1230
- })
1231
- );
1232
- if (!res.ok) throw new HttpError(res.status, res.statusText, await res.text());
1233
- const contentType = res.headers.get("content-type") ?? "";
1234
- if (opts.stream && contentType.includes("text/event-stream")) {
1235
- return consumeStream(res, opts.onDelta);
1236
- }
1237
- const result = parseBigIntJSON(await res.text());
1238
- return { text: extractText(result), conversationId: conversationIdOf(result) };
1239
- }
1240
- function conversationIdOf(result) {
1241
- const id = result.conversation_id;
1242
- return typeof id === "string" ? id : void 0;
1243
- }
1244
- async function consumeStream(res, onDelta) {
1245
- const reader = res.body?.getReader();
1246
- if (!reader) throw new Error("No response body for stream");
1247
- const decoder = new TextDecoder();
1248
- const result = {};
1249
- let buffer = "";
1250
- let lastText = "";
1251
- let conversationId;
1252
- const handle = (line) => {
1253
- if (!line.startsWith("data:")) return;
1254
- const payload = line.slice(5).trim();
1255
- if (payload === "" || payload === "[DONE]") return;
1256
- let data;
1257
- try {
1258
- data = parseBigIntJSON(payload);
1259
- } catch {
1260
- return;
1261
- }
1262
- applyPatch(data, result);
1263
- if (data.key?.length === 1 && data.key[0] === "conversation_id") {
1264
- conversationId = typeof data.content === "string" ? data.content : conversationId;
1265
- }
1266
- const text = extractText(result);
1267
- if (text && text !== lastText) {
1268
- if (onDelta) onDelta(text.slice(lastText.length));
1269
- lastText = text;
1270
- }
1271
- };
1272
- for (; ; ) {
1273
- const { done, value } = await reader.read();
1274
- if (done) break;
1275
- buffer += decoder.decode(value, { stream: true });
1276
- const lines = buffer.split("\n");
1277
- buffer = lines.pop() ?? "";
1278
- for (const ln of lines) handle(ln.replace(/\r$/, ""));
1279
- }
1280
- if (buffer.trim()) handle(buffer.trim());
1281
- return { text: lastText, conversationId: conversationId ?? conversationIdOf(result) };
1282
- }
1283
-
1284
- // src/api/agents.ts
1285
- var BASE = "/api/agent-factory/v3";
1286
- function listAgents(ctx, opts = {}) {
1287
- return request(ctx, `${BASE}/published/agent`, {
1288
- method: "POST",
1289
- body: {
1290
- offset: opts.offset ?? 0,
1291
- limit: opts.limit ?? 30,
1292
- category_id: opts.categoryId ?? "",
1293
- name: opts.name ?? "",
1294
- custom_space_id: opts.customSpaceId ?? "",
1295
- is_to_square: opts.isToSquare ?? 1
1296
- }
1297
- });
1298
- }
1299
- function getAgent(ctx, agentId) {
1300
- return request(ctx, `${BASE}/agent/${encodeURIComponent(agentId)}`);
1301
- }
1302
- function getAgentByKey(ctx, key) {
1303
- return request(ctx, `${BASE}/agent/by-key/${encodeURIComponent(key)}`);
1304
- }
1305
- function listPersonalAgents(ctx, opts = {}) {
1306
- return request(ctx, `${BASE}/personal-space/agent-list`, {
1307
- query: { offset: opts.offset ?? 0, limit: opts.limit ?? 30, name: opts.name || void 0 }
1308
- });
1309
- }
1310
- function listAgentTemplates(ctx, opts = {}) {
1311
- return request(ctx, `${BASE}/published/agent-tpl`, {
1312
- query: { offset: opts.offset ?? 0, limit: opts.limit ?? 30, name: opts.name || void 0 }
1313
- });
1314
- }
1315
- function getAgentTemplate(ctx, templateId) {
1316
- return request(ctx, `${BASE}/published/agent-tpl/${encodeURIComponent(templateId)}`);
1317
- }
1318
- function listAgentCategories(ctx) {
1319
- return request(ctx, `${BASE}/category`);
1320
- }
1321
- function createAgent(ctx, body) {
1322
- return request(ctx, `${BASE}/agent`, { method: "POST", body });
1323
- }
1324
- function updateAgent(ctx, agentId, body) {
1325
- return request(ctx, `${BASE}/agent/${encodeURIComponent(agentId)}`, { method: "PUT", body });
1326
- }
1327
- function deleteAgent(ctx, agentId) {
1328
- return request(ctx, `${BASE}/agent/${encodeURIComponent(agentId)}`, { method: "DELETE" });
1329
- }
1330
- function publishAgent(ctx, agentId) {
1331
- return request(ctx, `${BASE}/agent/${encodeURIComponent(agentId)}/publish`, { method: "POST" });
1332
- }
1333
- function unpublishAgent(ctx, agentId) {
1334
- return request(ctx, `${BASE}/agent/${encodeURIComponent(agentId)}/unpublish`, { method: "PUT" });
1335
- }
1336
- var APP = "/api/agent-factory/v1/app";
1337
- function listConversations(ctx, agentKey, opts = {}) {
1338
- return request(ctx, `${APP}/${encodeURIComponent(agentKey)}/conversation`, {
1339
- query: { page: opts.page ?? 1, size: opts.size ?? 30 }
1340
- });
1341
- }
1342
- function listMessages(ctx, agentKey, conversationId) {
1343
- return request(
1344
- ctx,
1345
- `${APP}/${encodeURIComponent(agentKey)}/conversation/${encodeURIComponent(conversationId)}`
1346
- );
1347
- }
1348
-
1349
- // src/resources/agents.ts
1350
- function skillMembers(agent) {
1351
- const config = agent.config ?? {};
1352
- const skills2 = config.skills ?? {};
1353
- return Array.isArray(skills2.skills) ? skills2.skills : [];
1354
- }
1355
- function setSkillMembers(agent, members) {
1356
- if (!agent.config || typeof agent.config !== "object") agent.config = {};
1357
- const config = agent.config;
1358
- if (!config.skills || typeof config.skills !== "object") config.skills = {};
1359
- config.skills.skills = members;
1360
- }
1361
- function agents2(ctx) {
1362
- return {
1363
- list: (opts) => listAgents(ctx, opts),
1364
- get: (agentId) => getAgent(ctx, agentId),
1365
- getByKey: (key) => getAgentByKey(ctx, key),
1366
- personalList: (opts) => listPersonalAgents(ctx, opts),
1367
- templateList: (opts) => listAgentTemplates(ctx, opts),
1368
- templateGet: (templateId) => getAgentTemplate(ctx, templateId),
1369
- categoryList: () => listAgentCategories(ctx),
1370
- create: (body) => createAgent(ctx, body),
1371
- update: (agentId, body) => updateAgent(ctx, agentId, body),
1372
- delete: (agentId) => deleteAgent(ctx, agentId),
1373
- publish: (agentId) => publishAgent(ctx, agentId),
1374
- unpublish: (agentId) => unpublishAgent(ctx, agentId),
1375
- sessions: (agentKey, opts) => listConversations(ctx, agentKey, opts),
1376
- history: (agentKey, conversationId) => listMessages(ctx, agentKey, conversationId),
1377
- /** List skill ids attached to an agent (config.skills.skills). */
1378
- skillList: async (agentId) => {
1379
- const agent = await getAgent(ctx, agentId);
1380
- const arr = skillMembers(agent);
1381
- return arr.map((m) => String(m.skill_id ?? "")).filter(Boolean);
1382
- },
1383
- /** Attach skill(s) to an agent (dedup), then persist. */
1384
- skillAdd: async (agentId, skillIds) => {
1385
- const agent = await getAgent(ctx, agentId);
1386
- const arr = skillMembers(agent);
1387
- const have = new Set(arr.map((m) => String(m.skill_id ?? "")));
1388
- for (const id of skillIds) if (!have.has(id)) arr.push({ skill_id: id });
1389
- setSkillMembers(agent, arr);
1390
- return updateAgent(ctx, agentId, agent);
1391
- },
1392
- /** Detach skill(s) from an agent, then persist. */
1393
- skillRemove: async (agentId, skillIds) => {
1394
- const agent = await getAgent(ctx, agentId);
1395
- const drop = new Set(skillIds);
1396
- const arr = skillMembers(agent).filter(
1397
- (m) => !drop.has(String(m.skill_id ?? ""))
1398
- );
1399
- setSkillMembers(agent, arr);
1400
- return updateAgent(ctx, agentId, agent);
1401
- },
1402
- /** Send a chat turn to an agent (resolves agent id/key/version first). */
1403
- chat: async (agentId, query, opts = {}) => {
1404
- const info = await fetchAgentInfo(ctx, agentId, opts.version ?? "v0");
1405
- return sendChat(ctx, info, query, opts);
1406
- }
1407
- };
1408
- }
1409
-
1410
- // src/api/lifecycle.ts
1411
- import { createHash, randomUUID as randomUUID2 } from "crypto";
1412
-
1413
1267
  // src/api/context-loader.ts
1414
1268
  var MCP_PATH = "/api/agent-retrieval/v1/mcp";
1415
1269
  var PROTOCOL = "2024-11-05";
@@ -1450,16 +1304,19 @@ function parseBody(text) {
1450
1304
  async function post(ctx, knId, sessionId, body, timeoutMs) {
1451
1305
  const controller = timeoutMs === void 0 ? void 0 : new AbortController();
1452
1306
  const timer = controller === void 0 ? void 0 : setTimeout(() => controller.abort(), timeoutMs);
1307
+ const rpcMethod = body?.method;
1308
+ const isHandshake = rpcMethod === "initialize" || Boolean(rpcMethod?.startsWith("notifications/"));
1309
+ const send = () => authFetch(
1310
+ ctx,
1311
+ () => tlsFetch(ctx.insecure, mcpUrl(ctx), {
1312
+ method: "POST",
1313
+ headers: headers(ctx, knId, sessionId),
1314
+ body: stringifyBigIntJSON(body),
1315
+ ...controller ? { signal: controller.signal } : {}
1316
+ })
1317
+ );
1453
1318
  try {
1454
- const res = await authFetch(
1455
- ctx,
1456
- () => tlsFetch(ctx.insecure, mcpUrl(ctx), {
1457
- method: "POST",
1458
- headers: headers(ctx, knId, sessionId),
1459
- body: stringifyBigIntJSON(body),
1460
- ...controller ? { signal: controller.signal } : {}
1461
- })
1462
- );
1319
+ const res = await (isHandshake ? withoutPreview(send) : send());
1463
1320
  const text = await res.text();
1464
1321
  if (!res.ok) throw new HttpError(res.status, res.statusText, text);
1465
1322
  return { res, text };
@@ -1506,7 +1363,8 @@ function unwrapToolResult(parsed) {
1506
1363
  const receipt = structuredContent?.bkn_receipt;
1507
1364
  const content = result.content;
1508
1365
  if (result.isError === true) {
1509
- const message = Array.isArray(content) && content[0] && typeof content[0].text === "string" ? content[0].text : "tool call failed";
1366
+ const raw = Array.isArray(content) && content[0] && typeof content[0].text === "string" ? content[0].text : "tool call failed";
1367
+ const message = readableServerError(raw) || raw;
1510
1368
  throw new ToolError(`Context-loader error: ${message}`, toolErrorCode(structuredContent));
1511
1369
  }
1512
1370
  if (Array.isArray(content) && content[0] && typeof content[0].text === "string") {
@@ -1941,15 +1799,93 @@ function context(ctx) {
1941
1799
  };
1942
1800
  }
1943
1801
 
1802
+ // src/api/sandbox-budget.ts
1803
+ var SANDBOX_MAX_TIMEOUT_SEC = 3600;
1804
+ function sandboxBudgetMs(timeoutSec) {
1805
+ return (timeoutSec ?? SANDBOX_MAX_TIMEOUT_SEC) * 1e3 + 15e3;
1806
+ }
1807
+
1808
+ // src/api/functions.ts
1809
+ var PATH = "/api/agent-operator-integration/v1";
1810
+ function functionInputBody(def) {
1811
+ return {
1812
+ name: def.name,
1813
+ description: def.description ?? "",
1814
+ script_type: def.scriptType ?? "python",
1815
+ code: def.code,
1816
+ inputs: def.inputs ?? [],
1817
+ outputs: def.outputs ?? [],
1818
+ ...def.dependencies?.length ? { dependencies: def.dependencies } : {},
1819
+ ...def.dependenciesUrl ? { dependencies_url: def.dependenciesUrl } : {}
1820
+ };
1821
+ }
1822
+ function executeFunction(ctx, opts) {
1823
+ return request(ctx, `${PATH}/function/execute`, {
1824
+ method: "POST",
1825
+ // The sandbox has to boot, install, and run before it answers, and it sends
1826
+ // no header until it does — so the abort budget and undici's 300s header
1827
+ // deadline both have to move, or a long run dies at 300s regardless.
1828
+ timeoutMs: sandboxBudgetMs(opts.timeout),
1829
+ headersTimeoutMs: sandboxBudgetMs(opts.timeout),
1830
+ body: {
1831
+ code: opts.code,
1832
+ event: opts.event ?? {},
1833
+ ...opts.language ? { language: opts.language } : {},
1834
+ ...opts.timeout !== void 0 ? { timeout: opts.timeout } : {},
1835
+ ...opts.dependencies?.length ? { dependencies: opts.dependencies } : {},
1836
+ ...opts.dependenciesUrl ? { dependencies_url: opts.dependenciesUrl } : {},
1837
+ ...opts.source ? { source: opts.source } : {},
1838
+ ...opts.taskId ? { task_id: opts.taskId } : {},
1839
+ ...opts.bknToken ? { bkn_token: opts.bknToken } : {},
1840
+ ...opts.conversationId ? { bkn_conversation_id: opts.conversationId } : {},
1841
+ ...opts.interactionId ? { bkn_interaction_id: opts.interactionId } : {}
1842
+ }
1843
+ });
1844
+ }
1845
+ function inferFunctionSchema(ctx, code) {
1846
+ return request(ctx, `${PATH}/function/infer-schema`, {
1847
+ method: "POST",
1848
+ // Deriving a schema runs the code, so it is a sandbox run like any other.
1849
+ timeoutMs: sandboxBudgetMs(void 0),
1850
+ headersTimeoutMs: sandboxBudgetMs(void 0),
1851
+ body: { code }
1852
+ });
1853
+ }
1854
+ function listFunctionDependencies(ctx) {
1855
+ return request(ctx, `${PATH}/function/dependencies`);
1856
+ }
1857
+ function listDependencyVersions(ctx, packageName, opts = {}) {
1858
+ return request(ctx, `${PATH}/function/dependency-versions/${encodeURIComponent(packageName)}`, {
1859
+ query: {
1860
+ pypi_repo_url: opts.pypiRepoUrl,
1861
+ python_version: opts.pythonVersion
1862
+ }
1863
+ });
1864
+ }
1865
+ function functionTemplate(ctx, templateType = "python") {
1866
+ return request(ctx, `${PATH}/template/${encodeURIComponent(templateType)}`);
1867
+ }
1868
+
1869
+ // src/resources/functions.ts
1870
+ function functions(ctx) {
1871
+ return {
1872
+ run: (opts) => executeFunction(ctx, opts),
1873
+ inferSchema: (code) => inferFunctionSchema(ctx, code),
1874
+ dependencies: () => listFunctionDependencies(ctx),
1875
+ dependencyVersions: (packageName, opts) => listDependencyVersions(ctx, packageName, opts),
1876
+ template: (templateType) => functionTemplate(ctx, templateType)
1877
+ };
1878
+ }
1879
+
1944
1880
  // src/resources/knowledge-networks.ts
1945
1881
  import { mkdirSync as mkdirSync2 } from "fs";
1946
1882
  import { resolve as resolve2 } from "path";
1947
1883
 
1948
1884
  // src/api/bkn-backend.ts
1949
- var BASE2 = "/api/bkn-backend/v1/knowledge-networks";
1885
+ var BASE = "/api/bkn-backend/v1/knowledge-networks";
1950
1886
  var BKNS = "/api/bkn-backend/v1/bkns";
1951
1887
  function knPath(knId, path) {
1952
- return `${BASE2}/${encodeURIComponent(knId)}/${path}`;
1888
+ return `${BASE}/${encodeURIComponent(knId)}/${path}`;
1953
1889
  }
1954
1890
  async function uploadBkn(ctx, tarBuffer, opts = {}) {
1955
1891
  const url = new URL(`${ctx.baseUrl}${BKNS}`);
@@ -2049,7 +1985,7 @@ function deleteActionSchedules(ctx, knId, ids) {
2049
1985
  }
2050
1986
 
2051
1987
  // src/api/knowledge-networks.ts
2052
- var ONTOLOGY_BASE = "/api/ontology-manager/v1/knowledge-networks";
1988
+ var ONTOLOGY_BASE = "/api/bkn-backend/v1/knowledge-networks";
2053
1989
  var ONTOLOGY_QUERY_BASE = "/api/ontology-query/v1/knowledge-networks";
2054
1990
  var RETRIEVAL_BASE = "/api/agent-retrieval/v1/kn";
2055
1991
  function listKnowledgeNetworks(ctx, opts = {}) {
@@ -2140,12 +2076,6 @@ function executeActionType(ctx, knId, atId, body) {
2140
2076
  { method: "POST", body, responseParser: parseBigIntJSON }
2141
2077
  );
2142
2078
  }
2143
- function getActionTypeInputs(ctx, knId, atId) {
2144
- return request(
2145
- ctx,
2146
- `${ONTOLOGY_QUERY_BASE}/${encodeURIComponent(knId)}/action-types/${encodeURIComponent(atId)}/inputs`
2147
- );
2148
- }
2149
2079
  function getActionExecution(ctx, knId, executionId) {
2150
2080
  return request(
2151
2081
  ctx,
@@ -2259,12 +2189,6 @@ function deleteMetric(ctx, knId, metricId) {
2259
2189
  }
2260
2190
  );
2261
2191
  }
2262
- function searchMetrics(ctx, knId, body) {
2263
- return request(ctx, `${ONTOLOGY_BASE}/${encodeURIComponent(knId)}/metrics/search`, {
2264
- method: "POST",
2265
- body
2266
- });
2267
- }
2268
2192
  function validateMetric(ctx, knId, body) {
2269
2193
  return request(ctx, `${ONTOLOGY_BASE}/${encodeURIComponent(knId)}/metrics/validation`, {
2270
2194
  method: "POST",
@@ -2275,14 +2199,18 @@ function searchBody(knId, query, opts) {
2275
2199
  return {
2276
2200
  kn_id: knId,
2277
2201
  query,
2278
- mode: opts.mode ?? "keyword_vector_retrieval",
2279
- max_concepts: opts.maxConcepts ?? 10,
2280
- return_query_understanding: opts.returnQueryUnderstanding ?? false
2202
+ ...opts.conceptGroups?.length ? { concept_groups: opts.conceptGroups } : {},
2203
+ ...opts.objectTypes?.length ? { object_types: opts.objectTypes } : {},
2204
+ ...opts.excludeObjectTypes?.length ? { exclude_object_types: opts.excludeObjectTypes } : {},
2205
+ ...opts.maxObjectTypes === void 0 ? {} : { max_object_types: opts.maxObjectTypes },
2206
+ ...opts.maxInstancesPerType === void 0 ? {} : { max_instances_per_type: opts.maxInstancesPerType },
2207
+ ...opts.rerank === void 0 ? {} : { rerank: opts.rerank },
2208
+ ...opts.includeObjectTypes === void 0 ? {} : { include_object_types: opts.includeObjectTypes }
2281
2209
  };
2282
2210
  }
2283
- function semanticSearch(ctx, knId, query, opts = {}) {
2211
+ function searchInstance(ctx, knId, query, opts = {}) {
2284
2212
  if (opts.bknContext) {
2285
- return request(ctx, `${RETRIEVAL_BASE}/semantic-search`, {
2213
+ return request(ctx, `${RETRIEVAL_BASE}/search_instance`, {
2286
2214
  method: "POST",
2287
2215
  body: { ...searchBody(knId, query, opts), bkn_context: opts.bknContext }
2288
2216
  });
@@ -2291,7 +2219,7 @@ function semanticSearch(ctx, knId, query, opts = {}) {
2291
2219
  ctx,
2292
2220
  knId,
2293
2221
  query,
2294
- (bknContext) => request(ctx, `${RETRIEVAL_BASE}/semantic-search`, {
2222
+ (bknContext) => request(ctx, `${RETRIEVAL_BASE}/search_instance`, {
2295
2223
  method: "POST",
2296
2224
  body: {
2297
2225
  ...searchBody(knId, query, opts),
@@ -2466,7 +2394,7 @@ async function rerank(ctx, model, query, documents) {
2466
2394
  }
2467
2395
 
2468
2396
  // src/api/resources.ts
2469
- var BASE3 = "/api/vega-backend/v1/resources";
2397
+ var BASE2 = "/api/vega-backend/v1/resources";
2470
2398
  var ResourceCategory = z.enum([
2471
2399
  "table",
2472
2400
  "file",
@@ -2478,7 +2406,7 @@ var ResourceCategory = z.enum([
2478
2406
  "logicview",
2479
2407
  "dataset"
2480
2408
  ]);
2481
- var ResourceStatus = z.enum(["active", "disabled", "deprecated", "stale"]);
2409
+ var ResourceStatus = z.enum(["active", "deprecated", "stale"]);
2482
2410
  var ResourceLocalStatus = z.enum(["unavailable", "available", "stale"]);
2483
2411
  var ResourceAccountInfo = z.object({ id: z.string(), type: z.string(), name: z.string().optional() }).passthrough();
2484
2412
  var nullAsAbsent = (schema) => schema.nullish().transform((v) => v ?? void 0);
@@ -2516,6 +2444,8 @@ var Resource = z.object({
2516
2444
  // status; request options below remain constrained to known values.
2517
2445
  category: z.string(),
2518
2446
  status: z.string(),
2447
+ // Older deployments omit this newly split field; the migration default is enabled.
2448
+ enabled: z.boolean().default(true),
2519
2449
  status_message: z.string().optional(),
2520
2450
  last_discover_status: z.string().optional(),
2521
2451
  schema: z.string().optional(),
@@ -2542,10 +2472,16 @@ var Resource = z.object({
2542
2472
  update_time: z.number(),
2543
2473
  operations: z.array(z.string()).optional()
2544
2474
  }).passthrough();
2545
- var ListResourcesResponse = z.object({ entries: z.array(Resource), total_count: z.number() }).passthrough();
2475
+ var ResourceSummary = Resource.omit({
2476
+ source_metadata: true,
2477
+ schema_definition: true,
2478
+ index_config: true,
2479
+ logic_definition: true
2480
+ });
2481
+ var ListResourcesResponse = z.object({ entries: z.array(ResourceSummary), total_count: z.number() }).passthrough();
2546
2482
  var BatchResourcesResponse = z.object({ entries: z.array(Resource) }).passthrough();
2547
2483
  async function listResources2(ctx, opts = {}) {
2548
- const result = await request(ctx, BASE3, {
2484
+ const result = await request(ctx, BASE2, {
2549
2485
  query: {
2550
2486
  catalog_id: opts.catalogId || void 0,
2551
2487
  name: opts.name || void 0,
@@ -2565,7 +2501,7 @@ async function listResources2(ctx, opts = {}) {
2565
2501
  }
2566
2502
  async function getResource(ctx, id, opts = {}) {
2567
2503
  const ids = Array.isArray(id) ? id : [id];
2568
- const result = await request(ctx, `${BASE3}/${ids.map(encodeURIComponent).join(",")}`, {
2504
+ const result = await request(ctx, `${BASE2}/${ids.map(encodeURIComponent).join(",")}`, {
2569
2505
  query: {
2570
2506
  ignore_missing: opts.ignoreMissing === void 0 ? void 0 : String(opts.ignoreMissing)
2571
2507
  }
@@ -2573,7 +2509,7 @@ async function getResource(ctx, id, opts = {}) {
2573
2509
  return BatchResourcesResponse.parse(result);
2574
2510
  }
2575
2511
  function createResourceRaw(ctx, body) {
2576
- return request(ctx, BASE3, { method: "POST", body });
2512
+ return request(ctx, BASE2, { method: "POST", body });
2577
2513
  }
2578
2514
  async function createResource(ctx, req) {
2579
2515
  const result = await createResourceRaw(ctx, {
@@ -2594,7 +2530,13 @@ async function createResource(ctx, req) {
2594
2530
  return Resource.parse(result);
2595
2531
  }
2596
2532
  function updateResourceRaw(ctx, id, body) {
2597
- return request(ctx, `${BASE3}/${encodeURIComponent(id)}`, { method: "PUT", body });
2533
+ return request(ctx, `${BASE2}/${encodeURIComponent(id)}`, { method: "PUT", body });
2534
+ }
2535
+ function enableResource(ctx, id) {
2536
+ return request(ctx, `${BASE2}/${encodeURIComponent(id)}/enable`, { method: "POST" });
2537
+ }
2538
+ function disableResource(ctx, id) {
2539
+ return request(ctx, `${BASE2}/${encodeURIComponent(id)}/disable`, { method: "POST" });
2598
2540
  }
2599
2541
  async function updateResource(ctx, id, patch) {
2600
2542
  const current = firstResource(await getResource(ctx, id));
@@ -2635,6 +2577,7 @@ function resourceUpdateBody(id, current, patch) {
2635
2577
  tags: patch.tags ?? current.tags ?? [],
2636
2578
  description: patch.description ?? current.description ?? "",
2637
2579
  category: current.category,
2580
+ enabled: current.enabled,
2638
2581
  schema_definition: patch.schemaDefinition ?? current.schema_definition,
2639
2582
  index_config: patch.indexConfig === void 0 ? current.index_config : patch.indexConfig,
2640
2583
  logic_definition: patch.logicDefinition ?? current.logic_definition
@@ -2674,7 +2617,7 @@ function firstResource(result) {
2674
2617
  }
2675
2618
  function deleteResource(ctx, id, opts = {}) {
2676
2619
  const ids = Array.isArray(id) ? id : [id];
2677
- return request(ctx, `${BASE3}/${ids.map(encodeURIComponent).join(",")}`, {
2620
+ return request(ctx, `${BASE2}/${ids.map(encodeURIComponent).join(",")}`, {
2678
2621
  method: "DELETE",
2679
2622
  query: {
2680
2623
  ignore_missing: opts.ignoreMissing === void 0 ? void 0 : String(opts.ignoreMissing)
@@ -2714,7 +2657,7 @@ function queryResource(ctx, id, opts = {}) {
2714
2657
  } : {},
2715
2658
  ...opts.having !== void 0 ? { having: opts.having } : {}
2716
2659
  };
2717
- return request(ctx, `${BASE3}/${encodeURIComponent(id)}/data`, {
2660
+ return request(ctx, `${BASE2}/${encodeURIComponent(id)}/data`, {
2718
2661
  method: "POST",
2719
2662
  headers: { "X-HTTP-Method-Override": "GET" },
2720
2663
  body,
@@ -2722,7 +2665,7 @@ function queryResource(ctx, id, opts = {}) {
2722
2665
  });
2723
2666
  }
2724
2667
  async function createResourceDocuments(ctx, resourceId, documents) {
2725
- const result = await request(ctx, `${BASE3}/${encodeURIComponent(resourceId)}/data`, {
2668
+ const result = await request(ctx, `${BASE2}/${encodeURIComponent(resourceId)}/data`, {
2726
2669
  method: "POST",
2727
2670
  headers: { "X-HTTP-Method-Override": "POST" },
2728
2671
  body: documents
@@ -2730,7 +2673,7 @@ async function createResourceDocuments(ctx, resourceId, documents) {
2730
2673
  return z.object({ ids: z.array(z.string()) }).passthrough().parse(result);
2731
2674
  }
2732
2675
  async function upsertResourceDocuments(ctx, resourceId, documents) {
2733
- const result = await request(ctx, `${BASE3}/${encodeURIComponent(resourceId)}/data`, {
2676
+ const result = await request(ctx, `${BASE2}/${encodeURIComponent(resourceId)}/data`, {
2734
2677
  method: "PUT",
2735
2678
  body: documents
2736
2679
  });
@@ -2739,7 +2682,7 @@ async function upsertResourceDocuments(ctx, resourceId, documents) {
2739
2682
  async function getResourceDocument(ctx, resourceId, documentId) {
2740
2683
  const result = await request(
2741
2684
  ctx,
2742
- `${BASE3}/${encodeURIComponent(resourceId)}/data/${encodeURIComponent(documentId)}`,
2685
+ `${BASE2}/${encodeURIComponent(resourceId)}/data/${encodeURIComponent(documentId)}`,
2743
2686
  { responseParser: parseBigIntJSON }
2744
2687
  );
2745
2688
  return z.record(z.unknown()).parse(result);
@@ -2747,7 +2690,7 @@ async function getResourceDocument(ctx, resourceId, documentId) {
2747
2690
  async function upsertResourceDocument(ctx, resourceId, documentId, document) {
2748
2691
  const result = await request(
2749
2692
  ctx,
2750
- `${BASE3}/${encodeURIComponent(resourceId)}/data/${encodeURIComponent(documentId)}`,
2693
+ `${BASE2}/${encodeURIComponent(resourceId)}/data/${encodeURIComponent(documentId)}`,
2751
2694
  { method: "PUT", body: document }
2752
2695
  );
2753
2696
  return z.object({ id: z.string() }).passthrough().parse(result);
@@ -2756,7 +2699,7 @@ function deleteResourceDocuments(ctx, resourceId, documentIds) {
2756
2699
  const ids = Array.isArray(documentIds) ? documentIds : [documentIds];
2757
2700
  return request(
2758
2701
  ctx,
2759
- `${BASE3}/${encodeURIComponent(resourceId)}/data/${ids.map(encodeURIComponent).join(",")}`,
2702
+ `${BASE2}/${encodeURIComponent(resourceId)}/data/${ids.map(encodeURIComponent).join(",")}`,
2760
2703
  { method: "DELETE" }
2761
2704
  );
2762
2705
  }
@@ -2764,7 +2707,7 @@ async function deleteResourceDocumentsByFilter(ctx, resourceId, filterCondition)
2764
2707
  if (Object.keys(filterCondition).length === 0) {
2765
2708
  throw new InputError("delete-by-filter requires a non-empty filter condition");
2766
2709
  }
2767
- return request(ctx, `${BASE3}/${encodeURIComponent(resourceId)}/data`, {
2710
+ return request(ctx, `${BASE2}/${encodeURIComponent(resourceId)}/data`, {
2768
2711
  method: "POST",
2769
2712
  headers: { "X-HTTP-Method-Override": "DELETE" },
2770
2713
  body: { filter_condition: filterCondition }
@@ -2828,7 +2771,8 @@ var Catalog = z2.object({
2828
2771
  update_time: z2.number(),
2829
2772
  operations: z2.array(z2.string()).optional()
2830
2773
  }).passthrough();
2831
- var ListCatalogsResponse = z2.object({ entries: z2.array(Catalog), total_count: z2.number() }).passthrough();
2774
+ var CatalogSummary = Catalog.omit({ connector_config: true, metadata: true });
2775
+ var ListCatalogsResponse = z2.object({ entries: z2.array(CatalogSummary), total_count: z2.number() }).passthrough();
2832
2776
  var BatchCatalogsResponse = z2.object({ entries: z2.array(Catalog) }).passthrough();
2833
2777
  var CatalogRef = z2.object({ id: z2.string() }).passthrough();
2834
2778
  var CatalogHealthStatus = z2.object({
@@ -2967,6 +2911,7 @@ async function listBuildTasks(ctx, opts = {}) {
2967
2911
  catalog_id: opts.catalogId || void 0,
2968
2912
  status: opts.status || void 0,
2969
2913
  mode: opts.mode,
2914
+ execute_type: opts.executeType,
2970
2915
  sort: opts.sort,
2971
2916
  direction: opts.direction
2972
2917
  }
@@ -3457,10 +3402,14 @@ var DiscoverResult = z3.object({
3457
3402
  var DiscoverTask = z3.object({
3458
3403
  id: z3.string(),
3459
3404
  catalog_id: z3.string(),
3405
+ resource_id: z3.string().optional(),
3406
+ resource_name: z3.string().optional(),
3460
3407
  catalog_name: z3.string().optional(),
3461
3408
  schedule_id: z3.string(),
3462
3409
  strategy: z3.string(),
3463
3410
  trigger_type: z3.string(),
3411
+ // Catalog tasks created before priority support have the manual default.
3412
+ queue_priority: z3.number().default(20),
3464
3413
  status: z3.string(),
3465
3414
  progress: z3.number(),
3466
3415
  message: z3.string(),
@@ -3484,6 +3433,7 @@ async function listDiscoverTasks(ctx, opts = {}) {
3484
3433
  const result = await request(ctx, `${VEGA_BASE2}/discover-tasks`, {
3485
3434
  query: {
3486
3435
  catalog_id: opts.catalogId || void 0,
3436
+ resource_id: opts.resourceId || void 0,
3487
3437
  schedule_id: opts.scheduleId || void 0,
3488
3438
  status: opts.status,
3489
3439
  strategy: opts.strategy,
@@ -3520,6 +3470,14 @@ async function discoverCatalog(ctx, catalogId, req = {}) {
3520
3470
  );
3521
3471
  return IdResponse.parse(result);
3522
3472
  }
3473
+ async function discoverResource(ctx, resourceId) {
3474
+ const result = await request(
3475
+ ctx,
3476
+ `${VEGA_BASE2}/resources/${encodeURIComponent(resourceId)}/discover`,
3477
+ { method: "POST" }
3478
+ );
3479
+ return IdResponse.parse(result);
3480
+ }
3523
3481
 
3524
3482
  // src/utils/pk-detection.ts
3525
3483
  var PK_NAME_HINTS = ["id", "_id", "pk"];
@@ -3934,7 +3892,7 @@ function kn(ctx) {
3934
3892
  return {
3935
3893
  list: (opts) => listKnowledgeNetworks(ctx, opts),
3936
3894
  get: (knId, opts) => getKnowledgeNetwork(ctx, knId, opts),
3937
- search: (knId, query, opts) => semanticSearch(ctx, knId, query, opts),
3895
+ search: (knId, query, opts) => searchInstance(ctx, knId, query, opts),
3938
3896
  create: (opts) => createKnowledgeNetwork(ctx, opts),
3939
3897
  update: (knId, body) => updateKnowledgeNetwork(ctx, knId, body),
3940
3898
  delete: (knId) => deleteKnowledgeNetwork(ctx, knId),
@@ -3950,7 +3908,6 @@ function kn(ctx) {
3950
3908
  metricCreate: (knId, body) => createMetric(ctx, knId, body),
3951
3909
  metricUpdate: (knId, metricId, body) => updateMetric(ctx, knId, metricId, body),
3952
3910
  metricDelete: (knId, metricId) => deleteMetric(ctx, knId, metricId),
3953
- metricSearch: (knId, body) => searchMetrics(ctx, knId, body),
3954
3911
  metricValidate: (knId, body) => validateMetric(ctx, knId, body),
3955
3912
  objectTypes: (knId, opts) => listObjectTypes(ctx, knId, opts),
3956
3913
  objectTypeQuery: (knId, otId, body) => queryObjectTypeInstances(ctx, knId, otId, body),
@@ -3966,7 +3923,6 @@ function kn(ctx) {
3966
3923
  actionTypes: (knId, opts) => listActionTypes(ctx, knId, opts),
3967
3924
  actionTypeQuery: (knId, atId, body) => queryActionType(ctx, knId, atId, body),
3968
3925
  actionTypeExecute: (knId, atId, body) => executeActionType(ctx, knId, atId, body),
3969
- actionTypeInputs: (knId, atId) => getActionTypeInputs(ctx, knId, atId),
3970
3926
  actionTypeGet: (knId, id) => getSchemaItem(ctx, knId, "action-types", id),
3971
3927
  conceptGroups: (knId) => listConceptGroups(ctx, knId),
3972
3928
  conceptGroup: (knId, cgId) => getConceptGroup(ctx, knId, cgId),
@@ -4067,6 +4023,8 @@ function resources(ctx) {
4067
4023
  create: (req) => createResource(ctx, req),
4068
4024
  delete: (id, opts) => deleteResource(ctx, id, opts),
4069
4025
  update: (id, patch) => updateResource(ctx, id, patch),
4026
+ enable: (id) => enableResource(ctx, id),
4027
+ disable: (id) => disableResource(ctx, id),
4070
4028
  configureIndex: (id, opts) => configureResourceIndex(ctx, id, opts),
4071
4029
  find: (name, opts) => findResource(ctx, name, opts),
4072
4030
  query: (id, opts) => queryResource(ctx, id, opts),
@@ -4084,7 +4042,7 @@ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
4084
4042
  import { basename, dirname as dirname2, resolve as resolve4 } from "path";
4085
4043
 
4086
4044
  // src/api/skills.ts
4087
- var BASE4 = "/api/agent-operator-integration/v1";
4045
+ var BASE3 = "/api/agent-operator-integration/v1";
4088
4046
  async function registerSkillZip(ctx, bytes, opts = {}) {
4089
4047
  const form2 = new FormData();
4090
4048
  form2.set("file_type", "zip");
@@ -4093,7 +4051,7 @@ async function registerSkillZip(ctx, bytes, opts = {}) {
4093
4051
  if (opts.extendInfo) form2.set("extend_info", stringifyBigIntJSON(opts.extendInfo));
4094
4052
  const res = await authFetch(
4095
4053
  ctx,
4096
- () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE4}/skills`, {
4054
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE3}/skills`, {
4097
4055
  method: "POST",
4098
4056
  headers: buildHeaders(ctx),
4099
4057
  body: form2
@@ -4109,7 +4067,7 @@ async function updateSkillPackageZip(ctx, skillId, bytes, filename = "skill.zip"
4109
4067
  form2.set("file", new Blob([bytes]), filename);
4110
4068
  const res = await authFetch(
4111
4069
  ctx,
4112
- () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE4}/skills/${encodeURIComponent(skillId)}/package`, {
4070
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE3}/skills/${encodeURIComponent(skillId)}/package`, {
4113
4071
  method: "PUT",
4114
4072
  headers: buildHeaders(ctx),
4115
4073
  body: form2
@@ -4121,7 +4079,7 @@ async function updateSkillPackageZip(ctx, skillId, bytes, filename = "skill.zip"
4121
4079
  }
4122
4080
  function skillPath(skillId, view, path) {
4123
4081
  const seg = view === "draft" ? "management/" : "";
4124
- return `${BASE4}/skills/${encodeURIComponent(skillId)}/${seg}${path}`;
4082
+ return `${BASE3}/skills/${encodeURIComponent(skillId)}/${seg}${path}`;
4125
4083
  }
4126
4084
  async function downloadSkill(ctx, skillId, view = "published") {
4127
4085
  const res = await authFetch(
@@ -4134,7 +4092,7 @@ async function downloadSkill(ctx, skillId, view = "published") {
4134
4092
  return new Uint8Array(await res.arrayBuffer());
4135
4093
  }
4136
4094
  function executeSkill(ctx, skillId, opts) {
4137
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}/execute`, {
4095
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/execute`, {
4138
4096
  method: "POST",
4139
4097
  body: {
4140
4098
  entry_shell: opts.entryShell,
@@ -4145,30 +4103,29 @@ function executeSkill(ctx, skillId, opts) {
4145
4103
  // caller never learns the exit code. With no stated limit the sandbox
4146
4104
  // applies its own — 300s by default, 3600s at most — so the budget has to
4147
4105
  // cover that rather than a number of ours.
4148
- timeoutMs: executeBudgetMs(opts.timeout),
4106
+ timeoutMs: sandboxBudgetMs(opts.timeout),
4149
4107
  // The abort deadline alone tops out at undici's 300s header deadline,
4150
4108
  // because `execute-sync` blocks and sends no headers until the run is over.
4151
- headersTimeoutMs: executeBudgetMs(opts.timeout)
4109
+ headersTimeoutMs: sandboxBudgetMs(opts.timeout)
4152
4110
  });
4153
4111
  }
4154
- var SANDBOX_MAX_TIMEOUT_SEC = 3600;
4155
- function executeBudgetMs(timeoutSec) {
4156
- return (timeoutSec ?? SANDBOX_MAX_TIMEOUT_SEC) * 1e3 + 15e3;
4157
- }
4158
4112
  function getSkillNames(ctx, ids) {
4159
- return request(ctx, `${BASE4}/skills/names`, { method: "POST", body: { ids } });
4113
+ return request(ctx, `${BASE3}/skills/names`, { method: "POST", body: { ids } });
4160
4114
  }
4161
4115
  function updateSkillMetadata(ctx, skillId, body) {
4162
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}`, { method: "PUT", body });
4116
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/metadata`, {
4117
+ method: "PUT",
4118
+ body
4119
+ });
4163
4120
  }
4164
4121
  function republishSkillVersion(ctx, skillId, version) {
4165
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}/history/republish`, {
4122
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/history/republish`, {
4166
4123
  method: "POST",
4167
4124
  body: { version }
4168
4125
  });
4169
4126
  }
4170
4127
  function publishSkillVersion(ctx, skillId, version) {
4171
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}/history/publish`, {
4128
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/history/publish`, {
4172
4129
  method: "POST",
4173
4130
  body: { version }
4174
4131
  });
@@ -4184,19 +4141,19 @@ function listQuery2(opts) {
4184
4141
  };
4185
4142
  }
4186
4143
  function listSkills(ctx, opts = {}) {
4187
- return request(ctx, `${BASE4}/skills`, { query: listQuery2(opts) });
4144
+ return request(ctx, `${BASE3}/skills`, { query: listQuery2(opts) });
4188
4145
  }
4189
4146
  function listSkillMarket(ctx, opts = {}) {
4190
- return request(ctx, `${BASE4}/skills/market`, { query: listQuery2(opts) });
4147
+ return request(ctx, `${BASE3}/skills/market`, { query: listQuery2(opts) });
4191
4148
  }
4192
4149
  function getSkill(ctx, skillId) {
4193
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}`);
4150
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}`);
4194
4151
  }
4195
4152
  function getSkillMarket(ctx, skillId) {
4196
- return request(ctx, `${BASE4}/skills/market/${encodeURIComponent(skillId)}`);
4153
+ return request(ctx, `${BASE3}/skills/market/${encodeURIComponent(skillId)}`);
4197
4154
  }
4198
4155
  function deleteSkill(ctx, skillId) {
4199
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}`, { method: "DELETE" });
4156
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}`, { method: "DELETE" });
4200
4157
  }
4201
4158
  function getSkillContent(ctx, skillId, opts = {}) {
4202
4159
  return request(ctx, skillPath(skillId, opts.view ?? "published", "content"), {
@@ -4211,10 +4168,10 @@ function readSkillFile(ctx, skillId, relPath, opts = {}) {
4211
4168
  });
4212
4169
  }
4213
4170
  function getSkillHistory(ctx, skillId) {
4214
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}/history`);
4171
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/history`);
4215
4172
  }
4216
4173
  function setSkillStatus(ctx, skillId, status2) {
4217
- return request(ctx, `${BASE4}/skills/${encodeURIComponent(skillId)}/status`, {
4174
+ return request(ctx, `${BASE3}/skills/${encodeURIComponent(skillId)}/status`, {
4218
4175
  method: "PUT",
4219
4176
  body: { status: status2 }
4220
4177
  });
@@ -4502,7 +4459,7 @@ import { dirname as dirname3, resolve as resolve5 } from "path";
4502
4459
  // src/api/toolboxes.ts
4503
4460
  import { readFile } from "fs/promises";
4504
4461
  import { basename as basename2 } from "path";
4505
- var PATH = "/api/agent-operator-integration/v1/tool-box";
4462
+ var PATH2 = "/api/agent-operator-integration/v1/tool-box";
4506
4463
  var IMPEX = "/api/agent-operator-integration/v1/impex";
4507
4464
  async function exportConfig(ctx, id, type = "toolbox") {
4508
4465
  const res = await authFetch(
@@ -4542,7 +4499,7 @@ async function uploadTool(ctx, boxId, filePath, metadataType = "openapi") {
4542
4499
  form2.append("data", new Blob([new Uint8Array(buf)]), basename2(filePath));
4543
4500
  const res = await authFetch(
4544
4501
  ctx,
4545
- () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${PATH}/${encodeURIComponent(boxId)}/tool`, {
4502
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${PATH2}/${encodeURIComponent(boxId)}/tool`, {
4546
4503
  method: "POST",
4547
4504
  headers: buildHeaders(ctx),
4548
4505
  body: form2
@@ -4552,13 +4509,42 @@ async function uploadTool(ctx, boxId, filePath, metadataType = "openapi") {
4552
4509
  if (!res.ok) throw new HttpError(res.status, res.statusText, text);
4553
4510
  return text ? parseBigIntJSON(text) : text;
4554
4511
  }
4512
+ function toolBody(opts) {
4513
+ return {
4514
+ metadata_type: opts.metadataType,
4515
+ ...opts.function ? { function_input: functionInputBody(opts.function) } : {},
4516
+ ...opts.data !== void 0 ? { data: opts.data } : {},
4517
+ ...opts.useRule ? { use_rule: opts.useRule } : {}
4518
+ };
4519
+ }
4520
+ function createTool(ctx, boxId, opts) {
4521
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tool`, {
4522
+ method: "POST",
4523
+ body: toolBody(opts)
4524
+ });
4525
+ }
4526
+ function getTool(ctx, boxId, toolId) {
4527
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tool/${encodeURIComponent(toolId)}`);
4528
+ }
4529
+ function updateTool(ctx, boxId, toolId, opts) {
4530
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tool/${encodeURIComponent(toolId)}`, {
4531
+ method: "POST",
4532
+ body: { name: opts.name, description: opts.description, ...toolBody(opts) }
4533
+ });
4534
+ }
4535
+ function deleteTools(ctx, boxId, toolIds) {
4536
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tools/batch-delete`, {
4537
+ method: "POST",
4538
+ body: { tool_ids: toolIds }
4539
+ });
4540
+ }
4555
4541
  function listToolboxes(ctx, opts = {}) {
4556
- return request(ctx, `${PATH}/list`, {
4542
+ return request(ctx, `${PATH2}/list`, {
4557
4543
  query: { keyword: opts.keyword || void 0, limit: opts.limit, offset: opts.offset ?? 0 }
4558
4544
  });
4559
4545
  }
4560
4546
  function listTools2(ctx, boxId, opts = {}) {
4561
- return request(ctx, `${PATH}/${encodeURIComponent(boxId)}/tools/list`, {
4547
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tools/list`, {
4562
4548
  query: {
4563
4549
  page: opts.page,
4564
4550
  page_size: Number.isFinite(opts.pageSize) && opts.pageSize > 0 ? opts.pageSize : void 0,
@@ -4567,22 +4553,22 @@ function listTools2(ctx, boxId, opts = {}) {
4567
4553
  });
4568
4554
  }
4569
4555
  function createToolbox(ctx, opts) {
4570
- return request(ctx, PATH, {
4556
+ return request(ctx, PATH2, {
4571
4557
  method: "POST",
4572
4558
  body: {
4573
- metadata_type: "openapi",
4559
+ metadata_type: opts.metadataType ?? "openapi",
4574
4560
  box_name: opts.name,
4575
4561
  box_desc: opts.description ?? "",
4576
- box_svc_url: opts.serviceUrl,
4562
+ ...opts.serviceUrl ? { box_svc_url: opts.serviceUrl } : {},
4577
4563
  source: opts.source ?? "custom"
4578
4564
  }
4579
4565
  });
4580
4566
  }
4581
4567
  function deleteToolbox(ctx, boxId) {
4582
- return request(ctx, `${PATH}/${encodeURIComponent(boxId)}`, { method: "DELETE" });
4568
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}`, { method: "DELETE" });
4583
4569
  }
4584
4570
  function setToolboxStatus(ctx, boxId, status2) {
4585
- return request(ctx, `${PATH}/${encodeURIComponent(boxId)}/status`, {
4571
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/status`, {
4586
4572
  method: "POST",
4587
4573
  body: { status: status2 }
4588
4574
  });
@@ -4597,7 +4583,7 @@ function envelope(e) {
4597
4583
  };
4598
4584
  }
4599
4585
  function executeTool(ctx, boxId, toolId, e = {}) {
4600
- return request(ctx, `${PATH}/${encodeURIComponent(boxId)}/proxy/${encodeURIComponent(toolId)}`, {
4586
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/proxy/${encodeURIComponent(toolId)}`, {
4601
4587
  method: "POST",
4602
4588
  body: envelope(e)
4603
4589
  });
@@ -4605,7 +4591,7 @@ function executeTool(ctx, boxId, toolId, e = {}) {
4605
4591
  function debugTool(ctx, boxId, toolId, e = {}) {
4606
4592
  return request(
4607
4593
  ctx,
4608
- `${PATH}/${encodeURIComponent(boxId)}/tool/${encodeURIComponent(toolId)}/debug`,
4594
+ `${PATH2}/${encodeURIComponent(boxId)}/tool/${encodeURIComponent(toolId)}/debug`,
4609
4595
  {
4610
4596
  method: "POST",
4611
4597
  body: envelope(e)
@@ -4613,7 +4599,7 @@ function debugTool(ctx, boxId, toolId, e = {}) {
4613
4599
  );
4614
4600
  }
4615
4601
  function setToolStatuses(ctx, boxId, updates) {
4616
- return request(ctx, `${PATH}/${encodeURIComponent(boxId)}/tools/status`, {
4602
+ return request(ctx, `${PATH2}/${encodeURIComponent(boxId)}/tools/status`, {
4617
4603
  method: "POST",
4618
4604
  body: updates.map((u) => ({ tool_id: u.toolId, status: u.status }))
4619
4605
  });
@@ -4634,6 +4620,10 @@ function toolboxes(ctx) {
4634
4620
  toolIds.map((toolId) => ({ toolId, status: status2 }))
4635
4621
  ),
4636
4622
  upload: (boxId, filePath, metadataType) => uploadTool(ctx, boxId, filePath, metadataType),
4623
+ createTool: (boxId, opts) => createTool(ctx, boxId, opts),
4624
+ getTool: (boxId, toolId) => getTool(ctx, boxId, toolId),
4625
+ updateTool: (boxId, toolId, opts) => updateTool(ctx, boxId, toolId, opts),
4626
+ deleteTools: (boxId, toolIds) => deleteTools(ctx, boxId, toolIds),
4637
4627
  /** Export a toolbox config to a local `.adp` file. */
4638
4628
  export: async (id, outPath, type) => {
4639
4629
  const bytes = await exportConfig(ctx, id, type);
@@ -5851,132 +5841,6 @@ function buildCasesFromQueries(raw) {
5851
5841
  };
5852
5842
  });
5853
5843
  }
5854
- function applyOp(actual, op, expected) {
5855
- return op === "eq" ? actual === expected : op === "lt" ? actual < expected : op === "lte" ? actual <= expected : op === "gt" ? actual > expected : actual >= expected;
5856
- }
5857
- function toolName2(s) {
5858
- const v = s.attributes["gen_ai.tool.name"];
5859
- return typeof v === "string" ? v : s.name;
5860
- }
5861
- function orderedToolNames(spans) {
5862
- return spans.filter((s) => s.kind === "tool").slice().sort((a, b) => Number(BigInt(a.startTimeUnixNano) - BigInt(b.startTimeUnixNano))).map(toolName2);
5863
- }
5864
- function isSubsequence(seq, actual) {
5865
- let i = 0;
5866
- for (const n of actual) {
5867
- if (n === seq[i]) i++;
5868
- if (i === seq.length) return true;
5869
- }
5870
- return seq.length === 0;
5871
- }
5872
- async function evaluateAssertion(a, ctx) {
5873
- const r = a;
5874
- switch (a.type) {
5875
- case "contains": {
5876
- const v = String(r.value ?? "");
5877
- return ctx.answer.includes(v) ? { type: a.type, verdict: "pass" } : { type: a.type, verdict: "fail", actual: ctx.answer };
5878
- }
5879
- case "not_contains": {
5880
- const v = String(r.value ?? "");
5881
- return ctx.answer.includes(v) ? { type: a.type, verdict: "fail", actual: ctx.answer } : { type: a.type, verdict: "pass" };
5882
- }
5883
- case "regex": {
5884
- let re;
5885
- try {
5886
- re = new RegExp(String(r.pattern ?? ""));
5887
- } catch {
5888
- return { type: a.type, verdict: "skip", reason: `invalid regex: ${r.pattern}` };
5889
- }
5890
- return re.test(ctx.answer) ? { type: a.type, verdict: "pass" } : { type: a.type, verdict: "fail", actual: ctx.answer };
5891
- }
5892
- case "tool_call_count": {
5893
- const count = ctx.spans.filter(
5894
- (s) => s.kind === "tool" && toolName2(s) === String(r.tool ?? "")
5895
- ).length;
5896
- return applyOp(count, r.op ?? "eq", Number(r.value ?? 0)) ? { type: a.type, verdict: "pass", actual: count } : { type: a.type, verdict: "fail", actual: count };
5897
- }
5898
- case "tool_call_order": {
5899
- const seq = Array.isArray(r.sequence) ? r.sequence.map(String) : [];
5900
- const actual = orderedToolNames(ctx.spans);
5901
- return isSubsequence(seq, actual) ? { type: a.type, verdict: "pass", actual } : { type: a.type, verdict: "fail", actual };
5902
- }
5903
- case "latency_ms": {
5904
- if (ctx.durationMs == null)
5905
- return { type: a.type, verdict: "skip", reason: "durationMs unavailable" };
5906
- return applyOp(ctx.durationMs, r.op ?? "lte", Number(r.value ?? 0)) ? { type: a.type, verdict: "pass", actual: ctx.durationMs } : { type: a.type, verdict: "fail", actual: ctx.durationMs };
5907
- }
5908
- case "semantic_match": {
5909
- if (!ctx.judgeSemanticMatch)
5910
- return { type: a.type, verdict: "skip", reason: "no judge (pass --llm)" };
5911
- if (!ctx.reference?.answer)
5912
- return { type: a.type, verdict: "skip", reason: "no reference.answer on case" };
5913
- const smv = await ctx.judgeSemanticMatch(
5914
- String(r.question ?? ""),
5915
- ctx.answer,
5916
- ctx.reference.answer
5917
- );
5918
- return { type: a.type, verdict: smv.verdict, actual: smv.reasoning };
5919
- }
5920
- default:
5921
- return { type: a.type, verdict: "skip", reason: `unknown assertion type: ${a.type}` };
5922
- }
5923
- }
5924
- async function runEvalSet(agentId, cases, deps) {
5925
- const results = [];
5926
- for (const c of cases) {
5927
- const query = c.input.user_message;
5928
- let answer = "";
5929
- let conversationId = null;
5930
- let spans = [];
5931
- let errorCode;
5932
- let chatFailed = false;
5933
- try {
5934
- const run = await deps.runQuery(query);
5935
- answer = run.answer;
5936
- conversationId = run.conversationId;
5937
- if (conversationId) {
5938
- try {
5939
- spans = await deps.fetchSpans(conversationId);
5940
- } catch {
5941
- errorCode = "trace-fetch-failed";
5942
- }
5943
- }
5944
- } catch {
5945
- chatFailed = true;
5946
- errorCode = "chat-failed";
5947
- }
5948
- const assertionResults = [];
5949
- if (!chatFailed) {
5950
- for (const a of c.assertions ?? []) {
5951
- assertionResults.push(
5952
- await evaluateAssertion(a, {
5953
- answer,
5954
- spans,
5955
- reference: c.reference,
5956
- judgeSemanticMatch: deps.judgeSemanticMatch
5957
- })
5958
- );
5959
- }
5960
- }
5961
- results.push({
5962
- queryId: c.query_id,
5963
- query,
5964
- answer,
5965
- conversationId,
5966
- assertions: assertionResults,
5967
- ...errorCode ? { errorCode } : {}
5968
- });
5969
- }
5970
- const flat = results.flatMap((r) => r.assertions);
5971
- return {
5972
- agentId,
5973
- total: cases.length,
5974
- passed: flat.filter((a) => a.verdict === "pass").length,
5975
- failed: flat.filter((a) => a.verdict === "fail").length,
5976
- skipped: flat.filter((a) => a.verdict === "skip").length,
5977
- cases: results
5978
- };
5979
- }
5980
5844
 
5981
5845
  // src/bkn-trace/fixture-validate.ts
5982
5846
  import { readFileSync as readFileSync4, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
@@ -6720,20 +6584,6 @@ function validateFixturePath(path) {
6720
6584
  }
6721
6585
 
6722
6586
  // src/resources/trace.ts
6723
- async function semanticJudge(question, answer, reference) {
6724
- const prompt = [
6725
- "You judge whether an agent ANSWER semantically matches a REFERENCE answer.",
6726
- question ? `QUESTION/CRITERION: ${question}` : "",
6727
- `ANSWER: ${answer}`,
6728
- `REFERENCE: ${reference}`,
6729
- 'Respond with ONLY JSON: {"verdict":"pass|fail","reasoning":"<one sentence>"}'
6730
- ].filter(Boolean).join("\n");
6731
- const out = await judgeJson(prompt, { timeoutMs: 12e4 });
6732
- return {
6733
- verdict: out.verdict === "pass" ? "pass" : "fail",
6734
- reasoning: typeof out.reasoning === "string" ? out.reasoning : ""
6735
- };
6736
- }
6737
6587
  function trace(ctx) {
6738
6588
  const lifecycle = traceLifecycleApi(ctx);
6739
6589
  const managed = new ManagedTrace(lifecycle);
@@ -6824,30 +6674,7 @@ function trace(ctx) {
6824
6674
  /** Build eval cases from a loosely-shaped queries object/array. */
6825
6675
  evalSetBuild: (raw) => buildCasesFromQueries(raw),
6826
6676
  /** Validate BKN Trace phase-one fixture files or directories. */
6827
- validateFixture: (path) => validateFixturePath(path),
6828
- /**
6829
- * Run an eval set against an agent: each case's query is sent to the agent,
6830
- * the resulting trace is fetched, and assertions are checked. `llm` enables
6831
- * `semantic_match` assertions via the local claude judge.
6832
- */
6833
- evalSetTest: async (agentId, cases, opts = {}) => {
6834
- const info = await fetchAgentInfo(ctx, agentId, opts.version ?? "v0");
6835
- return runEvalSet(agentId, cases, {
6836
- runQuery: async (query) => {
6837
- const res = await sendChat(ctx, info, query, {});
6838
- return { answer: res.text, conversationId: res.conversationId ?? null };
6839
- },
6840
- fetchSpans: async (conversationId) => {
6841
- const { spans, traceIds } = await getRawSpansByConversation(ctx, conversationId);
6842
- const primary = traceIds[0] ?? conversationId;
6843
- return assembleTraceTree(
6844
- primary,
6845
- traceIds.length > 0 ? spans.filter((s) => !s.traceId || s.traceId === primary) : spans
6846
- ).spans;
6847
- },
6848
- judgeSemanticMatch: opts.llm && claudeAvailable() ? semanticJudge : void 0
6849
- });
6850
- }
6677
+ validateFixture: (path) => validateFixturePath(path)
6851
6678
  };
6852
6679
  }
6853
6680
  function isRuleApplicable(ruleId, spans) {
@@ -6878,7 +6705,7 @@ function isRuleApplicable(ruleId, spans) {
6878
6705
 
6879
6706
  // src/api/vega-semantic.ts
6880
6707
  import { z as z4 } from "zod";
6881
- var BASE5 = "/api/vega-backend/v1/semantic-understanding-tasks";
6708
+ var BASE4 = "/api/vega-backend/v1/semantic-understanding-tasks";
6882
6709
  var SemanticUnderstandingScope = z4.enum(["resource", "catalog"]);
6883
6710
  var SemanticUnderstandingApplyMode = z4.enum(["dry_run", "fill_empty", "force"]);
6884
6711
  var SemanticUnderstandingTaskSort = z4.enum(["create_time", "start_time", "finish_time"]);
@@ -6927,7 +6754,7 @@ async function createSemanticUnderstandingTask(ctx, req) {
6927
6754
  }
6928
6755
  } : {}
6929
6756
  };
6930
- const result = await request(ctx, BASE5, {
6757
+ const result = await request(ctx, BASE4, {
6931
6758
  method: "POST",
6932
6759
  body: {
6933
6760
  scope: req.scope,
@@ -6939,7 +6766,7 @@ async function createSemanticUnderstandingTask(ctx, req) {
6939
6766
  return SemanticUnderstandingTask.parse(result);
6940
6767
  }
6941
6768
  async function listSemanticUnderstandingTasks(ctx, opts = {}) {
6942
- const result = await request(ctx, BASE5, {
6769
+ const result = await request(ctx, BASE4, {
6943
6770
  query: {
6944
6771
  scope: opts.scope,
6945
6772
  catalog_id: opts.catalogId || void 0,
@@ -6956,12 +6783,12 @@ async function listSemanticUnderstandingTasks(ctx, opts = {}) {
6956
6783
  return ListSemanticUnderstandingTasksResponse.parse(result);
6957
6784
  }
6958
6785
  async function getSemanticUnderstandingTask(ctx, id) {
6959
- const result = await request(ctx, `${BASE5}/${encodeURIComponent(id)}`);
6786
+ const result = await request(ctx, `${BASE4}/${encodeURIComponent(id)}`);
6960
6787
  return SemanticUnderstandingTask.parse(result);
6961
6788
  }
6962
6789
  function deleteSemanticUnderstandingTasks(ctx, ids, opts = {}) {
6963
6790
  const values = Array.isArray(ids) ? ids : [ids];
6964
- return request(ctx, `${BASE5}/${values.map(encodeURIComponent).join(",")}`, {
6791
+ return request(ctx, `${BASE4}/${values.map(encodeURIComponent).join(",")}`, {
6965
6792
  method: "DELETE",
6966
6793
  query: {
6967
6794
  ignore_missing: opts.ignoreMissing === void 0 ? void 0 : String(opts.ignoreMissing)
@@ -6992,6 +6819,7 @@ function vega(ctx) {
6992
6819
  catalogHealthCheckSchedule: (id) => getCatalogHealthCheckSchedule(ctx, id),
6993
6820
  updateCatalogHealthCheckSchedule: (id, req) => updateCatalogHealthCheckSchedule(ctx, id, req),
6994
6821
  discoverCatalog: (catalogId, req) => discoverCatalog(ctx, catalogId, req),
6822
+ discoverResource: (resourceId) => discoverResource(ctx, resourceId),
6995
6823
  catalogResources: (id, category, limit, offset) => listCatalogResources(ctx, id, category, limit, offset),
6996
6824
  catalogHealth: (id) => catalogHealthStatus(ctx, id),
6997
6825
  connectorTypes: () => listConnectorTypes(ctx),
@@ -7153,9 +6981,9 @@ function createClient(opts = {}) {
7153
6981
  ctx,
7154
6982
  kn: kn(ctx),
7155
6983
  resource: resources(ctx),
7156
- agents: agents2(ctx),
7157
6984
  context: context(ctx),
7158
6985
  models: models(ctx),
6986
+ functions: functions(ctx),
7159
6987
  skills: skills(ctx),
7160
6988
  toolboxes: toolboxes(ctx),
7161
6989
  trace: trace(ctx),
@@ -7192,7 +7020,7 @@ function hostOf(baseUrl) {
7192
7020
  }
7193
7021
  }
7194
7022
  function normalize2(baseUrl) {
7195
- return baseUrl.replace(/\/+$/, "");
7023
+ return trimTrailingSlashes(baseUrl);
7196
7024
  }
7197
7025
  function usernameOf(token) {
7198
7026
  if (!token) return void 0;
@@ -7255,7 +7083,7 @@ async function currentTokenFresh(opts = {}) {
7255
7083
  const claims = decodeJwt(token.accessToken);
7256
7084
  const decodable = claims?.exp !== void 0;
7257
7085
  const needsRefresh = decodable ? isExpired(claims) : true;
7258
- if (token.refreshToken && needsRefresh) {
7086
+ if (token.refreshToken && needsRefresh && !isDryRun()) {
7259
7087
  try {
7260
7088
  const t = await refreshAccessToken(baseUrl, token.refreshToken, void 0, opts.insecure);
7261
7089
  writeToken(
@@ -7345,6 +7173,9 @@ function exportCreds() {
7345
7173
  }
7346
7174
 
7347
7175
  export {
7176
+ enableDryRun,
7177
+ DryRunSignal,
7178
+ trimTrailingSlashes,
7348
7179
  HttpError,
7349
7180
  NonJsonResponseError,
7350
7181
  ToolError,
@@ -7372,9 +7203,10 @@ export {
7372
7203
  getUserSafe,
7373
7204
  changePasswordSafe,
7374
7205
  admin,
7375
- agents2 as agents,
7376
7206
  releaseLifecycleSessions,
7377
7207
  context,
7208
+ functions,
7209
+ BuildTaskExecuteType,
7378
7210
  BuildTaskStatus,
7379
7211
  BuildTaskSort,
7380
7212
  SortDirection,
@@ -7416,4 +7248,4 @@ export {
7416
7248
  exportCreds,
7417
7249
  auth_exports
7418
7250
  };
7419
- //# sourceMappingURL=chunk-Z2NRTUB3.js.map
7251
+ //# sourceMappingURL=chunk-WIYRGBAB.js.map