@parall/codex-agent 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +90 -0
- package/dist/dispatch.d.ts +53 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +515 -0
- package/dist/event-mapping.d.ts +36 -0
- package/dist/event-mapping.d.ts.map +1 -0
- package/dist/event-mapping.js +246 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/jsonrpc-client.d.ts +51 -0
- package/dist/jsonrpc-client.d.ts.map +1 -0
- package/dist/jsonrpc-client.js +111 -0
- package/dist/session-manager.d.ts +28 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +82 -0
- package/dist/workspace.d.ts +4 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +26 -0
- package/package.json +41 -0
- package/src/config.ts +118 -0
- package/src/dispatch.ts +559 -0
- package/src/event-mapping.ts +258 -0
- package/src/index.ts +107 -0
- package/src/jsonrpc-client.ts +148 -0
- package/src/session-manager.ts +104 -0
- package/src/workspace.ts +32 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type CodexAgentConfig = {
|
|
2
|
+
apiUrl: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
orgId: string;
|
|
5
|
+
wsUrl?: string;
|
|
6
|
+
swimlaneName?: string;
|
|
7
|
+
codexBin: string;
|
|
8
|
+
codexHome: string;
|
|
9
|
+
stateDir: string;
|
|
10
|
+
workspaceDir: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
reasoningEffort?: string;
|
|
13
|
+
sandbox: string;
|
|
14
|
+
approvalPolicy: string;
|
|
15
|
+
runtimeKey?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function resolveCodexAgentConfig(env?: NodeJS.ProcessEnv): CodexAgentConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Normalise a sandbox value (CLI docs use kebab-case like `workspace-write`,
|
|
20
|
+
* but the app-server JSON-RPC protocol uses camelCase like `workspaceWrite`).
|
|
21
|
+
* Accept both forms and emit the canonical protocol form.
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeSandbox(value: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Normalise an approval policy string to the camelCase form the app-server
|
|
26
|
+
* JSON-RPC protocol uses (`never` / `onRequest` / `unlessTrusted`).
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizeApprovalPolicy(value: string): string;
|
|
29
|
+
export declare function resolveWsUrl(apiUrl: string, explicitWsUrl?: string, swimlaneName?: string): string;
|
|
30
|
+
export declare function buildCodexRuntimeKey(agentUserId: string): string;
|
|
31
|
+
export declare function sessionStateFilePathForRuntime(stateDir: string, runtimeKey: string): string;
|
|
32
|
+
export declare function stepIdFilePathForSession(stateDir: string, sessionKey: string): string;
|
|
33
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CA6B9F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlG;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrF"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
function requireEnv(env, name) {
|
|
4
|
+
const value = env[name]?.trim();
|
|
5
|
+
if (!value) {
|
|
6
|
+
throw new Error(`Missing required env var: ${name}`);
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
function resolvePath(value) {
|
|
11
|
+
return path.isAbsolute(value) ? value : path.resolve(process.cwd(), value);
|
|
12
|
+
}
|
|
13
|
+
export function resolveCodexAgentConfig(env = process.env) {
|
|
14
|
+
const apiUrl = requireEnv(env, "PRLL_API_URL");
|
|
15
|
+
const apiKey = requireEnv(env, "PRLL_API_KEY");
|
|
16
|
+
const orgId = requireEnv(env, "PRLL_ORG_ID");
|
|
17
|
+
const codexHome = resolvePath(env.PRLL_CODEX_HOME?.trim()
|
|
18
|
+
|| env.CODEX_HOME?.trim()
|
|
19
|
+
|| env.HOME
|
|
20
|
+
|| os.homedir());
|
|
21
|
+
const stateDir = resolvePath(env.PRLL_CODEX_STATE_DIR?.trim() || path.join(codexHome, ".parall-agent"));
|
|
22
|
+
const workspaceDir = resolvePath(env.PRLL_CODEX_WORKSPACE_DIR?.trim() || path.join(stateDir, "workspace"));
|
|
23
|
+
return {
|
|
24
|
+
apiUrl,
|
|
25
|
+
apiKey,
|
|
26
|
+
orgId,
|
|
27
|
+
wsUrl: env.PRLL_WS_URL?.trim() || undefined,
|
|
28
|
+
swimlaneName: env.PRLL_SWIMLANE_NAME?.trim() || undefined,
|
|
29
|
+
codexBin: env.PRLL_CODEX_BIN?.trim() || "codex",
|
|
30
|
+
codexHome,
|
|
31
|
+
stateDir,
|
|
32
|
+
workspaceDir,
|
|
33
|
+
model: env.PRLL_CODEX_MODEL?.trim() || undefined,
|
|
34
|
+
reasoningEffort: env.PRLL_CODEX_REASONING_EFFORT?.trim() || undefined,
|
|
35
|
+
sandbox: env.PRLL_CODEX_SANDBOX?.trim() || "workspace-write",
|
|
36
|
+
approvalPolicy: env.PRLL_CODEX_APPROVAL?.trim() || "never",
|
|
37
|
+
runtimeKey: env.PRLL_CODEX_RUNTIME_KEY?.trim() || undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Normalise a sandbox value (CLI docs use kebab-case like `workspace-write`,
|
|
42
|
+
* but the app-server JSON-RPC protocol uses camelCase like `workspaceWrite`).
|
|
43
|
+
* Accept both forms and emit the canonical protocol form.
|
|
44
|
+
*/
|
|
45
|
+
export function normalizeSandbox(value) {
|
|
46
|
+
const map = {
|
|
47
|
+
"workspace-write": "workspaceWrite",
|
|
48
|
+
"workspacewrite": "workspaceWrite",
|
|
49
|
+
"danger-full-access": "dangerFullAccess",
|
|
50
|
+
"dangerfullaccess": "dangerFullAccess",
|
|
51
|
+
"read-only": "readOnly",
|
|
52
|
+
"readonly": "readOnly",
|
|
53
|
+
};
|
|
54
|
+
return map[value.toLowerCase()] ?? value;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Normalise an approval policy string to the camelCase form the app-server
|
|
58
|
+
* JSON-RPC protocol uses (`never` / `onRequest` / `unlessTrusted`).
|
|
59
|
+
*/
|
|
60
|
+
export function normalizeApprovalPolicy(value) {
|
|
61
|
+
const map = {
|
|
62
|
+
"never": "never",
|
|
63
|
+
"on-request": "onRequest",
|
|
64
|
+
"onrequest": "onRequest",
|
|
65
|
+
"unless-trusted": "unlessTrusted",
|
|
66
|
+
"unlesstrusted": "unlessTrusted",
|
|
67
|
+
"on-failure": "onFailure",
|
|
68
|
+
"onfailure": "onFailure",
|
|
69
|
+
};
|
|
70
|
+
return map[value.toLowerCase()] ?? value;
|
|
71
|
+
}
|
|
72
|
+
export function resolveWsUrl(apiUrl, explicitWsUrl, swimlaneName) {
|
|
73
|
+
const base = explicitWsUrl || `${apiUrl.replace(/\/$/, "").replace(/^http/, "ws")}/ws`;
|
|
74
|
+
if (!swimlaneName)
|
|
75
|
+
return base;
|
|
76
|
+
const url = new URL(base);
|
|
77
|
+
url.searchParams.set("swimlane", swimlaneName);
|
|
78
|
+
return url.toString();
|
|
79
|
+
}
|
|
80
|
+
export function buildCodexRuntimeKey(agentUserId) {
|
|
81
|
+
return `agent:main:codex:${agentUserId}:orchestrator`;
|
|
82
|
+
}
|
|
83
|
+
export function sessionStateFilePathForRuntime(stateDir, runtimeKey) {
|
|
84
|
+
const fileName = Buffer.from(runtimeKey).toString("base64url");
|
|
85
|
+
return path.join(stateDir, "threads", `${fileName}.json`);
|
|
86
|
+
}
|
|
87
|
+
export function stepIdFilePathForSession(stateDir, sessionKey) {
|
|
88
|
+
const fileName = Buffer.from(sessionKey).toString("base64url");
|
|
89
|
+
return path.join(stateDir, "step-ids", `${fileName}.txt`);
|
|
90
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CleanupForkOpts, DispatchAdapter, DispatchOpts, ForkOpts, ForkSessionHandle, GatewayLogger, RuntimeEvent } from "@parall/agent-core";
|
|
2
|
+
import type { CodexAgentConfig } from "./config.js";
|
|
3
|
+
import type { CodexSessionManager } from "./session-manager.js";
|
|
4
|
+
type CodexAppServerAdapterOptions = Pick<CodexAgentConfig, "approvalPolicy" | "codexBin" | "codexHome" | "model" | "reasoningEffort" | "sandbox" | "workspaceDir"> & {
|
|
5
|
+
sessionManager: CodexSessionManager;
|
|
6
|
+
log?: GatewayLogger;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Bridge driver backed by `codex app-server --listen stdio://`.
|
|
10
|
+
*
|
|
11
|
+
* Lifecycle:
|
|
12
|
+
* - bridge startup: spawn one `codex app-server` subprocess, do the
|
|
13
|
+
* `initialize` / `initialized` handshake once, keep the pipe open
|
|
14
|
+
* - per Parall dispatch: `thread/start` (first time) or `thread/resume`,
|
|
15
|
+
* then `turn/start`; forward server notifications until `turn/completed`
|
|
16
|
+
* - fork-on-busy: `thread/fork` creates a disposable sibling thread
|
|
17
|
+
*
|
|
18
|
+
* Concurrency: agent-core routes one dispatch per sessionKey at a time, so
|
|
19
|
+
* main + fork can interleave turns on the same stdio pipe. We route
|
|
20
|
+
* notifications by threadId the server stamps on every item/turn event.
|
|
21
|
+
*/
|
|
22
|
+
export declare class CodexAppServerAdapter implements DispatchAdapter {
|
|
23
|
+
private readonly opts;
|
|
24
|
+
private client;
|
|
25
|
+
private proc;
|
|
26
|
+
private initialized;
|
|
27
|
+
private startPromise;
|
|
28
|
+
private readonly activeTurns;
|
|
29
|
+
private readonly resumedThreadIds;
|
|
30
|
+
private stopping;
|
|
31
|
+
/**
|
|
32
|
+
* Store an active turn sink keyed by threadId. If a sink already exists for
|
|
33
|
+
* the same threadId, log a warning and fail the existing sink — this
|
|
34
|
+
* shouldn't happen in practice (agent-core serialises per sessionKey, and
|
|
35
|
+
* thread/fork returns a distinct id) but the failure mode of a silent
|
|
36
|
+
* replacement would be a perpetually hung dispatch generator, which is
|
|
37
|
+
* hard to debug.
|
|
38
|
+
*/
|
|
39
|
+
private setActiveTurn;
|
|
40
|
+
constructor(opts: CodexAppServerAdapterOptions);
|
|
41
|
+
dispatch({ bodyForAgent, sessionKey, context }: DispatchOpts): AsyncIterable<RuntimeEvent>;
|
|
42
|
+
forkSession({ sessionKey: parentSessionKey }: ForkOpts): Promise<ForkSessionHandle | null>;
|
|
43
|
+
cleanupFork({ fork }: CleanupForkOpts): void;
|
|
44
|
+
private logForkFailure;
|
|
45
|
+
stop(): Promise<void>;
|
|
46
|
+
private ensureStarted;
|
|
47
|
+
private doStart;
|
|
48
|
+
private handleSubprocessClose;
|
|
49
|
+
private openThread;
|
|
50
|
+
private routeNotification;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,KAAK,4BAA4B,GAAG,IAAI,CACtC,gBAAgB,EACd,gBAAgB,GAChB,UAAU,GACV,WAAW,GACX,OAAO,GACP,iBAAiB,GACjB,SAAS,GACT,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,mBAAmB,CAAC;IACpC,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IA6B/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IA5BjC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;gBAYQ,IAAI,EAAE,4BAA4B;IAExD,QAAQ,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IA0J3F,WAAW,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAuBhG,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAIrC,OAAO,CAAC,cAAc;IAKhB,IAAI;YAaI,aAAa;YAcb,OAAO;IA2DrB,OAAO,CAAC,qBAAqB;YAiCf,UAAU;IAuCxB,OAAO,CAAC,iBAAiB;CA2B1B"}
|