@agent-api/sdk 1.1.3 → 1.1.5

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 (61) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +26 -4
  3. package/dist/client.d.ts +4 -1
  4. package/dist/client.js +5 -1
  5. package/dist/index.d.ts +1 -5
  6. package/dist/index.js +1 -3
  7. package/dist/local-skills.js +13 -1
  8. package/dist/node-client.d.ts +6 -0
  9. package/dist/node-client.js +7 -0
  10. package/dist/node.d.ts +8 -0
  11. package/dist/node.js +6 -0
  12. package/dist/resources/auth.d.ts +3 -1
  13. package/dist/resources/auth.js +18 -0
  14. package/dist/resources/skills-node.d.ts +7 -0
  15. package/dist/resources/skills-node.js +156 -0
  16. package/dist/resources/skills.d.ts +1 -3
  17. package/dist/resources/skills.js +0 -153
  18. package/dist/types/auth.d.ts +3 -0
  19. package/dist/types/responses.d.ts +4 -0
  20. package/dist/version.d.ts +2 -2
  21. package/dist/version.js +1 -1
  22. package/dist-cjs/client.js +72 -0
  23. package/dist-cjs/errors.js +146 -0
  24. package/dist-cjs/index.js +52 -0
  25. package/dist-cjs/internal/env.js +7 -0
  26. package/dist-cjs/internal/http.js +108 -0
  27. package/dist-cjs/internal/output-text.js +15 -0
  28. package/dist-cjs/internal/query.js +13 -0
  29. package/dist-cjs/local/context.js +158 -0
  30. package/dist-cjs/local/core.js +1077 -0
  31. package/dist-cjs/local/index.js +19 -0
  32. package/dist-cjs/local/tools.js +380 -0
  33. package/dist-cjs/local-functions.js +37 -0
  34. package/dist-cjs/local-skills.js +308 -0
  35. package/dist-cjs/node-client.js +11 -0
  36. package/dist-cjs/node.js +32 -0
  37. package/dist-cjs/package.json +3 -0
  38. package/dist-cjs/pagination.js +43 -0
  39. package/dist-cjs/preset-tools.js +91 -0
  40. package/dist-cjs/resources/auth.js +111 -0
  41. package/dist-cjs/resources/models.js +13 -0
  42. package/dist-cjs/resources/presets.js +13 -0
  43. package/dist-cjs/resources/responses.js +58 -0
  44. package/dist-cjs/resources/skills-node.js +193 -0
  45. package/dist-cjs/resources/skills.js +112 -0
  46. package/dist-cjs/resources/tools.js +13 -0
  47. package/dist-cjs/resources/volumes.js +114 -0
  48. package/dist-cjs/streaming.js +42 -0
  49. package/dist-cjs/tool-validation.js +18 -0
  50. package/dist-cjs/types/auth.js +2 -0
  51. package/dist-cjs/types/catalog.js +2 -0
  52. package/dist-cjs/types/common.js +2 -0
  53. package/dist-cjs/types/index.js +25 -0
  54. package/dist-cjs/types/input.js +2 -0
  55. package/dist-cjs/types/responses.js +2 -0
  56. package/dist-cjs/types/skills.js +2 -0
  57. package/dist-cjs/types/streaming.js +2 -0
  58. package/dist-cjs/types/tools.js +2 -0
  59. package/dist-cjs/types/volumes.js +2 -0
  60. package/dist-cjs/version.js +5 -0
  61. package/package.json +20 -5
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.localSkillFromDirectory = localSkillFromDirectory;
37
+ exports.pendingLocalSkillCalls = pendingLocalSkillCalls;
38
+ exports.runLocalSkillHandlers = runLocalSkillHandlers;
39
+ const local_functions_js_1 = require("./local-functions.js");
40
+ const DEFAULT_FOCUS_MANIFEST_CHARS = 16000;
41
+ const DEFAULT_FOCUS_FILE_CHARS = 12000;
42
+ async function localSkillFromDirectory(rootDir, options = {}) {
43
+ const fs = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
44
+ const path = await Promise.resolve().then(() => __importStar(require("node:path")));
45
+ const crypto = await Promise.resolve().then(() => __importStar(require("node:crypto")));
46
+ const root = path.resolve(rootDir);
47
+ const files = await walkFiles(fs, path, root, root);
48
+ const hash = crypto.createHash("sha256");
49
+ for (const rel of files.sort()) {
50
+ hash.update(rel);
51
+ hash.update("\0");
52
+ hash.update(await fs.readFile(path.join(root, rel)));
53
+ hash.update("\0");
54
+ }
55
+ const digest = "sha256:" + hash.digest("hex");
56
+ const base = path.basename(root);
57
+ const localSkillID = options.id ?? base;
58
+ const { manifest, manifestTruncated } = await readLocalManifest(fs, path, root, options.max_manifest_chars ?? DEFAULT_FOCUS_MANIFEST_CHARS);
59
+ return {
60
+ local_skill_id: localSkillID,
61
+ skill_ref: skillRefForLocal(localSkillID, digest),
62
+ name: options.name ?? base,
63
+ description: options.description,
64
+ root_hint: root,
65
+ digest,
66
+ manifest,
67
+ manifest_truncated: manifestTruncated,
68
+ metadata: options.metadata,
69
+ };
70
+ }
71
+ function pendingLocalSkillCalls(response) {
72
+ return (0, local_functions_js_1.pendingFunctionCalls)(response).filter((call) => isLocalSkillFocusCall(call));
73
+ }
74
+ function isLocalSkillFocusCall(call) {
75
+ if (call.name !== "skill") {
76
+ return false;
77
+ }
78
+ try {
79
+ const args = call.arguments ? JSON.parse(call.arguments) : {};
80
+ return String(args.action || "").trim().toLowerCase() === "focus";
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ async function runLocalSkillHandlers(response, localSkills) {
87
+ const byRef = await localSkillsByRef(localSkills);
88
+ const outputs = [];
89
+ for (const call of pendingLocalSkillCalls(response)) {
90
+ const args = call.arguments ? JSON.parse(call.arguments) : {};
91
+ const payload = await focusLocalSkills(args, byRef);
92
+ outputs.push((0, local_functions_js_1.functionCallOutputInput)(call.call_id, payload));
93
+ }
94
+ return outputs;
95
+ }
96
+ async function focusLocalSkills(args, byRef) {
97
+ const maxManifestChars = manifestCharLimit(args);
98
+ const maxFileChars = fileCharLimit(args);
99
+ const items = Array.isArray(args.skills) ? args.skills : [];
100
+ if (!Array.isArray(args.skills)) {
101
+ return { data: [{ ok: false, error: { code: "invalid_skill_focus", message: "skills must be an array" } }] };
102
+ }
103
+ const data = [];
104
+ for (const raw of items) {
105
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
106
+ data.push({ ok: false, error: { code: "invalid_skill_focus", message: "skill item must be an object" } });
107
+ continue;
108
+ }
109
+ const item = raw;
110
+ const skillRef = String(item.skill_ref || "").trim();
111
+ const result = { ok: false, skill_ref: skillRef, branch: "main" };
112
+ const descriptor = byRef.get(skillRef);
113
+ if (!descriptor) {
114
+ result.error = { code: "skill_ref_not_found", message: "skill_ref was not registered with the SDK" };
115
+ data.push(result);
116
+ continue;
117
+ }
118
+ try {
119
+ result.skill = await focusedLocalSkill(descriptor, maxManifestChars, pathsArg(item), maxFileChars, includeManifest(item));
120
+ result.ok = true;
121
+ }
122
+ catch (error) {
123
+ result.error = { code: "local_skill_focus_failed", message: error instanceof Error ? error.message : String(error) };
124
+ }
125
+ data.push(result);
126
+ }
127
+ return { data };
128
+ }
129
+ async function focusedLocalSkill(descriptor, maxManifestChars, paths, maxFileChars, includeManifest) {
130
+ const fs = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
131
+ const path = await Promise.resolve().then(() => __importStar(require("node:path")));
132
+ const { TextDecoder } = await Promise.resolve().then(() => __importStar(require("node:util")));
133
+ const root = path.resolve(descriptor.root_hint || ".");
134
+ const stat = await fs.stat(root);
135
+ if (!stat.isDirectory()) {
136
+ throw new Error(`local skill root is not a directory: ${root}`);
137
+ }
138
+ let manifest = "";
139
+ let manifestTruncated = false;
140
+ if (includeManifest) {
141
+ try {
142
+ const manifestBytes = await fs.readFile(path.join(root, "SKILL.md"));
143
+ manifest = new TextDecoder("utf-8", { fatal: true }).decode(manifestBytes);
144
+ const manifestChars = Array.from(manifest);
145
+ if (maxManifestChars > 0 && manifestChars.length > maxManifestChars) {
146
+ manifest = manifestChars.slice(0, maxManifestChars).join("");
147
+ manifestTruncated = true;
148
+ }
149
+ }
150
+ catch (error) {
151
+ if (error?.code !== "ENOENT") {
152
+ throw error;
153
+ }
154
+ }
155
+ }
156
+ const dirents = await fs.readdir(root, { withFileTypes: true });
157
+ const entries = await Promise.all(dirents
158
+ .filter((entry) => ![".git", "__pycache__", "node_modules"].includes(entry.name))
159
+ .sort((a, b) => a.name.localeCompare(b.name))
160
+ .map(async (entry) => {
161
+ const full = path.join(root, entry.name);
162
+ const entryStat = await fs.stat(full);
163
+ return {
164
+ path: entry.name,
165
+ is_dir: entry.isDirectory(),
166
+ size: entry.isDirectory() ? 0 : entryStat.size,
167
+ modified_at: Math.floor(entryStat.mtimeMs / 1000),
168
+ };
169
+ }));
170
+ return {
171
+ skill_ref: await descriptorSkillRef(descriptor),
172
+ name: descriptor.name || "",
173
+ description: descriptor.description || "",
174
+ branch: "SKILL_BRANCH_MAIN",
175
+ digest: descriptor.digest || "",
176
+ manifest,
177
+ manifest_truncated: manifestTruncated,
178
+ entries,
179
+ files: await Promise.all(paths.map((relPath) => focusedLocalFile(fs, path, root, relPath, maxFileChars))),
180
+ };
181
+ }
182
+ function manifestCharLimit(args) {
183
+ const raw = args.max_manifest_chars ?? DEFAULT_FOCUS_MANIFEST_CHARS;
184
+ const value = Number(raw);
185
+ return Number.isFinite(value) ? value : DEFAULT_FOCUS_MANIFEST_CHARS;
186
+ }
187
+ function fileCharLimit(args) {
188
+ const raw = args.max_file_chars ?? DEFAULT_FOCUS_FILE_CHARS;
189
+ const value = Number(raw);
190
+ return Number.isFinite(value) ? value : DEFAULT_FOCUS_FILE_CHARS;
191
+ }
192
+ function pathsArg(item) {
193
+ if (!Array.isArray(item.paths)) {
194
+ return [];
195
+ }
196
+ return item.paths
197
+ .filter((value) => typeof value === "string")
198
+ .map((value) => value.trim())
199
+ .filter(Boolean);
200
+ }
201
+ function includeManifest(item) {
202
+ return typeof item.include_manifest === "boolean" ? item.include_manifest : true;
203
+ }
204
+ async function focusedLocalFile(fs, path, root, relPath, maxFileChars) {
205
+ const base = { path: relPath, branch: "SKILL_BRANCH_MAIN", content: "", truncated: false, size: 0 };
206
+ const { TextDecoder } = await Promise.resolve().then(() => __importStar(require("node:util")));
207
+ try {
208
+ const full = path.resolve(root, relPath);
209
+ const relative = path.relative(root, full);
210
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
211
+ return { ...base, error: { type: "skill_error", code: "invalid_skill_file_path", message: "path must stay inside the local skill root" } };
212
+ }
213
+ const stat = await fs.stat(full);
214
+ if (!stat.isFile()) {
215
+ return { ...base, error: { type: "skill_error", code: "skill_file_not_found", message: "skill file was not found" } };
216
+ }
217
+ const raw = await fs.readFile(full);
218
+ let content = new TextDecoder("utf-8", { fatal: true }).decode(raw);
219
+ let truncated = false;
220
+ const chars = Array.from(content);
221
+ if (maxFileChars > 0 && chars.length > maxFileChars) {
222
+ content = chars.slice(0, maxFileChars).join("");
223
+ truncated = true;
224
+ }
225
+ return { ...base, content, truncated, size: stat.size };
226
+ }
227
+ catch (error) {
228
+ if (error?.code === "ENOENT") {
229
+ return { ...base, error: { type: "skill_error", code: "skill_file_not_found", message: "skill file was not found" } };
230
+ }
231
+ if (error instanceof TypeError) {
232
+ return { ...base, error: { type: "skill_error", code: "invalid_skill_file_utf8", message: "skill file must be valid UTF-8" } };
233
+ }
234
+ return { ...base, error: { type: "skill_error", code: "skill_file_read_failed", message: error instanceof Error ? error.message : String(error) } };
235
+ }
236
+ }
237
+ async function walkFiles(fs, path, root, dir) {
238
+ const entries = await fs.readdir(dir, { withFileTypes: true });
239
+ const out = [];
240
+ for (const entry of entries) {
241
+ if (entry.name === ".git" || entry.name === "node_modules") {
242
+ continue;
243
+ }
244
+ const full = path.join(dir, entry.name);
245
+ if (entry.isDirectory()) {
246
+ out.push(...await walkFiles(fs, path, root, full));
247
+ continue;
248
+ }
249
+ if (entry.isFile()) {
250
+ out.push(path.relative(root, full).split(path.sep).join("/"));
251
+ }
252
+ }
253
+ return out;
254
+ }
255
+ async function localSkillsByRef(localSkills) {
256
+ const out = new Map();
257
+ for (const skill of localSkills) {
258
+ out.set(await descriptorSkillRef(skill), skill);
259
+ }
260
+ return out;
261
+ }
262
+ async function descriptorSkillRef(descriptor) {
263
+ const existing = String(descriptor.skill_ref || "").trim();
264
+ if (existing) {
265
+ return existing;
266
+ }
267
+ return skillRefForLocal(descriptor.local_skill_id || "", descriptor.digest || "");
268
+ }
269
+ function skillRefForLocal(localSkillID, digest) {
270
+ const slug = skillRefSlug(localSkillID) || "local-skill";
271
+ const digestPart = skillRefDigestPart(digest) || "unknown";
272
+ return `local::${slug}@${digestPart}::main`;
273
+ }
274
+ function skillRefSlug(raw) {
275
+ return raw
276
+ .trim()
277
+ .toLowerCase()
278
+ .replace(/::/g, "-")
279
+ .replace(/@/g, "-")
280
+ .replace(/[^a-z0-9_-]+/g, "-")
281
+ .replace(/^[-_]+|[-_]+$/g, "")
282
+ .slice(0, 64)
283
+ .replace(/^[-_]+|[-_]+$/g, "");
284
+ }
285
+ function skillRefDigestPart(raw) {
286
+ const digest = raw.trim().toLowerCase().split(":").pop() || "";
287
+ return digest.replace(/[^a-z0-9_-]+/g, "").slice(0, 16);
288
+ }
289
+ async function readLocalManifest(fs, path, root, maxManifestChars) {
290
+ const { TextDecoder } = await Promise.resolve().then(() => __importStar(require("node:util")));
291
+ try {
292
+ const raw = await fs.readFile(path.join(root, "SKILL.md"));
293
+ let manifest = new TextDecoder("utf-8", { fatal: true }).decode(raw);
294
+ let manifestTruncated = false;
295
+ const chars = Array.from(manifest);
296
+ if (maxManifestChars > 0 && chars.length > maxManifestChars) {
297
+ manifest = chars.slice(0, maxManifestChars).join("");
298
+ manifestTruncated = true;
299
+ }
300
+ return { manifest, manifestTruncated };
301
+ }
302
+ catch (error) {
303
+ if (error?.code === "ENOENT") {
304
+ return { manifest: "", manifestTruncated: false };
305
+ }
306
+ throw error;
307
+ }
308
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodeAgentAPI = void 0;
4
+ const client_js_1 = require("./client.js");
5
+ const skills_node_js_1 = require("./resources/skills-node.js");
6
+ class NodeAgentAPI extends client_js_1.AgentAPI {
7
+ createSkillsResource() {
8
+ return new skills_node_js_1.NodeSkillsResource(this.http);
9
+ }
10
+ }
11
+ exports.NodeAgentAPI = NodeAgentAPI;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.runLocalSkillHandlers = exports.pendingLocalSkillCalls = exports.localSkillFromDirectory = exports.localWorkspaceToolInstructions = exports.localWorkspaceToolDefinition = exports.createLocalWorkspaceToolRegistry = exports.LocalWorkspaceDriver = exports.NodeSkillsResource = exports.NodeAgentAPI = void 0;
18
+ __exportStar(require("./index.js"), exports);
19
+ var node_client_js_1 = require("./node-client.js");
20
+ Object.defineProperty(exports, "NodeAgentAPI", { enumerable: true, get: function () { return node_client_js_1.NodeAgentAPI; } });
21
+ var skills_node_js_1 = require("./resources/skills-node.js");
22
+ Object.defineProperty(exports, "NodeSkillsResource", { enumerable: true, get: function () { return skills_node_js_1.NodeSkillsResource; } });
23
+ var tools_js_1 = require("./local/tools.js");
24
+ Object.defineProperty(exports, "LocalWorkspaceDriver", { enumerable: true, get: function () { return tools_js_1.LocalWorkspaceDriver; } });
25
+ Object.defineProperty(exports, "createLocalWorkspaceToolRegistry", { enumerable: true, get: function () { return tools_js_1.createLocalWorkspaceToolRegistry; } });
26
+ Object.defineProperty(exports, "localWorkspaceToolDefinition", { enumerable: true, get: function () { return tools_js_1.localWorkspaceToolDefinition; } });
27
+ Object.defineProperty(exports, "localWorkspaceToolInstructions", { enumerable: true, get: function () { return tools_js_1.localWorkspaceToolInstructions; } });
28
+ var local_skills_js_1 = require("./local-skills.js");
29
+ Object.defineProperty(exports, "localSkillFromDirectory", { enumerable: true, get: function () { return local_skills_js_1.localSkillFromDirectory; } });
30
+ Object.defineProperty(exports, "pendingLocalSkillCalls", { enumerable: true, get: function () { return local_skills_js_1.pendingLocalSkillCalls; } });
31
+ Object.defineProperty(exports, "runLocalSkillHandlers", { enumerable: true, get: function () { return local_skills_js_1.runLocalSkillHandlers; } });
32
+ __exportStar(require("./local/index.js"), exports);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Page = void 0;
4
+ exports.collectPage = collectPage;
5
+ class Page {
6
+ fetchPage;
7
+ params;
8
+ data;
9
+ hasMore;
10
+ nextPageToken;
11
+ constructor(fetchPage, params, data, hasMore, nextPageToken) {
12
+ this.fetchPage = fetchPage;
13
+ this.params = params;
14
+ this.data = data;
15
+ this.hasMore = hasMore;
16
+ this.nextPageToken = nextPageToken;
17
+ }
18
+ [Symbol.asyncIterator]() {
19
+ return this.iterateAll()[Symbol.asyncIterator]();
20
+ }
21
+ async getNextPage() {
22
+ if (!this.hasMore || !this.nextPageToken) {
23
+ return null;
24
+ }
25
+ const nextParams = { ...this.params, page_token: this.nextPageToken };
26
+ const result = await this.fetchPage(nextParams);
27
+ return new Page(this.fetchPage, nextParams, result.data, result.has_more, result.next_page_token);
28
+ }
29
+ async *iterateAll() {
30
+ let page = this;
31
+ while (page) {
32
+ for (const item of page.data) {
33
+ yield item;
34
+ }
35
+ page = await page.getNextPage();
36
+ }
37
+ }
38
+ }
39
+ exports.Page = Page;
40
+ async function collectPage(fetchPage, params) {
41
+ const result = await fetchPage(params);
42
+ return new Page(fetchPage, params, result.data, result.has_more, result.next_page_token);
43
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolvePresetTools = resolvePresetTools;
4
+ exports.resolvePresetToolsFromCatalog = resolvePresetToolsFromCatalog;
5
+ exports.mergeTools = mergeTools;
6
+ exports.publicToolToRequestTool = publicToolToRequestTool;
7
+ const tool_validation_js_1 = require("./tool-validation.js");
8
+ /**
9
+ * Resolve a preset's allowed tool names into concrete request tools and append
10
+ * caller-provided tools. This is a convenience for hybrid apps that need to add
11
+ * local/client tools while preserving the preset's default server tools.
12
+ *
13
+ * The Agent API request surface remains OpenAI-compatible: the returned array
14
+ * is intended for the normal CreateResponseRequest.tools field.
15
+ */
16
+ async function resolvePresetTools(client, options) {
17
+ const presets = options.presets ?? (await client.presets.list()).data;
18
+ const toolCatalog = options.toolCatalog ?? (await client.tools.list()).data;
19
+ return resolvePresetToolsFromCatalog({ ...options, presets, toolCatalog });
20
+ }
21
+ function resolvePresetToolsFromCatalog(options) {
22
+ const presetId = options.preset.trim();
23
+ if (!presetId) {
24
+ throw new Error("preset is required");
25
+ }
26
+ const preset = options.presets?.find((row) => row.preset === presetId);
27
+ if (!preset) {
28
+ throw new Error(`preset not found: ${presetId}`);
29
+ }
30
+ const catalogByName = new Map();
31
+ for (const tool of options.toolCatalog ?? []) {
32
+ const name = tool.name?.trim();
33
+ if (name)
34
+ catalogByName.set(name, tool);
35
+ }
36
+ const missingToolNames = [];
37
+ const presetTools = [];
38
+ const unknownPresetTool = options.unknownPresetTool ?? "stub";
39
+ for (const name of preset.policy?.allowed_tools ?? []) {
40
+ const trimmed = name.trim();
41
+ if (!trimmed)
42
+ continue;
43
+ const catalogTool = catalogByName.get(trimmed);
44
+ if (catalogTool) {
45
+ presetTools.push(publicToolToRequestTool(catalogTool));
46
+ continue;
47
+ }
48
+ missingToolNames.push(trimmed);
49
+ if (unknownPresetTool === "error") {
50
+ throw new Error(`preset tool not found in catalog: ${trimmed}`);
51
+ }
52
+ if (unknownPresetTool === "stub") {
53
+ presetTools.push({ name: trimmed });
54
+ }
55
+ }
56
+ return {
57
+ preset,
58
+ tools: mergeTools(presetTools, options.tools ?? []),
59
+ missingToolNames,
60
+ };
61
+ }
62
+ function mergeTools(...groups) {
63
+ const out = [];
64
+ for (const group of groups) {
65
+ for (const tool of group) {
66
+ const name = tool.name?.trim();
67
+ if (!name) {
68
+ throw new Error("tools[].name is required");
69
+ }
70
+ out.push({ ...tool, name });
71
+ }
72
+ }
73
+ (0, tool_validation_js_1.validateUniqueToolNames)(out);
74
+ return out;
75
+ }
76
+ function publicToolToRequestTool(tool) {
77
+ const out = { name: tool.name };
78
+ if (tool.type)
79
+ out.type = tool.type;
80
+ if (tool.description)
81
+ out.description = tool.description;
82
+ if (tool.parameters)
83
+ out.parameters = tool.parameters;
84
+ if (tool.max_tokens != null)
85
+ out.max_tokens = tool.max_tokens;
86
+ if (tool.max_tokens_per_page != null)
87
+ out.max_tokens_per_page = tool.max_tokens_per_page;
88
+ if (tool.version)
89
+ out.version = tool.version;
90
+ return out;
91
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceAuthFlowError = exports.AuthResource = void 0;
4
+ exports.browserAuthSessionExpiresWithin = browserAuthSessionExpiresWithin;
5
+ const defaultDevicePollIntervalSeconds = 5;
6
+ class AuthResource {
7
+ http;
8
+ constructor(http) {
9
+ this.http = http;
10
+ }
11
+ startDeviceAuth(params = {}, options = {}) {
12
+ return this.http.request("POST", "/v1/auth/device/start", params, options);
13
+ }
14
+ pollDeviceAuth(params, options = {}) {
15
+ requireDeviceCode(params.device_code);
16
+ return this.http.request("POST", "/v1/auth/device/poll", params, options);
17
+ }
18
+ refreshBrowserSession(params, options = {}) {
19
+ requireRefreshToken(params.refresh_token);
20
+ return this.http.request("POST", "/v1/auth/refresh", {}, {
21
+ ...options,
22
+ headers: {
23
+ ...options.headers,
24
+ Cookie: `agent_api_refresh=${encodeURIComponent(params.refresh_token)}`,
25
+ },
26
+ });
27
+ }
28
+ async waitForDeviceAuth(params, options = {}) {
29
+ requireDeviceCode(params.device_code);
30
+ const startedAt = Date.now();
31
+ for (;;) {
32
+ throwIfAborted(params.signal);
33
+ const result = await this.pollDeviceAuth({ device_code: params.device_code }, options);
34
+ params.on_poll?.(result);
35
+ if (result.status === "approved" && result.access_token && result.refresh_token) {
36
+ return result;
37
+ }
38
+ if (result.status === "expired" || result.status === "consumed") {
39
+ throw new DeviceAuthFlowError(result.message || `Device auth ${result.status}`, result);
40
+ }
41
+ const timeoutMs = effectiveTimeoutMs(params, result);
42
+ if (timeoutMs !== undefined && Date.now() - startedAt >= timeoutMs) {
43
+ throw new DeviceAuthFlowError("Device auth timed out", result);
44
+ }
45
+ await sleep(pollDelayMs(params, result), params.signal);
46
+ }
47
+ }
48
+ }
49
+ exports.AuthResource = AuthResource;
50
+ function browserAuthSessionExpiresWithin(session, windowMs = 60_000, nowMs = Date.now()) {
51
+ return session.access_token_expires_at * 1000 - nowMs <= windowMs;
52
+ }
53
+ class DeviceAuthFlowError extends Error {
54
+ result;
55
+ constructor(message, result) {
56
+ super(message);
57
+ this.name = "DeviceAuthFlowError";
58
+ this.result = result;
59
+ Object.setPrototypeOf(this, DeviceAuthFlowError.prototype);
60
+ }
61
+ }
62
+ exports.DeviceAuthFlowError = DeviceAuthFlowError;
63
+ function requireDeviceCode(deviceCode) {
64
+ if (!deviceCode || !deviceCode.trim()) {
65
+ throw new TypeError("device_code is required");
66
+ }
67
+ }
68
+ function requireRefreshToken(refreshToken) {
69
+ if (!refreshToken || !refreshToken.trim()) {
70
+ throw new TypeError("refresh_token is required");
71
+ }
72
+ }
73
+ function pollDelayMs(params, result) {
74
+ const seconds = params.interval_seconds ?? result.interval_seconds ?? defaultDevicePollIntervalSeconds;
75
+ return Math.max(1, seconds) * 1000;
76
+ }
77
+ function effectiveTimeoutMs(params, result) {
78
+ if (params.timeout_ms !== undefined) {
79
+ return Math.max(0, params.timeout_ms);
80
+ }
81
+ const expiresAt = result.expires_at;
82
+ if (!expiresAt)
83
+ return undefined;
84
+ return Math.max(0, expiresAt * 1000 - Date.now());
85
+ }
86
+ function sleep(ms, signal) {
87
+ if (!signal) {
88
+ return new Promise((resolve) => setTimeout(resolve, ms));
89
+ }
90
+ throwIfAborted(signal);
91
+ return new Promise((resolve, reject) => {
92
+ const timeout = setTimeout(cleanupResolve, ms);
93
+ signal.addEventListener("abort", cleanupReject, { once: true });
94
+ function cleanupResolve() {
95
+ signal?.removeEventListener("abort", cleanupReject);
96
+ resolve();
97
+ }
98
+ function cleanupReject() {
99
+ clearTimeout(timeout);
100
+ reject(abortError());
101
+ }
102
+ });
103
+ }
104
+ function throwIfAborted(signal) {
105
+ if (signal?.aborted) {
106
+ throw abortError();
107
+ }
108
+ }
109
+ function abortError() {
110
+ return new DOMException("Device auth wait aborted", "AbortError");
111
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModelsResource = void 0;
4
+ class ModelsResource {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ list(options) {
10
+ return this.http.request("GET", "/v1/models", undefined, options);
11
+ }
12
+ }
13
+ exports.ModelsResource = ModelsResource;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PresetsResource = void 0;
4
+ class PresetsResource {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ list(options) {
10
+ return this.http.request("GET", "/v1/presets", undefined, options);
11
+ }
12
+ }
13
+ exports.PresetsResource = PresetsResource;