@eigenpal/sdk 0.6.14 → 0.6.15
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 +8 -0
- package/README.md +20 -20
- package/package.json +1 -1
- package/src/client.ts +173 -4
- package/src/generated/index.ts +8 -16
- package/src/generated/sdk.gen.ts +25 -42
- package/src/generated/types.gen.ts +105 -207
- package/src/index.ts +17 -9
- package/src/lib/files.ts +22 -32
- package/src/resources/agents.ts +0 -52
- package/src/resources/executions.ts +38 -32
- package/src/resources/workflows.ts +3 -80
- package/src/telemetry.ts +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { OperationResult } from '../client';
|
|
2
2
|
import { EigenpalTimeoutError } from '../errors';
|
|
3
3
|
import type { Client } from '../generated/client';
|
|
4
|
-
import { runsGet
|
|
5
|
-
import type { ExecutionStatus, RunsGetResponse
|
|
6
|
-
import {
|
|
4
|
+
import { runsGet } from '../generated/sdk.gen';
|
|
5
|
+
import type { ExecutionStatus, RunsGetResponse } from '../generated/types.gen';
|
|
6
|
+
import { buildRunJsonBody, buildRunMultipart, hasFileInput } from '../lib/files';
|
|
7
7
|
import type { WorkflowInput } from './workflows';
|
|
8
8
|
|
|
9
9
|
export interface RunAndWaitOptions {
|
|
@@ -22,6 +22,13 @@ export interface RunAndWaitOptions {
|
|
|
22
22
|
signal?: AbortSignal;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export type WorkflowRunAndWaitResponse = {
|
|
26
|
+
runId: string;
|
|
27
|
+
status?: ExecutionStatus;
|
|
28
|
+
output?: unknown;
|
|
29
|
+
error?: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
25
32
|
const TERMINAL_STATUSES = new Set<ExecutionStatus>([
|
|
26
33
|
'completed',
|
|
27
34
|
'failed',
|
|
@@ -48,55 +55,54 @@ export class WorkflowExecutionsResource {
|
|
|
48
55
|
/**
|
|
49
56
|
* Trigger a workflow and poll for completion client-side.
|
|
50
57
|
*
|
|
51
|
-
* Unlike `
|
|
58
|
+
* Unlike `client.run({ waitForCompletion: 60 })`, this helper polls
|
|
52
59
|
* indefinitely (up to `timeoutMs`, default 5 min) so it works for runs
|
|
53
60
|
* that exceed the server-side 60s sync window. Returns the final
|
|
54
|
-
* response with `status`/`
|
|
61
|
+
* response with `status`/`output`/`error` populated.
|
|
55
62
|
*/
|
|
56
63
|
async runAndWait(
|
|
57
64
|
workflowId: string,
|
|
58
65
|
input?: WorkflowInput,
|
|
59
66
|
options: RunAndWaitOptions = {}
|
|
60
|
-
): Promise<
|
|
67
|
+
): Promise<WorkflowRunAndWaitResponse> {
|
|
61
68
|
const pollInterval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
62
69
|
const timeoutMs = options.timeoutMs ?? DEFAULT_RUN_AND_WAIT_TIMEOUT_MS;
|
|
63
70
|
const deadline = Date.now() + timeoutMs;
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
72
|
+
const target = `workflows.${workflowId}`;
|
|
73
|
+
const runUrl = `/api/v1/run/${encodeURIComponent(target)}`;
|
|
74
|
+
const runQuery =
|
|
75
|
+
options.version && options.version !== 'latest' ? { version: options.version } : undefined;
|
|
76
|
+
let runResult: { runId: string };
|
|
68
77
|
if (hasFileInput(input)) {
|
|
69
78
|
// Build the multipart body once, up front — `dispatch` may retry the
|
|
70
79
|
// POST, and a drained stream cannot be replayed.
|
|
71
|
-
const { formData } = await
|
|
72
|
-
runResult = await this.dispatch<
|
|
80
|
+
const { formData } = await buildRunMultipart({ input, overrides: options.overrides });
|
|
81
|
+
runResult = await this.dispatch<{ runId: string }>(
|
|
73
82
|
() =>
|
|
74
83
|
this.client.post({
|
|
75
|
-
url:
|
|
76
|
-
|
|
77
|
-
query: triggerQuery,
|
|
84
|
+
url: runUrl,
|
|
85
|
+
query: runQuery,
|
|
78
86
|
body: formData,
|
|
79
87
|
bodySerializer: null,
|
|
80
88
|
headers: { 'Content-Type': null },
|
|
81
89
|
signal: options.signal,
|
|
82
|
-
}) as Promise<OperationResult<
|
|
90
|
+
}) as Promise<OperationResult<{ runId: string }>>
|
|
83
91
|
);
|
|
84
92
|
} else {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
signal: options.signal,
|
|
95
|
-
})
|
|
93
|
+
const body = buildRunJsonBody(input, options.overrides);
|
|
94
|
+
runResult = await this.dispatch<{ runId: string }>(
|
|
95
|
+
() =>
|
|
96
|
+
this.client.post({
|
|
97
|
+
url: runUrl,
|
|
98
|
+
query: runQuery,
|
|
99
|
+
body,
|
|
100
|
+
signal: options.signal,
|
|
101
|
+
}) as Promise<OperationResult<{ runId: string }>>
|
|
96
102
|
);
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
const
|
|
105
|
+
const runId = runResult.runId;
|
|
100
106
|
|
|
101
107
|
while (true) {
|
|
102
108
|
if (options.signal?.aborted) {
|
|
@@ -104,7 +110,7 @@ export class WorkflowExecutionsResource {
|
|
|
104
110
|
}
|
|
105
111
|
if (Date.now() >= deadline) {
|
|
106
112
|
throw new EigenpalTimeoutError(
|
|
107
|
-
`runAndWait timed out after ${timeoutMs}ms (
|
|
113
|
+
`runAndWait timed out after ${timeoutMs}ms (runId=${runId})`
|
|
108
114
|
);
|
|
109
115
|
}
|
|
110
116
|
|
|
@@ -112,22 +118,22 @@ export class WorkflowExecutionsResource {
|
|
|
112
118
|
() =>
|
|
113
119
|
runsGet({
|
|
114
120
|
client: this.client,
|
|
115
|
-
path: { id:
|
|
121
|
+
path: { id: runId },
|
|
116
122
|
query: { include: 'detail' },
|
|
117
123
|
signal: options.signal,
|
|
118
124
|
}) as Promise<OperationResult<RunsGetResponse>>
|
|
119
125
|
);
|
|
120
126
|
const status = response.run as {
|
|
121
127
|
status?: ExecutionStatus | null;
|
|
122
|
-
|
|
128
|
+
output?: unknown;
|
|
123
129
|
error?: string | null;
|
|
124
130
|
};
|
|
125
131
|
|
|
126
132
|
if (status.status && TERMINAL_STATUSES.has(status.status)) {
|
|
127
133
|
return {
|
|
128
|
-
|
|
134
|
+
runId,
|
|
129
135
|
status: status.status,
|
|
130
|
-
...(status.
|
|
136
|
+
...(status.output != null ? { output: status.output } : {}),
|
|
131
137
|
...(status.error != null ? { error: status.error } : {}),
|
|
132
138
|
};
|
|
133
139
|
}
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import type { OperationResult } from '../client';
|
|
2
2
|
import type { Client } from '../generated/client';
|
|
3
|
-
import {
|
|
4
|
-
workflowsGet,
|
|
5
|
-
workflowsList,
|
|
6
|
-
workflowsRun,
|
|
7
|
-
workflowsVersionsList,
|
|
8
|
-
} from '../generated/sdk.gen';
|
|
3
|
+
import { workflowsGet, workflowsList, workflowsVersionsList } from '../generated/sdk.gen';
|
|
9
4
|
import type {
|
|
10
5
|
ListVersionsResponse,
|
|
11
6
|
ListWorkflowsResponse,
|
|
12
|
-
RunWorkflowResponse,
|
|
13
7
|
WorkflowDetail,
|
|
14
8
|
} from '../generated/types.gen';
|
|
15
|
-
import { buildMultipart, hasFileInput } from '../lib/files';
|
|
16
9
|
import { WorkflowExecutionsResource } from './executions';
|
|
17
10
|
|
|
18
11
|
/**
|
|
@@ -24,17 +17,6 @@ import { WorkflowExecutionsResource } from './executions';
|
|
|
24
17
|
*/
|
|
25
18
|
export type WorkflowInput = Record<string, unknown>;
|
|
26
19
|
|
|
27
|
-
export interface RunWorkflowOptions {
|
|
28
|
-
/** Specific version id, or `"latest"` (default). */
|
|
29
|
-
version?: string;
|
|
30
|
-
/** Hold the connection up to N seconds for completion (max 60). Omit for async. */
|
|
31
|
-
waitForCompletion?: number;
|
|
32
|
-
/** Per-step output overrides for replay. */
|
|
33
|
-
overrides?: { steps?: Record<string, Record<string, unknown>> };
|
|
34
|
-
/** AbortSignal to cancel the request. */
|
|
35
|
-
signal?: AbortSignal;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
20
|
export interface ListWorkflowsOptions {
|
|
39
21
|
/** Substring match against workflow name. */
|
|
40
22
|
search?: string;
|
|
@@ -55,8 +37,9 @@ export interface ListVersionsOptions {
|
|
|
55
37
|
type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
|
|
56
38
|
|
|
57
39
|
/**
|
|
58
|
-
* Workflow resource — list, get,
|
|
40
|
+
* Workflow resource — list, get, and inspect versions of saved workflows.
|
|
59
41
|
* Existing run retrieval and mutation lives on `client.runs`.
|
|
42
|
+
* Starting runs lives on root `client.run(...)`.
|
|
60
43
|
*/
|
|
61
44
|
export class WorkflowsResource {
|
|
62
45
|
public readonly executions: WorkflowExecutionsResource;
|
|
@@ -68,66 +51,6 @@ export class WorkflowsResource {
|
|
|
68
51
|
this.executions = new WorkflowExecutionsResource(client, dispatch);
|
|
69
52
|
}
|
|
70
53
|
|
|
71
|
-
/**
|
|
72
|
-
* Execute a workflow.
|
|
73
|
-
*
|
|
74
|
-
* @param workflowId — id like `wf_abc123`.
|
|
75
|
-
* @param input — workflow inputs keyed by name. Pass `undefined` for inputs-less workflows.
|
|
76
|
-
* @param options — `version`, `waitForCompletion`, `overrides`.
|
|
77
|
-
*
|
|
78
|
-
* - With no `waitForCompletion`, returns immediately with `{ executionId }`.
|
|
79
|
-
* Poll via `client.runs.get(id)` or use `client.workflows.executions.runAndWait`.
|
|
80
|
-
* - With `waitForCompletion: 60`, the server holds the connection up to 60
|
|
81
|
-
* seconds. The response also includes `status`, `result`, and `error`
|
|
82
|
-
* when the run finishes within the window.
|
|
83
|
-
*/
|
|
84
|
-
async run(
|
|
85
|
-
workflowId: string,
|
|
86
|
-
input?: WorkflowInput,
|
|
87
|
-
options: RunWorkflowOptions = {}
|
|
88
|
-
): Promise<RunWorkflowResponse> {
|
|
89
|
-
const query = {
|
|
90
|
-
...(options.version ? { version: options.version } : {}),
|
|
91
|
-
...(options.waitForCompletion !== undefined
|
|
92
|
-
? { wait_for_completion: options.waitForCompletion }
|
|
93
|
-
: {}),
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// File-bearing input → multipart/form-data (no base64 overhead).
|
|
97
|
-
if (hasFileInput(input)) {
|
|
98
|
-
const { formData } = await buildMultipart({ input, overrides: options.overrides });
|
|
99
|
-
return this.dispatch<RunWorkflowResponse>(
|
|
100
|
-
() =>
|
|
101
|
-
this.client.post({
|
|
102
|
-
url: '/api/v1/workflows/{id}/run',
|
|
103
|
-
path: { id: workflowId },
|
|
104
|
-
query,
|
|
105
|
-
body: formData,
|
|
106
|
-
// Skip JSON serialization; FormData passes through to fetch which
|
|
107
|
-
// sets the Content-Type header (with boundary) automatically.
|
|
108
|
-
bodySerializer: null,
|
|
109
|
-
// Explicitly null the JSON Content-Type header that the request
|
|
110
|
-
// pipeline would otherwise inherit.
|
|
111
|
-
headers: { 'Content-Type': null },
|
|
112
|
-
signal: options.signal,
|
|
113
|
-
}) as Promise<OperationResult<RunWorkflowResponse>>
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return this.dispatch<RunWorkflowResponse>(() =>
|
|
118
|
-
workflowsRun({
|
|
119
|
-
client: this.client,
|
|
120
|
-
path: { id: workflowId },
|
|
121
|
-
query,
|
|
122
|
-
body: {
|
|
123
|
-
...(input !== undefined ? { input } : {}),
|
|
124
|
-
...(options.overrides ? { overrides: options.overrides } : {}),
|
|
125
|
-
},
|
|
126
|
-
signal: options.signal,
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
54
|
/** List workflows, paginated. */
|
|
132
55
|
async list(options: ListWorkflowsOptions = {}): Promise<ListWorkflowsResponse> {
|
|
133
56
|
const { signal, ...query } = options;
|
package/src/telemetry.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
export const SDK_LANGUAGE = 'typescript';
|
|
20
20
|
// Rewritten at publish time by scripts/render-sdk-versions.sh.
|
|
21
21
|
// Keep this string literal exactly stable — sed matches on it.
|
|
22
|
-
export const SDK_VERSION = '0.6.
|
|
22
|
+
export const SDK_VERSION = '0.6.15';
|
|
23
23
|
|
|
24
24
|
function detectRuntime(): string {
|
|
25
25
|
const g = globalThis as unknown as {
|