@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
@@ -1,6 +1,6 @@
1
- import { RESERVED_BODY_FIELDS, ToolDiscovery } from './config.js';
2
- import { isRecord } from './guards.js';
3
- import { HOOK_EVENTS, HookEvent, INJECT_EVENTS } from './hook-events.js';
1
+ import { RESERVED_BODY_FIELDS, ToolDiscovery } from '../core/config.js';
2
+ import { isRecord } from '../core/guards.js';
3
+ import { HOOK_EVENTS, HookEvent, INJECT_EVENTS } from '../hooks/hook-events.js';
4
4
  /**
5
5
  * A JSON document that defines an agent, and the rules for reading one.
6
6
  *
@@ -896,8 +896,10 @@ export function resolveAgentSpec(layers) {
896
896
  * The property worth keeping is that **a redacted spec is still a valid spec** — it parses, it
897
897
  * resolves, and what comes back is the same agent pointed at the same servers, needing only the
898
898
  * credentials the importing host supplies itself. So a bundled server loses its `env` and its
899
- * `headers` and nothing else, and nothing outside `bundle` is touched: the format has no
900
- * credential field at any depth, which is the reason there is nothing else to strip.
899
+ * `headers` and nothing else, and nothing outside `bundle` is touched: those two are the only
900
+ * fields the format gives a credential. A server can still carry one where the format gives it no
901
+ * field — an `--api-key` among its `args`, a token in its `url` — and that is kept, because
902
+ * cutting it would point the agent at a different server. `findSpecSecrets` says where to look.
901
903
  */
902
904
  export function exportSpec(spec, { secrets = false } = {}) {
903
905
  if (secrets || !spec.bundle?.mcpServers) {
@@ -911,3 +913,160 @@ export function exportSpec(spec, { secrets = false } = {}) {
911
913
  },
912
914
  };
913
915
  }
