@inferencesh/sdk 0.4.4 → 0.4.8

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/dist/agent.js DELETED
@@ -1,188 +0,0 @@
1
- "use strict";
2
- /**
3
- * Headless Agent SDK
4
- *
5
- * Chat with AI agents without UI dependencies.
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.Agent = void 0;
9
- const stream_1 = require("./stream");
10
- const eventsource_1 = require("eventsource");
11
- const types_1 = require("./types");
12
- // =============================================================================
13
- // Agent Class
14
- // =============================================================================
15
- class Agent {
16
- constructor(config, options) {
17
- this.chatId = null;
18
- // Unified stream for both Chat and ChatMessage events (uses TypedEvents)
19
- this.stream = null;
20
- this.apiKey = config.apiKey;
21
- this.baseUrl = config.baseUrl || 'https://api.inference.sh';
22
- this.options = options;
23
- }
24
- /** Get current chat ID */
25
- get currentChatId() {
26
- return this.chatId;
27
- }
28
- /** Send a message to the agent */
29
- async sendMessage(text, options = {}) {
30
- const isAdHoc = 'core_app_ref' in this.options;
31
- // Upload files if provided
32
- let imageUri;
33
- let fileUris;
34
- if (options.files && options.files.length > 0) {
35
- const uploadedFiles = await Promise.all(options.files.map(f => this.uploadFile(f)));
36
- // Separate images from other files
37
- const images = uploadedFiles.filter(f => f.content_type?.startsWith('image/'));
38
- const others = uploadedFiles.filter(f => !f.content_type?.startsWith('image/'));
39
- if (images.length > 0)
40
- imageUri = images[0].uri;
41
- if (others.length > 0)
42
- fileUris = others.map(f => f.uri);
43
- }
44
- // Both template and ad-hoc use /agents/run
45
- const input = { text, image: imageUri, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 };
46
- const body = isAdHoc
47
- ? { chat_id: this.chatId, agent_config: this.options, input }
48
- : { chat_id: this.chatId, agent: this.options.agent, input };
49
- const response = await this.request('post', '/agents/run', { data: body });
50
- // Update chat ID if new
51
- if (!this.chatId && response.assistant_message.chat_id) {
52
- this.chatId = response.assistant_message.chat_id;
53
- this.startStreaming(options);
54
- }
55
- return response.assistant_message;
56
- }
57
- /** Get chat by ID */
58
- async getChat(chatId) {
59
- const id = chatId || this.chatId;
60
- if (!id)
61
- return null;
62
- return this.request('get', `/chats/${id}`);
63
- }
64
- /** Stop the current chat generation */
65
- async stopChat() {
66
- if (!this.chatId)
67
- return;
68
- await this.request('post', `/chats/${this.chatId}/stop`);
69
- }
70
- /**
71
- * Submit a tool result
72
- * @param toolInvocationId - The tool invocation ID
73
- * @param resultOrAction - Either a raw result string, or an object with action and optional form_data (will be JSON-serialized)
74
- */
75
- async submitToolResult(toolInvocationId, resultOrAction) {
76
- // Serialize widget actions to JSON string
77
- const result = typeof resultOrAction === 'string'
78
- ? resultOrAction
79
- : JSON.stringify(resultOrAction);
80
- await this.request('post', `/tools/${toolInvocationId}`, { data: { result } });
81
- }
82
- /** Stop streaming and cleanup */
83
- disconnect() {
84
- this.stream?.stop();
85
- this.stream = null;
86
- }
87
- /** Reset the agent (start fresh chat) */
88
- reset() {
89
- this.disconnect();
90
- this.chatId = null;
91
- }
92
- /** Upload a file and return the file object */
93
- async uploadFile(data) {
94
- // Create file record
95
- let contentType = 'application/octet-stream';
96
- let size;
97
- if (data instanceof Blob) {
98
- contentType = data.type || 'application/octet-stream';
99
- size = data.size;
100
- }
101
- const files = await this.request('post', '/files', { data: { files: [{ uri: '', content_type: contentType, size }] } });
102
- const file = files[0];
103
- if (!file.upload_url)
104
- throw new Error('No upload URL');
105
- // Convert to blob if needed
106
- let blob;
107
- if (data instanceof Blob) {
108
- blob = data;
109
- }
110
- else if (data.startsWith('data:')) {
111
- const matches = data.match(/^data:([^;]+);base64,(.+)$/);
112
- if (!matches)
113
- throw new Error('Invalid data URI');
114
- const bytes = Uint8Array.from(atob(matches[2]), c => c.charCodeAt(0));
115
- blob = new Blob([bytes], { type: matches[1] });
116
- }
117
- else {
118
- const bytes = Uint8Array.from(atob(data), c => c.charCodeAt(0));
119
- blob = new Blob([bytes], { type: contentType });
120
- }
121
- // Upload to signed URL
122
- const uploadResp = await fetch(file.upload_url, {
123
- method: 'PUT',
124
- body: blob,
125
- headers: { 'Content-Type': blob.type },
126
- });
127
- if (!uploadResp.ok)
128
- throw new Error('Upload failed');
129
- return { uri: file.uri, content_type: file.content_type };
130
- }
131
- // =============================================================================
132
- // Private Methods
133
- // =============================================================================
134
- startStreaming(options) {
135
- if (!this.chatId)
136
- return;
137
- // Unified stream with TypedEvents (single SSE connection for both Chat and ChatMessage)
138
- this.stream = new stream_1.StreamManager({
139
- createEventSource: async () => this.createEventSource(`/chats/${this.chatId}/stream`),
140
- autoReconnect: true,
141
- });
142
- // Listen for Chat object updates (status changes)
143
- this.stream.addEventListener('chats', (chat) => {
144
- options.onChat?.(chat);
145
- });
146
- // Listen for ChatMessage updates
147
- this.stream.addEventListener('chat_messages', (message) => {
148
- options.onMessage?.(message);
149
- // Check for client tool invocations
150
- if (message.tool_invocations && options.onToolCall) {
151
- for (const inv of message.tool_invocations) {
152
- if (inv.type === types_1.ToolTypeClient && inv.status === types_1.ToolInvocationStatusAwaitingInput) {
153
- options.onToolCall({
154
- id: inv.id,
155
- name: inv.function?.name || '',
156
- args: inv.function?.arguments || {},
157
- });
158
- }
159
- }
160
- }
161
- });
162
- this.stream.connect();
163
- }
164
- createEventSource(endpoint) {
165
- return new eventsource_1.EventSource(`${this.baseUrl}${endpoint}`, {
166
- fetch: (input, init) => fetch(input, {
167
- ...init,
168
- headers: { ...init.headers, Authorization: `Bearer ${this.apiKey}` },
169
- }),
170
- });
171
- }
172
- async request(method, endpoint, options = {}) {
173
- const response = await fetch(`${this.baseUrl}${endpoint}`, {
174
- method: method.toUpperCase(),
175
- headers: {
176
- 'Content-Type': 'application/json',
177
- Authorization: `Bearer ${this.apiKey}`,
178
- },
179
- body: options.data ? JSON.stringify(options.data) : undefined,
180
- });
181
- const json = await response.json();
182
- if (!response.ok || !json.success) {
183
- throw new Error(json.error?.message || 'Request failed');
184
- }
185
- return json.data;
186
- }
187
- }
188
- exports.Agent = Agent;