@cerebro-labs/agentnava-sdk 0.26.0 → 0.44.1

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 (62) hide show
  1. package/README.md +204 -23
  2. package/account.d.ts +154 -0
  3. package/account.js +219 -0
  4. package/account.js.map +1 -0
  5. package/agent.d.ts +217 -88
  6. package/agent.js +295 -125
  7. package/agent.js.map +1 -1
  8. package/apps.generated.d.ts +154 -0
  9. package/apps.generated.js +152 -0
  10. package/apps.generated.js.map +1 -0
  11. package/attach.d.ts +25 -26
  12. package/attach.js +53 -66
  13. package/attach.js.map +1 -1
  14. package/connection.d.ts +79 -82
  15. package/connection.js +67 -134
  16. package/connection.js.map +1 -1
  17. package/conversation.d.ts +55 -35
  18. package/conversation.js +70 -50
  19. package/conversation.js.map +1 -1
  20. package/database.d.ts +53 -0
  21. package/database.js +69 -0
  22. package/database.js.map +1 -0
  23. package/end-user.d.ts +58 -47
  24. package/end-user.js +62 -72
  25. package/end-user.js.map +1 -1
  26. package/errors.d.ts +2 -1
  27. package/errors.js +2 -1
  28. package/errors.js.map +1 -1
  29. package/http.d.ts +5 -0
  30. package/http.js +109 -8
  31. package/http.js.map +1 -1
  32. package/import-tools.d.ts +48 -33
  33. package/import-tools.js +281 -127
  34. package/import-tools.js.map +1 -1
  35. package/index.d.ts +5 -2
  36. package/index.js +9 -2
  37. package/index.js.map +1 -1
  38. package/load-agent-dir.js +28 -5
  39. package/load-agent-dir.js.map +1 -1
  40. package/package.json +5 -1
  41. package/secret.d.ts +1 -1
  42. package/secret.js +1 -1
  43. package/secret.js.map +1 -1
  44. package/templates-inline.js +1 -1
  45. package/templates-inline.js.map +1 -1
  46. package/turn.d.ts +1 -1
  47. package/turn.js +77 -29
  48. package/turn.js.map +1 -1
  49. package/types.d.ts +409 -83
  50. package/types.js.map +1 -1
  51. package/version.d.ts +1 -1
  52. package/version.js +1 -1
  53. package/version.js.map +1 -1
  54. package/workflows.d.ts +10 -0
  55. package/workflows.js +16 -0
  56. package/workflows.js.map +1 -1
  57. package/workspace.d.ts +80 -62
  58. package/workspace.js +92 -75
  59. package/workspace.js.map +1 -1
  60. package/connection-status.d.ts +0 -28
  61. package/connection-status.js +0 -61
  62. package/connection-status.js.map +0 -1
package/http.js CHANGED
@@ -85,6 +85,8 @@ export class Http {
85
85
  Authorization: `Bearer ${this.#apiKey}`,
86
86
  [CLIENT_HEADER]: CLIENT_ID,
87
87
  };
88
+ if (options.idempotencyKey)
89
+ headers['Idempotency-Key'] = options.idempotencyKey;
88
90
  let body;
