@cubicecho/agent-core 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +50 -2
  2. package/dist/{compaction.d.ts → context/compaction.d.ts} +3 -3
  3. package/dist/{compaction.js → context/compaction.js} +6 -6
  4. package/dist/{ledger.d.ts → context/ledger.d.ts} +2 -2
  5. package/dist/{ledger.js → context/ledger.js} +3 -3
  6. package/dist/{calibration.js → endpoint/calibration.js} +4 -4
  7. package/dist/{capabilities.d.ts → endpoint/capabilities.d.ts} +2 -2
  8. package/dist/{capabilities.js → endpoint/capabilities.js} +3 -3
  9. package/dist/{client.d.ts → endpoint/client.d.ts} +27 -11
  10. package/dist/{client.js → endpoint/client.js} +85 -26
  11. package/dist/{schema-compat.js → endpoint/schema-compat.js} +2 -2
  12. package/dist/{hooks.js → hooks/hooks.js} +6 -6
  13. package/dist/index.d.ts +30 -30
  14. package/dist/index.js +29 -29
  15. package/dist/{agent-loop.d.ts → run/agent-loop.d.ts} +25 -16
  16. package/dist/{agent-loop.js → run/agent-loop.js} +34 -25
  17. package/dist/{events.d.ts → run/events.d.ts} +3 -3
  18. package/dist/{events.js → run/events.js} +6 -6
  19. package/dist/{request-body.d.ts → run/request-body.d.ts} +3 -3
  20. package/dist/{request-body.js → run/request-body.js} +4 -4
  21. package/dist/{run-calls.d.ts → run/run-calls.d.ts} +3 -3
  22. package/dist/{run-calls.js → run/run-calls.js} +4 -4
  23. package/dist/{reset.js → runtime/reset.js} +6 -6
  24. package/dist/{runtime.d.ts → runtime/runtime.d.ts} +11 -11
  25. package/dist/{runtime.js → runtime/runtime.js} +12 -12
  26. package/dist/{snapshot.js → runtime/snapshot.js} +4 -4
  27. package/dist/{spec.d.ts → spec/spec.d.ts} +44 -4
  28. package/dist/{spec.js → spec/spec.js} +164 -5
  29. package/dist/{preselect.d.ts → tools/preselect.d.ts} +5 -4
  30. package/dist/{preselect.js → tools/preselect.js} +6 -5
  31. package/dist/{tool-loading.js → tools/tool-loading.js} +3 -3
  32. package/dist/{continuation.d.ts → turn/continuation.d.ts} +2 -2
  33. package/dist/{continuation.js → turn/continuation.js} +5 -5
  34. package/dist/{run-turn.d.ts → turn/run-turn.d.ts} +2 -2
  35. package/dist/{run-turn.js → turn/run-turn.js} +7 -7
  36. package/dist/{side-task.d.ts → turn/side-task.d.ts} +2 -2
  37. package/dist/{side-task.js → turn/side-task.js} +9 -9
  38. package/dist/{errors.d.ts → wire/errors.d.ts} +4 -0
  39. package/dist/{errors.js → wire/errors.js} +4 -0
  40. package/dist/{retry.js → wire/retry.js} +1 -1
  41. package/dist/{stream.js → wire/stream.js} +1 -1
  42. package/dist/{tool-calls.js → wire/tool-calls.js} +1 -1
  43. package/llms.txt +180 -175
  44. package/package.json +3 -3
  45. /package/dist/{config.d.ts → core/config.d.ts} +0 -0
  46. /package/dist/{config.js → core/config.js} +0 -0
  47. /package/dist/{digest.d.ts → core/digest.d.ts} +0 -0
  48. /package/dist/{digest.js → core/digest.js} +0 -0
  49. /package/dist/{guards.d.ts → core/guards.d.ts} +0 -0
  50. /package/dist/{guards.js → core/guards.js} +0 -0
  51. /package/dist/{platform.d.ts → core/platform.d.ts} +0 -0
  52. /package/dist/{platform.js → core/platform.js} +0 -0
  53. /package/dist/{scope.d.ts → core/scope.d.ts} +0 -0
  54. /package/dist/{scope.js → core/scope.js} +0 -0
  55. /package/dist/{calibration.d.ts → endpoint/calibration.d.ts} +0 -0
  56. /package/dist/{schema-compat.d.ts → endpoint/schema-compat.d.ts} +0 -0
  57. /package/dist/{hook-events.d.ts → hooks/hook-events.d.ts} +0 -0
  58. /package/dist/{hook-events.js → hooks/hook-events.js} +0 -0
  59. /package/dist/{hooks.d.ts → hooks/hooks.d.ts} +0 -0
  60. /package/dist/{reset.d.ts → runtime/reset.d.ts} +0 -0
  61. /package/dist/{snapshot.d.ts → runtime/snapshot.d.ts} +0 -0
  62. /package/dist/{catalog.d.ts → tools/catalog.d.ts} +0 -0
  63. /package/dist/{catalog.js → tools/catalog.js} +0 -0
  64. /package/dist/{tool-loading.d.ts → tools/tool-loading.d.ts} +0 -0
  65. /package/dist/{retry.d.ts → wire/retry.d.ts} +0 -0
  66. /package/dist/{stream.d.ts → wire/stream.d.ts} +0 -0
  67. /package/dist/{thinking.d.ts → wire/thinking.d.ts} +0 -0
  68. /package/dist/{thinking.js → wire/thinking.js} +0 -0
  69. /package/dist/{tokens.d.ts → wire/tokens.d.ts} +0 -0
  70. /package/dist/{tokens.js → wire/tokens.js} +0 -0
  71. /package/dist/{tool-calls.d.ts → wire/tool-calls.d.ts} +0 -0
  72. /package/dist/{wire.d.ts → wire/wire.d.ts} +0 -0
  73. /package/dist/{wire.js → wire/wire.js} +0 -0
