@strav/brain 1.0.0-alpha.16 → 1.0.0-alpha.18
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/package.json +4 -2
- package/src/agent.ts +34 -5
- package/src/agent_generate_result.ts +2 -0
- package/src/agent_result.ts +7 -0
- package/src/agent_runner.ts +134 -15
- package/src/agent_stream_event.ts +100 -0
- package/src/brain_config.ts +91 -1
- package/src/brain_manager.ts +287 -6
- package/src/brain_provider.ts +25 -1
- package/src/index.ts +37 -2
- package/src/mcp/client.ts +99 -13
- package/src/mcp/index.ts +7 -0
- package/src/mcp/oauth.ts +227 -0
- package/src/mcp/pool.ts +106 -0
- package/src/mcp/resolve_mcp_tools.ts +31 -9
- package/src/mcp_server.ts +16 -0
- package/src/persistence/brain_message.ts +34 -0
- package/src/persistence/brain_message_repository.ts +106 -0
- package/src/persistence/brain_store.ts +166 -0
- package/src/persistence/brain_suspended_run.ts +30 -0
- package/src/persistence/brain_suspended_run_repository.ts +68 -0
- package/src/persistence/brain_thread.ts +30 -0
- package/src/persistence/brain_thread_repository.ts +65 -0
- package/src/persistence/database_brain_store.ts +190 -0
- package/src/persistence/index.ts +48 -0
- package/src/persistence/schema/brain_message_schema.ts +61 -0
- package/src/persistence/schema/brain_suspended_run_schema.ts +58 -0
- package/src/persistence/schema/brain_thread_schema.ts +50 -0
- package/src/persistence/schema/index.ts +3 -0
- package/src/provider.ts +145 -1
- package/src/providers/anthropic_provider.ts +723 -38
- package/src/providers/deepseek_provider.ts +117 -0
- package/src/providers/gemini_provider.ts +625 -33
- package/src/providers/ollama_provider.ts +86 -0
- package/src/providers/openai_compat_provider.ts +616 -0
- package/src/providers/openai_provider.ts +801 -43
- package/src/providers/openai_responses_provider.ts +1015 -0
- package/src/suspended_run.ts +153 -0
- package/src/thread.ts +40 -1
- package/src/tool.ts +7 -0
- package/src/tool_runner.ts +81 -0
- package/src/types.ts +343 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DeepSeekProvider` — `OpenAICompatProvider` pointed at DeepSeek's
|
|
3
|
+
* OpenAI-compatible `/v1/chat/completions` endpoint.
|
|
4
|
+
*
|
|
5
|
+
* Inherits the OpenAI-compat overrides (strip `reasoning_effort`,
|
|
6
|
+
* `json_object`-mode generate with schema-in-system-prompt, throws
|
|
7
|
+
* on combined tools + schema) from the base class. Only adds:
|
|
8
|
+
*
|
|
9
|
+
* - Constructor with DeepSeek defaults — base URL
|
|
10
|
+
* `https://api.deepseek.com/v1`, default model `deepseek-chat`.
|
|
11
|
+
*
|
|
12
|
+
* - `mapUsage` override — DeepSeek reports prompt cache hits on
|
|
13
|
+
* the extension field `prompt_cache_hit_tokens` rather than
|
|
14
|
+
* OpenAI's `prompt_tokens_details.cached_tokens`.
|
|
15
|
+
*
|
|
16
|
+
* `countTokens` not implemented (DeepSeek has no count endpoint).
|
|
17
|
+
* `BrainManager.countTokens` returns `null` when routed here.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type OpenAI from 'openai'
|
|
21
|
+
import { BrainError } from '../brain_error.ts'
|
|
22
|
+
import type { DeepSeekProviderConfig } from '../brain_config.ts'
|
|
23
|
+
import type { ResolveMcpToolsOptions } from '../mcp/resolve_mcp_tools.ts'
|
|
24
|
+
import type {
|
|
25
|
+
AudioSource,
|
|
26
|
+
ChatUsage,
|
|
27
|
+
EmbedOptions,
|
|
28
|
+
EmbedResult,
|
|
29
|
+
TranscribeOptions,
|
|
30
|
+
TranscribeResult,
|
|
31
|
+
} from '../types.ts'
|
|
32
|
+
import { OpenAICompatProvider } from './openai_compat_provider.ts'
|
|
33
|
+
|
|
34
|
+
const DEFAULT_DEEPSEEK_MODEL = 'deepseek-chat'
|
|
35
|
+
const DEFAULT_DEEPSEEK_BASE_URL = 'https://api.deepseek.com/v1'
|
|
36
|
+
|
|
37
|
+
export interface DeepSeekProviderOptions {
|
|
38
|
+
client?: OpenAI
|
|
39
|
+
/**
|
|
40
|
+
* Internal seam — tests inject a stub MCP client factory so MCP
|
|
41
|
+
* tool resolution doesn't dial the network. Real apps leave it
|
|
42
|
+
* unset; the provider uses the default `MCPClient`.
|
|
43
|
+
*/
|
|
44
|
+
mcpClientFactory?: ResolveMcpToolsOptions['clientFactory']
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class DeepSeekProvider extends OpenAICompatProvider {
|
|
48
|
+
constructor(
|
|
49
|
+
name: string,
|
|
50
|
+
config: DeepSeekProviderConfig,
|
|
51
|
+
options: DeepSeekProviderOptions = {},
|
|
52
|
+
) {
|
|
53
|
+
super(
|
|
54
|
+
name,
|
|
55
|
+
{
|
|
56
|
+
driver: 'openai',
|
|
57
|
+
apiKey: config.apiKey,
|
|
58
|
+
baseUrl: config.baseUrl ?? DEFAULT_DEEPSEEK_BASE_URL,
|
|
59
|
+
defaultModel: config.defaultModel ?? DEFAULT_DEEPSEEK_MODEL,
|
|
60
|
+
...(config.defaultMaxTokens !== undefined
|
|
61
|
+
? { defaultMaxTokens: config.defaultMaxTokens }
|
|
62
|
+
: {}),
|
|
63
|
+
},
|
|
64
|
+
options,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* DeepSeek doesn't expose an audio transcription endpoint.
|
|
70
|
+
* Override the inherited `transcribe` (from OpenAIProvider) to
|
|
71
|
+
* throw clearly rather than 404 at the wire.
|
|
72
|
+
*/
|
|
73
|
+
override async transcribe(
|
|
74
|
+
_audio: AudioSource,
|
|
75
|
+
_options?: TranscribeOptions,
|
|
76
|
+
): Promise<TranscribeResult<OpenAI.Audio.TranscriptionCreateResponse>> {
|
|
77
|
+
throw new BrainError(
|
|
78
|
+
"DeepSeekProvider.transcribe: DeepSeek's API does not expose audio transcription. Route transcribe calls to a provider with native support — OpenAI / Ollama / Gemini.",
|
|
79
|
+
{ context: { provider: this.name } },
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* DeepSeek doesn't expose an embeddings endpoint via their
|
|
85
|
+
* OpenAI-compat API. Override the inherited `embed` to throw
|
|
86
|
+
* with a clear message instead of letting the SDK return a
|
|
87
|
+
* confusing 404.
|
|
88
|
+
*/
|
|
89
|
+
override async embed(
|
|
90
|
+
_texts: readonly string[],
|
|
91
|
+
_options?: EmbedOptions,
|
|
92
|
+
): Promise<EmbedResult<OpenAI.CreateEmbeddingResponse>> {
|
|
93
|
+
throw new BrainError(
|
|
94
|
+
`DeepSeekProvider.embed: DeepSeek's API does not expose embeddings. Route embed calls to a provider with native support — OpenAI / Gemini / Ollama.`,
|
|
95
|
+
{ context: { provider: this.name } },
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* DeepSeek reports cache hits on `prompt_cache_hit_tokens`
|
|
101
|
+
* (extension field on their `CompletionUsage`). Read it first,
|
|
102
|
+
* falling back to OpenAI's `prompt_tokens_details.cached_tokens`
|
|
103
|
+
* when present.
|
|
104
|
+
*/
|
|
105
|
+
protected override mapUsage(u: OpenAI.CompletionUsage | undefined): ChatUsage {
|
|
106
|
+
return {
|
|
107
|
+
inputTokens: u?.prompt_tokens ?? 0,
|
|
108
|
+
outputTokens: u?.completion_tokens ?? 0,
|
|
109
|
+
cacheReadTokens:
|
|
110
|
+
((u as unknown as { prompt_cache_hit_tokens?: number } | undefined)
|
|
111
|
+
?.prompt_cache_hit_tokens) ??
|
|
112
|
+
u?.prompt_tokens_details?.cached_tokens ??
|
|
113
|
+
0,
|
|
114
|
+
cacheCreationTokens: 0,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|