@open-multi-agent/core 1.4.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 +373 -0
- package/dist/agent/agent.d.ts +153 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +559 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/loop-detector.d.ts +39 -0
- package/dist/agent/loop-detector.d.ts.map +1 -0
- package/dist/agent/loop-detector.js +122 -0
- package/dist/agent/loop-detector.js.map +1 -0
- package/dist/agent/pool.d.ts +158 -0
- package/dist/agent/pool.d.ts.map +1 -0
- package/dist/agent/pool.js +320 -0
- package/dist/agent/pool.js.map +1 -0
- package/dist/agent/runner.d.ts +242 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +943 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/structured-output.d.ts +33 -0
- package/dist/agent/structured-output.d.ts.map +1 -0
- package/dist/agent/structured-output.js +116 -0
- package/dist/agent/structured-output.js.map +1 -0
- package/dist/cli/oma.d.ts +30 -0
- package/dist/cli/oma.d.ts.map +1 -0
- package/dist/cli/oma.js +433 -0
- package/dist/cli/oma.js.map +1 -0
- package/dist/dashboard/layout-tasks.d.ts +23 -0
- package/dist/dashboard/layout-tasks.d.ts.map +1 -0
- package/dist/dashboard/layout-tasks.js +79 -0
- package/dist/dashboard/layout-tasks.js.map +1 -0
- package/dist/dashboard/render-team-run-dashboard.d.ts +11 -0
- package/dist/dashboard/render-team-run-dashboard.d.ts.map +1 -0
- package/dist/dashboard/render-team-run-dashboard.js +456 -0
- package/dist/dashboard/render-team-run-dashboard.js.map +1 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/adapter.d.ts +54 -0
- package/dist/llm/adapter.d.ts.map +1 -0
- package/dist/llm/adapter.js +101 -0
- package/dist/llm/adapter.js.map +1 -0
- package/dist/llm/anthropic.d.ts +57 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +432 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/azure-openai.d.ts +74 -0
- package/dist/llm/azure-openai.d.ts.map +1 -0
- package/dist/llm/azure-openai.js +267 -0
- package/dist/llm/azure-openai.js.map +1 -0
- package/dist/llm/bedrock.d.ts +41 -0
- package/dist/llm/bedrock.d.ts.map +1 -0
- package/dist/llm/bedrock.js +345 -0
- package/dist/llm/bedrock.js.map +1 -0
- package/dist/llm/copilot.d.ts +92 -0
- package/dist/llm/copilot.d.ts.map +1 -0
- package/dist/llm/copilot.js +433 -0
- package/dist/llm/copilot.js.map +1 -0
- package/dist/llm/deepseek.d.ts +21 -0
- package/dist/llm/deepseek.d.ts.map +1 -0
- package/dist/llm/deepseek.js +24 -0
- package/dist/llm/deepseek.js.map +1 -0
- package/dist/llm/gemini.d.ts +65 -0
- package/dist/llm/gemini.d.ts.map +1 -0
- package/dist/llm/gemini.js +427 -0
- package/dist/llm/gemini.js.map +1 -0
- package/dist/llm/grok.d.ts +21 -0
- package/dist/llm/grok.d.ts.map +1 -0
- package/dist/llm/grok.js +24 -0
- package/dist/llm/grok.js.map +1 -0
- package/dist/llm/minimax.d.ts +21 -0
- package/dist/llm/minimax.d.ts.map +1 -0
- package/dist/llm/minimax.js +24 -0
- package/dist/llm/minimax.js.map +1 -0
- package/dist/llm/openai-common.d.ts +65 -0
- package/dist/llm/openai-common.d.ts.map +1 -0
- package/dist/llm/openai-common.js +286 -0
- package/dist/llm/openai-common.js.map +1 -0
- package/dist/llm/openai.d.ts +63 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +256 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/qiniu.d.ts +21 -0
- package/dist/llm/qiniu.d.ts.map +1 -0
- package/dist/llm/qiniu.js +24 -0
- package/dist/llm/qiniu.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +2 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory/shared.d.ts +162 -0
- package/dist/memory/shared.d.ts.map +1 -0
- package/dist/memory/shared.js +294 -0
- package/dist/memory/shared.js.map +1 -0
- package/dist/memory/store.d.ts +72 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +121 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +245 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +1400 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +112 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +256 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/task/queue.d.ts +191 -0
- package/dist/task/queue.d.ts.map +1 -0
- package/dist/task/queue.js +408 -0
- package/dist/task/queue.js.map +1 -0
- package/dist/task/task.d.ts +90 -0
- package/dist/task/task.d.ts.map +1 -0
- package/dist/task/task.js +206 -0
- package/dist/task/task.js.map +1 -0
- package/dist/team/messaging.d.ts +106 -0
- package/dist/team/messaging.d.ts.map +1 -0
- package/dist/team/messaging.js +183 -0
- package/dist/team/messaging.js.map +1 -0
- package/dist/team/team.d.ts +141 -0
- package/dist/team/team.d.ts.map +1 -0
- package/dist/team/team.js +293 -0
- package/dist/team/team.js.map +1 -0
- package/dist/tool/built-in/bash.d.ts +12 -0
- package/dist/tool/built-in/bash.d.ts.map +1 -0
- package/dist/tool/built-in/bash.js +133 -0
- package/dist/tool/built-in/bash.js.map +1 -0
- package/dist/tool/built-in/delegate.d.ts +29 -0
- package/dist/tool/built-in/delegate.d.ts.map +1 -0
- package/dist/tool/built-in/delegate.js +92 -0
- package/dist/tool/built-in/delegate.js.map +1 -0
- package/dist/tool/built-in/file-edit.d.ts +14 -0
- package/dist/tool/built-in/file-edit.d.ts.map +1 -0
- package/dist/tool/built-in/file-edit.js +130 -0
- package/dist/tool/built-in/file-edit.js.map +1 -0
- package/dist/tool/built-in/file-read.d.ts +12 -0
- package/dist/tool/built-in/file-read.d.ts.map +1 -0
- package/dist/tool/built-in/file-read.js +82 -0
- package/dist/tool/built-in/file-read.js.map +1 -0
- package/dist/tool/built-in/file-write.d.ts +11 -0
- package/dist/tool/built-in/file-write.d.ts.map +1 -0
- package/dist/tool/built-in/file-write.js +70 -0
- package/dist/tool/built-in/file-write.js.map +1 -0
- package/dist/tool/built-in/fs-walk.d.ts +23 -0
- package/dist/tool/built-in/fs-walk.d.ts.map +1 -0
- package/dist/tool/built-in/fs-walk.js +78 -0
- package/dist/tool/built-in/fs-walk.js.map +1 -0
- package/dist/tool/built-in/glob.d.ts +12 -0
- package/dist/tool/built-in/glob.d.ts.map +1 -0
- package/dist/tool/built-in/glob.js +82 -0
- package/dist/tool/built-in/glob.js.map +1 -0
- package/dist/tool/built-in/grep.d.ts +15 -0
- package/dist/tool/built-in/grep.d.ts.map +1 -0
- package/dist/tool/built-in/grep.js +218 -0
- package/dist/tool/built-in/grep.js.map +1 -0
- package/dist/tool/built-in/index.d.ts +48 -0
- package/dist/tool/built-in/index.d.ts.map +1 -0
- package/dist/tool/built-in/index.js +56 -0
- package/dist/tool/built-in/index.js.map +1 -0
- package/dist/tool/executor.d.ts +100 -0
- package/dist/tool/executor.d.ts.map +1 -0
- package/dist/tool/executor.js +184 -0
- package/dist/tool/executor.js.map +1 -0
- package/dist/tool/framework.d.ts +167 -0
- package/dist/tool/framework.d.ts.map +1 -0
- package/dist/tool/framework.js +402 -0
- package/dist/tool/framework.js.map +1 -0
- package/dist/tool/mcp.d.ts +31 -0
- package/dist/tool/mcp.d.ts.map +1 -0
- package/dist/tool/mcp.js +175 -0
- package/dist/tool/mcp.js.map +1 -0
- package/dist/tool/text-tool-extractor.d.ts +32 -0
- package/dist/tool/text-tool-extractor.d.ts.map +1 -0
- package/dist/tool/text-tool-extractor.js +195 -0
- package/dist/tool/text-tool-extractor.js.map +1 -0
- package/dist/types.d.ts +916 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/keywords.d.ts +18 -0
- package/dist/utils/keywords.d.ts.map +1 -0
- package/dist/utils/keywords.js +32 -0
- package/dist/utils/keywords.js.map +1 -0
- package/dist/utils/semaphore.d.ts +49 -0
- package/dist/utils/semaphore.d.ts.map +1 -0
- package/dist/utils/semaphore.js +89 -0
- package/dist/utils/semaphore.js.map +1 -0
- package/dist/utils/tokens.d.ts +7 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +30 -0
- package/dist/utils/tokens.js.map +1 -0
- package/dist/utils/trace.d.ts +12 -0
- package/dist/utils/trace.d.ts.map +1 -0
- package/dist/utils/trace.js +30 -0
- package/dist/utils/trace.js.map +1 -0
- package/docs/DECISIONS.md +49 -0
- package/docs/cli.md +265 -0
- package/docs/context-management.md +24 -0
- package/docs/featured-partner.md +28 -0
- package/docs/observability.md +56 -0
- package/docs/providers.md +78 -0
- package/docs/shared-memory.md +27 -0
- package/docs/tool-configuration.md +152 -0
- package/package.json +96 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview OpenAI adapter implementing {@link LLMAdapter}.
|
|
3
|
+
*
|
|
4
|
+
* Converts between the framework's internal {@link ContentBlock} types and the
|
|
5
|
+
* OpenAI Chat Completions wire format. Key mapping decisions:
|
|
6
|
+
*
|
|
7
|
+
* - Framework `tool_use` blocks in assistant messages → OpenAI `tool_calls`
|
|
8
|
+
* - Framework `tool_result` blocks in user messages → OpenAI `tool` role messages
|
|
9
|
+
* - Framework `image` blocks in user messages → OpenAI image content parts
|
|
10
|
+
* - System prompt in {@link LLMChatOptions} → prepended `system` message
|
|
11
|
+
*
|
|
12
|
+
* Because OpenAI and Anthropic use fundamentally different role-based structures
|
|
13
|
+
* for tool calling (Anthropic embeds tool results in user-role content arrays;
|
|
14
|
+
* OpenAI uses a dedicated `tool` role), the conversion necessarily splits
|
|
15
|
+
* `tool_result` blocks out into separate top-level messages.
|
|
16
|
+
*
|
|
17
|
+
* API key resolution order:
|
|
18
|
+
* 1. `apiKey` constructor argument
|
|
19
|
+
* 2. `OPENAI_API_KEY` environment variable
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { OpenAIAdapter } from './openai.js'
|
|
24
|
+
*
|
|
25
|
+
* const adapter = new OpenAIAdapter()
|
|
26
|
+
* const response = await adapter.chat(messages, {
|
|
27
|
+
* model: 'gpt-5.4',
|
|
28
|
+
* maxTokens: 1024,
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import OpenAI from 'openai';
|
|
33
|
+
import { toOpenAITool, fromOpenAICompletion, normalizeFinishReason, buildOpenAIMessageList, getOpenAIReasoningText, } from './openai-common.js';
|
|
34
|
+
import { extractToolCallsFromText } from '../tool/text-tool-extractor.js';
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Adapter implementation
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* LLM adapter backed by the OpenAI Chat Completions API.
|
|
40
|
+
*
|
|
41
|
+
* Thread-safe — a single instance may be shared across concurrent agent runs.
|
|
42
|
+
*/
|
|
43
|
+
export class OpenAIAdapter {
|
|
44
|
+
name = 'openai';
|
|
45
|
+
#client;
|
|
46
|
+
constructor(apiKey, baseURL) {
|
|
47
|
+
this.#client = new OpenAI({
|
|
48
|
+
apiKey: apiKey ?? process.env['OPENAI_API_KEY'],
|
|
49
|
+
baseURL,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
// chat()
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Send a synchronous (non-streaming) chat request and return the complete
|
|
57
|
+
* {@link LLMResponse}.
|
|
58
|
+
*
|
|
59
|
+
* Throws an `OpenAI.APIError` on non-2xx responses. Callers should catch and
|
|
60
|
+
* handle these (e.g. rate limits, context length exceeded).
|
|
61
|
+
*/
|
|
62
|
+
async chat(messages, options) {
|
|
63
|
+
const openAIMessages = buildOpenAIMessageList(messages, options.systemPrompt);
|
|
64
|
+
const completion = await this.#client.chat.completions.create({
|
|
65
|
+
// Sampling params first so extraBody can override them. Structural
|
|
66
|
+
// fields (model/messages/tools/stream) come after extraBody so users
|
|
67
|
+
// cannot accidentally clobber them via extraBody.
|
|
68
|
+
max_tokens: options.maxTokens,
|
|
69
|
+
temperature: options.temperature,
|
|
70
|
+
frequency_penalty: options.frequencyPenalty,
|
|
71
|
+
presence_penalty: options.presencePenalty,
|
|
72
|
+
top_p: options.topP,
|
|
73
|
+
top_k: options.topK,
|
|
74
|
+
min_p: options.minP,
|
|
75
|
+
parallel_tool_calls: options.parallelToolCalls,
|
|
76
|
+
reasoning_effort: options.thinking?.effort,
|
|
77
|
+
...options.extraBody,
|
|
78
|
+
model: options.model,
|
|
79
|
+
messages: openAIMessages,
|
|
80
|
+
tools: options.tools ? options.tools.map(toOpenAITool) : undefined,
|
|
81
|
+
stream: false,
|
|
82
|
+
// Cast covers `top_k` / `min_p` and arbitrary `extraBody` keys,
|
|
83
|
+
// which local OpenAI-compatible servers (vLLM, llama-server) accept
|
|
84
|
+
// but the upstream SDK type does not declare.
|
|
85
|
+
}, {
|
|
86
|
+
signal: options.abortSignal,
|
|
87
|
+
});
|
|
88
|
+
const toolNames = options.tools?.map(t => t.name);
|
|
89
|
+
return fromOpenAICompletion(completion, toolNames);
|
|
90
|
+
}
|
|
91
|
+
// -------------------------------------------------------------------------
|
|
92
|
+
// stream()
|
|
93
|
+
// -------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Send a streaming chat request and yield {@link StreamEvent}s incrementally.
|
|
96
|
+
*
|
|
97
|
+
* Sequence guarantees match {@link AnthropicAdapter.stream}:
|
|
98
|
+
* - Zero or more `text` events
|
|
99
|
+
* - Zero or more `reasoning` events
|
|
100
|
+
* - Zero or more `tool_use` events (emitted once per tool call, after
|
|
101
|
+
* arguments have been fully assembled)
|
|
102
|
+
* - Exactly one terminal event: `done` or `error`
|
|
103
|
+
*/
|
|
104
|
+
async *stream(messages, options) {
|
|
105
|
+
const openAIMessages = buildOpenAIMessageList(messages, options.systemPrompt);
|
|
106
|
+
// We request usage in the final chunk so we can include it in the `done` event.
|
|
107
|
+
const streamResponse = await this.#client.chat.completions.create({
|
|
108
|
+
// See chat() above for the rationale behind this field ordering.
|
|
109
|
+
max_tokens: options.maxTokens,
|
|
110
|
+
temperature: options.temperature,
|
|
111
|
+
frequency_penalty: options.frequencyPenalty,
|
|
112
|
+
presence_penalty: options.presencePenalty,
|
|
113
|
+
top_p: options.topP,
|
|
114
|
+
top_k: options.topK,
|
|
115
|
+
min_p: options.minP,
|
|
116
|
+
parallel_tool_calls: options.parallelToolCalls,
|
|
117
|
+
reasoning_effort: options.thinking?.effort,
|
|
118
|
+
...options.extraBody,
|
|
119
|
+
model: options.model,
|
|
120
|
+
messages: openAIMessages,
|
|
121
|
+
tools: options.tools ? options.tools.map(toOpenAITool) : undefined,
|
|
122
|
+
stream: true,
|
|
123
|
+
stream_options: { include_usage: true },
|
|
124
|
+
}, {
|
|
125
|
+
signal: options.abortSignal,
|
|
126
|
+
});
|
|
127
|
+
// Accumulate state across chunks.
|
|
128
|
+
let completionId = '';
|
|
129
|
+
let completionModel = '';
|
|
130
|
+
let finalFinishReason = 'stop';
|
|
131
|
+
let inputTokens = 0;
|
|
132
|
+
let outputTokens = 0;
|
|
133
|
+
// tool_calls are streamed piecemeal; key = tool call index
|
|
134
|
+
const toolCallBuffers = new Map();
|
|
135
|
+
// Full text accumulator for the `done` response.
|
|
136
|
+
let fullReasoning = '';
|
|
137
|
+
let fullText = '';
|
|
138
|
+
try {
|
|
139
|
+
for await (const chunk of streamResponse) {
|
|
140
|
+
completionId = chunk.id;
|
|
141
|
+
completionModel = chunk.model;
|
|
142
|
+
// Usage is only populated in the final chunk when stream_options.include_usage is set.
|
|
143
|
+
if (chunk.usage !== null && chunk.usage !== undefined) {
|
|
144
|
+
inputTokens = chunk.usage.prompt_tokens;
|
|
145
|
+
outputTokens = chunk.usage.completion_tokens;
|
|
146
|
+
}
|
|
147
|
+
const choice = chunk.choices[0];
|
|
148
|
+
if (choice === undefined)
|
|
149
|
+
continue;
|
|
150
|
+
const delta = choice.delta;
|
|
151
|
+
// --- text delta ---
|
|
152
|
+
if (delta.content !== null && delta.content !== undefined) {
|
|
153
|
+
fullText += delta.content;
|
|
154
|
+
const textEvent = { type: 'text', data: delta.content };
|
|
155
|
+
yield textEvent;
|
|
156
|
+
}
|
|
157
|
+
// --- reasoning delta ---
|
|
158
|
+
const reasoningDelta = getOpenAIReasoningText(delta);
|
|
159
|
+
if (reasoningDelta.length > 0) {
|
|
160
|
+
fullReasoning += reasoningDelta;
|
|
161
|
+
const reasoningEvent = { type: 'reasoning', data: reasoningDelta };
|
|
162
|
+
yield reasoningEvent;
|
|
163
|
+
}
|
|
164
|
+
// --- tool call delta ---
|
|
165
|
+
for (const toolCallDelta of delta.tool_calls ?? []) {
|
|
166
|
+
const idx = toolCallDelta.index;
|
|
167
|
+
if (!toolCallBuffers.has(idx)) {
|
|
168
|
+
toolCallBuffers.set(idx, {
|
|
169
|
+
id: toolCallDelta.id ?? '',
|
|
170
|
+
name: toolCallDelta.function?.name ?? '',
|
|
171
|
+
argsJson: '',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const buf = toolCallBuffers.get(idx);
|
|
175
|
+
// buf is guaranteed to exist: we just set it above.
|
|
176
|
+
if (buf !== undefined) {
|
|
177
|
+
if (toolCallDelta.id)
|
|
178
|
+
buf.id = toolCallDelta.id;
|
|
179
|
+
if (toolCallDelta.function?.name)
|
|
180
|
+
buf.name = toolCallDelta.function.name;
|
|
181
|
+
if (toolCallDelta.function?.arguments) {
|
|
182
|
+
buf.argsJson += toolCallDelta.function.arguments;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (choice.finish_reason !== null && choice.finish_reason !== undefined) {
|
|
187
|
+
finalFinishReason = choice.finish_reason;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Emit accumulated tool_use events after the stream ends.
|
|
191
|
+
const finalToolUseBlocks = [];
|
|
192
|
+
for (const buf of toolCallBuffers.values()) {
|
|
193
|
+
let parsedInput = {};
|
|
194
|
+
try {
|
|
195
|
+
const parsed = JSON.parse(buf.argsJson);
|
|
196
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
197
|
+
parsedInput = parsed;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Malformed JSON — surface as empty object.
|
|
202
|
+
}
|
|
203
|
+
const toolUseBlock = {
|
|
204
|
+
type: 'tool_use',
|
|
205
|
+
id: buf.id,
|
|
206
|
+
name: buf.name,
|
|
207
|
+
input: parsedInput,
|
|
208
|
+
};
|
|
209
|
+
finalToolUseBlocks.push(toolUseBlock);
|
|
210
|
+
const toolUseEvent = { type: 'tool_use', data: toolUseBlock };
|
|
211
|
+
yield toolUseEvent;
|
|
212
|
+
}
|
|
213
|
+
// Build the complete content array for the done response.
|
|
214
|
+
const doneContent = [];
|
|
215
|
+
if (fullReasoning.length > 0) {
|
|
216
|
+
doneContent.push({ type: 'reasoning', text: fullReasoning });
|
|
217
|
+
}
|
|
218
|
+
if (fullText.length > 0) {
|
|
219
|
+
const textBlock = { type: 'text', text: fullText };
|
|
220
|
+
doneContent.push(textBlock);
|
|
221
|
+
}
|
|
222
|
+
doneContent.push(...finalToolUseBlocks);
|
|
223
|
+
// Fallback: extract tool calls from text when streaming produced no
|
|
224
|
+
// native tool_calls (same logic as fromOpenAICompletion).
|
|
225
|
+
if (finalToolUseBlocks.length === 0 && fullText.length > 0 && options.tools) {
|
|
226
|
+
const toolNames = options.tools.map(t => t.name);
|
|
227
|
+
const extracted = extractToolCallsFromText(fullText, toolNames);
|
|
228
|
+
if (extracted.length > 0) {
|
|
229
|
+
doneContent.push(...extracted);
|
|
230
|
+
for (const block of extracted) {
|
|
231
|
+
yield { type: 'tool_use', data: block };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const hasToolUseBlocks = doneContent.some(b => b.type === 'tool_use');
|
|
236
|
+
const resolvedStopReason = hasToolUseBlocks && finalFinishReason === 'stop'
|
|
237
|
+
? 'tool_use'
|
|
238
|
+
: normalizeFinishReason(finalFinishReason);
|
|
239
|
+
const finalResponse = {
|
|
240
|
+
id: completionId,
|
|
241
|
+
content: doneContent,
|
|
242
|
+
model: completionModel,
|
|
243
|
+
stop_reason: resolvedStopReason,
|
|
244
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
245
|
+
};
|
|
246
|
+
const doneEvent = { type: 'done', data: finalResponse };
|
|
247
|
+
yield doneEvent;
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
251
|
+
const errorEvent = { type: 'error', data: error };
|
|
252
|
+
yield errorEvent;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Qiniu adapter.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around OpenAIAdapter that hard-codes the official Qiniu
|
|
5
|
+
* OpenAI-compatible endpoint and QINIU_API_KEY environment variable fallback.
|
|
6
|
+
*/
|
|
7
|
+
import { OpenAIAdapter } from './openai.js';
|
|
8
|
+
/**
|
|
9
|
+
* LLM adapter for Qiniu models (deepseek-v3 and future models).
|
|
10
|
+
*
|
|
11
|
+
* Thread-safe. Can be shared across agents.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* provider: 'qiniu'
|
|
15
|
+
* model: 'deepseek-v3' (or any model available to your Qiniu API key)
|
|
16
|
+
*/
|
|
17
|
+
export declare class QiniuAdapter extends OpenAIAdapter {
|
|
18
|
+
readonly name = "qiniu";
|
|
19
|
+
constructor(apiKey?: string, baseURL?: string);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=qiniu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qiniu.d.ts","sourceRoot":"","sources":["../../src/llm/qiniu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;;GAQG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C,QAAQ,CAAC,IAAI,WAAU;gBAEX,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAO9C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Qiniu adapter.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around OpenAIAdapter that hard-codes the official Qiniu
|
|
5
|
+
* OpenAI-compatible endpoint and QINIU_API_KEY environment variable fallback.
|
|
6
|
+
*/
|
|
7
|
+
import { OpenAIAdapter } from './openai.js';
|
|
8
|
+
/**
|
|
9
|
+
* LLM adapter for Qiniu models (deepseek-v3 and future models).
|
|
10
|
+
*
|
|
11
|
+
* Thread-safe. Can be shared across agents.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* provider: 'qiniu'
|
|
15
|
+
* model: 'deepseek-v3' (or any model available to your Qiniu API key)
|
|
16
|
+
*/
|
|
17
|
+
export class QiniuAdapter extends OpenAIAdapter {
|
|
18
|
+
name = 'qiniu';
|
|
19
|
+
constructor(apiKey, baseURL) {
|
|
20
|
+
// Allow override of baseURL (for proxies or future changes) but default to official Qiniu endpoint.
|
|
21
|
+
super(apiKey ?? process.env['QINIU_API_KEY'], baseURL ?? 'https://api.qnaigc.com/v1');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=qiniu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qiniu.js","sourceRoot":"","sources":["../../src/llm/qiniu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAa,SAAQ,aAAa;IACpC,IAAI,GAAG,OAAO,CAAA;IAEvB,YAAY,MAAe,EAAE,OAAgB;QAC3C,oGAAoG;QACpG,KAAK,CACH,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EACtC,OAAO,IAAI,2BAA2B,CACvC,CAAA;IACH,CAAC;CACF"}
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/mcp.js
ADDED
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared memory layer for teams of cooperating agents.
|
|
3
|
+
*
|
|
4
|
+
* Each agent writes under its own namespace (`<agentName>/<key>`) so entries
|
|
5
|
+
* remain attributable, while any agent may read any entry. The
|
|
6
|
+
* {@link SharedMemory.getSummary} method produces a human-readable digest
|
|
7
|
+
* suitable for injecting into an agent's context window.
|
|
8
|
+
*/
|
|
9
|
+
import type { MemoryEntry, MemoryStore } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Namespaced shared memory for a team of agents.
|
|
12
|
+
*
|
|
13
|
+
* Writes are namespaced as `<agentName>/<key>` so that entries from different
|
|
14
|
+
* agents never collide and are always attributable. Reads are namespace-aware
|
|
15
|
+
* but also accept fully-qualified keys, making cross-agent reads straightforward.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const mem = new SharedMemory()
|
|
20
|
+
*
|
|
21
|
+
* await mem.write('researcher', 'findings', 'TypeScript 5.5 ships const type params')
|
|
22
|
+
* await mem.write('coder', 'plan', 'Implement feature X using const type params')
|
|
23
|
+
*
|
|
24
|
+
* const entry = await mem.read('researcher/findings')
|
|
25
|
+
* const all = await mem.listByAgent('researcher')
|
|
26
|
+
* const summary = await mem.getSummary()
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class SharedMemory {
|
|
30
|
+
private readonly store;
|
|
31
|
+
/**
|
|
32
|
+
* Monotonic turn counter used to evaluate per-entry `expiresAtTurn`.
|
|
33
|
+
* Advanced explicitly via {@link advanceTurn}; not bound to any specific
|
|
34
|
+
* unit (the orchestrator drives it once per completed task in `runTeam` /
|
|
35
|
+
* `runTasks`).
|
|
36
|
+
*/
|
|
37
|
+
private turnCount;
|
|
38
|
+
/**
|
|
39
|
+
* @param store - Optional custom {@link MemoryStore} backing this shared memory.
|
|
40
|
+
* Defaults to an in-process {@link InMemoryStore}. Custom stores
|
|
41
|
+
* receive namespaced keys (`<agentName>/<key>`) opaque to them.
|
|
42
|
+
* Stores that don't implement {@link MemoryStore.setWithExpiry}
|
|
43
|
+
* still work — `writeExpiring` falls back to plain `set` on
|
|
44
|
+
* them and the entry never expires.
|
|
45
|
+
*
|
|
46
|
+
* @throws {TypeError} when `store` is provided but does not structurally
|
|
47
|
+
* implement {@link MemoryStore} (fails fast on malformed
|
|
48
|
+
* values, e.g. plain objects from untrusted JSON config).
|
|
49
|
+
*/
|
|
50
|
+
constructor(store?: MemoryStore);
|
|
51
|
+
/**
|
|
52
|
+
* Advance the turn counter by one. Entries previously written via
|
|
53
|
+
* {@link writeExpiring} with `ttlTurns: N` expire once the counter reaches
|
|
54
|
+
* `(write-time count) + N`.
|
|
55
|
+
*
|
|
56
|
+
* Called by the orchestrator after each completed task in `runTeam` and
|
|
57
|
+
* `runTasks`. Standalone `runAgent` does not advance the counter — there
|
|
58
|
+
* is no team turn boundary in single-agent runs.
|
|
59
|
+
*/
|
|
60
|
+
advanceTurn(): void;
|
|
61
|
+
/** Current turn count. Useful for tests and observability. */
|
|
62
|
+
getTurnCount(): number;
|
|
63
|
+
/**
|
|
64
|
+
* Write `value` under the namespaced key `<agentName>/<key>`.
|
|
65
|
+
*
|
|
66
|
+
* Metadata is merged with a `{ agent: agentName }` marker so consumers can
|
|
67
|
+
* identify provenance when iterating all entries.
|
|
68
|
+
*
|
|
69
|
+
* @param agentName - The writing agent's name (used as a namespace prefix).
|
|
70
|
+
* @param key - Logical key within the agent's namespace.
|
|
71
|
+
* @param value - String value to store (serialise objects before writing).
|
|
72
|
+
* @param metadata - Optional extra metadata stored alongside the entry.
|
|
73
|
+
*/
|
|
74
|
+
write(agentName: string, key: string, value: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Like {@link write}, but tags the entry with a turn-count expiry so it is
|
|
77
|
+
* automatically dropped from reads once the {@link advanceTurn} counter has
|
|
78
|
+
* advanced `ttlTurns` steps.
|
|
79
|
+
*
|
|
80
|
+
* Backends that don't implement {@link MemoryStore.setWithExpiry} fall back
|
|
81
|
+
* to a plain write — the entry persists indefinitely and `ttlTurns` is
|
|
82
|
+
* effectively ignored. Custom store authors who need TTL must implement
|
|
83
|
+
* the optional method.
|
|
84
|
+
*
|
|
85
|
+
* @param ttlTurns - Number of turns the entry should remain readable for.
|
|
86
|
+
* Must be an integer ≥ 1; throws {@link RangeError}
|
|
87
|
+
* otherwise.
|
|
88
|
+
*
|
|
89
|
+
* @throws {RangeError} when `ttlTurns` is not an integer or is less than 1.
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* In parallel batch execution (`runTasks` / `runTeam` running multiple
|
|
93
|
+
* tasks in one batch) the turn counter advances per *completed* task, not
|
|
94
|
+
* per *invoked* task. So if task A writes a TTL entry while task B is
|
|
95
|
+
* still running, B completing first will advance the counter and may
|
|
96
|
+
* expire A's entry sooner than wall-clock intuition suggests. For
|
|
97
|
+
* cross-task hand-off semantics that need stricter ordering, write the
|
|
98
|
+
* entry without TTL and delete explicitly.
|
|
99
|
+
*/
|
|
100
|
+
writeExpiring(agentName: string, key: string, value: string, ttlTurns: number, metadata?: Record<string, unknown>): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Read an entry by its fully-qualified key (`<agentName>/<key>`).
|
|
103
|
+
*
|
|
104
|
+
* Returns `null` when the key is absent **or** when the entry has expired
|
|
105
|
+
* (per its `expiresAtTurn` against the current turn counter). Expired
|
|
106
|
+
* entries are filtered out but **not** deleted from the underlying store —
|
|
107
|
+
* deletion is left to the store impl (Redis has native TTL, Postgres a
|
|
108
|
+
* cron, etc.). Reading is therefore safe to call from concurrent processes
|
|
109
|
+
* without the risk of stomping on a fresh write to the same key.
|
|
110
|
+
*/
|
|
111
|
+
read(key: string): Promise<MemoryEntry | null>;
|
|
112
|
+
/** Returns every non-expired entry in the shared store, regardless of agent. */
|
|
113
|
+
listAll(): Promise<MemoryEntry[]>;
|
|
114
|
+
/**
|
|
115
|
+
* Returns all non-expired entries written by `agentName` (i.e. those whose
|
|
116
|
+
* key starts with `<agentName>/`).
|
|
117
|
+
*/
|
|
118
|
+
listByAgent(agentName: string): Promise<MemoryEntry[]>;
|
|
119
|
+
/**
|
|
120
|
+
* Produces a human-readable summary of all entries in the store.
|
|
121
|
+
*
|
|
122
|
+
* The output is structured as a markdown-style block, grouped by agent, and
|
|
123
|
+
* is designed to be prepended to an agent's system prompt or injected as a
|
|
124
|
+
* user turn so the agent has context about what its teammates know.
|
|
125
|
+
*
|
|
126
|
+
* Returns an empty string when the store is empty.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```
|
|
130
|
+
* ## Shared Team Memory
|
|
131
|
+
*
|
|
132
|
+
* ### researcher
|
|
133
|
+
* - findings: TypeScript 5.5 ships const type params
|
|
134
|
+
*
|
|
135
|
+
* ### coder
|
|
136
|
+
* - plan: Implement feature X using const type params
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
getSummary(filter?: {
|
|
140
|
+
taskIds?: string[];
|
|
141
|
+
}): Promise<string>;
|
|
142
|
+
/**
|
|
143
|
+
* Returns the underlying {@link MemoryStore} so callers that only need the
|
|
144
|
+
* raw key-value interface can receive a properly typed reference without
|
|
145
|
+
* accessing private fields via bracket notation.
|
|
146
|
+
*/
|
|
147
|
+
getStore(): MemoryStore;
|
|
148
|
+
private static namespaceKey;
|
|
149
|
+
/** True when `entry.expiresAtTurn` is set and has been reached. */
|
|
150
|
+
private isExpired;
|
|
151
|
+
/**
|
|
152
|
+
* Drops expired entries from `entries`. **Does not delete from the
|
|
153
|
+
* underlying store** — that would race with concurrent writers in
|
|
154
|
+
* distributed backends (the entry being deleted may have been
|
|
155
|
+
* overwritten with a fresh value between our read and our delete).
|
|
156
|
+
* Stores that want active cleanup should implement their own TTL sweep
|
|
157
|
+
* (Redis: native EXPIRE; Postgres: a cron). Entries without
|
|
158
|
+
* `expiresAtTurn` are always kept.
|
|
159
|
+
*/
|
|
160
|
+
private filterExpired;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/memory/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA0B3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAI;IAErB;;;;;;;;;;;OAWG;gBACS,KAAK,CAAC,EAAE,WAAW;IAc/B;;;;;;;;OAQG;IACH,WAAW,IAAI,IAAI;IAInB,8DAA8D;IAC9D,YAAY,IAAI,MAAM;IAQtB;;;;;;;;;;OAUG;IACG,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAsBhB;;;;;;;;;OASG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWpD,gFAAgF;IAC1E,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIvC;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAW5D;;;;;;;;;;;;;;;;;;;OAmBG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAiDlE;;;;OAIG;IACH,QAAQ,IAAI,WAAW;IAQvB,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B,mEAAmE;IACnE,OAAO,CAAC,SAAS;IAIjB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;CAGtB"}
|