package/dist/index.js CHANGED
@@ -9,32 +9,32 @@
9
9
  * prompts, and whatever the run is about — because that is the caller's, and it is the part
10
10
  * that differs between one server and the next.
11
11
  */
12
- export { PRESELECT_APPEND, PRESELECT_EXCLUSIVE, runAgentLoop, } from './agent-loop.js';
13
- export { calibrate, charsPerTokenFor, resetCalibration } from './calibration.js';
14
- export { capabilitiesFor, EFFORT_LADDER, EFFORT_NONE, EFFORT_OFF, effortFor, expireCapabilities, modelCapabilitiesFor, negotiate, resetCapabilities, } from './capabilities.js';
15
- export { configureClients, contextLimitFor, endpointId, endpointKey, firstTokenMs, getClient, listModels, NO_KEY, resetClients, resolveApiKey, servedWindow, timeoutMs, } from './client.js';
16
- export { applyCompaction, COMPACT_AT, compactTranscript, KEEP_RATIO, planCompaction, pruneToolResults, requestIndex, runCompaction, SUMMARY_LEAD, SUMMARY_PROMPT, summariser, } from './compaction.js';
17
- export { ToolDiscovery, } from './config.js';
18
- export { continueTurn, } from './continuation.js';
19
- export { AgentLoopError, AgentLoopOverflow, errorMessage, failedRun, ToolIterationLimit, } from './errors.js';
20
- export { configureEvents, emit, endRun, fold, history, RunEventKind, RunOutcome, resetEvents, runMetrics, watch, } from './events.js';
21
- export { HOOK_EVENTS, HookEvent, INJECT_EVENTS } from './hook-events.js';
22
- export { assembleContext, configureHooks, consult, gather, HOOK_CONTEXT_TOKENS, HOOK_PREFACE, notify, resetHooks, turnIndex, turnMessages, UNTRUSTED_PREFACE, untrusted, withContext, } from './hooks.js';
23
- export { estimateFrom, rebaseLedger, recordRequest, tokensBetween, } from './ledger.js';
24
- export { PRESELECT_SCHEMA, PRESELECT_SYSTEM, preselect, preselectByKeywords, preselectInput, preselection, preselectSystem, } from './preselect.js';
25
- export { buildBody } from './request-body.js';
26
- export { resetAll } from './reset.js';
27
- export { backoffMs, ContextOverflow, EndpointSilent, isModelLoading, isOverflow, isTransient, SMALLEST_LIKELY_WINDOW, } from './retry.js';
28
- export { preview } from './run-calls.js';
29
- export { runTurn } from './run-turn.js';
30
- export { createRuntime, defaultRuntime } from './runtime.js';
31
- export { isGrammarError, relaxSchema, relaxTools, sanitizeSchema, sanitizeTools, } from './schema-compat.js';
32
- export { ask, askJson, clean, listLines, parseJson, resetHints, taskCall, tryAsk, } from './side-task.js';
33
- export { CAPABILITY_SNAPSHOT_VERSION, exportCapabilities, importCapabilities, } from './snapshot.js';
34
- export { AGENT_SPEC, AGENT_SPEC_VERSION, AGENT_TASKS, exportSpec, parseSpec, REF_FILE, REF_URL, RESOLVED_DEFAULTS, resolveAgentSpec, SPEC_EVENTS, } from './spec.js';
35
- export { CacheBreakReason, streamTurn, } from './stream.js';
36
- export { ALL_FENCES, DEFAULT_FENCES, FenceSplitter, SPLIT_OUTPUT, SPLIT_REASONING, stripThinking, THINK_FENCE, } from './thinking.js';
37
- export { compact, contextChars, contextTokens, estimateTokens, messageTokens, requestChars, requestTokens, } from './tokens.js';
38
- export { ARGUMENTS_MALFORMED, ARGUMENTS_TRUNCATED, parseToolArguments, recoverToolCalls, ToolArgumentsError, } from './tool-calls.js';
39
- export { CALL_TOOL, carryOver, catalogList, catalogPrompt, expandNames, holdsDefinitions, inCatalog, LOAD_TOOLS, LOAD_TOOLS_DEFINITION, loadedTools, loadResult, orderTools, PROXY_TOOLS, proxiedCall, proxyCatalogPrompt, proxyLoadResult, requestedNames, shownCall, } from './tool-loading.js';
40
- export { FinishReason, FUNCTION_TOOL, JSON_SCHEMA_FORMAT, PartType, Role, SchemaType } from './wire.js';
12
+ export { applyCompaction, COMPACT_AT, compactTranscript, KEEP_RATIO, planCompaction, pruneToolResults, requestIndex, runCompaction, SUMMARY_LEAD, SUMMARY_PROMPT, summariser, } from './context/compaction.js';
13
+ export { estimateFrom, rebaseLedger, recordRequest, tokensBetween, } from './context/ledger.js';
14
+ export { ToolDiscovery, } from './core/config.js';
15
+ export { calibrate, charsPerTokenFor, resetCalibration } from './endpoint/calibration.js';
16
+ export { capabilitiesFor, EFFORT_LADDER, EFFORT_NONE, EFFORT_OFF, effortFor, expireCapabilities, modelCapabilitiesFor, negotiate, resetCapabilities, } from './endpoint/capabilities.js';
17
+ export { configureClients, contextLimitFor, endpointId, endpointKey, firstTokenMs, getClient, listModels, NO_KEY, resetClients, resolveApiKey, servedWindow, timeoutMs, } from './endpoint/client.js';
18
+ export { isGrammarError, relaxSchema, relaxTools, sanitizeSchema, sanitizeTools, } from './endpoint/schema-compat.js';
19
+ export { HOOK_EVENTS, HookEvent, INJECT_EVENTS } from './hooks/hook-events.js';
20
+ export { assembleContext, configureHooks, consult, gather, HOOK_CONTEXT_TOKENS, HOOK_PREFACE, notify, resetHooks, turnIndex, turnMessages, UNTRUSTED_PREFACE, untrusted, withContext, } from './hooks/hooks.js';
21
+ export { PRESELECT_APPEND, PRESELECT_EXCLUSIVE, PRESELECTED_NOTICE, runAgentLoop, } from './run/agent-loop.js';
22
+ export { configureEvents, emit, endRun, fold, history, RunEventKind, RunOutcome, resetEvents, runMetrics, watch, } from './run/events.js';
23
+ export { buildBody } from './run/request-body.js';
24
+ export { preview } from './run/run-calls.js';
25
+ export { resetAll } from './runtime/reset.js';
26
+ export { createRuntime, defaultRuntime } from './runtime/runtime.js';
27
+ export { CAPABILITY_SNAPSHOT_VERSION, exportCapabilities, importCapabilities, } from './runtime/snapshot.js';
28
+ export { AGENT_SPEC, AGENT_SPEC_VERSION, AGENT_TASKS, exportSpec, findSpecSecrets, parseSpec, REF_FILE, REF_URL, RESOLVED_DEFAULTS, resolveAgentSpec, SecretSign, SPEC_EVENTS, } from './spec/spec.js';
29
+ export { PRESELECT_SCHEMA, PRESELECT_SYSTEM, preselect, preselectByKeywords, preselectInput, preselection, preselectSystem, } from './tools/preselect.js';
30
+ export { CALL_TOOL, carryOver, catalogList, catalogPrompt, expandNames, holdsDefinitions, inCatalog, LOAD_TOOLS, LOAD_TOOLS_DEFINITION, loadedTools, loadResult, orderTools, PROXY_TOOLS, proxiedCall, proxyCatalogPrompt, proxyLoadResult, requestedNames, shownCall, } from './tools/tool-loading.js';
31
+ export { continueTurn, } from './turn/continuation.js';
32
+ export { runTurn } from './turn/run-turn.js';
33
+ export { ask, askJson, clean, listLines, parseJson, resetHints, taskCall, tryAsk, } from './turn/side-task.js';
34
+ export { AgentLoopError, AgentLoopOverflow, errorMessage, failedRun, ToolIterationLimit, } from './wire/errors.js';
35
+ export { backoffMs, ContextOverflow, EndpointSilent, isModelLoading, isOverflow, isTransient, SMALLEST_LIKELY_WINDOW, } from './wire/retry.js';
36
+ export { CacheBreakReason, streamTurn, } from './wire/stream.js';
37
+ export { ALL_FENCES, DEFAULT_FENCES, FenceSplitter, SPLIT_OUTPUT, SPLIT_REASONING, stripThinking, THINK_FENCE, } from './wire/thinking.js';
38
+ export { compact, contextChars, contextTokens, estimateTokens, messageTokens, requestChars, requestTokens, } from './wire/tokens.js';
39
+ export { ARGUMENTS_MALFORMED, ARGUMENTS_TRUNCATED, parseToolArguments, recoverToolCalls, ToolArgumentsError, } from './wire/tool-calls.js';
40
+ export { FinishReason, FUNCTION_TOOL, JSON_SCHEMA_FORMAT, PartType, Role, SchemaType } from './wire/wire.js';
@@ -1,17 +1,17 @@
1
1
  import type OpenAI from 'openai';
