@apolloyh/apollo-agent 0.1.11 → 0.2.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/.env.example +7 -0
- package/dist/brand.d.ts +1 -1
- package/dist/brand.js +1 -1
- package/dist/config.d.ts +4 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +28 -15
- package/dist/llm/anthropic.d.ts +18 -11
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +6 -3
- package/dist/llm/openai.d.ts +8 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +214 -0
- package/dist/runtime/query-engine.d.ts +1 -0
- package/dist/runtime/query-engine.d.ts.map +1 -1
- package/dist/runtime/query-engine.js +11 -6
- package/dist/sdk.d.ts +2 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +2 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/guide.md +13 -2
- package/docs/sdk.md +4 -0
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -16,3 +16,10 @@ ANTHROPIC_DEFAULT_SONNET_MODEL_NAME=glm-5.2
|
|
|
16
16
|
# ANTHROPIC_TIMEOUT_MS=300000
|
|
17
17
|
# ANTHROPIC_CACHE_TTL=5m
|
|
18
18
|
# AGENT_SENDMAIL_PATH=/usr/sbin/sendmail
|
|
19
|
+
|
|
20
|
+
# OpenAI-compatible alternative
|
|
21
|
+
# APOLLO_LLM_PROTOCOL=openai
|
|
22
|
+
# OPENAI_API_KEY=
|
|
23
|
+
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
24
|
+
# OPENAI_MODEL=gpt-4o-mini
|
|
25
|
+
# OPENAI_MAX_TOKENS_PARAM=max_tokens
|
package/dist/brand.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Product identity — single source of truth for display strings. */
|
|
2
2
|
export declare const PRODUCT: {
|
|
3
3
|
readonly name: "Apollo";
|
|
4
|
-
readonly version: "0.
|
|
4
|
+
readonly version: "0.2.0";
|
|
5
5
|
readonly tagline: "Your personal agent — answer first, act when needed.";
|
|
6
6
|
readonly packageName: "@apolloyh/apollo-agent";
|
|
7
7
|
readonly userAgent: "ApolloAgent/0.1";
|
package/dist/brand.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Product identity — single source of truth for display strings. */
|
|
2
2
|
export const PRODUCT = {
|
|
3
3
|
name: "Apollo",
|
|
4
|
-
version: "0.
|
|
4
|
+
version: "0.2.0",
|
|
5
5
|
tagline: "Your personal agent — answer first, act when needed.",
|
|
6
6
|
packageName: "@apolloyh/apollo-agent",
|
|
7
7
|
userAgent: "ApolloAgent/0.1",
|
package/dist/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentConfig, LlmConfig, SubagentConfig } from "./types.js";
|
|
2
2
|
/** Default Apollo Task roles. */
|
|
3
3
|
export declare const DEFAULT_AGENTS: SubagentConfig[];
|
|
4
|
-
export declare const MISSING_AUTH_TOKEN_MESSAGE = "Missing
|
|
4
|
+
export declare const MISSING_AUTH_TOKEN_MESSAGE = "Missing model API token. Set ANTHROPIC_AUTH_TOKEN or OPENAI_API_KEY, then restart Apollo.";
|
|
5
5
|
export declare function ensureUserEnvFile(): {
|
|
6
6
|
path: string;
|
|
7
7
|
created: boolean;
|
|
@@ -14,7 +14,9 @@ export declare function ensureUserConfigExampleFile(): {
|
|
|
14
14
|
path: string;
|
|
15
15
|
created: boolean;
|
|
16
16
|
};
|
|
17
|
-
export declare function loadAgentConfig(configPath?: string
|
|
17
|
+
export declare function loadAgentConfig(configPath?: string, options?: {
|
|
18
|
+
isolated?: boolean;
|
|
19
|
+
}): Promise<AgentConfig>;
|
|
18
20
|
/**
|
|
19
21
|
* Load an explicit env file, or discover project env then ~/.apollo/.env.
|
|
20
22
|
* By default **overrides** existing shell vars so local agent config wins.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,cAAc,EAkC1C,CAAC;AAsBF,eAAO,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,cAAc,EAkC1C,CAAC;AAsBF,eAAO,MAAM,0BAA0B,8FACsD,CAAC;AA8B9F,wBAAgB,iBAAiB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAatE;AAED,wBAAgB,oBAAoB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAazE;AAED,wBAAgB,2BAA2B,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAchF;AAED,wBAAsB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAkDrH;AAiBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAwB3F;AAYD,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,SAAS,CAsCrF"}
|
package/dist/config.js
CHANGED
|
@@ -55,7 +55,7 @@ const defaultConfig = {
|
|
|
55
55
|
};
|
|
56
56
|
const DEFAULT_CONFIG_PATH = ".apollo/config.json";
|
|
57
57
|
const LEGACY_CONFIG_PATH = "agent.config.json";
|
|
58
|
-
export const MISSING_AUTH_TOKEN_MESSAGE = "Missing
|
|
58
|
+
export const MISSING_AUTH_TOKEN_MESSAGE = "Missing model API token. Set ANTHROPIC_AUTH_TOKEN or OPENAI_API_KEY, then restart Apollo.";
|
|
59
59
|
const USER_ENV_TEMPLATE = `# Apollo uses Anthropic-compatible environment variable names.
|
|
60
60
|
# Add your provider token below, then restart Apollo.
|
|
61
61
|
ANTHROPIC_AUTH_TOKEN=
|
|
@@ -63,6 +63,12 @@ ANTHROPIC_AUTH_TOKEN=
|
|
|
63
63
|
# Optional provider settings:
|
|
64
64
|
# ANTHROPIC_BASE_URL=https://api.anthropic.com
|
|
65
65
|
# ANTHROPIC_MODEL=claude-haiku-4-5
|
|
66
|
+
|
|
67
|
+
# OpenAI-compatible alternative:
|
|
68
|
+
# APOLLO_LLM_PROTOCOL=openai
|
|
69
|
+
# OPENAI_API_KEY=
|
|
70
|
+
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
71
|
+
# OPENAI_MODEL=gpt-4o-mini
|
|
66
72
|
`;
|
|
67
73
|
const USER_CONFIG_TEMPLATE = `${JSON.stringify({
|
|
68
74
|
systemPrompt: "",
|
|
@@ -122,12 +128,12 @@ export function ensureUserConfigExampleFile() {
|
|
|
122
128
|
throw error;
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
|
-
export async function loadAgentConfig(configPath) {
|
|
131
|
+
export async function loadAgentConfig(configPath, options = {}) {
|
|
126
132
|
const userConfigPath = path.join(os.homedir(), ".apollo", "config.json");
|
|
127
133
|
const projectConfigPath = [DEFAULT_CONFIG_PATH, LEGACY_CONFIG_PATH].find(fsSync.existsSync);
|
|
128
134
|
const layers = [
|
|
129
|
-
...(fsSync.existsSync(userConfigPath) ? [{ file: userConfigPath, projectScoped: false }] : []),
|
|
130
|
-
...(projectConfigPath ? [{ file: projectConfigPath, projectScoped: true }] : []),
|
|
135
|
+
...(!options.isolated && fsSync.existsSync(userConfigPath) ? [{ file: userConfigPath, projectScoped: false }] : []),
|
|
136
|
+
...(!options.isolated && projectConfigPath ? [{ file: projectConfigPath, projectScoped: true }] : []),
|
|
131
137
|
...(configPath ? [{ file: configPath, projectScoped: true }] : []),
|
|
132
138
|
];
|
|
133
139
|
const seen = new Set();
|
|
@@ -223,13 +229,15 @@ function unwrapEnvValue(value) {
|
|
|
223
229
|
return value;
|
|
224
230
|
}
|
|
225
231
|
export function loadLlmConfig(options = {}) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
232
|
+
const requestedProtocol = process.env.APOLLO_LLM_PROTOCOL ?? (process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_AUTH_TOKEN ? "openai" : "anthropic");
|
|
233
|
+
if (requestedProtocol !== "anthropic" && requestedProtocol !== "openai")
|
|
234
|
+
throw new Error("APOLLO_LLM_PROTOCOL must be anthropic or openai.");
|
|
235
|
+
const protocol = requestedProtocol;
|
|
236
|
+
const authToken = protocol === "openai" ? process.env.OPENAI_API_KEY : process.env.ANTHROPIC_AUTH_TOKEN;
|
|
237
|
+
const baseUrl = protocol === "openai" ? process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1" : process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";
|
|
238
|
+
const model = protocol === "openai"
|
|
239
|
+
? process.env.OPENAI_MODEL ?? "gpt-4o-mini"
|
|
240
|
+
: process.env.ANTHROPIC_MODEL || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL || process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME || process.env.ANTHROPIC_DEFAULT_SONNET_MODEL_NAME || "claude-haiku-4-5";
|
|
233
241
|
if (!authToken && !options.allowMissingAuth)
|
|
234
242
|
throw new Error(MISSING_AUTH_TOKEN_MESSAGE);
|
|
235
243
|
const cacheTtl = process.env.ANTHROPIC_CACHE_TTL ?? "5m";
|
|
@@ -237,25 +245,30 @@ export function loadLlmConfig(options = {}) {
|
|
|
237
245
|
throw new Error("ANTHROPIC_CACHE_TTL must be 5m or 1h.");
|
|
238
246
|
}
|
|
239
247
|
const providerDefaultMaxTokens = /(?:^glm-|bigmodel\.cn)/i.test(`${model} ${baseUrl}`) ? 128 * 1024 : 4096;
|
|
240
|
-
const maxTokens = positiveNumberEnv("ANTHROPIC_MAX_TOKENS", providerDefaultMaxTokens, true);
|
|
241
|
-
const timeoutMs = positiveNumberEnv("ANTHROPIC_TIMEOUT_MS", 300000, true);
|
|
248
|
+
const maxTokens = positiveNumberEnv(protocol === "openai" ? "OPENAI_MAX_TOKENS" : "ANTHROPIC_MAX_TOKENS", providerDefaultMaxTokens, true);
|
|
249
|
+
const timeoutMs = positiveNumberEnv(protocol === "openai" ? "OPENAI_TIMEOUT_MS" : "ANTHROPIC_TIMEOUT_MS", 300000, true);
|
|
250
|
+
const openaiMaxTokensParam = process.env.OPENAI_MAX_TOKENS_PARAM ?? (/^(?:o[134]-|gpt-5)/i.test(model) ? "max_completion_tokens" : "max_tokens");
|
|
251
|
+
if (openaiMaxTokensParam !== "max_tokens" && openaiMaxTokensParam !== "max_completion_tokens")
|
|
252
|
+
throw new Error("OPENAI_MAX_TOKENS_PARAM must be max_tokens or max_completion_tokens.");
|
|
242
253
|
let parsedBaseUrl;
|
|
243
254
|
try {
|
|
244
255
|
parsedBaseUrl = new URL(baseUrl);
|
|
245
256
|
}
|
|
246
257
|
catch {
|
|
247
|
-
throw new Error("
|
|
258
|
+
throw new Error("Model base URL must be a valid HTTP or HTTPS URL.");
|
|
248
259
|
}
|
|
249
260
|
if (parsedBaseUrl.protocol !== "http:" && parsedBaseUrl.protocol !== "https:") {
|
|
250
|
-
throw new Error("
|
|
261
|
+
throw new Error("Model base URL must be a valid HTTP or HTTPS URL.");
|
|
251
262
|
}
|
|
252
263
|
return {
|
|
264
|
+
protocol,
|
|
253
265
|
authToken: authToken ?? "",
|
|
254
266
|
baseUrl,
|
|
255
267
|
model,
|
|
256
268
|
maxTokens,
|
|
257
269
|
timeoutMs,
|
|
258
270
|
cacheTtl,
|
|
271
|
+
openaiMaxTokensParam,
|
|
259
272
|
};
|
|
260
273
|
}
|
|
261
274
|
function positiveNumberEnv(name, fallback, integer) {
|
package/dist/llm/anthropic.d.ts
CHANGED
|
@@ -21,30 +21,37 @@ export type ToolInputDelta = {
|
|
|
21
21
|
export type ThinkingDelta = {
|
|
22
22
|
text: string;
|
|
23
23
|
};
|
|
24
|
+
export type CreateMessageInput = {
|
|
25
|
+
system: string;
|
|
26
|
+
messages: Message[];
|
|
27
|
+
tools: AnthropicTool[];
|
|
28
|
+
stream?: boolean;
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
onTextDelta?: (text: string) => void;
|
|
31
|
+
onThinkingDelta?: (event: ThinkingDelta) => void;
|
|
32
|
+
onToolInputDelta?: (event: ToolInputDelta) => void;
|
|
33
|
+
};
|
|
34
|
+
export interface LlmClient {
|
|
35
|
+
createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
|
|
36
|
+
}
|
|
24
37
|
export declare class MalformedStreamError extends Error {
|
|
25
38
|
constructor(message: string, cause?: unknown);
|
|
26
39
|
}
|
|
27
40
|
export declare class MalformedToolInputError extends MalformedStreamError {
|
|
28
41
|
constructor(tool: string, bytes: number, cause: unknown);
|
|
29
42
|
}
|
|
30
|
-
export declare class
|
|
43
|
+
export declare class ProviderApiError extends Error {
|
|
31
44
|
readonly status: number;
|
|
32
45
|
readonly responseBody: string;
|
|
33
46
|
readonly responseHeaders: Headers;
|
|
34
47
|
constructor(status: number, responseBody: string, responseHeaders: Headers);
|
|
35
48
|
}
|
|
49
|
+
export declare class AnthropicApiError extends ProviderApiError {
|
|
50
|
+
name: string;
|
|
51
|
+
}
|
|
36
52
|
export declare class AnthropicClient {
|
|
37
53
|
private readonly config;
|
|
38
54
|
constructor(config: LlmConfig);
|
|
39
|
-
createMessage(input:
|
|
40
|
-
system: string;
|
|
41
|
-
messages: Message[];
|
|
42
|
-
tools: AnthropicTool[];
|
|
43
|
-
stream?: boolean;
|
|
44
|
-
signal?: AbortSignal;
|
|
45
|
-
onTextDelta?: (text: string) => void;
|
|
46
|
-
onThinkingDelta?: (event: ThinkingDelta) => void;
|
|
47
|
-
onToolInputDelta?: (event: ToolInputDelta) => void;
|
|
48
|
-
}): Promise<AnthropicResponse>;
|
|
55
|
+
createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
|
|
49
56
|
}
|
|
50
57
|
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B,EAAE,MAAM,CAAC;IACpC,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC;AAOF,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B,EAAE,MAAM,CAAC;IACpC,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC;AAOF,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACtE;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,qBAAa,uBAAwB,SAAQ,oBAAoB;gBACnD,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAIxD;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aACd,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,OAAO;gBAFxB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,OAAO;CAK3C;AAED,qBAAa,iBAAkB,SAAQ,gBAAgB;IAC5C,IAAI,SAAuB;CACrC;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAExC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsC3E"}
|
package/dist/llm/anthropic.js
CHANGED
|
@@ -10,18 +10,21 @@ export class MalformedToolInputError extends MalformedStreamError {
|
|
|
10
10
|
this.name = "MalformedToolInputError";
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
export class
|
|
13
|
+
export class ProviderApiError extends Error {
|
|
14
14
|
status;
|
|
15
15
|
responseBody;
|
|
16
16
|
responseHeaders;
|
|
17
17
|
constructor(status, responseBody, responseHeaders) {
|
|
18
|
-
super(`
|
|
18
|
+
super(`Provider API error ${status}: ${responseBody}`);
|
|
19
19
|
this.status = status;
|
|
20
20
|
this.responseBody = responseBody;
|
|
21
21
|
this.responseHeaders = responseHeaders;
|
|
22
|
-
this.name = "
|
|
22
|
+
this.name = "ProviderApiError";
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
export class AnthropicApiError extends ProviderApiError {
|
|
26
|
+
name = "AnthropicApiError";
|
|
27
|
+
}
|
|
25
28
|
export class AnthropicClient {
|
|
26
29
|
config;
|
|
27
30
|
constructor(config) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LlmConfig } from "../types.js";
|
|
2
|
+
import { type AnthropicResponse, type CreateMessageInput, type LlmClient } from "./anthropic.js";
|
|
3
|
+
export declare class OpenAIClient implements LlmClient {
|
|
4
|
+
private readonly config;
|
|
5
|
+
constructor(config: LlmConfig);
|
|
6
|
+
createMessage(input: CreateMessageInput): Promise<AnthropicResponse>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2C,SAAS,EAAW,MAAM,aAAa,CAAC;AAC/F,OAAO,EAIL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAKxB,qBAAa,YAAa,YAAW,SAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS;IAExC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAmB3E"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { ProviderApiError, MalformedStreamError, MalformedToolInputError, } from "./anthropic.js";
|
|
2
|
+
export class OpenAIClient {
|
|
3
|
+
config;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
}
|
|
7
|
+
async createMessage(input) {
|
|
8
|
+
const response = await fetch(openAIEndpoint(this.config.baseUrl), {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${this.config.authToken}` },
|
|
11
|
+
body: JSON.stringify({
|
|
12
|
+
model: this.config.model,
|
|
13
|
+
messages: toOpenAIMessages(input.system, input.messages),
|
|
14
|
+
[this.config.openaiMaxTokensParam ?? "max_tokens"]: this.config.maxTokens,
|
|
15
|
+
...(input.tools.length ? { tools: input.tools.map(toOpenAITool), tool_choice: "auto" } : {}),
|
|
16
|
+
stream: input.stream ?? false,
|
|
17
|
+
...(input.stream ? { stream_options: { include_usage: true } } : {}),
|
|
18
|
+
}),
|
|
19
|
+
signal: input.signal
|
|
20
|
+
? AbortSignal.any([input.signal, AbortSignal.timeout(normalizeTimeout(this.config.timeoutMs))])
|
|
21
|
+
: AbortSignal.timeout(normalizeTimeout(this.config.timeoutMs)),
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok)
|
|
24
|
+
throw new ProviderApiError(response.status, await response.text(), response.headers);
|
|
25
|
+
return input.stream ? readOpenAIStream(response, input) : normalizeOpenAIResponse(await response.json());
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function openAIEndpoint(baseUrl) {
|
|
29
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
30
|
+
if (/\/chat\/completions$/i.test(base))
|
|
31
|
+
return base;
|
|
32
|
+
return `${base}${/\/v1$/i.test(base) ? "" : "/v1"}/chat/completions`;
|
|
33
|
+
}
|
|
34
|
+
function toOpenAITool(tool) {
|
|
35
|
+
return { type: "function", function: { name: tool.name, description: tool.description, parameters: tool.input_schema } };
|
|
36
|
+
}
|
|
37
|
+
function toOpenAIMessages(system, messages) {
|
|
38
|
+
const output = system ? [{ role: "system", content: system }] : [];
|
|
39
|
+
for (const message of messages) {
|
|
40
|
+
if (typeof message.content === "string") {
|
|
41
|
+
output.push({ role: message.role, content: message.content });
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (message.role === "assistant") {
|
|
45
|
+
const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
|
|
46
|
+
const toolCalls = message.content.filter((block) => block.type === "tool_use").map((block) => ({
|
|
47
|
+
id: block.id,
|
|
48
|
+
type: "function",
|
|
49
|
+
function: { name: block.name, arguments: JSON.stringify(block.input) },
|
|
50
|
+
}));
|
|
51
|
+
output.push({ role: "assistant", content: text || null, ...(toolCalls.length ? { tool_calls: toolCalls } : {}) });
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (const block of message.content) {
|
|
55
|
+
if (block.type === "tool_result")
|
|
56
|
+
output.push({ role: "tool", tool_call_id: block.tool_use_id, content: block.is_error ? `[error] ${block.content}` : block.content });
|
|
57
|
+
}
|
|
58
|
+
const text = message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
|
|
59
|
+
if (text)
|
|
60
|
+
output.push({ role: "user", content: text });
|
|
61
|
+
}
|
|
62
|
+
return output;
|
|
63
|
+
}
|
|
64
|
+
function normalizeOpenAIResponse(value) {
|
|
65
|
+
const source = value;
|
|
66
|
+
const choice = source.choices?.[0];
|
|
67
|
+
if (!choice?.message)
|
|
68
|
+
throw new MalformedStreamError("OpenAI API returned no assistant message.");
|
|
69
|
+
return {
|
|
70
|
+
id: source.id ?? "",
|
|
71
|
+
type: "message",
|
|
72
|
+
role: "assistant",
|
|
73
|
+
content: normalizeOpenAIContent(choice.message),
|
|
74
|
+
stop_reason: normalizeStopReason(choice.finish_reason),
|
|
75
|
+
usage: normalizeUsage(source.usage),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function readOpenAIStream(response, input) {
|
|
79
|
+
if (!response.body)
|
|
80
|
+
throw new MalformedStreamError("OpenAI API returned an empty stream body.");
|
|
81
|
+
const reader = response.body.getReader();
|
|
82
|
+
const decoder = new TextDecoder();
|
|
83
|
+
const tools = new Map();
|
|
84
|
+
let buffer = "", id = "", text = "", thinking = "", stopReason, usage, ended = false;
|
|
85
|
+
const apply = (data) => {
|
|
86
|
+
if (!data || data === "[DONE]")
|
|
87
|
+
return;
|
|
88
|
+
let event;
|
|
89
|
+
try {
|
|
90
|
+
event = JSON.parse(data);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new MalformedStreamError("OpenAI API returned malformed JSON in the event stream.", error);
|
|
94
|
+
}
|
|
95
|
+
id ||= event.id ?? "";
|
|
96
|
+
usage = normalizeUsage(event.usage) ?? usage;
|
|
97
|
+
const choice = event.choices?.[0];
|
|
98
|
+
const delta = choice?.delta;
|
|
99
|
+
if (choice?.finish_reason)
|
|
100
|
+
stopReason = normalizeStopReason(choice.finish_reason);
|
|
101
|
+
if (!delta)
|
|
102
|
+
return;
|
|
103
|
+
const reasoning = delta.reasoning_content ?? delta.reasoning;
|
|
104
|
+
if (reasoning) {
|
|
105
|
+
thinking += reasoning;
|
|
106
|
+
input.onThinkingDelta?.({ text: reasoning });
|
|
107
|
+
}
|
|
108
|
+
if (delta.content) {
|
|
109
|
+
text += delta.content;
|
|
110
|
+
input.onTextDelta?.(delta.content);
|
|
111
|
+
}
|
|
112
|
+
for (const part of delta.tool_calls ?? []) {
|
|
113
|
+
const index = part.index ?? 0;
|
|
114
|
+
const tool = tools.get(index) ?? { id: "", name: "", arguments: "" };
|
|
115
|
+
const wasUnnamed = !tool.name;
|
|
116
|
+
tool.id ||= part.id ?? "";
|
|
117
|
+
tool.name += part.function?.name ?? "";
|
|
118
|
+
tool.arguments += part.function?.arguments ?? "";
|
|
119
|
+
tools.set(index, tool);
|
|
120
|
+
if (wasUnnamed && tool.name)
|
|
121
|
+
input.onToolInputDelta?.({ bytes: 0, tool: tool.name });
|
|
122
|
+
if (part.function?.arguments)
|
|
123
|
+
input.onToolInputDelta?.({ bytes: tool.arguments.length, tool: tool.name || undefined, detail: partialToolDetail(tool.arguments) });
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
for (;;) {
|
|
128
|
+
const chunk = await reader.read();
|
|
129
|
+
if (chunk.done) {
|
|
130
|
+
ended = true;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
134
|
+
let separator = buffer.match(/\r?\n\r?\n/);
|
|
135
|
+
while (separator?.index !== undefined) {
|
|
136
|
+
const raw = buffer.slice(0, separator.index);
|
|
137
|
+
buffer = buffer.slice(separator.index + separator[0].length);
|
|
138
|
+
apply(parseSseData(raw));
|
|
139
|
+
separator = buffer.match(/\r?\n\r?\n/);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
buffer += decoder.decode();
|
|
143
|
+
if (buffer.trim())
|
|
144
|
+
apply(parseSseData(buffer));
|
|
145
|
+
if (!text && !thinking && !tools.size)
|
|
146
|
+
throw new MalformedStreamError("OpenAI API returned an empty or incomplete event stream.");
|
|
147
|
+
const content = [];
|
|
148
|
+
if (thinking)
|
|
149
|
+
content.push({ type: "thinking", thinking });
|
|
150
|
+
if (text)
|
|
151
|
+
content.push({ type: "text", text });
|
|
152
|
+
for (const [, tool] of [...tools].sort(([a], [b]) => a - b))
|
|
153
|
+
content.push(toToolUse(tool));
|
|
154
|
+
return { id, type: "message", role: "assistant", content, stop_reason: stopReason, usage };
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
if (!ended)
|
|
158
|
+
await reader.cancel().catch(() => undefined);
|
|
159
|
+
reader.releaseLock();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function normalizeOpenAIContent(message) {
|
|
163
|
+
const content = [];
|
|
164
|
+
const reasoning = message.reasoning_content ?? message.reasoning;
|
|
165
|
+
if (reasoning)
|
|
166
|
+
content.push({ type: "thinking", thinking: reasoning });
|
|
167
|
+
if (message.content)
|
|
168
|
+
content.push({ type: "text", text: message.content });
|
|
169
|
+
for (const [index, call] of (message.tool_calls ?? []).entries())
|
|
170
|
+
content.push(toToolUse({ id: call.id ?? `call-${index}`, name: call.function?.name ?? "", arguments: call.function?.arguments ?? "" }));
|
|
171
|
+
return content;
|
|
172
|
+
}
|
|
173
|
+
function toToolUse(tool) {
|
|
174
|
+
try {
|
|
175
|
+
return { type: "tool_use", id: tool.id, name: tool.name, input: tool.arguments.trim() ? JSON.parse(tool.arguments) : {} };
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
throw new MalformedToolInputError(tool.name, tool.arguments.length, error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function normalizeUsage(value) {
|
|
182
|
+
if (!value || typeof value !== "object")
|
|
183
|
+
return undefined;
|
|
184
|
+
const usage = value;
|
|
185
|
+
if (typeof usage.prompt_tokens !== "number" && typeof usage.completion_tokens !== "number")
|
|
186
|
+
return undefined;
|
|
187
|
+
return { input_tokens: usage.prompt_tokens ?? 0, output_tokens: usage.completion_tokens ?? 0, cache_creation_input_tokens: 0, cache_read_input_tokens: usage.prompt_tokens_details?.cached_tokens ?? 0 };
|
|
188
|
+
}
|
|
189
|
+
function normalizeStopReason(reason) {
|
|
190
|
+
if (reason === "tool_calls" || reason === "function_call")
|
|
191
|
+
return "tool_use";
|
|
192
|
+
if (reason === "length")
|
|
193
|
+
return "max_tokens";
|
|
194
|
+
if (reason === "stop")
|
|
195
|
+
return "end_turn";
|
|
196
|
+
return reason;
|
|
197
|
+
}
|
|
198
|
+
function parseSseData(raw) {
|
|
199
|
+
return raw.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n").trim();
|
|
200
|
+
}
|
|
201
|
+
function partialToolDetail(input) {
|
|
202
|
+
const match = input.slice(0, 8192).match(/"(?:path|file_path|command|query|url|description)"\s*:\s*"((?:\\.|[^"\\])*)"/);
|
|
203
|
+
if (!match?.[1])
|
|
204
|
+
return undefined;
|
|
205
|
+
try {
|
|
206
|
+
return JSON.parse(`"${match[1]}"`);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function normalizeTimeout(value) {
|
|
213
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 300000;
|
|
214
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/runtime/query-engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EAChB,SAAS,EAET,SAAS,EACT,OAAO,EACP,cAAc,EAEd,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/runtime/query-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { AnthropicClient, MalformedStreamError, ProviderApiError, } from "../llm/anthropic.js";
|
|
3
|
+
import { OpenAIClient } from "../llm/openai.js";
|
|
3
4
|
import { ContextManager, isContextSummary } from "./context.js";
|
|
4
5
|
import { buildCompactionTranscript, COMPACTION_SYSTEM_PROMPT, normalizeCompactionSummary, } from "./compaction.js";
|
|
5
6
|
import { createCliApprovalProvider } from "./permissions.js";
|
|
@@ -68,7 +69,9 @@ export class QueryEngine {
|
|
|
68
69
|
activeTurnAbort;
|
|
69
70
|
constructor(options) {
|
|
70
71
|
this.options = options;
|
|
71
|
-
this.client =
|
|
72
|
+
this.client = options.llmConfig.protocol === "openai"
|
|
73
|
+
? new OpenAIClient(options.llmConfig)
|
|
74
|
+
: new AnthropicClient(options.llmConfig);
|
|
72
75
|
this.contextManager = new ContextManager(options.agentConfig.context, options.emit);
|
|
73
76
|
this.skillManager = new SkillManager(options.agentConfig);
|
|
74
77
|
this.mcpManager = new McpManager(options.agentConfig);
|
|
@@ -138,6 +141,7 @@ export class QueryEngine {
|
|
|
138
141
|
model: this.options.llmConfig.model,
|
|
139
142
|
baseUrl: this.options.llmConfig.baseUrl,
|
|
140
143
|
maxTokens: this.options.llmConfig.maxTokens,
|
|
144
|
+
openaiMaxTokensParam: this.options.llmConfig.openaiMaxTokensParam,
|
|
141
145
|
contextMaxChars: this.options.agentConfig.context.maxChars,
|
|
142
146
|
workspaceRoot: this.options.agentConfig.workspaceRoot,
|
|
143
147
|
};
|
|
@@ -942,6 +946,7 @@ export class QueryEngine {
|
|
|
942
946
|
}
|
|
943
947
|
configFingerprint() {
|
|
944
948
|
return fingerprint({
|
|
949
|
+
protocol: this.options.llmConfig.protocol ?? "anthropic",
|
|
945
950
|
baseUrl: this.options.llmConfig.baseUrl.replace(/\/$/, ""),
|
|
946
951
|
model: this.options.llmConfig.model,
|
|
947
952
|
maxTokens: this.options.llmConfig.maxTokens,
|
|
@@ -1101,7 +1106,7 @@ function fingerprint(value) {
|
|
|
1101
1106
|
return createHash("sha256").update(content).digest("hex").slice(0, 12);
|
|
1102
1107
|
}
|
|
1103
1108
|
function isTransientLlmError(error) {
|
|
1104
|
-
if (error instanceof
|
|
1109
|
+
if (error instanceof ProviderApiError) {
|
|
1105
1110
|
const shouldRetry = error.responseHeaders.get("x-should-retry");
|
|
1106
1111
|
if (shouldRetry === "false")
|
|
1107
1112
|
return false;
|
|
@@ -1122,7 +1127,7 @@ function isTransientLlmError(error) {
|
|
|
1122
1127
|
return ["ECONNRESET", "ECONNREFUSED", "EPIPE", "ETIMEDOUT", "ENETUNREACH", "EAI_AGAIN"].includes(code ?? "");
|
|
1123
1128
|
}
|
|
1124
1129
|
function isContextOverflowError(error) {
|
|
1125
|
-
if (!(error instanceof
|
|
1130
|
+
if (!(error instanceof ProviderApiError))
|
|
1126
1131
|
return false;
|
|
1127
1132
|
if (error.status === 413)
|
|
1128
1133
|
return true;
|
|
@@ -1132,7 +1137,7 @@ function isContextOverflowError(error) {
|
|
|
1132
1137
|
.test(error.responseBody);
|
|
1133
1138
|
}
|
|
1134
1139
|
function retryDelayMs(error, attempt) {
|
|
1135
|
-
if (error instanceof
|
|
1140
|
+
if (error instanceof ProviderApiError) {
|
|
1136
1141
|
const retryAfter = error.responseHeaders.get("retry-after");
|
|
1137
1142
|
if (retryAfter) {
|
|
1138
1143
|
const seconds = Number(retryAfter);
|
|
@@ -1149,7 +1154,7 @@ function retryDelayMs(error, attempt) {
|
|
|
1149
1154
|
return Math.round(base + Math.random() * base * 0.25);
|
|
1150
1155
|
}
|
|
1151
1156
|
function retryReason(error) {
|
|
1152
|
-
if (error instanceof
|
|
1157
|
+
if (error instanceof ProviderApiError)
|
|
1153
1158
|
return `provider API ${error.status}`;
|
|
1154
1159
|
if (error instanceof Error && error.name === "TimeoutError")
|
|
1155
1160
|
return "provider request timed out";
|
package/dist/sdk.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { QueryEngine, type QueryEngineOptions } from "./runtime/query-engine.js"
|
|
|
2
2
|
import type { AgentConfig, ApprovalProvider, AskUserFn, LlmConfig, TraceSink } from "./types.js";
|
|
3
3
|
export type CreateQueryEngineOptions = {
|
|
4
4
|
configPath?: string;
|
|
5
|
+
configMode?: "layered" | "isolated";
|
|
6
|
+
workspaceRoot?: string;
|
|
5
7
|
envPath?: string;
|
|
6
8
|
agentConfig?: AgentConfig;
|
|
7
9
|
llmConfig?: LlmConfig;
|
package/dist/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7G,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7G,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBpG;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAO5F;AAID,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
|
package/dist/sdk.js
CHANGED
|
@@ -3,7 +3,8 @@ import { QueryEngine } from "./runtime/query-engine.js";
|
|
|
3
3
|
export async function createQueryEngine(options = {}) {
|
|
4
4
|
if (options.envPath || !options.llmConfig)
|
|
5
5
|
loadEnvFile(options.envPath);
|
|
6
|
-
const
|
|
6
|
+
const loadedConfig = options.agentConfig ?? (await loadAgentConfig(options.configPath, { isolated: options.configMode === "isolated" }));
|
|
7
|
+
const agentConfig = options.workspaceRoot ? { ...loadedConfig, workspaceRoot: options.workspaceRoot } : loadedConfig;
|
|
7
8
|
const llmConfig = options.llmConfig ?? loadLlmConfig();
|
|
8
9
|
const engine = new QueryEngine({
|
|
9
10
|
agentConfig,
|
package/dist/types.d.ts
CHANGED
|
@@ -168,12 +168,14 @@ export type ToolExecutionContext = {
|
|
|
168
168
|
planMode?: boolean;
|
|
169
169
|
};
|
|
170
170
|
export type LlmConfig = {
|
|
171
|
+
protocol?: "anthropic" | "openai";
|
|
171
172
|
authToken: string;
|
|
172
173
|
baseUrl: string;
|
|
173
174
|
model: string;
|
|
174
175
|
maxTokens: number;
|
|
175
176
|
timeoutMs?: number;
|
|
176
177
|
cacheTtl?: "5m" | "1h";
|
|
178
|
+
openaiMaxTokensParam?: "max_tokens" | "max_completion_tokens";
|
|
177
179
|
};
|
|
178
180
|
export type McpServerConfig = {
|
|
179
181
|
command: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/docs/guide.md
CHANGED
|
@@ -43,7 +43,18 @@ EXA_API_KEY=your_exa_key
|
|
|
43
43
|
# ANTHROPIC_CACHE_TTL=5m
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Apollo
|
|
46
|
+
Apollo 默认使用 Anthropic Messages API,也支持 OpenAI-compatible Chat Completions。切换为 OpenAI 协议:
|
|
47
|
+
|
|
48
|
+
```dotenv
|
|
49
|
+
APOLLO_LLM_PROTOCOL=openai
|
|
50
|
+
OPENAI_API_KEY=your_openai_token
|
|
51
|
+
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
52
|
+
OPENAI_MODEL=gpt-4o-mini
|
|
53
|
+
# OPENAI_MAX_TOKENS=4096
|
|
54
|
+
# OPENAI_MAX_TOKENS_PARAM=max_tokens
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
OpenAI 兼容层支持流式文本、公开的 reasoning/thinking 字段、并行工具调用、工具结果回传、usage/cache token 和标准重试错误。模型供应商不返回 reasoning 正文时,Apollo 无法展示该内容。
|
|
47
58
|
|
|
48
59
|
环境文件发现顺序:
|
|
49
60
|
|
|
@@ -243,7 +254,7 @@ Apollo 不伪造本地 Prompt Cache 命中;`/status` 只使用模型厂商响
|
|
|
243
254
|
|
|
244
255
|
## 故障排查
|
|
245
256
|
|
|
246
|
-
- `Missing ANTHROPIC_AUTH_TOKEN
|
|
257
|
+
- `Missing model API token`:配置 `ANTHROPIC_AUTH_TOKEN` 或 `OPENAI_API_KEY` 后重启。
|
|
247
258
|
- `EEXIST .../bin/apollo`:先确认 `which apollo`;移除旧的手动软链接或旧全局包后重装。
|
|
248
259
|
- 搜索不可用:检查 `EXA_API_KEY`,普通文件和代码搜索不依赖 Exa。
|
|
249
260
|
- 修改配置没有生效:重启 Apollo;配置和提示词在当前 Engine 中冻结。
|
package/docs/sdk.md
CHANGED
|
@@ -82,6 +82,8 @@ const engine = await createQueryEngine({
|
|
|
82
82
|
| 参数 | 类型 | 说明 |
|
|
83
83
|
|---|---|---|
|
|
84
84
|
| `configPath` | `string` | Agent 显式配置路径;在用户配置和项目配置之后覆盖,默认还会发现 `~/.apollo/config.json`、`.apollo/config.json`,并兼容旧 `agent.config.json` |
|
|
85
|
+
| `configMode` | `"layered" \| "isolated"` | `isolated` 只读取显式 `configPath`,适合 Web 服务;默认保持 CLI 分层发现 |
|
|
86
|
+
| `workspaceRoot` | `string` | 覆盖会话、记忆和工具使用的工作目录,不改变配置文件来源 |
|
|
85
87
|
| `envPath` | `string` | 可选环境变量文件;未提供模型配置时默认发现 `.apollo/.env`,然后 `.env` |
|
|
86
88
|
| `agentConfig` | `AgentConfig` | 直接传入完整 Agent 配置;优先于 `configPath` |
|
|
87
89
|
| `llmConfig` | `LlmConfig` | 直接传入模型配置;优先于环境变量 |
|
|
@@ -94,6 +96,8 @@ const engine = await createQueryEngine({
|
|
|
94
96
|
|
|
95
97
|
如果同时传入 `agentConfig` 和 `configPath`,使用 `agentConfig`;如果同时传入 `llmConfig` 和环境变量,使用 `llmConfig`。
|
|
96
98
|
|
|
99
|
+
`LlmConfig.protocol` 可设为 `anthropic` 或 `openai`。OpenAI 协议使用 `/v1/chat/completions`,并将响应归一为 Apollo 内部的 text、thinking、tool_use 和 usage 事件。
|
|
100
|
+
|
|
97
101
|
## 系统提示词与缓存
|
|
98
102
|
|
|
99
103
|
`~/.apollo/config.json` 和项目的 `.apollo/config.json` 都可以配置:
|
package/package.json
CHANGED