loopengine 0.1.6 → 0.1.8
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/README.md +12 -0
- package/dist/bin/cli.d.ts +1 -1
- package/dist/bin/cli.js +5 -0
- package/dist/core/agent-config.d.ts +22 -3
- package/dist/core/discover-agents.js +14 -2
- package/dist/core/model-calls/gemini-model-call.d.ts +17 -0
- package/dist/core/model-calls/gemini-model-call.js +53 -0
- package/dist/core/model-calls/glm-model-call.d.ts +15 -0
- package/dist/core/model-calls/glm-model-call.js +46 -0
- package/dist/core/model-calls/kimi-model-call.d.ts +15 -0
- package/dist/core/model-calls/kimi-model-call.js +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/dist/web/agent-file-admin.d.ts +1 -1
- package/dist/web/agent-file-admin.js +5 -0
- package/dist/web/agents-config-page.js +1 -1
- package/dist/web/global-config.d.ts +1 -1
- package/dist/web/global-config.js +5 -0
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -466,6 +466,18 @@ you, using the matching API key from the environment:
|
|
|
466
466
|
| `'anthropic'` | `ANTHROPIC_API_KEY` | no — defaults to `claude-sonnet-5` |
|
|
467
467
|
| `'openai'` | `OPENAI_API_KEY` | yes |
|
|
468
468
|
| `'deepseek'` | `DEEPSEEK_API_KEY` | yes |
|
|
469
|
+
| `'kimi'` | `MOONSHOT_API_KEY` | yes |
|
|
470
|
+
| `'glm'` | `GLM_API_KEY` | yes |
|
|
471
|
+
| `'gemini'` | `GEMINI_API_KEY` | yes |
|
|
472
|
+
|
|
473
|
+
`'kimi'`'s env var is `MOONSHOT_API_KEY`, not `KIMI_API_KEY` — deliberate,
|
|
474
|
+
matching Moonshot AI's own docs (the API/company behind Kimi) rather than
|
|
475
|
+
this package's own provider name. `openai`/`deepseek`/`kimi`/`glm`/
|
|
476
|
+
`gemini` all reuse the same OpenAI-Chat-Completions-compatible request
|
|
477
|
+
translation, just pointed at each provider's own base URL — see
|
|
478
|
+
`core/model-calls/*.ts` for the provider-specific details (base URLs,
|
|
479
|
+
`max_completion_tokens` vs `max_tokens`, and Gemini's own "still in beta"
|
|
480
|
+
caveat on Google's compatibility layer).
|
|
469
481
|
|
|
470
482
|
For anything else (a custom SDK client, a canned/simulated model for
|
|
471
483
|
testing), export your own `createModelCall(): ModelCall` instead.
|
package/dist/bin/cli.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare class AgentNotFoundError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
export declare class AgentModelError extends Error {
|
|
9
9
|
}
|
|
10
|
-
type Provider = 'anthropic' | 'openai' | 'deepseek';
|
|
10
|
+
type Provider = 'anthropic' | 'openai' | 'deepseek' | 'kimi' | 'glm' | 'gemini';
|
|
11
11
|
export interface AgentTemplateOptions {
|
|
12
12
|
systemPrompt?: string;
|
|
13
13
|
model?: {
|
package/dist/bin/cli.js
CHANGED
|
@@ -26,6 +26,11 @@ const MODEL_ENV_VAR = {
|
|
|
26
26
|
anthropic: 'ANTHROPIC_API_KEY',
|
|
27
27
|
openai: 'OPENAI_API_KEY',
|
|
28
28
|
deepseek: 'DEEPSEEK_API_KEY',
|
|
29
|
+
// Moonshot AI's own env var name, not KIMI_API_KEY — see
|
|
30
|
+
// kimi-model-call.ts's own header comment for why.
|
|
31
|
+
kimi: 'MOONSHOT_API_KEY',
|
|
32
|
+
glm: 'GLM_API_KEY',
|
|
33
|
+
gemini: 'GEMINI_API_KEY',
|
|
29
34
|
};
|
|
30
35
|
// Escapes a value for safe interpolation into a single-quoted TS string
|
|
31
36
|
// literal in generated code — an operator-supplied systemPrompt (from
|
|
@@ -237,9 +237,10 @@ export type HttpNotifierConfig = {
|
|
|
237
237
|
* export your own `createModelCall` for anything this can't express (a
|
|
238
238
|
* canned/simulated `ModelCall` for a demo, a custom SDK client, a
|
|
239
239
|
* provider this doesn't list). `model` is required for `openai`/
|
|
240
|
-
* `deepseek` (no safe hardcoded default — a
|
|
241
|
-
* too often to bake one in) but optional for
|
|
242
|
-
* `'claude-sonnet-5'`), mirroring each factory's
|
|
240
|
+
* `deepseek`/`kimi`/`glm`/`gemini` (no safe hardcoded default — a
|
|
241
|
+
* flagship model name changes too often to bake one in) but optional for
|
|
242
|
+
* `anthropic` (defaults to `'claude-sonnet-5'`), mirroring each factory's
|
|
243
|
+
* own options exactly. */
|
|
243
244
|
export type AgentModelConfig = {
|
|
244
245
|
provider: 'anthropic';
|
|
245
246
|
model?: string;
|
|
@@ -256,6 +257,24 @@ export type AgentModelConfig = {
|
|
|
256
257
|
apiKey?: string;
|
|
257
258
|
maxTokens?: number;
|
|
258
259
|
baseURL?: string;
|
|
260
|
+
} | {
|
|
261
|
+
provider: 'kimi';
|
|
262
|
+
model: string;
|
|
263
|
+
apiKey?: string;
|
|
264
|
+
maxTokens?: number;
|
|
265
|
+
baseURL?: string;
|
|
266
|
+
} | {
|
|
267
|
+
provider: 'glm';
|
|
268
|
+
model: string;
|
|
269
|
+
apiKey?: string;
|
|
270
|
+
maxTokens?: number;
|
|
271
|
+
baseURL?: string;
|
|
272
|
+
} | {
|
|
273
|
+
provider: 'gemini';
|
|
274
|
+
model: string;
|
|
275
|
+
apiKey?: string;
|
|
276
|
+
maxTokens?: number;
|
|
277
|
+
baseURL?: string;
|
|
259
278
|
};
|
|
260
279
|
export interface ToolSchema {
|
|
261
280
|
name: string;
|
|
@@ -47,8 +47,20 @@ export async function synthesizeCreateModelCall(model) {
|
|
|
47
47
|
const { createOpenAIModelCall } = await import('./model-calls/openai-model-call.js');
|
|
48
48
|
return () => (cached ??= createOpenAIModelCall(model));
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
if (model.provider === 'deepseek') {
|
|
51
|
+
const { createDeepSeekModelCall } = await import('./model-calls/deepseek-model-call.js');
|
|
52
|
+
return () => (cached ??= createDeepSeekModelCall(model));
|
|
53
|
+
}
|
|
54
|
+
if (model.provider === 'kimi') {
|
|
55
|
+
const { createKimiModelCall } = await import('./model-calls/kimi-model-call.js');
|
|
56
|
+
return () => (cached ??= createKimiModelCall(model));
|
|
57
|
+
}
|
|
58
|
+
if (model.provider === 'glm') {
|
|
59
|
+
const { createGlmModelCall } = await import('./model-calls/glm-model-call.js');
|
|
60
|
+
return () => (cached ??= createGlmModelCall(model));
|
|
61
|
+
}
|
|
62
|
+
const { createGeminiModelCall } = await import('./model-calls/gemini-model-call.js');
|
|
63
|
+
return () => (cached ??= createGeminiModelCall(model));
|
|
52
64
|
}
|
|
53
65
|
/** Resolves one directory entry to an agent module's path, or undefined if
|
|
54
66
|
* this entry isn't one — a `.ts`/`.js` file directly (the common case), or
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import type { ModelCall } from '#core/run-agent.js';
|
|
3
|
+
export interface GeminiModelCallOptions {
|
|
4
|
+
/** Defaults to the GEMINI_API_KEY env var. */
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
/** No hardcoded default — same reasoning as OpenAIModelCallOptions.model:
|
|
7
|
+
* pass the one you actually want. */
|
|
8
|
+
model: string;
|
|
9
|
+
maxTokens?: number;
|
|
10
|
+
/** Defaults to Google's own OpenAI-compatible endpoint — override to
|
|
11
|
+
* point at a proxy/mirror. Trailing slash required (see this file's
|
|
12
|
+
* own header comment). */
|
|
13
|
+
baseURL?: string;
|
|
14
|
+
/** Inject a pre-configured client instead of building one from apiKey/baseURL — e.g. to pass a custom `fetch` in tests. */
|
|
15
|
+
client?: OpenAI;
|
|
16
|
+
}
|
|
17
|
+
export declare function createGeminiModelCall(options: GeminiModelCallOptions): ModelCall;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// A sixth real ModelCall implementation. Google's own OpenAI-compatible
|
|
2
|
+
// endpoint for Gemini (ai.google.dev/gemini-api/docs/openai) supports the
|
|
3
|
+
// same messages/tools/tool_choice request shape and tool_calls response
|
|
4
|
+
// shape as OpenAI's Chat Completions API, so this reuses
|
|
5
|
+
// openai-model-call.ts's translation verbatim via the real `openai` SDK
|
|
6
|
+
// client, same pattern deepseek/kimi/glm-model-call.ts already
|
|
7
|
+
// established — rather than a bespoke native @google/genai integration
|
|
8
|
+
// (Gemini's own SDK has a meaningfully different message-role/content-
|
|
9
|
+
// parts/function-calling shape).
|
|
10
|
+
//
|
|
11
|
+
// Caveat, from Google's own docs: "Support for the OpenAI libraries is
|
|
12
|
+
// still in beta while we extend feature support" — this is the one
|
|
13
|
+
// provider here riding a compatibility layer its own vendor calls beta,
|
|
14
|
+
// not a fully stable wire contract the way DeepSeek/Kimi/GLM's own docs
|
|
15
|
+
// present theirs. Uses `max_completion_tokens`, same as Kimi/GLM.
|
|
16
|
+
//
|
|
17
|
+
// The trailing slash on the base URL matters — Google's endpoint 404s
|
|
18
|
+
// without it (confirmed against their own docs' exact example URL).
|
|
19
|
+
import OpenAI from 'openai';
|
|
20
|
+
import { toMessageParams, toModelResponse } from './openai-model-call.js';
|
|
21
|
+
export function createGeminiModelCall(options) {
|
|
22
|
+
if (!options.client && !options.apiKey && !process.env.GEMINI_API_KEY) {
|
|
23
|
+
// Fails here, with a Gemini-specific message, rather than letting the
|
|
24
|
+
// OpenAI SDK's own constructor validation reject it — that error says
|
|
25
|
+
// "set OPENAI_API_KEY", which would send someone who never touched
|
|
26
|
+
// that variable chasing the wrong fix.
|
|
27
|
+
throw new Error('createGeminiModelCall: no apiKey given and GEMINI_API_KEY is not set.');
|
|
28
|
+
}
|
|
29
|
+
const client = options.client ??
|
|
30
|
+
new OpenAI({
|
|
31
|
+
// Explicitly null, not undefined, if neither is set — see
|
|
32
|
+
// kimi-model-call.ts's identical comment for why this matters even
|
|
33
|
+
// though the guard above already rules out reaching here with no
|
|
34
|
+
// key at all.
|
|
35
|
+
apiKey: options.apiKey ?? process.env.GEMINI_API_KEY ?? null,
|
|
36
|
+
baseURL: options.baseURL ?? 'https://generativelanguage.googleapis.com/v1beta/openai/',
|
|
37
|
+
});
|
|
38
|
+
const maxTokens = options.maxTokens ?? 4096;
|
|
39
|
+
return async (messages, system, tools) => {
|
|
40
|
+
const response = await client.chat.completions.create({
|
|
41
|
+
model: options.model,
|
|
42
|
+
max_completion_tokens: maxTokens,
|
|
43
|
+
messages: [{ role: 'system', content: system }, ...messages.flatMap(toMessageParams)],
|
|
44
|
+
tools: tools.length
|
|
45
|
+
? tools.map((t) => ({
|
|
46
|
+
type: 'function',
|
|
47
|
+
function: { name: t.name, description: t.description, parameters: t.input_schema },
|
|
48
|
+
}))
|
|
49
|
+
: undefined,
|
|
50
|
+
});
|
|
51
|
+
return toModelResponse(response.choices[0]);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import type { ModelCall } from '#core/run-agent.js';
|
|
3
|
+
export interface GlmModelCallOptions {
|
|
4
|
+
/** Defaults to the GLM_API_KEY env var. */
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
/** No hardcoded default — same reasoning as OpenAIModelCallOptions.model:
|
|
7
|
+
* pass the one you actually want. */
|
|
8
|
+
model: string;
|
|
9
|
+
maxTokens?: number;
|
|
10
|
+
/** Defaults to Zhipu's own API — override to point at a proxy/mirror. */
|
|
11
|
+
baseURL?: string;
|
|
12
|
+
/** Inject a pre-configured client instead of building one from apiKey/baseURL — e.g. to pass a custom `fetch` in tests. */
|
|
13
|
+
client?: OpenAI;
|
|
14
|
+
}
|
|
15
|
+
export declare function createGlmModelCall(options: GlmModelCallOptions): ModelCall;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// A fifth real ModelCall implementation. GLM (Zhipu AI / Z.ai)'s Chat
|
|
2
|
+
// Completions API is OpenAI-compatible — confirmed against Zhipu's own
|
|
3
|
+
// docs (docs.bigmodel.cn/cn/guide/develop/openai/introduction): same
|
|
4
|
+
// messages/tools/tool_choice request shape, same tool_calls response
|
|
5
|
+
// shape — so this reuses openai-model-call.ts's message/response
|
|
6
|
+
// translation verbatim via the real `openai` SDK client, just pointed at
|
|
7
|
+
// Zhipu's base URL, rather than duplicating that logic. Same pattern
|
|
8
|
+
// deepseek-model-call.ts/kimi-model-call.ts already established.
|
|
9
|
+
//
|
|
10
|
+
// Uses the newer `max_completion_tokens` field, same as Kimi — no
|
|
11
|
+
// DeepSeek-style documented exception for GLM.
|
|
12
|
+
import OpenAI from 'openai';
|
|
13
|
+
import { toMessageParams, toModelResponse } from './openai-model-call.js';
|
|
14
|
+
export function createGlmModelCall(options) {
|
|
15
|
+
if (!options.client && !options.apiKey && !process.env.GLM_API_KEY) {
|
|
16
|
+
// Fails here, with a GLM-specific message, rather than letting the
|
|
17
|
+
// OpenAI SDK's own constructor validation reject it — that error says
|
|
18
|
+
// "set OPENAI_API_KEY", which would send someone who never touched
|
|
19
|
+
// that variable chasing the wrong fix.
|
|
20
|
+
throw new Error('createGlmModelCall: no apiKey given and GLM_API_KEY is not set.');
|
|
21
|
+
}
|
|
22
|
+
const client = options.client ??
|
|
23
|
+
new OpenAI({
|
|
24
|
+
// Explicitly null, not undefined, if neither is set — see
|
|
25
|
+
// kimi-model-call.ts's identical comment for why this matters even
|
|
26
|
+
// though the guard above already rules out reaching here with no
|
|
27
|
+
// key at all.
|
|
28
|
+
apiKey: options.apiKey ?? process.env.GLM_API_KEY ?? null,
|
|
29
|
+
baseURL: options.baseURL ?? 'https://open.bigmodel.cn/api/paas/v4/',
|
|
30
|
+
});
|
|
31
|
+
const maxTokens = options.maxTokens ?? 4096;
|
|
32
|
+
return async (messages, system, tools) => {
|
|
33
|
+
const response = await client.chat.completions.create({
|
|
34
|
+
model: options.model,
|
|
35
|
+
max_completion_tokens: maxTokens,
|
|
36
|
+
messages: [{ role: 'system', content: system }, ...messages.flatMap(toMessageParams)],
|
|
37
|
+
tools: tools.length
|
|
38
|
+
? tools.map((t) => ({
|
|
39
|
+
type: 'function',
|
|
40
|
+
function: { name: t.name, description: t.description, parameters: t.input_schema },
|
|
41
|
+
}))
|
|
42
|
+
: undefined,
|
|
43
|
+
});
|
|
44
|
+
return toModelResponse(response.choices[0]);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import type { ModelCall } from '#core/run-agent.js';
|
|
3
|
+
export interface KimiModelCallOptions {
|
|
4
|
+
/** Defaults to the MOONSHOT_API_KEY env var. */
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
/** No hardcoded default — same reasoning as OpenAIModelCallOptions.model:
|
|
7
|
+
* pass the one you actually want. */
|
|
8
|
+
model: string;
|
|
9
|
+
maxTokens?: number;
|
|
10
|
+
/** Defaults to Moonshot's own API — override to point at a proxy/mirror. */
|
|
11
|
+
baseURL?: string;
|
|
12
|
+
/** Inject a pre-configured client instead of building one from apiKey/baseURL — e.g. to pass a custom `fetch` in tests. */
|
|
13
|
+
client?: OpenAI;
|
|
14
|
+
}
|
|
15
|
+
export declare function createKimiModelCall(options: KimiModelCallOptions): ModelCall;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// A fourth real ModelCall implementation. Kimi (Moonshot AI)'s Chat
|
|
2
|
+
// Completions API is wire-compatible with OpenAI's — confirmed against
|
|
3
|
+
// Moonshot's own docs (platform.kimi.ai/docs/api/chat): same messages/
|
|
4
|
+
// tools/tool_choice request shape, same tool_calls response shape — so
|
|
5
|
+
// this reuses openai-model-call.ts's message/response translation
|
|
6
|
+
// verbatim via the real `openai` SDK client, just pointed at Moonshot's
|
|
7
|
+
// base URL, rather than duplicating that logic. Same pattern
|
|
8
|
+
// deepseek-model-call.ts already established for a third provider.
|
|
9
|
+
//
|
|
10
|
+
// Unlike DeepSeek, Moonshot's docs use the newer `max_completion_tokens`
|
|
11
|
+
// field (matching the current OpenAI SDK) rather than the deprecated
|
|
12
|
+
// `max_tokens` DeepSeek's own docs still list — decided at the request-
|
|
13
|
+
// building call site below, since toMessageParams/toModelResponse don't
|
|
14
|
+
// touch that field either way.
|
|
15
|
+
//
|
|
16
|
+
// Env var is MOONSHOT_API_KEY, not KIMI_API_KEY, despite every other
|
|
17
|
+
// provider here matching its own literal exactly — deliberate: this
|
|
18
|
+
// matches the underlying API/company's own docs and what anyone
|
|
19
|
+
// copy-pasting from Moonshot's own examples already has set, not this
|
|
20
|
+
// package's own provider name.
|
|
21
|
+
import OpenAI from 'openai';
|
|
22
|
+
import { toMessageParams, toModelResponse } from './openai-model-call.js';
|
|
23
|
+
export function createKimiModelCall(options) {
|
|
24
|
+
if (!options.client && !options.apiKey && !process.env.MOONSHOT_API_KEY) {
|
|
25
|
+
// Fails here, with a Kimi-specific message, rather than letting the
|
|
26
|
+
// OpenAI SDK's own constructor validation reject it — that error says
|
|
27
|
+
// "set OPENAI_API_KEY", which would send someone who never touched
|
|
28
|
+
// that variable chasing the wrong fix.
|
|
29
|
+
throw new Error('createKimiModelCall: no apiKey given and MOONSHOT_API_KEY is not set.');
|
|
30
|
+
}
|
|
31
|
+
const client = options.client ??
|
|
32
|
+
new OpenAI({
|
|
33
|
+
// Explicitly null, not undefined, if neither is set — the OpenAI
|
|
34
|
+
// SDK's own constructor falls back to reading OPENAI_API_KEY itself
|
|
35
|
+
// when apiKey is undefined (its normal, correct behavior for
|
|
36
|
+
// createOpenAIModelCall), which here would silently authenticate
|
|
37
|
+
// against Moonshot with an OpenAI key if one happens to be set. The
|
|
38
|
+
// guard above already rules out reaching here with no key at all,
|
|
39
|
+
// but null (not undefined) is kept regardless so this line is
|
|
40
|
+
// correct on its own, not just because of the guard before it.
|
|
41
|
+
apiKey: options.apiKey ?? process.env.MOONSHOT_API_KEY ?? null,
|
|
42
|
+
baseURL: options.baseURL ?? 'https://api.moonshot.ai/v1',
|
|
43
|
+
});
|
|
44
|
+
const maxTokens = options.maxTokens ?? 4096;
|
|
45
|
+
return async (messages, system, tools) => {
|
|
46
|
+
const response = await client.chat.completions.create({
|
|
47
|
+
model: options.model,
|
|
48
|
+
max_completion_tokens: maxTokens,
|
|
49
|
+
messages: [{ role: 'system', content: system }, ...messages.flatMap(toMessageParams)],
|
|
50
|
+
tools: tools.length
|
|
51
|
+
? tools.map((t) => ({
|
|
52
|
+
type: 'function',
|
|
53
|
+
function: { name: t.name, description: t.description, parameters: t.input_schema },
|
|
54
|
+
}))
|
|
55
|
+
: undefined,
|
|
56
|
+
});
|
|
57
|
+
return toModelResponse(response.choices[0]);
|
|
58
|
+
};
|
|
59
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ export { createOpenAIModelCall } from './core/model-calls/openai-model-call.js';
|
|
|
14
14
|
export type { OpenAIModelCallOptions } from './core/model-calls/openai-model-call.js';
|
|
15
15
|
export { createDeepSeekModelCall } from './core/model-calls/deepseek-model-call.js';
|
|
16
16
|
export type { DeepSeekModelCallOptions } from './core/model-calls/deepseek-model-call.js';
|
|
17
|
+
export { createKimiModelCall } from './core/model-calls/kimi-model-call.js';
|
|
18
|
+
export type { KimiModelCallOptions } from './core/model-calls/kimi-model-call.js';
|
|
19
|
+
export { createGlmModelCall } from './core/model-calls/glm-model-call.js';
|
|
20
|
+
export type { GlmModelCallOptions } from './core/model-calls/glm-model-call.js';
|
|
21
|
+
export { createGeminiModelCall } from './core/model-calls/gemini-model-call.js';
|
|
22
|
+
export type { GeminiModelCallOptions } from './core/model-calls/gemini-model-call.js';
|
|
17
23
|
export { discoverAgents, loadAgentModule, synthesizeCreateModelCall } from './core/discover-agents.js';
|
|
18
24
|
export type { AgentModule } from './core/discover-agents.js';
|
|
19
25
|
export { agentAsTool } from './core/agent-as-tool.js';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,9 @@ export { VectorIndex, embed, cosineSimilarity } from './core/vector-index.js';
|
|
|
16
16
|
export { createAnthropicModelCall } from './core/model-calls/anthropic-model-call.js';
|
|
17
17
|
export { createOpenAIModelCall } from './core/model-calls/openai-model-call.js';
|
|
18
18
|
export { createDeepSeekModelCall } from './core/model-calls/deepseek-model-call.js';
|
|
19
|
+
export { createKimiModelCall } from './core/model-calls/kimi-model-call.js';
|
|
20
|
+
export { createGlmModelCall } from './core/model-calls/glm-model-call.js';
|
|
21
|
+
export { createGeminiModelCall } from './core/model-calls/gemini-model-call.js';
|
|
19
22
|
export { discoverAgents, loadAgentModule, synthesizeCreateModelCall } from './core/discover-agents.js';
|
|
20
23
|
export { agentAsTool } from './core/agent-as-tool.js';
|
|
21
24
|
// Everything below backs the Admin UI (agents-config/list/global-config
|
|
@@ -2,7 +2,7 @@ export declare class AgentEditNotSupportedError extends Error {
|
|
|
2
2
|
}
|
|
3
3
|
export declare class AgentFileNotFoundError extends Error {
|
|
4
4
|
}
|
|
5
|
-
type Provider = 'anthropic' | 'openai' | 'deepseek';
|
|
5
|
+
type Provider = 'anthropic' | 'openai' | 'deepseek' | 'kimi' | 'glm' | 'gemini';
|
|
6
6
|
export interface AgentEditableFields {
|
|
7
7
|
systemPrompt?: string;
|
|
8
8
|
model?: {
|
|
@@ -45,6 +45,11 @@ const MODEL_ENV_VAR = {
|
|
|
45
45
|
anthropic: 'ANTHROPIC_API_KEY',
|
|
46
46
|
openai: 'OPENAI_API_KEY',
|
|
47
47
|
deepseek: 'DEEPSEEK_API_KEY',
|
|
48
|
+
// Moonshot AI's own env var name, not KIMI_API_KEY — see
|
|
49
|
+
// core/model-calls/kimi-model-call.ts's own header comment for why.
|
|
50
|
+
kimi: 'MOONSHOT_API_KEY',
|
|
51
|
+
glm: 'GLM_API_KEY',
|
|
52
|
+
gemini: 'GEMINI_API_KEY',
|
|
48
53
|
};
|
|
49
54
|
// The exact shape agentIndexTemplate (bin/cli.ts) always generates for the
|
|
50
55
|
// model field's trailing comment — used to recognize a comment this
|
|
@@ -653,7 +653,7 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
653
653
|
'<form class="add-source" id="modelForm" style="display:none">' +
|
|
654
654
|
'<label>Provider' +
|
|
655
655
|
'<select name="provider">' +
|
|
656
|
-
['anthropic', 'openai', 'deepseek'].map(function (p) {
|
|
656
|
+
['anthropic', 'openai', 'deepseek', 'kimi', 'glm', 'gemini'].map(function (p) {
|
|
657
657
|
return '<option value="' + p + '"' + (p === cfg.model.provider ? ' selected' : '') + '>' + p + '</option>';
|
|
658
658
|
}).join('') +
|
|
659
659
|
'</select>' +
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentConfig } from '../core/agent-config.js';
|
|
2
2
|
export interface ModelProviderInfo {
|
|
3
|
-
provider: 'anthropic' | 'openai' | 'deepseek';
|
|
3
|
+
provider: 'anthropic' | 'openai' | 'deepseek' | 'kimi' | 'glm' | 'gemini';
|
|
4
4
|
envVar: string;
|
|
5
5
|
configured: boolean;
|
|
6
6
|
}
|
|
@@ -8,6 +8,11 @@ const KNOWN_PROVIDERS = [
|
|
|
8
8
|
{ provider: 'anthropic', envVar: 'ANTHROPIC_API_KEY' },
|
|
9
9
|
{ provider: 'openai', envVar: 'OPENAI_API_KEY' },
|
|
10
10
|
{ provider: 'deepseek', envVar: 'DEEPSEEK_API_KEY' },
|
|
11
|
+
// Moonshot AI's own env var name, not KIMI_API_KEY — see
|
|
12
|
+
// core/model-calls/kimi-model-call.ts's own header comment for why.
|
|
13
|
+
{ provider: 'kimi', envVar: 'MOONSHOT_API_KEY' },
|
|
14
|
+
{ provider: 'glm', envVar: 'GLM_API_KEY' },
|
|
15
|
+
{ provider: 'gemini', envVar: 'GEMINI_API_KEY' },
|
|
11
16
|
];
|
|
12
17
|
/** Every registered agent's resolved model, alongside whether each
|
|
13
18
|
* supported provider actually has credentials available in this
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loopengine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Runtime for tool-using AI agents with a transparent ReAct loop.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
"dist/core/model-calls/openai-model-call.d.ts",
|
|
42
42
|
"dist/core/model-calls/deepseek-model-call.js",
|
|
43
43
|
"dist/core/model-calls/deepseek-model-call.d.ts",
|
|
44
|
+
"dist/core/model-calls/kimi-model-call.js",
|
|
45
|
+
"dist/core/model-calls/kimi-model-call.d.ts",
|
|
46
|
+
"dist/core/model-calls/glm-model-call.js",
|
|
47
|
+
"dist/core/model-calls/glm-model-call.d.ts",
|
|
48
|
+
"dist/core/model-calls/gemini-model-call.js",
|
|
49
|
+
"dist/core/model-calls/gemini-model-call.d.ts",
|
|
44
50
|
"dist/core/discover-agents.js",
|
|
45
51
|
"dist/core/discover-agents.d.ts",
|
|
46
52
|
"dist/core/agent-as-tool.js",
|