@alpacakit/agents 0.1.0-beta.19
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/LICENSE +21 -0
- package/README.md +224 -0
- package/dist/agents/builtin.d.ts +19 -0
- package/dist/agents/builtin.d.ts.map +1 -0
- package/dist/agents/builtin.js +14 -0
- package/dist/agents/claude.d.ts +20 -0
- package/dist/agents/claude.d.ts.map +1 -0
- package/dist/agents/claude.js +480 -0
- package/dist/agents/codex.d.ts +19 -0
- package/dist/agents/codex.d.ts.map +1 -0
- package/dist/agents/codex.js +355 -0
- package/dist/agents/openai-compatible/config.d.ts +16 -0
- package/dist/agents/openai-compatible/config.d.ts.map +1 -0
- package/dist/agents/openai-compatible/config.js +160 -0
- package/dist/agents/openai-compatible/engine.d.ts +18 -0
- package/dist/agents/openai-compatible/engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/engine.js +10 -0
- package/dist/agents/openai-compatible/fetch-engine.d.ts +38 -0
- package/dist/agents/openai-compatible/fetch-engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/fetch-engine.js +216 -0
- package/dist/agents/openai-compatible/pi/engine.d.ts +32 -0
- package/dist/agents/openai-compatible/pi/engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/engine.js +98 -0
- package/dist/agents/openai-compatible/pi/module.d.ts +87 -0
- package/dist/agents/openai-compatible/pi/module.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/module.js +43 -0
- package/dist/agents/openai-compatible/pi/sandbox.d.ts +25 -0
- package/dist/agents/openai-compatible/pi/sandbox.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/sandbox.js +69 -0
- package/dist/agents/openai-compatible/pi/session.d.ts +17 -0
- package/dist/agents/openai-compatible/pi/session.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/session.js +354 -0
- package/dist/agents/openai-compatible/response.d.ts +19 -0
- package/dist/agents/openai-compatible/response.d.ts.map +1 -0
- package/dist/agents/openai-compatible/response.js +203 -0
- package/dist/agents/openai-compatible/types.d.ts +34 -0
- package/dist/agents/openai-compatible/types.d.ts.map +1 -0
- package/dist/agents/openai-compatible/types.js +1 -0
- package/dist/agents/openai-compatible.d.ts +12 -0
- package/dist/agents/openai-compatible.d.ts.map +1 -0
- package/dist/agents/openai-compatible.js +45 -0
- package/dist/auth/login-probe.d.ts +21 -0
- package/dist/auth/login-probe.d.ts.map +1 -0
- package/dist/auth/login-probe.js +47 -0
- package/dist/auth/login.d.ts +79 -0
- package/dist/auth/login.d.ts.map +1 -0
- package/dist/auth/login.js +9 -0
- package/dist/auth/material.d.ts +87 -0
- package/dist/auth/material.d.ts.map +1 -0
- package/dist/auth/material.js +59 -0
- package/dist/auth/profile-store.d.ts +14 -0
- package/dist/auth/profile-store.d.ts.map +1 -0
- package/dist/auth/profile-store.js +101 -0
- package/dist/auth/secrets.d.ts +14 -0
- package/dist/auth/secrets.d.ts.map +1 -0
- package/dist/auth/secrets.js +40 -0
- package/dist/codex/app-server.d.ts +30 -0
- package/dist/codex/app-server.d.ts.map +1 -0
- package/dist/codex/app-server.js +322 -0
- package/dist/codex/index.d.ts +3 -0
- package/dist/codex/index.d.ts.map +1 -0
- package/dist/codex/index.js +1 -0
- package/dist/codex/protocol.d.ts +124 -0
- package/dist/codex/protocol.d.ts.map +1 -0
- package/dist/codex/protocol.js +283 -0
- package/dist/config/agent-config-validation.d.ts +22 -0
- package/dist/config/agent-config-validation.d.ts.map +1 -0
- package/dist/config/agent-config-validation.js +31 -0
- package/dist/config/agent-configs.d.ts +37 -0
- package/dist/config/agent-configs.d.ts.map +1 -0
- package/dist/config/agent-configs.js +214 -0
- package/dist/config/compose.d.ts +10 -0
- package/dist/config/compose.d.ts.map +1 -0
- package/dist/config/compose.js +89 -0
- package/dist/config/config.d.ts +21 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +33 -0
- package/dist/config/errors.d.ts +45 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +37 -0
- package/dist/config/extension.d.ts +3 -0
- package/dist/config/extension.d.ts.map +1 -0
- package/dist/config/extension.js +1 -0
- package/dist/config/ids.d.ts +8 -0
- package/dist/config/ids.d.ts.map +1 -0
- package/dist/config/ids.js +4 -0
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/model.d.ts +105 -0
- package/dist/config/model.d.ts.map +1 -0
- package/dist/config/model.js +1 -0
- package/dist/config/paths.d.ts +7 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +10 -0
- package/dist/config/schema.d.ts +59 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +83 -0
- package/dist/config/store.d.ts +34 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +420 -0
- package/dist/config/support.d.ts +14 -0
- package/dist/config/support.d.ts.map +1 -0
- package/dist/config/support.js +32 -0
- package/dist/config/values.d.ts +21 -0
- package/dist/config/values.d.ts.map +1 -0
- package/dist/config/values.js +22 -0
- package/dist/config/xdg.d.ts +20 -0
- package/dist/config/xdg.d.ts.map +1 -0
- package/dist/config/xdg.js +23 -0
- package/dist/core/async-queue.d.ts +14 -0
- package/dist/core/async-queue.d.ts.map +1 -0
- package/dist/core/async-queue.js +46 -0
- package/dist/core/env.d.ts +19 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/env.js +39 -0
- package/dist/core/error.d.ts +121 -0
- package/dist/core/error.d.ts.map +1 -0
- package/dist/core/error.js +88 -0
- package/dist/core/fs.d.ts +16 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +30 -0
- package/dist/core/json.d.ts +20 -0
- package/dist/core/json.d.ts.map +1 -0
- package/dist/core/json.js +42 -0
- package/dist/core/node-ports.d.ts +9 -0
- package/dist/core/node-ports.d.ts.map +1 -0
- package/dist/core/node-ports.js +135 -0
- package/dist/core/ports.d.ts +71 -0
- package/dist/core/ports.d.ts.map +1 -0
- package/dist/core/ports.js +19 -0
- package/dist/core/redact.d.ts +8 -0
- package/dist/core/redact.d.ts.map +1 -0
- package/dist/core/redact.js +66 -0
- package/dist/core/run.d.ts +125 -0
- package/dist/core/run.d.ts.map +1 -0
- package/dist/core/run.js +27 -0
- package/dist/core/values.d.ts +12 -0
- package/dist/core/values.d.ts.map +1 -0
- package/dist/core/values.js +9 -0
- package/dist/corpus/failure-corpus.d.ts +21 -0
- package/dist/corpus/failure-corpus.d.ts.map +1 -0
- package/dist/corpus/failure-corpus.js +89 -0
- package/dist/fleet/fleet.d.ts +120 -0
- package/dist/fleet/fleet.d.ts.map +1 -0
- package/dist/fleet/fleet.js +409 -0
- package/dist/fleet/policy.d.ts +45 -0
- package/dist/fleet/policy.d.ts.map +1 -0
- package/dist/fleet/policy.js +50 -0
- package/dist/fleet/store.d.ts +28 -0
- package/dist/fleet/store.d.ts.map +1 -0
- package/dist/fleet/store.js +225 -0
- package/dist/host/capabilities.d.ts +146 -0
- package/dist/host/capabilities.d.ts.map +1 -0
- package/dist/host/capabilities.js +59 -0
- package/dist/host/context.d.ts +29 -0
- package/dist/host/context.d.ts.map +1 -0
- package/dist/host/context.js +11 -0
- package/dist/host/github-dir.d.ts +16 -0
- package/dist/host/github-dir.d.ts.map +1 -0
- package/dist/host/github-dir.js +164 -0
- package/dist/host/mcp-list.d.ts +12 -0
- package/dist/host/mcp-list.d.ts.map +1 -0
- package/dist/host/mcp-list.js +122 -0
- package/dist/host/requirement-ref.d.ts +12 -0
- package/dist/host/requirement-ref.d.ts.map +1 -0
- package/dist/host/requirement-ref.js +40 -0
- package/dist/host/run-command.d.ts +27 -0
- package/dist/host/run-command.d.ts.map +1 -0
- package/dist/host/run-command.js +66 -0
- package/dist/host/validate-spec.d.ts +10 -0
- package/dist/host/validate-spec.d.ts.map +1 -0
- package/dist/host/validate-spec.js +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/kernel/classify.d.ts +44 -0
- package/dist/kernel/classify.d.ts.map +1 -0
- package/dist/kernel/classify.js +136 -0
- package/dist/kernel/cli-agent.d.ts +62 -0
- package/dist/kernel/cli-agent.d.ts.map +1 -0
- package/dist/kernel/cli-agent.js +281 -0
- package/dist/kernel/cli-login.d.ts +13 -0
- package/dist/kernel/cli-login.d.ts.map +1 -0
- package/dist/kernel/cli-login.js +199 -0
- package/dist/kernel/definition.d.ts +41 -0
- package/dist/kernel/definition.d.ts.map +1 -0
- package/dist/kernel/definition.js +13 -0
- package/dist/kernel/env-template.d.ts +17 -0
- package/dist/kernel/env-template.d.ts.map +1 -0
- package/dist/kernel/env-template.js +78 -0
- package/dist/kernel/facets.d.ts +58 -0
- package/dist/kernel/facets.d.ts.map +1 -0
- package/dist/kernel/facets.js +102 -0
- package/dist/kernel/guard.d.ts +24 -0
- package/dist/kernel/guard.d.ts.map +1 -0
- package/dist/kernel/guard.js +69 -0
- package/dist/kernel/handle.d.ts +29 -0
- package/dist/kernel/handle.d.ts.map +1 -0
- package/dist/kernel/handle.js +97 -0
- package/dist/kernel/keyed.d.ts +19 -0
- package/dist/kernel/keyed.d.ts.map +1 -0
- package/dist/kernel/keyed.js +35 -0
- package/dist/kernel/login.d.ts +20 -0
- package/dist/kernel/login.d.ts.map +1 -0
- package/dist/kernel/login.js +74 -0
- package/dist/kernel/options.d.ts +73 -0
- package/dist/kernel/options.d.ts.map +1 -0
- package/dist/kernel/options.js +41 -0
- package/dist/kernel/run.d.ts +20 -0
- package/dist/kernel/run.d.ts.map +1 -0
- package/dist/kernel/run.js +245 -0
- package/dist/kernel/runtime.d.ts +48 -0
- package/dist/kernel/runtime.d.ts.map +1 -0
- package/dist/kernel/runtime.js +108 -0
- package/dist/keyring/index.d.ts +2 -0
- package/dist/keyring/index.d.ts.map +1 -0
- package/dist/keyring/index.js +1 -0
- package/dist/keyring/resolver.d.ts +9 -0
- package/dist/keyring/resolver.d.ts.map +1 -0
- package/dist/keyring/resolver.js +62 -0
- package/dist/run-agent.d.ts +19 -0
- package/dist/run-agent.d.ts.map +1 -0
- package/dist/run-agent.js +25 -0
- package/dist/structured/extract.d.ts +27 -0
- package/dist/structured/extract.d.ts.map +1 -0
- package/dist/structured/extract.js +188 -0
- package/dist/structured/run-structured.d.ts +83 -0
- package/dist/structured/run-structured.d.ts.map +1 -0
- package/dist/structured/run-structured.js +202 -0
- package/dist/structured/standard-schema.d.ts +34 -0
- package/dist/structured/standard-schema.d.ts.map +1 -0
- package/dist/structured/standard-schema.js +6 -0
- package/dist/testing/fake-agent.d.ts +32 -0
- package/dist/testing/fake-agent.d.ts.map +1 -0
- package/dist/testing/fake-agent.js +43 -0
- package/dist/testing/fake-clock.d.ts +8 -0
- package/dist/testing/fake-clock.d.ts.map +1 -0
- package/dist/testing/fake-clock.js +44 -0
- package/dist/testing/fake-exec.d.ts +26 -0
- package/dist/testing/fake-exec.d.ts.map +1 -0
- package/dist/testing/fake-exec.js +69 -0
- package/dist/testing/fake-secrets.d.ts +3 -0
- package/dist/testing/fake-secrets.d.ts.map +1 -0
- package/dist/testing/fake-secrets.js +5 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +9 -0
- package/package.json +75 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in codex adapter (v1 E1/E2 argv kept verbatim):
|
|
3
|
+
* `codex exec [--model m] [-c model_reasoning_effort="e"] --json
|
|
4
|
+
* --skip-git-repo-check --sandbox <mode> -C <workspace>`, prompt on
|
|
5
|
+
* stdin. Codex sandboxing is filesystem-level, so read-only grants have
|
|
6
|
+
* no argv mapping and are ignored here.
|
|
7
|
+
*/
|
|
8
|
+
import { LOGIN_METHOD } from "../auth/login.js";
|
|
9
|
+
import { cliLoginProbe } from "../auth/login-probe.js";
|
|
10
|
+
import { AUTH_MATERIAL_KIND, envVarAuthMaterial } from "../auth/material.js";
|
|
11
|
+
import { requireSecret } from "../auth/secrets.js";
|
|
12
|
+
import { listAllCodexMcpServerStatuses, withCodexAppServer, } from "../codex/app-server.js";
|
|
13
|
+
import { CODEX_APP_SERVER_METHOD } from "../codex/protocol.js";
|
|
14
|
+
import { AGENT_ERROR_CODE, AgentError, AUTH_FAILURE_REASON, } from "../core/error.js";
|
|
15
|
+
import { readJsonRecord, readRecord, readString } from "../core/json.js";
|
|
16
|
+
import { AGENT_EVENT_TYPE } from "../core/run.js";
|
|
17
|
+
import { INSTALL_STATUS, MCP_SCOPE, MCP_TRANSPORT, SKILL_SOURCE_KIND, } from "../host/capabilities.js";
|
|
18
|
+
import { runHostCommand } from "../host/run-command.js";
|
|
19
|
+
import { parseCooldownHint } from "../kernel/classify.js";
|
|
20
|
+
import { defineCliAgent } from "../kernel/cli-agent.js";
|
|
21
|
+
import { cliLoginCommand } from "../kernel/cli-login.js";
|
|
22
|
+
import { SANDBOX_MODE } from "../kernel/options.js";
|
|
23
|
+
export const CODEX_HOME_ENV_VAR = "CODEX_HOME";
|
|
24
|
+
export const CODEX_API_KEY_ENV_VAR = "OPENAI_API_KEY";
|
|
25
|
+
const CODEX = {
|
|
26
|
+
id: "codex",
|
|
27
|
+
command: "codex",
|
|
28
|
+
cli: {
|
|
29
|
+
exec: "exec",
|
|
30
|
+
model: "--model",
|
|
31
|
+
config: "-c",
|
|
32
|
+
reasoningEffortConfigKey: "model_reasoning_effort",
|
|
33
|
+
json: "--json",
|
|
34
|
+
skipGitRepoCheck: "--skip-git-repo-check",
|
|
35
|
+
sandbox: "--sandbox",
|
|
36
|
+
workspace: "-C",
|
|
37
|
+
},
|
|
38
|
+
sandbox: {
|
|
39
|
+
full: "danger-full-access",
|
|
40
|
+
readOnly: "read-only",
|
|
41
|
+
},
|
|
42
|
+
auth: {
|
|
43
|
+
// Exit-code-only login probe (E12): `codex login status` exits 0 when a
|
|
44
|
+
// credential is present, nonzero otherwise. The output format is not
|
|
45
|
+
// parsed — only the exit code decides valid/invalid, like claude's.
|
|
46
|
+
statusArgs: ["login", "status"],
|
|
47
|
+
oauthLoginArgs: ["login"],
|
|
48
|
+
deviceLoginArgs: ["login", "--device-auth"],
|
|
49
|
+
},
|
|
50
|
+
json: {
|
|
51
|
+
field: {
|
|
52
|
+
type: "type",
|
|
53
|
+
text: "text",
|
|
54
|
+
item: "item",
|
|
55
|
+
},
|
|
56
|
+
event: {
|
|
57
|
+
turnCompleted: "turn.completed",
|
|
58
|
+
agentMessage: "agent_message",
|
|
59
|
+
itemCompleted: "item.completed",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
mcp: {
|
|
63
|
+
add: "add",
|
|
64
|
+
env: "--env",
|
|
65
|
+
executableSeparator: "--",
|
|
66
|
+
mcp: "mcp",
|
|
67
|
+
remove: "remove",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const COMPETING_API_KEY_VARS = ["OPENAI_API_KEY", "CODEX_API_KEY"];
|
|
71
|
+
const COMPETING_HOME_VARS = ["CODEX_HOME", "CODEX_API_KEY"];
|
|
72
|
+
const UNSUPPORTED_CWD_REASON = "unsupported codex stdio mcp cwd";
|
|
73
|
+
const UNSUPPORTED_SCOPE_REASON_PREFIX = "unsupported codex mcp scope";
|
|
74
|
+
const UNSUPPORTED_PLUGIN_OVERWRITE_REASON = "plugin install does not support overwrite";
|
|
75
|
+
const CODEX_PLUGIN_AUTH_REQUIRED_MESSAGE = "Codex plugin installation requires app authorization";
|
|
76
|
+
const CODEX_ALREADY_INSTALLED_STATUS = /already/i;
|
|
77
|
+
const CODEX_MCP_UNUSABLE_STATUS = /failed|error|invalid|missing|required/i;
|
|
78
|
+
/** Codex capacity phrasing (v1 F5 signals, kept verbatim). */
|
|
79
|
+
const CAPACITY_TEXT = /selected model is at capacity|model is at capacity/i;
|
|
80
|
+
const CAPACITY_COMBINED = /at capacity/i;
|
|
81
|
+
const CAPACITY_MODEL = /model/i;
|
|
82
|
+
function sharedArgs(ctx, sandboxValue) {
|
|
83
|
+
return [
|
|
84
|
+
CODEX.cli.exec,
|
|
85
|
+
...(ctx.model === null ? [] : [CODEX.cli.model, ctx.model]),
|
|
86
|
+
...(ctx.effort === null
|
|
87
|
+
? []
|
|
88
|
+
: [
|
|
89
|
+
CODEX.cli.config,
|
|
90
|
+
`${CODEX.cli.reasoningEffortConfigKey}="${ctx.effort}"`,
|
|
91
|
+
]),
|
|
92
|
+
CODEX.cli.json,
|
|
93
|
+
CODEX.cli.skipGitRepoCheck,
|
|
94
|
+
CODEX.cli.sandbox,
|
|
95
|
+
sandboxValue,
|
|
96
|
+
CODEX.cli.workspace,
|
|
97
|
+
ctx.workspace,
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
function parseCodexLine(line) {
|
|
101
|
+
const record = readJsonRecord(line);
|
|
102
|
+
if (record === null) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const type = readString(record, CODEX.json.field.type);
|
|
106
|
+
if (type === CODEX.json.event.turnCompleted) {
|
|
107
|
+
return [{ type: AGENT_EVENT_TYPE.turn }];
|
|
108
|
+
}
|
|
109
|
+
if (type === CODEX.json.event.agentMessage) {
|
|
110
|
+
const text = readString(record, CODEX.json.field.text);
|
|
111
|
+
return text === null ? [] : [{ type: AGENT_EVENT_TYPE.message, text }];
|
|
112
|
+
}
|
|
113
|
+
if (type === CODEX.json.event.itemCompleted) {
|
|
114
|
+
const item = readRecord(record, CODEX.json.field.item);
|
|
115
|
+
if (item !== null &&
|
|
116
|
+
readString(item, CODEX.json.field.type) === CODEX.json.event.agentMessage) {
|
|
117
|
+
const text = readString(item, CODEX.json.field.text);
|
|
118
|
+
return text === null ? [] : [{ type: AGENT_EVENT_TYPE.message, text }];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Codex "selected model is at capacity" phrasing, plus the looser
|
|
125
|
+
* "model ... at capacity" combination. Exported for custom agents that
|
|
126
|
+
* surface the same provider text.
|
|
127
|
+
*/
|
|
128
|
+
export function capacityTextMatcher() {
|
|
129
|
+
return (evidence) => {
|
|
130
|
+
const text = `${evidence.stderr}\n${evidence.stdout}`;
|
|
131
|
+
const matches = CAPACITY_TEXT.test(text) ||
|
|
132
|
+
(CAPACITY_COMBINED.test(text) && CAPACITY_MODEL.test(text));
|
|
133
|
+
if (!matches) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
code: AGENT_ERROR_CODE.capacity,
|
|
138
|
+
message: "Provider is at capacity",
|
|
139
|
+
data: { cooldownUntil: parseCooldownHint(text, evidence.now) },
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function codexAppServerCwd(ctx) {
|
|
144
|
+
return ctx.location.projectDir ?? ctx.location.homeDir;
|
|
145
|
+
}
|
|
146
|
+
function codexAppServerCwds(ctx) {
|
|
147
|
+
return [codexAppServerCwd(ctx)];
|
|
148
|
+
}
|
|
149
|
+
async function listCodexSkills(ctx) {
|
|
150
|
+
return withCodexAppServer(codexAppServerOptions(ctx), async (client) => {
|
|
151
|
+
const result = await client.request(CODEX_APP_SERVER_METHOD.skillsList, {
|
|
152
|
+
cwds: codexAppServerCwds(ctx),
|
|
153
|
+
forceReload: true,
|
|
154
|
+
});
|
|
155
|
+
return skillsFromCodexResult(result);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async function installCodexPlugin(ctx, source, options) {
|
|
159
|
+
if (options.overwrite === true) {
|
|
160
|
+
// `plugin/install` has no overwrite semantics; refusing is honest,
|
|
161
|
+
// silently ignoring the request is not (same contract as claude).
|
|
162
|
+
throw new AgentError({
|
|
163
|
+
code: AGENT_ERROR_CODE.invalidInput,
|
|
164
|
+
message: "Codex plugin installation cannot overwrite an installed plugin",
|
|
165
|
+
data: { reason: UNSUPPORTED_PLUGIN_OVERWRITE_REASON },
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return withCodexAppServer(codexAppServerOptions(ctx), async (client) => {
|
|
169
|
+
const result = await client.request(CODEX_APP_SERVER_METHOD.pluginInstall, {
|
|
170
|
+
pluginName: source.name,
|
|
171
|
+
marketplacePath: null,
|
|
172
|
+
remoteMarketplaceName: null,
|
|
173
|
+
});
|
|
174
|
+
return installOutcomeFromCodexPlugin(source.name, result);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async function listCodexMcp(ctx) {
|
|
178
|
+
return withCodexAppServer(codexAppServerOptions(ctx), async (client) => (await listAllCodexMcpServerStatuses(client)).map(codexMcpState));
|
|
179
|
+
}
|
|
180
|
+
async function addCodexStdioMcp(ctx, name, spec, options) {
|
|
181
|
+
assertCodexStdioMcpSupported(spec, options);
|
|
182
|
+
await runHostCommand(ctx, {
|
|
183
|
+
command: CODEX.command,
|
|
184
|
+
args: [
|
|
185
|
+
CODEX.mcp.mcp,
|
|
186
|
+
CODEX.mcp.add,
|
|
187
|
+
name,
|
|
188
|
+
...Object.entries(spec.env).flatMap(([key, value]) => [
|
|
189
|
+
CODEX.mcp.env,
|
|
190
|
+
`${key}=${value}`,
|
|
191
|
+
]),
|
|
192
|
+
CODEX.mcp.executableSeparator,
|
|
193
|
+
spec.command,
|
|
194
|
+
...spec.args,
|
|
195
|
+
],
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
status: INSTALL_STATUS.installed,
|
|
199
|
+
location: `codex:${options.scope}:${name}`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
async function removeCodexMcp(ctx, name, options) {
|
|
203
|
+
assertCodexMcpScopeSupported(options.scope);
|
|
204
|
+
await runHostCommand(ctx, {
|
|
205
|
+
command: CODEX.command,
|
|
206
|
+
args: [CODEX.mcp.mcp, CODEX.mcp.remove, name],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function assertCodexStdioMcpSupported(spec, options) {
|
|
210
|
+
assertCodexMcpScopeSupported(options.scope);
|
|
211
|
+
if (spec.cwd !== null) {
|
|
212
|
+
throw new AgentError({
|
|
213
|
+
code: AGENT_ERROR_CODE.invalidInput,
|
|
214
|
+
message: "Codex stdio MCP registration does not support server cwd",
|
|
215
|
+
data: { reason: UNSUPPORTED_CWD_REASON },
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function assertCodexMcpScopeSupported(scope) {
|
|
220
|
+
if (scope === MCP_SCOPE.user) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const reason = [UNSUPPORTED_SCOPE_REASON_PREFIX, scope].join(": ");
|
|
224
|
+
throw new AgentError({
|
|
225
|
+
code: AGENT_ERROR_CODE.invalidInput,
|
|
226
|
+
message: `Codex MCP registration does not support scope "${scope}"`,
|
|
227
|
+
data: { reason },
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function codexAppServerOptions(ctx) {
|
|
231
|
+
return {
|
|
232
|
+
exec: ctx.exec,
|
|
233
|
+
clock: ctx.clock,
|
|
234
|
+
env: ctx.env,
|
|
235
|
+
cwd: codexAppServerCwd(ctx),
|
|
236
|
+
command: CODEX.command,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function skillsFromCodexResult(result) {
|
|
240
|
+
return result.data.flatMap((entry) => entry.skills.map((skill) => ({
|
|
241
|
+
id: skill.name,
|
|
242
|
+
name: skill.name,
|
|
243
|
+
description: skill.description,
|
|
244
|
+
location: skill.path,
|
|
245
|
+
source: `codex:${skill.scope}`,
|
|
246
|
+
})));
|
|
247
|
+
}
|
|
248
|
+
function installOutcomeFromCodexPlugin(name, result) {
|
|
249
|
+
if (result.appsNeedingAuth.length > 0) {
|
|
250
|
+
throw new AgentError({
|
|
251
|
+
code: AGENT_ERROR_CODE.auth,
|
|
252
|
+
message: CODEX_PLUGIN_AUTH_REQUIRED_MESSAGE,
|
|
253
|
+
data: {
|
|
254
|
+
reason: AUTH_FAILURE_REASON.notLoggedIn,
|
|
255
|
+
detail: result.authPolicy,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const location = result.location ?? `codex:plugin:${name}`;
|
|
260
|
+
const alreadyInstalled = result.alreadyInstalled === true ||
|
|
261
|
+
(result.status !== null &&
|
|
262
|
+
CODEX_ALREADY_INSTALLED_STATUS.test(result.status));
|
|
263
|
+
return {
|
|
264
|
+
status: alreadyInstalled
|
|
265
|
+
? INSTALL_STATUS.alreadyInstalled
|
|
266
|
+
: INSTALL_STATUS.installed,
|
|
267
|
+
location,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function codexMcpState(status) {
|
|
271
|
+
// tools === null = the app-server did not enumerate tools; McpServerState
|
|
272
|
+
// keeps that distinct from an enumerated-but-empty tool list.
|
|
273
|
+
const tools = status.tools === null
|
|
274
|
+
? null
|
|
275
|
+
: Object.entries(status.tools).map(([key, tool]) => tool.name ?? key);
|
|
276
|
+
return {
|
|
277
|
+
name: status.name,
|
|
278
|
+
transport: MCP_TRANSPORT.stdio,
|
|
279
|
+
usable: !CODEX_MCP_UNUSABLE_STATUS.test(status.authStatus),
|
|
280
|
+
tools,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function codexLogin(args) {
|
|
284
|
+
return (request, ctx) => cliLoginCommand({
|
|
285
|
+
command: CODEX.command,
|
|
286
|
+
args,
|
|
287
|
+
envPatch: {
|
|
288
|
+
set: { [CODEX_HOME_ENV_VAR]: request.homeDir },
|
|
289
|
+
unset: COMPETING_API_KEY_VARS,
|
|
290
|
+
},
|
|
291
|
+
request,
|
|
292
|
+
ctx,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
export function codex() {
|
|
296
|
+
return defineCliAgent({
|
|
297
|
+
id: CODEX.id,
|
|
298
|
+
command: CODEX.command,
|
|
299
|
+
args: {
|
|
300
|
+
[SANDBOX_MODE.full]: (_sandbox, ctx) => sharedArgs(ctx, CODEX.sandbox.full),
|
|
301
|
+
[SANDBOX_MODE.readOnly]: (_sandbox, ctx) => sharedArgs(ctx, CODEX.sandbox.readOnly),
|
|
302
|
+
},
|
|
303
|
+
parseLine: parseCodexLine,
|
|
304
|
+
classify: [capacityTextMatcher()],
|
|
305
|
+
detectCompletion: (line, state) => {
|
|
306
|
+
if (state.messages.length === 0) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
const record = readJsonRecord(line);
|
|
310
|
+
return (record !== null &&
|
|
311
|
+
readString(record, CODEX.json.field.type) ===
|
|
312
|
+
CODEX.json.event.turnCompleted);
|
|
313
|
+
},
|
|
314
|
+
auth: {
|
|
315
|
+
[AUTH_MATERIAL_KIND.homeDir]: envVarAuthMaterial({
|
|
316
|
+
set: (material) => ({ [CODEX_HOME_ENV_VAR]: material.path }),
|
|
317
|
+
unset: COMPETING_API_KEY_VARS,
|
|
318
|
+
check: (material, ctx) => cliLoginProbe({
|
|
319
|
+
command: CODEX.command,
|
|
320
|
+
args: CODEX.auth.statusArgs,
|
|
321
|
+
envPatch: {
|
|
322
|
+
set: { [CODEX_HOME_ENV_VAR]: material.path },
|
|
323
|
+
unset: COMPETING_API_KEY_VARS,
|
|
324
|
+
},
|
|
325
|
+
ctx,
|
|
326
|
+
}),
|
|
327
|
+
}),
|
|
328
|
+
[AUTH_MATERIAL_KIND.apiKey]: envVarAuthMaterial({
|
|
329
|
+
set: async (material, secrets) => ({
|
|
330
|
+
[CODEX_API_KEY_ENV_VAR]: await requireSecret(secrets, material.secret),
|
|
331
|
+
}),
|
|
332
|
+
unset: COMPETING_HOME_VARS,
|
|
333
|
+
}),
|
|
334
|
+
},
|
|
335
|
+
login: {
|
|
336
|
+
methods: {
|
|
337
|
+
[LOGIN_METHOD.oauth]: codexLogin(CODEX.auth.oauthLoginArgs),
|
|
338
|
+
[LOGIN_METHOD.device]: codexLogin(CODEX.auth.deviceLoginArgs),
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
skills: {
|
|
342
|
+
list: listCodexSkills,
|
|
343
|
+
install: {
|
|
344
|
+
[SKILL_SOURCE_KIND.plugin]: installCodexPlugin,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
mcp: {
|
|
348
|
+
list: listCodexMcp,
|
|
349
|
+
add: {
|
|
350
|
+
[MCP_TRANSPORT.stdio]: addCodexStdioMcp,
|
|
351
|
+
},
|
|
352
|
+
remove: removeCodexMcp,
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type DoctorCheck } from "../../host/capabilities.js";
|
|
2
|
+
import type { OpenAiCompatibleConfig, ResolvedOpenAiCompatibleConfig } from "./types.js";
|
|
3
|
+
export interface OpenAiCompatibleConfigResolver {
|
|
4
|
+
normalize<Id extends string>(config: OpenAiCompatibleConfig<Id>): OpenAiCompatibleConfig<Id>;
|
|
5
|
+
resolve(config: OpenAiCompatibleConfig, env: Readonly<Record<string, string>>): ResolvedOpenAiCompatibleConfig;
|
|
6
|
+
doctorChecks(config: OpenAiCompatibleConfig, env: Readonly<Record<string, string>>): readonly DoctorCheck[];
|
|
7
|
+
}
|
|
8
|
+
export declare class DefaultOpenAiCompatibleConfigResolver implements OpenAiCompatibleConfigResolver {
|
|
9
|
+
normalize<Id extends string>(config: OpenAiCompatibleConfig<Id>): OpenAiCompatibleConfig<Id>;
|
|
10
|
+
resolve(config: OpenAiCompatibleConfig, env: Readonly<Record<string, string>>): ResolvedOpenAiCompatibleConfig;
|
|
11
|
+
doctorChecks(config: OpenAiCompatibleConfig, env: Readonly<Record<string, string>>): readonly DoctorCheck[];
|
|
12
|
+
private resolveRequiredTemplate;
|
|
13
|
+
private missingEnvChecks;
|
|
14
|
+
}
|
|
15
|
+
export declare const defaultOpenAiCompatibleConfigResolver: DefaultOpenAiCompatibleConfigResolver;
|
|
16
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/agents/openai-compatible/config.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,KAAK,EAEV,sBAAsB,EACtB,8BAA8B,EAC/B,MAAM,YAAY,CAAC;AAmBpB,MAAM,WAAW,8BAA8B;IAC7C,SAAS,CAAC,EAAE,SAAS,MAAM,EACzB,MAAM,EAAE,sBAAsB,CAAC,EAAE,CAAC,GACjC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC9B,OAAO,CACL,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,8BAA8B,CAAC;IAClC,YAAY,CACV,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,SAAS,WAAW,EAAE,CAAC;CAC3B;AAED,qBAAa,qCACX,YAAW,8BAA8B;IAEzC,SAAS,CAAC,EAAE,SAAS,MAAM,EACzB,MAAM,EAAE,sBAAsB,CAAC,EAAE,CAAC,GACjC,sBAAsB,CAAC,EAAE,CAAC;IAW7B,OAAO,CACL,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,8BAA8B;IAyCjC,YAAY,CACV,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,SAAS,WAAW,EAAE;IASzB,OAAO,CAAC,uBAAuB;IAuB/B,OAAO,CAAC,gBAAgB;CAYzB;AAED,eAAO,MAAM,qCAAqC,uCACL,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { AGENT_ERROR_CODE, AgentError, NOT_AVAILABLE_CAUSE, } from "../../core/error.js";
|
|
2
|
+
import { DOCTOR_CHECK_STATUS, } from "../../host/capabilities.js";
|
|
3
|
+
import { referencedEnvNames as referencedTemplateEnvNames, resolveEnvTemplate, } from "../../kernel/env-template.js";
|
|
4
|
+
const CONFIG_FIELD = {
|
|
5
|
+
apiKey: "apiKey",
|
|
6
|
+
baseUrl: "baseUrl",
|
|
7
|
+
headers: "headers",
|
|
8
|
+
model: "model",
|
|
9
|
+
requestParams: "requestParams",
|
|
10
|
+
};
|
|
11
|
+
const DOCTOR_CHECK = {
|
|
12
|
+
baseUrl: "base-url",
|
|
13
|
+
envPrefix: "env:",
|
|
14
|
+
};
|
|
15
|
+
const HTTP_PROTOCOL = {
|
|
16
|
+
http: "http:",
|
|
17
|
+
https: "https:",
|
|
18
|
+
};
|
|
19
|
+
const OBJECT_PATH_SEPARATOR = ".";
|
|
20
|
+
export class DefaultOpenAiCompatibleConfigResolver {
|
|
21
|
+
normalize(config) {
|
|
22
|
+
return {
|
|
23
|
+
id: config.id,
|
|
24
|
+
baseUrl: config.baseUrl,
|
|
25
|
+
model: config.model,
|
|
26
|
+
apiKey: config.apiKey,
|
|
27
|
+
headers: { ...config.headers },
|
|
28
|
+
requestParams: structuredClone(config.requestParams),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
resolve(config, env) {
|
|
32
|
+
const baseUrl = this.resolveRequiredTemplate(CONFIG_FIELD.baseUrl, config.baseUrl, env);
|
|
33
|
+
assertHttpBaseUrl(baseUrl);
|
|
34
|
+
return {
|
|
35
|
+
id: config.id,
|
|
36
|
+
baseUrl,
|
|
37
|
+
model: this.resolveRequiredTemplate(CONFIG_FIELD.model, config.model, env),
|
|
38
|
+
apiKey: config.apiKey === null
|
|
39
|
+
? null
|
|
40
|
+
: this.resolveRequiredTemplate(CONFIG_FIELD.apiKey, config.apiKey, env),
|
|
41
|
+
headers: Object.fromEntries(Object.entries(config.headers).map(([key, value]) => [
|
|
42
|
+
key,
|
|
43
|
+
this.resolveRequiredTemplate(pathLabel(CONFIG_FIELD.headers, key), value, env),
|
|
44
|
+
])),
|
|
45
|
+
requestParams: resolveJsonObjectTemplates(CONFIG_FIELD.requestParams, config.requestParams, env),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
doctorChecks(config, env) {
|
|
49
|
+
const envChecks = this.missingEnvChecks(config, env);
|
|
50
|
+
if (envChecks.length > 0) {
|
|
51
|
+
return envChecks;
|
|
52
|
+
}
|
|
53
|
+
const baseUrlCheck = validateBaseUrlCheck(config, env);
|
|
54
|
+
return baseUrlCheck === null ? [] : [baseUrlCheck];
|
|
55
|
+
}
|
|
56
|
+
resolveRequiredTemplate(label, value, env) {
|
|
57
|
+
const resolved = resolveEnvTemplate(value, env);
|
|
58
|
+
if (!resolved.ok) {
|
|
59
|
+
throw new AgentError({
|
|
60
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
61
|
+
message: `openaiCompatible.${label} references ${resolved.reason} environment variable: ${resolved.envName}`,
|
|
62
|
+
data: { cause: NOT_AVAILABLE_CAUSE.badConfig },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (resolved.value.trim().length === 0) {
|
|
66
|
+
throw new AgentError({
|
|
67
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
68
|
+
message: `openaiCompatible.${label} resolved to an empty value`,
|
|
69
|
+
data: { cause: NOT_AVAILABLE_CAUSE.badConfig },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return resolved.value;
|
|
73
|
+
}
|
|
74
|
+
missingEnvChecks(config, env) {
|
|
75
|
+
return referencedTemplateEnvNames(config)
|
|
76
|
+
.filter((name) => (env[name] ?? "").length === 0)
|
|
77
|
+
.map((name) => ({
|
|
78
|
+
id: `${DOCTOR_CHECK.envPrefix}${name}`,
|
|
79
|
+
status: DOCTOR_CHECK_STATUS.fail,
|
|
80
|
+
detail: `Missing or empty environment variable: ${name}`,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export const defaultOpenAiCompatibleConfigResolver = new DefaultOpenAiCompatibleConfigResolver();
|
|
85
|
+
function resolveJsonTemplates(label, value, env) {
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
const resolved = resolveEnvTemplate(value, env);
|
|
88
|
+
if (!resolved.ok) {
|
|
89
|
+
throw new AgentError({
|
|
90
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
91
|
+
message: `openaiCompatible.${label} references ${resolved.reason} environment variable: ${resolved.envName}`,
|
|
92
|
+
data: { cause: NOT_AVAILABLE_CAUSE.badConfig },
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return resolved.value;
|
|
96
|
+
}
|
|
97
|
+
if (Array.isArray(value)) {
|
|
98
|
+
return value.map((item, index) => resolveJsonTemplates(arrayPathLabel(label, index), item, env));
|
|
99
|
+
}
|
|
100
|
+
if (isJsonRecord(value)) {
|
|
101
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
102
|
+
key,
|
|
103
|
+
resolveJsonTemplates(pathLabel(label, key), item, env),
|
|
104
|
+
]));
|
|
105
|
+
}
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
function resolveJsonObjectTemplates(label, value, env) {
|
|
109
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
110
|
+
key,
|
|
111
|
+
resolveJsonTemplates(pathLabel(label, key), item, env),
|
|
112
|
+
]));
|
|
113
|
+
}
|
|
114
|
+
function isJsonRecord(value) {
|
|
115
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
116
|
+
}
|
|
117
|
+
function validateBaseUrlCheck(config, env) {
|
|
118
|
+
const resolved = resolveEnvTemplate(config.baseUrl, env);
|
|
119
|
+
if (!resolved.ok) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
assertHttpBaseUrl(resolved.value);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
return {
|
|
128
|
+
id: DOCTOR_CHECK.baseUrl,
|
|
129
|
+
status: DOCTOR_CHECK_STATUS.fail,
|
|
130
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function assertHttpBaseUrl(baseUrl) {
|
|
135
|
+
let parsed;
|
|
136
|
+
try {
|
|
137
|
+
parsed = new URL(baseUrl);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
throw new AgentError({
|
|
141
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
142
|
+
message: `Invalid OpenAI-compatible baseUrl: ${baseUrl}`,
|
|
143
|
+
data: { cause: NOT_AVAILABLE_CAUSE.badConfig },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (parsed.protocol !== HTTP_PROTOCOL.http &&
|
|
147
|
+
parsed.protocol !== HTTP_PROTOCOL.https) {
|
|
148
|
+
throw new AgentError({
|
|
149
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
150
|
+
message: `Invalid OpenAI-compatible baseUrl protocol: ${parsed.protocol}`,
|
|
151
|
+
data: { cause: NOT_AVAILABLE_CAUSE.badConfig },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function pathLabel(parent, child) {
|
|
156
|
+
return [parent, child].join(OBJECT_PATH_SEPARATOR);
|
|
157
|
+
}
|
|
158
|
+
function arrayPathLabel(parent, index) {
|
|
159
|
+
return `${parent}[${index}]`;
|
|
160
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine port: how a resolved OpenAI-compatible config is turned
|
|
3
|
+
* into an AgentRun. The engine owns its own availability — its doctor
|
|
4
|
+
* checks describe requirements of the engine itself (peer packages,
|
|
5
|
+
* node floor), never of the config (the resolver owns those). The
|
|
6
|
+
* shipped default is the dependency-free fetch chat-completions engine;
|
|
7
|
+
* an in-process pi-session engine (design E3, v1 parity) is a
|
|
8
|
+
* detail-backlog implementation of this same port.
|
|
9
|
+
*/
|
|
10
|
+
import type { DoctorCheck } from "../../host/capabilities.js";
|
|
11
|
+
import type { AgentRun, RunContext } from "../../kernel/definition.js";
|
|
12
|
+
import type { ResolvedRunOptions } from "../../kernel/options.js";
|
|
13
|
+
import type { ResolvedOpenAiCompatibleConfig } from "./types.js";
|
|
14
|
+
export interface OpenAiCompatibleEngine {
|
|
15
|
+
doctorChecks(): Promise<readonly DoctorCheck[]>;
|
|
16
|
+
run(config: ResolvedOpenAiCompatibleConfig, options: ResolvedRunOptions, ctx: RunContext): AgentRun;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/agents/openai-compatible/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,YAAY,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;IAChD,GAAG,CACD,MAAM,EAAE,8BAA8B,EACtC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,EAAE,UAAU,GACd,QAAQ,CAAC;CACb"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine port: how a resolved OpenAI-compatible config is turned
|
|
3
|
+
* into an AgentRun. The engine owns its own availability — its doctor
|
|
4
|
+
* checks describe requirements of the engine itself (peer packages,
|
|
5
|
+
* node floor), never of the config (the resolver owns those). The
|
|
6
|
+
* shipped default is the dependency-free fetch chat-completions engine;
|
|
7
|
+
* an in-process pi-session engine (design E3, v1 parity) is a
|
|
8
|
+
* detail-backlog implementation of this same port.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AgentError } from "../../core/error.js";
|
|
2
|
+
import type { DoctorCheck } from "../../host/capabilities.js";
|
|
3
|
+
import type { AgentRun, RunContext } from "../../kernel/definition.js";
|
|
4
|
+
import type { ResolvedRunOptions } from "../../kernel/options.js";
|
|
5
|
+
import type { OpenAiCompatibleEngine } from "./engine.js";
|
|
6
|
+
import { type OpenAiCompatibleResponseDecoder } from "./response.js";
|
|
7
|
+
import type { ResolvedOpenAiCompatibleConfig } from "./types.js";
|
|
8
|
+
export interface OpenAiCompatibleRetryPolicy {
|
|
9
|
+
readonly maxAttempts: number;
|
|
10
|
+
shouldRetry(error: AgentError, attempt: number): boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface OpenAiCompatibleHttpFailurePolicy {
|
|
13
|
+
errorFor(response: Response, ctx: RunContext): Promise<AgentError | null>;
|
|
14
|
+
}
|
|
15
|
+
export type FetchOpenAiCompatibleEngineDependencies = {
|
|
16
|
+
readonly decoders?: readonly OpenAiCompatibleResponseDecoder[];
|
|
17
|
+
readonly retryPolicy?: OpenAiCompatibleRetryPolicy;
|
|
18
|
+
readonly failurePolicy?: OpenAiCompatibleHttpFailurePolicy;
|
|
19
|
+
};
|
|
20
|
+
export declare class FetchOpenAiCompatibleEngine implements OpenAiCompatibleEngine {
|
|
21
|
+
private readonly decoders;
|
|
22
|
+
private readonly retryPolicy;
|
|
23
|
+
private readonly failurePolicy;
|
|
24
|
+
constructor(dependencies?: FetchOpenAiCompatibleEngineDependencies);
|
|
25
|
+
doctorChecks(): Promise<readonly DoctorCheck[]>;
|
|
26
|
+
run(config: ResolvedOpenAiCompatibleConfig, options: ResolvedRunOptions, ctx: RunContext): AgentRun;
|
|
27
|
+
private decoderFor;
|
|
28
|
+
}
|
|
29
|
+
export declare class DefaultOpenAiCompatibleRetryPolicy implements OpenAiCompatibleRetryPolicy {
|
|
30
|
+
readonly maxAttempts = 2;
|
|
31
|
+
shouldRetry(error: AgentError, attempt: number): boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class DefaultOpenAiCompatibleHttpFailurePolicy implements OpenAiCompatibleHttpFailurePolicy {
|
|
34
|
+
private readonly handlers;
|
|
35
|
+
errorFor(response: Response, ctx: RunContext): Promise<AgentError | null>;
|
|
36
|
+
}
|
|
37
|
+
export declare const defaultOpenAiCompatibleEngine: FetchOpenAiCompatibleEngine;
|
|
38
|
+
//# sourceMappingURL=fetch-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-engine.d.ts","sourceRoot":"","sources":["../../../src/agents/openai-compatible/fetch-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EAIX,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAa,8BAA8B,EAAE,MAAM,YAAY,CAAC;AA+C5E,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1D;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,uCAAuC,GAAG;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,+BAA+B,EAAE,CAAC;IAC/D,QAAQ,CAAC,WAAW,CAAC,EAAE,2BAA2B,CAAC;IACnD,QAAQ,CAAC,aAAa,CAAC,EAAE,iCAAiC,CAAC;CAC5D,CAAC;AAEF,qBAAa,2BAA4B,YAAW,sBAAsB;IACxE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;gBAEtD,YAAY,GAAE,uCAA4C;IAUhE,YAAY,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC;IAI9C,GAAG,CACR,MAAM,EAAE,8BAA8B,EACtC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,EAAE,UAAU,GACd,QAAQ;IA+CX,OAAO,CAAC,UAAU;CAanB;AAED,qBAAa,kCACX,YAAW,2BAA2B;IAEtC,QAAQ,CAAC,WAAW,KAAwB;IAE5C,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;CAGzD;AAED,qBAAa,wCACX,YAAW,iCAAiC;IAE5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAIvB;IAEI,QAAQ,CACZ,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAM9B;AAyID,eAAO,MAAM,6BAA6B,6BAAoC,CAAC"}
|