@inferencesh/sdk 0.5.2 → 0.5.5
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 +22 -0
- package/dist/agent/actions.js +88 -7
- package/dist/agent/provider.d.ts +1 -1
- package/dist/agent/provider.js +20 -4
- package/dist/agent/types.d.ts +14 -3
- package/dist/api/agents.d.ts +8 -1
- package/dist/api/agents.js +84 -9
- package/dist/api/tasks.d.ts +6 -0
- package/dist/api/tasks.js +51 -1
- package/dist/http/client.d.ts +16 -0
- package/dist/http/client.js +10 -0
- package/dist/http/poll.d.ts +39 -0
- package/dist/http/poll.js +73 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +3 -0
- package/dist/tool-builder.js +2 -0
- package/dist/tool-builder.test.js +11 -0
- package/dist/types.d.ts +50 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -264,6 +264,28 @@ await agent.sendMessage('What is the weather in Paris?', {
|
|
|
264
264
|
});
|
|
265
265
|
```
|
|
266
266
|
|
|
267
|
+
### Structured Output
|
|
268
|
+
|
|
269
|
+
Use `output_schema` to get structured JSON responses:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
const agent = client.agents.create({
|
|
273
|
+
core_app: { ref: 'infsh/claude-sonnet-4@latest' },
|
|
274
|
+
output_schema: {
|
|
275
|
+
type: 'object',
|
|
276
|
+
properties: {
|
|
277
|
+
summary: { type: 'string' },
|
|
278
|
+
sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] },
|
|
279
|
+
confidence: { type: 'number' },
|
|
280
|
+
},
|
|
281
|
+
required: ['summary', 'sentiment', 'confidence'],
|
|
282
|
+
},
|
|
283
|
+
internal_tools: { finish: true },
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const response = await agent.sendMessage('Analyze: Great product!');
|
|
287
|
+
```
|
|
288
|
+
|
|
267
289
|
### Agent Methods
|
|
268
290
|
|
|
269
291
|
| Method | Description |
|
package/dist/agent/actions.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { ToolInvocationStatusAwaitingInput, ToolTypeClient, } from '../types';
|
|
8
8
|
import { StreamManager } from '../http/stream';
|
|
9
|
+
import { PollManager } from '../http/poll';
|
|
9
10
|
import { isAdHocConfig, extractClientToolHandlers } from './types';
|
|
10
11
|
import * as api from './api';
|
|
11
12
|
// =============================================================================
|
|
@@ -16,7 +17,7 @@ const dispatchedToolInvocations = new Set();
|
|
|
16
17
|
// Action Creators
|
|
17
18
|
// =============================================================================
|
|
18
19
|
export function createActions(ctx) {
|
|
19
|
-
const { client, dispatch, getConfig, getChatId, getClientToolHandlers, getStreamManager, setStreamManager, callbacks } = ctx;
|
|
20
|
+
const { client, dispatch, getConfig, getChatId, getClientToolHandlers, getStreamManager, setStreamManager, getStreamEnabled, getPollIntervalMs, callbacks } = ctx;
|
|
20
21
|
// =========================================================================
|
|
21
22
|
// Internal helpers
|
|
22
23
|
// =========================================================================
|
|
@@ -48,7 +49,8 @@ export function createActions(ctx) {
|
|
|
48
49
|
if (!handler) {
|
|
49
50
|
console.warn(`[AgentSDK] No handler for client tool: ${functionName}`);
|
|
50
51
|
api.submitToolResult(client, invocation.id, JSON.stringify({
|
|
51
|
-
|
|
52
|
+
status: 'not_available',
|
|
53
|
+
message: `Client tool "${functionName}" is not available in this environment`,
|
|
52
54
|
}));
|
|
53
55
|
continue;
|
|
54
56
|
}
|
|
@@ -77,10 +79,24 @@ export function createActions(ctx) {
|
|
|
77
79
|
setStreamManager(undefined);
|
|
78
80
|
dispatch({ type: 'SET_STATUS', payload: 'connecting' });
|
|
79
81
|
callbacks.onStatusChange?.('connecting');
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
try {
|
|
83
|
+
// Fetch initial chat
|
|
84
|
+
const chat = await api.fetchChat(client, id);
|
|
85
|
+
if (chat) {
|
|
86
|
+
setChat(chat);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error('[AgentSDK] Failed to fetch chat:', error);
|
|
91
|
+
dispatch({ type: 'SET_STATUS', payload: 'idle' });
|
|
92
|
+
dispatch({ type: 'SET_IS_GENERATING', payload: false });
|
|
93
|
+
callbacks.onStatusChange?.('idle');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!getStreamEnabled()) {
|
|
97
|
+
// Polling mode
|
|
98
|
+
pollChat(id);
|
|
99
|
+
return;
|
|
84
100
|
}
|
|
85
101
|
// Single unified stream with TypedEvents (both Chat and ChatMessage events)
|
|
86
102
|
const manager = new StreamManager({
|
|
@@ -96,6 +112,17 @@ export function createActions(ctx) {
|
|
|
96
112
|
dispatch({ type: 'SET_STATUS', payload: 'streaming' });
|
|
97
113
|
callbacks.onStatusChange?.('streaming');
|
|
98
114
|
},
|
|
115
|
+
onStop: () => {
|
|
116
|
+
// Only reset if this is an unexpected stop (stream died, max reconnects exhausted).
|
|
117
|
+
// If stopStream() was called intentionally, it clears the manager ref first,
|
|
118
|
+
// so getStreamManager() will be undefined and we skip the duplicate dispatch.
|
|
119
|
+
if (getStreamManager()) {
|
|
120
|
+
setStreamManager(undefined);
|
|
121
|
+
dispatch({ type: 'SET_STATUS', payload: 'idle' });
|
|
122
|
+
dispatch({ type: 'SET_IS_GENERATING', payload: false });
|
|
123
|
+
callbacks.onStatusChange?.('idle');
|
|
124
|
+
}
|
|
125
|
+
},
|
|
99
126
|
});
|
|
100
127
|
// Listen for Chat object updates (status changes)
|
|
101
128
|
manager.addEventListener('chats', (chatData) => {
|
|
@@ -108,12 +135,60 @@ export function createActions(ctx) {
|
|
|
108
135
|
setStreamManager(manager);
|
|
109
136
|
manager.connect();
|
|
110
137
|
};
|
|
138
|
+
/** Poll-based alternative to streaming for restricted environments */
|
|
139
|
+
const pollChat = (id) => {
|
|
140
|
+
let prevStatus = null;
|
|
141
|
+
const manager = new PollManager({
|
|
142
|
+
pollFunction: () => client.http.request('get', `/chats/${id}/status`),
|
|
143
|
+
intervalMs: getPollIntervalMs(),
|
|
144
|
+
onData: async (statusData) => {
|
|
145
|
+
if (statusData.status === prevStatus)
|
|
146
|
+
return;
|
|
147
|
+
prevStatus = statusData.status;
|
|
148
|
+
// Status changed — fetch full chat
|
|
149
|
+
try {
|
|
150
|
+
const chat = await api.fetchChat(client, id);
|
|
151
|
+
if (chat) {
|
|
152
|
+
setChat(chat);
|
|
153
|
+
if (chat.chat_messages) {
|
|
154
|
+
for (const message of chat.chat_messages) {
|
|
155
|
+
updateMessage(message);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
console.warn('[AgentSDK] Poll fetch error:', err);
|
|
162
|
+
callbacks.onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
onStart: () => {
|
|
166
|
+
dispatch({ type: 'SET_STATUS', payload: 'streaming' });
|
|
167
|
+
callbacks.onStatusChange?.('streaming');
|
|
168
|
+
},
|
|
169
|
+
onStop: () => {
|
|
170
|
+
if (getStreamManager()) {
|
|
171
|
+
setStreamManager(undefined);
|
|
172
|
+
dispatch({ type: 'SET_STATUS', payload: 'idle' });
|
|
173
|
+
dispatch({ type: 'SET_IS_GENERATING', payload: false });
|
|
174
|
+
callbacks.onStatusChange?.('idle');
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
onError: (error) => {
|
|
178
|
+
console.warn('[AgentSDK] Poll error:', error);
|
|
179
|
+
callbacks.onError?.(error);
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
setStreamManager(manager);
|
|
183
|
+
manager.start();
|
|
184
|
+
};
|
|
111
185
|
const stopStream = () => {
|
|
112
186
|
const manager = getStreamManager();
|
|
187
|
+
// Clear ref first so onStop callback (from manager.stop) is a no-op
|
|
188
|
+
setStreamManager(undefined);
|
|
113
189
|
if (manager) {
|
|
114
190
|
manager.stop();
|
|
115
191
|
}
|
|
116
|
-
setStreamManager(undefined);
|
|
117
192
|
dispatch({ type: 'SET_STATUS', payload: 'idle' });
|
|
118
193
|
dispatch({ type: 'SET_IS_GENERATING', payload: false });
|
|
119
194
|
callbacks.onStatusChange?.('idle');
|
|
@@ -150,6 +225,12 @@ export function createActions(ctx) {
|
|
|
150
225
|
streamChat(newChatId);
|
|
151
226
|
}
|
|
152
227
|
}
|
|
228
|
+
else {
|
|
229
|
+
// API returned no result — reset status so we don't get stuck
|
|
230
|
+
dispatch({ type: 'SET_STATUS', payload: 'idle' });
|
|
231
|
+
dispatch({ type: 'SET_IS_GENERATING', payload: false });
|
|
232
|
+
callbacks.onStatusChange?.('idle');
|
|
233
|
+
}
|
|
153
234
|
}
|
|
154
235
|
catch (error) {
|
|
155
236
|
console.error('[AgentSDK] Failed to send message:', error);
|
package/dist/agent/provider.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ import type { AgentChatProviderProps } from './types';
|
|
|
27
27
|
* }
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
|
-
export declare function AgentChatProvider({ client, agentConfig, chatId, onChatCreated, onStatusChange, onError, children, }: AgentChatProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function AgentChatProvider({ client, agentConfig, chatId, clientToolHandlers: extraHandlers, onChatCreated, onStatusChange, onError, stream, pollIntervalMs, children, }: AgentChatProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
31
31
|
export declare namespace AgentChatProvider {
|
|
32
32
|
var displayName: string;
|
|
33
33
|
}
|
package/dist/agent/provider.js
CHANGED
|
@@ -9,6 +9,14 @@ import { useReducer, useRef, useEffect, useMemo } from 'react';
|
|
|
9
9
|
import { AgentChatContext } from './context';
|
|
10
10
|
import { chatReducer, initialState } from './reducer';
|
|
11
11
|
import { createActions, getClientToolHandlers } from './actions';
|
|
12
|
+
function mergeHandlers(base, extra) {
|
|
13
|
+
if (!extra || extra.size === 0)
|
|
14
|
+
return base;
|
|
15
|
+
const merged = new Map(base);
|
|
16
|
+
for (const [k, v] of extra)
|
|
17
|
+
merged.set(k, v);
|
|
18
|
+
return merged;
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* AgentChatProvider - Provides chat state and actions to children
|
|
14
22
|
*
|
|
@@ -31,23 +39,29 @@ import { createActions, getClientToolHandlers } from './actions';
|
|
|
31
39
|
* }
|
|
32
40
|
* ```
|
|
33
41
|
*/
|
|
34
|
-
export function AgentChatProvider({ client, agentConfig, chatId, onChatCreated, onStatusChange, onError, children, }) {
|
|
42
|
+
export function AgentChatProvider({ client, agentConfig, chatId, clientToolHandlers: extraHandlers, onChatCreated, onStatusChange, onError, stream, pollIntervalMs, children, }) {
|
|
35
43
|
// Core state via useReducer
|
|
36
44
|
const [state, dispatch] = useReducer(chatReducer, initialState);
|
|
37
45
|
// Refs for mutable values that actions need access to
|
|
38
46
|
const configRef = useRef(agentConfig);
|
|
39
47
|
const chatIdRef = useRef(chatId ?? null);
|
|
40
48
|
const streamManagerRef = useRef(undefined);
|
|
41
|
-
const
|
|
49
|
+
const streamRef = useRef(stream);
|
|
50
|
+
const pollIntervalMsRef = useRef(pollIntervalMs);
|
|
51
|
+
const clientToolHandlersRef = useRef(mergeHandlers(getClientToolHandlers(agentConfig), extraHandlers));
|
|
42
52
|
const callbacksRef = useRef({ onChatCreated, onStatusChange, onError });
|
|
43
53
|
// Keep refs in sync with props
|
|
44
54
|
useEffect(() => {
|
|
45
55
|
configRef.current = agentConfig;
|
|
46
|
-
clientToolHandlersRef.current = getClientToolHandlers(agentConfig);
|
|
47
|
-
}, [agentConfig]);
|
|
56
|
+
clientToolHandlersRef.current = mergeHandlers(getClientToolHandlers(agentConfig), extraHandlers);
|
|
57
|
+
}, [agentConfig, extraHandlers]);
|
|
48
58
|
useEffect(() => {
|
|
49
59
|
callbacksRef.current = { onChatCreated, onStatusChange, onError };
|
|
50
60
|
}, [onChatCreated, onStatusChange, onError]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
streamRef.current = stream;
|
|
63
|
+
pollIntervalMsRef.current = pollIntervalMs;
|
|
64
|
+
}, [stream, pollIntervalMs]);
|
|
51
65
|
// Keep chatIdRef synced with state
|
|
52
66
|
useEffect(() => {
|
|
53
67
|
chatIdRef.current = state.chatId;
|
|
@@ -61,6 +75,8 @@ export function AgentChatProvider({ client, agentConfig, chatId, onChatCreated,
|
|
|
61
75
|
getClientToolHandlers: () => clientToolHandlersRef.current,
|
|
62
76
|
getStreamManager: () => streamManagerRef.current,
|
|
63
77
|
setStreamManager: (manager) => { streamManagerRef.current = manager; },
|
|
78
|
+
getStreamEnabled: () => streamRef.current ?? client.http.getStreamDefault(),
|
|
79
|
+
getPollIntervalMs: () => pollIntervalMsRef.current ?? client.http.getPollIntervalMs(),
|
|
64
80
|
callbacks: callbacksRef.current,
|
|
65
81
|
}), [client]);
|
|
66
82
|
// Re-bind callbacks when they change
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { Dispatch } from 'react';
|
|
|
7
7
|
import type { ChatDTO, ChatMessageDTO, AgentTool, AgentConfig as GeneratedAgentConfig, CoreAppConfig } from '../types';
|
|
8
8
|
import type { HttpClient } from '../http/client';
|
|
9
9
|
import type { StreamManager } from '../http/stream';
|
|
10
|
+
import type { PollManager } from '../http/poll';
|
|
10
11
|
/**
|
|
11
12
|
* Minimal file interface returned by upload (just needs uri and content_type)
|
|
12
13
|
*/
|
|
@@ -20,7 +21,7 @@ export interface UploadedFile {
|
|
|
20
21
|
*/
|
|
21
22
|
export interface AgentClient {
|
|
22
23
|
/** HTTP client for API requests */
|
|
23
|
-
http: Pick<HttpClient, 'request' | 'createEventSource'>;
|
|
24
|
+
http: Pick<HttpClient, 'request' | 'createEventSource' | 'getStreamDefault' | 'getPollIntervalMs'>;
|
|
24
25
|
/** Files API for uploads */
|
|
25
26
|
files: {
|
|
26
27
|
upload: (data: string | Blob | globalThis.File) => Promise<UploadedFile>;
|
|
@@ -134,12 +135,18 @@ export interface AgentChatProviderProps {
|
|
|
134
135
|
agentConfig: AgentOptions;
|
|
135
136
|
/** Optional existing chat ID to continue */
|
|
136
137
|
chatId?: string;
|
|
138
|
+
/** Extra client tool handlers, merged with any from agentConfig. Use with TemplateAgentConfig to handle tools defined server-side. */
|
|
139
|
+
clientToolHandlers?: Map<string, ClientToolHandlerFn>;
|
|
137
140
|
/** Callback when a new chat is created */
|
|
138
141
|
onChatCreated?: (chatId: string) => void;
|
|
139
142
|
/** Callback when chat status changes */
|
|
140
143
|
onStatusChange?: (status: ChatStatus) => void;
|
|
141
144
|
/** Callback when an error occurs */
|
|
142
145
|
onError?: (error: Error) => void;
|
|
146
|
+
/** Use SSE streaming (true, default) or polling (false) for real-time updates */
|
|
147
|
+
stream?: boolean;
|
|
148
|
+
/** Polling interval in ms when stream is false (default: 2000) */
|
|
149
|
+
pollIntervalMs?: number;
|
|
143
150
|
/** Children */
|
|
144
151
|
children: React.ReactNode;
|
|
145
152
|
}
|
|
@@ -201,14 +208,18 @@ export type ChatAction = {
|
|
|
201
208
|
/**
|
|
202
209
|
* Context for action creators
|
|
203
210
|
*/
|
|
211
|
+
/** Union of manager types used for real-time updates */
|
|
212
|
+
export type UpdateManager = StreamManager<unknown> | PollManager<unknown>;
|
|
204
213
|
export interface ActionsContext {
|
|
205
214
|
client: AgentClient;
|
|
206
215
|
dispatch: Dispatch<ChatAction>;
|
|
207
216
|
getConfig: () => AgentOptions | null;
|
|
208
217
|
getChatId: () => string | null;
|
|
209
218
|
getClientToolHandlers: () => Map<string, ClientToolHandlerFn>;
|
|
210
|
-
getStreamManager: () =>
|
|
211
|
-
setStreamManager: (manager:
|
|
219
|
+
getStreamManager: () => UpdateManager | undefined;
|
|
220
|
+
setStreamManager: (manager: UpdateManager | undefined) => void;
|
|
221
|
+
getStreamEnabled: () => boolean;
|
|
222
|
+
getPollIntervalMs: () => number;
|
|
212
223
|
callbacks: {
|
|
213
224
|
onChatCreated?: (chatId: string) => void;
|
|
214
225
|
onStatusChange?: (status: ChatStatus) => void;
|
package/dist/api/agents.d.ts
CHANGED
|
@@ -27,6 +27,10 @@ export interface SendMessageOptions {
|
|
|
27
27
|
name: string;
|
|
28
28
|
args: Record<string, unknown>;
|
|
29
29
|
}) => void;
|
|
30
|
+
/** Use SSE streaming (true) or polling (false). Overrides client default. */
|
|
31
|
+
stream?: boolean;
|
|
32
|
+
/** Polling interval in ms when stream is false. Overrides client default. */
|
|
33
|
+
pollIntervalMs?: number;
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Agent for chat interactions
|
|
@@ -40,6 +44,7 @@ export declare class Agent {
|
|
|
40
44
|
private readonly agentName;
|
|
41
45
|
private chatId;
|
|
42
46
|
private stream;
|
|
47
|
+
private poller;
|
|
43
48
|
private dispatchedToolCalls;
|
|
44
49
|
/** @internal */
|
|
45
50
|
constructor(http: HttpClient, files: FilesAPI, config: string | AgentConfig, options?: AgentOptions);
|
|
@@ -64,7 +69,7 @@ export declare class Agent {
|
|
|
64
69
|
};
|
|
65
70
|
form_data?: Record<string, unknown>;
|
|
66
71
|
}): Promise<void>;
|
|
67
|
-
/** Stop streaming and cleanup */
|
|
72
|
+
/** Stop streaming/polling and cleanup */
|
|
68
73
|
disconnect(): void;
|
|
69
74
|
/** Reset the agent (start fresh chat) */
|
|
70
75
|
reset(): void;
|
|
@@ -74,6 +79,8 @@ export declare class Agent {
|
|
|
74
79
|
startStreaming(options?: Omit<SendMessageOptions, 'files'>): void;
|
|
75
80
|
/** Stream events until chat becomes idle */
|
|
76
81
|
private streamUntilIdle;
|
|
82
|
+
/** Poll until chat becomes idle, dispatching callbacks on changes */
|
|
83
|
+
private pollUntilIdle;
|
|
77
84
|
}
|
|
78
85
|
/**
|
|
79
86
|
* Agents API
|
package/dist/api/agents.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StreamManager } from '../http/stream';
|
|
2
|
+
import { PollManager } from '../http/poll';
|
|
2
3
|
import { ToolTypeClient, ToolInvocationStatusAwaitingInput, } from '../types';
|
|
3
4
|
/**
|
|
4
5
|
* Agent for chat interactions
|
|
@@ -10,6 +11,7 @@ export class Agent {
|
|
|
10
11
|
constructor(http, files, config, options) {
|
|
11
12
|
this.chatId = null;
|
|
12
13
|
this.stream = null;
|
|
14
|
+
this.poller = null;
|
|
13
15
|
this.dispatchedToolCalls = new Set();
|
|
14
16
|
this.http = http;
|
|
15
17
|
this.files = files;
|
|
@@ -59,24 +61,28 @@ export class Agent {
|
|
|
59
61
|
agent_name: this.agentName ?? this.config.name,
|
|
60
62
|
input: { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
|
|
61
63
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
const useStream = options.stream ?? this.http.getStreamDefault();
|
|
65
|
+
const waitFn = useStream
|
|
66
|
+
? (opts) => this.streamUntilIdle(opts)
|
|
67
|
+
: (opts) => this.pollUntilIdle(opts);
|
|
68
|
+
// For existing chats with callbacks: Start waiting BEFORE POST so we don't miss updates
|
|
69
|
+
let waitPromise = null;
|
|
64
70
|
if (this.chatId && hasCallbacks) {
|
|
65
|
-
|
|
71
|
+
waitPromise = waitFn(options);
|
|
66
72
|
}
|
|
67
73
|
// Make the POST request
|
|
68
74
|
const response = await this.http.request('post', '/agents/run', { data: body });
|
|
69
|
-
// For new chats: Set chatId and start
|
|
75
|
+
// For new chats: Set chatId and start waiting immediately after POST
|
|
70
76
|
const isNewChat = !this.chatId && response.assistant_message.chat_id;
|
|
71
77
|
if (isNewChat) {
|
|
72
78
|
this.chatId = response.assistant_message.chat_id;
|
|
73
79
|
if (hasCallbacks) {
|
|
74
|
-
|
|
80
|
+
waitPromise = waitFn(options);
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
|
-
// Wait for
|
|
78
|
-
if (
|
|
79
|
-
await
|
|
83
|
+
// Wait for completion
|
|
84
|
+
if (waitPromise) {
|
|
85
|
+
await waitPromise;
|
|
80
86
|
}
|
|
81
87
|
return { userMessage: response.user_message, assistantMessage: response.assistant_message };
|
|
82
88
|
}
|
|
@@ -100,10 +106,12 @@ export class Agent {
|
|
|
100
106
|
const result = typeof resultOrAction === 'string' ? resultOrAction : JSON.stringify(resultOrAction);
|
|
101
107
|
await this.http.request('post', `/tools/${toolInvocationId}`, { data: { result } });
|
|
102
108
|
}
|
|
103
|
-
/** Stop streaming and cleanup */
|
|
109
|
+
/** Stop streaming/polling and cleanup */
|
|
104
110
|
disconnect() {
|
|
105
111
|
this.stream?.stop();
|
|
106
112
|
this.stream = null;
|
|
113
|
+
this.poller?.stop();
|
|
114
|
+
this.poller = null;
|
|
107
115
|
}
|
|
108
116
|
/** Reset the agent (start fresh chat) */
|
|
109
117
|
reset() {
|
|
@@ -155,6 +163,73 @@ export class Agent {
|
|
|
155
163
|
this.stream.connect();
|
|
156
164
|
});
|
|
157
165
|
}
|
|
166
|
+
/** Poll until chat becomes idle, dispatching callbacks on changes */
|
|
167
|
+
pollUntilIdle(options) {
|
|
168
|
+
if (!this.chatId)
|
|
169
|
+
return Promise.resolve();
|
|
170
|
+
const intervalMs = options.pollIntervalMs ?? this.http.getPollIntervalMs();
|
|
171
|
+
let prevStatus = null;
|
|
172
|
+
let knownMessageIds = new Set();
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
this.poller?.stop();
|
|
175
|
+
this.poller = new PollManager({
|
|
176
|
+
pollFunction: async () => {
|
|
177
|
+
// Lightweight status check first
|
|
178
|
+
const status = await this.http.request('get', `/chats/${this.chatId}/status`);
|
|
179
|
+
if (status.status === prevStatus) {
|
|
180
|
+
// No change — return a stub to skip processing
|
|
181
|
+
return { status: status.status };
|
|
182
|
+
}
|
|
183
|
+
// Status changed — fetch full chat
|
|
184
|
+
return this.http.request('get', `/chats/${this.chatId}`);
|
|
185
|
+
},
|
|
186
|
+
intervalMs,
|
|
187
|
+
onData: (chat) => {
|
|
188
|
+
if (chat.status === prevStatus && !chat.chat_messages)
|
|
189
|
+
return;
|
|
190
|
+
prevStatus = chat.status;
|
|
191
|
+
options.onChat?.(chat);
|
|
192
|
+
// Dispatch new/updated messages
|
|
193
|
+
if (chat.chat_messages && options.onMessage) {
|
|
194
|
+
for (const message of chat.chat_messages) {
|
|
195
|
+
if (!knownMessageIds.has(message.id)) {
|
|
196
|
+
knownMessageIds.add(message.id);
|
|
197
|
+
options.onMessage(message);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
// Re-dispatch for potential updates
|
|
201
|
+
options.onMessage(message);
|
|
202
|
+
}
|
|
203
|
+
// Handle client tool invocations
|
|
204
|
+
if (message.tool_invocations && options.onToolCall) {
|
|
205
|
+
for (const inv of message.tool_invocations) {
|
|
206
|
+
if (this.dispatchedToolCalls.has(inv.id))
|
|
207
|
+
continue;
|
|
208
|
+
if (inv.type === ToolTypeClient && inv.status === ToolInvocationStatusAwaitingInput) {
|
|
209
|
+
this.dispatchedToolCalls.add(inv.id);
|
|
210
|
+
options.onToolCall({
|
|
211
|
+
id: inv.id,
|
|
212
|
+
name: inv.function?.name || '',
|
|
213
|
+
args: inv.function?.arguments || {},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (chat.status === 'idle') {
|
|
221
|
+
this.poller?.stop();
|
|
222
|
+
this.poller = null;
|
|
223
|
+
resolve();
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
onError: (error) => {
|
|
227
|
+
console.warn('[Agent] Poll error:', error);
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
this.poller.start();
|
|
231
|
+
});
|
|
232
|
+
}
|
|
158
233
|
}
|
|
159
234
|
/**
|
|
160
235
|
* Agents API
|
package/dist/api/tasks.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export interface RunOptions {
|
|
|
13
13
|
maxReconnects?: number;
|
|
14
14
|
/** Delay between reconnection attempts in ms (default: 1000) */
|
|
15
15
|
reconnectDelayMs?: number;
|
|
16
|
+
/** Use SSE streaming (true) or polling (false). Overrides client default. */
|
|
17
|
+
stream?: boolean;
|
|
18
|
+
/** Polling interval in ms when stream is false. Overrides client default. */
|
|
19
|
+
pollIntervalMs?: number;
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
22
|
* Tasks API
|
|
@@ -52,6 +56,8 @@ export declare class TasksAPI {
|
|
|
52
56
|
* Run a task and optionally wait for completion
|
|
53
57
|
*/
|
|
54
58
|
run(params: ApiAppRunRequest, processedInput: unknown, options?: RunOptions): Promise<Task>;
|
|
59
|
+
/** Poll GET /tasks/{id}/status until terminal, full-fetch on status change. */
|
|
60
|
+
private pollUntilTerminal;
|
|
55
61
|
/**
|
|
56
62
|
* Update task visibility
|
|
57
63
|
*/
|
package/dist/api/tasks.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StreamManager } from '../http/stream';
|
|
2
|
+
import { PollManager } from '../http/poll';
|
|
2
3
|
import { TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, } from '../types';
|
|
3
4
|
//TODO: This is ugly...
|
|
4
5
|
function stripTask(task) {
|
|
@@ -78,7 +79,11 @@ export class TasksAPI {
|
|
|
78
79
|
if (!wait) {
|
|
79
80
|
return stripTask(task);
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
+
const useStream = options.stream ?? this.http.getStreamDefault();
|
|
83
|
+
if (!useStream) {
|
|
84
|
+
return this.pollUntilTerminal(task, options);
|
|
85
|
+
}
|
|
86
|
+
// Wait for completion with optional updates via SSE
|
|
82
87
|
// Accumulate state across partial updates to preserve fields like session_id
|
|
83
88
|
let accumulatedTask = { ...task };
|
|
84
89
|
return new Promise((resolve, reject) => {
|
|
@@ -131,6 +136,51 @@ export class TasksAPI {
|
|
|
131
136
|
streamManager.connect();
|
|
132
137
|
});
|
|
133
138
|
}
|
|
139
|
+
/** Poll GET /tasks/{id}/status until terminal, full-fetch on status change. */
|
|
140
|
+
pollUntilTerminal(task, options) {
|
|
141
|
+
const { onUpdate, maxReconnects = 5 } = options;
|
|
142
|
+
const intervalMs = options.pollIntervalMs ?? this.http.getPollIntervalMs();
|
|
143
|
+
let prevStatus = task.status;
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
const poller = new PollManager({
|
|
146
|
+
pollFunction: () => this.http.request('get', `/tasks/${task.id}/status`),
|
|
147
|
+
intervalMs,
|
|
148
|
+
maxRetries: maxReconnects,
|
|
149
|
+
onData: async (statusData) => {
|
|
150
|
+
if (statusData.status === prevStatus)
|
|
151
|
+
return;
|
|
152
|
+
prevStatus = statusData.status;
|
|
153
|
+
// Status changed — fetch full task
|
|
154
|
+
try {
|
|
155
|
+
const fullTask = await this.http.request('get', `/tasks/${task.id}`);
|
|
156
|
+
const stripped = stripTask(fullTask);
|
|
157
|
+
onUpdate?.(stripped);
|
|
158
|
+
if (fullTask.status === TaskStatusCompleted) {
|
|
159
|
+
poller.stop();
|
|
160
|
+
resolve(stripped);
|
|
161
|
+
}
|
|
162
|
+
else if (fullTask.status === TaskStatusFailed) {
|
|
163
|
+
poller.stop();
|
|
164
|
+
reject(new Error(fullTask.error || 'task failed'));
|
|
165
|
+
}
|
|
166
|
+
else if (fullTask.status === TaskStatusCancelled) {
|
|
167
|
+
poller.stop();
|
|
168
|
+
reject(new Error('task cancelled'));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
poller.stop();
|
|
173
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
onError: (error) => {
|
|
177
|
+
reject(error);
|
|
178
|
+
poller.stop();
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
poller.start();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
134
184
|
/**
|
|
135
185
|
* Update task visibility
|
|
136
186
|
*/
|
package/dist/http/client.d.ts
CHANGED
|
@@ -25,6 +25,16 @@ export interface HttpClientConfig {
|
|
|
25
25
|
* Can be used for retry logic, auth refresh, OTP handling, etc.
|
|
26
26
|
*/
|
|
27
27
|
onError?: ErrorHandler;
|
|
28
|
+
/**
|
|
29
|
+
* Use polling instead of SSE for real-time updates (default: true = SSE).
|
|
30
|
+
* Set to false for environments that can't maintain long-lived connections
|
|
31
|
+
* (Convex actions, Cloudflare Workers, restricted edge runtimes).
|
|
32
|
+
*/
|
|
33
|
+
stream?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Polling interval in milliseconds when stream is false (default: 2000).
|
|
36
|
+
*/
|
|
37
|
+
pollIntervalMs?: number;
|
|
28
38
|
}
|
|
29
39
|
/**
|
|
30
40
|
* Low-level HTTP client for inference.sh API
|
|
@@ -40,9 +50,15 @@ export declare class HttpClient {
|
|
|
40
50
|
private readonly customHeaders;
|
|
41
51
|
private readonly credentials;
|
|
42
52
|
private readonly onError;
|
|
53
|
+
private readonly streamDefault;
|
|
54
|
+
private readonly pollInterval;
|
|
43
55
|
constructor(config: HttpClientConfig);
|
|
44
56
|
/** Get the base URL */
|
|
45
57
|
getBaseUrl(): string;
|
|
58
|
+
/** Whether SSE streaming is the default transport (true) or polling (false) */
|
|
59
|
+
getStreamDefault(): boolean;
|
|
60
|
+
/** Get the default poll interval in ms */
|
|
61
|
+
getPollIntervalMs(): number;
|
|
46
62
|
/** Check if in proxy mode */
|
|
47
63
|
isProxyMode(): boolean;
|
|
48
64
|
/** Resolve dynamic headers */
|
package/dist/http/client.js
CHANGED
|
@@ -19,11 +19,21 @@ export class HttpClient {
|
|
|
19
19
|
this.customHeaders = config.headers || {};
|
|
20
20
|
this.credentials = config.credentials || 'include';
|
|
21
21
|
this.onError = config.onError;
|
|
22
|
+
this.streamDefault = config.stream ?? true;
|
|
23
|
+
this.pollInterval = config.pollIntervalMs ?? 2000;
|
|
22
24
|
}
|
|
23
25
|
/** Get the base URL */
|
|
24
26
|
getBaseUrl() {
|
|
25
27
|
return this.baseUrl;
|
|
26
28
|
}
|
|
29
|
+
/** Whether SSE streaming is the default transport (true) or polling (false) */
|
|
30
|
+
getStreamDefault() {
|
|
31
|
+
return this.streamDefault;
|
|
32
|
+
}
|
|
33
|
+
/** Get the default poll interval in ms */
|
|
34
|
+
getPollIntervalMs() {
|
|
35
|
+
return this.pollInterval;
|
|
36
|
+
}
|
|
27
37
|
/** Check if in proxy mode */
|
|
28
38
|
isProxyMode() {
|
|
29
39
|
return !!this.proxyUrl;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PollManager — polling transport alternative to StreamManager.
|
|
3
|
+
*
|
|
4
|
+
* Used when long-lived SSE connections are unavailable (Convex actions,
|
|
5
|
+
* Cloudflare Workers, restricted edge runtimes).
|
|
6
|
+
*/
|
|
7
|
+
export interface PollManagerOptions<T> {
|
|
8
|
+
/** Function that fetches the latest data each poll cycle */
|
|
9
|
+
pollFunction: () => Promise<T>;
|
|
10
|
+
/** Milliseconds between polls (default 2000) */
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
/** Maximum consecutive errors before giving up (default 5) */
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
/** Delay after an error before retrying (default 1000) */
|
|
15
|
+
retryDelayMs?: number;
|
|
16
|
+
/** Called with data on every successful poll */
|
|
17
|
+
onData?: (data: T) => void;
|
|
18
|
+
/** Called when an error occurs */
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
/** Called when polling starts */
|
|
21
|
+
onStart?: () => void;
|
|
22
|
+
/** Called when polling stops (intentionally or after max retries) */
|
|
23
|
+
onStop?: () => void;
|
|
24
|
+
}
|
|
25
|
+
export declare class PollManager<T> {
|
|
26
|
+
private options;
|
|
27
|
+
private interval;
|
|
28
|
+
private retryTimeout;
|
|
29
|
+
private consecutiveErrors;
|
|
30
|
+
private isStopped;
|
|
31
|
+
private polling;
|
|
32
|
+
constructor(options: PollManagerOptions<T>);
|
|
33
|
+
/** Start polling. First poll is immediate, then at intervalMs. */
|
|
34
|
+
start(): void;
|
|
35
|
+
/** Stop polling and clean up. */
|
|
36
|
+
stop(): void;
|
|
37
|
+
private cleanup;
|
|
38
|
+
private poll;
|
|
39
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PollManager — polling transport alternative to StreamManager.
|
|
3
|
+
*
|
|
4
|
+
* Used when long-lived SSE connections are unavailable (Convex actions,
|
|
5
|
+
* Cloudflare Workers, restricted edge runtimes).
|
|
6
|
+
*/
|
|
7
|
+
export class PollManager {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.interval = null;
|
|
10
|
+
this.retryTimeout = null;
|
|
11
|
+
this.consecutiveErrors = 0;
|
|
12
|
+
this.isStopped = true;
|
|
13
|
+
this.polling = false;
|
|
14
|
+
this.options = {
|
|
15
|
+
intervalMs: 2000,
|
|
16
|
+
maxRetries: 5,
|
|
17
|
+
retryDelayMs: 1000,
|
|
18
|
+
...options,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Start polling. First poll is immediate, then at intervalMs. */
|
|
22
|
+
start() {
|
|
23
|
+
if (!this.isStopped)
|
|
24
|
+
return;
|
|
25
|
+
this.isStopped = false;
|
|
26
|
+
this.consecutiveErrors = 0;
|
|
27
|
+
this.options.onStart?.();
|
|
28
|
+
this.poll(); // immediate first poll
|
|
29
|
+
this.interval = setInterval(() => this.poll(), this.options.intervalMs);
|
|
30
|
+
}
|
|
31
|
+
/** Stop polling and clean up. */
|
|
32
|
+
stop() {
|
|
33
|
+
if (this.isStopped)
|
|
34
|
+
return;
|
|
35
|
+
this.isStopped = true;
|
|
36
|
+
this.cleanup();
|
|
37
|
+
this.options.onStop?.();
|
|
38
|
+
}
|
|
39
|
+
cleanup() {
|
|
40
|
+
if (this.interval) {
|
|
41
|
+
clearInterval(this.interval);
|
|
42
|
+
this.interval = null;
|
|
43
|
+
}
|
|
44
|
+
if (this.retryTimeout) {
|
|
45
|
+
clearTimeout(this.retryTimeout);
|
|
46
|
+
this.retryTimeout = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async poll() {
|
|
50
|
+
if (this.isStopped || this.polling)
|
|
51
|
+
return;
|
|
52
|
+
this.polling = true;
|
|
53
|
+
try {
|
|
54
|
+
const data = await this.options.pollFunction();
|
|
55
|
+
this.polling = false;
|
|
56
|
+
if (this.isStopped)
|
|
57
|
+
return;
|
|
58
|
+
this.consecutiveErrors = 0;
|
|
59
|
+
this.options.onData?.(data);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
this.polling = false;
|
|
63
|
+
if (this.isStopped)
|
|
64
|
+
return;
|
|
65
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
66
|
+
this.consecutiveErrors++;
|
|
67
|
+
this.options.onError?.(error);
|
|
68
|
+
if (this.consecutiveErrors >= this.options.maxRetries) {
|
|
69
|
+
this.stop();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { HttpClient, HttpClientConfig, ErrorHandler, createHttpClient } from './http/client';
|
|
2
2
|
export { StreamManager, StreamManagerOptions, PartialDataWrapper } from './http/stream';
|
|
3
|
+
export { PollManager, PollManagerOptions } from './http/poll';
|
|
3
4
|
export { InferenceError, RequirementsNotMetException, SessionError, SessionNotFoundError, SessionExpiredError, SessionEndedError, WorkerLostError, } from './http/errors';
|
|
4
5
|
export { TasksAPI, RunOptions } from './api/tasks';
|
|
5
6
|
export { FilesAPI, UploadFileOptions } from './api/files';
|
|
@@ -35,6 +36,15 @@ export interface InferenceConfig {
|
|
|
35
36
|
* When set, requests are routed through your proxy server to protect API keys.
|
|
36
37
|
*/
|
|
37
38
|
proxyUrl?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Use SSE streaming (true, default) or polling (false) for real-time updates.
|
|
41
|
+
* Set to false for environments that can't maintain long-lived connections.
|
|
42
|
+
*/
|
|
43
|
+
stream?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Polling interval in milliseconds when stream is false (default: 2000).
|
|
46
|
+
*/
|
|
47
|
+
pollIntervalMs?: number;
|
|
38
48
|
}
|
|
39
49
|
/**
|
|
40
50
|
* Inference.sh SDK Client
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// HTTP utilities
|
|
2
2
|
export { HttpClient, createHttpClient } from './http/client';
|
|
3
3
|
export { StreamManager } from './http/stream';
|
|
4
|
+
export { PollManager } from './http/poll';
|
|
4
5
|
export { InferenceError, RequirementsNotMetException, SessionError, SessionNotFoundError, SessionExpiredError, SessionEndedError, WorkerLostError, } from './http/errors';
|
|
5
6
|
// API modules
|
|
6
7
|
export { TasksAPI } from './api/tasks';
|
|
@@ -49,6 +50,8 @@ export class Inference {
|
|
|
49
50
|
headers: 'headers' in config ? config.headers : undefined,
|
|
50
51
|
credentials: 'credentials' in config ? config.credentials : undefined,
|
|
51
52
|
onError: 'onError' in config ? config.onError : undefined,
|
|
53
|
+
stream: 'stream' in config ? config.stream : undefined,
|
|
54
|
+
pollIntervalMs: 'pollIntervalMs' in config ? config.pollIntervalMs : undefined,
|
|
52
55
|
});
|
|
53
56
|
this.files = new FilesAPI(this.http);
|
|
54
57
|
this.tasks = new TasksAPI(this.http);
|
package/dist/tool-builder.js
CHANGED
|
@@ -28,6 +28,8 @@ function toJsonSchema(params) {
|
|
|
28
28
|
if (schema.properties) {
|
|
29
29
|
const nested = toJsonSchema(schema.properties);
|
|
30
30
|
prop.properties = nested.properties;
|
|
31
|
+
if (nested.required.length > 0)
|
|
32
|
+
prop.required = nested.required;
|
|
31
33
|
}
|
|
32
34
|
if (schema.items) {
|
|
33
35
|
const itemSchema = toJsonSchema({ _item: schema.items });
|
|
@@ -149,8 +149,19 @@ describe('ClientToolBuilder (tool)', () => {
|
|
|
149
149
|
name: { type: 'string', description: 'Name' },
|
|
150
150
|
email: { type: 'string', description: 'Email' },
|
|
151
151
|
},
|
|
152
|
+
required: ['name', 'email'],
|
|
152
153
|
});
|
|
153
154
|
});
|
|
155
|
+
it('propagates required into nested objects with optional fields', () => {
|
|
156
|
+
const t = tool('update_user')
|
|
157
|
+
.param('user', object({
|
|
158
|
+
name: string('Name'),
|
|
159
|
+
bio: optional(string('Bio')),
|
|
160
|
+
}))
|
|
161
|
+
.build();
|
|
162
|
+
const userProp = t.client?.input_schema.properties?.user;
|
|
163
|
+
expect(userProp.required).toEqual(['name']);
|
|
164
|
+
});
|
|
154
165
|
it('creates tool with array parameters', () => {
|
|
155
166
|
const t = tool('process_items')
|
|
156
167
|
.param('items', array(string('Item'), 'List of items'))
|
package/dist/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface InternalToolsConfig {
|
|
|
7
7
|
widget?: boolean;
|
|
8
8
|
finish?: boolean;
|
|
9
9
|
skills?: boolean;
|
|
10
|
+
host_context?: boolean;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* ToolType represents the type of tool (used in both AgentTool definition and ToolInvocation)
|
|
@@ -396,6 +397,16 @@ export interface ApiAgentRunRequest {
|
|
|
396
397
|
*/
|
|
397
398
|
stream?: boolean;
|
|
398
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* EmbedAgentRunRequest is the embed variant of ApiAgentRunRequest.
|
|
402
|
+
* Only template agents are supported (no ad-hoc configs).
|
|
403
|
+
*/
|
|
404
|
+
export interface EmbedAgentRunRequest {
|
|
405
|
+
chat_id?: string;
|
|
406
|
+
agent: string;
|
|
407
|
+
input: ChatTaskInput;
|
|
408
|
+
stream?: boolean;
|
|
409
|
+
}
|
|
399
410
|
export interface CreateAgentMessageRequest {
|
|
400
411
|
chat_id?: string;
|
|
401
412
|
agent_id?: string;
|
|
@@ -508,6 +519,26 @@ export interface CreateAgentRequest {
|
|
|
508
519
|
*/
|
|
509
520
|
export interface SDKTypes {
|
|
510
521
|
}
|
|
522
|
+
export interface SkillPublishRequest {
|
|
523
|
+
name: string;
|
|
524
|
+
description: string;
|
|
525
|
+
category: string;
|
|
526
|
+
repo_url: string;
|
|
527
|
+
license: string;
|
|
528
|
+
allowed_tools: string;
|
|
529
|
+
compatibility: string;
|
|
530
|
+
instructions: string;
|
|
531
|
+
files: SkillFile[];
|
|
532
|
+
metadata?: {
|
|
533
|
+
[key: string]: string;
|
|
534
|
+
};
|
|
535
|
+
/**
|
|
536
|
+
* Spec fields for roundtrip fidelity
|
|
537
|
+
*/
|
|
538
|
+
disable_model_invocation: boolean;
|
|
539
|
+
user_invocable?: boolean;
|
|
540
|
+
context: string;
|
|
541
|
+
}
|
|
511
542
|
export interface CheckoutCreateRequest {
|
|
512
543
|
amount: number;
|
|
513
544
|
success_url: string;
|
|
@@ -915,6 +946,14 @@ export interface PermissionModelDTO {
|
|
|
915
946
|
team?: TeamRelationDTO;
|
|
916
947
|
visibility: Visibility;
|
|
917
948
|
}
|
|
949
|
+
/**
|
|
950
|
+
* ResourceStatusDTO is a lightweight status-only response for polling transports.
|
|
951
|
+
*/
|
|
952
|
+
export interface ResourceStatusDTO {
|
|
953
|
+
id: string;
|
|
954
|
+
status: any;
|
|
955
|
+
updated_at: string;
|
|
956
|
+
}
|
|
918
957
|
export type ChatStatus = string;
|
|
919
958
|
export declare const ChatStatusBusy: ChatStatus;
|
|
920
959
|
export declare const ChatStatusIdle: ChatStatus;
|
|
@@ -1745,6 +1784,16 @@ export interface InstanceEnvVar {
|
|
|
1745
1784
|
name: string;
|
|
1746
1785
|
value: string;
|
|
1747
1786
|
}
|
|
1787
|
+
/**
|
|
1788
|
+
* SkillFile represents a file in the skill directory (stored as JSONB in skill_versions)
|
|
1789
|
+
*/
|
|
1790
|
+
export interface SkillFile {
|
|
1791
|
+
path: string;
|
|
1792
|
+
uri?: string;
|
|
1793
|
+
size: number;
|
|
1794
|
+
hash: string;
|
|
1795
|
+
content?: string;
|
|
1796
|
+
}
|
|
1748
1797
|
/**
|
|
1749
1798
|
* Hardware/System related types
|
|
1750
1799
|
*/
|
|
@@ -2092,6 +2141,7 @@ export interface ToolInvocationDTO extends BaseModel, PermissionModelDTO {
|
|
|
2092
2141
|
chat_message_id: string;
|
|
2093
2142
|
tool_invocation_id: string;
|
|
2094
2143
|
type: ToolType;
|
|
2144
|
+
display_name?: string;
|
|
2095
2145
|
execution_id?: string;
|
|
2096
2146
|
function: ToolInvocationFunction;
|
|
2097
2147
|
status: ToolInvocationStatus;
|