@orkestrel/agent 0.0.8 → 0.0.10

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.
@@ -278,7 +278,7 @@ var WorkspaceError = class extends Error {
278
278
  super(message);
279
279
  this.name = "WorkspaceError";
280
280
  this.code = code;
281
- this.context = context;
281
+ if (context !== void 0) this.context = context;
282
282
  }
283
283
  };
284
284
  /**
@@ -398,8 +398,8 @@ var Conversation = class {
398
398
  constructor(options, seed) {
399
399
  this.#id = seed?.id ?? options?.id ?? crypto.randomUUID();
400
400
  this.#emitter = new _orkestrel_emitter.Emitter({
401
- on: options?.on,
402
- error: options?.error
401
+ ...options?.on === void 0 ? {} : { on: options.on },
402
+ ...options?.error === void 0 ? {} : { error: options.error }
403
403
  });
404
404
  this.#summarize = options?.summarize;
405
405
  this.#keep = options?.keep ?? 0;
@@ -609,10 +609,11 @@ var ConversationManager = class {
609
609
  }
610
610
  add(input) {
611
611
  const sections = input?.sections ?? this.#sections;
612
+ const summarize = input?.summarize ?? this.#summarize;
612
613
  const conversation = new Conversation({
613
614
  ...input?.id === void 0 ? {} : { id: input.id },
614
615
  ...input?.on === void 0 ? {} : { on: input.on },
615
- summarize: input?.summarize ?? this.#summarize,
616
+ ...summarize === void 0 ? {} : { summarize },
616
617
  keep: input?.keep ?? this.#keep,
617
618
  ...sections === void 0 ? {} : { sections }
618
619
  }, input?.snapshot);
@@ -818,6 +819,38 @@ async function settleAgentJob(agent, allowPartial) {
818
819
  return result;
819
820
  }
820
821
  /**
822
+ * Handle one queued agent job by rehydrating it through a registry with the queue
823
+ * attempt's signal, then applying the shared partial-result policy.
824
+ *
825
+ * @param registry - The registry that rehydrates the serializable job
826
+ * @param allowPartial - Whether a partial result resolves instead of throwing
827
+ * @param input - The serializable agent job
828
+ * @param execution - The queue attempt whose signal bounds the agent
829
+ * @returns The settled agent result
830
+ */
831
+ function handleAgentQueueJob(registry, allowPartial, input, execution) {
832
+ return settleAgentJob(registry.build(input, execution.signal), allowPartial);
833
+ }
834
+ /**
835
+ * Handle one runner agent job by fanning out its declared children, rehydrating the
836
+ * parent through a registry with the controller signal, and applying the shared
837
+ * partial-result policy.
838
+ *
839
+ * @remarks
840
+ * Children are fired and tracked through the runner controller without awaiting them
841
+ * inline, preserving bounded-runner progress.
842
+ *
843
+ * @param registry - The registry that rehydrates serializable jobs
844
+ * @param allowPartial - Whether a partial result resolves instead of throwing
845
+ * @param controller - The runner controller for this parent job
846
+ * @returns The settled parent agent result
847
+ */
848
+ function handleAgentRunnerJob(registry, allowPartial, controller) {
849
+ const children = controller.input.children;
850
+ if (children !== void 0) for (const child of children) controller.spawn(child);
851
+ return settleAgentJob(registry.build(controller.input, controller.signal), allowPartial);
852
+ }
853
+ /**
821
854
  * Whether a {@link FileContent} is the TEXT arm — the narrowing guard for the text-vs-binary
822
855
  * union (AGENTS §14: narrow an untyped arm via a guard, never an `as`).
823
856
  *
@@ -1415,6 +1448,15 @@ function escapeRegExp(value) {
1415
1448
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1416
1449
  }
1417
1450
  /**
1451
+ * Sanitize one reported token count into a safe non-negative integer.
1452
+ *
1453
+ * @param value - The token count to sanitize
1454
+ * @returns The floored count, or `0` when the value is non-finite or non-positive
1455
+ */
1456
+ function sanitizeToken(value) {
1457
+ return Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
1458
+ }
1459
+ /**
1418
1460
  * Sanitize a {@link TokenUsage} into safe, non-negative integers — the guard an agent's
1419
1461
  * abort-usage path applies to a provider's partial usage before it is charged against a
1420
1462
  * budget or folded into the run total.
@@ -1433,11 +1475,10 @@ function escapeRegExp(value) {
1433
1475
  * ```
1434
1476
  */
