@cubicecho/agent-core 2.23.0 → 2.25.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 (71) hide show
  1. package/README.md +14 -9
  2. package/dist/agent-loop.d.ts +84 -204
  3. package/dist/agent-loop.js +416 -643
  4. package/dist/calibration.d.ts +14 -10
  5. package/dist/calibration.js +30 -22
  6. package/dist/capabilities.d.ts +140 -35
  7. package/dist/capabilities.js +345 -152
  8. package/dist/client.d.ts +104 -35
  9. package/dist/client.js +210 -78
  10. package/dist/compaction.d.ts +103 -60
  11. package/dist/compaction.js +163 -93
  12. package/dist/config.d.ts +48 -12
  13. package/dist/config.js +20 -1
  14. package/dist/continuation.d.ts +25 -17
  15. package/dist/continuation.js +70 -47
  16. package/dist/digest.d.ts +7 -0
  17. package/dist/digest.js +18 -0
  18. package/dist/errors.d.ts +24 -15
  19. package/dist/errors.js +23 -15
  20. package/dist/events.d.ts +108 -58
  21. package/dist/events.js +265 -128
  22. package/dist/guards.d.ts +53 -0
  23. package/dist/guards.js +55 -0
  24. package/dist/hook-events.d.ts +38 -0
  25. package/dist/hook-events.js +36 -0
  26. package/dist/hooks.d.ts +105 -83
  27. package/dist/hooks.js +224 -139
  28. package/dist/index.d.ts +30 -25
  29. package/dist/index.js +29 -23
  30. package/dist/ledger.d.ts +62 -30
  31. package/dist/ledger.js +163 -56
  32. package/dist/platform.d.ts +13 -0
  33. package/dist/platform.js +13 -0
  34. package/dist/preselect.d.ts +222 -0
  35. package/dist/preselect.js +290 -0
  36. package/dist/request-body.d.ts +32 -0
  37. package/dist/request-body.js +47 -0
  38. package/dist/reset.d.ts +1 -0
  39. package/dist/reset.js +7 -6
  40. package/dist/retry.d.ts +40 -143
  41. package/dist/retry.js +79 -285
  42. package/dist/run-calls.d.ts +123 -0
  43. package/dist/run-calls.js +351 -0
  44. package/dist/run-turn.d.ts +44 -16
  45. package/dist/run-turn.js +74 -37
  46. package/dist/runtime.d.ts +23 -17
  47. package/dist/runtime.js +34 -24
  48. package/dist/schema-compat.d.ts +51 -11
  49. package/dist/schema-compat.js +375 -193
  50. package/dist/scope.d.ts +28 -5
  51. package/dist/scope.js +37 -10
  52. package/dist/side-task.d.ts +127 -39
  53. package/dist/side-task.js +189 -100
  54. package/dist/snapshot.d.ts +12 -7
  55. package/dist/snapshot.js +87 -65
  56. package/dist/spec.d.ts +66 -36
  57. package/dist/spec.js +514 -265
  58. package/dist/stream.d.ts +73 -16
  59. package/dist/stream.js +228 -98
  60. package/dist/thinking.d.ts +23 -8
  61. package/dist/thinking.js +96 -46
  62. package/dist/tokens.d.ts +171 -6
  63. package/dist/tokens.js +326 -6
  64. package/dist/tool-calls.d.ts +89 -15
  65. package/dist/tool-calls.js +205 -85
  66. package/dist/tool-loading.d.ts +109 -187
  67. package/dist/tool-loading.js +286 -372
  68. package/dist/wire.d.ts +81 -0
  69. package/dist/wire.js +73 -0
  70. package/llms.txt +87 -43
  71. package/package.json +4 -4
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import OpenAI from "openai";
2
- import type { Endpoint } from "./config.ts";
1
+ import OpenAI from 'openai';
2
+ import type { Endpoint, EndpointIdentity, RetryPolicy } from './config.ts';
3
3
  /**
4
4
  * The SDK insists on a non-empty key even where the server will not look at it. This is what it
5
5
  * gets. It also reads as "this endpoint has no key" at a call site, which an empty string does
@@ -7,11 +7,25 @@ import type { Endpoint } from "./config.ts";
7
7
  */
8
8
  export declare const NO_KEY = "agent-core";
9
9
  /**
10
- * Zero, less, or absent means no limit, which the SDK spells as `undefined`.
10
+ * An endpoint's request timeout in the SDK's spelling: milliseconds, and `undefined` for no limit.
11
11
  *
12
- * @param config Read for `requestTimeoutSeconds` alone.
12
+ * @param config - Read for `requestTimeoutSeconds` alone. Zero, less, or absent means no limit.
13
+ * @returns The request timeout in milliseconds, or `undefined` for no limit.
13
14
  */