916
+ /** Why `findSpecSecrets` named a place. */
917
+ export const SecretSign = {
918
+ /** A URL with a user or a password before its host. */
919
+ Userinfo: 'userinfo',
920
+ /** A URL query parameter whose name reads as a credential's. */
921
+ Query: 'query',
922
+ /** The value of a command-line flag, or of a header written as `Name: value`, so named. */
923
+ Flag: 'flag',
924
+ /** A value with the shape of a credential: a known key prefix, or `Bearer` and a token. */
925
+ Value: 'value',
926
+ /** A key of the server itself whose name reads as a credential's. */
927
+ Field: 'field',
928
+ };
929
+ /** A name that reads as a credential's: `api-key`, `TOKEN`, `Authorization`. */
930
+ const SECRET_NAME = /key|token|secret|passw|auth|credential|bearer/i;
931
+ /** A value shaped like a credential, whatever it is called. */
932
+ const SECRET_VALUE = /^(sk-|pk-|rk-|ghp_|gho_|ghs_|github_pat_|glpat-|xox[abprs]-|AKIA)|\b(bearer|basic)\s+\S/i;
933
+ /** What an absolute URL opens with. */
934
+ const URL_SCHEME = /^[a-z][a-z0-9+.-]*:\/\//i;
935
+ /** A header as one string, `Name: value`, as `--header` takes it. */
936
+ const HEADER = /^([\w-]+):\s*(\S.*)$/;
937
+ /** A flag carrying its own value, `--name=value`. */
938
+ const FLAG_WITH_VALUE = /^(-{1,2}[^=\s]+)=(.+)$/;
939
+ /** The keys of a server `findSpecSecrets` reads for itself, or `exportSpec` strips. */
940
+ const SERVER_KEYS_READ = new Set(['id', 'slug', 'url', 'command', 'args', 'env', 'headers']);
941
+ /**
942
+ * Whether a string is a credential written out, as against a reference to one.
943
+ *
944
+ * @param value - What a field, a flag or a parameter holds.
945
+ * @returns `false` for an empty string and for one holding a `${VAR}`, which names where the
946
+ * credential is and is not it.
947
+ */
948
+ const writtenOut = (value) => value !== '' && VARIABLE.test(value) === false;
949
+ /**
950
+ * Why a URL may carry a credential.
951
+ *
952
+ * @param text - A string, which need not be a URL.
953
+ * @returns `Userinfo`, `Query`, or `undefined` for a URL that shows neither and for a string
954
+ * that is not an absolute URL.
955
+ */
956
+ function urlSign(text) {
957
+ if (URL_SCHEME.test(text) === false || URL.canParse(text) === false) {
958
+ return undefined;
959
+ }
960
+ const url = new URL(text);
961
+ if (writtenOut(url.username) || writtenOut(url.password)) {
962
+ return SecretSign.Userinfo;
963
+ }
964
+ for (const [name, value] of url.searchParams) {
965
+ if (SECRET_NAME.test(name) && writtenOut(value)) {
966
+ return SecretSign.Query;
967
+ }
968
+ }
969
+ return undefined;
970
+ }
971
+ /**
972
+ * Why one word of a command line may be a credential, read on its own.
973
+ *
974
+ * @param word - One argument.
975
+ * @returns A sign, or `undefined` for a word that shows none. A flag with no value of its own
976
+ * shows none here: `argumentSigns` reads the word after it.
977
+ */
978
+ function wordSign(word) {
979
+ if (writtenOut(word) === false) {
980
+ return undefined;
981
+ }
982
+ const flag = FLAG_WITH_VALUE.exec(word);
983
+ if (flag?.[1] !== undefined && SECRET_NAME.test(flag[1])) {
984
+ return SecretSign.Flag;
985
+ }
986
+ const header = HEADER.exec(word);
987
+ if (header?.[1] !== undefined && SECRET_NAME.test(header[1])) {
988
+ return SecretSign.Flag;
989
+ }
990
+ // A flag's own value is read as a word too: `--url=https://user:pass@host`.
991
+ const value = flag?.[2] ?? word;
992
+ return SECRET_VALUE.test(value) ? SecretSign.Value : urlSign(value);
993
+ }
994
+ /**
995
+ * The words of a command line that may be credentials.
996
+ *
997
+ * @param words - The arguments in order. One that is not a string is passed over.
998
+ * @returns Each suspect word's index and its sign, in order, at most one sign a word.
999
+ *
1000
+ * @remarks
1001
+ * A flag named like a credential marks the word after it, unless that word is another flag.
1002
+ */
1003
+ function argumentSigns(words) {
1004
+ const signs = [];
1005
+ let flagged = false;
1006
+ for (const [index, word] of words.entries()) {
1007
+ if (typeof word !== 'string') {
1008
+ flagged = false;
1009
+ continue;
1010
+ }
1011
+ const isFlag = word.startsWith('-');
1012
+ const sign = flagged && isFlag === false && writtenOut(word) ? SecretSign.Flag : wordSign(word);
1013
+ if (sign) {
1014
+ signs.push([index, sign]);
1015
+ }
1016
+ flagged = isFlag && word.includes('=') === false && SECRET_NAME.test(word);
1017
+ }
1018
+ return signs;
1019
+ }
1020
+ /**
1021
+ * The places one bundled server may carry a credential, outside its `env` and `headers`.
1022
+ *
1023
+ * @param server - The server as the document holds it.
1024
+ * @param path - Where the server is, which each hint's path opens with.
1025
+ * @returns The hints in the order `url`, `command`, `args`, then the server's other keys.
1026
+ */
1027
+ function serverSecrets(server, path) {
1028
+ const name = server.slug ?? server.id ?? '';
1029
+ const hints = [];
1030
+ const hint = (at, sign) => {
1031
+ if (sign) {
1032
+ hints.push({ path: `${path}.${at}`, server: name, sign });
1033
+ }
1034
+ };
1035
+ if (typeof server.url === 'string') {
1036
+ hint('url', urlSign(server.url));
1037
+ }
1038
+ if (typeof server.command === 'string') {
1039
+ // A command written as one line is read as its words, and named once.
1040
+ hint('command', argumentSigns(server.command.split(/\s+/))[0]?.[1]);
1041
+ }
1042
+ if (Array.isArray(server.args)) {
1043
+ for (const [index, sign] of argumentSigns(server.args)) {
1044
+ hint(`args[${index}]`, sign);
1045
+ }
1046
+ }
1047
+ for (const [key, value] of Object.entries(server)) {
1048
+ const empty = absent(value) || value === '' || (typeof value === 'string' && writtenOut(value) === false);
1049
+ if (SERVER_KEYS_READ.has(key) === false && SECRET_NAME.test(key) && empty === false) {
1050
+ hint(key, SecretSign.Field);
1051
+ }
1052
+ }
1053
+ return hints;
1054
+ }
1055
+ /**
1056
+ * Where a document's bundled servers may still carry a credential after `exportSpec`.
1057
+ *
1058
+ * @param spec - A document, exported or not: `env` and `headers` are not reported either way,
1059
+ * since `exportSpec` strips them.
1060
+ * @returns One hint for each suspect place, in document order, each naming where and why and
1061
+ * none holding the value. Empty for a document with no bundle.
1062
+ *
1063
+ * @remarks
1064
+ * A host calls this before it offers an export as safe to share, and warns with what comes back.
1065
+ * It reads a server's `url`, its `command` and `args`, and the names of its other keys, and is a
1066
+ * guess both ways: a credential in a positional argument with no telling prefix is missed, and a
1067
+ * flag called `--keyboard` is named. A `${VAR}` is a reference and is never named.
1068
+ */
1069
+ export function findSpecSecrets(spec) {
1070
+ const servers = spec.bundle?.mcpServers ?? [];
1071
+ return servers.flatMap((server, index) => serverSecrets(server, `bundle.mcpServers[${index}]`));
1072
+ }
@@ -1,6 +1,6 @@
1
- import type { OnNotice } from './capabilities.ts';
1
+ import type { Endpoint } from '../core/config.ts';
2
+ import type { OnNotice } from '../endpoint/capabilities.ts';
2
3
  import type { CatalogServer } from './catalog.ts';