1435
1477
  function sanitizeUsage(usage) {
1436
- const clean = (value) => Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
1437
1478
  return {
1438
- prompt: clean(usage.prompt),
1439
- completion: clean(usage.completion),
1440
- total: clean(usage.total)
1479
+ prompt: sanitizeToken(usage.prompt),
1480
+ completion: sanitizeToken(usage.completion),
1481
+ total: sanitizeToken(usage.total)
1441
1482
  };
1442
1483
  }
1443
1484
  //#endregion
@@ -1521,8 +1562,8 @@ var InstructionManager = class {
1521
1562
  #format;
1522
1563
  constructor(options) {
1523
1564
  this.#emitter = new _orkestrel_emitter.Emitter({
1524
- on: options?.on,
1525
- error: options?.error
1565
+ ...options?.on === void 0 ? {} : { on: options.on },
1566
+ ...options?.error === void 0 ? {} : { error: options.error }
1526
1567
  });
1527
1568
  this.#format = options?.format;
1528
1569
  }
@@ -1724,8 +1765,8 @@ var Workspace = class {
1724
1765
  constructor(options, seed) {
1725
1766
  this.#id = options?.id ?? crypto.randomUUID();
1726
1767
  this.#emitter = new _orkestrel_emitter.Emitter({
1727
- on: options?.on,
1728
- error: options?.error
1768
+ ...options?.on === void 0 ? {} : { on: options.on },
1769
+ ...options?.error === void 0 ? {} : { error: options.error }
1729
1770
  });
1730
1771
  if (seed) for (const [path, file] of seed) this.#files.set(path, file);
1731
1772
  }