2
- import type { CatalogServer } from './catalog.ts';
3
- import { type CompactionOptions } from './compaction.ts';
4
- import type { Endpoint, ModelParams, RetryPolicy, ToolPolicy } from './config.ts';
2
+ import { type CompactionOptions } from '../context/compaction.ts';
3
+ import { type TokenLedger } from '../context/ledger.ts';
4
+ import type { Endpoint, ModelParams, RetryPolicy, ToolPolicy } from '../core/config.ts';
5
+ import { HookEvent } from '../hooks/hook-events.ts';
6
+ import { type HookContext, type HookNote, type HookRunner, type OnNote } from '../hooks/hooks.ts';
7
+ import type { CatalogServer } from '../tools/catalog.ts';
8
+ import { type KeywordPreselectOptions } from '../tools/preselect.ts';
9
+ import { type ToolOrder } from '../tools/tool-loading.ts';
10
+ import { type SideTask } from '../turn/side-task.ts';
11
+ import { type Turn, type TurnUsage } from '../wire/stream.ts';
12
+ import { type ToolCallOutcome, type ToolCallRequest, type ToolCallResult } from '../wire/tool-calls.ts';
5
13
  import { type RunEventInput, type RunMetrics } from './events.ts';
6
- import { HookEvent } from './hook-events.ts';
7
- import { type HookContext, type HookNote, type HookRunner, type OnNote } from './hooks.ts';
8
- import { type TokenLedger } from './ledger.ts';
9
- import { type KeywordPreselectOptions } from './preselect.ts';
10
14
  import { type ToolDispatch } from './run-calls.ts';