3
- import type { Endpoint } from './config.ts';
4
4
  /**
5
5
  * The system prompt a preselector is given, holding it to the cap its answer will be held to.
6
6
  *
@@ -176,8 +176,9 @@ export interface PreselectOptions {
176
176
  * The tools a request is likely to need, picked by a small model before the run starts, or none.
177
177
  *
178
178
  * @param config - The endpoint the preselector is reached through.
179
- * @param model - The preselector. An empty name picks nothing, which is what `toolSelectModel`
180
- * means by empty.
179
+ * @param model - The preselector. An empty name picks nothing, silently, which is what
180
+ * `toolSelectModel` means by empty: a host whose settings read `""` as "the run's model" passes
181
+ * `toolSelectModel: settings.toolSelectModel || settings.model`.
181
182
  * @param catalog - The servers to choose from.
182
183
  * @param prompt - The request being planned for. Only its head is read; see `preselectInput`.
183
184
  * @param [options] - Cancellation, notices, the reply ceiling, the temperature and reasoning effort
@@ -1,7 +1,7 @@
1
- import { byCodeUnit, counted, isRecord } from './guards.js';
2
- import { askJson, tryAsk } from './side-task.js';
1
+ import { byCodeUnit, counted, isRecord } from '../core/guards.js';
2
+ import { askJson, tryAsk } from '../turn/side-task.js';
3
+ import { SchemaType } from '../wire/wire.js';
3
4
  import { catalogList, expandNames, MAX_PER_LOAD } from './tool-loading.js';
4
- import { SchemaType } from './wire.js';
5
5
  /**
6
6
  * Choosing a run's tools before it starts, from the request and the catalogue's names.
7
7
  *
@@ -243,8 +243,9 @@ export function preselectByKeywords(catalog, prompt, { maxPerLoad = MAX_PER_LOAD
243
243
  * The tools a request is likely to need, picked by a small model before the run starts, or none.
244
244
  *
245
245
  * @param config - The endpoint the preselector is reached through.
246
- * @param model - The preselector. An empty name picks nothing, which is what `toolSelectModel`
247
- * means by empty.
246
+ * @param model - The preselector. An empty name picks nothing, silently, which is what
247
+ * `toolSelectModel` means by empty: a host whose settings read `""` as "the run's model" passes
248
+ * `toolSelectModel: settings.toolSelectModel || settings.model`.
248
249
  * @param catalog - The servers to choose from.
249
250
  * @param prompt - The request being planned for. Only its head is read; see `preselectInput`.
250
251
  * @param [options] - Cancellation, notices, the reply ceiling, the temperature and reasoning effort
@@ -1,6 +1,6 @@
1
- import { byCodeUnit, isRecord } from './guards.js';
2
- import { ARGUMENT_PREVIEW_CHARS } from './tool-calls.js';
3
- import { FUNCTION_TOOL, SchemaType } from './wire.js';
1
+ import { byCodeUnit, isRecord } from '../core/guards.js';
2
+ import { ARGUMENT_PREVIEW_CHARS } from '../wire/tool-calls.js';
3
+ import { FUNCTION_TOOL, SchemaType } from '../wire/wire.js';
4
4
  /**
5
5
  * On-demand tool loading.
6
6
  *
@@ -1,7 +1,7 @@
1
1
  import type OpenAI from 'openai';
2
- import { type Capabilities } from './capabilities.ts';
2
+ import { type Capabilities } from '../endpoint/capabilities.ts';
3
+ import { type Turn } from '../wire/stream.ts';
3
4
  import { type RequestBuilder, type RunTurnOptions } from './run-turn.ts';
4
- import { type Turn } from './stream.ts';
5
5
  /**
6
6
  * Picking up an answer the token ceiling cut off, instead of keeping half of it.
7
7
  *
@@ -1,9 +1,9 @@
1
- import { modelCapabilitiesFor } from './capabilities.js';
2
- import { errorMessage } from './errors.js';
3
- import { ContextOverflow, refusesRequest } from './retry.js';
1
+ import { modelCapabilitiesFor } from '../endpoint/capabilities.js';
2
+ import { errorMessage } from '../wire/errors.js';
3
+ import { ContextOverflow, refusesRequest } from '../wire/retry.js';
4
+ import { addCounts } from '../wire/stream.js';
5
+ import { FinishReason, Role } from '../wire/wire.js';
4
6
  import { modelLabel, runTurn } from './run-turn.js';
5
- import { addCounts } from './stream.js';
6
- import { FinishReason, Role } from './wire.js';
7
7
  /**
8
8
  * Whether a turn is one a continuation can finish: cut off at the ceiling, with an answer begun
9
9
  * and no tool call in it.
@@ -1,6 +1,6 @@
1
1
  import type OpenAI from 'openai';
2
- import { type Capabilities, type ModelCapabilities, type OnNotice } from './capabilities.ts';
3
- import { type StreamTurnOptions, type Turn } from './stream.ts';
2
+ import { type Capabilities, type ModelCapabilities, type OnNotice } from '../endpoint/capabilities.ts';
3
+ import { type StreamTurnOptions, type Turn } from '../wire/stream.ts';
4
4
  /**
5
5
  * One turn, given as many attempts as the caller allows.
6
6
  *
@@ -1,10 +1,10 @@
1
- import { calibrate, charsPerTokenFor } from './calibration.js';
2
- import { negotiate } from './capabilities.js';
3
- import { errorMessage } from './errors.js';
4
- import { MS_PER_SECOND } from './platform.js';
5
- import { backoffMs, ContextOverflow, EndpointSilent, isModelLoading, isOverflow, isTransient, LOADING_POLL_MS, LOADING_TIMEOUT_MS, SMALLEST_LIKELY_WINDOW, sleep, } from './retry.js';
6
- import { streamTurn } from './stream.js';
7
- import { compact, requestTokens } from './tokens.js';
1
+ import { MS_PER_SECOND } from '../core/platform.js';
2
+ import { calibrate, charsPerTokenFor } from '../endpoint/calibration.js';
3
+ import { negotiate } from '../endpoint/capabilities.js';
4
+ import { errorMessage } from '../wire/errors.js';
5
+ import { backoffMs, ContextOverflow, EndpointSilent, isModelLoading, isOverflow, isTransient, LOADING_POLL_MS, LOADING_TIMEOUT_MS, SMALLEST_LIKELY_WINDOW, sleep, } from '../wire/retry.js';
6
+ import { streamTurn } from '../wire/stream.js';
7
+ import { compact, requestTokens } from '../wire/tokens.js';
8
8
  /**
9
9
  * What a notice calls the model, where the caller did not say which one it is.
10
10
  *
@@ -1,6 +1,6 @@
1
1
  import type OpenAI from 'openai';
2
- import { type OnNotice } from './capabilities.ts';
3
- import type { Endpoint, EndpointIdentity } from './config.ts';
2
+ import type { Endpoint, EndpointIdentity } from '../core/config.ts';
3
+ import { type OnNotice } from '../endpoint/capabilities.ts';
4
4
  /**
5
5
  * The pairs that refused the hints, the live set, for `exportCapabilities` and
6
6
  * `importCapabilities`.
@@ -1,12 +1,12 @@
1
- import { capabilitiesFor, ceilingAndTemperature, EFFORT_NONE, effortFor, modelCapabilitiesFor, negotiate, } from './capabilities.js';
2
- import { endpointId, getClient, modelKey, resolveApiKey, sameUrl } from './client.js';
3
- import { errorMessage } from './errors.js';
4
- import { isAbort, refusesRequest } from './retry.js';
5
- import { relaxSchema, sanitizeSchema } from './schema-compat.js';
6
- import { scoped } from './scope.js';
7
- import { stripThinking } from './thinking.js';
8
- import { CODE_FENCE, looseJson } from './tool-calls.js';
9
- import { JSON_SCHEMA_FORMAT, Role } from './wire.js';
1
+ import { scoped } from '../core/scope.js';
2
+ import { capabilitiesFor, ceilingAndTemperature, EFFORT_NONE, effortFor, modelCapabilitiesFor, negotiate, } from '../endpoint/capabilities.js';
3
+ import { endpointId, getClient, modelKey, resolveApiKey, sameUrl } from '../endpoint/client.js';
4
+ import { relaxSchema, sanitizeSchema } from '../endpoint/schema-compat.js';
5
+ import { errorMessage } from '../wire/errors.js';
6
+ import { isAbort, refusesRequest } from '../wire/retry.js';
7
+ import { stripThinking } from '../wire/thinking.js';
8
+ import { CODE_FENCE, looseJson } from '../wire/tool-calls.js';
9
+ import { JSON_SCHEMA_FORMAT, Role } from '../wire/wire.js';
10
10
  /**
11
11
  * One-shot calls that support a run without being one: picking tools, naming a session,
12
12
  * summarising a transcript, proposing follow-ups. They share a shape — small prompt, short
@@ -38,6 +38,8 @@ export interface AgentLoopFailure {
38
38
  loaded: string[];
39
39
  /** The tools the model had called, `load_tools` excluded. */
