operon-agents 0.1.0-alpha.2 → 0.1.0-alpha.21
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 +42 -0
- package/dist/app-server/client.js +8 -5
- package/dist/app-server/main.js +1 -1
- package/dist/app-server/params.d.ts +115 -0
- package/dist/app-server/params.js +81 -0
- package/dist/app-server/protocol.d.ts +10 -4
- package/dist/app-server/protocol.js +45 -37
- package/dist/app-server/server.d.ts +0 -1
- package/dist/app-server/server.js +46 -35
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/cron/cron-expr.js +1 -1
- package/dist/cron/extension.js +2 -2
- package/dist/extensions/index.d.ts +19 -5
- package/dist/extensions/index.js +66 -10
- package/dist/extensions/loader.d.ts +2 -2
- package/dist/extensions/loader.js +23 -15
- package/dist/extensions/manager.d.ts +15 -13
- package/dist/extensions/manager.js +28 -25
- package/dist/extensions/runtime.d.ts +69 -74
- package/dist/extensions/runtime.js +183 -381
- package/dist/extensions/types.d.ts +55 -45
- package/dist/harness.d.ts +339 -180
- package/dist/harness.js +673 -420
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/local.d.ts +25 -8
- package/dist/local.js +103 -33
- package/dist/providers.d.ts +144 -0
- package/dist/providers.js +280 -0
- package/dist/telemetry-posthog.d.ts +88 -0
- package/dist/telemetry-posthog.js +142 -0
- package/dist/telemetry.d.ts +4 -0
- package/dist/telemetry.js +3 -0
- package/dist/workspace-mcp.d.ts +62 -0
- package/dist/workspace-mcp.js +222 -0
- package/package.json +10 -3
package/dist/index.d.ts
CHANGED
|
@@ -14,11 +14,14 @@
|
|
|
14
14
|
export * from "./harness.ts";
|
|
15
15
|
export * from "./extensions/index.ts";
|
|
16
16
|
export * from "./cron/index.ts";
|
|
17
|
+
export * from "./providers.ts";
|
|
17
18
|
export * from "./local.ts";
|
|
19
|
+
export * from "./workspace-mcp.ts";
|
|
18
20
|
export * from "operon-agents-core";
|
|
19
21
|
export * as llm from "operon-agents-core/llm";
|
|
20
22
|
export * as mcp from "operon-agents-core/mcp";
|
|
21
23
|
export * as protocol from "operon-agents-core/protocol";
|
|
22
24
|
export * as tools from "operon-agents-core/tools";
|
|
23
25
|
export * as tracing from "operon-agents-core/tracing";
|
|
26
|
+
export * as telemetry from "./telemetry.ts";
|
|
24
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -16,8 +16,12 @@ export * from "./harness.js";
|
|
|
16
16
|
// Core supplies the primitives they are built on (Capability / LoopHooks / ToolFilter / Injector).
|
|
17
17
|
export * from "./extensions/index.js";
|
|
18
18
|
export * from "./cron/index.js";
|
|
19
|
+
// Model providers the host configures (a self-hosted endpoint, a gateway) — see providers.ts.
|
|
20
|
+
export * from "./providers.js";
|
|
19
21
|
// Deployment composition roots: local vs server injection presets (Invariant 7 — no engine "mode").
|
|
20
22
|
export * from "./local.js";
|
|
23
|
+
// Per-directory MCP sharing for hosts that open many sessions in one folder (a desktop app).
|
|
24
|
+
export * from "./workspace-mcp.js";
|
|
21
25
|
// The curated core engine, re-exported for convenience; `operon-agents/core` is the dedicated
|
|
22
26
|
// primitives entrypoint.
|
|
23
27
|
export * from "operon-agents-core";
|
|
@@ -26,4 +30,5 @@ export * as mcp from "operon-agents-core/mcp";
|
|
|
26
30
|
export * as protocol from "operon-agents-core/protocol";
|
|
27
31
|
export * as tools from "operon-agents-core/tools";
|
|
28
32
|
export * as tracing from "operon-agents-core/tracing";
|
|
33
|
+
export * as telemetry from "./telemetry.js";
|
|
29
34
|
//# sourceMappingURL=index.js.map
|
package/dist/internal.d.ts
CHANGED
package/dist/internal.js
CHANGED
package/dist/local.d.ts
CHANGED
|
@@ -1,24 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { type
|
|
1
|
+
import type { ModelRuntime } from "operon-agents-core";
|
|
2
|
+
import { type HookDef, type Logger, type McpServerConfig, type PluginManager } from "operon-agents-core";
|
|
3
|
+
import { type Harness, type HarnessOptions } from "./harness.ts";
|
|
3
4
|
export interface LocalDeploymentOptions<TContext = unknown> extends HarnessOptions<TContext> {
|
|
4
5
|
/**
|
|
5
6
|
* App home root — sessions (`<homeDir>/sessions`), MCP creds, logs, and disk-discovered agent
|
|
6
7
|
* profiles all live under it. Defaults to `~/.agents`. (`homeDir` is a local-deployment concept;
|
|
7
|
-
* the harness itself only knows `
|
|
8
|
+
* the harness itself only knows `HarnessParts.sessionRepository`.)
|
|
8
9
|
*/
|
|
9
10
|
readonly homeDir?: string;
|
|
10
|
-
/**
|
|
11
|
+
/** MCP servers to expose, shared by every session of the harness. */
|
|
11
12
|
readonly mcpServers?: Record<string, McpServerConfig>;
|
|
12
|
-
/** Installed-plugin manager, if any. */
|
|
13
|
+
/** Installed-plugin manager, if any. Loaded once here, then handed out as `HarnessParts.pluginManager`. */
|
|
13
14
|
readonly pluginManager?: PluginManager;
|
|
14
15
|
/** Shell hooks from config (`config.hooks`), projected as HookDefs. */
|
|
15
16
|
readonly hooks?: readonly HookDef[];
|
|
16
17
|
/** Discover agent profiles from disk (`<homeDir>/agents` + `<cwd>/.agents/agents`). Default true. */
|
|
17
18
|
readonly loadDiskProfiles?: boolean;
|
|
19
|
+
/** Diagnostics logger. Defaults to a rotating file under `<homeDir>/logs`. */
|
|
20
|
+
readonly logger?: Logger;
|
|
21
|
+
/** Context budget for the default compaction capability. */
|
|
22
|
+
readonly maxContextTokens?: number;
|
|
23
|
+
/**
|
|
24
|
+
* The model runtime this harness resolves providers through. Pass the same one the host used to
|
|
25
|
+
* build its `ChatModel` (see `createModelRuntimeFromConfig`) when a model lives on a configured
|
|
26
|
+
* endpoint — otherwise the two registries disagree about what exists. Omitted, the harness builds
|
|
27
|
+
* one from `<homeDir>/providers.toml` itself.
|
|
28
|
+
*/
|
|
29
|
+
readonly modelRuntime?: ModelRuntime;
|
|
30
|
+
/** Skip reading `<homeDir>/providers.toml` entirely. Ignored when `modelRuntime` is given. */
|
|
31
|
+
readonly loadConfiguredProviders?: boolean;
|
|
18
32
|
}
|
|
19
|
-
/** Build `HarnessOptions` wired for a local, single-
|
|
33
|
+
/** Build `HarnessOptions` wired for a local, single-environment deployment. */
|
|
20
34
|
export declare function localHarnessOptions<TContext>(options: LocalDeploymentOptions<TContext>): Promise<HarnessOptions<TContext>>;
|
|
35
|
+
/**
|
|
36
|
+
* The local entry point: one harness per process, one `createSession()` per conversation on it.
|
|
37
|
+
* Its `close()` closes those sessions and then the harness scope — the cron timer, the workspace
|
|
38
|
+
* MCP connections and the rotating log handle all live there, so nothing else tears them down.
|
|
39
|
+
*/
|
|
21
40
|
export declare function createLocalHarness<TContext = unknown>(options: LocalDeploymentOptions<TContext>): Promise<Harness<TContext>>;
|
|
22
|
-
/** Convenience: a local harness with one session opened and ready to `prompt()`. */
|
|
23
|
-
export declare function createLocalSession<TContext = unknown>(options: LocalDeploymentOptions<TContext>, session?: CreateSessionOptions<TContext>): Promise<HarnessSession<TContext>>;
|
|
24
41
|
//# sourceMappingURL=local.d.ts.map
|
package/dist/local.js
CHANGED
|
@@ -1,58 +1,128 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The local composition root — every convention a single-
|
|
3
|
-
* bundled in one place: disk sessions under `<homeDir>/sessions`, the local
|
|
2
|
+
* The local composition root — every convention a single-environment, single-operator app runs on,
|
|
3
|
+
* bundled in one place: disk sessions under `<homeDir>/sessions`, the local environment, a rotating
|
|
4
4
|
* file log, file-backed MCP credentials, disk-discovered agent profiles, and the cron extension.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* There is still no "mode" inside the engine (Architecture Invariant 7): this file only picks
|
|
13
|
-
* backends, and returns a plain `Harness` nothing downstream can distinguish.
|
|
6
|
+
* It is a PRESET: pure data in (`LocalDeploymentOptions`), the three composition hooks out.
|
|
7
|
+
* The `harness` hook registers the process-lived objects on the harness scope; the `session`
|
|
8
|
+
* hook builds each session's capability set. A hosted deployment writes its own preset the same
|
|
9
|
+
* way (see `examples/managed-agents`) — there is still no "mode" inside the engine
|
|
10
|
+
* (Architecture Invariant 7): this file only picks backends, and returns plain `HarnessOptions`
|
|
11
|
+
* nothing downstream can distinguish.
|
|
14
12
|
*/
|
|
15
13
|
import { homedir } from "node:os";
|
|
16
14
|
import { cronExtension } from "./cron/index.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
15
|
+
import { createModelRuntimeFromConfig } from "./providers.js";
|
|
16
|
+
import { join, resolve } from "node:path";
|
|
17
|
+
import { DiskSessionRepository, LocalEnvironment, McpOAuthService, RotatingFileSink, SkillRegistry, createMcpServers, loadSkillRoots, loadAgentProfiles, resolveGlobalLogPath, sinkLogger, } from "operon-agents-core";
|
|
19
18
|
import { createHarness, defaultCapabilities, } from "./harness.js";
|
|
20
|
-
/** Build `HarnessOptions` wired for a local, single-
|
|
19
|
+
/** Build `HarnessOptions` wired for a local, single-environment deployment. */
|
|
21
20
|
export async function localHarnessOptions(options) {
|
|
22
|
-
const homeDir
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
21
|
+
const { homeDir: home, mcpServers, pluginManager, hooks, loadDiskProfiles, logger, maxContextTokens, modelRuntime, loadConfiguredProviders, harness, session, extensions, ...engine } = options;
|
|
22
|
+
// Filled by the `harness` half below, read by the `session` half — one process, one set.
|
|
23
|
+
let sharedParts = {};
|
|
24
|
+
// Set when the shared skill scan ran through a LocalEnvironment at the default workDir (the host
|
|
25
|
+
// named no environment): that catalog only describes sessions rooted there.
|
|
26
|
+
let sharedSkillsWorkDir;
|
|
27
|
+
const homeDir = home ?? join(homedir(), ".agents");
|
|
27
28
|
// Agent profiles come from disk here; the server preset supplies them externally instead.
|
|
28
29
|
const extraSubagentProfiles = options.extraSubagentProfiles ??
|
|
29
|
-
((
|
|
30
|
+
((loadDiskProfiles ?? true)
|
|
30
31
|
? await loadAgentProfiles({ homeDir, cwd: options.workDir ?? process.cwd() })
|
|
31
32
|
: undefined);
|
|
33
|
+
// Installed plugins are read ONCE per process, not per session: the manager is a harness-tier
|
|
34
|
+
// object, and `session.plugins.reload()` is the explicit refresh.
|
|
35
|
+
if (pluginManager !== undefined)
|
|
36
|
+
await pluginManager.load();
|
|
37
|
+
// Configured endpoints are resolved once per harness, not per session: the registry is a
|
|
38
|
+
// harness-tier object, and a session only ever reads it.
|
|
39
|
+
const runtime = modelRuntime ??
|
|
40
|
+
((loadConfiguredProviders ?? true)
|
|
41
|
+
? await createModelRuntimeFromConfig({ homeDir })
|
|
42
|
+
: undefined);
|
|
32
43
|
return {
|
|
33
|
-
...
|
|
34
|
-
// Disk sessions under <homeDir>/sessions; an injected repository still wins. The machine defaults to local.
|
|
35
|
-
repository: options.repository ?? new DiskSessionRepository(homeDir),
|
|
36
|
-
logger,
|
|
44
|
+
...engine,
|
|
37
45
|
...(extraSubagentProfiles !== undefined ? { extraSubagentProfiles } : {}),
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
harness: async () => {
|
|
47
|
+
// Disk sessions under <homeDir>/sessions; diagnostics roll on disk under <homeDir>/logs.
|
|
48
|
+
// The MCP connections, the skill scan and the OAuth store are process-wide: one set for
|
|
49
|
+
// every session this harness opens, built once, here.
|
|
50
|
+
const oauthService = new McpOAuthService({ homeDir });
|
|
51
|
+
const configs = { ...(mcpServers ?? {}), ...(pluginManager?.mcpServerConfigs() ?? {}) };
|
|
52
|
+
let servers;
|
|
53
|
+
if (Object.keys(configs).length > 0) {
|
|
54
|
+
servers = createMcpServers(configs, { oauthService });
|
|
55
|
+
// The set has no session and no event sink of its own: failures surface through
|
|
56
|
+
// `onStatusChange`, which each session subscribes to when it views it.
|
|
57
|
+
await servers.connect({ sessionId: "" });
|
|
58
|
+
}
|
|
59
|
+
const fromHost = await harness?.();
|
|
60
|
+
// Skills follow the EXECUTION environment, not the host's disk: the catalog the model sees
|
|
61
|
+
// must be the one whose scripts its Bash can reach. A host that named an environment above
|
|
62
|
+
// is scanned through it; an environment FACTORY (one per session) has no single filesystem
|
|
63
|
+
// to scan, so there is no shared registry then and each session scans through its own.
|
|
64
|
+
//
|
|
65
|
+
// A host that named none gets NO harness-wide environment: each session runs in a
|
|
66
|
+
// LocalEnvironment at its own workDir (the harness's fallback). The shared scan then goes
|
|
67
|
+
// through the default workDir and is reused only by sessions rooted there.
|
|
68
|
+
const hostEnvironment = fromHost?.environment;
|
|
69
|
+
const defaultWorkDir = resolve(options.workDir ?? process.cwd());
|
|
70
|
+
const scanEnvironment = hostEnvironment ?? new LocalEnvironment(defaultWorkDir);
|
|
71
|
+
let skillRegistry = fromHost?.skillRegistry;
|
|
72
|
+
if (skillRegistry === undefined && typeof scanEnvironment !== "function") {
|
|
73
|
+
skillRegistry = new SkillRegistry();
|
|
74
|
+
await loadSkillRoots(scanEnvironment, skillRegistry, {
|
|
75
|
+
...(pluginManager !== undefined ? { roots: pluginManager.skillRoots(), includeDefaultRoots: true } : {}),
|
|
76
|
+
});
|
|
77
|
+
if (hostEnvironment === undefined)
|
|
78
|
+
sharedSkillsWorkDir = defaultWorkDir;
|
|
79
|
+
}
|
|
80
|
+
sharedParts = {
|
|
81
|
+
sessionRepository: new DiskSessionRepository(homeDir),
|
|
82
|
+
logger: logger ?? sinkLogger(new RotatingFileSink({ path: resolveGlobalLogPath({ homeDir }) })),
|
|
44
83
|
oauthService,
|
|
84
|
+
...(hostEnvironment !== undefined ? { environment: hostEnvironment } : {}),
|
|
85
|
+
...(servers !== undefined ? { mcpServers: servers } : {}),
|
|
86
|
+
...(skillRegistry !== undefined ? { skillRegistry } : {}),
|
|
87
|
+
...(pluginManager !== undefined ? { pluginManager } : {}),
|
|
88
|
+
// What `ExtensionHost.registerProvider` mutates, and where a session's model is looked up.
|
|
89
|
+
...(runtime !== undefined ? { modelRuntime: runtime } : {}),
|
|
90
|
+
...fromHost,
|
|
91
|
+
close: async () => {
|
|
92
|
+
await fromHost?.close?.();
|
|
93
|
+
await servers?.shutdown();
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
return sharedParts;
|
|
97
|
+
},
|
|
98
|
+
session: session ??
|
|
99
|
+
((ctx) => defaultCapabilities({
|
|
100
|
+
shared: sessionSharedParts(sharedParts, sharedSkillsWorkDir, ctx.workDir),
|
|
101
|
+
ownEnvironment: ctx.ownEnvironment,
|
|
102
|
+
// `createSession({ mcpServers })` — layered over the process-shared connections.
|
|
103
|
+
...(ctx.mcpServers !== undefined ? { sessionMcpServers: ctx.mcpServers } : {}),
|
|
104
|
+
...(maxContextTokens !== undefined ? { maxContextTokens } : {}),
|
|
105
|
+
...(pluginManager !== undefined ? { pluginManager } : {}),
|
|
106
|
+
...(hooks !== undefined ? { hooks } : {}),
|
|
45
107
|
})),
|
|
46
108
|
// Cron rides the extension channel now: LOCAL deployments attach it, the server profile
|
|
47
109
|
// simply doesn't — Invariant 7 ("cron is local-only") is structural, not an option to pass.
|
|
48
|
-
extensions: [cronExtension(), ...(
|
|
110
|
+
extensions: [cronExtension(), ...(extensions ?? [])],
|
|
49
111
|
};
|
|
50
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* The local entry point: one harness per process, one `createSession()` per conversation on it.
|
|
115
|
+
* Its `close()` closes those sessions and then the harness scope — the cron timer, the workspace
|
|
116
|
+
* MCP connections and the rotating log handle all live there, so nothing else tears them down.
|
|
117
|
+
*/
|
|
51
118
|
export async function createLocalHarness(options) {
|
|
52
119
|
return createHarness(await localHarnessOptions(options));
|
|
53
120
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
|
|
121
|
+
/** The shared parts a session may reuse: all of them, less a skill catalog scanned for another workDir. */
|
|
122
|
+
function sessionSharedParts(parts, skillsWorkDir, workDir) {
|
|
123
|
+
if (skillsWorkDir === undefined || resolve(workDir) === skillsWorkDir)
|
|
124
|
+
return parts;
|
|
125
|
+
const { skillRegistry: _skillRegistry, ...rest } = parts;
|
|
126
|
+
return rest;
|
|
57
127
|
}
|
|
58
128
|
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model providers configured by the host, as opposed to the ones the engine ships with.
|
|
3
|
+
*
|
|
4
|
+
* The built-in catalog knows every major provider, but each of those is a fixed list at a fixed
|
|
5
|
+
* URL. A self-hosted endpoint — vLLM, Ollama, LiteLLM, a gateway, a proxy in front of a vendor —
|
|
6
|
+
* is neither: its address is local knowledge, and which models it serves is a question only that
|
|
7
|
+
* endpoint can answer. So a provider here is a URL plus how to authenticate, and its model list is
|
|
8
|
+
* fetched from the endpoint (`GET {baseUrl}/models`, the OpenAI-compatible shape every one of them
|
|
9
|
+
* speaks) rather than declared.
|
|
10
|
+
*
|
|
11
|
+
* The file is `<homeDir>/providers.toml`, so every local host — the TUI, the app server, a script
|
|
12
|
+
* that builds its own harness — sees the same providers without each inventing a config format.
|
|
13
|
+
* Nothing else in the framework reads it: this is the provider registry, not a general config.
|
|
14
|
+
*
|
|
15
|
+
* ```toml
|
|
16
|
+
* # A self-hosted endpoint. Models come from GET http://localhost:8000/v1/models.
|
|
17
|
+
* [providers.local]
|
|
18
|
+
* base_url = "http://localhost:8000/v1"
|
|
19
|
+
* api_key_env = "LOCAL_API_KEY" # optional; omit for a keyless server
|
|
20
|
+
* context_window = 128000 # the default applied to every model it reports
|
|
21
|
+
*
|
|
22
|
+
* # Per-model facts the endpoint does not report.
|
|
23
|
+
* [providers.local.models."qwen3-coder"]
|
|
24
|
+
* name = "Qwen3 Coder"
|
|
25
|
+
* context_window = 256000
|
|
26
|
+
* reasoning = true
|
|
27
|
+
*
|
|
28
|
+
* # A provider whose models are declared rather than fetched.
|
|
29
|
+
* [providers.corp]
|
|
30
|
+
* base_url = "https://llm.corp.internal/v1"
|
|
31
|
+
* api_key_env = "CORP_API_KEY"
|
|
32
|
+
* fetch_models = false
|
|
33
|
+
* [providers.corp.models."gpt-4o-mini"]
|
|
34
|
+
* context_window = 128000
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
import { type Api, type ModelRuntime } from "operon-agents-core";
|
|
39
|
+
/** The wire dialects a configured endpoint can speak. Almost everything speaks the first. */
|
|
40
|
+
export declare const PROVIDER_APIS: readonly ["openai-completions", "openai-responses", "anthropic-messages"];
|
|
41
|
+
export type ProviderApi = (typeof PROVIDER_APIS)[number];
|
|
42
|
+
declare const ProviderEntrySchema: z.ZodObject<{
|
|
43
|
+
base_url: z.ZodString;
|
|
44
|
+
name: z.ZodOptional<z.ZodString>;
|
|
45
|
+
api: z.ZodDefault<z.ZodEnum<{
|
|
46
|
+
"openai-completions": "openai-completions";
|
|
47
|
+
"openai-responses": "openai-responses";
|
|
48
|
+
"anthropic-messages": "anthropic-messages";
|
|
49
|
+
}>>;
|
|
50
|
+
api_key_env: z.ZodOptional<z.ZodString>;
|
|
51
|
+
api_key: z.ZodOptional<z.ZodString>;
|
|
52
|
+
fetch_models: z.ZodDefault<z.ZodBoolean>;
|
|
53
|
+
context_window: z.ZodDefault<z.ZodNumber>;
|
|
54
|
+
max_output_tokens: z.ZodDefault<z.ZodNumber>;
|
|
55
|
+
reasoning: z.ZodDefault<z.ZodBoolean>;
|
|
56
|
+
vision: z.ZodDefault<z.ZodBoolean>;
|
|
57
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
58
|
+
models: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
59
|
+
name: z.ZodOptional<z.ZodString>;
|
|
60
|
+
context_window: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
max_output_tokens: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
reasoning: z.ZodOptional<z.ZodBoolean>;
|
|
63
|
+
vision: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
+
api: z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
"openai-completions": "openai-completions";
|
|
66
|
+
"openai-responses": "openai-responses";
|
|
67
|
+
"anthropic-messages": "anthropic-messages";
|
|
68
|
+
}>>;
|
|
69
|
+
}, z.core.$strip>>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
export declare const ProvidersFileSchema: z.ZodObject<{
|
|
72
|
+
providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
73
|
+
base_url: z.ZodString;
|
|
74
|
+
name: z.ZodOptional<z.ZodString>;
|
|
75
|
+
api: z.ZodDefault<z.ZodEnum<{
|
|
76
|
+
"openai-completions": "openai-completions";
|
|
77
|
+
"openai-responses": "openai-responses";
|
|
78
|
+
"anthropic-messages": "anthropic-messages";
|
|
79
|
+
}>>;
|
|
80
|
+
api_key_env: z.ZodOptional<z.ZodString>;
|
|
81
|
+
api_key: z.ZodOptional<z.ZodString>;
|
|
82
|
+
fetch_models: z.ZodDefault<z.ZodBoolean>;
|
|
83
|
+
context_window: z.ZodDefault<z.ZodNumber>;
|
|
84
|
+
max_output_tokens: z.ZodDefault<z.ZodNumber>;
|
|
85
|
+
reasoning: z.ZodDefault<z.ZodBoolean>;
|
|
86
|
+
vision: z.ZodDefault<z.ZodBoolean>;
|
|
87
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
88
|
+
models: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
89
|
+
name: z.ZodOptional<z.ZodString>;
|
|
90
|
+
context_window: z.ZodOptional<z.ZodNumber>;
|
|
91
|
+
max_output_tokens: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
reasoning: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
vision: z.ZodOptional<z.ZodBoolean>;
|
|
94
|
+
api: z.ZodOptional<z.ZodEnum<{
|
|
95
|
+
"openai-completions": "openai-completions";
|
|
96
|
+
"openai-responses": "openai-responses";
|
|
97
|
+
"anthropic-messages": "anthropic-messages";
|
|
98
|
+
}>>;
|
|
99
|
+
}, z.core.$strip>>>;
|
|
100
|
+
}, z.core.$strip>>>;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
export type ProviderEntry = z.infer<typeof ProviderEntrySchema>;
|
|
103
|
+
export type ProvidersFile = z.infer<typeof ProvidersFileSchema>;
|
|
104
|
+
export interface LoadedProviders {
|
|
105
|
+
readonly providers: Readonly<Record<string, ProviderEntry>>;
|
|
106
|
+
/** Problems that did not stop the load: a malformed entry, an unreadable file. */
|
|
107
|
+
readonly warnings: readonly string[];
|
|
108
|
+
}
|
|
109
|
+
export declare function providersConfigPath(homeDir: string): string;
|
|
110
|
+
/**
|
|
111
|
+
* Read `<homeDir>/providers.toml`. A missing file is the normal case and yields no providers; a
|
|
112
|
+
* malformed one yields none plus a warning, because refusing to start over a config file the host
|
|
113
|
+
* may not even use would be worse than running with the built-in providers alone.
|
|
114
|
+
*/
|
|
115
|
+
export declare function loadProviderConfigs(homeDir: string): Promise<LoadedProviders>;
|
|
116
|
+
/** The model ids an OpenAI-compatible `/models` response lists, in the order the endpoint gave. */
|
|
117
|
+
export declare function parseModelsResponse(body: unknown): readonly string[];
|
|
118
|
+
/**
|
|
119
|
+
* Turn one config entry into a provider the engine can stream through. Its model list starts at
|
|
120
|
+
* whatever the config declared and is replaced by the endpoint's on the first refresh.
|
|
121
|
+
*/
|
|
122
|
+
export declare function providerFromConfig(providerId: string, entry: ProviderEntry): import("@earendil-works/pi-ai").Provider<Api>;
|
|
123
|
+
export interface ModelRuntimeFromConfigOptions {
|
|
124
|
+
readonly homeDir: string;
|
|
125
|
+
/**
|
|
126
|
+
* Ask each configured endpoint for its models. Default true. With it off the runtime carries
|
|
127
|
+
* only what the config declared, which is what an offline start wants.
|
|
128
|
+
*/
|
|
129
|
+
readonly refresh?: boolean;
|
|
130
|
+
/** Per-endpoint budget for the model-list fetch. Default 5s: a dead endpoint must not hang startup. */
|
|
131
|
+
readonly refreshTimeoutMs?: number;
|
|
132
|
+
readonly onWarning?: (message: string) => void;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* One model runtime carrying the engine's built-in providers plus everything in
|
|
136
|
+
* `<homeDir>/providers.toml`, with each configured endpoint asked what it serves.
|
|
137
|
+
*
|
|
138
|
+
* Hand the same runtime to `defineModel({ provider, model, runtime })` and to
|
|
139
|
+
* `createLocalHarness({ modelRuntime })`, so the model a host resolves and the models its sessions
|
|
140
|
+
* can switch to come from one registry.
|
|
141
|
+
*/
|
|
142
|
+
export declare function createModelRuntimeFromConfig(options: ModelRuntimeFromConfigOptions): Promise<ModelRuntime>;
|
|
143
|
+
export {};
|
|
144
|
+
//# sourceMappingURL=providers.d.ts.map
|