tnega 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +115 -100
  2. package/dist/agent.js +2510 -134
  3. package/dist/agent.js.map +4 -4
  4. package/dist/bin.js +30723 -5163
  5. package/dist/bin.js.map +4 -4
  6. package/dist/cli-runtime.js +30690 -5094
  7. package/dist/cli-runtime.js.map +4 -4
  8. package/dist/coding-agent.js +19088 -0
  9. package/dist/coding-agent.js.map +7 -0
  10. package/dist/core.js +74 -1
  11. package/dist/core.js.map +4 -4
  12. package/dist/eval.js +23159 -1990
  13. package/dist/eval.js.map +4 -4
  14. package/dist/events.js +22 -1
  15. package/dist/events.js.map +2 -2
  16. package/dist/evolve.js +17631 -1815
  17. package/dist/evolve.js.map +4 -4
  18. package/dist/index.js +31848 -6076
  19. package/dist/index.js.map +4 -4
  20. package/dist/llm.js +8 -0
  21. package/dist/llm.js.map +2 -2
  22. package/dist/services.js +12 -1
  23. package/dist/services.js.map +2 -2
  24. package/dist/session.js +793 -122
  25. package/dist/session.js.map +4 -4
  26. package/dist/tools.js +242 -135
  27. package/dist/tools.js.map +4 -4
  28. package/dist/types/packages/agent/src/inbox-durable.d.ts +54 -0
  29. package/dist/types/packages/agent/src/index.d.ts +4 -0
  30. package/dist/types/packages/agent/src/live.d.ts +115 -0
  31. package/dist/types/packages/agent/src/llm-service.d.ts +32 -0
  32. package/dist/types/packages/agent/src/prompt.d.ts +55 -0
  33. package/dist/types/packages/agent/src/service.d.ts +24 -0
  34. package/dist/types/packages/agent/src/types.d.ts +75 -1
  35. package/dist/types/packages/benchmark/src/bigcodebench.d.ts +6 -0
  36. package/dist/types/packages/benchmark/src/humaneval.d.ts +11 -0
  37. package/dist/types/packages/benchmark/src/index.d.ts +9 -0
  38. package/dist/types/packages/benchmark/src/manifest.d.ts +10 -0
  39. package/dist/types/packages/benchmark/src/mbpp.d.ts +10 -0
  40. package/dist/types/packages/benchmark/src/parquet.d.ts +2 -0
  41. package/dist/types/packages/benchmark/src/stdlib.d.ts +3 -0
  42. package/dist/types/packages/benchmark/src/swebench.d.ts +2 -0
  43. package/dist/types/packages/benchmark/src/types.d.ts +58 -0
  44. package/dist/types/packages/cli/src/commands.d.ts +26 -2
  45. package/dist/types/packages/cli/src/config.d.ts +2 -0
  46. package/dist/types/packages/cli/src/index.d.ts +4 -2
  47. package/dist/types/packages/cli/src/profile-file.d.ts +26 -0
  48. package/dist/types/packages/cli/src/profile.d.ts +9 -0
  49. package/dist/types/packages/cli/src/server.d.ts +2 -0
  50. package/dist/types/packages/cli/src/store.d.ts +10 -9
  51. package/dist/types/packages/coding-agent/src/codingAgent.d.ts +25 -0
  52. package/dist/types/packages/coding-agent/src/index.d.ts +6 -0
  53. package/dist/types/packages/coding-agent/src/mcp.d.ts +24 -0
  54. package/dist/types/packages/coding-agent/src/plan.d.ts +13 -0
  55. package/dist/types/packages/coding-agent/src/skills.d.ts +12 -0
  56. package/dist/types/packages/coding-agent/src/slash.d.ts +28 -0
  57. package/dist/types/packages/coding-agent/src/types.d.ts +41 -0
  58. package/dist/types/packages/core/src/events.d.ts +4 -1
  59. package/dist/types/packages/core/src/index.d.ts +1 -0
  60. package/dist/types/packages/core/src/invariant.d.ts +45 -0
  61. package/dist/types/packages/eval/src/codingRuntime.d.ts +18 -0
  62. package/dist/types/packages/eval/src/policy.d.ts +8 -0
  63. package/dist/types/packages/eval/src/runner.d.ts +4 -0
  64. package/dist/types/packages/eval/src/strategies.d.ts +10 -0
  65. package/dist/types/packages/eval/src/trace.d.ts +7 -0
  66. package/dist/types/packages/eval/src/types.d.ts +97 -1
  67. package/dist/types/packages/eval/src/workspace.d.ts +17 -0
  68. package/dist/types/packages/llm/src/types.d.ts +2 -0
  69. package/dist/types/packages/session/src/index.d.ts +397 -12
  70. package/dist/types/packages/session/src/invariant.d.ts +33 -0
  71. package/dist/types/packages/tools/src/builtins.d.ts +2 -0
  72. package/dist/types/packages/tools/src/execution.d.ts +31 -0
  73. package/dist/types/packages/tools/src/index.d.ts +17 -0
  74. package/dist/types/src/index.d.ts +5 -5
  75. package/dist/web/assets/index-45pokiBH.js +270 -0
  76. package/dist/web/assets/index-DCLL69Kz.css +1 -0
  77. package/dist/web/index.html +2 -2
  78. package/package.json +92 -88
  79. package/dist/web/assets/index-C3jFlR4V.css +0 -1
  80. package/dist/web/assets/index-DeFGh2h4.js +0 -268