40
40
  used: string[];
41
+ /** The shortlist the run opened with, as the result's `preselected` would have said it. */
42
+ preselected: string[];
41
43
  }
42
44
  /**
43
45
  * What `runAgentLoop` throws, carrying the run as it stood and what was caught as `cause`.
@@ -55,6 +57,7 @@ export declare class AgentLoopError extends Error implements AgentLoopFailure {
55
57
  readonly toolCalls: ToolCallOutcome[];
56
58
  readonly loaded: string[];
57
59
  readonly used: string[];
60
+ readonly preselected: string[];
58
61
  /**
59
62
  * @param message - What went wrong — the cause's own message, where there is a cause.
60
63
  * @param run - The run as it stood. Held, not copied.
@@ -87,6 +90,7 @@ export declare class AgentLoopOverflow extends ContextOverflow implements AgentL
87
90
  readonly toolCalls: ToolCallOutcome[];
88
91
  readonly loaded: string[];
89
92
  readonly used: string[];
93
+ readonly preselected: string[];
90
94
  /**
91
95
  * @param message - The overflow's own message.
92
96
  * @param run - The run as it stood. Held, not copied.
@@ -28,6 +28,7 @@ export class AgentLoopError extends Error {
28
28
  toolCalls;
29
29
  loaded;
30
30
  used;
31
+ preselected;
31
32
  /**
32
33
  * @param message - What went wrong — the cause's own message, where there is a cause.
33
34
  * @param run - The run as it stood. Held, not copied.
@@ -40,6 +41,7 @@ export class AgentLoopError extends Error {
40
41
  this.toolCalls = run.toolCalls;
41
42
  this.loaded = run.loaded;
42
43
  this.used = run.used;
44
+ this.preselected = run.preselected;
43
45
  }
44
46
  }
45
47
  /**
@@ -67,6 +69,7 @@ export class AgentLoopOverflow extends ContextOverflow {
67
69
  toolCalls;
68
70
  loaded;
69
71
  used;
72
+ preselected;
70
73
  /**
71
74
  * @param message - The overflow's own message.
72
75
  * @param run - The run as it stood. Held, not copied.
@@ -79,6 +82,7 @@ export class AgentLoopOverflow extends ContextOverflow {
79
82
  this.toolCalls = run.toolCalls;
80
83
  this.loaded = run.loaded;
81
84
  this.used = run.used;
85
+ this.preselected = run.preselected;
82
86
  }
83
87
  }
84
88
  /**
@@ -1,5 +1,5 @@
1
1
  import OpenAI from 'openai';
2
- import { ABORT_ERROR, ABORT_EVENT } from './platform.js';
2
+ import { ABORT_ERROR, ABORT_EVENT } from '../core/platform.js';
3
3
  import { HttpStatus } from './wire.js';
4
4
  /**
5
5
  * Everything about a request failing that is not about what the request said.
@@ -1,4 +1,4 @@
1
- import { MS_PER_SECOND } from './platform.js';
1
+ import { MS_PER_SECOND } from '../core/platform.js';
2
2
  import { EndpointSilent } from './retry.js';
3
3
  import { DEFAULT_FENCES, FenceSplitter, SPLIT_REASONING } from './thinking.js';
4
4
  import { FUNCTION_TOOL } from './wire.js';
@@ -1,4 +1,4 @@
1
- import { isRecord } from './guards.js';
1
+ import { isRecord } from '../core/guards.js';
2
2
  import { THINK_FENCE } from './thinking.js';
3
3
  import { FinishReason, FUNCTION_TOOL } from './wire.js';
4
4
  /**