11
- import { type SideTask } from './side-task.ts';
12
- import { type Turn, type TurnUsage } from './stream.ts';
13
- import { type ToolCallOutcome, type ToolCallRequest, type ToolCallResult } from './tool-calls.ts';
14
- import { type ToolOrder } from './tool-loading.ts';
15
15
  /**
16
16
  * The loop above a turn: send, run the tools the model asked for, send again, until it stops
17
17
  * asking.
@@ -181,7 +181,9 @@ export interface AgentLoopOptions {
181
181
  *
182
182
  * `true` takes `preselect`'s defaults; an object passes `keywords` and `maxPerLoad` through.
183
183
  * Its notices arrive as `notice` events, and a preselection that fails picks nothing rather
184
- * than ending the run. It runs before the hooks gather, not beside them.
184
+ * than ending the run. What it picked is a notice too, `PRESELECTED_NOTICE` and the names,
185
+ * before the first `turn` event, and is the result's `preselected`. It runs before the hooks
186
+ * gather, not beside them.
185
187
  */
186
188
  preselect?: boolean | {
187
189
  keywords?: boolean | KeywordPreselectOptions;
@@ -352,6 +354,11 @@ export interface AgentLoopResult {
352
354
  loaded: string[];
353
355
  /** The tools the model actually called, `load_tools` excluded and `call_tool` looked through. */
354
356
  used: string[];
357
+ /**
358
+ * The shortlist the run opened with, as the host's `preselected` gave it or the loop's own
359
+ * preselection picked it. Empty in eager mode, and where nothing was picked.
360
+ */
361
+ preselected: string[];
355
362
  /** The hooks' notes from before the first request. */
356
363
  notes: HookNote[];
357
364
  /**
@@ -400,10 +407,10 @@ export interface AgentLoopResult {
400
407
  * and the ledger. See `AgentLoopResult`.
401
408
  *
402
409
  * @remarks
403
- * What it throws carries the run as it stood — `messages`, `usage`, `toolCalls`, `loaded` and
404
- * `used` — because the steps before a failure were real and a host that stores its transcript
405
- * has nothing else to store them from. A spent budget is a `ToolIterationLimit`, an overflow is
406
- * an `AgentLoopOverflow`, which is still a `ContextOverflow`, and anything else is an
410
+ * What it throws carries the run as it stood — `messages`, `usage`, `toolCalls`, `loaded`, `used`
411
+ * and `preselected` — because the steps before a failure were real and a host that stores its
412
+ * transcript has nothing else to store them from. A spent budget is a `ToolIterationLimit`, an
413
+ * overflow is an `AgentLoopOverflow`, which is still a `ContextOverflow`, and anything else is an
407
414
  * `AgentLoopError` with what was caught as its `cause` and its message as its own; `failedRun`
408
415
  * reads the run off any of the three. A failure while a step's tools run leaves the transcript
409
416
  * well-formed: the results that came back are kept, and each call without one is answered with a
@@ -439,3 +446,5 @@ export interface AgentLoopResult {
439
446
  * run's `temperature` or `maxTokens`.
440
447
  */
441
448
  export declare function runAgentLoop(options: AgentLoopOptions): Promise<AgentLoopResult>;
449
+ /** What opens the notice naming the loop's own picks, ahead of the names. */
450
+ export declare const PRESELECTED_NOTICE = "tools picked before the run: ";
@@ -1,26 +1,26 @@
1
- import { charsPerTokenFor } from './calibration.js';
2
- import { capabilitiesFor, modelCapabilitiesFor, } from './capabilities.js';
3
- import { firstTokenMs, getClient, loadingMs, timeoutMs } from './client.js';
4
- import { compactTranscript, planCompaction, summariser } from './compaction.js';
5
- import { ToolDiscovery } from './config.js';
6
- import { continueTurn } from './continuation.js';
7
- import { AgentLoopError, AgentLoopOverflow, errorMessage, ToolIterationLimit, } from './errors.js';
1
+ import { compactTranscript, planCompaction, summariser } from '../context/compaction.js';
2
+ import { breakReason, rebaseLedger, recordRequest, } from '../context/ledger.js';
3
+ import { ToolDiscovery } from '../core/config.js';
4
+ import { counted } from '../core/guards.js';
5
+ import { charsPerTokenFor } from '../endpoint/calibration.js';
6
+ import { capabilitiesFor, modelCapabilitiesFor, } from '../endpoint/capabilities.js';
7
+ import { firstTokenMs, getClient, loadingMs, timeoutMs } from '../endpoint/client.js';
8
+ import { HookEvent } from '../hooks/hook-events.js';
9
+ import { configureHooks, gather, notify, turnIndex, turnMessages, withContext, } from '../hooks/hooks.js';
10
+ import { preselect } from '../tools/preselect.js';
11
+ import { CALL_TOOL, catalogPrompt, inCatalog, LOAD_TOOLS, LOAD_TOOLS_DEFINITION, loadedTools, orderTools, PROXY_TOOLS, proxyCatalogPrompt, toolName, } from '../tools/tool-loading.js';
12
+ import { continueTurn } from '../turn/continuation.js';
13
+ import { runTurn } from '../turn/run-turn.js';
14
+ import { taskCall, tryAsk } from '../turn/side-task.js';
15
+ import { AgentLoopError, AgentLoopOverflow, errorMessage, ToolIterationLimit, } from '../wire/errors.js';
16
+ import { ContextOverflow } from '../wire/retry.js';
17
+ import { addCounts, noUsage } from '../wire/stream.js';
18
+ import { contextTokens, toolsChars } from '../wire/tokens.js';
19
+ import { recoverToolCalls, } from '../wire/tool-calls.js';
20
+ import { FinishReason, PartType, Role } from '../wire/wire.js';
8
21
  import { RunEventKind, RunOutcome, runMetrics, stamp, } from './events.js';
9
- import { counted } from './guards.js';
10
- import { HookEvent } from './hook-events.js';
11
- import { configureHooks, gather, notify, turnIndex, turnMessages, withContext, } from './hooks.js';
12
- import { breakReason, rebaseLedger, recordRequest, } from './ledger.js';
13
- import { preselect } from './preselect.js';
14
22
  import { buildBody } from './request-body.js';
15
- import { ContextOverflow } from './retry.js';
16
23
  import { assistantMessage, definedAs, loadShortlist, readCalls, runCalls, } from './run-calls.js';
17
- import { runTurn } from './run-turn.js';
18
- import { taskCall, tryAsk } from './side-task.js';
19
- import { addCounts, noUsage } from './stream.js';
20
- import { contextTokens, toolsChars } from './tokens.js';
21
- import { recoverToolCalls, } from './tool-calls.js';
22
- import { CALL_TOOL, catalogPrompt, inCatalog, LOAD_TOOLS, LOAD_TOOLS_DEFINITION, loadedTools, orderTools, PROXY_TOOLS, proxyCatalogPrompt, toolName, } from './tool-loading.js';
23
- import { FinishReason, PartType, Role } from './wire.js';
24
24
  /** The `preselectRouting` that sends the first step the shortlist alone. */
25
25
  export const PRESELECT_EXCLUSIVE = 'exclusive';
26
26
  /** The `preselectRouting` that loads the shortlist after what was carried, and sends the first step like any other. */
@@ -71,10 +71,10 @@ function cacheDiagnosis(previous, next, usage) {
71
71
  * and the ledger. See `AgentLoopResult`.
72
72
  *
73
73
  * @remarks
74
- * What it throws carries the run as it stood — `messages`, `usage`, `toolCalls`, `loaded` and
75
- * `used` — because the steps before a failure were real and a host that stores its transcript
76
- * has nothing else to store them from. A spent budget is a `ToolIterationLimit`, an overflow is
77
- * an `AgentLoopOverflow`, which is still a `ContextOverflow`, and anything else is an
74
+ * What it throws carries the run as it stood — `messages`, `usage`, `toolCalls`, `loaded`, `used`
75
+ * and `preselected` — because the steps before a failure were real and a host that stores its
76
+ * transcript has nothing else to store them from. A spent budget is a `ToolIterationLimit`, an
77
+ * overflow is an `AgentLoopOverflow`, which is still a `ContextOverflow`, and anything else is an
78
78
  * `AgentLoopError` with what was caught as its `cause` and its message as its own; `failedRun`
79
79
  * reads the run off any of the three. A failure while a step's tools run leaves the transcript
80
80
  * well-formed: the results that came back are kept, and each call without one is answered with a
@@ -118,6 +118,7 @@ export async function runAgentLoop(options) {
118
118
  toolCalls: [],
119
119
  loaded: [],
120
120
  used: [],
121
+ preselected: [],
121
122
  }),
122
123
  };
123
124
  let result;
@@ -285,6 +286,8 @@ function recorder(heard) {
285
286
  };
286
287
  return { recorded, onEvent };
287
288
  }
