@eigenpal/sdk 0.0.0-placeholder
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 +7 -0
- package/LICENSE +201 -0
- package/README.md +179 -0
- package/package.json +51 -0
- package/src/client.ts +237 -0
- package/src/errors.ts +103 -0
- package/src/generated/client/client.gen.ts +280 -0
- package/src/generated/client/index.ts +25 -0
- package/src/generated/client/types.gen.ts +214 -0
- package/src/generated/client/utils.gen.ts +318 -0
- package/src/generated/client.gen.ts +22 -0
- package/src/generated/core/auth.gen.ts +41 -0
- package/src/generated/core/bodySerializer.gen.ts +82 -0
- package/src/generated/core/params.gen.ts +169 -0
- package/src/generated/core/pathSerializer.gen.ts +171 -0
- package/src/generated/core/queryKeySerializer.gen.ts +117 -0
- package/src/generated/core/serverSentEvents.gen.ts +242 -0
- package/src/generated/core/types.gen.ts +104 -0
- package/src/generated/core/utils.gen.ts +140 -0
- package/src/generated/index.ts +63 -0
- package/src/generated/sdk.gen.ts +151 -0
- package/src/generated/types.gen.ts +608 -0
- package/src/index.ts +64 -0
- package/src/lib/files.ts +128 -0
- package/src/resources/executions.ts +179 -0
- package/src/resources/workflows.ts +154 -0
- package/src/runtime-config.ts +15 -0
package/src/lib/files.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-input helpers for `client.workflows.run()`.
|
|
3
|
+
*
|
|
4
|
+
* Pass a `File`, `Blob`, or explicit `{ content, filename, mimeType }` triple
|
|
5
|
+
* as a workflow input value. The SDK auto-detects file values and uploads
|
|
6
|
+
* them as `multipart/form-data` — matching `curl -F`. No base64 needed.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Explicit file descriptor — raw bytes plus metadata. Use when you have a
|
|
11
|
+
* `Buffer` / `Uint8Array` / `ArrayBuffer` and want to set the filename /
|
|
12
|
+
* mime type yourself (a bare `Blob` has no filename).
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* await client.workflows.run('extract-invoice', {
|
|
16
|
+
* contract_document: {
|
|
17
|
+
* content: buffer,
|
|
18
|
+
* filename: 'contract.pdf',
|
|
19
|
+
* mimeType: 'application/pdf',
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export interface FileDescriptor {
|
|
25
|
+
content: ArrayBuffer | ArrayBufferView | Blob;
|
|
26
|
+
filename: string;
|
|
27
|
+
mimeType?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Any value that the SDK accepts as a "file" workflow input.
|
|
32
|
+
*/
|
|
33
|
+
export type FileInput = Blob | FileDescriptor;
|
|
34
|
+
|
|
35
|
+
const DEFAULT_MIME = 'application/octet-stream';
|
|
36
|
+
|
|
37
|
+
export function isFileInput(value: unknown): value is FileInput {
|
|
38
|
+
if (typeof Blob !== 'undefined' && value instanceof Blob) return true;
|
|
39
|
+
if (value !== null && typeof value === 'object') {
|
|
40
|
+
const v = value as { content?: unknown; filename?: unknown };
|
|
41
|
+
if (
|
|
42
|
+
typeof v.filename === 'string' &&
|
|
43
|
+
v.content != null &&
|
|
44
|
+
(v.content instanceof ArrayBuffer ||
|
|
45
|
+
ArrayBuffer.isView(v.content) ||
|
|
46
|
+
(typeof Blob !== 'undefined' && v.content instanceof Blob))
|
|
47
|
+
) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function hasFileInput(input: Record<string, unknown> | undefined): boolean {
|
|
55
|
+
if (!input) return false;
|
|
56
|
+
for (const value of Object.values(input)) {
|
|
57
|
+
if (isFileInput(value)) return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Convert a `FileInput` to `{ blob, filename }` for `FormData.append`. */
|
|
63
|
+
function toBlobAndFilename(file: FileInput): { blob: Blob; filename: string } {
|
|
64
|
+
// File extends Blob, so the Blob branch covers it.
|
|
65
|
+
if (typeof Blob !== 'undefined' && file instanceof Blob) {
|
|
66
|
+
const name = (file as File).name ?? 'file';
|
|
67
|
+
return { blob: file, filename: name };
|
|
68
|
+
}
|
|
69
|
+
const desc = file as FileDescriptor;
|
|
70
|
+
const content = desc.content;
|
|
71
|
+
const type = desc.mimeType ?? DEFAULT_MIME;
|
|
72
|
+
let blob: Blob;
|
|
73
|
+
if (content instanceof Blob) {
|
|
74
|
+
blob = type && content.type !== type ? content.slice(0, content.size, type) : content;
|
|
75
|
+
} else {
|
|
76
|
+
// ArrayBuffer or ArrayBufferView — wrap in a Blob.
|
|
77
|
+
blob = new Blob([content as BlobPart], { type });
|
|
78
|
+
}
|
|
79
|
+
return { blob, filename: desc.filename };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface MultipartParts {
|
|
83
|
+
/** FormData ready to send as the request body. */
|
|
84
|
+
formData: FormData;
|
|
85
|
+
/** Number of file fields appended (0 means no files were detected). */
|
|
86
|
+
fileCount: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Build a `multipart/form-data` body that matches what
|
|
91
|
+
* `processMultipartRunBody` on the server expects:
|
|
92
|
+
*
|
|
93
|
+
* - Each file in `input` becomes a top-level form field (key = input name).
|
|
94
|
+
* - Non-file inputs + overrides + trigger go in a `_json` text field.
|
|
95
|
+
*
|
|
96
|
+
* Only top-level file values are extracted. Files nested inside arrays /
|
|
97
|
+
* objects keep their position in the JSON sidecar — the server doesn't
|
|
98
|
+
* support nested file uploads via multipart.
|
|
99
|
+
*/
|
|
100
|
+
export function buildMultipart(args: {
|
|
101
|
+
input?: Record<string, unknown>;
|
|
102
|
+
overrides?: { steps?: Record<string, Record<string, unknown>> };
|
|
103
|
+
trigger?: 'api' | 'cli';
|
|
104
|
+
}): MultipartParts {
|
|
105
|
+
const fd = new FormData();
|
|
106
|
+
const inputScalars: Record<string, unknown> = {};
|
|
107
|
+
let fileCount = 0;
|
|
108
|
+
|
|
109
|
+
for (const [key, value] of Object.entries(args.input ?? {})) {
|
|
110
|
+
if (isFileInput(value)) {
|
|
111
|
+
const { blob, filename } = toBlobAndFilename(value);
|
|
112
|
+
fd.append(key, blob, filename);
|
|
113
|
+
fileCount += 1;
|
|
114
|
+
} else {
|
|
115
|
+
inputScalars[key] = value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const sidecar: Record<string, unknown> = {};
|
|
120
|
+
if (Object.keys(inputScalars).length > 0) sidecar.input = inputScalars;
|
|
121
|
+
if (args.overrides) sidecar.overrides = args.overrides;
|
|
122
|
+
if (args.trigger) sidecar.trigger = args.trigger;
|
|
123
|
+
if (Object.keys(sidecar).length > 0) {
|
|
124
|
+
fd.append('_json', JSON.stringify(sidecar));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return { formData: fd, fileCount };
|
|
128
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type { OperationResult } from '../client';
|
|
2
|
+
import { EigenpalTimeoutError } from '../errors';
|
|
3
|
+
import type { Client } from '../generated/client';
|
|
4
|
+
import {
|
|
5
|
+
executionsCancel,
|
|
6
|
+
executionsGet,
|
|
7
|
+
executionsList,
|
|
8
|
+
workflowsRun,
|
|
9
|
+
} from '../generated/sdk.gen';
|
|
10
|
+
import type {
|
|
11
|
+
CancelExecutionResponse,
|
|
12
|
+
ExecutionStatus,
|
|
13
|
+
ExecutionStatusResponse,
|
|
14
|
+
ListExecutionsResponse,
|
|
15
|
+
RunWorkflowResponse,
|
|
16
|
+
} from '../generated/types.gen';
|
|
17
|
+
import { buildMultipart, hasFileInput } from '../lib/files';
|
|
18
|
+
import type { WorkflowInput } from './workflows';
|
|
19
|
+
|
|
20
|
+
export interface ListExecutionsOptions {
|
|
21
|
+
workflowId?: string;
|
|
22
|
+
/** Comma-separated list of execution statuses. */
|
|
23
|
+
status?: string;
|
|
24
|
+
/** ISO timestamp or relative expression like `"now()-7d"`. */
|
|
25
|
+
fromDate?: string;
|
|
26
|
+
toDate?: string;
|
|
27
|
+
exampleId?: string;
|
|
28
|
+
limit?: number;
|
|
29
|
+
offset?: number;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RunAndWaitOptions {
|
|
34
|
+
/** Workflow version. Default: `"latest"`. */
|
|
35
|
+
version?: string;
|
|
36
|
+
/** Per-step output overrides for replay. */
|
|
37
|
+
overrides?: { steps?: Record<string, Record<string, unknown>> };
|
|
38
|
+
/** Polling interval in milliseconds. Default: 2_000. */
|
|
39
|
+
pollIntervalMs?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Total client-side timeout in milliseconds. Default: 5 minutes. Throws
|
|
42
|
+
* `EigenpalTimeoutError` if the run hasn't reached a terminal state by then.
|
|
43
|
+
*/
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
/** AbortSignal to cancel the entire poll loop. */
|
|
46
|
+
signal?: AbortSignal;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const TERMINAL_STATUSES = new Set<ExecutionStatus>([
|
|
50
|
+
'completed',
|
|
51
|
+
'failed',
|
|
52
|
+
'cancelled',
|
|
53
|
+
'rejected',
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
const DEFAULT_POLL_INTERVAL_MS = 2_000;
|
|
57
|
+
const DEFAULT_RUN_AND_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
58
|
+
|
|
59
|
+
type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
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`.
|
|
65
|
+
*/
|
|
66
|
+
export class ExecutionsResource {
|
|
67
|
+
constructor(
|
|
68
|
+
private readonly client: Client,
|
|
69
|
+
private readonly dispatch: Dispatch
|
|
70
|
+
) {}
|
|
71
|
+
|
|
72
|
+
/** Get execution status. Pass `includeSteps` for the full per-step payload. */
|
|
73
|
+
async get(
|
|
74
|
+
executionId: string,
|
|
75
|
+
options: { includeSteps?: boolean; signal?: AbortSignal } = {}
|
|
76
|
+
): Promise<ExecutionStatusResponse> {
|
|
77
|
+
return this.dispatch<ExecutionStatusResponse>(
|
|
78
|
+
() =>
|
|
79
|
+
executionsGet({
|
|
80
|
+
client: this.client,
|
|
81
|
+
path: { executionId },
|
|
82
|
+
query: options.includeSteps ? { includeSteps: 'true' } : {},
|
|
83
|
+
signal: options.signal,
|
|
84
|
+
}) as Promise<OperationResult<ExecutionStatusResponse>>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 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 }));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Cancel an execution. Idempotent. */
|
|
95
|
+
async cancel(
|
|
96
|
+
executionId: string,
|
|
97
|
+
options: { signal?: AbortSignal } = {}
|
|
98
|
+
): Promise<CancelExecutionResponse> {
|
|
99
|
+
return this.dispatch(() =>
|
|
100
|
+
executionsCancel({
|
|
101
|
+
client: this.client,
|
|
102
|
+
path: { executionId },
|
|
103
|
+
signal: options.signal,
|
|
104
|
+
})
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Trigger a workflow and poll for completion client-side.
|
|
110
|
+
*
|
|
111
|
+
* Unlike `workflows.run({ waitForCompletion: 60 })`, this helper polls
|
|
112
|
+
* indefinitely (up to `timeoutMs`, default 5 min) so it works for runs
|
|
113
|
+
* that exceed the server-side 60s sync window. Returns the final
|
|
114
|
+
* response with `status`/`result`/`error` populated.
|
|
115
|
+
*/
|
|
116
|
+
async runAndWait(
|
|
117
|
+
workflowId: string,
|
|
118
|
+
input?: WorkflowInput,
|
|
119
|
+
options: RunAndWaitOptions = {}
|
|
120
|
+
): Promise<RunWorkflowResponse> {
|
|
121
|
+
const pollInterval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
122
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_RUN_AND_WAIT_TIMEOUT_MS;
|
|
123
|
+
const deadline = Date.now() + timeoutMs;
|
|
124
|
+
|
|
125
|
+
// Trigger async — we don't ask the server to wait, since we're polling.
|
|
126
|
+
const triggerQuery = options.version ? { version: options.version } : {};
|
|
127
|
+
const runResult = hasFileInput(input)
|
|
128
|
+
? await this.dispatch<RunWorkflowResponse>(() => {
|
|
129
|
+
const { formData } = buildMultipart({ input, overrides: options.overrides });
|
|
130
|
+
return this.client.post({
|
|
131
|
+
url: '/v1/workflows/{id}/run',
|
|
132
|
+
path: { id: workflowId },
|
|
133
|
+
query: triggerQuery,
|
|
134
|
+
body: formData,
|
|
135
|
+
bodySerializer: null,
|
|
136
|
+
headers: { 'Content-Type': null },
|
|
137
|
+
signal: options.signal,
|
|
138
|
+
}) as Promise<OperationResult<RunWorkflowResponse>>;
|
|
139
|
+
})
|
|
140
|
+
: await this.dispatch<RunWorkflowResponse>(() =>
|
|
141
|
+
workflowsRun({
|
|
142
|
+
client: this.client,
|
|
143
|
+
path: { id: workflowId },
|
|
144
|
+
query: triggerQuery,
|
|
145
|
+
body: {
|
|
146
|
+
...(input !== undefined ? { input } : {}),
|
|
147
|
+
...(options.overrides ? { overrides: options.overrides } : {}),
|
|
148
|
+
},
|
|
149
|
+
signal: options.signal,
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const { executionId } = runResult;
|
|
154
|
+
|
|
155
|
+
while (true) {
|
|
156
|
+
if (options.signal?.aborted) {
|
|
157
|
+
throw new EigenpalTimeoutError('runAndWait aborted');
|
|
158
|
+
}
|
|
159
|
+
if (Date.now() >= deadline) {
|
|
160
|
+
throw new EigenpalTimeoutError(
|
|
161
|
+
`runAndWait timed out after ${timeoutMs}ms (executionId=${executionId})`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const status = await this.get(executionId, { signal: options.signal });
|
|
166
|
+
|
|
167
|
+
if (status.status && TERMINAL_STATUSES.has(status.status)) {
|
|
168
|
+
return {
|
|
169
|
+
executionId,
|
|
170
|
+
status: status.status,
|
|
171
|
+
...(status.result != null ? { result: status.result } : {}),
|
|
172
|
+
...(status.error != null ? { error: status.error } : {}),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { OperationResult } from '../client';
|
|
2
|
+
import type { Client } from '../generated/client';
|
|
3
|
+
import {
|
|
4
|
+
workflowsGet,
|
|
5
|
+
workflowsList,
|
|
6
|
+
workflowsRun,
|
|
7
|
+
workflowsVersionsList,
|
|
8
|
+
} from '../generated/sdk.gen';
|
|
9
|
+
import type {
|
|
10
|
+
ListVersionsResponse,
|
|
11
|
+
ListWorkflowsResponse,
|
|
12
|
+
RunWorkflowResponse,
|
|
13
|
+
WorkflowSummary,
|
|
14
|
+
} from '../generated/types.gen';
|
|
15
|
+
import { buildMultipart, hasFileInput } from '../lib/files';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Workflow inputs keyed by name as declared in the workflow YAML.
|
|
19
|
+
*
|
|
20
|
+
* File values (`File`, `Blob`, or `{ content, filename, mimeType }`) are
|
|
21
|
+
* detected automatically and uploaded as `multipart/form-data` — same as
|
|
22
|
+
* `curl -F`. No base64 round-trip required.
|
|
23
|
+
*/
|
|
24
|
+
export type WorkflowInput = Record<string, unknown>;
|
|
25
|
+
|
|
26
|
+
export interface RunWorkflowOptions {
|
|
27
|
+
/** Specific version id, or `"latest"` (default). */
|
|
28
|
+
version?: string;
|
|
29
|
+
/** Hold the connection up to N seconds for completion (max 60). Omit for async. */
|
|
30
|
+
waitForCompletion?: number;
|
|
31
|
+
/** Per-step output overrides for replay. */
|
|
32
|
+
overrides?: { steps?: Record<string, Record<string, unknown>> };
|
|
33
|
+
/** AbortSignal to cancel the request. */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ListWorkflowsOptions {
|
|
38
|
+
/** Substring match against workflow name. */
|
|
39
|
+
search?: string;
|
|
40
|
+
/** Exact-match by workflow name (slug). */
|
|
41
|
+
name?: string;
|
|
42
|
+
kind?: 'workflow' | 'block';
|
|
43
|
+
limit?: number;
|
|
44
|
+
offset?: number;
|
|
45
|
+
signal?: AbortSignal;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ListVersionsOptions {
|
|
49
|
+
limit?: number;
|
|
50
|
+
offset?: number;
|
|
51
|
+
signal?: AbortSignal;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Workflow resource — list, get, run, and inspect versions of saved
|
|
58
|
+
* workflows. Reached via `client.workflows`.
|
|
59
|
+
*/
|
|
60
|
+
export class WorkflowsResource {
|
|
61
|
+
constructor(
|
|
62
|
+
private readonly client: Client,
|
|
63
|
+
private readonly dispatch: Dispatch
|
|
64
|
+
) {}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Execute a workflow.
|
|
68
|
+
*
|
|
69
|
+
* @param workflowId — id like `wf_abc123`.
|
|
70
|
+
* @param input — workflow inputs keyed by name. Pass `undefined` for inputs-less workflows.
|
|
71
|
+
* @param options — `version`, `waitForCompletion`, `overrides`.
|
|
72
|
+
*
|
|
73
|
+
* - With no `waitForCompletion`, returns immediately with `{ executionId }`.
|
|
74
|
+
* Poll via `client.executions.get(id)` or use `client.executions.runAndWait`.
|
|
75
|
+
* - With `waitForCompletion: 60`, the server holds the connection up to 60
|
|
76
|
+
* seconds. The response also includes `status`, `result`, and `error`
|
|
77
|
+
* when the run finishes within the window.
|
|
78
|
+
*/
|
|
79
|
+
async run(
|
|
80
|
+
workflowId: string,
|
|
81
|
+
input?: WorkflowInput,
|
|
82
|
+
options: RunWorkflowOptions = {}
|
|
83
|
+
): Promise<RunWorkflowResponse> {
|
|
84
|
+
const query = {
|
|
85
|
+
...(options.version ? { version: options.version } : {}),
|
|
86
|
+
...(options.waitForCompletion !== undefined
|
|
87
|
+
? { wait_for_completion: options.waitForCompletion }
|
|
88
|
+
: {}),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// File-bearing input → multipart/form-data (no base64 overhead).
|
|
92
|
+
if (hasFileInput(input)) {
|
|
93
|
+
const { formData } = buildMultipart({ input, overrides: options.overrides });
|
|
94
|
+
return this.dispatch<RunWorkflowResponse>(
|
|
95
|
+
() =>
|
|
96
|
+
this.client.post({
|
|
97
|
+
url: '/v1/workflows/{id}/run',
|
|
98
|
+
path: { id: workflowId },
|
|
99
|
+
query,
|
|
100
|
+
body: formData,
|
|
101
|
+
// Skip JSON serialization; FormData passes through to fetch which
|
|
102
|
+
// sets the Content-Type header (with boundary) automatically.
|
|
103
|
+
bodySerializer: null,
|
|
104
|
+
// Explicitly null the JSON Content-Type header that the request
|
|
105
|
+
// pipeline would otherwise inherit.
|
|
106
|
+
headers: { 'Content-Type': null },
|
|
107
|
+
signal: options.signal,
|
|
108
|
+
}) as Promise<OperationResult<RunWorkflowResponse>>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return this.dispatch<RunWorkflowResponse>(() =>
|
|
113
|
+
workflowsRun({
|
|
114
|
+
client: this.client,
|
|
115
|
+
path: { id: workflowId },
|
|
116
|
+
query,
|
|
117
|
+
body: {
|
|
118
|
+
...(input !== undefined ? { input } : {}),
|
|
119
|
+
...(options.overrides ? { overrides: options.overrides } : {}),
|
|
120
|
+
},
|
|
121
|
+
signal: options.signal,
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** List workflows, paginated. */
|
|
127
|
+
async list(options: ListWorkflowsOptions = {}): Promise<ListWorkflowsResponse> {
|
|
128
|
+
const { signal, ...query } = options;
|
|
129
|
+
return this.dispatch(() => workflowsList({ client: this.client, query, signal }));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Get a single workflow by id. */
|
|
133
|
+
async get(workflowId: string, options: { signal?: AbortSignal } = {}): Promise<WorkflowSummary> {
|
|
134
|
+
return this.dispatch(() =>
|
|
135
|
+
workflowsGet({ client: this.client, path: { id: workflowId }, signal: options.signal })
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** List tagged versions for a workflow, paginated. */
|
|
140
|
+
async versions(
|
|
141
|
+
workflowId: string,
|
|
142
|
+
options: ListVersionsOptions = {}
|
|
143
|
+
): Promise<ListVersionsResponse> {
|
|
144
|
+
const { signal, ...query } = options;
|
|
145
|
+
return this.dispatch(() =>
|
|
146
|
+
workflowsVersionsList({
|
|
147
|
+
client: this.client,
|
|
148
|
+
path: { id: workflowId },
|
|
149
|
+
query,
|
|
150
|
+
signal,
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CreateClientConfig } from './generated/client.gen';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runtime configuration hook for the generated hey-api client.
|
|
5
|
+
*
|
|
6
|
+
* The hand-written `Eigenpal` class in `client.ts` calls
|
|
7
|
+
* `setClientConfig()` on construction with the user's `apiKey` and
|
|
8
|
+
* `baseUrl`, so the generated SDK functions automatically pick up the
|
|
9
|
+
* Authorization header. This factory returns a no-op default — values
|
|
10
|
+
* are populated when an `Eigenpal` instance is created.
|
|
11
|
+
*/
|
|
12
|
+
export const createClientConfig: CreateClientConfig = (config) => ({
|
|
13
|
+
...config,
|
|
14
|
+
baseUrl: config?.baseUrl ?? 'https://app.eigenpal.com',
|
|
15
|
+
});
|