@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,322 @@
|
|
|
1
|
+
import { AGENT_ERROR_CODE, AgentError, NOT_AVAILABLE_CAUSE, TIMEOUT_KIND, } from "../core/error.js";
|
|
2
|
+
import { readJsonRecord } from "../core/json.js";
|
|
3
|
+
import { redactSecrets } from "../core/redact.js";
|
|
4
|
+
import { OUTPUT_CHANNEL, PROCESS_SIGNAL } from "../core/values.js";
|
|
5
|
+
import { CODEX_APP_SERVER_METHOD, CODEX_APP_SERVER_RESULT_DECODERS, CODEX_MCP_STATUS_DETAIL, } from "./protocol.js";
|
|
6
|
+
const DEFAULT_CODEX_COMMAND = "codex";
|
|
7
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
8
|
+
const APP_SERVER_ARGS = ["app-server"];
|
|
9
|
+
/**
|
|
10
|
+
* Neutral, library-scoped identity for the OSS package: it names the library
|
|
11
|
+
* function, not a product or family, so `@alpacakit/agents` ships no product
|
|
12
|
+
* branding in the handshake. Consumers pass `clientInfo` to override.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_APP_SERVER_CLIENT_INFO = {
|
|
15
|
+
name: "agents",
|
|
16
|
+
title: "Agents",
|
|
17
|
+
version: "0.1.0",
|
|
18
|
+
};
|
|
19
|
+
const OUTPUT_TAIL_CHARS = 2_000;
|
|
20
|
+
const MCP_PAGE_LIMIT = 500;
|
|
21
|
+
const JSON_RPC_FRAME_SEPARATOR = "\n";
|
|
22
|
+
const JSON_RPC_FRAME_BOUNDARY = /\r?\n/u;
|
|
23
|
+
const JSON_RPC_FIELD = {
|
|
24
|
+
id: "id",
|
|
25
|
+
method: "method",
|
|
26
|
+
result: "result",
|
|
27
|
+
error: "error",
|
|
28
|
+
message: "message",
|
|
29
|
+
};
|
|
30
|
+
export function createCodexAppServer(options) {
|
|
31
|
+
return new ExecCodexAppServer(resolveOptions(options));
|
|
32
|
+
}
|
|
33
|
+
export async function withCodexAppServer(options, task) {
|
|
34
|
+
const client = createCodexAppServer(options);
|
|
35
|
+
try {
|
|
36
|
+
return await task(client);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await client.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function listAllCodexMcpServerStatuses(client) {
|
|
43
|
+
const statuses = [];
|
|
44
|
+
let cursor = null;
|
|
45
|
+
do {
|
|
46
|
+
const page = await client.request(CODEX_APP_SERVER_METHOD.mcpServerStatusList, {
|
|
47
|
+
detail: CODEX_MCP_STATUS_DETAIL.toolsAndAuthOnly,
|
|
48
|
+
cursor,
|
|
49
|
+
limit: MCP_PAGE_LIMIT,
|
|
50
|
+
});
|
|
51
|
+
statuses.push(...page.data);
|
|
52
|
+
cursor = page.nextCursor;
|
|
53
|
+
} while (cursor !== null);
|
|
54
|
+
return statuses;
|
|
55
|
+
}
|
|
56
|
+
class ExecCodexAppServer {
|
|
57
|
+
options;
|
|
58
|
+
process = null;
|
|
59
|
+
initialized = false;
|
|
60
|
+
connecting = null;
|
|
61
|
+
nextId = 1;
|
|
62
|
+
stderr = "";
|
|
63
|
+
stdoutLine = "";
|
|
64
|
+
pending = new Map();
|
|
65
|
+
constructor(options) {
|
|
66
|
+
this.options = options;
|
|
67
|
+
}
|
|
68
|
+
async request(method, params) {
|
|
69
|
+
await this.connect();
|
|
70
|
+
return this.sendRequest(method, params);
|
|
71
|
+
}
|
|
72
|
+
async close() {
|
|
73
|
+
const process = this.process;
|
|
74
|
+
this.process = null;
|
|
75
|
+
this.initialized = false;
|
|
76
|
+
if (process !== null) {
|
|
77
|
+
process.endStdin();
|
|
78
|
+
process.kill(PROCESS_SIGNAL.sigterm);
|
|
79
|
+
}
|
|
80
|
+
this.rejectAll(appServerClosedError());
|
|
81
|
+
}
|
|
82
|
+
async connect() {
|
|
83
|
+
if (this.initialized) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (this.connecting !== null) {
|
|
87
|
+
return this.connecting;
|
|
88
|
+
}
|
|
89
|
+
this.connecting = this.connectFresh().finally(() => {
|
|
90
|
+
this.connecting = null;
|
|
91
|
+
});
|
|
92
|
+
return this.connecting;
|
|
93
|
+
}
|
|
94
|
+
async connectFresh() {
|
|
95
|
+
if (this.process === null) {
|
|
96
|
+
await this.startProcess();
|
|
97
|
+
}
|
|
98
|
+
await this.sendRequest(CODEX_APP_SERVER_METHOD.initialize, {
|
|
99
|
+
clientInfo: this.options.clientInfo,
|
|
100
|
+
capabilities: { experimentalApi: true },
|
|
101
|
+
});
|
|
102
|
+
this.sendNotification(CODEX_APP_SERVER_METHOD.initialized, {});
|
|
103
|
+
this.initialized = true;
|
|
104
|
+
}
|
|
105
|
+
async startProcess() {
|
|
106
|
+
const command = await this.options.exec.which(this.options.command, this.options.env);
|
|
107
|
+
if (command === null) {
|
|
108
|
+
throw new AgentError({
|
|
109
|
+
code: AGENT_ERROR_CODE.notAvailable,
|
|
110
|
+
message: `Command "${this.options.command}" was not found on PATH`,
|
|
111
|
+
data: { cause: NOT_AVAILABLE_CAUSE.notInstalled },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const process = this.options.exec.spawn({
|
|
115
|
+
command,
|
|
116
|
+
args: [...APP_SERVER_ARGS],
|
|
117
|
+
cwd: this.options.cwd,
|
|
118
|
+
env: this.options.env,
|
|
119
|
+
stdin: null,
|
|
120
|
+
keepStdinOpen: true,
|
|
121
|
+
});
|
|
122
|
+
this.process = process;
|
|
123
|
+
void this.readProcess(process);
|
|
124
|
+
}
|
|
125
|
+
async readProcess(process) {
|
|
126
|
+
try {
|
|
127
|
+
for await (const chunk of process.chunks) {
|
|
128
|
+
if (chunk.channel === OUTPUT_CHANNEL.stderr) {
|
|
129
|
+
this.stderr = appendTail(this.stderr, chunk.text);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
this.handleStdout(chunk.text);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const exit = await process.exit;
|
|
136
|
+
if (this.process === process) {
|
|
137
|
+
this.process = null;
|
|
138
|
+
this.initialized = false;
|
|
139
|
+
}
|
|
140
|
+
if (this.pending.size > 0) {
|
|
141
|
+
this.rejectAll(appServerExitedError(exit.code, this.stderr));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.rejectAll(appServerExitedError(null, error instanceof Error ? error.message : ""));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
handleStdout(text) {
|
|
149
|
+
this.stdoutLine += text;
|
|
150
|
+
const lines = this.stdoutLine.split(JSON_RPC_FRAME_BOUNDARY);
|
|
151
|
+
this.stdoutLine = lines.pop() ?? "";
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
const response = parseResponseLine(line);
|
|
154
|
+
if (response !== null) {
|
|
155
|
+
this.handleResponse(response);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
sendRequest(method, params) {
|
|
160
|
+
const process = this.process;
|
|
161
|
+
if (process === null) {
|
|
162
|
+
throw appServerExitedError(null, this.stderr);
|
|
163
|
+
}
|
|
164
|
+
const id = this.nextId;
|
|
165
|
+
this.nextId += 1;
|
|
166
|
+
return new Promise((resolve, reject) => {
|
|
167
|
+
const cancelTimeout = this.options.clock.setTimeout(() => {
|
|
168
|
+
this.pending.delete(id);
|
|
169
|
+
// A timeout kills the whole server, not just this request: JSON-RPC
|
|
170
|
+
// gives no per-call cancellation, and a hung app-server cannot be
|
|
171
|
+
// trusted with further requests. Other in-flight requests are then
|
|
172
|
+
// rejected as `failed` by the exit path; clients are created per
|
|
173
|
+
// host-plane call, so the blast radius is that one call.
|
|
174
|
+
process.kill(PROCESS_SIGNAL.sigkill);
|
|
175
|
+
reject(new AgentError({
|
|
176
|
+
code: AGENT_ERROR_CODE.timeout,
|
|
177
|
+
message: `Codex app-server request timed out: ${String(method)}`,
|
|
178
|
+
data: {
|
|
179
|
+
kind: TIMEOUT_KIND.total,
|
|
180
|
+
limitMs: this.options.requestTimeoutMs,
|
|
181
|
+
},
|
|
182
|
+
}));
|
|
183
|
+
}, this.options.requestTimeoutMs);
|
|
184
|
+
this.pending.set(id, {
|
|
185
|
+
method,
|
|
186
|
+
resolve,
|
|
187
|
+
reject,
|
|
188
|
+
cancelTimeout,
|
|
189
|
+
});
|
|
190
|
+
process.writeStdin(`${JSON.stringify({ method, id, params })}${JSON_RPC_FRAME_SEPARATOR}`);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
sendNotification(method, params) {
|
|
194
|
+
this.process?.writeStdin(`${JSON.stringify({ method, params })}${JSON_RPC_FRAME_SEPARATOR}`);
|
|
195
|
+
}
|
|
196
|
+
handleResponse(response) {
|
|
197
|
+
const pending = this.pending.get(response.id);
|
|
198
|
+
if (pending === undefined) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
this.pending.delete(response.id);
|
|
202
|
+
pending.cancelTimeout();
|
|
203
|
+
if (response.error !== null) {
|
|
204
|
+
pending.reject(appServerResponseError(pending.method, response.error));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const decoder = resultDecoderFor(pending.method);
|
|
208
|
+
if (decoder === null) {
|
|
209
|
+
pending.resolve(response.result);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const decoded = decoder(response.result);
|
|
213
|
+
if (decoded === null) {
|
|
214
|
+
pending.reject(appServerMalformedResultError(pending.method, response.result));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
pending.resolve(decoded);
|
|
218
|
+
}
|
|
219
|
+
rejectAll(error) {
|
|
220
|
+
for (const pending of this.pending.values()) {
|
|
221
|
+
pending.cancelTimeout();
|
|
222
|
+
pending.reject(error);
|
|
223
|
+
}
|
|
224
|
+
this.pending.clear();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function resolveOptions(options) {
|
|
228
|
+
return {
|
|
229
|
+
exec: options.exec,
|
|
230
|
+
clock: options.clock,
|
|
231
|
+
env: options.env,
|
|
232
|
+
cwd: options.cwd,
|
|
233
|
+
command: options.command ?? DEFAULT_CODEX_COMMAND,
|
|
234
|
+
requestTimeoutMs: options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
|
|
235
|
+
clientInfo: options.clientInfo ?? DEFAULT_APP_SERVER_CLIENT_INFO,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/** `initialize` is handshake-only; its result is intentionally not modeled. */
|
|
239
|
+
function resultDecoderFor(method) {
|
|
240
|
+
return method === CODEX_APP_SERVER_METHOD.initialize
|
|
241
|
+
? null
|
|
242
|
+
: CODEX_APP_SERVER_RESULT_DECODERS[method];
|
|
243
|
+
}
|
|
244
|
+
function appendTail(current, next) {
|
|
245
|
+
const combined = current + next;
|
|
246
|
+
return combined.length <= OUTPUT_TAIL_CHARS
|
|
247
|
+
? combined
|
|
248
|
+
: combined.slice(-OUTPUT_TAIL_CHARS);
|
|
249
|
+
}
|
|
250
|
+
function parseResponseLine(line) {
|
|
251
|
+
const record = readJsonRecord(line.trim());
|
|
252
|
+
if (record === null) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
// Server-initiated requests and notifications carry `method`; a JSON-RPC
|
|
256
|
+
// response never does. Their id space is the server's own, so treating
|
|
257
|
+
// them as responses would resolve an unrelated pending client request.
|
|
258
|
+
if (record[JSON_RPC_FIELD.method] !== undefined) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
const id = record[JSON_RPC_FIELD.id];
|
|
262
|
+
if (typeof id !== "number") {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
id,
|
|
267
|
+
result: record[JSON_RPC_FIELD.result],
|
|
268
|
+
error: jsonRpcErrorFromUnknown(record[JSON_RPC_FIELD.error]),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function jsonRpcErrorFromUnknown(value) {
|
|
272
|
+
if (typeof value !== "object" || value === null) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
const message = Reflect.get(value, JSON_RPC_FIELD.message);
|
|
276
|
+
return {
|
|
277
|
+
message: typeof message === "string" ? message : null,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function appServerResponseError(method, error) {
|
|
281
|
+
const detail = redactSecrets(error.message ?? "");
|
|
282
|
+
return new AgentError({
|
|
283
|
+
code: AGENT_ERROR_CODE.failed,
|
|
284
|
+
message: detail === "" ? `Codex app-server request failed: ${method}` : detail,
|
|
285
|
+
data: {
|
|
286
|
+
exitCode: null,
|
|
287
|
+
stdoutTail: null,
|
|
288
|
+
stderrTail: detail === "" ? null : detail.slice(-OUTPUT_TAIL_CHARS),
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
function appServerMalformedResultError(method, result) {
|
|
293
|
+
const detail = redactSecrets(JSON.stringify(result) ?? "");
|
|
294
|
+
return new AgentError({
|
|
295
|
+
code: AGENT_ERROR_CODE.failed,
|
|
296
|
+
message: `Codex app-server returned a malformed result: ${method}`,
|
|
297
|
+
data: {
|
|
298
|
+
exitCode: null,
|
|
299
|
+
stdoutTail: detail === "" ? null : detail.slice(-OUTPUT_TAIL_CHARS),
|
|
300
|
+
stderrTail: null,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function appServerExitedError(exitCode, stderr) {
|
|
305
|
+
const stderrTail = redactSecrets(stderr.slice(-OUTPUT_TAIL_CHARS));
|
|
306
|
+
return new AgentError({
|
|
307
|
+
code: AGENT_ERROR_CODE.failed,
|
|
308
|
+
message: "Codex app-server exited before completing the request",
|
|
309
|
+
data: {
|
|
310
|
+
exitCode,
|
|
311
|
+
stdoutTail: null,
|
|
312
|
+
stderrTail: stderrTail === "" ? null : stderrTail,
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function appServerClosedError() {
|
|
317
|
+
return new AgentError({
|
|
318
|
+
code: AGENT_ERROR_CODE.failed,
|
|
319
|
+
message: "Codex app-server connection closed",
|
|
320
|
+
data: { exitCode: null, stdoutTail: null, stderrTail: null },
|
|
321
|
+
});
|
|
322
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { type AppServerClientInfo, type CodexAppServer, type CodexAppServerOptions, createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
|
|
2
|
+
export type { CodexAppServerMethods, CodexMcpServerStatus, CodexMcpServerStatusPage, CodexPluginInstallResult, CodexPluginListResult, CodexPluginMarketplace, CodexPluginSummary, CodexSkillListResult, } from "./protocol.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codex/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,6BAA6B,EAC7B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createCodexAppServer, listAllCodexMcpServerStatuses, withCodexAppServer, } from "./app-server.js";
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-server method registry: adding a method adds a row in
|
|
3
|
+
* `CodexAppServerMethods` plus its decoder row in
|
|
4
|
+
* `CODEX_APP_SERVER_RESULT_DECODERS`. Result rows are RESOLVED shapes
|
|
5
|
+
* (rule 2): meaningful absence is `null` / empty collection, never `?`.
|
|
6
|
+
* The decoders normalize the foreign JSON-RPC payload at the boundary
|
|
7
|
+
* (rule 1) — strict on the fields consumers depend on, normalizing on
|
|
8
|
+
* fields the server may omit — so a malformed server response becomes a
|
|
9
|
+
* typed failure in the client instead of a TypeError in a caller.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CODEX_APP_SERVER_METHOD: {
|
|
12
|
+
readonly initialize: "initialize";
|
|
13
|
+
readonly initialized: "initialized";
|
|
14
|
+
readonly pluginList: "plugin/list";
|
|
15
|
+
readonly pluginInstall: "plugin/install";
|
|
16
|
+
readonly skillsList: "skills/list";
|
|
17
|
+
readonly mcpServerStatusList: "mcpServerStatus/list";
|
|
18
|
+
};
|
|
19
|
+
export declare const CODEX_MCP_STATUS_DETAIL: {
|
|
20
|
+
readonly toolsAndAuthOnly: "toolsAndAuthOnly";
|
|
21
|
+
};
|
|
22
|
+
export type CodexMcpStatusDetail = (typeof CODEX_MCP_STATUS_DETAIL)[keyof typeof CODEX_MCP_STATUS_DETAIL];
|
|
23
|
+
export type CodexPluginInterfaceSummary = {
|
|
24
|
+
readonly displayName: string | null;
|
|
25
|
+
readonly shortDescription: string | null;
|
|
26
|
+
readonly longDescription: string | null;
|
|
27
|
+
readonly capabilities: readonly string[];
|
|
28
|
+
};
|
|
29
|
+
export type CodexPluginSummary = {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly installed: boolean;
|
|
33
|
+
readonly enabled: boolean;
|
|
34
|
+
readonly installPolicy: string;
|
|
35
|
+
readonly interface: CodexPluginInterfaceSummary | null;
|
|
36
|
+
};
|
|
37
|
+
export type CodexPluginMarketplace = {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly path: string | null;
|
|
40
|
+
readonly plugins: readonly CodexPluginSummary[];
|
|
41
|
+
};
|
|
42
|
+
export type CodexMarketplaceLoadError = {
|
|
43
|
+
readonly marketplacePath: string;
|
|
44
|
+
readonly message: string;
|
|
45
|
+
};
|
|
46
|
+
export type CodexPluginListResult = {
|
|
47
|
+
readonly marketplaces: readonly CodexPluginMarketplace[];
|
|
48
|
+
readonly marketplaceLoadErrors: readonly CodexMarketplaceLoadError[];
|
|
49
|
+
};
|
|
50
|
+
export type CodexPluginInstallResult = {
|
|
51
|
+
readonly status: string | null;
|
|
52
|
+
readonly alreadyInstalled: boolean | null;
|
|
53
|
+
readonly appsNeedingAuth: readonly unknown[];
|
|
54
|
+
readonly authPolicy: string | null;
|
|
55
|
+
readonly location: string | null;
|
|
56
|
+
};
|
|
57
|
+
export type CodexSkillSummary = {
|
|
58
|
+
readonly name: string;
|
|
59
|
+
readonly description: string;
|
|
60
|
+
readonly enabled: boolean;
|
|
61
|
+
readonly path: string;
|
|
62
|
+
readonly scope: string;
|
|
63
|
+
};
|
|
64
|
+
export type CodexSkillListEntryError = {
|
|
65
|
+
readonly path: string;
|
|
66
|
+
readonly message: string;
|
|
67
|
+
};
|
|
68
|
+
export type CodexSkillListEntry = {
|
|
69
|
+
readonly cwd: string;
|
|
70
|
+
readonly skills: readonly CodexSkillSummary[];
|
|
71
|
+
readonly errors: readonly CodexSkillListEntryError[];
|
|
72
|
+
};
|
|
73
|
+
export type CodexSkillListResult = {
|
|
74
|
+
readonly data: readonly CodexSkillListEntry[];
|
|
75
|
+
};
|
|
76
|
+
export type CodexMcpToolSummary = {
|
|
77
|
+
readonly name: string | null;
|
|
78
|
+
};
|
|
79
|
+
export type CodexMcpServerStatus = {
|
|
80
|
+
readonly name: string;
|
|
81
|
+
readonly authStatus: string;
|
|
82
|
+
/** `null` = the server did not enumerate tools (distinct from zero tools). */
|
|
83
|
+
readonly tools: Readonly<Record<string, CodexMcpToolSummary>> | null;
|
|
84
|
+
};
|
|
85
|
+
export type CodexMcpServerStatusPage = {
|
|
86
|
+
readonly data: readonly CodexMcpServerStatus[];
|
|
87
|
+
readonly nextCursor: string | null;
|
|
88
|
+
};
|
|
89
|
+
export type CodexAppServerMethods = {
|
|
90
|
+
[CODEX_APP_SERVER_METHOD.pluginList]: {
|
|
91
|
+
readonly params: {
|
|
92
|
+
readonly cwds: readonly string[];
|
|
93
|
+
};
|
|
94
|
+
readonly result: CodexPluginListResult;
|
|
95
|
+
};
|
|
96
|
+
[CODEX_APP_SERVER_METHOD.pluginInstall]: {
|
|
97
|
+
readonly params: {
|
|
98
|
+
readonly pluginName: string;
|
|
99
|
+
readonly marketplacePath: string | null;
|
|
100
|
+
readonly remoteMarketplaceName: string | null;
|
|
101
|
+
};
|
|
102
|
+
readonly result: CodexPluginInstallResult;
|
|
103
|
+
};
|
|
104
|
+
[CODEX_APP_SERVER_METHOD.skillsList]: {
|
|
105
|
+
readonly params: {
|
|
106
|
+
readonly cwds: readonly string[];
|
|
107
|
+
readonly forceReload: boolean;
|
|
108
|
+
};
|
|
109
|
+
readonly result: CodexSkillListResult;
|
|
110
|
+
};
|
|
111
|
+
[CODEX_APP_SERVER_METHOD.mcpServerStatusList]: {
|
|
112
|
+
readonly params: {
|
|
113
|
+
readonly detail: CodexMcpStatusDetail;
|
|
114
|
+
readonly cursor: string | null;
|
|
115
|
+
readonly limit: number;
|
|
116
|
+
};
|
|
117
|
+
readonly result: CodexMcpServerStatusPage;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
export type CodexAppServerResultDecoder<M extends keyof CodexAppServerMethods> = (value: unknown) => CodexAppServerMethods[M]["result"] | null;
|
|
121
|
+
export declare const CODEX_APP_SERVER_RESULT_DECODERS: {
|
|
122
|
+
readonly [M in keyof CodexAppServerMethods]: CodexAppServerResultDecoder<M>;
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/codex/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAEX,eAAO,MAAM,uBAAuB;;CAE1B,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAC9B,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC;AAEzE,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,2BAA2B,GAAG,IAAI,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACzD,QAAQ,CAAC,qBAAqB,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,GAAG,IAAI,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE;QACpC,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;SAAE,CAAC;QACtD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;KACxC,CAAC;IACF,CAAC,uBAAuB,CAAC,aAAa,CAAC,EAAE;QACvC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;YACxC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;SAC/C,CAAC;QACF,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;KAC3C,CAAC;IACF,CAAC,uBAAuB,CAAC,UAAU,CAAC,EAAE;QACpC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;YACjC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;SAC/B,CAAC;QACF,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;KACvC,CAAC;IACF,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,EAAE;QAC7C,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;YACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;YAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,qBAAqB,IAC3E,CAAC,KAAK,EAAE,OAAO,KAAK,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;AAmChE,eAAO,MAAM,gCAAgC,EAAE;IAC7C,QAAQ,EAAE,CAAC,IAAI,MAAM,qBAAqB,GAAG,2BAA2B,CAAC,CAAC,CAAC;CAM5E,CAAC"}
|