289
+ /** What opens the notice naming the loop's own picks, ahead of the names. */
290
+ export const PRESELECTED_NOTICE = 'tools picked before the run: ';
288
291
  /**
289
292
  * How this run finds its tools, and what it starts with in hand: the loop's own preselection
290
293
  * where it was asked for and the host has not already decided, and what an earlier question
@@ -292,7 +295,8 @@ function recorder(heard) {
292
295
  *
293
296
  * @param options - The run's options. Read for the discovery mode, the catalogue, `loaded`,
294
297
  * `preselected` and `preselect`.
295
- * @param notice - Hears what the loop's own preselection has to say.
298
+ * @param notice - Hears what the loop's own preselection has to say, and then what it picked,
299
+ * by name. A shortlist the host gave is not told back to it.
296
300
  * @returns `proxied` and `onDemand`, the second true of both modes and both false where `catalog`
297
301
  * is empty; `preselected`, the shortlist, empty in eager mode; and `loaded`, a new set of what was
298
302
  * carried and then the shortlist — empty when eager or proxied.
@@ -309,6 +313,9 @@ async function discovery(options, notice) {
309
313
  let preselected = [];
310
314
  if (onDemand && chooses) {
311
315
  preselected = await chooseTools(options, notice);
316
+ if (preselected.length > 0) {
317
+ notice(`${PRESELECTED_NOTICE}${preselected.join(', ')}`);
318
+ }
312
319
  }
313
320
  else if (onDemand) {
314
321
  preselected = [...(options.preselected ?? [])];
@@ -450,6 +457,7 @@ async function runSteps(options, standing) {
450
457
  // As the result would have said it: proxied, nothing is loaded that the history does not hold.
451
458
  loaded: proxied ? [] : [...loaded],
452
459
  used: [...used],
460
+ preselected: [...preselected],
453
461
  });
454
462
  const announce = announcer(onMessage);
455
463
  // Held by reference rather than by index, so a `beforeStep` that folds the head into a summary
@@ -639,6 +647,7 @@ async function runSteps(options, standing) {
639
647
  toolCalls,
640
648
  loaded: proxied ? [] : [...loaded],
641
649
  used: [...used],
650
+ preselected: [...preselected],
642
651
  notes: gathered.notes,
643
652
  context: gathered.context,
644
653
  preface,
@@ -1,6 +1,6 @@
1
- import type { TokenLedger } from './ledger.ts';
2
- import type { TurnUsage } from './stream.ts';
3
- import { CacheBreakReason } from './stream.ts';
1
+ import type { TokenLedger } from '../context/ledger.ts';
2
+ import type { TurnUsage } from '../wire/stream.ts';
3
+ import { CacheBreakReason } from '../wire/stream.ts';
4
4
  /**
5
5
  * What a run is doing, while it is doing it.
6
6
  *
@@ -1,9 +1,9 @@
1
- import { getOrCreate } from './guards.js';
2
- import { ABORT_EVENT, MS_PER_MINUTE } from './platform.js';
3
- import { assignSettings, scoped } from './scope.js';
4
- import { CacheBreakReason } from './stream.js';
5
- import { LOAD_TOOLS } from './tool-loading.js';
6
- import { FinishReason } from './wire.js';
1
+ import { getOrCreate } from '../core/guards.js';
2
+ import { ABORT_EVENT, MS_PER_MINUTE } from '../core/platform.js';
3
+ import { assignSettings, scoped } from '../core/scope.js';
4
+ import { LOAD_TOOLS } from '../tools/tool-loading.js';
5
+ import { CacheBreakReason } from '../wire/stream.js';
6
+ import { FinishReason } from '../wire/wire.js';
7
7
  /** How many minutes an unended run's events are kept, absent a `retainUnendedMs`. */
