@agent-api/sdk 1.1.0 → 1.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog — @agent-api/sdk
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Added
6
+
7
+ - Browser/device login helpers for CLI and desktop integrations: `client.auth.startDeviceAuth()`, `client.auth.pollDeviceAuth()`, and `client.auth.waitForDeviceAuth()`.
8
+ - Convenience methods on `AgentAPI`: `startDeviceAuth()`, `pollDeviceAuth()`, and `waitForDeviceAuth()`.
9
+ - `DeviceAuthFlowError` for expired, consumed, or timed-out device login flows.
10
+
3
11
  ## 1.1.0
4
12
 
5
13
  ### Added
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Production JavaScript/TypeScript SDK for the Managed Agent API.
4
4
 
5
- **Published on npm:** [`@agent-api/sdk`](https://www.npmjs.com/package/@agent-api/sdk) (v1.0.8)
5
+ **Published on npm:** [`@agent-api/sdk`](https://www.npmjs.com/package/@agent-api/sdk) (v1.1.1)
6
6
 
7
7
  ## Install
8
8
 
@@ -46,7 +46,7 @@ src/
46
46
  errors.ts # Typed error hierarchy + retry helpers
47
47
  pagination.ts # Cursor pagination utilities
48
48
  streaming.ts # SSE parser
49
- resources/ # responses, models, presets, tools, volumes, skills
49
+ resources/ # auth, responses, models, presets, tools, volumes, skills
50
50
  types/ # Request/response TypeScript types
51
51
  internal/http.ts # Retries, timeouts, User-Agent
52
52
  ```
@@ -61,6 +61,25 @@ src/
61
61
  | `client.tools` | `list` |
62
62
  | `client.volumes` | `list`, `create`, `retrieve`, `update`, `delete`, `listEntries`, `searchEntries`, `readFile`, `writeFile`, `deletePath`, `reconcileUsage`, `createDirectory`, `downloadArchive`, `summarize`, `readLines`, `patchLines`, `grep` |
63
63
  | `client.skills` | `list`, `create`, `discover`, `focus`, `createDev`, `updateFile`, `retrieve`, `update`, `archive`, `delete`, `diff`, `acceptDev`, `discardDev`, `exportArchive`, `importArchive`, `pushDirectory`, `pullDirectory`, `listFiles`, `readFile`, `writeFile`, `deleteFile` |
64
+ | `client.auth` | `startDeviceAuth`, `pollDeviceAuth`, `waitForDeviceAuth` |
65
+
66
+ ## Browser Device Login
67
+
68
+ CLI and desktop apps can use browser login without handling user passwords or static API keys.
69
+
70
+ ```typescript
71
+ const challenge = await client.auth.startDeviceAuth({ client_name: "Agent CLI" });
72
+ console.log(`Open ${challenge.verification_uri_complete}`);
73
+
74
+ const session = await client.auth.waitForDeviceAuth({
75
+ device_code: challenge.device_code,
76
+ interval_seconds: challenge.interval_seconds,
77
+ });
78
+
79
+ console.log(session.access_token);
80
+ ```
81
+
82
+ The SDK returns URLs and polling helpers only. Opening the browser belongs to the CLI, Electron, Tauri, or native host app.
64
83
 
65
84
  ## Durable Volumes
66
85
 
package/dist/client.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { AuthResource } from "./resources/auth.js";
1
2
  import { ModelsResource } from "./resources/models.js";
2
3
  import { PresetsResource } from "./resources/presets.js";
3
4
  import { ResponsesResource } from "./resources/responses.js";
@@ -23,7 +24,11 @@ export declare class AgentAPI {
23
24
  readonly tools: ToolsResource;
24
25
  readonly volumes: VolumesResource;
25
26
  readonly skills: SkillsResource;
27
+ readonly auth: AuthResource;
26
28
  private readonly http;
27
29
  constructor(options?: ClientOptions);
30
+ startDeviceAuth: (...args: Parameters<AuthResource["startDeviceAuth"]>) => Promise<import("./index.js").DeviceAuthStart>;
31
+ pollDeviceAuth: (...args: Parameters<AuthResource["pollDeviceAuth"]>) => Promise<import("./index.js").DeviceAuthPollResult>;
32
+ waitForDeviceAuth: (...args: Parameters<AuthResource["waitForDeviceAuth"]>) => Promise<import("./index.js").ApprovedDeviceAuth>;
28
33
  }
29
34
  export { VERSION };
package/dist/client.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { APIConnectionError } from "./errors.js";
2
2
  import { readEnv } from "./internal/env.js";
3
3
  import { HTTPClient } from "./internal/http.js";
4
+ import { AuthResource } from "./resources/auth.js";
4
5
  import { ModelsResource } from "./resources/models.js";
5
6
  import { PresetsResource } from "./resources/presets.js";
6
7
  import { ResponsesResource } from "./resources/responses.js";
@@ -25,6 +26,7 @@ export class AgentAPI {
25
26
  tools;
26
27
  volumes;
27
28
  skills;
29
+ auth;
28
30
  http;
29
31
  constructor(options = {}) {
30
32
  this.apiKey = options.apiKey ?? readEnv("AGENT_API_KEY");
@@ -53,6 +55,10 @@ export class AgentAPI {
53
55
  this.tools = new ToolsResource(this.http);
54
56
  this.volumes = new VolumesResource(this.http);
55
57
  this.skills = new SkillsResource(this.http);
58
+ this.auth = new AuthResource(this.http);
56
59
  }
60
+ startDeviceAuth = (...args) => this.auth.startDeviceAuth(...args);
61
+ pollDeviceAuth = (...args) => this.auth.pollDeviceAuth(...args);
62
+ waitForDeviceAuth = (...args) => this.auth.waitForDeviceAuth(...args);
57
63
  }
58
64
  export { VERSION };
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export { functionCallOutputInput, pendingFunctionCalls, runLocalFunctionHandlers
7
7
  export type { LocalFunctionHandler, LocalFunctionHandlers } from "./local-functions.js";
8
8
  export { localSkillFromDirectory, pendingLocalSkillCalls, runLocalSkillHandlers } from "./local-skills.js";
9
9
  export type { LocalSkillDirectoryOptions } from "./local-skills.js";
10
+ export { AuthResource, DeviceAuthFlowError } from "./resources/auth.js";
package/dist/index.js CHANGED
@@ -4,3 +4,4 @@ export { APIError, APIConnectionError, APIStatusError, AuthenticationError, BadR
4
4
  export * from "./types/index.js";
5
5
  export { functionCallOutputInput, pendingFunctionCalls, runLocalFunctionHandlers, } from "./local-functions.js";
6
6
  export { localSkillFromDirectory, pendingLocalSkillCalls, runLocalSkillHandlers } from "./local-skills.js";
7
+ export { AuthResource, DeviceAuthFlowError } from "./resources/auth.js";
@@ -0,0 +1,14 @@
1
+ import type { HTTPClient } from "../internal/http.js";
2
+ import type { ApprovedDeviceAuth, DeviceAuthPollResult, DeviceAuthStart, PollDeviceAuthParams, StartDeviceAuthParams, WaitForDeviceAuthParams } from "../types/auth.js";
3
+ import type { RequestOptions } from "../types/common.js";
4
+ export declare class AuthResource {
5
+ private readonly http;
6
+ constructor(http: HTTPClient);
7
+ startDeviceAuth(params?: StartDeviceAuthParams, options?: RequestOptions): Promise<DeviceAuthStart>;
8
+ pollDeviceAuth(params: PollDeviceAuthParams, options?: RequestOptions): Promise<DeviceAuthPollResult>;
9
+ waitForDeviceAuth(params: WaitForDeviceAuthParams, options?: RequestOptions): Promise<ApprovedDeviceAuth>;
10
+ }
11
+ export declare class DeviceAuthFlowError extends Error {
12
+ readonly result?: DeviceAuthPollResult;
13
+ constructor(message: string, result?: DeviceAuthPollResult);
14
+ }
@@ -0,0 +1,87 @@
1
+ const defaultDevicePollIntervalSeconds = 5;
2
+ export class AuthResource {
3
+ http;
4
+ constructor(http) {
5
+ this.http = http;
6
+ }
7
+ startDeviceAuth(params = {}, options = {}) {
8
+ return this.http.request("POST", "/v1/auth/device/start", params, options);
9
+ }
10
+ pollDeviceAuth(params, options = {}) {
11
+ requireDeviceCode(params.device_code);
12
+ return this.http.request("POST", "/v1/auth/device/poll", params, options);
13
+ }
14
+ async waitForDeviceAuth(params, options = {}) {
15
+ requireDeviceCode(params.device_code);
16
+ const startedAt = Date.now();
17
+ for (;;) {
18
+ throwIfAborted(params.signal);
19
+ const result = await this.pollDeviceAuth({ device_code: params.device_code }, options);
20
+ params.on_poll?.(result);
21
+ if (result.status === "approved" && result.access_token && result.refresh_token) {
22
+ return result;
23
+ }
24
+ if (result.status === "expired" || result.status === "consumed") {
25
+ throw new DeviceAuthFlowError(result.message || `Device auth ${result.status}`, result);
26
+ }
27
+ const timeoutMs = effectiveTimeoutMs(params, result);
28
+ if (timeoutMs !== undefined && Date.now() - startedAt >= timeoutMs) {
29
+ throw new DeviceAuthFlowError("Device auth timed out", result);
30
+ }
31
+ await sleep(pollDelayMs(params, result), params.signal);
32
+ }
33
+ }
34
+ }
35
+ export class DeviceAuthFlowError extends Error {
36
+ result;
37
+ constructor(message, result) {
38
+ super(message);
39
+ this.name = "DeviceAuthFlowError";
40
+ this.result = result;
41
+ Object.setPrototypeOf(this, DeviceAuthFlowError.prototype);
42
+ }
43
+ }
44
+ function requireDeviceCode(deviceCode) {
45
+ if (!deviceCode || !deviceCode.trim()) {
46
+ throw new TypeError("device_code is required");
47
+ }
48
+ }
49
+ function pollDelayMs(params, result) {
50
+ const seconds = params.interval_seconds ?? result.interval_seconds ?? defaultDevicePollIntervalSeconds;
51
+ return Math.max(1, seconds) * 1000;
52
+ }
53
+ function effectiveTimeoutMs(params, result) {
54
+ if (params.timeout_ms !== undefined) {
55
+ return Math.max(0, params.timeout_ms);
56
+ }
57
+ const expiresAt = result.expires_at;
58
+ if (!expiresAt)
59
+ return undefined;
60
+ return Math.max(0, expiresAt * 1000 - Date.now());
61
+ }
62
+ function sleep(ms, signal) {
63
+ if (!signal) {
64
+ return new Promise((resolve) => setTimeout(resolve, ms));
65
+ }
66
+ throwIfAborted(signal);
67
+ return new Promise((resolve, reject) => {
68
+ const timeout = setTimeout(cleanupResolve, ms);
69
+ signal.addEventListener("abort", cleanupReject, { once: true });
70
+ function cleanupResolve() {
71
+ signal?.removeEventListener("abort", cleanupReject);
72
+ resolve();
73
+ }
74
+ function cleanupReject() {
75
+ clearTimeout(timeout);
76
+ reject(abortError());
77
+ }
78
+ });
79
+ }
80
+ function throwIfAborted(signal) {
81
+ if (signal?.aborted) {
82
+ throw abortError();
83
+ }
84
+ }
85
+ function abortError() {
86
+ return new DOMException("Device auth wait aborted", "AbortError");
87
+ }
@@ -0,0 +1,63 @@
1
+ export type DeviceAuthStatus = "pending" | "approved" | "expired" | "consumed" | string;
2
+ export interface DeviceAuthStart {
3
+ device_code: string;
4
+ user_code: string;
5
+ verification_uri: string;
6
+ verification_uri_complete: string;
7
+ expires_at: number;
8
+ interval_seconds: number;
9
+ }
10
+ export interface AuthSession {
11
+ access_token: string;
12
+ refresh_token: string;
13
+ token_type?: string;
14
+ access_token_expires_at: number;
15
+ refresh_token_expires_at?: number;
16
+ user_id: string;
17
+ workspace_id: string;
18
+ workspace_name?: string;
19
+ workspace_role: string;
20
+ scopes: string[];
21
+ }
22
+ export interface DeviceAuthPollResult {
23
+ status: DeviceAuthStatus;
24
+ message?: string;
25
+ interval_seconds?: number;
26
+ expires_at?: number;
27
+ access_token?: string;
28
+ refresh_token?: string;
29
+ token_type?: string;
30
+ access_token_expires_at?: number;
31
+ refresh_token_expires_at?: number;
32
+ user_id?: string;
33
+ workspace_id?: string;
34
+ workspace_name?: string;
35
+ workspace_role?: string;
36
+ scopes?: string[];
37
+ }
38
+ export type ApprovedDeviceAuth = DeviceAuthPollResult & {
39
+ status: "approved";
40
+ access_token: string;
41
+ refresh_token: string;
42
+ access_token_expires_at: number;
43
+ user_id: string;
44
+ workspace_id: string;
45
+ workspace_role: string;
46
+ scopes: string[];
47
+ };
48
+ export interface StartDeviceAuthParams {
49
+ client_name?: string;
50
+ }
51
+ export interface PollDeviceAuthParams {
52
+ device_code: string;
53
+ }
54
+ export interface WaitForDeviceAuthParams extends PollDeviceAuthParams {
55
+ /** Polling interval in seconds. Defaults to the server interval or 5 seconds. */
56
+ interval_seconds?: number;
57
+ /** Overall wait timeout in milliseconds. Defaults to the challenge expiry when present. */
58
+ timeout_ms?: number;
59
+ /** Optional cancellation signal for CLI/Desktop integrations. */
60
+ signal?: AbortSignal;
61
+ /** Called after every poll response, including pending responses. */
62
+ on_poll?: (result: DeviceAuthPollResult) => void;
63
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -6,3 +6,4 @@ export * from "./streaming.js";
6
6
  export * from "./catalog.js";
7
7
  export * from "./volumes.js";
8
8
  export * from "./skills.js";
9
+ export * from "./auth.js";
@@ -6,3 +6,4 @@ export * from "./streaming.js";
6
6
  export * from "./catalog.js";
7
7
  export * from "./volumes.js";
8
8
  export * from "./skills.js";
9
+ export * from "./auth.js";
@@ -2,10 +2,17 @@ import type { AgentCapabilityPreference, ErrorInfo, ModelRoutingMode, ModelRouti
2
2
  import type { ContentPart, Input, MemoryOptions, ReasoningConfig, ResponseFormat } from "./input.js";
3
3
  import type { LocalSkillDescriptor, SkillReference } from "./skills.js";
4
4
  import type { Tool } from "./tools.js";
5
+ export interface CallerContext {
6
+ timezone?: string;
7
+ locale?: string;
8
+ locality?: string;
9
+ extra?: unknown;
10
+ }
5
11
  export interface ResponseCreateParamsBase {
6
12
  input: Input;
7
13
  instructions?: string;
8
14
  language_preference?: string;
15
+ caller_context?: CallerContext;
9
16
  model?: string;
10
17
  models?: string[];
11
18
  model_routing?: ModelRoutingMode;
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.1.0";
2
- export declare const USER_AGENT = "@agent-api/sdk/1.1.0";
1
+ export declare const VERSION = "1.1.1";
2
+ export declare const USER_AGENT = "@agent-api/sdk/1.1.1";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "1.1.0";
1
+ export const VERSION = "1.1.1";
2
2
  export const USER_AGENT = `@agent-api/sdk/${VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-api/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Production JavaScript SDK for the Managed Agent API",
5
5
  "license": "MIT",
6
6
  "repository": {