@octavus/server-sdk 0.2.0 → 2.0.0
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 +227 -0
- package/dist/index.d.ts +72 -75
- package/dist/index.js +213 -69
- package/dist/index.js.map +1 -1
- package/package.json +13 -3
package/README.md
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# @octavus/server-sdk
|
|
2
|
+
|
|
3
|
+
Server SDK for integrating Octavus agents into your backend.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @octavus/server-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
This package provides a server-side SDK for interacting with the Octavus platform. Use it to:
|
|
14
|
+
|
|
15
|
+
- Create and manage agent sessions
|
|
16
|
+
- Execute triggers with tool handling
|
|
17
|
+
- Stream responses to clients
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { OctavusClient, toSSEStream } from '@octavus/server-sdk';
|
|
23
|
+
|
|
24
|
+
// Initialize client
|
|
25
|
+
const client = new OctavusClient({
|
|
26
|
+
baseUrl: process.env.OCTAVUS_BASE_URL!,
|
|
27
|
+
apiKey: process.env.OCTAVUS_API_KEY,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Create a session
|
|
31
|
+
const sessionId = await client.agentSessions.create(agentId, {
|
|
32
|
+
COMPANY_NAME: 'Acme Corp',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Attach to session with tool handlers
|
|
36
|
+
const session = client.agentSessions.attach(sessionId, {
|
|
37
|
+
tools: {
|
|
38
|
+
'get-user': async (args) => {
|
|
39
|
+
return await db.users.findById(args.userId);
|
|
40
|
+
},
|
|
41
|
+
'create-ticket': async (args) => {
|
|
42
|
+
return await ticketService.create(args);
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Trigger and stream response
|
|
48
|
+
const events = session.trigger('user-message', { USER_MESSAGE: 'Hello!' });
|
|
49
|
+
return new Response(toSSEStream(events), {
|
|
50
|
+
headers: { 'Content-Type': 'text/event-stream' },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## OctavusClient
|
|
55
|
+
|
|
56
|
+
### Configuration
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const client = new OctavusClient({
|
|
60
|
+
baseUrl: 'https://api.octavus.ai', // Or your self-hosted URL
|
|
61
|
+
apiKey: 'your-api-key', // Optional: for authenticated requests
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Agent Sessions API
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Create a new session
|
|
69
|
+
const sessionId = await client.agentSessions.create(agentId, input);
|
|
70
|
+
|
|
71
|
+
// Get session state (for debugging)
|
|
72
|
+
const state = await client.agentSessions.get(sessionId);
|
|
73
|
+
|
|
74
|
+
// Get UI-ready messages
|
|
75
|
+
const { messages, status } = await client.agentSessions.getMessages(sessionId);
|
|
76
|
+
|
|
77
|
+
// Restore expired session
|
|
78
|
+
await client.agentSessions.restore(sessionId, storedMessages, input);
|
|
79
|
+
|
|
80
|
+
// Attach to session for triggering
|
|
81
|
+
const session = client.agentSessions.attach(sessionId, options);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Agents API
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// List all agents
|
|
88
|
+
const agents = await client.agents.list();
|
|
89
|
+
|
|
90
|
+
// Get agent by ID
|
|
91
|
+
const agent = await client.agents.get(agentId);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Files API
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Get presigned upload URLs
|
|
98
|
+
const { files } = await client.files.getUploadUrls(sessionId, [
|
|
99
|
+
{ filename: 'photo.jpg', mediaType: 'image/jpeg', size: 102400 },
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
// Upload directly to S3
|
|
103
|
+
await fetch(files[0].uploadUrl, {
|
|
104
|
+
method: 'PUT',
|
|
105
|
+
body: imageFile,
|
|
106
|
+
headers: { 'Content-Type': 'image/jpeg' },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Use downloadUrl in trigger input
|
|
110
|
+
await session.trigger('user-message', {
|
|
111
|
+
FILES: [{ id: files[0].id, url: files[0].downloadUrl, mediaType: 'image/jpeg' }],
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## AgentSession
|
|
116
|
+
|
|
117
|
+
### Triggering Events
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const session = client.agentSessions.attach(sessionId, {
|
|
121
|
+
tools: {
|
|
122
|
+
'tool-name': async (args) => {
|
|
123
|
+
// Execute tool and return result
|
|
124
|
+
return { success: true };
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Stream events (for WebSocket/Socket.io)
|
|
130
|
+
for await (const event of session.trigger('user-message', input)) {
|
|
131
|
+
socket.emit('stream-event', event);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Convert to SSE (for HTTP endpoints)
|
|
135
|
+
const events = session.trigger('user-message', input);
|
|
136
|
+
return new Response(toSSEStream(events), {
|
|
137
|
+
headers: { 'Content-Type': 'text/event-stream' },
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Tool Handlers
|
|
142
|
+
|
|
143
|
+
The SDK automatically handles the tool execution loop:
|
|
144
|
+
|
|
145
|
+
1. Platform requests tool execution via `tool-request` event
|
|
146
|
+
2. SDK executes your tool handlers locally
|
|
147
|
+
3. SDK sends results back to continue the conversation
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const session = client.agentSessions.attach(sessionId, {
|
|
151
|
+
tools: {
|
|
152
|
+
'get-user-account': async (args) => {
|
|
153
|
+
// Access your database, APIs, etc.
|
|
154
|
+
return await db.users.findById(args.userId);
|
|
155
|
+
},
|
|
156
|
+
'create-support-ticket': async (args) => {
|
|
157
|
+
// Execute with full access to your backend
|
|
158
|
+
return await ticketService.create({
|
|
159
|
+
summary: args.summary,
|
|
160
|
+
priority: args.priority,
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Resource Handlers
|
|
168
|
+
|
|
169
|
+
Track resource updates from the agent:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { Resource } from '@octavus/server-sdk';
|
|
173
|
+
|
|
174
|
+
class ConversationSummaryResource extends Resource {
|
|
175
|
+
readonly name = 'CONVERSATION_SUMMARY';
|
|
176
|
+
|
|
177
|
+
async onUpdate(value: unknown) {
|
|
178
|
+
// Persist to database, trigger webhooks, etc.
|
|
179
|
+
await db.sessions.update(sessionId, { summary: value });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const session = client.agentSessions.attach(sessionId, {
|
|
184
|
+
resources: [new ConversationSummaryResource()],
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Abort Support
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const events = session.trigger('user-message', input, {
|
|
192
|
+
signal: request.signal, // AbortSignal from request
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Session Lifecycle
|
|
197
|
+
|
|
198
|
+
### Active Sessions
|
|
199
|
+
|
|
200
|
+
Sessions remain active for 24 hours (configurable). Use `getMessages()` for UI display.
|
|
201
|
+
|
|
202
|
+
### Expired Sessions
|
|
203
|
+
|
|
204
|
+
When Redis state expires:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const result = await client.agentSessions.getMessages(sessionId);
|
|
208
|
+
|
|
209
|
+
if (result.status === 'expired') {
|
|
210
|
+
// Restore from your stored messages
|
|
211
|
+
await client.agentSessions.restore(sessionId, storedMessages);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Re-exports
|
|
216
|
+
|
|
217
|
+
This package re-exports everything from `@octavus/core`, so you don't need to install it separately.
|
|
218
|
+
|
|
219
|
+
## Related Packages
|
|
220
|
+
|
|
221
|
+
- [`@octavus/react`](https://www.npmjs.com/package/@octavus/react) - React hooks
|
|
222
|
+
- [`@octavus/client-sdk`](https://www.npmjs.com/package/@octavus/client-sdk) - Client-side SDK
|
|
223
|
+
- [`@octavus/cli`](https://www.npmjs.com/package/@octavus/cli) - CLI for agent management
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ZodType, z } from 'zod';
|
|
2
|
-
import { ToolHandlers, StreamEvent, ChatMessage, UIMessage } from '@octavus/core';
|
|
2
|
+
import { ToolHandlers, ToolResult, StreamEvent, ChatMessage, UIMessage } from '@octavus/core';
|
|
3
3
|
export * from '@octavus/core';
|
|
4
|
+
export { AppError, ConflictError, ForbiddenError, MAIN_THREAD, NotFoundError, OCTAVUS_SKILL_TOOLS, OctavusError, ValidationError, createApiErrorEvent, createErrorEvent, createInternalErrorEvent, errorToStreamEvent, generateId, getSkillSlugFromToolCall, isAbortError, isAuthenticationError, isFileReference, isFileReferenceArray, isMainThread, isOctavusSkillTool, isOtherThread, isProviderError, isRateLimitError, isRetryableError, isToolError, isValidationError, resolveThread, safeParseStreamEvent, safeParseUIMessage, safeParseUIMessages, threadForPart } from '@octavus/core';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Error thrown when API request fails
|
|
@@ -24,8 +25,8 @@ declare abstract class BaseApiClient {
|
|
|
24
25
|
protected httpPatch<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T>;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
/** Agent format - interactive (chat) or
|
|
28
|
-
type AgentFormat = 'interactive' | '
|
|
28
|
+
/** Agent format - interactive (chat) or worker (background task) */
|
|
29
|
+
type AgentFormat = 'interactive' | 'worker';
|
|
29
30
|
/** Agent settings */
|
|
30
31
|
interface AgentSettings {
|
|
31
32
|
slug: string;
|
|
@@ -63,55 +64,6 @@ interface AgentDefinition {
|
|
|
63
64
|
/** Agent ID - use this for API calls like createSession */
|
|
64
65
|
id: string;
|
|
65
66
|
}
|
|
66
|
-
declare const agentFormatSchema: z.ZodEnum<{
|
|
67
|
-
interactive: "interactive";
|
|
68
|
-
generation: "generation";
|
|
69
|
-
}>;
|
|
70
|
-
declare const agentSchema: z.ZodObject<{
|
|
71
|
-
slug: z.ZodString;
|
|
72
|
-
id: z.ZodString;
|
|
73
|
-
name: z.ZodString;
|
|
74
|
-
description: z.ZodNullable<z.ZodString>;
|
|
75
|
-
format: z.ZodEnum<{
|
|
76
|
-
interactive: "interactive";
|
|
77
|
-
generation: "generation";
|
|
78
|
-
}>;
|
|
79
|
-
createdAt: z.ZodString;
|
|
80
|
-
updatedAt: z.ZodString;
|
|
81
|
-
projectId: z.ZodString;
|
|
82
|
-
}, z.core.$strip>;
|
|
83
|
-
declare const agentsResponseSchema: z.ZodObject<{
|
|
84
|
-
agents: z.ZodArray<z.ZodObject<{
|
|
85
|
-
slug: z.ZodString;
|
|
86
|
-
id: z.ZodString;
|
|
87
|
-
name: z.ZodString;
|
|
88
|
-
description: z.ZodNullable<z.ZodString>;
|
|
89
|
-
format: z.ZodEnum<{
|
|
90
|
-
interactive: "interactive";
|
|
91
|
-
generation: "generation";
|
|
92
|
-
}>;
|
|
93
|
-
createdAt: z.ZodString;
|
|
94
|
-
updatedAt: z.ZodString;
|
|
95
|
-
projectId: z.ZodString;
|
|
96
|
-
}, z.core.$strip>>;
|
|
97
|
-
}, z.core.$strip>;
|
|
98
|
-
declare const agentDefinitionSchema: z.ZodObject<{
|
|
99
|
-
settings: z.ZodObject<{
|
|
100
|
-
slug: z.ZodString;
|
|
101
|
-
name: z.ZodString;
|
|
102
|
-
description: z.ZodOptional<z.ZodString>;
|
|
103
|
-
format: z.ZodEnum<{
|
|
104
|
-
interactive: "interactive";
|
|
105
|
-
generation: "generation";
|
|
106
|
-
}>;
|
|
107
|
-
}, z.core.$strip>;
|
|
108
|
-
protocol: z.ZodString;
|
|
109
|
-
prompts: z.ZodArray<z.ZodObject<{
|
|
110
|
-
name: z.ZodString;
|
|
111
|
-
content: z.ZodString;
|
|
112
|
-
}, z.core.$strip>>;
|
|
113
|
-
id: z.ZodString;
|
|
114
|
-
}, z.core.$strip>;
|
|
115
67
|
|
|
116
68
|
/**
|
|
117
69
|
* API for listing and retrieving agent definitions.
|
|
@@ -137,6 +89,20 @@ declare abstract class Resource {
|
|
|
137
89
|
abstract onUpdate(value: unknown): Promise<void> | void;
|
|
138
90
|
}
|
|
139
91
|
|
|
92
|
+
/** Start a new trigger execution */
|
|
93
|
+
interface TriggerRequest {
|
|
94
|
+
type: 'trigger';
|
|
95
|
+
triggerName: string;
|
|
96
|
+
input?: Record<string, unknown>;
|
|
97
|
+
}
|
|
98
|
+
/** Continue execution after client-side tool handling */
|
|
99
|
+
interface ContinueRequest {
|
|
100
|
+
type: 'continue';
|
|
101
|
+
executionId: string;
|
|
102
|
+
toolResults: ToolResult[];
|
|
103
|
+
}
|
|
104
|
+
/** All request types supported by the session */
|
|
105
|
+
type SessionRequest = TriggerRequest | ContinueRequest;
|
|
140
106
|
/**
|
|
141
107
|
* Converts an async iterable of stream events to an SSE-formatted ReadableStream.
|
|
142
108
|
* Use this when you need to return an SSE response (e.g., HTTP endpoints).
|
|
@@ -171,38 +137,38 @@ declare class AgentSession {
|
|
|
171
137
|
private resourceMap;
|
|
172
138
|
constructor(sessionConfig: SessionConfig);
|
|
173
139
|
/**
|
|
174
|
-
*
|
|
140
|
+
* Execute a session request and stream the response.
|
|
175
141
|
*
|
|
176
|
-
* This method
|
|
177
|
-
*
|
|
178
|
-
* 2. Yields parsed stream events to the consumer
|
|
179
|
-
* 3. When tool-request event is received: executes tools locally
|
|
180
|
-
* 4. POSTs a new request with toolResults to continue
|
|
181
|
-
* 5. Repeats until done (no more tool requests)
|
|
142
|
+
* This is the unified method that handles both triggers and continuations.
|
|
143
|
+
* Use this when you want to pass through requests from the client directly.
|
|
182
144
|
*
|
|
183
|
-
* @param
|
|
184
|
-
* @param triggerInput - Input parameters for the trigger
|
|
145
|
+
* @param request - The request (check `request.type` for the kind)
|
|
185
146
|
* @param options - Optional configuration including abort signal
|
|
186
147
|
*
|
|
187
|
-
* @example
|
|
148
|
+
* @example HTTP route (simple passthrough)
|
|
188
149
|
* ```typescript
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* }
|
|
150
|
+
* const events = session.execute(body, { signal: request.signal });
|
|
151
|
+
* return new Response(toSSEStream(events));
|
|
152
|
+
* ```
|
|
193
153
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
154
|
+
* @example WebSocket handler
|
|
155
|
+
* ```typescript
|
|
156
|
+
* socket.on('message', (data) => {
|
|
157
|
+
* const events = session.execute(data);
|
|
158
|
+
* for await (const event of events) {
|
|
159
|
+
* socket.send(JSON.stringify(event));
|
|
160
|
+
* }
|
|
198
161
|
* });
|
|
199
162
|
* ```
|
|
200
163
|
*/
|
|
201
|
-
|
|
164
|
+
execute(request: SessionRequest, options?: TriggerOptions): AsyncGenerator<StreamEvent>;
|
|
202
165
|
getSessionId(): string;
|
|
166
|
+
private executeStream;
|
|
203
167
|
private handleResourceUpdate;
|
|
204
168
|
}
|
|
205
169
|
|
|
170
|
+
/** Session status indicating whether it's active or expired */
|
|
171
|
+
type SessionStatus = 'active' | 'expired';
|
|
206
172
|
interface SessionState {
|
|
207
173
|
id: string;
|
|
208
174
|
agentId: string;
|
|
@@ -210,6 +176,7 @@ interface SessionState {
|
|
|
210
176
|
variables: Record<string, unknown>;
|
|
211
177
|
resources: Record<string, unknown>;
|
|
212
178
|
messages: ChatMessage[];
|
|
179
|
+
status?: 'active';
|
|
213
180
|
createdAt: string;
|
|
214
181
|
updatedAt: string;
|
|
215
182
|
}
|
|
@@ -217,6 +184,18 @@ interface UISessionState {
|
|
|
217
184
|
sessionId: string;
|
|
218
185
|
agentId: string;
|
|
219
186
|
messages: UIMessage[];
|
|
187
|
+
status?: 'active';
|
|
188
|
+
}
|
|
189
|
+
interface ExpiredSessionState {
|
|
190
|
+
sessionId: string;
|
|
191
|
+
agentId: string;
|
|
192
|
+
status: 'expired';
|
|
193
|
+
createdAt: string;
|
|
194
|
+
}
|
|
195
|
+
interface RestoreSessionResult {
|
|
196
|
+
sessionId: string;
|
|
197
|
+
/** True if session was restored from messages, false if already active */
|
|
198
|
+
restored: boolean;
|
|
220
199
|
}
|
|
221
200
|
interface SessionAttachOptions {
|
|
222
201
|
tools?: ToolHandlers;
|
|
@@ -229,13 +208,31 @@ declare class AgentSessionsApi extends BaseApiClient {
|
|
|
229
208
|
/**
|
|
230
209
|
* Get full session state (for internal/debug use)
|
|
231
210
|
* Note: Contains all messages including hidden content
|
|
211
|
+
*
|
|
212
|
+
* Returns SessionState for active sessions, ExpiredSessionState for expired sessions.
|
|
213
|
+
* Check `status` field to determine which type was returned.
|
|
232
214
|
*/
|
|
233
|
-
get(sessionId: string): Promise<SessionState>;
|
|
215
|
+
get(sessionId: string): Promise<SessionState | ExpiredSessionState>;
|
|
234
216
|
/**
|
|
235
217
|
* Get UI-ready session messages (for client display)
|
|
236
|
-
* Returns only visible messages with hidden content filtered out
|
|
218
|
+
* Returns only visible messages with hidden content filtered out.
|
|
219
|
+
*
|
|
220
|
+
* For expired sessions, returns status: 'expired' without messages.
|
|
221
|
+
* Use restore() to restore from stored messages before continuing.
|
|
222
|
+
*/
|
|
223
|
+
getMessages(sessionId: string): Promise<UISessionState | ExpiredSessionState>;
|
|
224
|
+
/**
|
|
225
|
+
* Restore an expired session from stored messages.
|
|
226
|
+
*
|
|
227
|
+
* Use this to restore a session after its state has expired.
|
|
228
|
+
* The consumer should have stored the UIMessage[] array from previous interactions.
|
|
229
|
+
*
|
|
230
|
+
* @param sessionId - The session ID to restore
|
|
231
|
+
* @param messages - Previously stored UIMessage[] array
|
|
232
|
+
* @param input - Optional session input for system prompt interpolation (same as create)
|
|
233
|
+
* @returns { sessionId, restored: true } if restored, { sessionId, restored: false } if already active
|
|
237
234
|
*/
|
|
238
|
-
|
|
235
|
+
restore(sessionId: string, messages: UIMessage[], input?: Record<string, unknown>): Promise<RestoreSessionResult>;
|
|
239
236
|
/** Attach to an existing session for triggering events */
|
|
240
237
|
attach(sessionId: string, options?: SessionAttachOptions): AgentSession;
|
|
241
238
|
}
|
|
@@ -335,4 +332,4 @@ declare class OctavusClient {
|
|
|
335
332
|
getHeaders(): Record<string, string>;
|
|
336
333
|
}
|
|
337
334
|
|
|
338
|
-
export { type Agent, type AgentDefinition, type AgentFormat, type AgentPrompt, AgentSession, AgentSessionsApi, type AgentSettings, AgentsApi, ApiError, type FileUploadInfo, type FileUploadRequest, FilesApi, OctavusClient, type OctavusClientConfig, Resource, type SessionAttachOptions, type SessionConfig, type
|
|
335
|
+
export { type Agent, type AgentDefinition, type AgentFormat, type AgentPrompt, AgentSession, AgentSessionsApi, type AgentSettings, AgentsApi, ApiError, type ContinueRequest, type ExpiredSessionState, type FileUploadInfo, type FileUploadRequest, FilesApi, OctavusClient, type OctavusClientConfig, Resource, type RestoreSessionResult, type SessionAttachOptions, type SessionConfig, type SessionRequest, type SessionState, type SessionStatus, type TriggerOptions, type TriggerRequest, type UISessionState, type UploadUrlsResponse, toSSEStream };
|
package/dist/index.js
CHANGED
|
@@ -78,7 +78,7 @@ var BaseApiClient = class {
|
|
|
78
78
|
|
|
79
79
|
// src/agent-types.ts
|
|
80
80
|
import { z as z2 } from "zod";
|
|
81
|
-
var agentFormatSchema = z2.enum(["interactive", "
|
|
81
|
+
var agentFormatSchema = z2.enum(["interactive", "worker"]);
|
|
82
82
|
var agentSettingsSchema = z2.object({
|
|
83
83
|
slug: z2.string(),
|
|
84
84
|
name: z2.string(),
|
|
@@ -132,7 +132,9 @@ import {
|
|
|
132
132
|
// src/session.ts
|
|
133
133
|
import {
|
|
134
134
|
safeParseStreamEvent,
|
|
135
|
-
isAbortError
|
|
135
|
+
isAbortError,
|
|
136
|
+
createInternalErrorEvent,
|
|
137
|
+
createApiErrorEvent
|
|
136
138
|
} from "@octavus/core";
|
|
137
139
|
function toSSEStream(events) {
|
|
138
140
|
const encoder = new TextEncoder();
|
|
@@ -147,13 +149,12 @@ function toSSEStream(events) {
|
|
|
147
149
|
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
148
150
|
controller.close();
|
|
149
151
|
} catch (err) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`data: ${JSON.stringify({ type: "error", errorText: err instanceof Error ? err.message : "Unknown error" })}
|
|
153
|
-
|
|
154
|
-
`
|
|
155
|
-
)
|
|
152
|
+
const errorEvent = createInternalErrorEvent(
|
|
153
|
+
err instanceof Error ? err.message : "Unknown error"
|
|
156
154
|
);
|
|
155
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(errorEvent)}
|
|
156
|
+
|
|
157
|
+
`));
|
|
157
158
|
controller.close();
|
|
158
159
|
}
|
|
159
160
|
}
|
|
@@ -174,41 +175,60 @@ var AgentSession = class {
|
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
/**
|
|
177
|
-
*
|
|
178
|
+
* Execute a session request and stream the response.
|
|
178
179
|
*
|
|
179
|
-
* This method
|
|
180
|
-
*
|
|
181
|
-
* 2. Yields parsed stream events to the consumer
|
|
182
|
-
* 3. When tool-request event is received: executes tools locally
|
|
183
|
-
* 4. POSTs a new request with toolResults to continue
|
|
184
|
-
* 5. Repeats until done (no more tool requests)
|
|
180
|
+
* This is the unified method that handles both triggers and continuations.
|
|
181
|
+
* Use this when you want to pass through requests from the client directly.
|
|
185
182
|
*
|
|
186
|
-
* @param
|
|
187
|
-
* @param triggerInput - Input parameters for the trigger
|
|
183
|
+
* @param request - The request (check `request.type` for the kind)
|
|
188
184
|
* @param options - Optional configuration including abort signal
|
|
189
185
|
*
|
|
190
|
-
* @example
|
|
186
|
+
* @example HTTP route (simple passthrough)
|
|
191
187
|
* ```typescript
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* }
|
|
188
|
+
* const events = session.execute(body, { signal: request.signal });
|
|
189
|
+
* return new Response(toSSEStream(events));
|
|
190
|
+
* ```
|
|
196
191
|
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
192
|
+
* @example WebSocket handler
|
|
193
|
+
* ```typescript
|
|
194
|
+
* socket.on('message', (data) => {
|
|
195
|
+
* const events = session.execute(data);
|
|
196
|
+
* for await (const event of events) {
|
|
197
|
+
* socket.send(JSON.stringify(event));
|
|
198
|
+
* }
|
|
201
199
|
* });
|
|
202
200
|
* ```
|
|
203
201
|
*/
|
|
204
|
-
async *
|
|
205
|
-
|
|
202
|
+
async *execute(request, options) {
|
|
203
|
+
if (request.type === "continue") {
|
|
204
|
+
yield* this.executeStream(
|
|
205
|
+
{ executionId: request.executionId, toolResults: request.toolResults },
|
|
206
|
+
options?.signal
|
|
207
|
+
);
|
|
208
|
+
} else {
|
|
209
|
+
yield* this.executeStream(
|
|
210
|
+
{ triggerName: request.triggerName, input: request.input },
|
|
211
|
+
options?.signal
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
getSessionId() {
|
|
216
|
+
return this.sessionId;
|
|
217
|
+
}
|
|
218
|
+
async *executeStream(payload, signal) {
|
|
219
|
+
let toolResults = payload.toolResults;
|
|
220
|
+
let executionId = payload.executionId;
|
|
206
221
|
let continueLoop = true;
|
|
207
222
|
while (continueLoop) {
|
|
208
|
-
if (
|
|
223
|
+
if (signal?.aborted) {
|
|
209
224
|
yield { type: "finish", finishReason: "stop" };
|
|
210
225
|
return;
|
|
211
226
|
}
|
|
227
|
+
const body = {};
|
|
228
|
+
if (payload.triggerName !== void 0) body.triggerName = payload.triggerName;
|
|
229
|
+
if (payload.input !== void 0) body.input = payload.input;
|
|
230
|
+
if (executionId !== void 0) body.executionId = executionId;
|
|
231
|
+
if (toolResults !== void 0) body.toolResults = toolResults;
|
|
212
232
|
let response;
|
|
213
233
|
try {
|
|
214
234
|
response = await fetch(
|
|
@@ -216,12 +236,8 @@ var AgentSession = class {
|
|
|
216
236
|
{
|
|
217
237
|
method: "POST",
|
|
218
238
|
headers: this.config.getHeaders(),
|
|
219
|
-
body: JSON.stringify(
|
|
220
|
-
|
|
221
|
-
input: triggerInput,
|
|
222
|
-
toolResults
|
|
223
|
-
}),
|
|
224
|
-
signal: options?.signal
|
|
239
|
+
body: JSON.stringify(body),
|
|
240
|
+
signal
|
|
225
241
|
}
|
|
226
242
|
);
|
|
227
243
|
} catch (err) {
|
|
@@ -233,11 +249,11 @@ var AgentSession = class {
|
|
|
233
249
|
}
|
|
234
250
|
if (!response.ok) {
|
|
235
251
|
const { message } = await parseApiError(response, "Failed to trigger");
|
|
236
|
-
yield
|
|
252
|
+
yield createApiErrorEvent(response.status, message);
|
|
237
253
|
return;
|
|
238
254
|
}
|
|
239
255
|
if (!response.body) {
|
|
240
|
-
yield
|
|
256
|
+
yield createInternalErrorEvent("Response body is not readable");
|
|
241
257
|
return;
|
|
242
258
|
}
|
|
243
259
|
toolResults = void 0;
|
|
@@ -247,7 +263,7 @@ var AgentSession = class {
|
|
|
247
263
|
let pendingToolCalls = null;
|
|
248
264
|
let streamDone = false;
|
|
249
265
|
while (!streamDone) {
|
|
250
|
-
if (
|
|
266
|
+
if (signal?.aborted) {
|
|
251
267
|
reader.releaseLock();
|
|
252
268
|
yield { type: "finish", finishReason: "stop" };
|
|
253
269
|
return;
|
|
@@ -279,6 +295,9 @@ var AgentSession = class {
|
|
|
279
295
|
continue;
|
|
280
296
|
}
|
|
281
297
|
const event = parsed.data;
|
|
298
|
+
if (event.type === "start" && event.executionId) {
|
|
299
|
+
executionId = event.executionId;
|
|
300
|
+
}
|
|
282
301
|
if (event.type === "tool-request") {
|
|
283
302
|
pendingToolCalls = event.toolCalls;
|
|
284
303
|
continue;
|
|
@@ -300,23 +319,16 @@ var AgentSession = class {
|
|
|
300
319
|
}
|
|
301
320
|
}
|
|
302
321
|
}
|
|
303
|
-
if (
|
|
322
|
+
if (signal?.aborted) {
|
|
304
323
|
yield { type: "finish", finishReason: "stop" };
|
|
305
324
|
return;
|
|
306
325
|
}
|
|
307
326
|
if (pendingToolCalls && pendingToolCalls.length > 0) {
|
|
308
|
-
|
|
309
|
-
|
|
327
|
+
const serverTools = pendingToolCalls.filter((tc) => this.toolHandlers[tc.toolName]);
|
|
328
|
+
const clientTools = pendingToolCalls.filter((tc) => !this.toolHandlers[tc.toolName]);
|
|
329
|
+
const serverResults = await Promise.all(
|
|
330
|
+
serverTools.map(async (tc) => {
|
|
310
331
|
const handler = this.toolHandlers[tc.toolName];
|
|
311
|
-
if (!handler) {
|
|
312
|
-
return {
|
|
313
|
-
toolCallId: tc.toolCallId,
|
|
314
|
-
toolName: tc.toolName,
|
|
315
|
-
error: `No handler for tool: ${tc.toolName}`,
|
|
316
|
-
outputVariable: tc.outputVariable,
|
|
317
|
-
blockIndex: tc.blockIndex
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
332
|
try {
|
|
321
333
|
const result = await handler(tc.args);
|
|
322
334
|
return {
|
|
@@ -337,21 +349,34 @@ var AgentSession = class {
|
|
|
337
349
|
}
|
|
338
350
|
})
|
|
339
351
|
);
|
|
340
|
-
for (const tr of
|
|
352
|
+
for (const tr of serverResults) {
|
|
341
353
|
if (tr.error) {
|
|
342
|
-
yield { type: "tool-output-error", toolCallId: tr.toolCallId,
|
|
354
|
+
yield { type: "tool-output-error", toolCallId: tr.toolCallId, error: tr.error };
|
|
343
355
|
} else {
|
|
344
356
|
yield { type: "tool-output-available", toolCallId: tr.toolCallId, output: tr.result };
|
|
345
357
|
}
|
|
346
358
|
}
|
|
359
|
+
if (clientTools.length > 0) {
|
|
360
|
+
if (!executionId) {
|
|
361
|
+
yield createInternalErrorEvent("Missing executionId for client-tool-request");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
yield {
|
|
365
|
+
type: "client-tool-request",
|
|
366
|
+
executionId,
|
|
367
|
+
toolCalls: clientTools,
|
|
368
|
+
serverToolResults: serverResults.length > 0 ? serverResults : void 0
|
|
369
|
+
};
|
|
370
|
+
yield { type: "finish", finishReason: "client-tool-calls", executionId };
|
|
371
|
+
continueLoop = false;
|
|
372
|
+
} else {
|
|
373
|
+
toolResults = serverResults;
|
|
374
|
+
}
|
|
347
375
|
} else {
|
|
348
376
|
continueLoop = false;
|
|
349
377
|
}
|
|
350
378
|
}
|
|
351
379
|
}
|
|
352
|
-
getSessionId() {
|
|
353
|
-
return this.sessionId;
|
|
354
|
-
}
|
|
355
380
|
handleResourceUpdate(name, value) {
|
|
356
381
|
const resource = this.resourceMap.get(name);
|
|
357
382
|
if (resource) {
|
|
@@ -371,13 +396,25 @@ var sessionStateSchema = z3.object({
|
|
|
371
396
|
variables: z3.record(z3.string(), z3.unknown()),
|
|
372
397
|
resources: z3.record(z3.string(), z3.unknown()),
|
|
373
398
|
messages: z3.array(chatMessageSchema),
|
|
399
|
+
status: z3.literal("active").optional(),
|
|
374
400
|
createdAt: z3.string(),
|
|
375
401
|
updatedAt: z3.string()
|
|
376
402
|
});
|
|
377
403
|
var uiSessionResponseSchema = z3.object({
|
|
378
404
|
sessionId: z3.string(),
|
|
379
405
|
agentId: z3.string(),
|
|
380
|
-
messages: z3.array(uiMessageSchema)
|
|
406
|
+
messages: z3.array(uiMessageSchema),
|
|
407
|
+
status: z3.literal("active").optional()
|
|
408
|
+
});
|
|
409
|
+
var expiredSessionResponseSchema = z3.object({
|
|
410
|
+
sessionId: z3.string(),
|
|
411
|
+
agentId: z3.string(),
|
|
412
|
+
status: z3.literal("expired"),
|
|
413
|
+
createdAt: z3.string()
|
|
414
|
+
});
|
|
415
|
+
var restoreSessionResponseSchema = z3.object({
|
|
416
|
+
sessionId: z3.string(),
|
|
417
|
+
restored: z3.boolean()
|
|
381
418
|
});
|
|
382
419
|
var AgentSessionsApi = class extends BaseApiClient {
|
|
383
420
|
/** Create a new session for an agent */
|
|
@@ -392,18 +429,66 @@ var AgentSessionsApi = class extends BaseApiClient {
|
|
|
392
429
|
/**
|
|
393
430
|
* Get full session state (for internal/debug use)
|
|
394
431
|
* Note: Contains all messages including hidden content
|
|
432
|
+
*
|
|
433
|
+
* Returns SessionState for active sessions, ExpiredSessionState for expired sessions.
|
|
434
|
+
* Check `status` field to determine which type was returned.
|
|
395
435
|
*/
|
|
396
436
|
async get(sessionId) {
|
|
397
|
-
|
|
437
|
+
const response = await fetch(`${this.config.baseUrl}/api/agent-sessions/${sessionId}`, {
|
|
438
|
+
method: "GET",
|
|
439
|
+
headers: this.config.getHeaders()
|
|
440
|
+
});
|
|
441
|
+
if (!response.ok) {
|
|
442
|
+
await throwApiError(response, "Request failed");
|
|
443
|
+
}
|
|
444
|
+
const data = await response.json();
|
|
445
|
+
const expiredResult = expiredSessionResponseSchema.safeParse(data);
|
|
446
|
+
if (expiredResult.success) {
|
|
447
|
+
return expiredResult.data;
|
|
448
|
+
}
|
|
449
|
+
return sessionStateSchema.parse(data);
|
|
398
450
|
}
|
|
399
451
|
/**
|
|
400
452
|
* Get UI-ready session messages (for client display)
|
|
401
|
-
* Returns only visible messages with hidden content filtered out
|
|
453
|
+
* Returns only visible messages with hidden content filtered out.
|
|
454
|
+
*
|
|
455
|
+
* For expired sessions, returns status: 'expired' without messages.
|
|
456
|
+
* Use restore() to restore from stored messages before continuing.
|
|
402
457
|
*/
|
|
403
458
|
async getMessages(sessionId) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
459
|
+
const response = await fetch(
|
|
460
|
+
`${this.config.baseUrl}/api/agent-sessions/${sessionId}?format=ui`,
|
|
461
|
+
{
|
|
462
|
+
method: "GET",
|
|
463
|
+
headers: this.config.getHeaders()
|
|
464
|
+
}
|
|
465
|
+
);
|
|
466
|
+
if (!response.ok) {
|
|
467
|
+
await throwApiError(response, "Request failed");
|
|
468
|
+
}
|
|
469
|
+
const data = await response.json();
|
|
470
|
+
const expiredResult = expiredSessionResponseSchema.safeParse(data);
|
|
471
|
+
if (expiredResult.success) {
|
|
472
|
+
return expiredResult.data;
|
|
473
|
+
}
|
|
474
|
+
return uiSessionResponseSchema.parse(data);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Restore an expired session from stored messages.
|
|
478
|
+
*
|
|
479
|
+
* Use this to restore a session after its state has expired.
|
|
480
|
+
* The consumer should have stored the UIMessage[] array from previous interactions.
|
|
481
|
+
*
|
|
482
|
+
* @param sessionId - The session ID to restore
|
|
483
|
+
* @param messages - Previously stored UIMessage[] array
|
|
484
|
+
* @param input - Optional session input for system prompt interpolation (same as create)
|
|
485
|
+
* @returns { sessionId, restored: true } if restored, { sessionId, restored: false } if already active
|
|
486
|
+
*/
|
|
487
|
+
async restore(sessionId, messages, input) {
|
|
488
|
+
return await this.httpPost(
|
|
489
|
+
`/api/agent-sessions/${sessionId}/restore`,
|
|
490
|
+
{ messages, input },
|
|
491
|
+
restoreSessionResponseSchema
|
|
407
492
|
);
|
|
408
493
|
}
|
|
409
494
|
/** Attach to an existing session for triggering events */
|
|
@@ -501,21 +586,80 @@ var OctavusClient = class {
|
|
|
501
586
|
// src/resource.ts
|
|
502
587
|
var Resource = class {
|
|
503
588
|
};
|
|
589
|
+
|
|
590
|
+
// src/index.ts
|
|
591
|
+
import {
|
|
592
|
+
AppError,
|
|
593
|
+
NotFoundError,
|
|
594
|
+
ValidationError,
|
|
595
|
+
ConflictError,
|
|
596
|
+
ForbiddenError,
|
|
597
|
+
OctavusError,
|
|
598
|
+
isRateLimitError,
|
|
599
|
+
isAuthenticationError,
|
|
600
|
+
isProviderError,
|
|
601
|
+
isToolError,
|
|
602
|
+
isRetryableError,
|
|
603
|
+
isValidationError,
|
|
604
|
+
createErrorEvent,
|
|
605
|
+
errorToStreamEvent,
|
|
606
|
+
createInternalErrorEvent as createInternalErrorEvent2,
|
|
607
|
+
createApiErrorEvent as createApiErrorEvent2,
|
|
608
|
+
generateId,
|
|
609
|
+
isAbortError as isAbortError2,
|
|
610
|
+
MAIN_THREAD,
|
|
611
|
+
resolveThread,
|
|
612
|
+
isMainThread,
|
|
613
|
+
threadForPart,
|
|
614
|
+
isOtherThread,
|
|
615
|
+
isFileReference,
|
|
616
|
+
isFileReferenceArray,
|
|
617
|
+
safeParseStreamEvent as safeParseStreamEvent2,
|
|
618
|
+
safeParseUIMessage,
|
|
619
|
+
safeParseUIMessages,
|
|
620
|
+
OCTAVUS_SKILL_TOOLS,
|
|
621
|
+
isOctavusSkillTool,
|
|
622
|
+
getSkillSlugFromToolCall
|
|
623
|
+
} from "@octavus/core";
|
|
504
624
|
export {
|
|
505
625
|
AgentSession,
|
|
506
626
|
AgentSessionsApi,
|
|
507
627
|
AgentsApi,
|
|
508
628
|
ApiError,
|
|
629
|
+
AppError,
|
|
630
|
+
ConflictError,
|
|
509
631
|
FilesApi,
|
|
632
|
+
ForbiddenError,
|
|
633
|
+
MAIN_THREAD,
|
|
634
|
+
NotFoundError,
|
|
635
|
+
OCTAVUS_SKILL_TOOLS,
|
|
510
636
|
OctavusClient,
|
|
637
|
+
OctavusError,
|
|
511
638
|
Resource,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
639
|
+
ValidationError,
|
|
640
|
+
createApiErrorEvent2 as createApiErrorEvent,
|
|
641
|
+
createErrorEvent,
|
|
642
|
+
createInternalErrorEvent2 as createInternalErrorEvent,
|
|
643
|
+
errorToStreamEvent,
|
|
644
|
+
generateId,
|
|
645
|
+
getSkillSlugFromToolCall,
|
|
646
|
+
isAbortError2 as isAbortError,
|
|
647
|
+
isAuthenticationError,
|
|
648
|
+
isFileReference,
|
|
649
|
+
isFileReferenceArray,
|
|
650
|
+
isMainThread,
|
|
651
|
+
isOctavusSkillTool,
|
|
652
|
+
isOtherThread,
|
|
653
|
+
isProviderError,
|
|
654
|
+
isRateLimitError,
|
|
655
|
+
isRetryableError,
|
|
656
|
+
isToolError,
|
|
657
|
+
isValidationError,
|
|
658
|
+
resolveThread,
|
|
659
|
+
safeParseStreamEvent2 as safeParseStreamEvent,
|
|
660
|
+
safeParseUIMessage,
|
|
661
|
+
safeParseUIMessages,
|
|
662
|
+
threadForPart,
|
|
663
|
+
toSSEStream
|
|
520
664
|
};
|
|
521
665
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api-error.ts","../src/base-api-client.ts","../src/agent-types.ts","../src/agents.ts","../src/agent-sessions.ts","../src/session.ts","../src/files.ts","../src/client.ts","../src/resource.ts"],"sourcesContent":["import { z } from 'zod';\n\nconst ApiErrorResponseSchema = z.object({\n error: z.string().optional(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n/**\n * Error thrown when API request fails\n */\nexport class ApiError extends Error {\n constructor(\n message: string,\n public status: number,\n public code?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\ninterface ParsedApiError {\n message: string;\n code?: string;\n}\n\n/**\n * Parse error from API response using Zod\n */\nexport async function parseApiError(\n response: Response,\n defaultMessage: string,\n): Promise<ParsedApiError> {\n const fallbackMessage = `${defaultMessage}: ${response.statusText}`;\n\n try {\n const json: unknown = await response.json();\n const parsed = ApiErrorResponseSchema.safeParse(json);\n\n if (parsed.success) {\n return {\n message: parsed.data.error ?? parsed.data.message ?? fallbackMessage,\n code: parsed.data.code,\n };\n }\n } catch {\n // Use default message\n }\n\n return { message: fallbackMessage };\n}\n\n/**\n * Parse error from API response and throw ApiError\n */\nexport async function throwApiError(response: Response, defaultMessage: string): Promise<never> {\n const { message, code } = await parseApiError(response, defaultMessage);\n throw new ApiError(message, response.status, code);\n}\n","import type { ZodType } from 'zod';\nimport { throwApiError } from '@/api-error.js';\n\nexport { ApiError } from '@/api-error.js';\n\nexport interface ApiClientConfig {\n baseUrl: string;\n getHeaders: () => Record<string, string>;\n}\n\n/** Base class for API clients with shared HTTP utilities */\nexport abstract class BaseApiClient {\n protected readonly config: ApiClientConfig;\n\n constructor(config: ApiClientConfig) {\n this.config = config;\n }\n\n protected async httpGet<T>(path: string, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'GET',\n headers: this.config.getHeaders(),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n\n protected async httpPost<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'POST',\n headers: this.config.getHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n\n protected async httpPatch<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'PATCH',\n headers: this.config.getHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n}\n","import { z } from 'zod';\n\n/** Agent format - interactive (chat) or generation (background task) */\nexport type AgentFormat = 'interactive' | 'generation';\n\n/** Agent settings */\nexport interface AgentSettings {\n slug: string;\n name: string;\n description?: string;\n format: AgentFormat;\n}\n\n/** Agent prompt */\nexport interface AgentPrompt {\n name: string;\n content: string;\n}\n\n/**\n * Agent summary returned from list endpoint\n */\nexport interface Agent {\n /** Agent slug (human-readable identifier within project) */\n slug: string;\n /** Agent ID - use this for API calls */\n id: string;\n name: string;\n description: string | null;\n format: AgentFormat;\n createdAt: string;\n updatedAt: string;\n projectId: string;\n}\n\n/**\n * Full agent definition returned from get endpoint\n */\nexport interface AgentDefinition {\n settings: AgentSettings;\n protocol: string;\n prompts: AgentPrompt[];\n /** Agent ID - use this for API calls like createSession */\n id: string;\n}\n\n// Schemas\n\nexport const agentFormatSchema = z.enum(['interactive', 'generation']);\n\nconst agentSettingsSchema = z.object({\n slug: z.string(),\n name: z.string(),\n description: z.string().optional(),\n format: agentFormatSchema,\n});\n\nconst agentPromptSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const agentSchema = z.object({\n slug: z.string(),\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n format: agentFormatSchema,\n createdAt: z.string(),\n updatedAt: z.string(),\n projectId: z.string(),\n});\n\nexport const agentsResponseSchema = z.object({\n agents: z.array(agentSchema),\n});\n\nexport const agentDefinitionSchema = z.object({\n settings: agentSettingsSchema,\n protocol: z.string(),\n prompts: z.array(agentPromptSchema),\n id: z.string(),\n});\n","import { BaseApiClient } from '@/base-api-client.js';\nimport {\n agentsResponseSchema,\n agentDefinitionSchema,\n type Agent,\n type AgentDefinition,\n} from '@/agent-types.js';\n\n/**\n * API for listing and retrieving agent definitions.\n *\n * Note: Agent management (create, update, sync) should be done via the @octavus/cli package.\n * This API uses agent IDs only - use CLI for slug-based operations.\n */\nexport class AgentsApi extends BaseApiClient {\n /** List all agents in the project */\n async list(): Promise<Agent[]> {\n const response = await this.httpGet('/api/agents', agentsResponseSchema);\n return response.agents;\n }\n\n /** Get a single agent by ID */\n async get(agentId: string): Promise<AgentDefinition> {\n return await this.httpGet(`/api/agents/${agentId}`, agentDefinitionSchema);\n }\n}\n","import { z } from 'zod';\nimport {\n chatMessageSchema,\n uiMessageSchema,\n type ChatMessage,\n type ToolHandlers,\n type UIMessage,\n} from '@octavus/core';\nimport { BaseApiClient } from '@/base-api-client.js';\nimport { AgentSession } from '@/session.js';\nimport type { Resource } from '@/resource.js';\n\nconst createSessionResponseSchema = z.object({\n sessionId: z.string(),\n});\n\nconst sessionStateSchema = z.object({\n id: z.string(),\n agentId: z.string(),\n input: z.record(z.string(), z.unknown()),\n variables: z.record(z.string(), z.unknown()),\n resources: z.record(z.string(), z.unknown()),\n messages: z.array(chatMessageSchema),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nconst uiSessionResponseSchema = z.object({\n sessionId: z.string(),\n agentId: z.string(),\n messages: z.array(uiMessageSchema),\n});\n\nexport interface SessionState {\n id: string;\n agentId: string;\n input: Record<string, unknown>;\n variables: Record<string, unknown>;\n resources: Record<string, unknown>;\n messages: ChatMessage[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface UISessionState {\n sessionId: string;\n agentId: string;\n messages: UIMessage[];\n}\n\nexport interface SessionAttachOptions {\n tools?: ToolHandlers;\n resources?: Resource[];\n}\n\n/** API for managing agent sessions */\nexport class AgentSessionsApi extends BaseApiClient {\n /** Create a new session for an agent */\n async create(agentId: string, input?: Record<string, unknown>): Promise<string> {\n const response = await this.httpPost(\n '/api/agent-sessions',\n { agentId, input },\n createSessionResponseSchema,\n );\n return response.sessionId;\n }\n\n /**\n * Get full session state (for internal/debug use)\n * Note: Contains all messages including hidden content\n */\n async get(sessionId: string): Promise<SessionState> {\n return await this.httpGet(`/api/agent-sessions/${sessionId}`, sessionStateSchema);\n }\n\n /**\n * Get UI-ready session messages (for client display)\n * Returns only visible messages with hidden content filtered out\n */\n async getMessages(sessionId: string): Promise<UISessionState> {\n return await this.httpGet(\n `/api/agent-sessions/${sessionId}?format=ui`,\n uiSessionResponseSchema,\n );\n }\n\n /** Attach to an existing session for triggering events */\n attach(sessionId: string, options: SessionAttachOptions = {}): AgentSession {\n return new AgentSession({\n sessionId,\n config: this.config,\n tools: options.tools,\n resources: options.resources,\n });\n }\n}\n","import {\n safeParseStreamEvent,\n isAbortError,\n type StreamEvent,\n type ToolHandlers,\n type PendingToolCall,\n type ToolResult,\n} from '@octavus/core';\nimport { parseApiError } from '@/api-error.js';\nimport type { ApiClientConfig } from '@/base-api-client.js';\nimport type { Resource } from '@/resource.js';\n\n/**\n * Converts an async iterable of stream events to an SSE-formatted ReadableStream.\n * Use this when you need to return an SSE response (e.g., HTTP endpoints).\n *\n * @example\n * ```typescript\n * const events = session.trigger('user-message', input);\n * return new Response(toSSEStream(events), {\n * headers: { 'Content-Type': 'text/event-stream' },\n * });\n * ```\n */\nexport function toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of events) {\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`));\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (err) {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: 'error', errorText: err instanceof Error ? err.message : 'Unknown error' })}\\n\\n`,\n ),\n );\n controller.close();\n }\n },\n });\n}\n\nexport interface SessionConfig {\n sessionId: string;\n config: ApiClientConfig;\n tools?: ToolHandlers;\n resources?: Resource[];\n}\n\n/**\n * Options for trigger execution.\n */\nexport interface TriggerOptions {\n /** Abort signal to cancel the trigger execution */\n signal?: AbortSignal;\n}\n\n/** Handles streaming and tool continuation for agent sessions */\nexport class AgentSession {\n private sessionId: string;\n private config: ApiClientConfig;\n private toolHandlers: ToolHandlers;\n private resourceMap: Map<string, Resource>;\n\n constructor(sessionConfig: SessionConfig) {\n this.sessionId = sessionConfig.sessionId;\n this.config = sessionConfig.config;\n this.toolHandlers = sessionConfig.tools ?? {};\n this.resourceMap = new Map();\n\n // Index resources by name for fast lookup\n for (const resource of sessionConfig.resources ?? []) {\n this.resourceMap.set(resource.name, resource);\n }\n }\n\n /**\n * Trigger an agent action and stream the response as parsed events.\n *\n * This method:\n * 1. POSTs to the platform trigger endpoint\n * 2. Yields parsed stream events to the consumer\n * 3. When tool-request event is received: executes tools locally\n * 4. POSTs a new request with toolResults to continue\n * 5. Repeats until done (no more tool requests)\n *\n * @param triggerName - The trigger name defined in the agent's protocol\n * @param triggerInput - Input parameters for the trigger\n * @param options - Optional configuration including abort signal\n *\n * @example\n * ```typescript\n * // For sockets: iterate events directly\n * for await (const event of session.trigger('user-message', input)) {\n * conn.write(JSON.stringify(event));\n * }\n *\n * // For HTTP: convert to SSE stream with abort support\n * const events = session.trigger('user-message', input, { signal: request.signal });\n * return new Response(toSSEStream(events), {\n * headers: { 'Content-Type': 'text/event-stream' },\n * });\n * ```\n */\n async *trigger(\n triggerName: string,\n triggerInput?: Record<string, unknown>,\n options?: TriggerOptions,\n ): AsyncGenerator<StreamEvent> {\n let toolResults: ToolResult[] | undefined;\n let continueLoop = true;\n\n while (continueLoop) {\n // Check if aborted before making request\n if (options?.signal?.aborted) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n // Make request to platform (with toolResults on continuation)\n let response: Response;\n try {\n response = await fetch(\n `${this.config.baseUrl}/api/agent-sessions/${this.sessionId}/trigger`,\n {\n method: 'POST',\n headers: this.config.getHeaders(),\n body: JSON.stringify({\n triggerName,\n input: triggerInput,\n toolResults,\n }),\n signal: options?.signal,\n },\n );\n } catch (err) {\n // Handle abort errors gracefully\n if (isAbortError(err)) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n throw err;\n }\n\n if (!response.ok) {\n const { message } = await parseApiError(response, 'Failed to trigger');\n yield { type: 'error', errorText: message };\n return;\n }\n\n if (!response.body) {\n yield { type: 'error', errorText: 'Response body is not readable' };\n return;\n }\n\n // Reset tool results for next iteration\n toolResults = undefined;\n\n // Read and process the SSE stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let pendingToolCalls: PendingToolCall[] | null = null;\n\n // Read stream until done\n let streamDone = false;\n while (!streamDone) {\n // Check if aborted during stream reading\n if (options?.signal?.aborted) {\n reader.releaseLock();\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n let readResult: ReadableStreamReadResult<Uint8Array>;\n try {\n readResult = await reader.read();\n } catch (err) {\n // Handle abort errors gracefully during read\n if (isAbortError(err)) {\n reader.releaseLock();\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n throw err;\n }\n\n const { done, value } = readResult;\n\n if (done) {\n streamDone = true;\n continue;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const parsed = safeParseStreamEvent(JSON.parse(line.slice(6)));\n if (!parsed.success) {\n // Skip malformed events\n continue;\n }\n const event = parsed.data;\n\n // Handle tool-request - execute tools and prepare continuation\n if (event.type === 'tool-request') {\n pendingToolCalls = event.toolCalls;\n // Don't forward tool-request to consumer\n continue;\n }\n\n if (event.type === 'finish') {\n if (event.finishReason === 'tool-calls' && pendingToolCalls) {\n continue;\n }\n yield event;\n continueLoop = false;\n continue;\n }\n\n // Handle resource updates\n if (event.type === 'resource-update') {\n this.handleResourceUpdate(event.name, event.value);\n }\n\n // Yield all other events to the consumer\n yield event;\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n // Check if aborted before tool execution\n if (options?.signal?.aborted) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n // If we have pending tool calls, execute them and continue\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n toolResults = await Promise.all(\n pendingToolCalls.map(async (tc): Promise<ToolResult> => {\n const handler = this.toolHandlers[tc.toolName];\n if (!handler) {\n return {\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n error: `No handler for tool: ${tc.toolName}`,\n outputVariable: tc.outputVariable,\n blockIndex: tc.blockIndex,\n };\n }\n\n try {\n const result = await handler(tc.args);\n return {\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n result,\n outputVariable: tc.outputVariable,\n blockIndex: tc.blockIndex,\n };\n } catch (err) {\n return {\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n error: err instanceof Error ? err.message : 'Tool execution failed',\n outputVariable: tc.outputVariable,\n blockIndex: tc.blockIndex,\n };\n }\n }),\n );\n\n // Emit tool-output events immediately so UI updates right away\n // (before making continuation request)\n for (const tr of toolResults) {\n if (tr.error) {\n yield { type: 'tool-output-error', toolCallId: tr.toolCallId, errorText: tr.error };\n } else {\n yield { type: 'tool-output-available', toolCallId: tr.toolCallId, output: tr.result };\n }\n }\n\n // Continue loop with tool results\n } else {\n // No pending tools, we're done\n continueLoop = false;\n }\n }\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n private handleResourceUpdate(name: string, value: unknown): void {\n const resource = this.resourceMap.get(name);\n if (resource) {\n void resource.onUpdate(value);\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseApiClient } from '@/base-api-client.js';\n\n// =============================================================================\n// Schemas\n// =============================================================================\n\n/**\n * Schema for a single file upload request\n */\nexport const fileUploadRequestSchema = z.object({\n filename: z.string().min(1).max(255),\n mediaType: z.string().min(1),\n size: z.number().int().positive(),\n});\n\n/**\n * Schema for a single file upload response\n */\nexport const fileUploadInfoSchema = z.object({\n /** File ID to reference in messages */\n id: z.string(),\n /** Presigned PUT URL for uploading to S3 */\n uploadUrl: z.url(),\n /** Presigned GET URL for downloading after upload */\n downloadUrl: z.url(),\n});\n\n/**\n * Schema for the upload URLs response\n */\nexport const uploadUrlsResponseSchema = z.object({\n files: z.array(fileUploadInfoSchema),\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type FileUploadRequest = z.infer<typeof fileUploadRequestSchema>;\nexport type FileUploadInfo = z.infer<typeof fileUploadInfoSchema>;\nexport type UploadUrlsResponse = z.infer<typeof uploadUrlsResponseSchema>;\n\n// =============================================================================\n// API\n// =============================================================================\n\n/**\n * API for file operations.\n *\n * Provides methods to generate presigned URLs for file uploads.\n * Files are uploaded directly to S3, not through the platform.\n *\n * @example\n * ```typescript\n * // Get upload URLs\n * const { files } = await client.files.getUploadUrls(sessionId, [\n * { filename: 'image.png', mediaType: 'image/png', size: 12345 }\n * ]);\n *\n * // Upload directly to S3\n * await fetch(files[0].uploadUrl, {\n * method: 'PUT',\n * body: imageFile,\n * headers: { 'Content-Type': 'image/png' }\n * });\n *\n * // Use downloadUrl as FileReference in trigger input\n * ```\n */\nexport class FilesApi extends BaseApiClient {\n /**\n * Get presigned URLs for uploading files to a session.\n *\n * Returns upload URLs (PUT) and download URLs (GET) for each file.\n * Upload URLs expire in 15 minutes, download URLs match session TTL (24 hours).\n *\n * @param sessionId - The session ID to associate files with\n * @param files - Array of file metadata (filename, mediaType, size)\n * @returns Upload info with presigned URLs for each file\n *\n * @throws ApiError if session doesn't exist or validation fails\n *\n * @example\n * ```typescript\n * const { files } = await client.files.getUploadUrls(sessionId, [\n * { filename: 'photo.jpg', mediaType: 'image/jpeg', size: 102400 },\n * { filename: 'doc.pdf', mediaType: 'application/pdf', size: 204800 },\n * ]);\n *\n * // files[0].id - Use in FileReference\n * // files[0].uploadUrl - PUT to this URL\n * // files[0].downloadUrl - Use as FileReference.url\n * ```\n */\n async getUploadUrls(sessionId: string, files: FileUploadRequest[]): Promise<UploadUrlsResponse> {\n return await this.httpPost(\n '/api/files/upload-urls',\n { sessionId, files },\n uploadUrlsResponseSchema,\n );\n }\n}\n","import type { ApiClientConfig } from '@/base-api-client.js';\nimport { AgentsApi } from '@/agents.js';\nimport { AgentSessionsApi } from '@/agent-sessions.js';\nimport { FilesApi } from '@/files.js';\n\nexport interface OctavusClientConfig {\n baseUrl: string;\n apiKey?: string;\n}\n\n/** Client for interacting with the Octavus platform API */\nexport class OctavusClient {\n readonly agents: AgentsApi;\n readonly agentSessions: AgentSessionsApi;\n readonly files: FilesApi;\n readonly baseUrl: string;\n private readonly apiKey?: string;\n\n constructor(config: OctavusClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n\n const apiConfig: ApiClientConfig = {\n baseUrl: this.baseUrl,\n getHeaders: () => this.getHeaders(),\n };\n\n this.agents = new AgentsApi(apiConfig);\n this.agentSessions = new AgentSessionsApi(apiConfig);\n this.files = new FilesApi(apiConfig);\n }\n\n getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (this.apiKey) {\n headers.Authorization = `Bearer ${this.apiKey}`;\n }\n\n return headers;\n }\n}\n","/**\n * Base class for agent-managed resources.\n * Extend this class to define how each resource should be persisted when the agent updates it.\n */\nexport abstract class Resource {\n /** The resource name as defined in the agent protocol */\n abstract readonly name: string;\n\n /** Called when the agent updates this resource */\n abstract onUpdate(value: unknown): Promise<void> | void;\n}\n"],"mappings":"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","names":["z","z","z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/api-error.ts","../src/base-api-client.ts","../src/agent-types.ts","../src/agents.ts","../src/agent-sessions.ts","../src/session.ts","../src/files.ts","../src/client.ts","../src/resource.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod';\n\nconst ApiErrorResponseSchema = z.object({\n error: z.string().optional(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n/**\n * Error thrown when API request fails\n */\nexport class ApiError extends Error {\n constructor(\n message: string,\n public status: number,\n public code?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\ninterface ParsedApiError {\n message: string;\n code?: string;\n}\n\n/**\n * Parse error from API response using Zod\n */\nexport async function parseApiError(\n response: Response,\n defaultMessage: string,\n): Promise<ParsedApiError> {\n const fallbackMessage = `${defaultMessage}: ${response.statusText}`;\n\n try {\n const json: unknown = await response.json();\n const parsed = ApiErrorResponseSchema.safeParse(json);\n\n if (parsed.success) {\n return {\n message: parsed.data.error ?? parsed.data.message ?? fallbackMessage,\n code: parsed.data.code,\n };\n }\n } catch {\n // Use default message\n }\n\n return { message: fallbackMessage };\n}\n\n/**\n * Parse error from API response and throw ApiError\n */\nexport async function throwApiError(response: Response, defaultMessage: string): Promise<never> {\n const { message, code } = await parseApiError(response, defaultMessage);\n throw new ApiError(message, response.status, code);\n}\n","import type { ZodType } from 'zod';\nimport { throwApiError } from '@/api-error.js';\n\nexport { ApiError } from '@/api-error.js';\n\nexport interface ApiClientConfig {\n baseUrl: string;\n getHeaders: () => Record<string, string>;\n}\n\n/** Base class for API clients with shared HTTP utilities */\nexport abstract class BaseApiClient {\n protected readonly config: ApiClientConfig;\n\n constructor(config: ApiClientConfig) {\n this.config = config;\n }\n\n protected async httpGet<T>(path: string, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'GET',\n headers: this.config.getHeaders(),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n\n protected async httpPost<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'POST',\n headers: this.config.getHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n\n protected async httpPatch<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\n method: 'PATCH',\n headers: this.config.getHeaders(),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n return schema.parse(data);\n }\n}\n","import { z } from 'zod';\n\n/** Agent format - interactive (chat) or worker (background task) */\nexport type AgentFormat = 'interactive' | 'worker';\n\n/** Agent settings */\nexport interface AgentSettings {\n slug: string;\n name: string;\n description?: string;\n format: AgentFormat;\n}\n\n/** Agent prompt */\nexport interface AgentPrompt {\n name: string;\n content: string;\n}\n\n/**\n * Agent summary returned from list endpoint\n */\nexport interface Agent {\n /** Agent slug (human-readable identifier within project) */\n slug: string;\n /** Agent ID - use this for API calls */\n id: string;\n name: string;\n description: string | null;\n format: AgentFormat;\n createdAt: string;\n updatedAt: string;\n projectId: string;\n}\n\n/**\n * Full agent definition returned from get endpoint\n */\nexport interface AgentDefinition {\n settings: AgentSettings;\n protocol: string;\n prompts: AgentPrompt[];\n /** Agent ID - use this for API calls like createSession */\n id: string;\n}\n\n// Schemas\n\nexport const agentFormatSchema = z.enum(['interactive', 'worker']);\n\nconst agentSettingsSchema = z.object({\n slug: z.string(),\n name: z.string(),\n description: z.string().optional(),\n format: agentFormatSchema,\n});\n\nconst agentPromptSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const agentSchema = z.object({\n slug: z.string(),\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n format: agentFormatSchema,\n createdAt: z.string(),\n updatedAt: z.string(),\n projectId: z.string(),\n});\n\nexport const agentsResponseSchema = z.object({\n agents: z.array(agentSchema),\n});\n\nexport const agentDefinitionSchema = z.object({\n settings: agentSettingsSchema,\n protocol: z.string(),\n prompts: z.array(agentPromptSchema),\n id: z.string(),\n});\n","import { BaseApiClient } from '@/base-api-client.js';\nimport {\n agentsResponseSchema,\n agentDefinitionSchema,\n type Agent,\n type AgentDefinition,\n} from '@/agent-types.js';\n\n/**\n * API for listing and retrieving agent definitions.\n *\n * Note: Agent management (create, update, sync) should be done via the @octavus/cli package.\n * This API uses agent IDs only - use CLI for slug-based operations.\n */\nexport class AgentsApi extends BaseApiClient {\n /** List all agents in the project */\n async list(): Promise<Agent[]> {\n const response = await this.httpGet('/api/agents', agentsResponseSchema);\n return response.agents;\n }\n\n /** Get a single agent by ID */\n async get(agentId: string): Promise<AgentDefinition> {\n return await this.httpGet(`/api/agents/${agentId}`, agentDefinitionSchema);\n }\n}\n","import { z } from 'zod';\nimport {\n chatMessageSchema,\n uiMessageSchema,\n type ChatMessage,\n type ToolHandlers,\n type UIMessage,\n} from '@octavus/core';\nimport { BaseApiClient } from '@/base-api-client.js';\nimport { throwApiError } from '@/api-error.js';\nimport { AgentSession } from '@/session.js';\nimport type { Resource } from '@/resource.js';\n\nconst createSessionResponseSchema = z.object({\n sessionId: z.string(),\n});\n\nconst sessionStateSchema = z.object({\n id: z.string(),\n agentId: z.string(),\n input: z.record(z.string(), z.unknown()),\n variables: z.record(z.string(), z.unknown()),\n resources: z.record(z.string(), z.unknown()),\n messages: z.array(chatMessageSchema),\n status: z.literal('active').optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nconst uiSessionResponseSchema = z.object({\n sessionId: z.string(),\n agentId: z.string(),\n messages: z.array(uiMessageSchema),\n status: z.literal('active').optional(),\n});\n\nconst expiredSessionResponseSchema = z.object({\n sessionId: z.string(),\n agentId: z.string(),\n status: z.literal('expired'),\n createdAt: z.string(),\n});\n\nconst restoreSessionResponseSchema = z.object({\n sessionId: z.string(),\n restored: z.boolean(),\n});\n\n/** Session status indicating whether it's active or expired */\nexport type SessionStatus = 'active' | 'expired';\n\nexport interface SessionState {\n id: string;\n agentId: string;\n input: Record<string, unknown>;\n variables: Record<string, unknown>;\n resources: Record<string, unknown>;\n messages: ChatMessage[];\n status?: 'active';\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface UISessionState {\n sessionId: string;\n agentId: string;\n messages: UIMessage[];\n status?: 'active';\n}\n\nexport interface ExpiredSessionState {\n sessionId: string;\n agentId: string;\n status: 'expired';\n createdAt: string;\n}\n\nexport interface RestoreSessionResult {\n sessionId: string;\n /** True if session was restored from messages, false if already active */\n restored: boolean;\n}\n\nexport interface SessionAttachOptions {\n tools?: ToolHandlers;\n resources?: Resource[];\n}\n\n/** API for managing agent sessions */\nexport class AgentSessionsApi extends BaseApiClient {\n /** Create a new session for an agent */\n async create(agentId: string, input?: Record<string, unknown>): Promise<string> {\n const response = await this.httpPost(\n '/api/agent-sessions',\n { agentId, input },\n createSessionResponseSchema,\n );\n return response.sessionId;\n }\n\n /**\n * Get full session state (for internal/debug use)\n * Note: Contains all messages including hidden content\n *\n * Returns SessionState for active sessions, ExpiredSessionState for expired sessions.\n * Check `status` field to determine which type was returned.\n */\n async get(sessionId: string): Promise<SessionState | ExpiredSessionState> {\n const response = await fetch(`${this.config.baseUrl}/api/agent-sessions/${sessionId}`, {\n method: 'GET',\n headers: this.config.getHeaders(),\n });\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n\n const expiredResult = expiredSessionResponseSchema.safeParse(data);\n if (expiredResult.success) {\n return expiredResult.data;\n }\n\n return sessionStateSchema.parse(data);\n }\n\n /**\n * Get UI-ready session messages (for client display)\n * Returns only visible messages with hidden content filtered out.\n *\n * For expired sessions, returns status: 'expired' without messages.\n * Use restore() to restore from stored messages before continuing.\n */\n async getMessages(sessionId: string): Promise<UISessionState | ExpiredSessionState> {\n const response = await fetch(\n `${this.config.baseUrl}/api/agent-sessions/${sessionId}?format=ui`,\n {\n method: 'GET',\n headers: this.config.getHeaders(),\n },\n );\n\n if (!response.ok) {\n await throwApiError(response, 'Request failed');\n }\n\n const data: unknown = await response.json();\n\n const expiredResult = expiredSessionResponseSchema.safeParse(data);\n if (expiredResult.success) {\n return expiredResult.data;\n }\n\n return uiSessionResponseSchema.parse(data);\n }\n\n /**\n * Restore an expired session from stored messages.\n *\n * Use this to restore a session after its state has expired.\n * The consumer should have stored the UIMessage[] array from previous interactions.\n *\n * @param sessionId - The session ID to restore\n * @param messages - Previously stored UIMessage[] array\n * @param input - Optional session input for system prompt interpolation (same as create)\n * @returns { sessionId, restored: true } if restored, { sessionId, restored: false } if already active\n */\n async restore(\n sessionId: string,\n messages: UIMessage[],\n input?: Record<string, unknown>,\n ): Promise<RestoreSessionResult> {\n return await this.httpPost(\n `/api/agent-sessions/${sessionId}/restore`,\n { messages, input },\n restoreSessionResponseSchema,\n );\n }\n\n /** Attach to an existing session for triggering events */\n attach(sessionId: string, options: SessionAttachOptions = {}): AgentSession {\n return new AgentSession({\n sessionId,\n config: this.config,\n tools: options.tools,\n resources: options.resources,\n });\n }\n}\n","import {\n safeParseStreamEvent,\n isAbortError,\n createInternalErrorEvent,\n createApiErrorEvent,\n type StreamEvent,\n type ToolHandlers,\n type PendingToolCall,\n type ToolResult,\n} from '@octavus/core';\nimport { parseApiError } from '@/api-error.js';\nimport type { ApiClientConfig } from '@/base-api-client.js';\nimport type { Resource } from '@/resource.js';\n\n// =============================================================================\n// Request Types\n// =============================================================================\n\n/** Start a new trigger execution */\nexport interface TriggerRequest {\n type: 'trigger';\n triggerName: string;\n input?: Record<string, unknown>;\n}\n\n/** Continue execution after client-side tool handling */\nexport interface ContinueRequest {\n type: 'continue';\n executionId: string;\n toolResults: ToolResult[];\n}\n\n/** All request types supported by the session */\nexport type SessionRequest = TriggerRequest | ContinueRequest;\n\n/**\n * Converts an async iterable of stream events to an SSE-formatted ReadableStream.\n * Use this when you need to return an SSE response (e.g., HTTP endpoints).\n *\n * @example\n * ```typescript\n * const events = session.trigger('user-message', input);\n * return new Response(toSSEStream(events), {\n * headers: { 'Content-Type': 'text/event-stream' },\n * });\n * ```\n */\nexport function toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of events) {\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`));\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (err) {\n const errorEvent = createInternalErrorEvent(\n err instanceof Error ? err.message : 'Unknown error',\n );\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(errorEvent)}\\n\\n`));\n controller.close();\n }\n },\n });\n}\n\nexport interface SessionConfig {\n sessionId: string;\n config: ApiClientConfig;\n tools?: ToolHandlers;\n resources?: Resource[];\n}\n\n/**\n * Options for trigger execution.\n */\nexport interface TriggerOptions {\n /** Abort signal to cancel the trigger execution */\n signal?: AbortSignal;\n}\n\n/** Handles streaming and tool continuation for agent sessions */\nexport class AgentSession {\n private sessionId: string;\n private config: ApiClientConfig;\n private toolHandlers: ToolHandlers;\n private resourceMap: Map<string, Resource>;\n\n constructor(sessionConfig: SessionConfig) {\n this.sessionId = sessionConfig.sessionId;\n this.config = sessionConfig.config;\n this.toolHandlers = sessionConfig.tools ?? {};\n this.resourceMap = new Map();\n\n // Index resources by name for fast lookup\n for (const resource of sessionConfig.resources ?? []) {\n this.resourceMap.set(resource.name, resource);\n }\n }\n\n /**\n * Execute a session request and stream the response.\n *\n * This is the unified method that handles both triggers and continuations.\n * Use this when you want to pass through requests from the client directly.\n *\n * @param request - The request (check `request.type` for the kind)\n * @param options - Optional configuration including abort signal\n *\n * @example HTTP route (simple passthrough)\n * ```typescript\n * const events = session.execute(body, { signal: request.signal });\n * return new Response(toSSEStream(events));\n * ```\n *\n * @example WebSocket handler\n * ```typescript\n * socket.on('message', (data) => {\n * const events = session.execute(data);\n * for await (const event of events) {\n * socket.send(JSON.stringify(event));\n * }\n * });\n * ```\n */\n async *execute(request: SessionRequest, options?: TriggerOptions): AsyncGenerator<StreamEvent> {\n if (request.type === 'continue') {\n yield* this.executeStream(\n { executionId: request.executionId, toolResults: request.toolResults },\n options?.signal,\n );\n } else {\n yield* this.executeStream(\n { triggerName: request.triggerName, input: request.input },\n options?.signal,\n );\n }\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n private async *executeStream(\n payload: {\n triggerName?: string;\n input?: Record<string, unknown>;\n executionId?: string;\n toolResults?: ToolResult[];\n },\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n let toolResults = payload.toolResults;\n let executionId = payload.executionId;\n let continueLoop = true;\n\n while (continueLoop) {\n // Check if aborted before making request\n if (signal?.aborted) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n // Build request body - only include defined fields\n const body: Record<string, unknown> = {};\n if (payload.triggerName !== undefined) body.triggerName = payload.triggerName;\n if (payload.input !== undefined) body.input = payload.input;\n if (executionId !== undefined) body.executionId = executionId;\n if (toolResults !== undefined) body.toolResults = toolResults;\n\n // Make request to platform\n let response: Response;\n try {\n response = await fetch(\n `${this.config.baseUrl}/api/agent-sessions/${this.sessionId}/trigger`,\n {\n method: 'POST',\n headers: this.config.getHeaders(),\n body: JSON.stringify(body),\n signal,\n },\n );\n } catch (err) {\n // Handle abort errors gracefully\n if (isAbortError(err)) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n throw err;\n }\n\n if (!response.ok) {\n const { message } = await parseApiError(response, 'Failed to trigger');\n yield createApiErrorEvent(response.status, message);\n return;\n }\n\n if (!response.body) {\n yield createInternalErrorEvent('Response body is not readable');\n return;\n }\n\n // Reset tool results for next iteration (executionId persists through the loop)\n toolResults = undefined;\n\n // Read and process the SSE stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let pendingToolCalls: PendingToolCall[] | null = null;\n\n // Read stream until done\n let streamDone = false;\n while (!streamDone) {\n // Check if aborted during stream reading\n if (signal?.aborted) {\n reader.releaseLock();\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n let readResult: ReadableStreamReadResult<Uint8Array>;\n try {\n readResult = await reader.read();\n } catch (err) {\n // Handle abort errors gracefully during read\n if (isAbortError(err)) {\n reader.releaseLock();\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n throw err;\n }\n\n const { done, value } = readResult;\n\n if (done) {\n streamDone = true;\n continue;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const parsed = safeParseStreamEvent(JSON.parse(line.slice(6)));\n if (!parsed.success) {\n // Skip malformed events\n continue;\n }\n const event = parsed.data;\n\n // Capture executionId from start event\n if (event.type === 'start' && event.executionId) {\n executionId = event.executionId;\n }\n\n // Handle tool-request - split into server and client tools\n if (event.type === 'tool-request') {\n pendingToolCalls = event.toolCalls;\n // Don't forward tool-request to consumer\n continue;\n }\n\n if (event.type === 'finish') {\n if (event.finishReason === 'tool-calls' && pendingToolCalls) {\n continue;\n }\n yield event;\n continueLoop = false;\n continue;\n }\n\n if (event.type === 'resource-update') {\n this.handleResourceUpdate(event.name, event.value);\n }\n\n yield event;\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n\n // Check if aborted before tool execution\n if (signal?.aborted) {\n yield { type: 'finish', finishReason: 'stop' };\n return;\n }\n\n // If we have pending tool calls, split into server and client tools\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n const serverTools = pendingToolCalls.filter((tc) => this.toolHandlers[tc.toolName]);\n const clientTools = pendingToolCalls.filter((tc) => !this.toolHandlers[tc.toolName]);\n\n const serverResults = await Promise.all(\n serverTools.map(async (tc): Promise<ToolResult> => {\n // Handler is guaranteed to exist since we filtered by handler presence\n const handler = this.toolHandlers[tc.toolName]!;\n try {\n const result = await handler(tc.args);\n return {\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n result,\n outputVariable: tc.outputVariable,\n blockIndex: tc.blockIndex,\n };\n } catch (err) {\n return {\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n error: err instanceof Error ? err.message : 'Tool execution failed',\n outputVariable: tc.outputVariable,\n blockIndex: tc.blockIndex,\n };\n }\n }),\n );\n\n // Emit tool-output events for server tools immediately\n for (const tr of serverResults) {\n if (tr.error) {\n yield { type: 'tool-output-error', toolCallId: tr.toolCallId, error: tr.error };\n } else {\n yield { type: 'tool-output-available', toolCallId: tr.toolCallId, output: tr.result };\n }\n }\n\n // If there are client tools, emit client-tool-request and stop the loop\n if (clientTools.length > 0) {\n if (!executionId) {\n yield createInternalErrorEvent('Missing executionId for client-tool-request');\n return;\n }\n // Include executionId and server results in event\n yield {\n type: 'client-tool-request',\n executionId,\n toolCalls: clientTools,\n serverToolResults: serverResults.length > 0 ? serverResults : undefined,\n };\n yield { type: 'finish', finishReason: 'client-tool-calls', executionId };\n continueLoop = false;\n } else {\n // All tools handled server-side, continue loop\n toolResults = serverResults;\n }\n } else {\n // No pending tools, we're done\n continueLoop = false;\n }\n }\n }\n\n private handleResourceUpdate(name: string, value: unknown): void {\n const resource = this.resourceMap.get(name);\n if (resource) {\n void resource.onUpdate(value);\n }\n }\n}\n","import { z } from 'zod';\nimport { BaseApiClient } from '@/base-api-client.js';\n\n// =============================================================================\n// Schemas\n// =============================================================================\n\n/**\n * Schema for a single file upload request\n */\nexport const fileUploadRequestSchema = z.object({\n filename: z.string().min(1).max(255),\n mediaType: z.string().min(1),\n size: z.number().int().positive(),\n});\n\n/**\n * Schema for a single file upload response\n */\nexport const fileUploadInfoSchema = z.object({\n /** File ID to reference in messages */\n id: z.string(),\n /** Presigned PUT URL for uploading to S3 */\n uploadUrl: z.url(),\n /** Presigned GET URL for downloading after upload */\n downloadUrl: z.url(),\n});\n\n/**\n * Schema for the upload URLs response\n */\nexport const uploadUrlsResponseSchema = z.object({\n files: z.array(fileUploadInfoSchema),\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type FileUploadRequest = z.infer<typeof fileUploadRequestSchema>;\nexport type FileUploadInfo = z.infer<typeof fileUploadInfoSchema>;\nexport type UploadUrlsResponse = z.infer<typeof uploadUrlsResponseSchema>;\n\n// =============================================================================\n// API\n// =============================================================================\n\n/**\n * API for file operations.\n *\n * Provides methods to generate presigned URLs for file uploads.\n * Files are uploaded directly to S3, not through the platform.\n *\n * @example\n * ```typescript\n * // Get upload URLs\n * const { files } = await client.files.getUploadUrls(sessionId, [\n * { filename: 'image.png', mediaType: 'image/png', size: 12345 }\n * ]);\n *\n * // Upload directly to S3\n * await fetch(files[0].uploadUrl, {\n * method: 'PUT',\n * body: imageFile,\n * headers: { 'Content-Type': 'image/png' }\n * });\n *\n * // Use downloadUrl as FileReference in trigger input\n * ```\n */\nexport class FilesApi extends BaseApiClient {\n /**\n * Get presigned URLs for uploading files to a session.\n *\n * Returns upload URLs (PUT) and download URLs (GET) for each file.\n * Upload URLs expire in 15 minutes, download URLs match session TTL (24 hours).\n *\n * @param sessionId - The session ID to associate files with\n * @param files - Array of file metadata (filename, mediaType, size)\n * @returns Upload info with presigned URLs for each file\n *\n * @throws ApiError if session doesn't exist or validation fails\n *\n * @example\n * ```typescript\n * const { files } = await client.files.getUploadUrls(sessionId, [\n * { filename: 'photo.jpg', mediaType: 'image/jpeg', size: 102400 },\n * { filename: 'doc.pdf', mediaType: 'application/pdf', size: 204800 },\n * ]);\n *\n * // files[0].id - Use in FileReference\n * // files[0].uploadUrl - PUT to this URL\n * // files[0].downloadUrl - Use as FileReference.url\n * ```\n */\n async getUploadUrls(sessionId: string, files: FileUploadRequest[]): Promise<UploadUrlsResponse> {\n return await this.httpPost(\n '/api/files/upload-urls',\n { sessionId, files },\n uploadUrlsResponseSchema,\n );\n }\n}\n","import type { ApiClientConfig } from '@/base-api-client.js';\nimport { AgentsApi } from '@/agents.js';\nimport { AgentSessionsApi } from '@/agent-sessions.js';\nimport { FilesApi } from '@/files.js';\n\nexport interface OctavusClientConfig {\n baseUrl: string;\n apiKey?: string;\n}\n\n/** Client for interacting with the Octavus platform API */\nexport class OctavusClient {\n readonly agents: AgentsApi;\n readonly agentSessions: AgentSessionsApi;\n readonly files: FilesApi;\n readonly baseUrl: string;\n private readonly apiKey?: string;\n\n constructor(config: OctavusClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n\n const apiConfig: ApiClientConfig = {\n baseUrl: this.baseUrl,\n getHeaders: () => this.getHeaders(),\n };\n\n this.agents = new AgentsApi(apiConfig);\n this.agentSessions = new AgentSessionsApi(apiConfig);\n this.files = new FilesApi(apiConfig);\n }\n\n getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (this.apiKey) {\n headers.Authorization = `Bearer ${this.apiKey}`;\n }\n\n return headers;\n }\n}\n","/**\n * Base class for agent-managed resources.\n * Extend this class to define how each resource should be persisted when the agent updates it.\n */\nexport abstract class Resource {\n /** The resource name as defined in the agent protocol */\n abstract readonly name: string;\n\n /** Called when the agent updates this resource */\n abstract onUpdate(value: unknown): Promise<void> | void;\n}\n","export { OctavusClient, type OctavusClientConfig } from '@/client.js';\nexport { AgentsApi } from '@/agents.js';\nexport {\n AgentSessionsApi,\n type SessionState,\n type UISessionState,\n type ExpiredSessionState,\n type RestoreSessionResult,\n type SessionStatus,\n type SessionAttachOptions,\n} from '@/agent-sessions.js';\nexport {\n FilesApi,\n type FileUploadRequest,\n type FileUploadInfo,\n type UploadUrlsResponse,\n} from '@/files.js';\nexport {\n AgentSession,\n toSSEStream,\n type SessionConfig,\n type TriggerOptions,\n type SessionRequest,\n type TriggerRequest,\n type ContinueRequest,\n} from '@/session.js';\nexport { Resource } from '@/resource.js';\nexport { ApiError } from '@/api-error.js';\n\n// Agent types (read-only - use @octavus/cli for agent management)\nexport type {\n AgentFormat,\n AgentSettings,\n AgentPrompt,\n Agent,\n AgentDefinition,\n} from '@/agent-types.js';\n\nexport type * from '@octavus/core';\nexport {\n // Error classes\n AppError,\n NotFoundError,\n ValidationError,\n ConflictError,\n ForbiddenError,\n OctavusError,\n // Error type guards\n isRateLimitError,\n isAuthenticationError,\n isProviderError,\n isToolError,\n isRetryableError,\n isValidationError,\n // Error event helpers\n createErrorEvent,\n errorToStreamEvent,\n createInternalErrorEvent,\n createApiErrorEvent,\n // Utilities\n generateId,\n isAbortError,\n // Thread helpers\n MAIN_THREAD,\n resolveThread,\n isMainThread,\n threadForPart,\n isOtherThread,\n // Type guards\n isFileReference,\n isFileReferenceArray,\n // Safe parse helpers\n safeParseStreamEvent,\n safeParseUIMessage,\n safeParseUIMessages,\n // Skills\n OCTAVUS_SKILL_TOOLS,\n isOctavusSkillTool,\n getSkillSlugFromToolCall,\n} from '@octavus/core';\n"],"mappings":"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","names":["z","z","z","z","z","createInternalErrorEvent","createApiErrorEvent","isAbortError","safeParseStreamEvent"]}
|
package/package.json
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octavus/server-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Server SDK for integrating Octavus agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Octavus AI <dev@octavus.ai>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/octavus-ai/js-sdk.git",
|
|
10
|
+
"directory": "packages/server-sdk"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://octavus.ai",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/octavus-ai/js-sdk/issues"
|
|
15
|
+
},
|
|
7
16
|
"keywords": [
|
|
8
17
|
"octavus",
|
|
9
18
|
"ai",
|
|
10
19
|
"agents",
|
|
11
20
|
"sdk",
|
|
12
21
|
"server",
|
|
13
|
-
"tools"
|
|
22
|
+
"tools",
|
|
23
|
+
"nodejs"
|
|
14
24
|
],
|
|
15
25
|
"type": "module",
|
|
16
26
|
"sideEffects": false,
|
|
@@ -30,7 +40,7 @@
|
|
|
30
40
|
},
|
|
31
41
|
"dependencies": {
|
|
32
42
|
"zod": "^4.1.13",
|
|
33
|
-
"@octavus/core": "^
|
|
43
|
+
"@octavus/core": "^2.0.0"
|
|
34
44
|
},
|
|
35
45
|
"devDependencies": {
|
|
36
46
|
"tsup": "^8.3.5",
|