@eigenpal/sdk 0.4.10 → 0.4.11

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/src/index.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Official TypeScript SDK for the Eigenpal API.
2
+ * Official TypeScript SDK for the EigenPal API.
3
3
  *
4
4
  * @example
5
5
  * ```ts
6
- * import { Eigenpal } from '@eigenpal/sdk';
6
+ * import { EigenpalClient } from '@eigenpal/sdk';
7
7
  *
8
- * const client = new Eigenpal({ apiKey: process.env.EIGENPAL_API_KEY! });
8
+ * const client = new EigenpalClient({ apiKey: process.env.EIGENPAL_API_KEY! });
9
9
  *
10
10
  * // Async — enqueue and poll later.
11
11
  * const { executionId } = await client.workflows.run('wf_abc', { input: { ... } });
@@ -16,10 +16,10 @@
16
16
  * });
17
17
  *
18
18
  * // Client-side poll (up to 5min by default).
19
- * const final = await client.executions.runAndWait('wf_abc', { input: { ... } });
19
+ * const final = await client.workflows.executions.runAndWait('wf_abc', { input: { ... } });
20
20
  * ```
21
21
  */
22
- export { Eigenpal, type EigenpalOptions } from './client';
22
+ export { EigenpalClient, type EigenpalOptions } from './client';
23
23
 
