@erdoai/server 0.1.4

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/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # @erdoai/server
2
+
3
+ Server-side TypeScript client for invoking Erdo AI agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @erdoai/server
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Invocation
14
+
15
+ ```typescript
16
+ import { ErdoClient } from '@erdoai/server';
17
+
18
+ const client = new ErdoClient({
19
+ endpoint: 'https://api.erdo.ai',
20
+ authToken: process.env.ERDO_API_KEY,
21
+ });
22
+
23
+ // Get final result
24
+ const result = await client.invoke('data-analyst', {
25
+ messages: [{ role: 'user', content: 'What were our top products last month?' }],
26
+ });
27
+
28
+ console.log(result.messages);
29
+ ```
30
+
31
+ ### Streaming
32
+
33
+ ```typescript
34
+ for await (const event of client.invokeStream('data-analyst', {
35
+ messages: [{ role: 'user', content: 'Analyze our sales data' }],
36
+ })) {
37
+ switch (event.type) {
38
+ case 'content':
39
+ console.log('New content:', event.payload);
40
+ break;
41
+ case 'status':
42
+ console.log('Status:', event.payload);
43
+ break;
44
+ case 'error':
45
+ console.error('Error:', event.payload);
46
+ break;
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### Environment Variables
52
+
53
+ The client can be configured via environment variables:
54
+
55
+ ```bash
56
+ ERDO_ENDPOINT=https://api.erdo.ai
57
+ ERDO_AUTH_TOKEN=your-api-key
58
+ ```
59
+
60
+ ```typescript
61
+ // Uses environment variables automatically
62
+ const client = new ErdoClient();
63
+ ```
64
+
65
+ ## API Reference
66
+
67
+ ### `ErdoClient`
68
+
69
+ ```typescript
70
+ class ErdoClient {
71
+ constructor(options?: {
72
+ endpoint?: string; // API endpoint (default: env or https://api.erdo.ai)
73
+ authToken?: string; // API key (default: env ERDO_AUTH_TOKEN)
74
+ });
75
+
76
+ invoke(botKey: string, params: InvokeParams): Promise<InvokeResult>;
77
+ invokeStream(botKey: string, params: InvokeParams): AsyncGenerator<SSEEvent>;
78
+ }
79
+ ```
80
+
81
+ ### `InvokeParams`
82
+
83
+ ```typescript
84
+ interface InvokeParams {
85
+ messages?: Message[]; // Messages to send to the agent
86
+ parameters?: Record<string, any>; // Parameters to pass to the agent
87
+ datasets?: string[]; // Dataset slugs to include
88
+ mode?: InvocationMode; // Invocation mode
89
+ }
90
+ ```
91
+
92
+ ### `SSEEvent`
93
+
94
+ ```typescript
95
+ interface SSEEvent {
96
+ type: 'content' | 'status' | 'error' | 'done';
97
+ payload: any;
98
+ metadata?: Record<string, any>;
99
+ }
100
+ ```
101
+
102
+ ## License
103
+
104
+ MIT
@@ -0,0 +1,94 @@
1
+ import { ErdoClientConfig, InvokeParams, InvokeResult, SSEEvent } from '@erdoai/types';
2
+
3
+ /**
4
+ * Erdo Client for invoking agents
5
+ *
6
+ * Ported from: erdo-python-sdk/erdo/invoke/client.py and invoke.py
7
+ */
8
+
9
+ declare class ErdoClient {
10
+ private readonly endpoint;
11
+ private readonly authToken;
12
+ constructor(config?: Partial<ErdoClientConfig>);
13
+ /**
14
+ * Invoke an agent and wait for the complete result
15
+ */
16
+ invoke(botKey: string, params?: InvokeParams): Promise<InvokeResult>;
17
+ /**
18
+ * Invoke an agent and stream SSE events
19
+ */
20
+ invokeStream(botKey: string, params?: InvokeParams): AsyncGenerator<SSEEvent, void, unknown>;
21
+ /**
22
+ * Collect all events from an invocation
23
+ */
24
+ private collectEvents;
25
+ /**
26
+ * Make the HTTP request to invoke an agent
27
+ */
28
+ private makeRequest;
29
+ /**
30
+ * Extract structured result from SSE events
31
+ *
32
+ * Ported from: erdo-python-sdk/erdo/invoke/invoke.py - _extract_result_data()
33
+ */
34
+ private extractResult;
35
+ }
36
+ /**
37
+ * Invoke an agent with a clean API
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { invoke } from '@erdoai/server';
42
+ *
43
+ * const result = await invoke('org.my-agent', {
44
+ * messages: [{ role: 'user', content: 'Analyze Q4 sales' }],
45
+ * mode: 'replay',
46
+ * });
47
+ * ```
48
+ */
49
+ declare function invoke(botKey: string, params?: InvokeParams): Promise<InvokeResult>;
50
+ /**
51
+ * Invoke an agent and stream events
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { invokeStream } from '@erdoai/server';
56
+ *
57
+ * for await (const event of invokeStream('org.my-agent', params)) {
58
+ * console.log(event.type, event.payload);
59
+ * }
60
+ * ```
61
+ */
62
+ declare function invokeStream(botKey: string, params?: InvokeParams): AsyncGenerator<SSEEvent, void, unknown>;
63
+
64
+ /**
65
+ * Configuration management for Erdo TypeScript SDK
66
+ *
67
+ * Ported from: erdo-python-sdk/erdo/config/config.py
68
+ */
69
+
70
+ /**
71
+ * Get configuration from environment variables
72
+ */
73
+ declare function getConfigFromEnv(): ErdoClientConfig;
74
+ /**
75
+ * Merge user config with environment config
76
+ */
77
+ declare function resolveConfig(userConfig?: Partial<ErdoClientConfig>): Required<ErdoClientConfig>;
78
+
79
+ /**
80
+ * SSE Client for Server-Sent Events streaming
81
+ *
82
+ * Ported from: erdo-python-sdk/erdo/invoke/client.py
83
+ */
84
+
85
+ /**
86
+ * Parse SSE events from a ReadableStream
87
+ */
88
+ declare function parseSSEStream(response: Response): AsyncGenerator<SSEEvent, void, unknown>;
89
+ /**
90
+ * Collect all events from an SSE stream
91
+ */
92
+ declare function collectSSEEvents(response: Response): Promise<SSEEvent[]>;
93
+
94
+ export { ErdoClient, collectSSEEvents, getConfigFromEnv, invoke, invokeStream, parseSSEStream, resolveConfig };
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ // src/config.ts
2
+ var DEFAULT_ENDPOINT = "https://api.erdo.ai";
3
+ function getConfigFromEnv() {
4
+ const env = typeof process !== "undefined" ? process.env : {};
5
+ return {
6
+ endpoint: env.ERDO_ENDPOINT || env.NEXT_PUBLIC_ERDO_ENDPOINT || DEFAULT_ENDPOINT,
7
+ authToken: env.ERDO_AUTH_TOKEN || env.NEXT_PUBLIC_ERDO_API_KEY
8
+ };
9
+ }
10
+ function resolveConfig(userConfig) {
11
+ const envConfig = getConfigFromEnv();
12
+ const endpoint = userConfig?.endpoint || envConfig.endpoint || DEFAULT_ENDPOINT;
13
+ const authToken = userConfig?.authToken || envConfig.authToken;
14
+ if (!authToken) {
15
+ throw new Error(
16
+ "No auth token configured. Set ERDO_AUTH_TOKEN environment variable or pass authToken to ErdoClient."
17
+ );
18
+ }
19
+ return {
20
+ endpoint,
21
+ authToken
22
+ };
23
+ }
24
+
25
+ // src/streaming/sse-client.ts
26
+ async function* parseSSEStream(response) {
27
+ if (!response.body) {
28
+ throw new Error("Response body is null");
29
+ }
30
+ const reader = response.body.getReader();
31
+ const decoder = new TextDecoder();
32
+ let buffer = "";
33
+ try {
34
+ while (true) {
35
+ const { done, value } = await reader.read();
36
+ if (done) {
37
+ if (buffer.trim()) {
38
+ const event = parseSSELine(buffer);
39
+ if (event) {
40
+ yield event;
41
+ }
42
+ }
43
+ break;
44
+ }
45
+ buffer += decoder.decode(value, { stream: true });
46
+ const lines = buffer.split("\n");
47
+ buffer = lines.pop() || "";
48
+ for (const line of lines) {
49
+ const event = parseSSELine(line);
50
+ if (event) {
51
+ yield event;
52
+ }
53
+ }
54
+ }
55
+ } finally {
56
+ reader.releaseLock();
57
+ }
58
+ }
59
+ function parseSSELine(line) {
60
+ const trimmedLine = line.trim();
61
+ if (!trimmedLine) {
62
+ return null;
63
+ }
64
+ if (trimmedLine.startsWith("data: ")) {
65
+ const data = trimmedLine.slice(6);
66
+ if (!data.trim()) {
67
+ return null;
68
+ }
69
+ try {
70
+ return JSON.parse(data);
71
+ } catch {
72
+ return { raw: data };
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ async function collectSSEEvents(response) {
78
+ const events = [];
79
+ for await (const event of parseSSEStream(response)) {
80
+ events.push(event);
81
+ }
82
+ return events;
83
+ }
84
+
85
+ // src/client.ts
86
+ var ErdoClient = class {
87
+ endpoint;
88
+ authToken;
89
+ constructor(config) {
90
+ const resolved = resolveConfig(config);
91
+ this.endpoint = resolved.endpoint;
92
+ this.authToken = resolved.authToken;
93
+ }
94
+ /**
95
+ * Invoke an agent and wait for the complete result
96
+ */
97
+ async invoke(botKey, params = {}) {
98
+ const events = await this.collectEvents(botKey, params);
99
+ return this.extractResult(botKey, events);
100
+ }
101
+ /**
102
+ * Invoke an agent and stream SSE events
103
+ */
104
+ async *invokeStream(botKey, params = {}) {
105
+ const response = await this.makeRequest(botKey, params);
106
+ yield* parseSSEStream(response);
107
+ }
108
+ /**
109
+ * Collect all events from an invocation
110
+ */
111
+ async collectEvents(botKey, params) {
112
+ const response = await this.makeRequest(botKey, params);
113
+ return collectSSEEvents(response);
114
+ }
115
+ /**
116
+ * Make the HTTP request to invoke an agent
117
+ */
118
+ async makeRequest(botKey, params) {
119
+ const url = `${this.endpoint}/bots/${botKey}/invoke`;
120
+ const invokeParams = {};
121
+ if (params.messages) {
122
+ invokeParams.messages = params.messages;
123
+ }
124
+ if (params.parameters) {
125
+ invokeParams.parameters = params.parameters;
126
+ }
127
+ if (params.datasets) {
128
+ invokeParams.dataset_slugs = params.datasets;
129
+ }
130
+ if (params.mode) {
131
+ invokeParams.mode = params.mode;
132
+ }
133
+ if (params.manualMocks) {
134
+ invokeParams.manual_mocks = params.manualMocks;
135
+ }
136
+ const response = await fetch(url, {
137
+ method: "POST",
138
+ headers: {
139
+ Authorization: `Bearer ${this.authToken}`,
140
+ "Content-Type": "application/json",
141
+ Accept: "text/event-stream"
142
+ },
143
+ body: JSON.stringify(invokeParams)
144
+ });
145
+ if (!response.ok) {
146
+ const errorText = await response.text();
147
+ throw new Error(`API request failed with status ${response.status}: ${errorText}`);
148
+ }
149
+ return response;
150
+ }
151
+ /**
152
+ * Extract structured result from SSE events
153
+ *
154
+ * Ported from: erdo-python-sdk/erdo/invoke/invoke.py - _extract_result_data()
155
+ */
156
+ extractResult(botKey, events) {
157
+ const messages = [];
158
+ const steps = [];
159
+ const stepsSeenKeys = /* @__PURE__ */ new Set();
160
+ let finalResult;
161
+ let invocationId;
162
+ for (const event of events) {
163
+ if (!event) continue;
164
+ const payload = event.payload;
165
+ const metadata = event.metadata;
166
+ if (payload && typeof payload === "object") {
167
+ if ("invocation_id" in payload && !invocationId) {
168
+ invocationId = payload.invocation_id;
169
+ }
170
+ }
171
+ if (payload && typeof payload === "object" && "action_type" in payload && "key" in payload) {
172
+ const stepKey = payload.key;
173
+ if (!stepsSeenKeys.has(stepKey)) {
174
+ stepsSeenKeys.add(stepKey);
175
+ steps.push({
176
+ key: stepKey,
177
+ action: payload.action_type,
178
+ status: "completed"
179
+ });
180
+ }
181
+ }
182
+ if (payload && typeof payload === "object" && "output" in payload && metadata?.user_visibility === "visible") {
183
+ const output = payload.output;
184
+ if (output && typeof output === "object" && "content" in output) {
185
+ const contentArray = output.content;
186
+ if (Array.isArray(contentArray)) {
187
+ for (const item of contentArray) {
188
+ if (item.content_type === "text") {
189
+ const role = metadata?.role || "assistant";
190
+ messages.push({
191
+ role,
192
+ content: item.content || ""
193
+ });
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ if (payload && typeof payload === "object" && "status" in payload && "output" in payload) {
200
+ finalResult = {
201
+ status: payload.status,
202
+ parameters: payload.parameters,
203
+ output: payload.output,
204
+ message: payload.message,
205
+ error: payload.error
206
+ };
207
+ }
208
+ }
209
+ return {
210
+ success: true,
211
+ botId: botKey,
212
+ invocationId,
213
+ result: finalResult,
214
+ messages,
215
+ events,
216
+ steps
217
+ };
218
+ }
219
+ };
220
+ var defaultClient = null;
221
+ function getDefaultClient() {
222
+ if (!defaultClient) {
223
+ defaultClient = new ErdoClient();
224
+ }
225
+ return defaultClient;
226
+ }
227
+ async function invoke(botKey, params = {}) {
228
+ return getDefaultClient().invoke(botKey, params);
229
+ }
230
+ async function* invokeStream(botKey, params = {}) {
231
+ yield* getDefaultClient().invokeStream(botKey, params);
232
+ }
233
+ export {
234
+ ErdoClient,
235
+ collectSSEEvents,
236
+ getConfigFromEnv,
237
+ invoke,
238
+ invokeStream,
239
+ parseSSEStream,
240
+ resolveConfig
241
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@erdoai/server",
3
+ "version": "0.1.4",
4
+ "description": "Erdo server SDK for invoking agents",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public",
20
+ "registry": "https://registry.npmjs.org/"
21
+ },
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "dev": "tsup --watch",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest"
28
+ },
29
+ "keywords": [
30
+ "erdo",
31
+ "ai",
32
+ "agent",
33
+ "sdk"
34
+ ],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/erdoai/erdo-ts-sdk.git",
39
+ "directory": "packages/server"
40
+ },
41
+ "dependencies": {
42
+ "@erdoai/types": "workspace:^"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^24.10.1",
46
+ "tsup": "^8.5.1",
47
+ "typescript": "^5.9.3",
48
+ "vitest": "^4.0.15"
49
+ }
50
+ }