aura-code 0.3.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/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/agent/context.d.ts +13 -0
- package/dist/agent/context.js +183 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/loop.d.ts +60 -0
- package/dist/agent/loop.js +228 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session-store.d.ts +30 -0
- package/dist/agent/session-store.js +178 -0
- package/dist/agent/session-store.js.map +1 -0
- package/dist/agent/spawner.d.ts +57 -0
- package/dist/agent/spawner.js +112 -0
- package/dist/agent/spawner.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +3 -0
- package/dist/agent/system-prompt.js +100 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/architect/engine.d.ts +47 -0
- package/dist/architect/engine.js +217 -0
- package/dist/architect/engine.js.map +1 -0
- package/dist/architect/types.d.ts +61 -0
- package/dist/architect/types.js +6 -0
- package/dist/architect/types.js.map +1 -0
- package/dist/cli/diamond.d.ts +1 -0
- package/dist/cli/diamond.js +23 -0
- package/dist/cli/diamond.js.map +1 -0
- package/dist/cli/display.d.ts +44 -0
- package/dist/cli/display.js +234 -0
- package/dist/cli/display.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1734 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +46 -0
- package/dist/config/defaults.js +106 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/project-config.d.ts +90 -0
- package/dist/config/project-config.js +141 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/harness/proposer.d.ts +26 -0
- package/dist/harness/proposer.js +204 -0
- package/dist/harness/proposer.js.map +1 -0
- package/dist/harness/weakness-miner.d.ts +28 -0
- package/dist/harness/weakness-miner.js +359 -0
- package/dist/harness/weakness-miner.js.map +1 -0
- package/dist/integrations/harnesses.d.ts +23 -0
- package/dist/integrations/harnesses.js +161 -0
- package/dist/integrations/harnesses.js.map +1 -0
- package/dist/orchestration/competence.d.ts +53 -0
- package/dist/orchestration/competence.js +181 -0
- package/dist/orchestration/competence.js.map +1 -0
- package/dist/orchestration/executor.d.ts +42 -0
- package/dist/orchestration/executor.js +206 -0
- package/dist/orchestration/executor.js.map +1 -0
- package/dist/orchestration/index.d.ts +20 -0
- package/dist/orchestration/index.js +39 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/orchestrator-prompts.d.ts +11 -0
- package/dist/orchestration/orchestrator-prompts.js +153 -0
- package/dist/orchestration/orchestrator-prompts.js.map +1 -0
- package/dist/orchestration/orchestrator.d.ts +27 -0
- package/dist/orchestration/orchestrator.js +169 -0
- package/dist/orchestration/orchestrator.js.map +1 -0
- package/dist/orchestration/plan-store.d.ts +53 -0
- package/dist/orchestration/plan-store.js +176 -0
- package/dist/orchestration/plan-store.js.map +1 -0
- package/dist/orchestration/router-prompts.d.ts +6 -0
- package/dist/orchestration/router-prompts.js +55 -0
- package/dist/orchestration/router-prompts.js.map +1 -0
- package/dist/orchestration/router.d.ts +23 -0
- package/dist/orchestration/router.js +70 -0
- package/dist/orchestration/router.js.map +1 -0
- package/dist/orchestration/ruby-detect.d.ts +6 -0
- package/dist/orchestration/ruby-detect.js +130 -0
- package/dist/orchestration/ruby-detect.js.map +1 -0
- package/dist/orchestration/ruby-types.d.ts +44 -0
- package/dist/orchestration/ruby-types.js +6 -0
- package/dist/orchestration/ruby-types.js.map +1 -0
- package/dist/orchestration/specialist-prompts.d.ts +19 -0
- package/dist/orchestration/specialist-prompts.js +143 -0
- package/dist/orchestration/specialist-prompts.js.map +1 -0
- package/dist/orchestration/specialists.d.ts +66 -0
- package/dist/orchestration/specialists.js +175 -0
- package/dist/orchestration/specialists.js.map +1 -0
- package/dist/orchestration/types.d.ts +82 -0
- package/dist/orchestration/types.js +6 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/perception/extractor.d.ts +7 -0
- package/dist/perception/extractor.js +521 -0
- package/dist/perception/extractor.js.map +1 -0
- package/dist/perception/graph-store.d.ts +25 -0
- package/dist/perception/graph-store.js +117 -0
- package/dist/perception/graph-store.js.map +1 -0
- package/dist/perception/index.d.ts +4 -0
- package/dist/perception/index.js +18 -0
- package/dist/perception/index.js.map +1 -0
- package/dist/perception/queries.d.ts +29 -0
- package/dist/perception/queries.js +354 -0
- package/dist/perception/queries.js.map +1 -0
- package/dist/perception/types.d.ts +103 -0
- package/dist/perception/types.js +6 -0
- package/dist/perception/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +11 -0
- package/dist/providers/anthropic.js +172 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +58 -0
- package/dist/providers/factory.js +354 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/fallback.d.ts +24 -0
- package/dist/providers/fallback.js +72 -0
- package/dist/providers/fallback.js.map +1 -0
- package/dist/providers/google.d.ts +11 -0
- package/dist/providers/google.js +129 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +24 -0
- package/dist/providers/openai-compatible.js +216 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/resilient-factory.d.ts +24 -0
- package/dist/providers/resilient-factory.js +57 -0
- package/dist/providers/resilient-factory.js.map +1 -0
- package/dist/providers/resilient.d.ts +63 -0
- package/dist/providers/resilient.js +145 -0
- package/dist/providers/resilient.js.map +1 -0
- package/dist/providers/types.d.ts +84 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/ruby/alternator.d.ts +40 -0
- package/dist/ruby/alternator.js +233 -0
- package/dist/ruby/alternator.js.map +1 -0
- package/dist/ruby/competence.d.ts +34 -0
- package/dist/ruby/competence.js +264 -0
- package/dist/ruby/competence.js.map +1 -0
- package/dist/ruby/episode-capture.d.ts +56 -0
- package/dist/ruby/episode-capture.js +193 -0
- package/dist/ruby/episode-capture.js.map +1 -0
- package/dist/ruby/fine-tune.d.ts +16 -0
- package/dist/ruby/fine-tune.js +253 -0
- package/dist/ruby/fine-tune.js.map +1 -0
- package/dist/ruby/index.d.ts +10 -0
- package/dist/ruby/index.js +26 -0
- package/dist/ruby/index.js.map +1 -0
- package/dist/ruby/ruby-model.d.ts +36 -0
- package/dist/ruby/ruby-model.js +81 -0
- package/dist/ruby/ruby-model.js.map +1 -0
- package/dist/ruby/training-data.d.ts +11 -0
- package/dist/ruby/training-data.js +107 -0
- package/dist/ruby/training-data.js.map +1 -0
- package/dist/ruby/types.d.ts +136 -0
- package/dist/ruby/types.js +20 -0
- package/dist/ruby/types.js.map +1 -0
- package/dist/safety/permissions.d.ts +32 -0
- package/dist/safety/permissions.js +304 -0
- package/dist/safety/permissions.js.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +342 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/session.d.ts +22 -0
- package/dist/server/session.js +16 -0
- package/dist/server/session.js.map +1 -0
- package/dist/setup/first-run.d.ts +41 -0
- package/dist/setup/first-run.js +386 -0
- package/dist/setup/first-run.js.map +1 -0
- package/dist/setup/global-config.d.ts +19 -0
- package/dist/setup/global-config.js +97 -0
- package/dist/setup/global-config.js.map +1 -0
- package/dist/tools/audio-transcribe.d.ts +8 -0
- package/dist/tools/audio-transcribe.js +156 -0
- package/dist/tools/audio-transcribe.js.map +1 -0
- package/dist/tools/browser.d.ts +15 -0
- package/dist/tools/browser.js +241 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/calendar.d.ts +12 -0
- package/dist/tools/calendar.js +196 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/clipboard.d.ts +7 -0
- package/dist/tools/clipboard.js +90 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/cron.d.ts +10 -0
- package/dist/tools/cron.js +167 -0
- package/dist/tools/cron.js.map +1 -0
- package/dist/tools/edit-file.d.ts +6 -0
- package/dist/tools/edit-file.js +98 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/email.d.ts +11 -0
- package/dist/tools/email.js +153 -0
- package/dist/tools/email.js.map +1 -0
- package/dist/tools/git.d.ts +1 -0
- package/dist/tools/git.js +7 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/http-request.d.ts +12 -0
- package/dist/tools/http-request.js +91 -0
- package/dist/tools/http-request.js.map +1 -0
- package/dist/tools/image-read.d.ts +7 -0
- package/dist/tools/image-read.js +125 -0
- package/dist/tools/image-read.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +201 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-dir.d.ts +1 -0
- package/dist/tools/list-dir.js +6 -0
- package/dist/tools/list-dir.js.map +1 -0
- package/dist/tools/mcp.d.ts +11 -0
- package/dist/tools/mcp.js +356 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/memory.d.ts +9 -0
- package/dist/tools/memory.js +124 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/notify.d.ts +9 -0
- package/dist/tools/notify.js +40 -0
- package/dist/tools/notify.js.map +1 -0
- package/dist/tools/read-file.d.ts +6 -0
- package/dist/tools/read-file.js +76 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/run-shell.d.ts +1 -0
- package/dist/tools/run-shell.js +6 -0
- package/dist/tools/run-shell.js.map +1 -0
- package/dist/tools/run-tests.d.ts +1 -0
- package/dist/tools/run-tests.js +6 -0
- package/dist/tools/run-tests.js.map +1 -0
- package/dist/tools/search-code.d.ts +1 -0
- package/dist/tools/search-code.js +6 -0
- package/dist/tools/search-code.js.map +1 -0
- package/dist/tools/telegram-bot.d.ts +2 -0
- package/dist/tools/telegram-bot.js +693 -0
- package/dist/tools/telegram-bot.js.map +1 -0
- package/dist/tools/telegram-safety.d.ts +52 -0
- package/dist/tools/telegram-safety.js +189 -0
- package/dist/tools/telegram-safety.js.map +1 -0
- package/dist/tools/telegram.d.ts +16 -0
- package/dist/tools/telegram.js +227 -0
- package/dist/tools/telegram.js.map +1 -0
- package/dist/tools/tools.d.ts +48 -0
- package/dist/tools/tools.js +328 -0
- package/dist/tools/tools.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +11 -0
- package/dist/tools/web-fetch.js +119 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.d.ts +8 -0
- package/dist/tools/web-search.js +81 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/whatsapp.d.ts +10 -0
- package/dist/tools/whatsapp.js +222 -0
- package/dist/tools/whatsapp.js.map +1 -0
- package/dist/tools/write-file.d.ts +1 -0
- package/dist/tools/write-file.js +6 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/tools/youtube-transcript.d.ts +9 -0
- package/dist/tools/youtube-transcript.js +200 -0
- package/dist/tools/youtube-transcript.js.map +1 -0
- package/dist/util/circuit-breaker.d.ts +44 -0
- package/dist/util/circuit-breaker.js +78 -0
- package/dist/util/circuit-breaker.js.map +1 -0
- package/dist/util/env.d.ts +18 -0
- package/dist/util/env.js +39 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/errors.d.ts +42 -0
- package/dist/util/errors.js +121 -0
- package/dist/util/errors.js.map +1 -0
- package/dist/util/rate-limiter.d.ts +71 -0
- package/dist/util/rate-limiter.js +141 -0
- package/dist/util/rate-limiter.js.map +1 -0
- package/dist/util/retry.d.ts +30 -0
- package/dist/util/retry.js +57 -0
- package/dist/util/retry.js.map +1 -0
- package/dist/util/sanitize.d.ts +16 -0
- package/dist/util/sanitize.js +255 -0
- package/dist/util/sanitize.js.map +1 -0
- package/dist/verify/checks.d.ts +21 -0
- package/dist/verify/checks.js +311 -0
- package/dist/verify/checks.js.map +1 -0
- package/dist/verify/index.d.ts +33 -0
- package/dist/verify/index.js +127 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/types.d.ts +20 -0
- package/dist/verify/types.js +3 -0
- package/dist/verify/types.js.map +1 -0
- package/dist/versioncheck.d.ts +22 -0
- package/dist/versioncheck.js +203 -0
- package/dist/versioncheck.js.map +1 -0
- package/dist/viz/index.d.ts +2 -0
- package/dist/viz/index.js +733 -0
- package/dist/viz/index.js.map +1 -0
- package/dist/workflows/engine.d.ts +46 -0
- package/dist/workflows/engine.js +320 -0
- package/dist/workflows/engine.js.map +1 -0
- package/dist/workflows/types.d.ts +92 -0
- package/dist/workflows/types.js +6 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { LLMProvider, ProviderConfig, ToolDefinition, HistoryMessage, LLMResponse, StreamChunk } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI-compatible provider.
|
|
4
|
+
* Works with: OpenAI, OpenRouter, xAI (Grok), Ollama, LM Studio,
|
|
5
|
+
* Together AI, Groq, Perplexity, and any server that speaks the OpenAI API spec.
|
|
6
|
+
*
|
|
7
|
+
* How to target each:
|
|
8
|
+
* OpenAI: model="gpt-4o" apiKey=OPENAI_API_KEY
|
|
9
|
+
* OpenRouter: model="anthropic/claude-3.5" baseUrl="https://openrouter.ai/api/v1" apiKey=OPENROUTER_API_KEY
|
|
10
|
+
* xAI/Grok: model="grok-beta" baseUrl="https://api.x.ai/v1" apiKey=XAI_API_KEY
|
|
11
|
+
* Ollama: model="llama3.2" baseUrl="http://localhost:11434/v1" apiKey="ollama"
|
|
12
|
+
* LM Studio: model="local-model" baseUrl="http://localhost:1234/v1" apiKey="lm-studio"
|
|
13
|
+
*/
|
|
14
|
+
export declare class OpenAICompatibleProvider implements LLMProvider {
|
|
15
|
+
name: string;
|
|
16
|
+
supportsTools: boolean;
|
|
17
|
+
model: string;
|
|
18
|
+
private client;
|
|
19
|
+
private maxTokens;
|
|
20
|
+
private temperature;
|
|
21
|
+
constructor(config: ProviderConfig, providerName?: string);
|
|
22
|
+
complete(system: string, history: HistoryMessage[], tools: ToolDefinition[]): Promise<LLMResponse>;
|
|
23
|
+
stream(system: string, history: HistoryMessage[], tools: ToolDefinition[]): AsyncGenerator<StreamChunk>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OpenAICompatibleProvider = void 0;
|
|
7
|
+
const openai_1 = __importDefault(require("openai"));
|
|
8
|
+
const env_js_1 = require("../util/env.js");
|
|
9
|
+
/**
|
|
10
|
+
* OpenAI-compatible provider.
|
|
11
|
+
* Works with: OpenAI, OpenRouter, xAI (Grok), Ollama, LM Studio,
|
|
12
|
+
* Together AI, Groq, Perplexity, and any server that speaks the OpenAI API spec.
|
|
13
|
+
*
|
|
14
|
+
* How to target each:
|
|
15
|
+
* OpenAI: model="gpt-4o" apiKey=OPENAI_API_KEY
|
|
16
|
+
* OpenRouter: model="anthropic/claude-3.5" baseUrl="https://openrouter.ai/api/v1" apiKey=OPENROUTER_API_KEY
|
|
17
|
+
* xAI/Grok: model="grok-beta" baseUrl="https://api.x.ai/v1" apiKey=XAI_API_KEY
|
|
18
|
+
* Ollama: model="llama3.2" baseUrl="http://localhost:11434/v1" apiKey="ollama"
|
|
19
|
+
* LM Studio: model="local-model" baseUrl="http://localhost:1234/v1" apiKey="lm-studio"
|
|
20
|
+
*/
|
|
21
|
+
class OpenAICompatibleProvider {
|
|
22
|
+
name;
|
|
23
|
+
supportsTools = true;
|
|
24
|
+
model;
|
|
25
|
+
client;
|
|
26
|
+
maxTokens;
|
|
27
|
+
temperature;
|
|
28
|
+
constructor(config, providerName) {
|
|
29
|
+
this.model = config.model;
|
|
30
|
+
this.maxTokens = config.maxTokens ?? 8096;
|
|
31
|
+
this.temperature = config.temperature ?? 0.2;
|
|
32
|
+
this.name = providerName ?? deriveProviderName(config);
|
|
33
|
+
this.client = new openai_1.default({
|
|
34
|
+
apiKey: config.apiKey ?? resolveApiKey(config),
|
|
35
|
+
baseURL: config.baseUrl ?? resolveBaseUrl(config),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async complete(system, history, tools) {
|
|
39
|
+
const messages = toOpenAIMessages(system, history);
|
|
40
|
+
const response = await this.client.chat.completions.create({
|
|
41
|
+
model: this.model,
|
|
42
|
+
max_tokens: this.maxTokens,
|
|
43
|
+
temperature: this.temperature,
|
|
44
|
+
tools: tools.length > 0 ? tools.map(toOpenAITool) : undefined,
|
|
45
|
+
messages,
|
|
46
|
+
});
|
|
47
|
+
return fromOpenAIResponse(response);
|
|
48
|
+
}
|
|
49
|
+
async *stream(system, history, tools) {
|
|
50
|
+
const messages = toOpenAIMessages(system, history);
|
|
51
|
+
const stream = await this.client.chat.completions.create({
|
|
52
|
+
model: this.model,
|
|
53
|
+
max_tokens: this.maxTokens,
|
|
54
|
+
temperature: this.temperature,
|
|
55
|
+
tools: tools.length > 0 ? tools.map(toOpenAITool) : undefined,
|
|
56
|
+
messages,
|
|
57
|
+
stream: true,
|
|
58
|
+
stream_options: { include_usage: true },
|
|
59
|
+
});
|
|
60
|
+
let textBuffer = '';
|
|
61
|
+
const toolCallBuilders = new Map();
|
|
62
|
+
let usage;
|
|
63
|
+
for await (const chunk of stream) {
|
|
64
|
+
// OpenAI sends a final usage-only chunk when stream_options.include_usage is set
|
|
65
|
+
if (chunk.usage) {
|
|
66
|
+
usage = { inputTokens: chunk.usage.prompt_tokens ?? 0, outputTokens: chunk.usage.completion_tokens ?? 0 };
|
|
67
|
+
}
|
|
68
|
+
const delta = chunk.choices[0]?.delta;
|
|
69
|
+
if (!delta)
|
|
70
|
+
continue;
|
|
71
|
+
// Text content
|
|
72
|
+
if (delta.content) {
|
|
73
|
+
textBuffer += delta.content;
|
|
74
|
+
yield { type: 'text', text: delta.content };
|
|
75
|
+
}
|
|
76
|
+
// Tool calls (streamed in pieces)
|
|
77
|
+
for (const tc of delta.tool_calls ?? []) {
|
|
78
|
+
if (!toolCallBuilders.has(tc.index)) {
|
|
79
|
+
const id = tc.id ?? `tc_${tc.index}`;
|
|
80
|
+
const name = tc.function?.name ?? '';
|
|
81
|
+
toolCallBuilders.set(tc.index, { id, name, args: '' });
|
|
82
|
+
yield { type: 'tool_start', id, name };
|
|
83
|
+
}
|
|
84
|
+
const builder = toolCallBuilders.get(tc.index);
|
|
85
|
+
if (tc.function?.arguments) {
|
|
86
|
+
builder.args += tc.function.arguments;
|
|
87
|
+
yield { type: 'tool_input', id: builder.id, partial: tc.function.arguments };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Finish
|
|
91
|
+
const finishReason = chunk.choices[0]?.finish_reason;
|
|
92
|
+
if (finishReason === 'tool_calls' || finishReason === 'stop') {
|
|
93
|
+
// Finalise all tool calls
|
|
94
|
+
const calls = [];
|
|
95
|
+
for (const [, b] of toolCallBuilders) {
|
|
96
|
+
let input = {};
|
|
97
|
+
try {
|
|
98
|
+
input = JSON.parse(b.args);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
input = { _raw: b.args };
|
|
102
|
+
}
|
|
103
|
+
const call = { id: b.id, name: b.name, input };
|
|
104
|
+
calls.push(call);
|
|
105
|
+
yield { type: 'tool_end', call };
|
|
106
|
+
}
|
|
107
|
+
yield {
|
|
108
|
+
type: 'done',
|
|
109
|
+
response: {
|
|
110
|
+
text: textBuffer,
|
|
111
|
+
toolCalls: calls,
|
|
112
|
+
stopReason: finishReason === 'tool_calls' ? 'tools' : 'done',
|
|
113
|
+
usage,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
yield { type: 'done', response: { text: textBuffer, toolCalls: [], stopReason: 'done', usage } };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
|
|
123
|
+
// ── Conversion helpers ──────────────────────────────────────────────────────
|
|
124
|
+
function toOpenAITool(t) {
|
|
125
|
+
return {
|
|
126
|
+
type: 'function',
|
|
127
|
+
function: { name: t.name, description: t.description, parameters: t.parameters },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function toOpenAIMessages(system, history) {
|
|
131
|
+
const out = [
|
|
132
|
+
{ role: 'system', content: system },
|
|
133
|
+
];
|
|
134
|
+
for (const msg of history) {
|
|
135
|
+
if (msg.role === 'user') {
|
|
136
|
+
out.push({ role: 'user', content: msg.content });
|
|
137
|
+
}
|
|
138
|
+
else if (msg.role === 'assistant') {
|
|
139
|
+
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
140
|
+
out.push({
|
|
141
|
+
role: 'assistant',
|
|
142
|
+
content: msg.content || null,
|
|
143
|
+
tool_calls: msg.toolCalls.map(tc => ({
|
|
144
|
+
id: tc.id, type: 'function',
|
|
145
|
+
function: { name: tc.name, arguments: JSON.stringify(tc.input) },
|
|
146
|
+
})),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
out.push({ role: 'assistant', content: msg.content });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else if (msg.role === 'tool_result') {
|
|
154
|
+
for (const r of msg.results) {
|
|
155
|
+
out.push({ role: 'tool', tool_call_id: r.id, content: r.content });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
function fromOpenAIResponse(response) {
|
|
162
|
+
const choice = response.choices[0];
|
|
163
|
+
if (!choice)
|
|
164
|
+
return { text: '', toolCalls: [], stopReason: 'done' };
|
|
165
|
+
const text = choice.message.content ?? '';
|
|
166
|
+
const toolCalls = (choice.message.tool_calls ?? []).map(tc => {
|
|
167
|
+
let input = {};
|
|
168
|
+
try {
|
|
169
|
+
input = JSON.parse(tc.function.arguments);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
input = { _raw: tc.function.arguments };
|
|
173
|
+
}
|
|
174
|
+
return { id: tc.id, name: tc.function.name, input };
|
|
175
|
+
});
|
|
176
|
+
const stopReason = choice.finish_reason === 'tool_calls' ? 'tools' :
|
|
177
|
+
choice.finish_reason === 'length' ? 'limit' : 'done';
|
|
178
|
+
const u = response.usage;
|
|
179
|
+
return {
|
|
180
|
+
text, toolCalls, stopReason,
|
|
181
|
+
usage: u ? { inputTokens: u.prompt_tokens ?? 0, outputTokens: u.completion_tokens ?? 0 } : undefined,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// ── Auto-resolution helpers ─────────────────────────────────────────────────
|
|
185
|
+
function deriveProviderName(config) {
|
|
186
|
+
const m = config.model.toLowerCase();
|
|
187
|
+
if (config.baseUrl?.includes('openrouter'))
|
|
188
|
+
return 'OpenRouter';
|
|
189
|
+
if (config.baseUrl?.includes('x.ai') || m.includes('grok'))
|
|
190
|
+
return 'xAI';
|
|
191
|
+
if (config.baseUrl?.includes('localhost') || config.baseUrl?.includes('127.0.0.1')) {
|
|
192
|
+
return config.baseUrl?.includes('11434') ? 'Ollama' : 'Local';
|
|
193
|
+
}
|
|
194
|
+
if (m.startsWith('gpt-') || m.startsWith('o1') || m.startsWith('o3'))
|
|
195
|
+
return 'OpenAI';
|
|
196
|
+
return 'OpenAI-compatible';
|
|
197
|
+
}
|
|
198
|
+
function resolveApiKey(config) {
|
|
199
|
+
const m = config.model.toLowerCase();
|
|
200
|
+
if (config.baseUrl?.includes('openrouter'))
|
|
201
|
+
return (0, env_js_1.getApiKey)('OPENROUTER_API_KEY') ?? '';
|
|
202
|
+
if (config.baseUrl?.includes('x.ai') || m.includes('grok'))
|
|
203
|
+
return (0, env_js_1.getApiKey)('XAI_API_KEY') ?? '';
|
|
204
|
+
if (config.baseUrl?.includes('xiaomimimo') || m.startsWith('mimo-'))
|
|
205
|
+
return (0, env_js_1.getApiKey)('XIAOMI_API_KEY') ?? '';
|
|
206
|
+
if (config.baseUrl?.includes('localhost') || config.baseUrl?.includes('127.0.0.1'))
|
|
207
|
+
return 'local';
|
|
208
|
+
return (0, env_js_1.getApiKey)('OPENAI_API_KEY') ?? '';
|
|
209
|
+
}
|
|
210
|
+
function resolveBaseUrl(config) {
|
|
211
|
+
const m = config.model.toLowerCase();
|
|
212
|
+
if (m.includes('grok'))
|
|
213
|
+
return 'https://api.x.ai/v1';
|
|
214
|
+
return undefined; // default OpenAI
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=openai-compatible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.js","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { LLMProvider, ProviderConfig } from './types.js';
|
|
2
|
+
import type { Display } from '../cli/display.js';
|
|
3
|
+
export interface ResilienceConfig {
|
|
4
|
+
/** Requests per minute (0 = unlimited). Default 0. */
|
|
5
|
+
rpm?: number;
|
|
6
|
+
/** Tokens per minute (0 = unlimited). Default 0. */
|
|
7
|
+
tpm?: number;
|
|
8
|
+
/** Burst capacity for the rate limiter. Default rpm/6. */
|
|
9
|
+
burst?: number;
|
|
10
|
+
/** Max retry attempts. Default 5. */
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
/** Circuit-breaker failure threshold. Default 5. */
|
|
13
|
+
circuitFailureThreshold?: number;
|
|
14
|
+
/** Circuit-breaker cooldown ms. Default 30000. */
|
|
15
|
+
circuitCooldownMs?: number;
|
|
16
|
+
/** Fallback model ids tried in order if the primary exhausts retries. */
|
|
17
|
+
fallbacks?: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a provider wrapped in resilience + optional fallback chain.
|
|
21
|
+
* The returned object is what the agent loop uses — it doesn't know
|
|
22
|
+
* whether it's wrapped.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createResilientProvider(config: ProviderConfig, resilience: ResilienceConfig, display?: Display): LLMProvider;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createResilientProvider = createResilientProvider;
|
|
4
|
+
const factory_js_1 = require("./factory.js");
|
|
5
|
+
const resilient_js_1 = require("./resilient.js");
|
|
6
|
+
const fallback_js_1 = require("./fallback.js");
|
|
7
|
+
/** Sensible defaults per provider family. */
|
|
8
|
+
const DEFAULTS_BY_KIND = {
|
|
9
|
+
google: { rpm: 30, tpm: 1_000_000, burst: 5, maxRetries: 6 },
|
|
10
|
+
anthropic: { rpm: 50, burst: 8, maxRetries: 5 },
|
|
11
|
+
'openai-compatible': { rpm: 60, burst: 10, maxRetries: 5 },
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Build a provider wrapped in resilience + optional fallback chain.
|
|
15
|
+
* The returned object is what the agent loop uses — it doesn't know
|
|
16
|
+
* whether it's wrapped.
|
|
17
|
+
*/
|
|
18
|
+
function createResilientProvider(config, resilience, display) {
|
|
19
|
+
const kind = (0, factory_js_1.detectProviderKind)(config.model);
|
|
20
|
+
const merged = { ...DEFAULTS_BY_KIND[kind], ...resilience };
|
|
21
|
+
const resilientOpts = {
|
|
22
|
+
rpm: merged.rpm,
|
|
23
|
+
tpm: merged.tpm,
|
|
24
|
+
burst: merged.burst,
|
|
25
|
+
maxRetries: merged.maxRetries,
|
|
26
|
+
circuitFailureThreshold: merged.circuitFailureThreshold,
|
|
27
|
+
circuitCooldownMs: merged.circuitCooldownMs,
|
|
28
|
+
onRetry: ({ provider, attempt, delayMs, error }) => {
|
|
29
|
+
display?.retry?.({
|
|
30
|
+
provider,
|
|
31
|
+
attempt,
|
|
32
|
+
delayMs,
|
|
33
|
+
reason: error.status === 429 ? 'rate limited' :
|
|
34
|
+
error.status === 529 ? 'provider overloaded' :
|
|
35
|
+
error.status === 0 ? 'network error' :
|
|
36
|
+
`HTTP ${error.status}`,
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
onRateLimitWait: (provider, waitMs) => {
|
|
40
|
+
// Only surface when the wait is meaningful (>100ms)
|
|
41
|
+
if (waitMs > 100)
|
|
42
|
+
display?.retry?.({ provider, attempt: 0, delayMs: waitMs, reason: 'pacing' });
|
|
43
|
+
},
|
|
44
|
+
onCircuitChange: (provider, state) => display?.circuit?.({ provider, state }),
|
|
45
|
+
};
|
|
46
|
+
const primary = new resilient_js_1.ResilientProvider((0, factory_js_1.createProvider)(config), resilientOpts);
|
|
47
|
+
if (!merged.fallbacks || merged.fallbacks.length === 0)
|
|
48
|
+
return primary;
|
|
49
|
+
const fallbackProviders = merged.fallbacks.map(model => {
|
|
50
|
+
const fc = { ...config, model, baseUrl: undefined };
|
|
51
|
+
return new resilient_js_1.ResilientProvider((0, factory_js_1.createProvider)(fc), resilientOpts);
|
|
52
|
+
});
|
|
53
|
+
return new fallback_js_1.FallbackChainProvider([primary, ...fallbackProviders], {
|
|
54
|
+
onFailover: ({ from, to, reason }) => display?.failover?.({ from, to, reason }),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=resilient-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilient-factory.js","sourceRoot":"","sources":["../../src/providers/resilient-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { LLMProvider, LLMResponse, StreamChunk, HistoryMessage, ToolDefinition } from '../providers/types.js';
|
|
2
|
+
import { ApiError } from '../util/errors.js';
|
|
3
|
+
export interface ResilientOptions {
|
|
4
|
+
/** Requests per minute budget. 0 = unlimited. Default 0. */
|
|
5
|
+
rpm?: number;
|
|
6
|
+
/** Tokens per minute budget (Gemini-style). 0 = unlimited. */
|
|
7
|
+
tpm?: number;
|
|
8
|
+
/** Burst size — max tokens consumable in a quick burst. Default rpm/6. */
|
|
9
|
+
burst?: number;
|
|
10
|
+
/** Max retry attempts. Default 5. */
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
/** Cooldown when circuit is open. Default 30s. */
|
|
13
|
+
circuitCooldownMs?: number;
|
|
14
|
+
/** Consecutive failures before circuit opens. Default 5. */
|
|
15
|
+
circuitFailureThreshold?: number;
|
|
16
|
+
/** Surface retry events (for the CLI display). */
|
|
17
|
+
onRetry?: (info: {
|
|
18
|
+
provider: string;
|
|
19
|
+
attempt: number;
|
|
20
|
+
delayMs: number;
|
|
21
|
+
error: ApiError;
|
|
22
|
+
}) => void;
|
|
23
|
+
/** Surface circuit-breaker state changes. */
|
|
24
|
+
onCircuitChange?: (provider: string, state: 'closed' | 'open' | 'half-open') => void;
|
|
25
|
+
/** Surface rate-limit waits (acquire returned > 0ms). */
|
|
26
|
+
onRateLimitWait?: (provider: string, waitMs: number) => void;
|
|
27
|
+
/** Sleep function for testing. */
|
|
28
|
+
sleep?: (ms: number) => Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Wrap a provider with rate limiting, circuit breaking, and retries.
|
|
32
|
+
* The wrapper itself implements LLMProvider, so the agent loop doesn't
|
|
33
|
+
* need to know whether it's wrapped.
|
|
34
|
+
*/
|
|
35
|
+
export declare class ResilientProvider implements LLMProvider {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly model: string;
|
|
38
|
+
readonly supportsTools: boolean;
|
|
39
|
+
private readonly inner;
|
|
40
|
+
private readonly rpmLimiter;
|
|
41
|
+
private readonly tpm;
|
|
42
|
+
private readonly breaker;
|
|
43
|
+
private readonly opts;
|
|
44
|
+
/** True once we've observed the provider work end-to-end. Used to gate TPM-based throttling. */
|
|
45
|
+
private tpmObserved;
|
|
46
|
+
constructor(inner: LLMProvider, opts?: ResilientOptions);
|
|
47
|
+
/** Non-streaming completion. */
|
|
48
|
+
complete(system: string, history: HistoryMessage[], tools: ToolDefinition[]): Promise<LLMResponse>;
|
|
49
|
+
/**
|
|
50
|
+
* Streaming completion. The wrap covers the `createStream` call (not iteration),
|
|
51
|
+
* so a transient connection error retries the whole stream. Mid-stream errors
|
|
52
|
+
* (after the first chunk) are NOT retried — we'd lose partial output.
|
|
53
|
+
*/
|
|
54
|
+
stream(system: string, history: HistoryMessage[], tools: ToolDefinition[]): AsyncGenerator<StreamChunk>;
|
|
55
|
+
private firstChunkOrThrow;
|
|
56
|
+
/** Acquire rate-limit + circuit slot, then call `fn` under retry. */
|
|
57
|
+
private runResilient;
|
|
58
|
+
private recordUsage;
|
|
59
|
+
/** TPM helper used by the Google provider to gate heavy requests. */
|
|
60
|
+
tpmHasRoomFor(n: number): boolean;
|
|
61
|
+
/** Force-open the circuit (e.g. when manually disabling a provider). */
|
|
62
|
+
trip(reason: string): void;
|
|
63
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResilientProvider = void 0;
|
|
4
|
+
const retry_js_1 = require("../util/retry.js");
|
|
5
|
+
const rate_limiter_js_1 = require("../util/rate-limiter.js");
|
|
6
|
+
const circuit_breaker_js_1 = require("../util/circuit-breaker.js");
|
|
7
|
+
const errors_js_1 = require("../util/errors.js");
|
|
8
|
+
/**
|
|
9
|
+
* Wrap a provider with rate limiting, circuit breaking, and retries.
|
|
10
|
+
* The wrapper itself implements LLMProvider, so the agent loop doesn't
|
|
11
|
+
* need to know whether it's wrapped.
|
|
12
|
+
*/
|
|
13
|
+
class ResilientProvider {
|
|
14
|
+
name;
|
|
15
|
+
model;
|
|
16
|
+
supportsTools;
|
|
17
|
+
inner;
|
|
18
|
+
rpmLimiter;
|
|
19
|
+
tpm;
|
|
20
|
+
breaker;
|
|
21
|
+
opts;
|
|
22
|
+
/** True once we've observed the provider work end-to-end. Used to gate TPM-based throttling. */
|
|
23
|
+
tpmObserved = false;
|
|
24
|
+
constructor(inner, opts = {}) {
|
|
25
|
+
this.inner = inner;
|
|
26
|
+
this.name = inner.name;
|
|
27
|
+
this.model = inner.model;
|
|
28
|
+
this.supportsTools = inner.supportsTools;
|
|
29
|
+
this.opts = opts;
|
|
30
|
+
const rpm = opts.rpm ?? 0;
|
|
31
|
+
this.rpmLimiter = new rate_limiter_js_1.RateLimiter({
|
|
32
|
+
capacity: opts.burst ?? Math.max(1, Math.ceil(rpm / 6)),
|
|
33
|
+
refillPerMs: rpm > 0 ? rpm / 60_000 : Number.MAX_SAFE_INTEGER,
|
|
34
|
+
sleep: opts.sleep,
|
|
35
|
+
});
|
|
36
|
+
this.tpm = opts.tpm && opts.tpm > 0 ? new rate_limiter_js_1.TpmTracker(opts.tpm) : null;
|
|
37
|
+
this.breaker = new circuit_breaker_js_1.CircuitBreaker({
|
|
38
|
+
failureThreshold: opts.circuitFailureThreshold ?? 5,
|
|
39
|
+
cooldownMs: opts.circuitCooldownMs ?? 30_000,
|
|
40
|
+
sleep: opts.sleep,
|
|
41
|
+
onStateChange: (state) => opts.onCircuitChange?.(this.inner.name, state),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Non-streaming completion. */
|
|
45
|
+
async complete(system, history, tools) {
|
|
46
|
+
return this.runResilient(async () => {
|
|
47
|
+
const result = await this.inner.complete(system, history, tools);
|
|
48
|
+
this.recordUsage(result.usage);
|
|
49
|
+
return result;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Streaming completion. The wrap covers the `createStream` call (not iteration),
|
|
54
|
+
* so a transient connection error retries the whole stream. Mid-stream errors
|
|
55
|
+
* (after the first chunk) are NOT retried — we'd lose partial output.
|
|
56
|
+
*/
|
|
57
|
+
async *stream(system, history, tools) {
|
|
58
|
+
// Collect chunks from the inner stream. Retry covers the call to obtain
|
|
59
|
+
// the generator and any error before the first yield.
|
|
60
|
+
const firstIterResult = await this.runResilient(async () => {
|
|
61
|
+
return await this.firstChunkOrThrow(this.inner.stream(system, history, tools));
|
|
62
|
+
});
|
|
63
|
+
// firstIterResult is either { firstChunk, generator } or a thrown error.
|
|
64
|
+
// After we have the first chunk, any further iteration errors propagate to the caller.
|
|
65
|
+
let gen;
|
|
66
|
+
let first;
|
|
67
|
+
if (firstIterResult.kind === 'done') {
|
|
68
|
+
// Inner stream finished without yielding anything — emit a synthetic done if needed
|
|
69
|
+
yield firstIterResult.final;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
gen = firstIterResult.gen;
|
|
73
|
+
first = firstIterResult.first;
|
|
74
|
+
yield first;
|
|
75
|
+
try {
|
|
76
|
+
for await (const chunk of gen) {
|
|
77
|
+
if (chunk.type === 'done') {
|
|
78
|
+
this.recordUsage(chunk.response.usage);
|
|
79
|
+
}
|
|
80
|
+
yield chunk;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
// Mid-stream error — wrap so the caller can see the cause, but do not retry
|
|
85
|
+
throw (0, errors_js_1.normaliseError)(e, this.inner.name);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async firstChunkOrThrow(gen) {
|
|
89
|
+
const it = gen[Symbol.asyncIterator]();
|
|
90
|
+
try {
|
|
91
|
+
const first = await it.next();
|
|
92
|
+
if (first.done) {
|
|
93
|
+
// Inner stream finished without yielding — call finalMessage equivalent?
|
|
94
|
+
// This shouldn't happen for our providers, but guard anyway.
|
|
95
|
+
return { kind: 'done', final: { type: 'done', response: { text: '', toolCalls: [], stopReason: 'done' } } };
|
|
96
|
+
}
|
|
97
|
+
return { kind: 'streaming', gen: gen, first: first.value };
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
// Re-throw so retry layer sees it
|
|
101
|
+
throw e;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Acquire rate-limit + circuit slot, then call `fn` under retry. */
|
|
105
|
+
async runResilient(fn) {
|
|
106
|
+
// 1. Wait for rate-limit token
|
|
107
|
+
const waitMs = await this.rpmLimiter.acquire(1);
|
|
108
|
+
if (waitMs > 0)
|
|
109
|
+
this.opts.onRateLimitWait?.(this.inner.name, waitMs);
|
|
110
|
+
// 2. Run under circuit breaker + retry
|
|
111
|
+
return await this.breaker.call(async () => {
|
|
112
|
+
return await (0, retry_js_1.withRetry)(fn, {
|
|
113
|
+
maxAttempts: this.opts.maxRetries ?? 5,
|
|
114
|
+
baseDelayMs: 1000,
|
|
115
|
+
maxDelayMs: 60_000,
|
|
116
|
+
sleep: this.opts.sleep,
|
|
117
|
+
onRetry: ({ attempt, delayMs, error }) => {
|
|
118
|
+
this.opts.onRetry?.({ provider: this.inner.name, attempt, delayMs, error });
|
|
119
|
+
// When a request was throttled, we also know its token cost is
|
|
120
|
+
// bounded — give the RPM/TPM budget a chance to recover.
|
|
121
|
+
if (error.retryAfterMs && this.tpm && error.tokens) {
|
|
122
|
+
this.tpm.record(error.tokens.input + error.tokens.output);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
recordUsage(usage) {
|
|
129
|
+
if (!usage)
|
|
130
|
+
return;
|
|
131
|
+
this.tpmObserved = true;
|
|
132
|
+
if (this.tpm)
|
|
133
|
+
this.tpm.record(usage.inputTokens + usage.outputTokens);
|
|
134
|
+
}
|
|
135
|
+
/** TPM helper used by the Google provider to gate heavy requests. */
|
|
136
|
+
tpmHasRoomFor(n) {
|
|
137
|
+
return this.tpm ? this.tpm.hasRoomFor(n) : true;
|
|
138
|
+
}
|
|
139
|
+
/** Force-open the circuit (e.g. when manually disabling a provider). */
|
|
140
|
+
trip(reason) {
|
|
141
|
+
this.breaker.call(async () => { throw new Error(reason); }).catch(() => { });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.ResilientProvider = ResilientProvider;
|
|
145
|
+
//# sourceMappingURL=resilient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilient.js","sourceRoot":"","sources":["../../src/providers/resilient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface ToolDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
parameters: {
|
|
5
|
+
type: 'object';
|
|
6
|
+
properties: Record<string, JSONSchemaProperty>;
|
|
7
|
+
required?: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface JSONSchemaProperty {
|
|
11
|
+
type: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
enum?: string[];
|
|
14
|
+
items?: JSONSchemaProperty;
|
|
15
|
+
default?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolCall {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
input: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface ToolResult {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
content: string;
|
|
26
|
+
isError?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type HistoryMessage = {
|
|
29
|
+
role: 'user';
|
|
30
|
+
content: string;
|
|
31
|
+
} | {
|
|
32
|
+
role: 'assistant';
|
|
33
|
+
content: string;
|
|
34
|
+
toolCalls?: ToolCall[];
|
|
35
|
+
} | {
|
|
36
|
+
role: 'tool_result';
|
|
37
|
+
results: ToolResult[];
|
|
38
|
+
};
|
|
39
|
+
export interface LLMResponse {
|
|
40
|
+
text: string;
|
|
41
|
+
toolCalls: ToolCall[];
|
|
42
|
+
stopReason: 'done' | 'tools' | 'limit';
|
|
43
|
+
usage?: {
|
|
44
|
+
inputTokens: number;
|
|
45
|
+
outputTokens: number;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export type StreamChunk = {
|
|
49
|
+
type: 'text';
|
|
50
|
+
text: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: 'tool_start';
|
|
53
|
+
name: string;
|
|
54
|
+
id: string;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'tool_input';
|
|
57
|
+
id: string;
|
|
58
|
+
partial: string;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'tool_end';
|
|
61
|
+
call: ToolCall;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'done';
|
|
64
|
+
response: LLMResponse;
|
|
65
|
+
};
|
|
66
|
+
export interface LLMProvider {
|
|
67
|
+
/** Provider name for display (e.g. "Anthropic", "OpenAI") */
|
|
68
|
+
name: string;
|
|
69
|
+
/** Model identifier being used */
|
|
70
|
+
model: string;
|
|
71
|
+
/** One-shot completion (no streaming) */
|
|
72
|
+
complete(system: string, history: HistoryMessage[], tools: ToolDefinition[]): Promise<LLMResponse>;
|
|
73
|
+
/** Streaming completion — yields chunks as the model generates */
|
|
74
|
+
stream(system: string, history: HistoryMessage[], tools: ToolDefinition[]): AsyncGenerator<StreamChunk>;
|
|
75
|
+
/** Whether this provider supports tool use */
|
|
76
|
+
supportsTools: boolean;
|
|
77
|
+
}
|
|
78
|
+
export interface ProviderConfig {
|
|
79
|
+
model: string;
|
|
80
|
+
apiKey?: string;
|
|
81
|
+
baseUrl?: string;
|
|
82
|
+
maxTokens?: number;
|
|
83
|
+
temperature?: number;
|
|
84
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// Tool definitions (provider-agnostic JSON Schema)
|
|
4
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,gFAAgF"}
|