@stacksjs/ai 0.70.87 → 0.70.90
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/agents/claude/index.js +197 -0
- package/dist/agents/index.js +1 -0
- package/dist/buddy.js +393 -0
- package/dist/drivers/anthropic/index.js +276 -0
- package/dist/drivers/claude-agent-sdk/index.js +198 -0
- package/dist/drivers/index.js +4 -0
- package/dist/drivers/ollama/index.js +332 -0
- package/dist/drivers/openai/index.js +351 -0
- package/dist/image.js +375 -0
- package/dist/index.js +16 -175
- package/dist/mcp.js +361 -0
- package/dist/personalization.js +244 -0
- package/dist/search.js +316 -0
- package/dist/text.js +51 -0
- package/dist/types.js +0 -0
- package/dist/utils/client-bedrock-runtime.js +17 -0
- package/dist/utils/client-bedrock.js +20 -0
- package/dist/utils/model-access.js +21 -0
- package/dist/utils/retry.js +39 -0
- package/dist/utils/tokens.js +59 -0
- package/dist/utils/usage.js +27 -0
- package/dist/utils/vision.js +54 -0
- package/package.json +1 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { fetchWithRetry } from "../../utils/retry";
|
|
2
|
+
import { recordUsage } from "../../utils/usage";
|
|
3
|
+
import { normalizeMessagesForProvider } from "../../utils/vision";
|
|
4
|
+
const DEFAULT_MODEL = "claude-sonnet-4-20250514", DEFAULT_MAX_TOKENS = 4096, DEFAULT_VERSION = "2023-06-01", BASE_URL = "https://api.anthropic.com/v1";
|
|
5
|
+
let globalConfig = null;
|
|
6
|
+
export function configure(config) {
|
|
7
|
+
globalConfig = config;
|
|
8
|
+
}
|
|
9
|
+
function getConfig(config) {
|
|
10
|
+
const merged = { ...globalConfig, ...config };
|
|
11
|
+
if (!merged.apiKey)
|
|
12
|
+
merged.apiKey = process.env.ANTHROPIC_API_KEY || "";
|
|
13
|
+
return merged;
|
|
14
|
+
}
|
|
15
|
+
export function createAnthropicDriver(config) {
|
|
16
|
+
const {
|
|
17
|
+
apiKey,
|
|
18
|
+
model = DEFAULT_MODEL,
|
|
19
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
20
|
+
anthropicVersion = DEFAULT_VERSION
|
|
21
|
+
} = config;
|
|
22
|
+
return {
|
|
23
|
+
name: "Claude API",
|
|
24
|
+
async process(command, systemPrompt, history) {
|
|
25
|
+
if (!apiKey)
|
|
26
|
+
throw Error("Anthropic API key not set. Configure your API key in settings.");
|
|
27
|
+
const response = await fetchWithRetry(`${BASE_URL}/messages`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: {
|
|
30
|
+
"Content-Type": "application/json",
|
|
31
|
+
"x-api-key": apiKey,
|
|
32
|
+
"anthropic-version": anthropicVersion
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
model,
|
|
36
|
+
max_tokens: maxTokens,
|
|
37
|
+
system: systemPrompt,
|
|
38
|
+
messages: [...history, { role: "user", content: command }]
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const error = await response.text();
|
|
43
|
+
throw Error(`Claude API error: ${error}`);
|
|
44
|
+
}
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
if (!data.content || data.content.length === 0)
|
|
47
|
+
throw Error("Claude API returned empty content");
|
|
48
|
+
return data.content[0].text;
|
|
49
|
+
},
|
|
50
|
+
async* stream(command, systemPrompt, history) {
|
|
51
|
+
if (!apiKey)
|
|
52
|
+
throw Error("Anthropic API key not set. Configure your API key in settings.");
|
|
53
|
+
const response = await fetch(`${BASE_URL}/messages`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: {
|
|
56
|
+
"Content-Type": "application/json",
|
|
57
|
+
"x-api-key": apiKey,
|
|
58
|
+
"anthropic-version": anthropicVersion
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
model,
|
|
62
|
+
max_tokens: maxTokens,
|
|
63
|
+
system: systemPrompt,
|
|
64
|
+
stream: !0,
|
|
65
|
+
messages: [...history, { role: "user", content: command }]
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
const error = await response.text();
|
|
70
|
+
throw Error(`Claude API error: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
const reader = response.body?.getReader();
|
|
73
|
+
if (!reader)
|
|
74
|
+
throw Error("No response body");
|
|
75
|
+
const decoder = new TextDecoder;
|
|
76
|
+
let buffer = "";
|
|
77
|
+
const handlePayload = function* (data) {
|
|
78
|
+
if (data === "[DONE]")
|
|
79
|
+
return;
|
|
80
|
+
let event;
|
|
81
|
+
try {
|
|
82
|
+
event = JSON.parse(data);
|
|
83
|
+
} catch {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (event.type === "error") {
|
|
87
|
+
const msg = event.error?.message ?? JSON.stringify(event.error ?? event);
|
|
88
|
+
throw Error(`[anthropic/stream] mid-stream error: ${msg}`);
|
|
89
|
+
}
|
|
90
|
+
if (event.type === "content_block_delta" && event.delta?.text)
|
|
91
|
+
yield event.delta.text;
|
|
92
|
+
};
|
|
93
|
+
while (!0) {
|
|
94
|
+
const { done, value } = await reader.read();
|
|
95
|
+
if (done)
|
|
96
|
+
break;
|
|
97
|
+
buffer += decoder.decode(value, { stream: !0 });
|
|
98
|
+
const lines = buffer.split(`
|
|
99
|
+
`);
|
|
100
|
+
buffer = lines.pop() || "";
|
|
101
|
+
for (const line of lines)
|
|
102
|
+
if (line.startsWith("data: "))
|
|
103
|
+
yield* handlePayload(line.slice(6));
|
|
104
|
+
}
|
|
105
|
+
if (buffer.startsWith("data: "))
|
|
106
|
+
yield* handlePayload(buffer.slice(6));
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export async function chat(messages, options = {}) {
|
|
111
|
+
const config = getConfig(), {
|
|
112
|
+
model = DEFAULT_MODEL,
|
|
113
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
114
|
+
temperature,
|
|
115
|
+
topP,
|
|
116
|
+
stop,
|
|
117
|
+
system,
|
|
118
|
+
tools,
|
|
119
|
+
toolChoice,
|
|
120
|
+
responseFormat
|
|
121
|
+
} = options, normalizedMessages = normalizeMessagesForProvider(messages, "anthropic"), startedAt = Date.now(), body = {
|
|
122
|
+
model,
|
|
123
|
+
max_tokens: maxTokens,
|
|
124
|
+
temperature,
|
|
125
|
+
top_p: topP,
|
|
126
|
+
stop_sequences: stop ? Array.isArray(stop) ? stop : [stop] : void 0,
|
|
127
|
+
system,
|
|
128
|
+
messages: normalizedMessages
|
|
129
|
+
};
|
|
130
|
+
if (tools && tools.length > 0) {
|
|
131
|
+
body.tools = tools.map((t) => ({
|
|
132
|
+
name: t.name,
|
|
133
|
+
description: t.description,
|
|
134
|
+
input_schema: t.parameters ?? { type: "object", properties: {} }
|
|
135
|
+
}));
|
|
136
|
+
if (toolChoice !== void 0)
|
|
137
|
+
body.tool_choice = mapAnthropicToolChoice(toolChoice);
|
|
138
|
+
}
|
|
139
|
+
if (responseFormat && responseFormat.type !== "text") {
|
|
140
|
+
const outputTool = buildAnthropicJsonTool(responseFormat), existing = Array.isArray(body.tools) ? body.tools : [];
|
|
141
|
+
body.tools = [...existing, outputTool];
|
|
142
|
+
if (toolChoice === void 0)
|
|
143
|
+
body.tool_choice = { type: "tool", name: outputTool.name };
|
|
144
|
+
}
|
|
145
|
+
const response = await fetch(`${BASE_URL}/messages`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: {
|
|
148
|
+
"Content-Type": "application/json",
|
|
149
|
+
"x-api-key": config.apiKey,
|
|
150
|
+
"anthropic-version": config.anthropicVersion || DEFAULT_VERSION
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify(body)
|
|
153
|
+
});
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
const error = await response.text();
|
|
156
|
+
throw Error(`Claude API error: ${error}`);
|
|
157
|
+
}
|
|
158
|
+
const data = await response.json();
|
|
159
|
+
if (!data.content || data.content.length === 0)
|
|
160
|
+
throw Error("Claude API returned empty content");
|
|
161
|
+
const block = data.content.find((b) => b.type === "tool_use") ?? data.content.find((b) => b.type === "text") ?? data.content[0], result = {
|
|
162
|
+
content: block?.type === "tool_use" ? JSON.stringify(block.input) : block?.text ?? "",
|
|
163
|
+
model: data.model,
|
|
164
|
+
usage: {
|
|
165
|
+
promptTokens: data.usage?.input_tokens || 0,
|
|
166
|
+
completionTokens: data.usage?.output_tokens || 0,
|
|
167
|
+
totalTokens: (data.usage?.input_tokens || 0) + (data.usage?.output_tokens || 0)
|
|
168
|
+
},
|
|
169
|
+
finishReason: data.stop_reason
|
|
170
|
+
};
|
|
171
|
+
recordUsage({
|
|
172
|
+
provider: "anthropic",
|
|
173
|
+
model: data.model,
|
|
174
|
+
promptTokens: result.usage.promptTokens,
|
|
175
|
+
completionTokens: result.usage.completionTokens,
|
|
176
|
+
totalTokens: result.usage.totalTokens,
|
|
177
|
+
durationMs: Date.now() - startedAt,
|
|
178
|
+
timestamp: Date.now()
|
|
179
|
+
});
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
function mapAnthropicToolChoice(choice) {
|
|
183
|
+
if (choice === "auto")
|
|
184
|
+
return { type: "auto" };
|
|
185
|
+
if (choice === "required")
|
|
186
|
+
return { type: "any" };
|
|
187
|
+
if (choice === "none")
|
|
188
|
+
return { type: "auto", disable_parallel_tool_use: !0 };
|
|
189
|
+
return { type: "tool", name: choice.name };
|
|
190
|
+
}
|
|
191
|
+
function buildAnthropicJsonTool(format) {
|
|
192
|
+
if (format.type === "json_schema")
|
|
193
|
+
return {
|
|
194
|
+
name: format.json_schema.name,
|
|
195
|
+
description: `Returns the result as JSON matching the '${format.json_schema.name}' schema.`,
|
|
196
|
+
input_schema: format.json_schema.schema
|
|
197
|
+
};
|
|
198
|
+
return {
|
|
199
|
+
name: "structured_output",
|
|
200
|
+
description: "Returns the result as a JSON object.",
|
|
201
|
+
input_schema: { type: "object", additionalProperties: !0 }
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
export async function* streamChat(messages, options = {}) {
|
|
205
|
+
const config = getConfig(), {
|
|
206
|
+
model = DEFAULT_MODEL,
|
|
207
|
+
maxTokens = DEFAULT_MAX_TOKENS,
|
|
208
|
+
temperature,
|
|
209
|
+
topP,
|
|
210
|
+
stop,
|
|
211
|
+
system
|
|
212
|
+
} = options, response = await fetch(`${BASE_URL}/messages`, {
|
|
213
|
+
method: "POST",
|
|
214
|
+
headers: {
|
|
215
|
+
"Content-Type": "application/json",
|
|
216
|
+
"x-api-key": config.apiKey,
|
|
217
|
+
"anthropic-version": config.anthropicVersion || DEFAULT_VERSION
|
|
218
|
+
},
|
|
219
|
+
body: JSON.stringify({
|
|
220
|
+
model,
|
|
221
|
+
max_tokens: maxTokens,
|
|
222
|
+
temperature,
|
|
223
|
+
top_p: topP,
|
|
224
|
+
stop_sequences: stop ? Array.isArray(stop) ? stop : [stop] : void 0,
|
|
225
|
+
system,
|
|
226
|
+
stream: !0,
|
|
227
|
+
messages: normalizeMessagesForProvider(messages, "anthropic")
|
|
228
|
+
})
|
|
229
|
+
});
|
|
230
|
+
if (!response.ok) {
|
|
231
|
+
const error = await response.text();
|
|
232
|
+
throw Error(`Claude API error: ${error}`);
|
|
233
|
+
}
|
|
234
|
+
const reader = response.body?.getReader();
|
|
235
|
+
if (!reader)
|
|
236
|
+
throw Error("No response body");
|
|
237
|
+
const decoder = new TextDecoder;
|
|
238
|
+
let buffer = "";
|
|
239
|
+
while (!0) {
|
|
240
|
+
const { done, value } = await reader.read();
|
|
241
|
+
if (done)
|
|
242
|
+
break;
|
|
243
|
+
buffer += decoder.decode(value, { stream: !0 });
|
|
244
|
+
const lines = buffer.split(`
|
|
245
|
+
`);
|
|
246
|
+
buffer = lines.pop() || "";
|
|
247
|
+
for (const line of lines)
|
|
248
|
+
if (line.startsWith("data: ")) {
|
|
249
|
+
const data = line.slice(6);
|
|
250
|
+
if (data === "[DONE]")
|
|
251
|
+
continue;
|
|
252
|
+
try {
|
|
253
|
+
const event = JSON.parse(data);
|
|
254
|
+
if (event.type === "content_block_delta" && event.delta?.text)
|
|
255
|
+
yield event.delta.text;
|
|
256
|
+
} catch {}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
export async function prompt(text, options = {}) {
|
|
261
|
+
return (await chat([{ role: "user", content: text }], options)).content;
|
|
262
|
+
}
|
|
263
|
+
export function estimateTokens(text) {
|
|
264
|
+
return Math.ceil(text.length / 4);
|
|
265
|
+
}
|
|
266
|
+
export const anthropicDriver = {
|
|
267
|
+
create: createAnthropicDriver
|
|
268
|
+
}, anthropic = {
|
|
269
|
+
configure,
|
|
270
|
+
chat,
|
|
271
|
+
streamChat,
|
|
272
|
+
prompt,
|
|
273
|
+
estimateTokens,
|
|
274
|
+
createDriver: createAnthropicDriver
|
|
275
|
+
};
|
|
276
|
+
export default anthropic;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
let sdkModule = null;
|
|
2
|
+
async function getSDK() {
|
|
3
|
+
if (!sdkModule)
|
|
4
|
+
try {
|
|
5
|
+
sdkModule = await import("@anthropic-ai/claude-agent-sdk");
|
|
6
|
+
} catch {
|
|
7
|
+
throw Error("Claude Agent SDK not installed. Run: bun add @anthropic-ai/claude-agent-sdk");
|
|
8
|
+
}
|
|
9
|
+
return sdkModule;
|
|
10
|
+
}
|
|
11
|
+
const sdkState = {
|
|
12
|
+
lastSessionId: void 0
|
|
13
|
+
}, DEFAULT_CONFIG = {
|
|
14
|
+
maxTurns: 25,
|
|
15
|
+
allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
|
|
16
|
+
permissionMode: "bypassPermissions"
|
|
17
|
+
};
|
|
18
|
+
export function createClaudeAgentSDKDriver(config = {}) {
|
|
19
|
+
const {
|
|
20
|
+
maxTurns = DEFAULT_CONFIG.maxTurns,
|
|
21
|
+
cwd,
|
|
22
|
+
allowedTools = DEFAULT_CONFIG.allowedTools,
|
|
23
|
+
disallowedTools,
|
|
24
|
+
permissionMode = DEFAULT_CONFIG.permissionMode,
|
|
25
|
+
customSystemPrompt,
|
|
26
|
+
appendSystemPrompt,
|
|
27
|
+
resumeSessionId
|
|
28
|
+
} = config;
|
|
29
|
+
return {
|
|
30
|
+
name: "Claude Agent SDK",
|
|
31
|
+
async process(command, systemPrompt, _history) {
|
|
32
|
+
const sdk = await getSDK(), { query } = sdk, fullPrompt = systemPrompt ? `${systemPrompt}
|
|
33
|
+
|
|
34
|
+
User request: ${command}` : command, options = {
|
|
35
|
+
allowedTools,
|
|
36
|
+
permissionMode,
|
|
37
|
+
maxTurns
|
|
38
|
+
};
|
|
39
|
+
if (disallowedTools)
|
|
40
|
+
options.disallowedTools = disallowedTools;
|
|
41
|
+
if (customSystemPrompt)
|
|
42
|
+
options.customSystemPrompt = customSystemPrompt;
|
|
43
|
+
if (appendSystemPrompt)
|
|
44
|
+
options.appendSystemPrompt = appendSystemPrompt;
|
|
45
|
+
if (cwd)
|
|
46
|
+
options.cwd = cwd;
|
|
47
|
+
if (resumeSessionId || sdkState.lastSessionId)
|
|
48
|
+
options.resume = resumeSessionId || sdkState.lastSessionId;
|
|
49
|
+
let result = "";
|
|
50
|
+
try {
|
|
51
|
+
for await (const message of query({ prompt: fullPrompt, options })) {
|
|
52
|
+
if (message.type === "system" && message.subtype === "init")
|
|
53
|
+
sdkState.lastSessionId = message.session_id;
|
|
54
|
+
if ("result" in message && typeof message.result === "string")
|
|
55
|
+
result = message.result;
|
|
56
|
+
}
|
|
57
|
+
return result || "No response from Claude Agent SDK";
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const err = error;
|
|
60
|
+
if (err.message.includes("ANTHROPIC_API_KEY"))
|
|
61
|
+
throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");
|
|
62
|
+
throw Error(`Claude Agent SDK error: ${err.message}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async* stream(command, systemPrompt, _history) {
|
|
66
|
+
const sdk = await getSDK(), { query } = sdk, fullPrompt = systemPrompt ? `${systemPrompt}
|
|
67
|
+
|
|
68
|
+
User request: ${command}` : command, options = {
|
|
69
|
+
allowedTools,
|
|
70
|
+
permissionMode,
|
|
71
|
+
maxTurns
|
|
72
|
+
};
|
|
73
|
+
if (disallowedTools)
|
|
74
|
+
options.disallowedTools = disallowedTools;
|
|
75
|
+
if (customSystemPrompt)
|
|
76
|
+
options.customSystemPrompt = customSystemPrompt;
|
|
77
|
+
if (appendSystemPrompt)
|
|
78
|
+
options.appendSystemPrompt = appendSystemPrompt;
|
|
79
|
+
if (cwd)
|
|
80
|
+
options.cwd = cwd;
|
|
81
|
+
if (resumeSessionId || sdkState.lastSessionId)
|
|
82
|
+
options.resume = resumeSessionId || sdkState.lastSessionId;
|
|
83
|
+
try {
|
|
84
|
+
for await (const message of query({ prompt: fullPrompt, options })) {
|
|
85
|
+
if (message.type === "system" && message.subtype === "init")
|
|
86
|
+
sdkState.lastSessionId = message.session_id;
|
|
87
|
+
if (message.type === "assistant") {
|
|
88
|
+
const assistantMsg = message;
|
|
89
|
+
if (assistantMsg.message?.content) {
|
|
90
|
+
for (const block of assistantMsg.message.content)
|
|
91
|
+
if (block.type === "text" && block.text)
|
|
92
|
+
yield block.text;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if ("result" in message && typeof message.result === "string")
|
|
96
|
+
yield message.result;
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
const err = error;
|
|
100
|
+
if (err.message.includes("ANTHROPIC_API_KEY"))
|
|
101
|
+
throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");
|
|
102
|
+
throw Error(`Claude Agent SDK error: ${err.message}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export async function processStreaming(command, cwd, config = {}) {
|
|
108
|
+
const sdk = await getSDK(), { query } = sdk, {
|
|
109
|
+
maxTurns = DEFAULT_CONFIG.maxTurns,
|
|
110
|
+
allowedTools = DEFAULT_CONFIG.allowedTools,
|
|
111
|
+
disallowedTools,
|
|
112
|
+
permissionMode = DEFAULT_CONFIG.permissionMode,
|
|
113
|
+
customSystemPrompt,
|
|
114
|
+
appendSystemPrompt,
|
|
115
|
+
resumeSessionId
|
|
116
|
+
} = config, options = {
|
|
117
|
+
allowedTools,
|
|
118
|
+
permissionMode,
|
|
119
|
+
maxTurns
|
|
120
|
+
};
|
|
121
|
+
if (disallowedTools)
|
|
122
|
+
options.disallowedTools = disallowedTools;
|
|
123
|
+
if (customSystemPrompt)
|
|
124
|
+
options.customSystemPrompt = customSystemPrompt;
|
|
125
|
+
if (appendSystemPrompt)
|
|
126
|
+
options.appendSystemPrompt = appendSystemPrompt;
|
|
127
|
+
if (cwd)
|
|
128
|
+
options.cwd = cwd;
|
|
129
|
+
if (resumeSessionId || sdkState.lastSessionId)
|
|
130
|
+
options.resume = resumeSessionId || sdkState.lastSessionId;
|
|
131
|
+
const encoder = new TextEncoder;
|
|
132
|
+
let fullResponse = "", resolveFullResponse;
|
|
133
|
+
const fullResponsePromise = new Promise((resolve) => {
|
|
134
|
+
resolveFullResponse = resolve;
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
stream: new ReadableStream({
|
|
138
|
+
async start(controller) {
|
|
139
|
+
try {
|
|
140
|
+
for await (const message of query({ prompt: command, options })) {
|
|
141
|
+
if (message.type === "system" && message.subtype === "init")
|
|
142
|
+
sdkState.lastSessionId = message.session_id;
|
|
143
|
+
if (message.type === "assistant") {
|
|
144
|
+
const assistantMsg = message;
|
|
145
|
+
if (assistantMsg.message?.content) {
|
|
146
|
+
for (const block of assistantMsg.message.content)
|
|
147
|
+
if (block.type === "text" && block.text) {
|
|
148
|
+
fullResponse += block.text;
|
|
149
|
+
controller.enqueue(encoder.encode(block.text));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if ("result" in message && typeof message.result === "string") {
|
|
154
|
+
if (!fullResponse) {
|
|
155
|
+
fullResponse = message.result;
|
|
156
|
+
controller.enqueue(encoder.encode(message.result));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
resolveFullResponse(fullResponse);
|
|
161
|
+
controller.close();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
resolveFullResponse(fullResponse);
|
|
164
|
+
controller.error(error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}),
|
|
168
|
+
fullResponse: fullResponsePromise
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
export async function resumeSession(sessionId, prompt) {
|
|
172
|
+
const sdk = await getSDK(), { query } = sdk;
|
|
173
|
+
let result = "";
|
|
174
|
+
for await (const message of query({
|
|
175
|
+
prompt,
|
|
176
|
+
options: {
|
|
177
|
+
resume: sessionId,
|
|
178
|
+
permissionMode: "bypassPermissions"
|
|
179
|
+
}
|
|
180
|
+
}))
|
|
181
|
+
if ("result" in message && typeof message.result === "string")
|
|
182
|
+
result = message.result;
|
|
183
|
+
return result || "No response from resumed session";
|
|
184
|
+
}
|
|
185
|
+
export function getLastSessionId() {
|
|
186
|
+
return sdkState.lastSessionId;
|
|
187
|
+
}
|
|
188
|
+
export function clearSession() {
|
|
189
|
+
sdkState.lastSessionId = void 0;
|
|
190
|
+
}
|
|
191
|
+
export const claudeAgentSDK = {
|
|
192
|
+
createDriver: createClaudeAgentSDKDriver,
|
|
193
|
+
processStreaming,
|
|
194
|
+
resumeSession,
|
|
195
|
+
getLastSessionId,
|
|
196
|
+
clearSession
|
|
197
|
+
};
|
|
198
|
+
export default claudeAgentSDK;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createAnthropicDriver, anthropicDriver, anthropic, estimateTokens } from "./anthropic";
|
|
2
|
+
export { createOpenAIDriver, openaiDriver, openai } from "./openai";
|
|
3
|
+
export { createOllamaDriver, ollamaDriver, ollama } from "./ollama";
|
|
4
|
+
export { createClaudeAgentSDKDriver, claudeAgentSDK, getLastSessionId, clearSession } from "./claude-agent-sdk";
|