@@ -2018,10 +2059,12 @@ var WorkspaceManager = class {
2018
2059
  return [...this.#workspaces.values()];
2019
2060
  }
2020
2061
  add(input) {
2062
+ const on = input?.on ?? this.#on;
2063
+ const error = input?.error ?? this.#error;
2021
2064
  const workspace = new Workspace({
2022
2065
  ...input?.id === void 0 ? {} : { id: input.id },
2023
- on: input?.on ?? this.#on,
2024
- error: input?.error ?? this.#error
2066
+ ...on === void 0 ? {} : { on },
2067
+ ...error === void 0 ? {} : { error }
2025
2068
  }, input?.seed);
2026
2069
  this.#workspaces.set(workspace.id, workspace);
2027
2070
  if (this.#active === void 0) this.#active = workspace.id;
@@ -2373,12 +2416,12 @@ var Agent = class {
2373
2416
  constructor(provider, options) {
2374
2417
  this.#provider = provider;
2375
2418
  this.#context = new AgentContext({
2376
- system: options?.system,
2377
- tools: options?.tools,
2378
- instructions: options?.instructions,
2379
- workspaces: options?.workspaces,
2380
- scope: options?.scope,
2381
- conversations: options?.conversations
2419
+ ...options?.system === void 0 ? {} : { system: options.system },
2420
+ ...options?.tools === void 0 ? {} : { tools: options.tools },
2421
+ ...options?.instructions === void 0 ? {} : { instructions: options.instructions },
2422
+ ...options?.workspaces === void 0 ? {} : { workspaces: options.workspaces },
2423
+ ...options?.scope === void 0 ? {} : { scope: options.scope },
2424
+ ...options?.conversations === void 0 ? {} : { conversations: options.conversations }
2382
2425
  });
2383
2426
  this.#limit = options?.limit ?? 10;
2384
2427
  this.#timeoutMs = options?.timeout;
@@ -2389,8 +2432,8 @@ var Agent = class {
2389
2432
  this.#window = options?.window;
2390
2433
  this.#strict = options?.strict ?? false;
2391
2434
  this.#emitter = new _orkestrel_emitter.Emitter({
2392
- on: options?.on,
2393
- error: options?.error
2435
+ ...options?.on === void 0 ? {} : { on: options.on },
2436
+ ...options?.error === void 0 ? {} : { error: options.error }
2394
2437
  });
2395
2438
  }
2396
2439
  get emitter() {
@@ -2413,42 +2456,42 @@ var Agent = class {
2413
2456
  const budget = options?.budget ?? this.#budget;
2414
2457
  budget?.start();
2415
2458
  const limit = options?.limit ?? this.#limit;
2416
- const abort = (0, _orkestrel_abort.createAbort)({ signal: this.#parents(timeout, budget, options?.signal) });
2459
+ const signal = this.#parents(timeout, budget, options?.signal);
2460
+ const abort = (0, _orkestrel_abort.createAbort)(signal === void 0 ? {} : { signal });
2417
2461
  this.#runs.add(abort);
2418
2462
  this.#status = "running";
2419
2463
  this.#emitter.emit("start", this.id);
2420
- const outcome = {
2464
+ const state = { outcome: {
2421
2465
  content: "",
2422
2466
  thinking: void 0,
2423
2467
  usage: void 0,
2424
2468
  partial: false,
2425
2469
  exhausted: false
2426
- };
2470
+ } };
2427
2471
  const channel = new Channel();
2428
2472
  const settled = (0, _orkestrel_workflow.createDeferred)();
2429
- this.#pump(abort, outcome, timeout, channel, settled, options?.think, options?.schema, limit, budget);
2473
+ this.#pump(abort, state, timeout, channel, settled, options?.think, options?.schema, limit, budget);
2430
2474
  settled.promise.catch(() => {});
2431
2475
  return {
2432
2476
  events: this.#events(channel, abort),
2433
2477
  result: settled.promise,
2434
- abort: (reason) => {
2435
- abort.abort(reason);
2436
- }
2478
+ abort: abort.abort.bind(abort)
2437
2479
  };
2438
2480
  }
2439
2481
  abort(reason) {
2440
2482
  for (const abort of [...this.#runs]) abort.abort(reason);
2441
2483
  }
2442
- async #pump(abort, outcome, timeout, channel, settled, think, schema, limit, budget) {
2484
+ async #pump(abort, state, timeout, channel, settled, think, schema, limit, budget) {
2443
2485
  let failure;
2444
2486
  try {
2445
- for await (const chunk of this.#run(abort, outcome, think, schema, limit, budget)) channel.push(chunk);
2487
+ for await (const chunk of this.#run(abort, state, think, schema, limit, budget)) channel.push(chunk);
2446
2488
  } catch (error) {
2447
2489
  failure = { error };
2448
2490
  } finally {
2449
2491
  timeout?.clear();
2450
2492
  this.#runs.delete(abort);
2451
2493
  if (failure === void 0) {
2494
+ const outcome = state.outcome;
2452
2495
  this.#status = "done";
2453
2496
  channel.close();
2454
2497
  const result = this.#result(outcome);
@@ -2471,7 +2514,7 @@ var Agent = class {
2471
2514
  abort.abort();
2472
2515
  }
2473
2516
  }
2474
- async *#run(abort, outcome, think, schema, limit, budget) {
2517
+ async *#run(abort, state, think, schema, limit, budget) {
2475
2518
  const messages = [...this.#context.build(this.#provider.format)];
2476
2519
  const tools = this.#context.tools;
2477
2520
  let content = "";
@@ -2479,7 +2522,7 @@ var Agent = class {
2479
2522
  let usage;
2480
2523
  let pending = false;
2481
2524
  let broke = false;
2482
- const compaction = { futile: false };
2525
+ const compaction = { state: { futile: false } };
2483
2526
  const compacting = this.#window !== void 0 && this.#context.conversations.active?.summarizable === true;
2484
2527
  if (compacting) {
2485
2528
  this.#window?.clear();
@@ -2491,14 +2534,20 @@ var Agent = class {
2491
2534
  await this.#scheduler?.yield({ signal: abort.signal });
2492
2535
  } catch (error) {
2493
2536
  if (abort.signal.aborted) {
2494
- outcome.partial = true;
2537
+ state.outcome = {
2538
+ ...state.outcome,
2539
+ partial: true
2540
+ };
2495
2541
  broke = true;
2496
2542
  break;
2497
2543
  }
2498
2544
  throw error;
2499
2545
  }
2500
2546
  if (abort.signal.aborted) {
2501
- outcome.partial = true;
2547
+ state.outcome = {
2548
+ ...state.outcome,
2549
+ partial: true
2550
+ };
2502
2551
  broke = true;
2503
2552
  break;
2504
2553
  }
@@ -2535,7 +2584,10 @@ var Agent = class {
2535
2584
  usage = this.#sum(usage, abortUsage);
2536
2585
  }
2537
2586
  }
2538
- outcome.partial = true;
2587
+ state.outcome = {
2588
+ ...state.outcome,
2589
+ partial: true
2590
+ };
2539
2591
  broke = true;
2540
2592
  break;
2541
2593
  }
@@ -2593,17 +2645,21 @@ var Agent = class {
2593
2645
  broke = true;
2594
2646
  break;
2595
2647
  }
2596
- if (!broke && pending) {
2597
- outcome.partial = true;
2598
- outcome.exhausted = !abort.signal.aborted;
2599
- }
2600
- outcome.content = content;
2601
- outcome.thinking = thinking;
2602
- outcome.usage = usage;
2648
+ if (!broke && pending) state.outcome = {
2649
+ ...state.outcome,
2650
+ partial: true,
2651
+ exhausted: !abort.signal.aborted
2652
+ };
2653
+ state.outcome = {
2654
+ ...state.outcome,
2655
+ content,
2656
+ thinking,
2657
+ usage
2658
+ };
2603
2659
  }
2604
2660
  async #trim(messages, compaction, latchFutile) {
2605
2661
  const conversation = this.#context.conversations.active;
2606
- if (this.#window === void 0 || conversation?.summarizable !== true || compaction.futile) return;
2662
+ if (this.#window === void 0 || conversation?.summarizable !== true || compaction.state.futile) return;
2607
2663
  this.#window.clear();
2608
2664
  this.#window.consume(messages);
2609
2665
  if (!this.#window.exhausted) return;
@@ -2616,7 +2672,7 @@ var Agent = class {
2616
2672
  return;
2617
2673
  }
2618
2674
  if (section === void 0) {
2619
- if (latchFutile) compaction.futile = true;
2675
+ if (latchFutile) compaction.state = { futile: true };
2620
2676
  return;
2621
2677
  }
2622
2678
  messages.splice(0, messages.length, ...this.#context.build(this.#provider.format));
@@ -2778,16 +2834,17 @@ var AgentRegistry = class {
2778
2834
  return agent;
2779
2835
  }
2780
2836
  #options(input, signal) {
2837
+ const budget = this.#budget(input.budget);
2781
2838
  return {
2782
- system: input.system,
2783
2839
  tools: this.#manager(input.tools),
2784
- limit: input.limit,
2785
- timeout: input.timeout,
2786
- budget: this.#budget(input.budget),
2787
- authority: input.authority === void 0 ? void 0 : this.authority(input.authority),
2788
- scheduler: input.scheduler === void 0 ? void 0 : this.scheduler(input.scheduler),
2789
- conversations: this.#store === void 0 ? void 0 : new ConversationManager({ store: this.#store }),
2790
- signal
2840
+ ...input.system === void 0 ? {} : { system: input.system },
2841
+ ...input.limit === void 0 ? {} : { limit: input.limit },
2842
+ ...input.timeout === void 0 ? {} : { timeout: input.timeout },
2843
+ ...budget === void 0 ? {} : { budget },
2844
+ ...input.authority === void 0 ? {} : { authority: this.authority(input.authority) },
2845
+ ...input.scheduler === void 0 ? {} : { scheduler: this.scheduler(input.scheduler) },
2846
+ ...this.#store === void 0 ? {} : { conversations: new ConversationManager({ store: this.#store }) },
2847
+ ...signal === void 0 ? {} : { signal }
2791
2848
  };
2792
2849
  }
2793
2850
  #manager(names) {
@@ -2853,7 +2910,7 @@ var Authority = class {
2853
2910
  for (const rule of this.#rules) if (rule.match(context)) return {
2854
2911
  zone: rule.zone,
2855
2912
  allowed: rule.allowed ?? true,
2856
- reason: rule.reason
2913
+ ...rule.reason === void 0 ? {} : { reason: rule.reason }
2857
2914
  };
2858
2915
  return this.#fallback;
2859
2916
  }
@@ -3032,16 +3089,19 @@ var Scope = class Scope {
3032
3089
  files;
3033
3090
  constructor(input) {
3034
3091
  this.name = input.name;
3035
- this.instructions = input.instructions === void 0 ? void 0 : [...input.instructions];
3036
- this.tools = input.tools === void 0 ? void 0 : [...input.tools];
3037
- this.files = input.files === void 0 ? void 0 : [...input.files];
3092
+ if (input.instructions !== void 0) this.instructions = [...input.instructions];
3093
+ if (input.tools !== void 0) this.tools = [...input.tools];
3094
+ if (input.files !== void 0) this.files = [...input.files];
3038
3095
  }
3039
3096
  narrow(config) {
3097
+ const instructions = Scope.#intersect(this.instructions, config.instructions);
3098
+ const tools = Scope.#intersect(this.tools, config.tools);
3099
+ const files = Scope.#intersect(this.files, config.files);
3040
3100
  return new Scope({
3041
3101
  name: this.name,
3042
- instructions: Scope.#intersect(this.instructions, config.instructions),
3043
- tools: Scope.#intersect(this.tools, config.tools),
3044
- files: Scope.#intersect(this.files, config.files)
3102
+ ...instructions === void 0 ? {} : { instructions },
3103
+ ...tools === void 0 ? {} : { tools },
3104
+ ...files === void 0 ? {} : { files }
3045
3105
  });
3046
3106
  }
3047
3107
  static #intersect(parent, child) {
@@ -3085,8 +3145,8 @@ var ScopeManager = class {
3085
3145
  #emitter;
3086
3146
  constructor(on, error) {
3087
3147
  this.#emitter = new _orkestrel_emitter.Emitter({
3088
- on,
3089
- error
3148
+ ...on === void 0 ? {} : { on },
3149
+ ...error === void 0 ? {} : { error }
3090
3150
  });
3091
3151
  }
3092
3152
  get emitter() {
@@ -3276,9 +3336,9 @@ var Tool = class {
3276
3336
  #execute;
3277
3337
  constructor(options) {
3278
3338
  this.name = options.name;
3279
- this.description = options.description;
3280
- this.summary = options.summary;
3281
- this.parameters = options.parameters;
3339
+ if (options.description !== void 0) this.description = options.description;
3340
+ if (options.summary !== void 0) this.summary = options.summary;
3341
+ if (options.parameters !== void 0) this.parameters = options.parameters;
3282
3342
  this.#execute = options.execute;
3283
3343
  }
3284
3344
  execute(args) {
@@ -3936,11 +3996,11 @@ function createAgentRegistry(options) {
3936
3996
  function createAgentQueue(options) {
3937
3997
  const { registry, allowPartial = false, concurrency, retries, timeout, store } = options;
3938
3998
  return (0, _orkestrel_queue.createQueue)({
3939
- concurrency,
3940
- retries,
3941
- timeout,
3942
- store,
3943
- handler: (input, execution) => settleAgentJob(registry.build(input, execution.signal), allowPartial)
3999
+ ...concurrency === void 0 ? {} : { concurrency },
4000
+ ...retries === void 0 ? {} : { retries },
4001
+ ...timeout === void 0 ? {} : { timeout },
4002
+ ...store === void 0 ? {} : { store },
4003
+ handler: handleAgentQueueJob.bind(void 0, registry, allowPartial)
3944
4004
  });
3945
4005
  }
3946
4006
  /**
@@ -3982,14 +4042,10 @@ function createAgentQueue(options) {
3982
4042
  function createAgentRunner(options) {
3983
4043
  const { registry, allowPartial = false, concurrency, retries, timeout } = options;
3984
4044
  return (0, _orkestrel_workflow.createRunner)({
3985
- concurrency,
3986
- retries,
3987
- timeout,
3988
- handler: (controller) => {
3989
- const children = controller.input.children;
3990
- if (children !== void 0) for (const child of children) controller.spawn(child);
3991
- return settleAgentJob(registry.build(controller.input, controller.signal), allowPartial);
3992
- }
4045
+ ...concurrency === void 0 ? {} : { concurrency },
4046
+ ...retries === void 0 ? {} : { retries },
4047
+ ...timeout === void 0 ? {} : { timeout },
4048
+ handler: handleAgentRunnerJob.bind(void 0, registry, allowPartial)
3993
4049
  });
3994
4050
  }
3995
4051
  /**
@@ -4269,6 +4325,8 @@ exports.estimateMessages = estimateMessages;
4269
4325
  exports.estimateTokens = estimateTokens;
4270
4326
  exports.fencedFile = fencedFile;
4271
4327
  exports.filterAllowList = filterAllowList;
4328
+ exports.handleAgentQueueJob = handleAgentQueueJob;
4329
+ exports.handleAgentRunnerJob = handleAgentRunnerJob;
4272
4330
  exports.inferLanguage = inferLanguage;
4273
4331
  exports.isAgentError = isAgentError;
4274
4332
  exports.isAgentJobError = isAgentJobError;
@@ -4287,6 +4345,7 @@ exports.isWorkspaceError = isWorkspaceError;
4287
4345
  exports.isWorkspaceSnapshot = isWorkspaceSnapshot;
4288
4346
  exports.offsetAt = offsetAt;
4289
4347
  exports.rangeOf = rangeOf;
4348
+ exports.sanitizeToken = sanitizeToken;
4290
4349
  exports.sanitizeUsage = sanitizeUsage;
4291
4350
  exports.settleAgentJob = settleAgentJob;
4292
4351
  exports.sliceRange = sliceRange;