89
91
  if (options.bytes !== undefined) {
90
92
  body = options.bytes;
@@ -98,10 +100,18 @@ export class Http {
98
100
  // AbortSignal.any is too new to rely on across every runtime this ships to.
99
101
  const controller = new AbortController();
100
102
  const timer = setTimeout(() => controller.abort(), this.#timeout);
101
- const onAbort = () => controller.abort();
102
- options.signal?.addEventListener('abort', onAbort, { once: true });
103
+ const onAbort = () => controller.abort(options.signal?.reason);
104
+ const releaseSignal = () => options.signal?.removeEventListener('abort', onAbort);
105
+ if (options.signal?.aborted)
106
+ onAbort();
107
+ else
108
+ options.signal?.addEventListener('abort', onAbort, { once: true });
103
109
  let res;
104
110
  try {
111
+ // Do not invoke even a custom fetch for a request already cancelled.
112
+ // Such a fetch may not itself honor an already-aborted signal.
113
+ if (controller.signal.aborted)
114
+ throw controller.signal.reason;
105
115
  res = await this.#doFetch(this.url(path, options.query), {
106
116
  method: options.method ?? 'GET',
107
117
  headers,
@@ -110,18 +120,28 @@ export class Http {
110
120
  });
111
121
  }
112
122
  catch (err) {
123
+ releaseSignal();
113
124
  if (options.signal?.aborted)
114
125
  throw err;
115
- throw networkError(controller.signal.aborted
126
+ const failure = networkError(controller.signal.aborted
116
127
  ? `Request to ${path} timed out after ${this.#timeout}ms`
117
128
  : `Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`, err);
129
+ if (options.idempotencyKey) {
130
+ throw new AgentNavaError({
131
+ message: `${failure.message} The turn may have been accepted. ${turnRecoveryMessage(path, options.idempotencyKey)}`,
132
+ code: 'network_error', status: 0,
133
+ });
134
+ }
135
+ throw failure;
118
136
  }
119
137
  finally {
120
138
  clearTimeout(timer);
121
- options.signal?.removeEventListener('abort', onAbort);
122
139
  }
140
+ // Headers end the connection timeout, not the caller's right to stop
141
+ // reading. Keep forwarding cancellation for the lifetime of the body.
142
+ res = responseUntilConsumed(res, releaseSignal, (reason) => controller.abort(reason));
123
143
  if (!res.ok)
124
- throw await toError(res, path);
144
+ throw await toError(res, path, options.idempotencyKey);
125
145
  return res;
126
146
  }
127
147
  async request(path, options = {}) {
@@ -150,6 +170,9 @@ export class Http {
150
170
  post(path, body, query) {
151
171
  return this.request(path, { method: 'POST', body, ...(query && { query }) });
152
172
  }
173
+ put(path, body) {
174
+ return this.request(path, { method: 'PUT', body });
175
+ }
153
176
  patch(path, body) {
154
177
  return this.request(path, { method: 'PATCH', body });
155
178
  }
@@ -157,10 +180,77 @@ export class Http {
157
180
  return this.request(path, { method: 'DELETE', ...(query && { query }) });
158
181
  }
159
182
  }
183
+ /** Dispose the caller's abort listener after EOF, failure or cancellation.
184
+ * Http.send is internal: callers consume status, headers and body, so wrapping
185
+ * the body preserves the values the SDK exposes without buffering a stream. */
186
+ function responseUntilConsumed(response, releaseSignal, abortFetch) {
187
+ if (!response.body) {
188
+ releaseSignal();
189
+ return response;
190
+ }
191
+ const reader = response.body.getReader();
192
+ let finished = false;
193
+ let released = false;
194
+ const release = () => {
195
+ if (released)
196
+ return;
197
+ released = true;
198
+ releaseSignal();
199
+ // Cancellation settles pending reads before lock release, even when the
200
+ // underlying source's cleanup promise has not settled.
201
+ try {
202
+ reader.releaseLock();
203
+ }
204
+ catch { /* cleanup preserves the original result */ }
205
+ };
206
+ return new Response(new ReadableStream({
207
+ async pull(controller) {
208
+ try {
209
+ const { done, value } = await reader.read();
210
+ if (finished)
211
+ return;
212
+ if (done) {
213
+ finished = true;
214
+ release();
215
+ controller.close();
216
+ }
217
+ else
218
+ controller.enqueue(value);
219
+ }
220
+ catch (error) {
221
+ if (finished)
222
+ return;
223
+ finished = true;
224
+ release();
225
+ controller.error(error);
226
+ }
227
+ },
228
+ cancel(reason) {
229
+ if (finished)
230
+ return;
231
+ finished = true;
232
+ // Bun can leave a real fetch socket open after reader.cancel(). Abort
233
+ // the transport as well, including requests with no caller signal.
234
+ abortFetch(reason);
235
+ try {
236
+ void reader.cancel(reason).catch(() => { });
237
+ }
238
+ catch { /* a custom reader may throw synchronously during cleanup */ }
239
+ finally {
240
+ release();
241
+ }
242
+ },
243
+ }, { highWaterMark: 0 }), {
244
+ status: response.status,
245
+ statusText: response.statusText,
246
+ headers: response.headers,
247
+ });
248
+ }
160
249
  /** Turn a failed Response into the one error type this SDK throws. */
161
- async function toError(res, path) {
250
+ async function toError(res, path, idempotencyKey) {
162
251
  let message = `${res.status} from ${path}`;
163
252
  let code = `http_${res.status}`;
253
+ let retryable;
164
254
  try {
165
255
  const text = await res.text();
166
256
  if (text) {
@@ -169,6 +259,8 @@ async function toError(res, path) {
169
259
  message = parsed.message ?? parsed.error ?? text.slice(0, 300);
170
260
  if (parsed.code)
171
261
  code = parsed.code;
262
+ if (parsed.retryable === false)
263
+ retryable = false;
172
264
  }
173
265
  catch {
174
266
  message = text.slice(0, 300);
@@ -181,12 +273,21 @@ async function toError(res, path) {
181
273
  const retryAfterHeader = res.headers.get('retry-after');
182
274
  const retryAfter = retryAfterHeader ? Number(retryAfterHeader) : undefined;
183
275
  const requestId = res.headers.get('x-request-id') ?? undefined;
184
- return new AgentNavaError({
185
- message,
276
+ const failure = new AgentNavaError({
277
+ message: idempotencyKey ? `${message} ${turnRecoveryMessage(path, idempotencyKey)}` : message,
186
278
  code,
187
279
  status: res.status,
188
280
  ...(retryAfter !== undefined && Number.isFinite(retryAfter) && { retryAfter }),
189
281
  ...(requestId !== undefined && { requestId }),
190
282
  });
283
+ // An uncertain handoff can be HTTP 503 while already owning accepted work.
284
+ // Respect the server's refusal to retry instead of creating a second turn.
285
+ if (retryable === false || (idempotencyKey && res.status >= 500))
286
+ Object.defineProperty(failure, 'retryable', { value: false, enumerable: true });
287
+ return failure;
288
+ }
289
+ /** Kept in errors because a dropped response may not have returned a turn ID. */
290
+ export function turnRecoveryMessage(path, idempotencyKey) {
291
+ return `Check the conversation before starting another turn. To check status, POST the original body to ${path} with the same authorization, Idempotency-Key: ${idempotencyKey} and X-Turn-Status: true.`;
191
292
  }
192
293
  //# sourceMappingURL=http.js.map
package/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["// The transport. Everything else in this SDK is objects and method names.\n\nimport { AgentNavaError, networkError } from './errors.ts';\nimport { SDK_VERSION } from './version.ts';\n\nexport interface ClientOptions {\n\t/** Defaults to `AGENTNAVA_API_KEY` from the environment. */\n\tapiKey?: string;\n\t/** Defaults to `https://api.agentnava.com`. */\n\tbaseURL?: string;\n\t/** Per-request timeout in milliseconds. Default 60_000. */\n\ttimeout?: number;\n\t/** Swap the fetch implementation, for tests or a proxy. */\n\tfetch?: typeof globalThis.fetch;\n}\n\n/** Tells the server which SDK is calling, on every request.\n *\n * WHY A CUSTOM HEADER AND NOT `User-Agent`. `User-Agent` is on the fetch\n * spec's forbidden-header list, so a browser DROPS it SILENTLY: the request\n * still goes, the header just is not there, and the server sees a client of\n * unknown age with nothing to indicate anything went wrong. A header we name\n * ourselves is sent by every runtime the same way. `X-AgentNava-User-Id`\n * already exists on this API, so the shape is not new.\n *\n * WHAT IT IS FOR. Not gating: the server does not refuse an old client on\n * sight. It is so the question \"who would break if we removed this field\"\n * has an answer that is a query rather than a guess. Once the package is on\n * a public registry, a customer can pin 0.25.0 and still be calling in three\n * years, and we have no other way to know they exist.\n *\n * The runtime note is best-effort and deliberately coarse. It separates Node\n * from Bun from a browser, which is the distinction that explains most\n * support questions, and carries nothing identifying. */\nconst CLIENT_HEADER = 'X-AgentNava-Client';\n\nfunction runtimeTag(): string {\n\tconst g = globalThis as {\n\t\tBun?: { version?: string };\n\t\tprocess?: { versions?: { node?: string } };\n\t\tdocument?: unknown;\n\t};\n\tif (g.Bun?.version) return `bun/${g.Bun.version}`;\n\tif (g.process?.versions?.node) return `node/${g.process.versions.node}`;\n\tif (g.document !== undefined) return 'browser';\n\treturn 'unknown';\n}\n\n/** `agentnava-sdk/0.25.0 (node/22.20.0)`. Computed once: it cannot change\n * within a process, and rebuilding it per request buys nothing. */\nconst CLIENT_ID = `agentnava-sdk/${SDK_VERSION} (${runtimeTag()})`;\n\nconst DEFAULT_BASE_URL = 'https://api.agentnava.com';\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\n/** Read a variable without assuming which runtime we are on.\n *\n * This SDK runs in Node, Bun, Deno, Workers and a browser bundle. `process` is\n * absent in several of those and touching it throws rather than returning\n * undefined, so the access is guarded rather than defaulted. */\nfunction readEnv(name: string): string | undefined {\n\ttry {\n\t\tconst proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n\t\treturn proc?.env?.[name];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport interface RequestOptions {\n\tmethod?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n\t/** Sent as a JSON body. Mutually exclusive with `bytes`. */\n\tbody?: unknown;\n\t/** Sent as the raw body, for file writes. Mutually exclusive with `body`. */\n\tbytes?: ArrayBuffer | Uint8Array;\n\tcontentType?: string;\n\tquery?: Record<string, string | number | boolean | undefined>;\n\t/* THERE IS DELIBERATELY NO `raw` FLAG.\n\t *\n\t * One was declared here, described as \"return the Response untouched\", and\n\t * read by nothing. `request` parses JSON unconditionally, so every caller\n\t * that asked for `raw: true` got a parsed body and then called `.text()` or\n\t * `.arrayBuffer()` on it. `kb.files.text()` and `kb.files.get()` were broken\n\t * for every developer from the day they shipped, and the flag is why: it made\n\t * the call site look correct.\n\t *\n\t * Use `send()` for a Response and `request<T>()` for parsed JSON. Two methods\n\t * that differ by return type cannot be confused the way one method with a\n\t * boolean can. */\n\tsignal?: AbortSignal;\n}\n\nexport class Http {\n\treadonly #apiKey: string;\n\treadonly #baseURL: string;\n\treadonly #timeout: number;\n\treadonly #doFetch: typeof globalThis.fetch;\n\n\tconstructor(options: ClientOptions = {}) {\n\t\tconst key = options.apiKey ?? readEnv('AGENTNAVA_API_KEY');\n\t\t// Thrown at construction, not at the first call. A missing key is a\n\t\t// configuration mistake, and finding it three layers into an async call\n\t\t// stack makes it look like the call was at fault.\n\t\tif (!key) {\n\t\t\tthrow new AgentNavaError({\n\t\t\t\tmessage:\n\t\t\t\t\t'No API key. Pass `AgentNava.getWorkspace({ apiKey })` or set AGENTNAVA_API_KEY in the environment.',\n\t\t\t\tcode: 'no_api_key',\n\t\t\t\tstatus: 401,\n\t\t\t});\n\t\t}\n\t\tthis.#apiKey = key;\n\t\tthis.#baseURL = (options.baseURL ?? readEnv('AGENTNAVA_BASE_URL') ?? DEFAULT_BASE_URL).replace(\n\t\t\t/\\/+$/,\n\t\t\t'',\n\t\t);\n\t\tthis.#timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.#doFetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\tprivate url(path: string, query?: RequestOptions['query']): string {\n\t\tconst url = new URL(this.#baseURL + path);\n\t\tfor (const [k, v] of Object.entries(query ?? {})) {\n\t\t\tif (v !== undefined) url.searchParams.set(k, String(v));\n\t\t}\n\t\treturn url.toString();\n\t}\n\n\t/** Make the request and hand back the raw Response, errors already thrown. */\n\tasync send(path: string, options: RequestOptions = {}): Promise<Response> {\n\t\tconst headers: Record<string, string> = {\n\t\t\tAuthorization: `Bearer ${this.#apiKey}`,\n\t\t\t[CLIENT_HEADER]: CLIENT_ID,\n\t\t};\n\t\tlet body: BodyInit | undefined;\n\t\tif (options.bytes !== undefined) {\n\t\t\tbody = options.bytes as BodyInit;\n\t\t\theaders['Content-Type'] = options.contentType ?? 'application/octet-stream';\n\t\t} else if (options.body !== undefined) {\n\t\t\tbody = JSON.stringify(options.body);\n\t\t\theaders['Content-Type'] = 'application/json';\n\t\t}\n\n\t\t// The caller's signal and our timeout both have to be able to abort, and\n\t\t// AbortSignal.any is too new to rely on across every runtime this ships to.\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), this.#timeout);\n\t\tconst onAbort = () => controller.abort();\n\t\toptions.signal?.addEventListener('abort', onAbort, { once: true });\n\n\t\tlet res: Response;\n\t\ttry {\n\t\t\tres = await this.#doFetch(this.url(path, options.query), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders,\n\t\t\t\t...(body !== undefined && { body }),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (options.signal?.aborted) throw err;\n\t\t\tthrow networkError(\n\t\t\t\tcontroller.signal.aborted\n\t\t\t\t\t? `Request to ${path} timed out after ${this.#timeout}ms`\n\t\t\t\t\t: `Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\terr,\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t\toptions.signal?.removeEventListener('abort', onAbort);\n\t\t}\n\n\t\tif (!res.ok) throw await toError(res, path);\n\t\treturn res;\n\t}\n\n\tasync request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n\t\tconst res = await this.send(path, options);\n\t\t// 204, and any other empty body, is a successful nothing rather than a\n\t\t// JSON parse error.\n\t\tif (res.status === 204) return undefined as T;\n\t\tconst text = await res.text();\n\t\tif (text.length === 0) return undefined as T;\n\t\ttry {\n\t\t\treturn JSON.parse(text) as T;\n\t\t} catch {\n\t\t\tthrow new AgentNavaError({\n\t\t\t\tmessage: `Expected JSON from ${path}, got: ${text.slice(0, 200)}`,\n\t\t\t\tcode: 'bad_response',\n\t\t\t\tstatus: res.status,\n\t\t\t});\n\t\t}\n\t}\n\n\tget<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'GET', ...(query && { query }) });\n\t}\n\tpost<T>(path: string, body?: unknown, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'POST', body, ...(query && { query }) });\n\t}\n\tpatch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'PATCH', body });\n\t}\n\tdelete<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'DELETE', ...(query && { query }) });\n\t}\n}\n\n/** Turn a failed Response into the one error type this SDK throws. */\nasync function toError(res: Response, path: string): Promise<AgentNavaError> {\n\tlet message = `${res.status} from ${path}`;\n\tlet code = `http_${res.status}`;\n\ttry {\n\t\tconst text = await res.text();\n\t\tif (text) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(text) as { message?: string; code?: string; error?: string };\n\t\t\t\tmessage = parsed.message ?? parsed.error ?? text.slice(0, 300);\n\t\t\t\tif (parsed.code) code = parsed.code;\n\t\t\t} catch {\n\t\t\t\tmessage = text.slice(0, 300);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// A body we cannot read is not worth failing over; the status still is.\n\t}\n\n\tconst retryAfterHeader = res.headers.get('retry-after');\n\tconst retryAfter = retryAfterHeader ? Number(retryAfterHeader) : undefined;\n\tconst requestId = res.headers.get('x-request-id') ?? undefined;\n\n\treturn new AgentNavaError({\n\t\tmessage,\n\t\tcode,\n\t\tstatus: res.status,\n\t\t...(retryAfter !== undefined && Number.isFinite(retryAfter) && { retryAfter }),\n\t\t...(requestId !== undefined && { requestId }),\n\t});\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["// The transport. Everything else in this SDK is objects and method names.\n\nimport { AgentNavaError, networkError } from './errors.ts';\nimport { SDK_VERSION } from './version.ts';\n\nexport interface ClientOptions {\n\t/** Defaults to `AGENTNAVA_API_KEY` from the environment. */\n\tapiKey?: string;\n\t/** Defaults to `https://api.agentnava.com`. */\n\tbaseURL?: string;\n\t/** Per-request timeout in milliseconds. Default 60_000. */\n\ttimeout?: number;\n\t/** Swap the fetch implementation, for tests or a proxy. */\n\tfetch?: typeof globalThis.fetch;\n}\n\n/** Tells the server which SDK is calling, on every request.\n *\n * WHY A CUSTOM HEADER AND NOT `User-Agent`. `User-Agent` is on the fetch\n * spec's forbidden-header list, so a browser DROPS it SILENTLY: the request\n * still goes, the header just is not there, and the server sees a client of\n * unknown age with nothing to indicate anything went wrong. A header we name\n * ourselves is sent by every runtime the same way. `X-AgentNava-User-Id`\n * already exists on this API, so the shape is not new.\n *\n * WHAT IT IS FOR. Not gating: the server does not refuse an old client on\n * sight. It is so the question \"who would break if we removed this field\"\n * has an answer that is a query rather than a guess. Once the package is on\n * a public registry, a customer can pin 0.25.0 and still be calling in three\n * years, and we have no other way to know they exist.\n *\n * The runtime note is best-effort and deliberately coarse. It separates Node\n * from Bun from a browser, which is the distinction that explains most\n * support questions, and carries nothing identifying. */\nconst CLIENT_HEADER = 'X-AgentNava-Client';\n\nfunction runtimeTag(): string {\n\tconst g = globalThis as {\n\t\tBun?: { version?: string };\n\t\tprocess?: { versions?: { node?: string } };\n\t\tdocument?: unknown;\n\t};\n\tif (g.Bun?.version) return `bun/${g.Bun.version}`;\n\tif (g.process?.versions?.node) return `node/${g.process.versions.node}`;\n\tif (g.document !== undefined) return 'browser';\n\treturn 'unknown';\n}\n\n/** `agentnava-sdk/0.25.0 (node/22.20.0)`. Computed once: it cannot change\n * within a process, and rebuilding it per request buys nothing. */\nconst CLIENT_ID = `agentnava-sdk/${SDK_VERSION} (${runtimeTag()})`;\n\nconst DEFAULT_BASE_URL = 'https://api.agentnava.com';\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\n/** Read a variable without assuming which runtime we are on.\n *\n * This SDK runs in Node, Bun, Deno, Workers and a browser bundle. `process` is\n * absent in several of those and touching it throws rather than returning\n * undefined, so the access is guarded rather than defaulted. */\nfunction readEnv(name: string): string | undefined {\n\ttry {\n\t\tconst proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n\t\treturn proc?.env?.[name];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport interface RequestOptions {\n\tmethod?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n\t/** Internal turn submission identity, minted once by Conversation.ask. */\n\tidempotencyKey?: string;\n\t/** Sent as a JSON body. Mutually exclusive with `bytes`. */\n\tbody?: unknown;\n\t/** Sent as the raw body, for file writes. Mutually exclusive with `body`. */\n\tbytes?: ArrayBuffer | Uint8Array;\n\tcontentType?: string;\n\tquery?: Record<string, string | number | boolean | undefined>;\n\t/* THERE IS DELIBERATELY NO `raw` FLAG.\n\t *\n\t * One was declared here, described as \"return the Response untouched\", and\n\t * read by nothing. `request` parses JSON unconditionally, so every caller\n\t * that asked for `raw: true` got a parsed body and then called `.text()` or\n\t * `.arrayBuffer()` on it. `kb.files.text()` and `kb.files.get()` were broken\n\t * for every developer from the day they shipped, and the flag is why: it made\n\t * the call site look correct.\n\t *\n\t * Use `send()` for a Response and `request<T>()` for parsed JSON. Two methods\n\t * that differ by return type cannot be confused the way one method with a\n\t * boolean can. */\n\tsignal?: AbortSignal;\n}\n\nexport class Http {\n\treadonly #apiKey: string;\n\treadonly #baseURL: string;\n\treadonly #timeout: number;\n\treadonly #doFetch: typeof globalThis.fetch;\n\n\tconstructor(options: ClientOptions = {}) {\n\t\tconst key = options.apiKey ?? readEnv('AGENTNAVA_API_KEY');\n\t\t// Thrown at construction, not at the first call. A missing key is a\n\t\t// configuration mistake, and finding it three layers into an async call\n\t\t// stack makes it look like the call was at fault.\n\t\tif (!key) {\n\t\t\tthrow new AgentNavaError({\n\t\t\t\tmessage:\n\t\t\t\t\t'No API key. Pass `AgentNava.getWorkspace({ apiKey })` or set AGENTNAVA_API_KEY in the environment.',\n\t\t\t\tcode: 'no_api_key',\n\t\t\t\tstatus: 401,\n\t\t\t});\n\t\t}\n\t\tthis.#apiKey = key;\n\t\tthis.#baseURL = (options.baseURL ?? readEnv('AGENTNAVA_BASE_URL') ?? DEFAULT_BASE_URL).replace(\n\t\t\t/\\/+$/,\n\t\t\t'',\n\t\t);\n\t\tthis.#timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.#doFetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n\t}\n\n\tprivate url(path: string, query?: RequestOptions['query']): string {\n\t\tconst url = new URL(this.#baseURL + path);\n\t\tfor (const [k, v] of Object.entries(query ?? {})) {\n\t\t\tif (v !== undefined) url.searchParams.set(k, String(v));\n\t\t}\n\t\treturn url.toString();\n\t}\n\n\t/** Make the request and hand back the raw Response, errors already thrown. */\n\tasync send(path: string, options: RequestOptions = {}): Promise<Response> {\n\t\tconst headers: Record<string, string> = {\n\t\t\tAuthorization: `Bearer ${this.#apiKey}`,\n\t\t\t[CLIENT_HEADER]: CLIENT_ID,\n\t\t};\n\t\tif (options.idempotencyKey) headers['Idempotency-Key'] = options.idempotencyKey;\n\t\tlet body: BodyInit | undefined;\n\t\tif (options.bytes !== undefined) {\n\t\t\tbody = options.bytes as BodyInit;\n\t\t\theaders['Content-Type'] = options.contentType ?? 'application/octet-stream';\n\t\t} else if (options.body !== undefined) {\n\t\t\tbody = JSON.stringify(options.body);\n\t\t\theaders['Content-Type'] = 'application/json';\n\t\t}\n\n\t\t// The caller's signal and our timeout both have to be able to abort, and\n\t\t// AbortSignal.any is too new to rely on across every runtime this ships to.\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), this.#timeout);\n\t\tconst onAbort = () => controller.abort(options.signal?.reason);\n\t\tconst releaseSignal = () => options.signal?.removeEventListener('abort', onAbort);\n\t\tif (options.signal?.aborted) onAbort();\n\t\telse options.signal?.addEventListener('abort', onAbort, { once: true });\n\n\t\tlet res: Response;\n\t\ttry {\n\t\t\t// Do not invoke even a custom fetch for a request already cancelled.\n\t\t\t// Such a fetch may not itself honor an already-aborted signal.\n\t\t\tif (controller.signal.aborted) throw controller.signal.reason;\n\t\t\tres = await this.#doFetch(this.url(path, options.query), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders,\n\t\t\t\t...(body !== undefined && { body }),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\treleaseSignal();\n\t\t\tif (options.signal?.aborted) throw err;\n\t\t\tconst failure = networkError(\n\t\t\t\tcontroller.signal.aborted\n\t\t\t\t\t? `Request to ${path} timed out after ${this.#timeout}ms`\n\t\t\t\t\t: `Request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\terr,\n\t\t\t);\n\t\t\tif (options.idempotencyKey) {\n\t\t\t\tthrow new AgentNavaError({\n\t\t\t\t\tmessage: `${failure.message} The turn may have been accepted. ${turnRecoveryMessage(path, options.idempotencyKey)}`,\n\t\t\t\t\tcode: 'network_error', status: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthrow failure;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\n\t\t// Headers end the connection timeout, not the caller's right to stop\n\t\t// reading. Keep forwarding cancellation for the lifetime of the body.\n\t\tres = responseUntilConsumed(res, releaseSignal, (reason) => controller.abort(reason));\n\t\tif (!res.ok) throw await toError(res, path, options.idempotencyKey);\n\t\treturn res;\n\t}\n\n\tasync request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n\t\tconst res = await this.send(path, options);\n\t\t// 204, and any other empty body, is a successful nothing rather than a\n\t\t// JSON parse error.\n\t\tif (res.status === 204) return undefined as T;\n\t\tconst text = await res.text();\n\t\tif (text.length === 0) return undefined as T;\n\t\ttry {\n\t\t\treturn JSON.parse(text) as T;\n\t\t} catch {\n\t\t\tthrow new AgentNavaError({\n\t\t\t\tmessage: `Expected JSON from ${path}, got: ${text.slice(0, 200)}`,\n\t\t\t\tcode: 'bad_response',\n\t\t\t\tstatus: res.status,\n\t\t\t});\n\t\t}\n\t}\n\n\tget<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'GET', ...(query && { query }) });\n\t}\n\tpost<T>(path: string, body?: unknown, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'POST', body, ...(query && { query }) });\n\t}\n\tput<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'PUT', body });\n\t}\n\tpatch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'PATCH', body });\n\t}\n\tdelete<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n\t\treturn this.request<T>(path, { method: 'DELETE', ...(query && { query }) });\n\t}\n}\n\n/** Dispose the caller's abort listener after EOF, failure or cancellation.\n * Http.send is internal: callers consume status, headers and body, so wrapping\n * the body preserves the values the SDK exposes without buffering a stream. */\nfunction responseUntilConsumed(\n\tresponse: Response,\n\treleaseSignal: () => void,\n\tabortFetch: (reason?: unknown) => void,\n): Response {\n\tif (!response.body) {\n\t\treleaseSignal();\n\t\treturn response;\n\t}\n\tconst reader = response.body.getReader();\n\tlet finished = false;\n\tlet released = false;\n\tconst release = () => {\n\t\tif (released) return;\n\t\treleased = true;\n\t\treleaseSignal();\n\t\t// Cancellation settles pending reads before lock release, even when the\n\t\t// underlying source's cleanup promise has not settled.\n\t\ttry { reader.releaseLock(); } catch { /* cleanup preserves the original result */ }\n\t};\n\treturn new Response(new ReadableStream<Uint8Array>({\n\t\tasync pull(controller) {\n\t\t\ttry {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (finished) return;\n\t\t\t\tif (done) {\n\t\t\t\t\tfinished = true;\n\t\t\t\t\trelease();\n\t\t\t\t\tcontroller.close();\n\t\t\t\t} else controller.enqueue(value);\n\t\t\t} catch (error) {\n\t\t\t\tif (finished) return;\n\t\t\t\tfinished = true;\n\t\t\t\trelease();\n\t\t\t\tcontroller.error(error);\n\t\t\t}\n\t\t},\n\t\tcancel(reason) {\n\t\t\tif (finished) return;\n\t\t\tfinished = true;\n\t\t\t// Bun can leave a real fetch socket open after reader.cancel(). Abort\n\t\t\t// the transport as well, including requests with no caller signal.\n\t\t\tabortFetch(reason);\n\t\t\ttry {\n\t\t\t\tvoid reader.cancel(reason).catch(() => {});\n\t\t\t} catch { /* a custom reader may throw synchronously during cleanup */ }\n\t\t\tfinally { release(); }\n\t\t},\n\t}, { highWaterMark: 0 }), {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders: response.headers,\n\t});\n}\n\n/** Turn a failed Response into the one error type this SDK throws. */\nasync function toError(res: Response, path: string, idempotencyKey?: string): Promise<AgentNavaError> {\n\tlet message = `${res.status} from ${path}`;\n\tlet code = `http_${res.status}`;\n\tlet retryable: boolean | undefined;\n\ttry {\n\t\tconst text = await res.text();\n\t\tif (text) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(text) as { message?: string; code?: string; error?: string; retryable?: boolean };\n\t\t\t\tmessage = parsed.message ?? parsed.error ?? text.slice(0, 300);\n\t\t\t\tif (parsed.code) code = parsed.code;\n\t\t\t\tif (parsed.retryable === false) retryable = false;\n\t\t\t} catch {\n\t\t\t\tmessage = text.slice(0, 300);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// A body we cannot read is not worth failing over; the status still is.\n\t}\n\n\tconst retryAfterHeader = res.headers.get('retry-after');\n\tconst retryAfter = retryAfterHeader ? Number(retryAfterHeader) : undefined;\n\tconst requestId = res.headers.get('x-request-id') ?? undefined;\n\n\tconst failure = new AgentNavaError({\n\t\tmessage: idempotencyKey ? `${message} ${turnRecoveryMessage(path, idempotencyKey)}` : message,\n\t\tcode,\n\t\tstatus: res.status,\n\t\t...(retryAfter !== undefined && Number.isFinite(retryAfter) && { retryAfter }),\n\t\t...(requestId !== undefined && { requestId }),\n\t});\n\t// An uncertain handoff can be HTTP 503 while already owning accepted work.\n\t// Respect the server's refusal to retry instead of creating a second turn.\n\tif (retryable === false || (idempotencyKey && res.status >= 500)) Object.defineProperty(failure, 'retryable', { value: false, enumerable: true });\n\treturn failure;\n}\n\n/** Kept in errors because a dropped response may not have returned a turn ID. */\nexport function turnRecoveryMessage(path: string, idempotencyKey: string): string {\n\treturn `Check the conversation before starting another turn. To check status, POST the original body to ${path} with the same authorization, Idempotency-Key: ${idempotencyKey} and X-Turn-Status: true.`;\n}\n"]}
package/import-tools.d.ts CHANGED
@@ -14,7 +14,7 @@ export type ImportWarningKind =
14
14
  /** Two endpoints produced the same tool name. */
15
15
  | 'name-collision'
16
16
  /** A parameter was renamed to something the API will accept. */
17
- | 'param-renamed';
17
+ | 'param-renamed' | 'unsupported-operation' | 'security-choice';
18
18
  export interface ImportWarning {
19
19
  kind: ImportWarningKind;
20
20
  /** The tool it concerns, when it concerns one. */
@@ -136,25 +136,54 @@ export interface PostmanCollection {
136
136
  * alternative is a URL with a placeholder nothing resolves.
137
137
  */
138
138
  export declare function fromPostman(collection: PostmanCollection, options?: ImportOptions): ImportedTools;
139
+ interface OpenApiSchema {
140
+ [key: string]: unknown;
141
+ $ref?: string;
142
+ type?: string | string[];
143
+ description?: string;
144
+ enum?: (string | number | boolean | null)[];
145
+ required?: string[];
146
+ properties?: Record<string, OpenApiSchema>;
147
+ items?: OpenApiSchema;
148
+ nullable?: boolean;
149
+ additionalProperties?: boolean | OpenApiSchema;
150
+ allOf?: OpenApiSchema[];
151
+ }
139
152
  interface OpenApiParam {
153
+ $ref?: string;
140
154
  name?: string;
141
155
  in?: string;
142
156
  required?: boolean;
143
157
  description?: string;
144
- schema?: {
145
- type?: string;
146
- enum?: (string | number)[];
147
- };
158
+ schema?: OpenApiSchema;
159
+ type?: string;
160
+ enum?: (string | number | boolean | null)[];
161
+ style?: string;
162
+ explode?: boolean;
163
+ }
164
+ interface OpenApiBody {
165
+ $ref?: string;
166
+ required?: boolean;
167
+ content?: Record<string, {
168
+ schema?: OpenApiSchema;
169
+ }>;
148
170
  }
149
171
  interface OpenApiOperation {
150
172
  operationId?: string;
151
173
  summary?: string;
152
174
  description?: string;
153
175
  parameters?: OpenApiParam[];
154
- requestBody?: {
155
- content?: Record<string, unknown>;
156
- };
157
- security?: unknown[];
176
+ requestBody?: OpenApiBody;
177
+ security?: Record<string, string[]>[];
178
+ }
179
+ type OpenApiPath = {
180
+ parameters?: OpenApiParam[];
181
+ } & Partial<Record<'get' | 'post' | 'put' | 'delete' | 'patch', OpenApiOperation>>;
182
+ interface SecurityScheme {
183
+ type?: string;
184
+ scheme?: string;
185
+ name?: string;
186
+ in?: string;
158
187
  }
159
188
  export interface OpenApiDocument {
160
189
  openapi?: string;
@@ -168,33 +197,19 @@ export interface OpenApiDocument {
168
197
  host?: string;
169
198
  basePath?: string;
170
199
  schemes?: string[];
171
- paths?: Record<string, Record<string, OpenApiOperation>>;
200
+ paths?: Record<string, OpenApiPath>;
172
201
  components?: {
173
- securitySchemes?: Record<string, {
174
- type?: string;
175
- scheme?: string;
176
- name?: string;
177
- in?: string;
178
- }>;
202
+ securitySchemes?: Record<string, SecurityScheme>;
203
+ schemas?: Record<string, OpenApiSchema>;
204
+ parameters?: Record<string, OpenApiParam>;
205
+ requestBodies?: Record<string, OpenApiBody>;
179
206
  };
180
- securityDefinitions?: Record<string, {
181
- type?: string;
182
- name?: string;
183
- in?: string;
184
- }>;
185
- security?: unknown[];
207
+ definitions?: Record<string, OpenApiSchema>;
208
+ securityDefinitions?: Record<string, SecurityScheme>;
209
+ security?: Record<string, string[]>[];
186
210
  }
187
- /**
188
- * Draft tools from an OpenAPI 3 or Swagger 2 document.
189
- *
190
- * WHAT THIS GIVES THAT POSTMAN DOES NOT: real parameter types and required
191
- * flags, which is exactly the shape `HttpToolParam` wants, and an enum where the
192
- * document declares one. FastAPI publishes this at `/openapi.json` without
193
- * anybody writing it, so for a FastAPI shop this is usually the richer source.
194
- *
195
- * WHAT IT STILL DOES NOT GIVE: a description a model can choose on. `summary`
196
- * is written for a developer reading a reference. Read the warnings.
197
- */
211
+ /** Draft supported OpenAPI/Swagger requests; authentication follows each
212
+ * operation's security requirement, including AND, alternatives and security:[]. */
198
213
  export declare function fromOpenApi(doc: OpenApiDocument, options?: ImportOptions): ImportedTools;
199
214
  /**
200
215
  * Fetch an OpenAPI document and draft tools from it.