@p-sw/brainbox 0.1.0 → 0.1.2-alpha.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/dist/index.js +5319 -0
- package/package.json +10 -4
- package/scripts/smoke_providers.ts +0 -176
- package/src/brain/index.ts +0 -936
- package/src/brain/manager.ts +0 -144
- package/src/brain/memory.ts +0 -99
- package/src/brain/messageHistory.ts +0 -26
- package/src/brain/schedule.ts +0 -11
- package/src/brain/types.ts +0 -26
- package/src/channel/base.ts +0 -527
- package/src/channel/discord.ts +0 -227
- package/src/channel/telegram.ts +0 -150
- package/src/commands/auth.tsx +0 -306
- package/src/commands/brain.ts +0 -119
- package/src/commands/daemon/commands.ts +0 -56
- package/src/commands/daemon/pairingCommand.ts +0 -15
- package/src/commands/daemon/restartCommand.ts +0 -17
- package/src/commands/daemon.ts +0 -168
- package/src/commands/index.ts +0 -16
- package/src/commands/model.tsx +0 -138
- package/src/commands/onboard.tsx +0 -473
- package/src/commands/pairing.ts +0 -32
- package/src/commands/restart.ts +0 -24
- package/src/config/file/auth.ts +0 -105
- package/src/config/file/root.ts +0 -37
- package/src/config/index.ts +0 -21
- package/src/config/loader.ts +0 -115
- package/src/index.ts +0 -61
- package/src/provider/index.ts +0 -122
- package/src/provider/llm.ts +0 -191
- package/src/provider/promptLoader.ts +0 -36
- package/src/provider/providers/302ai.ts +0 -17
- package/src/provider/providers/MiniMax.ts +0 -17
- package/src/provider/providers/anthropic.ts +0 -257
- package/src/provider/providers/azure_cognitive.ts +0 -40
- package/src/provider/providers/azure_openai.ts +0 -49
- package/src/provider/providers/baseten.ts +0 -17
- package/src/provider/providers/bedrock.ts +0 -312
- package/src/provider/providers/cerebras.ts +0 -17
- package/src/provider/providers/cloudflare_gateway.ts +0 -34
- package/src/provider/providers/cloudflare_workers.ts +0 -178
- package/src/provider/providers/copilot.ts +0 -22
- package/src/provider/providers/cortecs.ts +0 -17
- package/src/provider/providers/deepinfra.ts +0 -17
- package/src/provider/providers/deepseek.ts +0 -17
- package/src/provider/providers/digitalocean.ts +0 -17
- package/src/provider/providers/fireworks.ts +0 -17
- package/src/provider/providers/gitlab_duo.ts +0 -184
- package/src/provider/providers/gmi.ts +0 -17
- package/src/provider/providers/groq.ts +0 -17
- package/src/provider/providers/helicone.ts +0 -17
- package/src/provider/providers/huggingface.ts +0 -17
- package/src/provider/providers/ionet.ts +0 -17
- package/src/provider/providers/llamacpp.ts +0 -17
- package/src/provider/providers/llmgateway.ts +0 -17
- package/src/provider/providers/lmstudio.ts +0 -17
- package/src/provider/providers/mistral.ts +0 -17
- package/src/provider/providers/moonshot.ts +0 -17
- package/src/provider/providers/nebius.ts +0 -17
- package/src/provider/providers/nvidia.ts +0 -17
- package/src/provider/providers/ollama.ts +0 -17
- package/src/provider/providers/ollama_cloud.ts +0 -17
- package/src/provider/providers/openai.ts +0 -17
- package/src/provider/providers/openai_compatible.ts +0 -293
- package/src/provider/providers/openrouter.ts +0 -175
- package/src/provider/providers/ovhcloud.ts +0 -17
- package/src/provider/providers/sap_aicore.ts +0 -22
- package/src/provider/providers/scaleway.ts +0 -17
- package/src/provider/providers/snowflake_cortex.ts +0 -207
- package/src/provider/providers/stackit.ts +0 -17
- package/src/provider/providers/together.ts +0 -17
- package/src/provider/providers/venice.ts +0 -17
- package/src/provider/providers/vercel.ts +0 -17
- package/src/provider/providers/vertex.ts +0 -229
- package/src/provider/providers/xai.ts +0 -17
- package/src/provider/providers/zai.ts +0 -17
- package/src/provider/providers/zenmux.ts +0 -17
- package/src/provider/schema.ts +0 -143
- package/src/ui/TextInput.tsx +0 -114
- package/src/utils/daemonClient.ts +0 -85
- package/src/utils/logger.ts +0 -204
- package/tsconfig.json +0 -34
- /package/{prompts → dist/prompts}/daily_schedule.md +0 -0
- /package/{prompts → dist/prompts}/memoir.md +0 -0
- /package/{prompts → dist/prompts}/monthly_schedule.md +0 -0
- /package/{prompts → dist/prompts}/objectifier.md +0 -0
- /package/{prompts → dist/prompts}/persona_base_system_prompt.md +0 -0
- /package/{prompts → dist/prompts}/persona_base_system_prompt_fixed.md +0 -0
- /package/{prompts → dist/prompts}/persona_init.md +0 -0
- /package/{prompts → dist/prompts}/schedule_availability.md +0 -0
- /package/{prompts → dist/prompts}/send_message.md +0 -0
- /package/{prompts → dist/prompts}/start_conversation.md +0 -0
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { logger } from "@/utils/logger";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
LLMExecutor,
|
|
5
|
-
defaultReasoningEffort,
|
|
6
|
-
readAuthString,
|
|
7
|
-
type CallOptions,
|
|
8
|
-
type ChatChoice,
|
|
9
|
-
type ChatFunctionTool,
|
|
10
|
-
type ChatMessages,
|
|
11
|
-
type ChatWithToolsOptions,
|
|
12
|
-
type ToolCall,
|
|
13
|
-
} from "../llm";
|
|
14
|
-
|
|
15
|
-
const CortexAuthSchema = z
|
|
16
|
-
.object({
|
|
17
|
-
account: z.string().optional(),
|
|
18
|
-
})
|
|
19
|
-
.loose();
|
|
20
|
-
|
|
21
|
-
type CortexTool = {
|
|
22
|
-
type: "function";
|
|
23
|
-
function: {
|
|
24
|
-
name: string;
|
|
25
|
-
description?: string;
|
|
26
|
-
parameters?: Record<string, unknown>;
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
type CortexMessageWire =
|
|
31
|
-
| { role: "system" | "user"; content: string }
|
|
32
|
-
| {
|
|
33
|
-
role: "assistant";
|
|
34
|
-
content: string | null;
|
|
35
|
-
tool_calls?: Array<{
|
|
36
|
-
id: string;
|
|
37
|
-
type: "function";
|
|
38
|
-
function: { name: string; arguments: unknown };
|
|
39
|
-
}>;
|
|
40
|
-
}
|
|
41
|
-
| { role: "tool"; content: string; tool_call_id: string };
|
|
42
|
-
|
|
43
|
-
type CortexResponse = {
|
|
44
|
-
choices?: Array<{
|
|
45
|
-
message?: {
|
|
46
|
-
content?: string | null;
|
|
47
|
-
tool_calls?: Array<{
|
|
48
|
-
id: string;
|
|
49
|
-
type: "function";
|
|
50
|
-
function: { name: string; arguments: unknown };
|
|
51
|
-
}>;
|
|
52
|
-
};
|
|
53
|
-
}>;
|
|
54
|
-
message?: string;
|
|
55
|
-
error?: { message?: string };
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
function toCortexMessage(m: ChatMessages): CortexMessageWire {
|
|
59
|
-
if (m.role === "assistant") {
|
|
60
|
-
return {
|
|
61
|
-
role: "assistant",
|
|
62
|
-
content: m.content ?? null,
|
|
63
|
-
tool_calls: m.toolCalls?.map((c) => ({
|
|
64
|
-
id: c.id,
|
|
65
|
-
type: "function",
|
|
66
|
-
function: { name: c.function.name, arguments: c.function.arguments },
|
|
67
|
-
})),
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
if (m.role === "tool") {
|
|
71
|
-
return { role: "tool", content: m.content, tool_call_id: m.toolCallId };
|
|
72
|
-
}
|
|
73
|
-
return { role: m.role, content: m.content };
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function toCortexTool(t: ChatFunctionTool): CortexTool {
|
|
77
|
-
return {
|
|
78
|
-
type: "function",
|
|
79
|
-
function: {
|
|
80
|
-
name: t.name,
|
|
81
|
-
description: t.description,
|
|
82
|
-
parameters: t.parameters ?? { type: "object", properties: {} },
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export class SnowflakeCortexExecutor extends LLMExecutor {
|
|
88
|
-
readonly providerName = "snowflake-cortex";
|
|
89
|
-
readonly models: { conversation: string; identity: string };
|
|
90
|
-
|
|
91
|
-
private readonly apiKey: string;
|
|
92
|
-
private readonly baseURL: string;
|
|
93
|
-
|
|
94
|
-
constructor(opts: {
|
|
95
|
-
apiKey: string;
|
|
96
|
-
conversationModel: string;
|
|
97
|
-
identityModel: string;
|
|
98
|
-
auth?: Record<string, unknown>;
|
|
99
|
-
}) {
|
|
100
|
-
super();
|
|
101
|
-
this.models = {
|
|
102
|
-
conversation: opts.conversationModel,
|
|
103
|
-
identity: opts.identityModel,
|
|
104
|
-
};
|
|
105
|
-
this.apiKey = opts.apiKey;
|
|
106
|
-
const parsed = CortexAuthSchema.safeParse(opts.auth ?? {});
|
|
107
|
-
const extra = parsed.success ? parsed.data : {};
|
|
108
|
-
const account =
|
|
109
|
-
extra.account ??
|
|
110
|
-
readAuthString(opts.auth, "account", "SNOWFLAKE_ACCOUNT") ??
|
|
111
|
-
"";
|
|
112
|
-
this.baseURL = account
|
|
113
|
-
? `https://${account}.snowflakecomputing.com/api/v2/cortex/inference:complete`
|
|
114
|
-
: "https://__account__.snowflakecomputing.com/api/v2/cortex/inference:complete";
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private async send(body: Record<string, unknown>): Promise<CortexResponse> {
|
|
118
|
-
const res = await fetch(this.baseURL, {
|
|
119
|
-
method: "POST",
|
|
120
|
-
headers: {
|
|
121
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
122
|
-
"Content-Type": "application/json",
|
|
123
|
-
},
|
|
124
|
-
body: JSON.stringify(body),
|
|
125
|
-
});
|
|
126
|
-
if (!res.ok) {
|
|
127
|
-
const text = await res.text().catch(() => "");
|
|
128
|
-
throw new Error(
|
|
129
|
-
`snowflake-cortex request failed: ${res.status} ${res.statusText} body=${text.slice(0, 500)}`,
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
return (await res.json()) as CortexResponse;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async call<T>(model: string, options: CallOptions): Promise<T> {
|
|
136
|
-
const jsonMode = "jsonSchemaName" in options;
|
|
137
|
-
const reasoning = defaultReasoningEffort(
|
|
138
|
-
options.reasoningEffort,
|
|
139
|
-
model,
|
|
140
|
-
this.models.identity,
|
|
141
|
-
);
|
|
142
|
-
const log = logger.child("llm:snowflake-cortex");
|
|
143
|
-
log.debug(
|
|
144
|
-
`call: model=${model} jsonSchema=${jsonMode ? options.jsonSchemaName : "-"} msgLen=${options.message.length}`,
|
|
145
|
-
);
|
|
146
|
-
const body: Record<string, unknown> = {
|
|
147
|
-
model,
|
|
148
|
-
messages: [
|
|
149
|
-
{ role: "system", content: options.instruction },
|
|
150
|
-
{ role: "user", content: options.message },
|
|
151
|
-
],
|
|
152
|
-
};
|
|
153
|
-
if (reasoning !== "none") {
|
|
154
|
-
body["reasoning_effort"] = reasoning;
|
|
155
|
-
}
|
|
156
|
-
const data = await this.send(body);
|
|
157
|
-
if (data.error) {
|
|
158
|
-
throw new Error(
|
|
159
|
-
`snowflake-cortex API error: ${data.error.message ?? "unknown"}`,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
const content = data.choices?.[0]?.message?.content ?? data.message ?? "";
|
|
163
|
-
if (!content) {
|
|
164
|
-
throw new Error("Empty response from model");
|
|
165
|
-
}
|
|
166
|
-
return (jsonMode ? JSON.parse(content) : content) as T;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async chatWithTools(
|
|
170
|
-
model: string,
|
|
171
|
-
options: ChatWithToolsOptions,
|
|
172
|
-
): Promise<ChatChoice> {
|
|
173
|
-
const log = logger.child("llm:snowflake-cortex");
|
|
174
|
-
log.debug(
|
|
175
|
-
`chatWithTools: model=${model} msgs=${options.messages.length} tools=${options.tools.length}`,
|
|
176
|
-
);
|
|
177
|
-
const body: Record<string, unknown> = {
|
|
178
|
-
model,
|
|
179
|
-
messages: [
|
|
180
|
-
{ role: "system", content: options.instruction },
|
|
181
|
-
...options.messages.map(toCortexMessage),
|
|
182
|
-
],
|
|
183
|
-
tools: options.tools.map(toCortexTool),
|
|
184
|
-
};
|
|
185
|
-
const data = await this.send(body);
|
|
186
|
-
if (data.error) {
|
|
187
|
-
throw new Error(
|
|
188
|
-
`snowflake-cortex API error: ${data.error.message ?? "unknown"}`,
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
const choice = data.choices?.[0];
|
|
192
|
-
const content = choice?.message?.content ?? data.message ?? "";
|
|
193
|
-
const toolCalls: ToolCall[] | undefined = choice?.message?.tool_calls?.map(
|
|
194
|
-
(c) => ({
|
|
195
|
-
id: c.id,
|
|
196
|
-
function: {
|
|
197
|
-
name: c.function.name,
|
|
198
|
-
arguments:
|
|
199
|
-
typeof c.function.arguments === "string"
|
|
200
|
-
? c.function.arguments
|
|
201
|
-
: JSON.stringify(c.function.arguments ?? {}),
|
|
202
|
-
},
|
|
203
|
-
}),
|
|
204
|
-
);
|
|
205
|
-
return { message: { content: content || undefined, toolCalls } };
|
|
206
|
-
}
|
|
207
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class StackitExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "stackit",
|
|
11
|
-
baseURL: "https://api.openai-compat.openai-stackit.com/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class TogetherExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "together",
|
|
11
|
-
baseURL: "https://api.together.xyz/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class VeniceExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "venice",
|
|
11
|
-
baseURL: "https://api.venice.ai/api/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class VercelExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "vercel",
|
|
11
|
-
baseURL: "https://ai-gateway.vercel.sh/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { logger } from "@/utils/logger";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
LLMExecutor,
|
|
5
|
-
defaultReasoningEffort,
|
|
6
|
-
readAuthString,
|
|
7
|
-
type CallOptions,
|
|
8
|
-
type ChatChoice,
|
|
9
|
-
type ChatFunctionTool,
|
|
10
|
-
type ChatMessages,
|
|
11
|
-
type ChatWithToolsOptions,
|
|
12
|
-
type ToolCall,
|
|
13
|
-
} from "../llm";
|
|
14
|
-
|
|
15
|
-
const VertexAuthSchema = z
|
|
16
|
-
.object({
|
|
17
|
-
project: z.string().optional(),
|
|
18
|
-
region: z.string().optional(),
|
|
19
|
-
})
|
|
20
|
-
.loose();
|
|
21
|
-
|
|
22
|
-
type GeminiPart =
|
|
23
|
-
| { text: string }
|
|
24
|
-
| { functionCall: { name: string; args: Record<string, unknown> } }
|
|
25
|
-
| { functionResponse: { name: string; response: Record<string, unknown> } };
|
|
26
|
-
|
|
27
|
-
type GeminiResponse = {
|
|
28
|
-
candidates?: Array<{
|
|
29
|
-
content?: { parts?: GeminiPart[]; role?: string };
|
|
30
|
-
finishReason?: string;
|
|
31
|
-
}>;
|
|
32
|
-
error?: { message?: string; code?: number };
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
function toGeminiContents(
|
|
36
|
-
messages: ChatMessages[],
|
|
37
|
-
): Array<{ role: string; parts: GeminiPart[] }> {
|
|
38
|
-
const out: Array<{ role: string; parts: GeminiPart[] }> = [];
|
|
39
|
-
for (const m of messages) {
|
|
40
|
-
if (m.role === "system") continue; // system goes into systemInstruction
|
|
41
|
-
if (m.role === "user") {
|
|
42
|
-
out.push({ role: "user", parts: [{ text: m.content }] });
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
if (m.role === "assistant") {
|
|
46
|
-
const parts: GeminiPart[] = [];
|
|
47
|
-
if (m.content) parts.push({ text: m.content });
|
|
48
|
-
if (m.toolCalls) {
|
|
49
|
-
for (const c of m.toolCalls) {
|
|
50
|
-
let args: Record<string, unknown> = {};
|
|
51
|
-
try {
|
|
52
|
-
args = c.function.arguments ? JSON.parse(c.function.arguments) : {};
|
|
53
|
-
} catch {
|
|
54
|
-
args = {};
|
|
55
|
-
}
|
|
56
|
-
parts.push({ functionCall: { name: c.function.name, args } });
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
out.push({ role: "model", parts });
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
if (m.role === "tool") {
|
|
63
|
-
let response: Record<string, unknown> = {};
|
|
64
|
-
try {
|
|
65
|
-
response = JSON.parse(m.content);
|
|
66
|
-
} catch {
|
|
67
|
-
response = { result: m.content };
|
|
68
|
-
}
|
|
69
|
-
// ponytail: We don't track the original tool name on tool messages; the
|
|
70
|
-
// caller names the response. The wire response uses an empty name.
|
|
71
|
-
out.push({
|
|
72
|
-
role: "user",
|
|
73
|
-
parts: [{ functionResponse: { name: "", response } }],
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function toGeminiTool(t: ChatFunctionTool) {
|
|
81
|
-
return {
|
|
82
|
-
functionDeclarations: [
|
|
83
|
-
{
|
|
84
|
-
name: t.name,
|
|
85
|
-
description: t.description,
|
|
86
|
-
parameters: t.parameters ?? { type: "object", properties: {} },
|
|
87
|
-
},
|
|
88
|
-
],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function extractFromGemini(data: GeminiResponse): {
|
|
93
|
-
text: string;
|
|
94
|
-
toolCalls: ToolCall[] | undefined;
|
|
95
|
-
} {
|
|
96
|
-
const parts = data.candidates?.[0]?.content?.parts ?? [];
|
|
97
|
-
let text = "";
|
|
98
|
-
const toolCalls: ToolCall[] = [];
|
|
99
|
-
let idx = 0;
|
|
100
|
-
for (const p of parts) {
|
|
101
|
-
if ("text" in p) text += p.text;
|
|
102
|
-
if ("functionCall" in p) {
|
|
103
|
-
toolCalls.push({
|
|
104
|
-
id: `call_${idx++}`,
|
|
105
|
-
function: {
|
|
106
|
-
name: p.functionCall.name,
|
|
107
|
-
arguments: JSON.stringify(p.functionCall.args ?? {}),
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return { text, toolCalls: toolCalls.length > 0 ? toolCalls : undefined };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export class VertexExecutor extends LLMExecutor {
|
|
116
|
-
readonly providerName = "vertex";
|
|
117
|
-
readonly models: { conversation: string; identity: string };
|
|
118
|
-
|
|
119
|
-
private readonly apiKey: string;
|
|
120
|
-
private readonly project: string;
|
|
121
|
-
private readonly region: string;
|
|
122
|
-
private readonly baseURL: string;
|
|
123
|
-
|
|
124
|
-
constructor(opts: {
|
|
125
|
-
apiKey: string;
|
|
126
|
-
conversationModel: string;
|
|
127
|
-
identityModel: string;
|
|
128
|
-
auth?: Record<string, unknown>;
|
|
129
|
-
}) {
|
|
130
|
-
super();
|
|
131
|
-
this.models = {
|
|
132
|
-
conversation: opts.conversationModel,
|
|
133
|
-
identity: opts.identityModel,
|
|
134
|
-
};
|
|
135
|
-
this.apiKey = opts.apiKey;
|
|
136
|
-
const parsed = VertexAuthSchema.safeParse(opts.auth ?? {});
|
|
137
|
-
const extra = parsed.success ? parsed.data : {};
|
|
138
|
-
this.project =
|
|
139
|
-
extra.project ??
|
|
140
|
-
readAuthString(opts.auth, "project", "GOOGLE_CLOUD_PROJECT") ??
|
|
141
|
-
"";
|
|
142
|
-
this.region =
|
|
143
|
-
extra.region ??
|
|
144
|
-
readAuthString(opts.auth, "region", "GOOGLE_CLOUD_REGION") ??
|
|
145
|
-
"us-central1";
|
|
146
|
-
this.baseURL = this.project
|
|
147
|
-
? `https://${this.region}-aiplatform.googleapis.com/v1/projects/${this.project}/locations/${this.region}/publishers/google/models`
|
|
148
|
-
: "https://us-central1-aiplatform.googleapis.com/v1";
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private async generate(
|
|
152
|
-
model: string,
|
|
153
|
-
body: Record<string, unknown>,
|
|
154
|
-
): Promise<GeminiResponse> {
|
|
155
|
-
const url = `${this.baseURL}/${encodeURIComponent(model)}:generateContent`;
|
|
156
|
-
const res = await fetch(url, {
|
|
157
|
-
method: "POST",
|
|
158
|
-
headers: {
|
|
159
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
160
|
-
"Content-Type": "application/json",
|
|
161
|
-
},
|
|
162
|
-
body: JSON.stringify(body),
|
|
163
|
-
});
|
|
164
|
-
if (!res.ok) {
|
|
165
|
-
const text = await res.text().catch(() => "");
|
|
166
|
-
throw new Error(
|
|
167
|
-
`vertex request failed: ${res.status} ${res.statusText} body=${text.slice(0, 500)}`,
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
return (await res.json()) as GeminiResponse;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async call<T>(model: string, options: CallOptions): Promise<T> {
|
|
174
|
-
const jsonMode = "jsonSchemaName" in options;
|
|
175
|
-
const log = logger.child("llm:vertex");
|
|
176
|
-
log.debug(
|
|
177
|
-
`call: model=${model} jsonSchema=${jsonMode ? options.jsonSchemaName : "-"} msgLen=${options.message.length}`,
|
|
178
|
-
);
|
|
179
|
-
const body: Record<string, unknown> = {
|
|
180
|
-
contents: [
|
|
181
|
-
{
|
|
182
|
-
role: "user",
|
|
183
|
-
parts: [{ text: options.message }],
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
systemInstruction: { parts: [{ text: options.instruction }] },
|
|
187
|
-
};
|
|
188
|
-
if (jsonMode) {
|
|
189
|
-
body["generationConfig"] = {
|
|
190
|
-
responseMimeType: "application/json",
|
|
191
|
-
responseSchema: options.jsonSchema,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
const data = await this.generate(model, body);
|
|
195
|
-
if (data.error) {
|
|
196
|
-
throw new Error(`vertex API error: ${data.error.message ?? "unknown"}`);
|
|
197
|
-
}
|
|
198
|
-
const { text } = extractFromGemini(data);
|
|
199
|
-
if (!text) {
|
|
200
|
-
throw new Error("Empty response from model");
|
|
201
|
-
}
|
|
202
|
-
return (jsonMode ? JSON.parse(text) : text) as T;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async chatWithTools(
|
|
206
|
-
model: string,
|
|
207
|
-
options: ChatWithToolsOptions,
|
|
208
|
-
): Promise<ChatChoice> {
|
|
209
|
-
const log = logger.child("llm:vertex");
|
|
210
|
-
log.debug(
|
|
211
|
-
`chatWithTools: model=${model} msgs=${options.messages.length} tools=${options.tools.length}`,
|
|
212
|
-
);
|
|
213
|
-
const contents = toGeminiContents(options.messages);
|
|
214
|
-
const body: Record<string, unknown> = {
|
|
215
|
-
contents,
|
|
216
|
-
systemInstruction: { parts: [{ text: options.instruction }] },
|
|
217
|
-
tools:
|
|
218
|
-
options.tools.length > 0
|
|
219
|
-
? [toGeminiTool(options.tools[0]!)]
|
|
220
|
-
: undefined,
|
|
221
|
-
};
|
|
222
|
-
const data = await this.generate(model, body);
|
|
223
|
-
if (data.error) {
|
|
224
|
-
throw new Error(`vertex API error: ${data.error.message ?? "unknown"}`);
|
|
225
|
-
}
|
|
226
|
-
const { text, toolCalls } = extractFromGemini(data);
|
|
227
|
-
return { message: { content: text || undefined, toolCalls } };
|
|
228
|
-
}
|
|
229
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class XAIExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "xai",
|
|
11
|
-
baseURL: "https://api.x.ai/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class ZaiExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "zai",
|
|
11
|
-
baseURL: "https://api.z.ai/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { OpenAICompatibleExecutor } from "./openai_compatible";
|
|
2
|
-
|
|
3
|
-
export class ZenMuxExecutor extends OpenAICompatibleExecutor {
|
|
4
|
-
constructor(opts: {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
conversationModel: string;
|
|
7
|
-
identityModel: string;
|
|
8
|
-
}) {
|
|
9
|
-
super({
|
|
10
|
-
providerName: "zenmux",
|
|
11
|
-
baseURL: "https://zenmux.ai/api/v1",
|
|
12
|
-
apiKey: opts.apiKey,
|
|
13
|
-
conversationModel: opts.conversationModel,
|
|
14
|
-
identityModel: opts.identityModel,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
package/src/provider/schema.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
const timeString = {
|
|
2
|
-
type: "string",
|
|
3
|
-
pattern: "^([01][0-9]|2[0-3]):[0-5][0-9]$",
|
|
4
|
-
};
|
|
5
|
-
const endTimeString = {
|
|
6
|
-
type: "string",
|
|
7
|
-
pattern: "^([01][0-9]|2[0-3]):[0-5][0-9]$|^24:00$",
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const dailyScheduleSchema = {
|
|
11
|
-
type: "object",
|
|
12
|
-
additionalProperties: false,
|
|
13
|
-
properties: {
|
|
14
|
-
items: {
|
|
15
|
-
type: "array",
|
|
16
|
-
minItems: 48,
|
|
17
|
-
maxItems: 48,
|
|
18
|
-
items: {
|
|
19
|
-
type: "object",
|
|
20
|
-
additionalProperties: false,
|
|
21
|
-
properties: {
|
|
22
|
-
start: timeString,
|
|
23
|
-
end: endTimeString,
|
|
24
|
-
activity: { type: "string" },
|
|
25
|
-
notes: { type: "string" },
|
|
26
|
-
},
|
|
27
|
-
required: ["start", "end", "activity", "notes"],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
required: ["items"],
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const monthlyScheduleSchema = {
|
|
35
|
-
type: "object",
|
|
36
|
-
additionalProperties: false,
|
|
37
|
-
properties: {
|
|
38
|
-
items: {
|
|
39
|
-
type: "array",
|
|
40
|
-
minItems: 28,
|
|
41
|
-
maxItems: 31,
|
|
42
|
-
items: {
|
|
43
|
-
type: "object",
|
|
44
|
-
additionalProperties: false,
|
|
45
|
-
properties: {
|
|
46
|
-
day: { type: "integer", minimum: 1, maximum: 31 },
|
|
47
|
-
summary: { type: "string" },
|
|
48
|
-
},
|
|
49
|
-
required: ["day", "summary"],
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
required: ["items"],
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const availabilitySchema = {
|
|
57
|
-
type: "object",
|
|
58
|
-
additionalProperties: false,
|
|
59
|
-
properties: {
|
|
60
|
-
items: {
|
|
61
|
-
type: "array",
|
|
62
|
-
minItems: 1,
|
|
63
|
-
items: {
|
|
64
|
-
type: "object",
|
|
65
|
-
additionalProperties: false,
|
|
66
|
-
properties: {
|
|
67
|
-
start: timeString,
|
|
68
|
-
end: endTimeString,
|
|
69
|
-
status: {
|
|
70
|
-
type: "string",
|
|
71
|
-
enum: ["online", "do-not-disturb", "offline"],
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
required: ["start", "end", "status"],
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
required: ["items"],
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// ----------------------------------------------------------------------------
|
|
82
|
-
// Types — co-located with their schemas.
|
|
83
|
-
// ----------------------------------------------------------------------------
|
|
84
|
-
|
|
85
|
-
export type DailySlot = {
|
|
86
|
-
start: string;
|
|
87
|
-
end: string;
|
|
88
|
-
activity: string;
|
|
89
|
-
notes: string;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export type DailySchedule = {
|
|
93
|
-
items: DailySlot[];
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export type MonthlyDay = {
|
|
97
|
-
day: number;
|
|
98
|
-
summary: string;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export type MonthlySchedule = {
|
|
102
|
-
items: MonthlyDay[];
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export type AvailabilityStatus = "online" | "do-not-disturb" | "offline";
|
|
106
|
-
|
|
107
|
-
export type Availability = {
|
|
108
|
-
start: string;
|
|
109
|
-
end: string;
|
|
110
|
-
status: AvailabilityStatus;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export type AvailabilityWindows = {
|
|
114
|
-
items: Availability[];
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const baseSystemPromptSchema = {
|
|
118
|
-
type: "object",
|
|
119
|
-
additionalProperties: false,
|
|
120
|
-
properties: {
|
|
121
|
-
baseSystemPrompt: { type: "string" },
|
|
122
|
-
dndReplyProbability: { type: "number", minimum: 0, maximum: 1 },
|
|
123
|
-
startConversationCountThreshold: { type: "integer", minimum: 0, maximum: 10 },
|
|
124
|
-
startConversationTimeThreshold: {
|
|
125
|
-
type: "integer",
|
|
126
|
-
minimum: 30,
|
|
127
|
-
maximum: 720,
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
required: [
|
|
131
|
-
"baseSystemPrompt",
|
|
132
|
-
"dndReplyProbability",
|
|
133
|
-
"startConversationCountThreshold",
|
|
134
|
-
"startConversationTimeThreshold",
|
|
135
|
-
],
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
export type BaseSystemPromptGeneration = {
|
|
139
|
-
baseSystemPrompt: string;
|
|
140
|
-
dndReplyProbability: number;
|
|
141
|
-
startConversationCountThreshold: number;
|
|
142
|
-
startConversationTimeThreshold: number;
|
|
143
|
-
};
|