package/dist/tools.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { createRequire as __tnegaCreateRequire } from 'node:module'; const require = __tnegaCreateRequire(import.meta.url);
2
+
1
3
  // packages/core/src/utils.ts
2
4
  var DisposableList = class {
3
5
  sn = 0;
@@ -308,6 +310,16 @@ var EventsService = class {
308
310
  args.push(next);
309
311
  return next();
310
312
  }
313
+ async waterfallAsync(...args) {
314
+ const [thisArg, callbacks] = this._resolve("waterfallAsync", args);
315
+ const inner = args.pop();
316
+ const next = async () => {
317
+ const callback = callbacks.shift();
318
+ return callback ? await Reflect.apply(callback, thisArg, args) : inner(...args);
319
+ };
320
+ args.push(next);
321
+ return next();
322
+ }
311
323
  register(label, hooks, callback, options) {
312
324
  const method = options.prepend ? "unshift" : "push";
313
325
  return this.ctx.fiber.effect(() => {
@@ -837,7 +849,16 @@ var ReflectService = class {
837
849
  this.mixin("reflect", ["get", "set", "provide", "accessor", "mixin"]);
838
850
  this.mixin("fiber", ["runtime", "effect"]);
839
851
  this.mixin("registry", ["inject", "plugin"]);
840
- this.mixin("events", ["on", "once", "parallel", "emit", "serial", "bail", "waterfall"]);
852
+ this.mixin("events", [
853
+ "on",
854
+ "once",
855
+ "parallel",
856
+ "emit",
857
+ "serial",
858
+ "bail",
859
+ "waterfall",
860
+ "waterfallAsync"
861
+ ]);
841
862
  }
842
863
  ctx;
843
864
  static handler = {
@@ -1255,7 +1276,6 @@ var Service = class _Service {
1255
1276
  };
1256
1277
 
1257
1278
  // packages/tools/src/builtins.ts
1258
- import { spawn } from "node:child_process";
1259
1279
  import {
1260
1280
  appendFile,
1261
1281
  mkdir,
@@ -1498,6 +1518,116 @@ function evaluateExpression(source) {
1498
1518
  return value;
1499
1519
  }
1500
1520
 
1521
+ // packages/tools/src/execution.ts
1522
+ import { spawn } from "node:child_process";
1523
+ function errorMessage(error) {
1524
+ if (error instanceof Error) return error.message;
1525
+ return String(error);
1526
+ }
1527
+ async function killProcessTree(child) {
1528
+ if (child.pid === void 0) return;
1529
+ if (process.platform === "win32") {
1530
+ await new Promise((resolve2) => {
1531
+ const killer = spawn("taskkill", ["/pid", String(child.pid), "/t", "/f"], {
1532
+ stdio: "ignore",
1533
+ windowsHide: true
1534
+ });
1535
+ killer.on("error", () => resolve2());
1536
+ killer.on("exit", () => resolve2());
1537
+ });
1538
+ } else {
1539
+ try {
1540
+ process.kill(-child.pid, "SIGKILL");
1541
+ } catch {
1542
+ }
1543
+ child.kill("SIGKILL");
1544
+ }
1545
+ }
1546
+ function runLocalShell(request) {
1547
+ const timeoutMs = request.timeoutMs ?? 15e3;
1548
+ const maxBuffer = request.maxBuffer ?? 1024 * 1024;
1549
+ return new Promise((resolve2, reject) => {
1550
+ const child = spawn(request.command, {
1551
+ cwd: request.cwd,
1552
+ shell: true,
1553
+ windowsHide: true,
1554
+ ...process.platform === "win32" ? {} : { detached: true }
1555
+ });
1556
+ let stdout = "";
1557
+ let stderr = "";
1558
+ let settled = false;
1559
+ let timer;
1560
+ let onAbort = () => {
1561
+ };
1562
+ const append = (target, chunk, limit) => {
1563
+ if (target.length >= limit) return target;
1564
+ return target + chunk.toString("utf8").slice(0, limit - target.length);
1565
+ };
1566
+ const cleanup = () => {
1567
+ if (timer) clearTimeout(timer);
1568
+ request.signal?.removeEventListener("abort", onAbort);
1569
+ };
1570
+ const finish = (action) => {
1571
+ if (settled) return;
1572
+ settled = true;
1573
+ cleanup();
1574
+ action();
1575
+ };
1576
+ const fail2 = (message2) => {
1577
+ finish(() => {
1578
+ void killProcessTree(child).finally(() => reject(new Error(message2)));
1579
+ });
1580
+ };
1581
+ onAbort = () => fail2("shell command cancelled");
1582
+ if (request.signal) {
1583
+ if (request.signal.aborted) onAbort();
1584
+ else request.signal.addEventListener("abort", onAbort, { once: true });
1585
+ }
1586
+ if (timeoutMs > 0) {
1587
+ timer = setTimeout(() => fail2(`shell command timed out after ${timeoutMs}ms`), timeoutMs);
1588
+ }
1589
+ child.stdout.on("data", (chunk) => {
1590
+ stdout = append(stdout, chunk, maxBuffer);
1591
+ });
1592
+ child.stderr.on("data", (chunk) => {
1593
+ stderr = append(stderr, chunk, maxBuffer);
1594
+ });
1595
+ child.on("error", (error) => {
1596
+ finish(() => resolve2({ exitCode: 1, stdout, stderr: errorMessage(error) }));
1597
+ });
1598
+ child.on("close", (code, closeSignal) => {
1599
+ finish(() => resolve2({
1600
+ exitCode: code ?? 1,
1601
+ stdout,
1602
+ stderr: closeSignal ? `killed by ${closeSignal}` : stderr
1603
+ }));
1604
+ });
1605
+ });
1606
+ }
1607
+ var localExecutionProvider = {
1608
+ runShell: runLocalShell,
1609
+ async fetchHttp(request) {
1610
+ const init = {};
1611
+ if (request.headers) init.headers = request.headers;
1612
+ if (request.signal) init.signal = request.signal;
1613
+ const response = await fetch(request.url, init);
1614
+ const buffer = Buffer.from(await response.arrayBuffer());
1615
+ const maxBytes = request.maxBytes ?? 256 * 1024;
1616
+ const truncated = buffer.byteLength > maxBytes;
1617
+ const headers = {};
1618
+ response.headers.forEach((value, key) => {
1619
+ headers[key] = value;
1620
+ });
1621
+ return {
1622
+ status: response.status,
1623
+ ok: response.ok,
1624
+ headers,
1625
+ body: buffer.subarray(0, maxBytes).toString("utf8"),
1626
+ truncated
1627
+ };
1628
+ }
1629
+ };
1630
+
1501
1631
  // packages/tools/src/path.ts
1502
1632
  import { realpath } from "node:fs/promises";
1503
1633
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
@@ -1570,7 +1700,8 @@ function normalizeConfig(config = {}) {
1570
1700
  maxWriteBytes: config.maxWriteBytes ?? 1024 * 1024,
1571
1701
  maxSearchBytes: config.maxSearchBytes ?? 1024 * 1024,
1572
1702
  maxResults: config.maxResults ?? 200,
1573
- timeoutMs: config.timeoutMs ?? 15e3
1703
+ timeoutMs: config.timeoutMs ?? 15e3,
1704
+ execution: config.execution ?? localExecutionProvider
1574
1705
  };
1575
1706
  }
1576
1707
  function definition(name2, description, execute, parameters) {
@@ -2038,22 +2169,12 @@ function httpGetTool(config) {
2038
2169
  }
2039
2170
  const headers = optionalRecord(args.headers, "headers") ?? {};
2040
2171
  const maxBytes = optionalNumber(args.maxBytes, "maxBytes") ?? config.maxReadBytes;
2041
- const init = { headers };
2042
- if (options.signal) init.signal = options.signal;
2043
- const response = await fetch(url, init);
2044
- const buffer = Buffer.from(await response.arrayBuffer());
2045
- const truncated = buffer.byteLength > maxBytes;
2046
- const headerMap = {};
2047
- response.headers.forEach((value, key) => {
2048
- headerMap[key] = value;
2172
+ return config.execution.fetchHttp({
2173
+ url: url.href,
2174
+ ...Object.keys(headers).length ? { headers } : {},
2175
+ ...maxBytes !== config.maxReadBytes ? { maxBytes } : {},
2176
+ ...options.signal ? { signal: options.signal } : {}
2049
2177
  });
2050
- return {
2051
- status: response.status,
2052
- ok: response.ok,
2053
- headers: headerMap,
2054
- body: buffer.subarray(0, maxBytes).toString("utf8"),
2055
- truncated
2056
- };
2057
2178
  },
2058
2179
  {
2059
2180
  type: "object",
@@ -2078,13 +2199,13 @@ function shellTool(config) {
2078
2199
  const command = stringField(args.command, "command");
2079
2200
  const cwd = await resolveInside(config.cwd, optionalString(args.cwd, "cwd") ?? ".");
2080
2201
  const timeoutMs = optionalNumber(args.timeoutMs, "timeoutMs") ?? config.timeoutMs;
2081
- const result = await runShellCommand(
2202
+ const result = await config.execution.runShell({
2082
2203
  command,
2083
2204
  cwd,
2084
2205
  timeoutMs,
2085
- config.maxWriteBytes,
2086
- options.signal
2087
- );
2206
+ maxBuffer: config.maxWriteBytes,
2207
+ ...options.signal ? { signal: options.signal } : {}
2208
+ });
2088
2209
  return {
2089
2210
  exitCode: result.exitCode,
2090
2211
  stdout: result.stdout,
@@ -2102,84 +2223,6 @@ function shellTool(config) {
2102
2223
  }
2103
2224
  );
2104
2225
  }
2105
- async function killProcessTree(child) {
2106
- if (child.pid === void 0) return;
2107
- if (process.platform === "win32") {
2108
- await new Promise((resolve2) => {
2109
- const killer = spawn("taskkill", ["/pid", String(child.pid), "/t", "/f"], {
2110
- stdio: "ignore",
2111
- windowsHide: true
2112
- });
2113
- killer.on("error", () => resolve2());
2114
- killer.on("exit", () => resolve2());
2115
- });
2116
- } else {
2117
- try {
2118
- process.kill(-child.pid, "SIGKILL");
2119
- } catch {
2120
- }
2121
- child.kill("SIGKILL");
2122
- }
2123
- }
2124
- function runShellCommand(command, cwd, timeoutMs, maxBuffer, signal) {
2125
- return new Promise((resolve2, reject) => {
2126
- const child = spawn(command, {
2127
- cwd,
2128
- shell: true,
2129
- windowsHide: true,
2130
- ...process.platform === "win32" ? {} : { detached: true }
2131
- });
2132
- let stdout = "";
2133
- let stderr = "";
2134
- let settled = false;
2135
- let timer;
2136
- let onAbort = () => {
2137
- };
2138
- const append = (target, chunk, limit) => {
2139
- if (target.length >= limit) return target;
2140
- return target + chunk.toString("utf8").slice(0, limit - target.length);
2141
- };
2142
- const cleanup = () => {
2143
- if (timer) clearTimeout(timer);
2144
- signal?.removeEventListener("abort", onAbort);
2145
- };
2146
- const finish = (action) => {
2147
- if (settled) return;
2148
- settled = true;
2149
- cleanup();
2150
- action();
2151
- };
2152
- const fail2 = (message2) => {
2153
- finish(() => {
2154
- void killProcessTree(child).finally(() => reject(new Error(message2)));
2155
- });
2156
- };
2157
- onAbort = () => fail2("shell command cancelled");
2158
- if (signal) {
2159
- if (signal.aborted) onAbort();
2160
- else signal.addEventListener("abort", onAbort, { once: true });
2161
- }
2162
- if (timeoutMs > 0) {
2163
- timer = setTimeout(() => fail2(`shell command timed out after ${timeoutMs}ms`), timeoutMs);
2164
- }
2165
- child.stdout.on("data", (chunk) => {
2166
- stdout = append(stdout, chunk, maxBuffer);
2167
- });
2168
- child.stderr.on("data", (chunk) => {
2169
- stderr = append(stderr, chunk, maxBuffer);
2170
- });
2171
- child.on("error", (error) => {
2172
- finish(() => resolve2({ exitCode: 1, stdout, stderr: message(error) }));
2173
- });
2174
- child.on("close", (code, closeSignal) => {
2175
- finish(() => resolve2({
2176
- exitCode: code ?? 1,
2177
- stdout,
2178
- stderr: closeSignal ? `killed by ${closeSignal}` : stderr
2179
- }));
2180
- });
2181
- });
2182
- }
2183
2226
  function createBuiltinToolDefinitions(config = {}) {
2184
2227
  const normalized = normalizeConfig(config);
2185
2228
  const disabled = new Set(normalized.disabled);
@@ -2320,6 +2363,7 @@ function toToolError(error) {
2320
2363
  var ToolsService = class extends Service {
2321
2364
  static provide = "tools";
2322
2365
  _tools = /* @__PURE__ */ new Map();
2366
+ _guards = /* @__PURE__ */ new Set();
2323
2367
  _policy;
2324
2368
  constructor(ctx, config = {}) {
2325
2369
  super(ctx, "tools");
@@ -2337,13 +2381,27 @@ var ToolsService = class extends Service {
2337
2381
  throw new ToolAlreadyRegisteredError(name2);
2338
2382
  }
2339
2383
  this._tools.set(name2, definition2);
2384
+ this.ctx.emit("tools/change");
2340
2385
  return () => {
2341
2386
  this._tools.delete(name2);
2387
+ this.ctx.emit("tools/change");
2342
2388
  };
2343
2389
  }, `ctx.tools.register(${JSON.stringify(name2)})`);
2344
2390
  }
2345
2391
  unregister(name2) {
2346
- return this._tools.delete(name2);
2392
+ const removed = this._tools.delete(name2);
2393
+ if (removed) this.ctx.emit("tools/change");
2394
+ return removed;
2395
+ }
2396
+ /** Register a monotonic guard evaluated after pre-execute policy. */
2397
+ guard(guard) {
2398
+ if (typeof guard !== "function") throw new TypeError("tool guard must be a function");
2399
+ return this.ctx.fiber.effect(() => {
2400
+ this._guards.add(guard);
2401
+ return () => {
2402
+ this._guards.delete(guard);
2403
+ };
2404
+ }, "ctx.tools.guard()");
2347
2405
  }
2348
2406
  has(name2) {
2349
2407
  return this._tools.has(name2);
@@ -2357,58 +2415,99 @@ var ToolsService = class extends Service {
2357
2415
  async execute(name2, input, options = {}) {
2358
2416
  const tool = this._tools.get(name2);
2359
2417
  if (!tool) throw new ToolNotFoundError(name2);
2360
- const request = {
2418
+ let request = {
2361
2419
  tool,
2362
2420
  name: name2,
2363
2421
  input,
2364
2422
  options,
2365
2423
  startedAt: Date.now()
2366
2424
  };
2367
- await this.ctx.parallel("tools/pre-execute", request);
2368
- const policy = request.tool.policy;
2369
- const authorizer = policy?.authorizer ?? this._policy.authorizer;
2370
- if (authorizer) {
2371
- const allowed = await authorizer(request);
2372
- if (!allowed) {
2373
- return this._finish(
2374
- request,
2375
- this._failure(
2376
- request,
2377
- new ToolAuthorizationError(`tool authorization denied: ${name2}`)
2378
- )
2379
- );
2380
- }
2381
- }
2382
- const validator = policy?.validator ?? this._policy.validator;
2425
+ let preError;
2383
2426
  try {
2384
- await validator(request.input, request.tool);
2427
+ const resolved = await this.ctx.waterfallAsync(
2428
+ "tools/pre-execute",
2429
+ request,
2430
+ async (payload) => {
2431
+ await this._applyPolicy(payload);
2432
+ return payload;
2433
+ }
2434
+ );
2435
+ if (!resolved) {
2436
+ throw new ToolAuthorizationError(`tool rejected by tools/pre-execute: ${name2}`);
2437
+ }
2438
+ request = resolved;
2439
+ const denial = await this._checkGuards(request);
2440
+ if (denial) throw new ToolAuthorizationError(denial);
2385
2441
  } catch (error) {
2386
- return this._finish(request, this._failure(request, error));
2442
+ preError = error;
2387
2443
  }
2388
- let output;
2389
- let caught;
2444
+ let result;
2390
2445
  try {
2391
- await this.ctx.parallel("tools/execute", request);
2392
- output = await tool.execute(request.input, request.options);
2446
+ if (!preError) {
2447
+ result = await this.ctx.waterfallAsync(
2448
+ "tools/execute",
2449
+ request,
2450
+ async (payload) => {
2451
+ const output = await payload.tool.execute(payload.input, payload.options);
2452
+ return this._success(payload, output);
2453
+ }
2454
+ );
2455
+ }
2393
2456
  } catch (error) {
2394
- caught = error;
2457
+ result = this._failure(request, error);
2395
2458
  }
2396
- const result = caught === void 0 ? this._success(request, output) : this._failure(request, caught);
2397
- const truncator = policy?.truncator ?? this._policy.truncator;
2398
- if (truncator) {
2399
- try {
2400
- return this._finish(request, await truncator(result, request));
2401
- } catch (error) {
2402
- return this._finish(request, this._failure(request, error));
2403
- }
2459
+ if (preError) result = this._failure(request, preError);
2460
+ if (!result) {
2461
+ result = this._failure(
2462
+ request,
2463
+ new Error("tools/execute did not return a tool result")
2464
+ );
2404
2465
  }
2405
- return this._finish(request, result);
2466
+ try {
2467
+ const normalized = await this.ctx.waterfallAsync(
2468
+ "tools/post-execute",
2469
+ { request, result },
2470
+ async (payload) => {
2471
+ const policy = payload.request.tool.policy;
2472
+ const truncator = policy?.truncator ?? this._policy.truncator;
2473
+ return truncator ? await truncator(payload.result, payload.request) : payload.result;
2474
+ }
2475
+ );
2476
+ if (normalized && typeof normalized.ok === "boolean") result = normalized;
2477
+ } catch (error) {
2478
+ result = this._failure(request, error);
2479
+ }
2480
+ return this._finish(
2481
+ request,
2482
+ result ?? this._failure(
2483
+ request,
2484
+ new Error("tools/execute did not return a tool result")
2485
+ )
2486
+ );
2406
2487
  }
2407
2488
  async _finish(request, result) {
2408
- await this.ctx.parallel("tools/post-execute", { request, result });
2409
2489
  await this.ctx.parallel("tools/result", { request, result });
2410
2490
  return result;
2411
2491
  }
2492
+ async _applyPolicy(request) {
2493
+ const policy = request.tool.policy;
2494
+ const authorizer = policy?.authorizer ?? this._policy.authorizer;
2495
+ if (authorizer) {
2496
+ const allowed = await authorizer(request);
2497
+ if (!allowed) {
2498
+ throw new ToolAuthorizationError(`tool authorization denied: ${request.name}`);
2499
+ }
2500
+ }
2501
+ const validator = policy?.validator ?? this._policy.validator;
2502
+ if (validator) await validator(request.input, request.tool);
2503
+ }
2504
+ async _checkGuards(request) {
2505
+ for (const guard of this._guards) {
2506
+ const denial = await guard(request);
2507
+ if (denial) return denial;
2508
+ }
2509
+ return void 0;
2510
+ }
2412
2511
  _validate(definition2) {
2413
2512
  if (!definition2 || typeof definition2.schema?.name !== "string" || !definition2.schema.name) {
2414
2513
  throw new TypeError("tool definition requires a non-empty schema.name");
@@ -2427,6 +2526,7 @@ var ToolsService = class extends Service {
2427
2526
  durationMs: Date.now() - request.startedAt
2428
2527
  };
2429
2528
  if (request.options.callId) result.callId = request.options.callId;
2529
+ this._applyConcludesTurn(request, result);
2430
2530
  return result;
2431
2531
  }
2432
2532
  _failure(request, error) {
@@ -2441,6 +2541,12 @@ var ToolsService = class extends Service {
2441
2541
  if (request.options.callId) result.callId = request.options.callId;
2442
2542
  return result;
2443
2543
  }
2544
+ _applyConcludesTurn(request, result) {
2545
+ const staticDeclares = request.tool.metadata?.concludesTurn;
2546
+ if (staticDeclares === true || request.options.concludesTurn === true) {
2547
+ result.concludesTurn = true;
2548
+ }
2549
+ }
2444
2550
  };
2445
2551
  var tools = {
2446
2552
  name: "tools",
@@ -2461,6 +2567,7 @@ export {
2461
2567
  builtinTools,
2462
2568
  createBuiltinToolDefinitions,
2463
2569
  evaluateExpression,
2570
+ localExecutionProvider,
2464
2571
  name,
2465
2572
  resolveInside,
2466
2573
  tools,