14
- export declare const timeoutMs: (config: Pick<Endpoint, "requestTimeoutSeconds">) => number | undefined;
15
+ export declare const timeoutMs: (config: Pick<Endpoint, 'requestTimeoutSeconds'>) => number | undefined;
16
+ /**
17
+ * How long to wait out a model that is still loading, in milliseconds — `undefined` where the
18
+ * config has no opinion, and zero where it says not to wait at all.
19
+ *
20
+ * @param config - Read for `loadingTimeoutSeconds` alone. Zero or less is no wait.
21
+ * @returns Milliseconds: `undefined` only where the field is absent, and zero where it is zero or
22
+ * less.
23
+ *
24
+ * @remarks
25
+ * Zero rather than the SDK's `undefined` for "no wait", because here absent already means
26
+ * something else: `runTurn`'s own default.
27
+ */
28
+ export declare const loadingMs: (config: Pick<RetryPolicy, 'loadingTimeoutSeconds'>) => number | undefined;
15
29
  /** What the client pool is held to across a process. Every field optional; see `configureClients`. */
16
30
  export interface ClientPoolOptions {
17
31
  /** How many endpoints' clients are kept at once. The least recently asked for goes first. */
@@ -27,6 +41,13 @@ export interface ClientPoolOptions {
27
41
  * Changes what the client pool is held to, for a process whose endpoints are not shaped like the
28
42
  * deployments these defaults were chosen for.
29
43
  *
44
+ * @param [options] - The bounds to change. A field left out — or given anything that is not a number
45
+ * above zero — keeps what it has, so a half-built config narrows nothing. `Infinity` is a number
46
+ * above zero: as `maxClients` it lifts the bound, and as `listingMissMs` a miss is never asked
47
+ * about again until `resetClients`.
48
+ * @returns Everything in force afterwards, including what this call did not change.
49
+ *
50
+ * @remarks
30
51
  * One setting per runtime for the same reason `configureEvents` is: the pool is one thing per
31
52
  * runtime, and its size is a deployment's setting, said once at startup. A multi-tenant host
32
53
  * keying on a key per user raises `maxClients` so its tenants stop evicting each other's
@@ -36,12 +57,6 @@ export interface ClientPoolOptions {
36
57
  * A `maxClients` below the pool's current size evicts down to it at once, least recently asked
37
58
  * for first, as the next `getClient` would have. A shorter `listingMissMs` applies to misses
38
59
  * already remembered, since each is a timestamp compared against it when read.
39
- *
40
- * @param options The bounds to change. A field left out — or given anything that is not a number
41
- * above zero — keeps what it has, so a half-built config narrows nothing. `Infinity` is a number
42
- * above zero: as `maxClients` it lifts the bound, and as `listingMissMs` a miss is never asked
43
- * about again until `resetClients`.
44
- * @returns Everything in force afterwards, including what this call did not change.
45
60
  */
46
61
  export declare function configureClients(options?: ClientPoolOptions): Required<ClientPoolOptions>;
47
62
  /** How many idle windows the first chunk gets when `firstTokenSeconds` is not given. */
@@ -49,12 +64,19 @@ export declare const FIRST_TOKEN_FACTOR = 5;
49
64
  /**
50
65
  * The wait for a streamed turn's first chunk, in the SDK's spelling: `undefined` is no limit.
51
66
  *
52
- * @param config Read for `firstTokenSeconds`, and `requestTimeoutSeconds` where that is absent.
67
+ * @param config - Read for `firstTokenSeconds`, and `requestTimeoutSeconds` where that is absent.
68
+ * @returns Milliseconds. `firstTokenSeconds` where it is given, zero or less being no limit;
69
+ * otherwise `FIRST_TOKEN_FACTOR` request timeouts, and no limit where the request has none.
53
70
  */
54
- export declare const firstTokenMs: (config: Pick<Endpoint, "requestTimeoutSeconds" | "firstTokenSeconds">) => number | undefined;
71
+ export declare const firstTokenMs: (config: Pick<Endpoint, 'requestTimeoutSeconds' | 'firstTokenSeconds'>) => number | undefined;
55
72
  /**
56
73
  * The client for an endpoint, built once and kept.
57
74
  *
75
+ * @param config - Where to send requests and how long to wait. An absent `apiKey` becomes `NO_KEY`.
76
+ * @returns The pooled client: the same object for the same base URL, key and timeout, until it is
77
+ * evicted or `resetClients` runs. Asking for it makes it the last in line to be evicted.
78
+ *
79
+ * @remarks
58
80
  * Pooled on the three fields that change how a request is sent, so agents sharing a server share
59
81
  * a connection and agents on different servers never share a client.
60
82
  *
@@ -64,13 +86,12 @@ export declare const firstTokenMs: (config: Pick<Endpoint, "requestTimeoutSecond
64
86
  * connection pools rather than sharing them and holding every one of them — `maxClients` keeps
65
87
  * that from being unbounded, and it is the point at which a client of your own, built and held
66
88
  * per tenant, is the better answer than this.
67
- *
68
- * @param config Where to send requests and how long to wait. An absent `apiKey` becomes `NO_KEY`.
69
89
  */
70
90
  export declare function getClient(config: Endpoint): OpenAI;
71
91
  /**
72
92
  * A model an endpoint offers, and what it says the model will read. Zero means it did not say.
73
93
  *
94
+ * @remarks
74
95
  * The number is whatever the listing carried, which from llama.cpp is the trained window rather
75
96
  * than the served one; `contextLimitFor` is the lookup that knows the difference.
76
97
  */
@@ -82,6 +103,13 @@ export interface ModelInfo {
82
103
  * What counts as one endpoint, everywhere in this package that has to remember something about
83
104
  * one — the model listings, `capabilities`, and the no-thinking hints in `side-task`.
84
105
  *
106
+ * @param config - Read for `baseUrl` and `apiKey` alone, and the key is optional here where
107
+ * `Endpoint` requires it — `capabilitiesFor` is handed a URL and maybe a key rather than a whole
108
+ * config, and absent and empty already mean the same thing. The timeout is deliberately not in
109
+ * it; see `listings`.
110
+ * @returns The URL and the key as one JSON string, the key in the clear.
111
+ *
112
+ * @remarks
85
113
  * The URL and the key together, because the key is part of what is on the other end rather than
86
114
  * only how it is paid for: a router is free to send two keys to two different backends, and then
87
115
  * what one of them refused is not a fact about the other. Absent reads as `NO_KEY`, so an
@@ -91,34 +119,41 @@ export interface ModelInfo {
91
119
  * is impossible in a URL or a key, and two endpoints must never collide on one entry. A host
92
120
  * keeping its own per-endpoint state keys it on this rather than on a copy of it, so the two
93
121
  * cannot drift apart. It holds the key in the clear; `endpointId` is the one to write down.
122
+ */
123
+ export declare const endpointKey: (config: EndpointIdentity) => string;
124
+ /**
125
+ * One model on one endpoint, as every per-model cache keys it: stringified, so neither half runs
126
+ * into the other.
94
127
  *
95
- * @param config Read for `baseUrl` and `apiKey` alone, and the key is optional here where
96
- * `Endpoint` requires it — `capabilitiesFor` is handed a URL and maybe a key rather than a whole
97
- * config, and absent and empty already mean the same thing. The timeout is deliberately not in
98
- * it; see `listings`.
128
+ * @param endpoint - Whatever the cache names an endpoint by — `endpointKey` here, `endpointId`
129
+ * where the key may be written down.
130
+ * @param model - The model's name as the endpoint knows it.
131
+ * @returns The pair as a JSON array, which `JSON.parse` takes apart again.
99
132
  */
100
- export declare const endpointKey: (config: {
101
- baseUrl: string;
102
- apiKey?: string;
103
- }) => string;
133
+ export declare const modelKey: (endpoint: string, model: string) => string;
104
134
  /**
105
135
  * `endpointKey` hashed, for the remembered facts that can leave the process.
106
136
  *
137
+ * @param config - Read for `baseUrl` and `apiKey` alone, as `endpointKey` reads it.
138
+ * @returns The digest of that endpoint's `endpointKey`: the same for the same URL and key in any
139
+ * process, and no key to be read out of it.
140
+ *
141
+ * @remarks
107
142
  * What an endpoint refused is exported by `exportCapabilities` to be written into a settings row
108
143
  * or a file, and a key inside that blob is a credential copied somewhere nobody meant to keep one.
109
144
  * A digest identifies the same endpoint on the next boot without saying what the key was, and it
110
145
  * is how a host finds its own endpoint's entry in a `CapabilitySnapshot`.
111
- *
112
- * @param config Read for `baseUrl` and `apiKey` alone, as `endpointKey` reads it.
113
146
  */
114
- export declare const endpointId: (config: {
115
- baseUrl: string;
116
- apiKey?: string;
117
- }) => string;
147
+ export declare const endpointId: (config: EndpointIdentity) => string;
118
148
  /**
119
149
  * The window a local server's own API says it is serving a model in, for the servers whose
120
150
  * listing does not say.
121
151
  *
152
+ * @param config - The endpoint, plus the model whose window is wanted.
153
+ * @returns The window in tokens, or zero where none was found. Never rejects: a server that could
154
+ * not be reached answers zero too.
155
+ *
156
+ * @remarks
122
157
  * llama.cpp reports it on `/props` as `default_generation_settings.n_ctx`, per slot, and LM
123
158
  * Studio on `/api/v0/models` as `loaded_context_length` while the model is loaded. Both differ
124
159
  * from the trained window in the case that matters, a model started in a smaller one than it was
@@ -131,8 +166,6 @@ export declare const endpointId: (config: {
131
166
  * other error. A server that could not be reached is not remembered at all.
132
167
  *
133
168
  * The listing is not read here; `contextLimitFor` reads it first and comes here after.
134
- *
135
- * @param config The endpoint, plus the model whose window is wanted.
136
169
  */
137
170
  export declare function servedWindow(config: Endpoint & {
138
171
  model: string;
@@ -140,12 +173,19 @@ export declare function servedWindow(config: Endpoint & {
140
173
  /**
141
174
  * Asks an endpoint what it serves, and remembers the answer.
142
175
  *
143
- * @param config The endpoint to ask. Remembered per base URL and key, not per model.
176
+ * @param config - The endpoint to ask. Remembered per base URL and key, not per model.
177
+ * @returns The models in order of id, whatever order the endpoint listed them in.
144
178
  */
145
179
  export declare function listModels(config: Endpoint): Promise<ModelInfo[]>;
146
180
  /**
147
181
  * How much a model will read, in tokens. Zero means nobody knows.
148
182
  *
183
+ * @param config - The endpoint, plus the model whose window is wanted.
184
+ * @param [declared] - The operator's own number. Above zero it wins and the endpoint is not asked.
185
+ * @returns The window in tokens, or zero. Never rejects: a listing or a native route that failed
186
+ * is an unknown window.
187
+ *
188
+ * @remarks
149
189
  * `declared` is the operator's own number, and it wins outright: an endpoint can report the
150
190
  * window a model was *built* with while serving it in a much smaller one — llama.cpp will
151
191
  * happily load a 256k model at `-c 16384` and go on listing it as 256k — and a run refused on
@@ -163,9 +203,6 @@ export declare function listModels(config: Endpoint): Promise<ModelInfo[]>;
163
203
  * are two more requests that a server stating its window in the listing never needed. Asked
164
204
  * first, they were also asked again every `listingMissMs` for the life of the process on a server
165
205
  * whose `/props` answers without a window, by any host that sizes the window per turn.
166
- *
167
- * @param config The endpoint, plus the model whose window is wanted.
168
- * @param declared The operator's own number. Above zero it wins and the endpoint is not asked.
169
206
  */
170
207
  export declare function contextLimitFor(config: Endpoint & {
171
208
  model: string;
@@ -175,3 +212,35 @@ export declare function contextLimitFor(config: Endpoint & {
175
212
  * tests, and for a settings change under test.
176
213
  */
177
214
  export declare function resetClients(): void;
215
+ /**
216
+ * A base URL as two settings rows would agree on it: trimmed, without the trailing slash.
217
+ *
218
+ * @param a - The URL as one row has it.
219
+ * @param b - The URL as the other has it.
220
+ * @returns `true` where the two differ in nothing but surrounding whitespace and trailing slashes.
221
+ * Case counts, and so does a `/v1`.
222
+ */
223
+ export declare const sameUrl: (a: string, b: string) => boolean;
224
+ /**
225
+ * The key to send, where an endpoint may inherit one from the settings it overrides.
226
+ *
227
+ * @param own - The endpoint as the agent or profile states it. Its own key always wins. An empty or
228
+ * absent `baseUrl` is one that inherits the endpoint too.
229
+ * @param [inherited] - The settings it overrides. Absent treats `own` as the configured endpoint, so
230
+ * only its key and the environment's are in play.
231
+ * @param [env] - Where `OPENAI_API_KEY` is read from.
232
+ * @returns The key, never empty: `own`'s, else `NO_KEY` for an endpoint other than the inherited
233
+ * one, else the inherited key, then the environment's, then `NO_KEY`.
234
+ *
235
+ * @remarks
236
+ * A credential issued for one endpoint has no business being posted to another. A profile that
237
+ * names its own `baseUrl` and no key of its own is sent `NO_KEY` — not the operator's key, and
238
+ * not `$OPENAI_API_KEY` — because "I pointed an agent at a friend's server and it sent my OpenAI
239
+ * key" is not a mistake worth being able to make, and a local server wants no key anyway. One on
240
+ * the same endpoint inherits the key as it inherits everything else, and the environment is the
241
+ * last word on the endpoint that was configured rather than overridden.
242
+ */
243
+ export declare function resolveApiKey(own: {
244
+ baseUrl?: string;
245
+ apiKey?: string;
246
+ }, inherited?: EndpointIdentity, env?: Record<string, string | undefined>): string;