@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/CHANGELOG.md +59 -2
- package/README.md +58 -46
- package/package.json +1 -1
- package/src/client.ts +48 -17
- package/src/errors.ts +7 -2
- package/src/generated/index.ts +82 -21
- package/src/generated/sdk.gen.ts +203 -31
- package/src/generated/types.gen.ts +649 -88
- package/src/index.ts +21 -8
- package/src/lib/files.ts +27 -0
- package/src/resources/agents.ts +168 -0
- package/src/resources/executions.ts +35 -23
- package/src/resources/workflows.ts +9 -3
- package/src/runtime-config.ts +2 -2
- package/src/telemetry.ts +54 -0
package/src/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Official TypeScript SDK for the
|
|
2
|
+
* Official TypeScript SDK for the EigenPal API.
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
5
|
* ```ts
|
|
6
|
-
* import {
|
|
6
|
+
* import { EigenpalClient } from '@eigenpal/sdk';
|
|
7
7
|
*
|
|
8
|
-
* const client = new
|
|
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 {
|
|
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
|
-
|
|
61
|
+
CancelAgentExecutionResponse,
|
|
62
|
+
CancelWorkflowExecutionResponse,
|
|
54
63
|
ExecutionStatus,
|
|
55
|
-
ExecutionStatusResponse,
|
|
56
64
|
ExecutionSummary,
|
|
57
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
workflowsExecutionsCancel,
|
|
6
|
+
workflowsExecutionsGet,
|
|
7
|
+
workflowsExecutionsList,
|
|
8
8
|
workflowsRun,
|
|
9
9
|
} from '../generated/sdk.gen';
|
|
10
10
|
import type {
|
|
11
|
-
|
|
11
|
+
CancelWorkflowExecutionResponse,
|
|
12
12
|
ExecutionStatus,
|
|
13
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
*
|
|
63
|
-
* in-flight
|
|
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
|
|
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<
|
|
77
|
-
return this.dispatch<
|
|
75
|
+
): Promise<WorkflowExecutionStatusResponse> {
|
|
76
|
+
return this.dispatch<WorkflowExecutionStatusResponse>(
|
|
78
77
|
() =>
|
|
79
|
-
|
|
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<
|
|
83
|
+
}) as Promise<OperationResult<WorkflowExecutionStatusResponse>>
|
|
85
84
|
);
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
/** List executions, paginated. */
|
|
89
|
-
async list(
|
|
90
|
-
|
|
91
|
-
|
|
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<
|
|
110
|
+
): Promise<CancelWorkflowExecutionResponse> {
|
|
99
111
|
return this.dispatch(() =>
|
|
100
|
-
|
|
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
|
|
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,
|
package/src/runtime-config.ts
CHANGED
|
@@ -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 `
|
|
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 `
|
|
10
|
+
* are populated when an `EigenpalClient` instance is created.
|
|
11
11
|
*/
|
|
12
12
|
export const createClientConfig: CreateClientConfig = (config) => ({
|
|
13
13
|
...config,
|
package/src/telemetry.ts
ADDED
|
@@ -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
|
+
}
|