24
24
  export {
25
25
  EigenpalAuthError,
@@ -33,6 +33,11 @@ export {
33
33
  } from './errors';
34
34
 
35
35
  export type { FileDescriptor, FileInput } from './lib/files';
36
+ export type {
37
+ ListAgentExecutionsOptions,
38
+ ListAgentsOptions,
39
+ RunAgentOptions,
40
+ } from './resources/agents';
36
41
  export type {
37
42
  ListVersionsOptions,
38
43
  ListWorkflowsOptions,
@@ -48,17 +53,25 @@ export type { ListExecutionsOptions, RunAndWaitOptions } from './resources/execu
48
53
  // Re-export the canonical generated types so users can type their own
49
54
  // callbacks and helpers without reaching into `./generated`.
50
55
  export type {
56
+ AgentExecutionResponse,
57
+ AgentExecutionSummary,
58
+ AgentSummary,
51
59
  ApiErrorEnvelope,
52
60
  ApiErrorIssue,
53
- CancelExecutionResponse,
61
+ CancelAgentExecutionResponse,
62
+ CancelWorkflowExecutionResponse,
54
63
  ExecutionStatus,
55
- ExecutionStatusResponse,
56
64
  ExecutionSummary,
57
- ListExecutionsResponse,
65
+ GetAgentResponse,
66
+ ListAgentExecutionsResponse,
67
+ ListAgentsResponse,
58
68
  ListVersionsResponse,
69
+ ListWorkflowExecutionsResponse,
59
70
  ListWorkflowsResponse,
71
+ RunAgentResponse,
60
72
  RunWorkflowBody,
61
73
  RunWorkflowResponse,
74
+ WorkflowExecutionStatusResponse,
62
75
  WorkflowSummary,
63
76
  WorkflowVersion,
64
77
  } from './generated/types.gen';
package/src/lib/files.ts CHANGED
@@ -126,3 +126,30 @@ export function buildMultipart(args: {
126
126
 
127
127
  return { formData: fd, fileCount };
128
128
  }
129
+
130
+ /**
131
+ * Build multipart for agent runs. Agent run endpoints consume `_json` as the
132
+ * input object itself, unlike workflow runs where `_json` is a sidecar with
133
+ * `{ input, overrides, trigger }`.
134
+ */
135
+ export function buildAgentMultipart(input?: Record<string, unknown>): MultipartParts {
136
+ const fd = new FormData();
137
+ const inputScalars: Record<string, unknown> = {};
138
+ let fileCount = 0;
139
+
140
+ for (const [key, value] of Object.entries(input ?? {})) {
141
+ if (isFileInput(value)) {
142
+ const { blob, filename } = toBlobAndFilename(value);
143
+ fd.append(key, blob, filename);
144
+ fileCount += 1;
145
+ } else {
146
+ inputScalars[key] = value;
147
+ }
148
+ }
149
+
150
+ if (Object.keys(inputScalars).length > 0) {
151
+ fd.append('_json', JSON.stringify(inputScalars));
152
+ }
153
+
154
+ return { formData: fd, fileCount };
155
+ }
@@ -0,0 +1,168 @@
1
+ import type { OperationResult } from '../client';
2
+ import type { Client } from '../generated/client';
3
+ import {
4
+ agentsCreate,
5
+ agentsExecutionsCancel,
6
+ agentsExecutionsGet,
7
+ agentsExecutionsList,
8
+ agentsGet,
9
+ agentsList,
10
+ agentsRun,
11
+ agentsUpdate,
12
+ } from '../generated/sdk.gen';
13
+ import type {
14
+ AgentExecutionResponse,
15
+ CreateAgentBody,
16
+ CreateAgentResponse,
17
+ GetAgentResponse,
18
+ ListAgentExecutionsResponse,
19
+ ListAgentsResponse,
20
+ PatchAgentBody,
21
+ PatchAgentResponse,
22
+ RunAgentResponse,
23
+ } from '../generated/types.gen';
24
+ import { buildAgentMultipart, hasFileInput } from '../lib/files';
25
+ import type { WorkflowInput } from './workflows';
26
+
27
+ type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
28
+
29
+ export interface ListAgentsOptions {
30
+ search?: string;
31
+ limit?: number;
32
+ offset?: number;
33
+ signal?: AbortSignal;
34
+ }
35
+
36
+ export interface RunAgentOptions {
37
+ waitForCompletion?: number;
38
+ signal?: AbortSignal;
39
+ }
40
+
41
+ export interface ListAgentExecutionsOptions {
42
+ status?: string;
43
+ batchId?: string;
44
+ limit?: number;
45
+ offset?: number;
46
+ signal?: AbortSignal;
47
+ }
48
+
49
+ export class AgentExecutionsResource {
50
+ constructor(
51
+ private readonly client: Client,
52
+ private readonly dispatch: Dispatch
53
+ ) {}
54
+
55
+ async list(
56
+ agentId: string,
57
+ options: ListAgentExecutionsOptions = {}
58
+ ): Promise<ListAgentExecutionsResponse> {
59
+ const { signal, ...query } = options;
60
+ return this.dispatch(() =>
61
+ agentsExecutionsList({ client: this.client, path: { agentId }, query, signal })
62
+ );
63
+ }
64
+
65
+ async get(
66
+ executionId: string,
67
+ options: { include?: string; signal?: AbortSignal } = {}
68
+ ): Promise<AgentExecutionResponse> {
69
+ const { signal, include } = options;
70
+ return this.dispatch(() =>
71
+ agentsExecutionsGet({
72
+ client: this.client,
73
+ path: { executionId },
74
+ query: include ? { include } : {},
75
+ signal,
76
+ })
77
+ );
78
+ }
79
+
80
+ async cancel(
81
+ executionId: string,
82
+ options: { signal?: AbortSignal } = {}
83
+ ): Promise<AgentExecutionResponse> {
84
+ return this.dispatch(() =>
85
+ agentsExecutionsCancel({
86
+ client: this.client,
87
+ path: { executionId },
88
+ signal: options.signal,
89
+ })
90
+ );
91
+ }
92
+ }
93
+
94
+ export class AgentsResource {
95
+ public readonly executions: AgentExecutionsResource;
96
+
97
+ constructor(
98
+ private readonly client: Client,
99
+ private readonly dispatch: Dispatch
100
+ ) {
101
+ this.executions = new AgentExecutionsResource(client, dispatch);
102
+ }
103
+
104
+ async list(options: ListAgentsOptions = {}): Promise<ListAgentsResponse> {
105
+ const { signal, ...query } = options;
106
+ return this.dispatch(() => agentsList({ client: this.client, query, signal }));
107
+ }
108
+
109
+ async get(agentId: string, options: { signal?: AbortSignal } = {}): Promise<GetAgentResponse> {
110
+ return this.dispatch(() =>
111
+ agentsGet({ client: this.client, path: { agentId }, signal: options.signal })
112
+ );
113
+ }
114
+
115
+ async create(
116
+ body: CreateAgentBody,
117
+ options: { signal?: AbortSignal } = {}
118
+ ): Promise<CreateAgentResponse> {
119
+ return this.dispatch(() => agentsCreate({ client: this.client, body, signal: options.signal }));
120
+ }
121
+
122
+ async update(
123
+ agentId: string,
124
+ body: PatchAgentBody,
125
+ options: { signal?: AbortSignal } = {}
126
+ ): Promise<PatchAgentResponse> {
127
+ return this.dispatch(() =>
128
+ agentsUpdate({ client: this.client, path: { agentId }, body, signal: options.signal })
129
+ );
130
+ }
131
+
132
+ async run(
133
+ agentId: string,
134
+ input?: WorkflowInput,
135
+ options: RunAgentOptions = {}
136
+ ): Promise<RunAgentResponse> {
137
+ const query =
138
+ options.waitForCompletion !== undefined
139
+ ? { wait_for_completion: options.waitForCompletion }
140
+ : {};
141
+
142
+ if (hasFileInput(input)) {
143
+ const { formData } = buildAgentMultipart(input);
144
+ return this.dispatch<RunAgentResponse>(
145
+ () =>
146
+ this.client.post({
147
+ url: '/api/v1/agents/{agentId}/run',
148
+ path: { agentId },
149
+ query,
150
+ body: formData,
151
+ bodySerializer: null,
152
+ headers: { 'Content-Type': null },
153
+ signal: options.signal,
154
+ }) as Promise<OperationResult<RunAgentResponse>>
155
+ );
156
+ }
157
+
158
+ return this.dispatch(() =>
159
+ agentsRun({
160
+ client: this.client,
161
+ path: { agentId },
162
+ query,
163
+ body: { ...(input !== undefined ? { input } : {}) },
164
+ signal: options.signal,
165
+ })
166
+ );
167
+ }
168
+ }
@@ -2,25 +2,24 @@ import type { OperationResult } from '../client';
2
2
  import { EigenpalTimeoutError } from '../errors';
3
3
  import type { Client } from '../generated/client';
4
4
  import {
5
- executionsCancel,
6
- executionsGet,
7
- executionsList,
5
+ workflowsExecutionsCancel,
6
+ workflowsExecutionsGet,
7
+ workflowsExecutionsList,
8
8
  workflowsRun,
9
9
  } from '../generated/sdk.gen';
10
10
  import type {
11
- CancelExecutionResponse,
11
+ CancelWorkflowExecutionResponse,
12
12
  ExecutionStatus,
13
- ExecutionStatusResponse,
14
- ListExecutionsResponse,
13
+ ListWorkflowExecutionsResponse,
15
14
  RunWorkflowResponse,
15
+ WorkflowExecutionStatusResponse,
16
16
  } from '../generated/types.gen';
17
17
  import { buildMultipart, hasFileInput } from '../lib/files';
18
18
  import type { WorkflowInput } from './workflows';
19
19
 
20
20
  export interface ListExecutionsOptions {
21
- workflowId?: string;
22
- /** Comma-separated list of execution statuses. */
23
- status?: string;
21
+ /** Execution status, or an array of statuses. */
22
+ status?: string | string[];
24
23
  /** ISO timestamp or relative expression like `"now()-7d"`. */
25
24
  fromDate?: string;
26
25
  toDate?: string;
@@ -59,11 +58,11 @@ const DEFAULT_RUN_AND_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
59
58
  type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
60
59
 
61
60
  /**
62
- * Execution resource — read execution status, list executions, cancel
63
- * in-flight runs, and the convenience `runAndWait` helper that wraps a
64
- * workflow trigger + client-side poll loop. Reached via `client.executions`.
61
+ * Workflow execution resource — read execution status, list executions, cancel
62
+ * in-flight executions, and the convenience `runAndWait` helper that wraps a
63
+ * workflow trigger + client-side poll loop. Reached via `client.workflows.executions`.
65
64
  */
66
- export class ExecutionsResource {
65
+ export class WorkflowExecutionsResource {
67
66
  constructor(
68
67
  private readonly client: Client,
69
68
  private readonly dispatch: Dispatch
@@ -73,31 +72,44 @@ export class ExecutionsResource {
73
72
  async get(
74
73
  executionId: string,
75
74
  options: { includeSteps?: boolean; signal?: AbortSignal } = {}
76
- ): Promise<ExecutionStatusResponse> {
77
- return this.dispatch<ExecutionStatusResponse>(
75
+ ): Promise<WorkflowExecutionStatusResponse> {
76
+ return this.dispatch<WorkflowExecutionStatusResponse>(
78
77
  () =>
79
- executionsGet({
78
+ workflowsExecutionsGet({
80
79
  client: this.client,
81
80
  path: { executionId },
82
81
  query: options.includeSteps ? { includeSteps: 'true' } : {},
83
82
  signal: options.signal,
84
- }) as Promise<OperationResult<ExecutionStatusResponse>>
83
+ }) as Promise<OperationResult<WorkflowExecutionStatusResponse>>
85
84
  );
86
85
  }
87
86
 
88
87
  /** List executions, paginated. */
89
- async list(options: ListExecutionsOptions = {}): Promise<ListExecutionsResponse> {
90
- const { signal, ...query } = options;
91
- return this.dispatch(() => executionsList({ client: this.client, query, signal }));
88
+ async list(
89
+ workflowId: string,
90
+ options: ListExecutionsOptions = {}
91
+ ): Promise<ListWorkflowExecutionsResponse> {
92
+ const { signal, status, ...rest } = options;
93
+ // Wire format takes comma-separated lists; idiomatic JS callers can
94
+ // pass a string[] and we serialize.
95
+ const query = {
96
+ ...rest,
97
+ ...(status !== undefined
98
+ ? { status: Array.isArray(status) ? status.join(',') : status }
99
+ : {}),
100
+ };
101
+ return this.dispatch(() =>
102
+ workflowsExecutionsList({ client: this.client, path: { id: workflowId }, query, signal })
103
+ );
92
104
  }
93
105
 
94
106
  /** Cancel an execution. Idempotent. */
95
107
  async cancel(
96
108
  executionId: string,
97
109
  options: { signal?: AbortSignal } = {}
98
- ): Promise<CancelExecutionResponse> {
110
+ ): Promise<CancelWorkflowExecutionResponse> {
99
111
  return this.dispatch(() =>
100
- executionsCancel({
112
+ workflowsExecutionsCancel({
101
113
  client: this.client,
102
114
  path: { executionId },
103
115
  signal: options.signal,
@@ -128,7 +140,7 @@ export class ExecutionsResource {
128
140
  ? await this.dispatch<RunWorkflowResponse>(() => {
129
141
  const { formData } = buildMultipart({ input, overrides: options.overrides });
130
142
  return this.client.post({
131
- url: '/v1/workflows/{id}/run',
143
+ url: '/api/v1/workflows/{id}/run',
132
144
  path: { id: workflowId },
133
145
  query: triggerQuery,
134
146
  body: formData,
@@ -13,6 +13,7 @@ import type {
13
13
  WorkflowSummary,
14
14
  } from '../generated/types.gen';
15
15
  import { buildMultipart, hasFileInput } from '../lib/files';
16
+ import { WorkflowExecutionsResource } from './executions';
16
17
 
17
18
  /**
18
19
  * Workflow inputs keyed by name as declared in the workflow YAML.
@@ -58,10 +59,14 @@ type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
58
59
  * workflows. Reached via `client.workflows`.
59
60
  */
60
61
  export class WorkflowsResource {
62
+ public readonly executions: WorkflowExecutionsResource;
63
+
61
64
  constructor(
62
65
  private readonly client: Client,
63
66
  private readonly dispatch: Dispatch
64
- ) {}
67
+ ) {
68
+ this.executions = new WorkflowExecutionsResource(client, dispatch);
69
+ }
65
70
 
66
71
  /**
67
72
  * Execute a workflow.
@@ -71,7 +76,8 @@ export class WorkflowsResource {
71
76
  * @param options — `version`, `waitForCompletion`, `overrides`.
72
77
  *
73
78
  * - With no `waitForCompletion`, returns immediately with `{ executionId }`.
74
- * Poll via `client.executions.get(id)` or use `client.executions.runAndWait`.
79
+ * Poll via `client.workflows.executions.get(id)` or use
80
+ * `client.workflows.executions.runAndWait`.
75
81
  * - With `waitForCompletion: 60`, the server holds the connection up to 60
76
82
  * seconds. The response also includes `status`, `result`, and `error`
77
83
  * when the run finishes within the window.
@@ -94,7 +100,7 @@ export class WorkflowsResource {
94
100
  return this.dispatch<RunWorkflowResponse>(
95
101
  () =>
96
102
  this.client.post({
97
- url: '/v1/workflows/{id}/run',
103
+ url: '/api/v1/workflows/{id}/run',
98
104
  path: { id: workflowId },
99
105
  query,
100
106
  body: formData,
@@ -3,11 +3,11 @@ import type { CreateClientConfig } from './generated/client.gen';
3
3
  /**
4
4
  * Runtime configuration hook for the generated hey-api client.
5
5
  *
6
- * The hand-written `Eigenpal` class in `client.ts` calls
6
+ * The hand-written `EigenpalClient` class in `client.ts` calls
7
7
  * `setClientConfig()` on construction with the user's `apiKey` and
8
8
  * `baseUrl`, so the generated SDK functions automatically pick up the
9
9
  * Authorization header. This factory returns a no-op default — values
10
- * are populated when an `Eigenpal` instance is created.
10
+ * are populated when an `EigenpalClient` instance is created.
11
11
  */
12
12
  export const createClientConfig: CreateClientConfig = (config) => ({
13
13
  ...config,
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SDK telemetry headers attached to every outbound request.
3
+ *
4
+ * The server reads these to track adoption — which language, which
5
+ * version, which runtime are calling? Lets us answer "should we still
6
+ * support Node 20?" or "is the 0.4 series still in use?" from log
7
+ * aggregation alone, without having to ship a separate phone-home.
8
+ *
9
+ * Header convention follows the Stainless / Anthropic SDK pattern:
10
+ * X-Eigenpal-Sdk — language tag ("typescript")
11
+ * X-Eigenpal-Sdk-Version — package version (rewritten at publish)
12
+ * X-Eigenpal-Sdk-Runtime — "bun-1.3.11" / "node-22.0.0" / "deno-X" / "browser"
13
+ * X-Eigenpal-Sdk-Os — "darwin-arm64" / "linux-x64" / "browser"
14
+ *
15
+ * `User-Agent` carries the same info in a single human-readable string
16
+ * for log lines and proxies that don't surface custom headers.
17
+ */
18
+
19
+ export const SDK_LANGUAGE = 'typescript';
20
+ // Rewritten at publish time by scripts/render-sdk-versions.sh.
21
+ // Keep this string literal exactly stable — sed matches on it.
22
+ export const SDK_VERSION = '0.4.11';
23
+
24
+ function detectRuntime(): string {
25
+ const g = globalThis as unknown as {
26
+ Bun?: { version: string };
27
+ Deno?: { version?: { deno?: string } };
28
+ };
29
+ if (g.Bun?.version) return `bun-${g.Bun.version}`;
30
+ if (g.Deno?.version?.deno) return `deno-${g.Deno.version.deno}`;
31
+ if (typeof process !== 'undefined' && process.versions?.node) {
32
+ return `node-${process.versions.node}`;
33
+ }
34
+ return 'browser';
35
+ }
36
+
37
+ function detectOs(): string {
38
+ if (typeof process !== 'undefined' && process.platform) {
39
+ return `${process.platform}-${process.arch}`;
40
+ }
41
+ return 'browser';
42
+ }
43
+
44
+ export function buildTelemetryHeaders(): Record<string, string> {
45
+ const runtime = detectRuntime();
46
+ const os = detectOs();
47
+ return {
48
+ 'X-Eigenpal-Sdk': SDK_LANGUAGE,
49
+ 'X-Eigenpal-Sdk-Version': SDK_VERSION,
50
+ 'X-Eigenpal-Sdk-Runtime': runtime,
51
+ 'X-Eigenpal-Sdk-Os': os,
52
+ 'User-Agent': `eigenpal-sdk-typescript/${SDK_VERSION} (${runtime}; ${os})`,
53
+ };
54
+ }