8
8
  const RETAIN_UNENDED_MINUTES = 30;
9
9
  /** The numbers a run of the shape this bus was written for wants. */
@@ -1,7 +1,7 @@
1
1
  import type OpenAI from 'openai';
2
- import { type Capabilities, type ModelCapabilities } from './capabilities.ts';
3
- import { type ModelParams } from './config.ts';
4
- import { type ToolOrder } from './tool-loading.ts';
2
+ import { type ModelParams } from '../core/config.ts';
3
+ import { type Capabilities, type ModelCapabilities } from '../endpoint/capabilities.ts';
4
+ import { type ToolOrder } from '../tools/tool-loading.ts';
5
5
  /**
6
6
  * The one place a streamed request's body is decided from a config and what the endpoint and
7
7
  * the model have refused.
@@ -1,7 +1,7 @@
1
- import { ceilingAndTemperature, effortFor } from './capabilities.js';
2
- import { RESERVED_BODY_FIELDS } from './config.js';
3
- import { relaxTools, sanitizeTools } from './schema-compat.js';
4
- import { orderTools } from './tool-loading.js';
1
+ import { RESERVED_BODY_FIELDS } from '../core/config.js';
2
+ import { ceilingAndTemperature, effortFor, } from '../endpoint/capabilities.js';
3
+ import { relaxTools, sanitizeTools } from '../endpoint/schema-compat.js';
4
+ import { orderTools } from '../tools/tool-loading.js';
5
5
  /**
6
6
  * The one place a streamed request's body is decided from a config and what the endpoint and
7
7
  * the model have refused.
@@ -1,8 +1,8 @@
1
1
  import type OpenAI from 'openai';
2
- import type { CatalogServer } from './catalog.ts';
2
+ import type { CatalogServer } from '../tools/catalog.ts';
3
+ import type { Turn } from '../wire/stream.ts';
4
+ import { type ToolCall, type ToolCallOutcome, type ToolCallRequest, type ToolCallResult } from '../wire/tool-calls.ts';
3
5
  import type { RunEventInput } from './events.ts';
4
- import type { Turn } from './stream.ts';
5
- import { type ToolCall, type ToolCallOutcome, type ToolCallRequest, type ToolCallResult } from './tool-calls.ts';
6
6
  /**
7
7
  * The tools between two turns: a step's calls read, run and written into the transcript.
8
8
  *
@@ -1,8 +1,8 @@
1
- import { errorMessage } from './errors.js';
1
+ import { CALL_TOOL, expandNames, inCatalog, LOAD_TOOLS, loadResult, proxiedCall, proxyLoadResult, requestedNames, shownCall, toolName, } from '../tools/tool-loading.js';
2
+ import { errorMessage } from '../wire/errors.js';
3
+ import { parseToolArguments, } from '../wire/tool-calls.js';
4
+ import { FUNCTION_TOOL, Role } from '../wire/wire.js';
2
5
  import { RunEventKind } from './events.js';
3
- import { parseToolArguments, } from './tool-calls.js';
4
- import { CALL_TOOL, expandNames, inCatalog, LOAD_TOOLS, loadResult, proxiedCall, proxyLoadResult, requestedNames, shownCall, toolName, } from './tool-loading.js';
5
- import { FUNCTION_TOOL, Role } from './wire.js';
6
6
  /**
7
7
  * The tools between two turns: a step's calls read, run and written into the transcript.
8
8
  *
@@ -1,9 +1,9 @@
1
- import { resetCalibration } from './calibration.js';
2
- import { resetCapabilities } from './capabilities.js';
3
- import { resetClients } from './client.js';
4
- import { resetEvents } from './events.js';
5
- import { resetHooks } from './hooks.js';
6
- import { resetHints } from './side-task.js';
1
+ import { resetCalibration } from '../endpoint/calibration.js';
2
+ import { resetCapabilities } from '../endpoint/capabilities.js';
3
+ import { resetClients } from '../endpoint/client.js';
4
+ import { resetHooks } from '../hooks/hooks.js';
5
+ import { resetEvents } from '../run/events.js';
6
+ import { resetHints } from '../turn/side-task.js';
7
7
  /**
8
8
  * Forgets everything this package remembers between calls.
9
9
  *
@@ -1,15 +1,15 @@
1
- import { runAgentLoop } from './agent-loop.ts';
2
- import { calibrate, charsPerTokenFor, resetCalibration } from './calibration.ts';
3
- import { capabilitiesFor, expireCapabilities, resetCapabilities } from './capabilities.ts';
4
- import { type ClientPoolOptions, configureClients, contextLimitFor, getClient, listModels, resetClients, servedWindow } from './client.ts';
5
- import { compactTranscript, runCompaction, summariser } from './compaction.ts';
6
- import { continueTurn } from './continuation.ts';
7
- import { configureEvents, type EventBusOptions, emit, endRun, history, resetEvents, watch } from './events.ts';
8
- import { assembleContext, configureHooks, consult, gather, type HookOptions, notify, resetHooks, withContext } from './hooks.ts';
9
- import { preselect } from './preselect.ts';
1
+ import { compactTranscript, runCompaction, summariser } from '../context/compaction.ts';
2
+ import { calibrate, charsPerTokenFor, resetCalibration } from '../endpoint/calibration.ts';
3
+ import { capabilitiesFor, expireCapabilities, resetCapabilities } from '../endpoint/capabilities.ts';
4
+ import { type ClientPoolOptions, configureClients, contextLimitFor, getClient, listModels, resetClients, servedWindow } from '../endpoint/client.ts';
5
+ import { assembleContext, configureHooks, consult, gather, type HookOptions, notify, resetHooks, withContext } from '../hooks/hooks.ts';
6
+ import { runAgentLoop } from '../run/agent-loop.ts';
7
+ import { configureEvents, type EventBusOptions, emit, endRun, history, resetEvents, watch } from '../run/events.ts';
8
+ import { preselect } from '../tools/preselect.ts';
9
+ import { continueTurn } from '../turn/continuation.ts';
10
+ import { runTurn } from '../turn/run-turn.ts';
11
+ import { ask, askJson, resetHints, tryAsk } from '../turn/side-task.ts';
10
12
  import { resetAll } from './reset.ts';
11
- import { runTurn } from './run-turn.ts';
12
- import { ask, askJson, resetHints, tryAsk } from './side-task.ts';
13
13
  import { exportCapabilities, importCapabilities } from './snapshot.ts';
14
14
  /**
15
15
  * Every exported function that reads or writes what a runtime remembers, itself or through what
@@ -1,16 +1,16 @@
1
- import { runAgentLoop } from './agent-loop.js';
2
- import { calibrate, charsPerTokenFor, resetCalibration } from './calibration.js';
3
- import { capabilitiesFor, expireCapabilities, resetCapabilities } from './capabilities.js';
4
- import { configureClients, contextLimitFor, getClient, listModels, resetClients, servedWindow, } from './client.js';
5
- import { compactTranscript, runCompaction, summariser } from './compaction.js';
6
- import { continueTurn } from './continuation.js';
7
- import { configureEvents, emit, endRun, history, resetEvents, watch } from './events.js';
8
- import { assembleContext, configureHooks, consult, gather, notify, resetHooks, withContext, } from './hooks.js';
9
- import { preselect } from './preselect.js';
1
+ import { compactTranscript, runCompaction, summariser } from '../context/compaction.js';
2
+ import { inScope, rootScope } from '../core/scope.js';
3
+ import { calibrate, charsPerTokenFor, resetCalibration } from '../endpoint/calibration.js';
4
+ import { capabilitiesFor, expireCapabilities, resetCapabilities } from '../endpoint/capabilities.js';
5
+ import { configureClients, contextLimitFor, getClient, listModels, resetClients, servedWindow, } from '../endpoint/client.js';
6
+ import { assembleContext, configureHooks, consult, gather, notify, resetHooks, withContext, } from '../hooks/hooks.js';
7
+ import { runAgentLoop } from '../run/agent-loop.js';
8
+ import { configureEvents, emit, endRun, history, resetEvents, watch } from '../run/events.js';
9
+ import { preselect } from '../tools/preselect.js';
10
+ import { continueTurn } from '../turn/continuation.js';
11
+ import { runTurn } from '../turn/run-turn.js';
12
+ import { ask, askJson, resetHints, tryAsk } from '../turn/side-task.js';
10
13
  import { resetAll } from './reset.js';
11
- import { runTurn } from './run-turn.js';
12
- import { inScope, rootScope } from './scope.js';
13
- import { ask, askJson, resetHints, tryAsk } from './side-task.js';
14
14
  import { exportCapabilities, importCapabilities } from './snapshot.js';
15
15
  /**
16
16
  * Every exported function that reads or writes what a runtime remembers, itself or through what
@@ -1,7 +1,7 @@
1
- import { capabilitiesById, knownCapabilities, MODEL_FLAGS, modelCapabilitiesFor, OPTIMISTIC_MODEL, } from './capabilities.js';
2
- import { modelKey } from './client.js';
3
- import { isRecord } from './guards.js';
4
- import { refusedHints } from './side-task.js';
1
+ import { isRecord } from '../core/guards.js';
2
+ import { capabilitiesById, knownCapabilities, MODEL_FLAGS, modelCapabilitiesFor, OPTIMISTIC_MODEL, } from '../endpoint/capabilities.js';
3
+ import { modelKey } from '../endpoint/client.js';
4
+ import { refusedHints } from '../turn/side-task.js';
5
5
  /**
6
6
  * What endpoints and models refused, carried across a restart.
7
7
  *
@@ -1,5 +1,5 @@
1
- import { type AgentConfig, type Endpoint } from './config.ts';
2
- import { HookEvent } from './hook-events.ts';
1
+ import { type AgentConfig, type Endpoint } from '../core/config.ts';
2
+ import { HookEvent } from '../hooks/hook-events.ts';
3
3
  /**
4
4
  * A JSON document that defines an agent, and the rules for reading one.
5
5
  *
@@ -359,7 +359,47 @@ export interface ExportSpecOptions {
359
359
  * The property worth keeping is that **a redacted spec is still a valid spec** — it parses, it
360
360
  * resolves, and what comes back is the same agent pointed at the same servers, needing only the
361
361
  * credentials the importing host supplies itself. So a bundled server loses its `env` and its
362
- * `headers` and nothing else, and nothing outside `bundle` is touched: the format has no
363
- * credential field at any depth, which is the reason there is nothing else to strip.
362
+ * `headers` and nothing else, and nothing outside `bundle` is touched: those two are the only
363
+ * fields the format gives a credential. A server can still carry one where the format gives it no
364
+ * field — an `--api-key` among its `args`, a token in its `url` — and that is kept, because
365
+ * cutting it would point the agent at a different server. `findSpecSecrets` says where to look.
364
366
  */
365
367
  export declare function exportSpec(spec: AgentSpec, { secrets }?: ExportSpecOptions): AgentSpec;
368
+ /** Why `findSpecSecrets` named a place. */
369
+ export declare const SecretSign: {
370
+ /** A URL with a user or a password before its host. */
371
+ readonly Userinfo: 'userinfo';
372
+ /** A URL query parameter whose name reads as a credential's. */
373
+ readonly Query: 'query';
374
+ /** The value of a command-line flag, or of a header written as `Name: value`, so named. */
375
+ readonly Flag: 'flag';
376
+ /** A value with the shape of a credential: a known key prefix, or `Bearer` and a token. */
377
+ readonly Value: 'value';
378
+ /** A key of the server itself whose name reads as a credential's. */
379
+ readonly Field: 'field';
380
+ };
381
+ /** Any one of the reasons in `SecretSign`. */
382
+ export type SecretSign = (typeof SecretSign)[keyof typeof SecretSign];
383
+ /** One place `findSpecSecrets` thinks a credential may be, and never the credential. */
384
+ export interface SecretHint {
385
+ /** Where, in `parseSpec`'s spelling: `bundle.mcpServers[0].args[2]`. */
386
+ path: string;
387
+ /** The server's slug, or its id where it has no slug. */
388
+ server: string;
389
+ sign: SecretSign;
390
+ }
391
+ /**
392
+ * Where a document's bundled servers may still carry a credential after `exportSpec`.
393
+ *
394
+ * @param spec - A document, exported or not: `env` and `headers` are not reported either way,
395
+ * since `exportSpec` strips them.
396
+ * @returns One hint for each suspect place, in document order, each naming where and why and
397
+ * none holding the value. Empty for a document with no bundle.
398
+ *
399
+ * @remarks
400
+ * A host calls this before it offers an export as safe to share, and warns with what comes back.
401
+ * It reads a server's `url`, its `command` and `args`, and the names of its other keys, and is a
402
+ * guess both ways: a credential in a positional argument with no telling prefix is missed, and a
403
+ * flag called `--keyboard` is named. A `${VAR}` is a reference and is never named.
404
+ */
405
+ export declare function findSpecSecrets(spec: AgentSpec): SecretHint[];