@excitedjs/agent-runtime-codex 0.2.0-alpha.g0ddd418597ca
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 +44 -0
- package/dist/approval.d.ts +30 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +42 -0
- package/dist/approval.js.map +1 -0
- package/dist/args.d.ts +55 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +113 -0
- package/dist/args.js.map +1 -0
- package/dist/bin.d.ts +14 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +18 -0
- package/dist/bin.js.map +1 -0
- package/dist/codex-home.d.ts +42 -0
- package/dist/codex-home.d.ts.map +1 -0
- package/dist/codex-home.js +112 -0
- package/dist/codex-home.js.map +1 -0
- package/dist/config.d.ts +76 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +106 -0
- package/dist/config.js.map +1 -0
- package/dist/diagnostic.d.ts +14 -0
- package/dist/diagnostic.d.ts.map +1 -0
- package/dist/diagnostic.js +58 -0
- package/dist/diagnostic.js.map +1 -0
- package/dist/events.d.ts +88 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +225 -0
- package/dist/events.js.map +1 -0
- package/dist/handshake.d.ts +44 -0
- package/dist/handshake.d.ts.map +1 -0
- package/dist/handshake.js +85 -0
- package/dist/handshake.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/completion-body.d.ts +38 -0
- package/dist/internal/completion-body.d.ts.map +1 -0
- package/dist/internal/completion-body.js +62 -0
- package/dist/internal/completion-body.js.map +1 -0
- package/dist/internal/config-validate.d.ts +23 -0
- package/dist/internal/config-validate.d.ts.map +1 -0
- package/dist/internal/config-validate.js +122 -0
- package/dist/internal/config-validate.js.map +1 -0
- package/dist/internal/os.d.ts +30 -0
- package/dist/internal/os.d.ts.map +1 -0
- package/dist/internal/os.js +81 -0
- package/dist/internal/os.js.map +1 -0
- package/dist/internal/socket.d.ts +23 -0
- package/dist/internal/socket.d.ts.map +1 -0
- package/dist/internal/socket.js +74 -0
- package/dist/internal/socket.js.map +1 -0
- package/dist/internal/turn-render.d.ts +22 -0
- package/dist/internal/turn-render.d.ts.map +1 -0
- package/dist/internal/turn-render.js +40 -0
- package/dist/internal/turn-render.js.map +1 -0
- package/dist/mcp-config.d.ts +9 -0
- package/dist/mcp-config.d.ts.map +1 -0
- package/dist/mcp-config.js +21 -0
- package/dist/mcp-config.js.map +1 -0
- package/dist/paths.d.ts +7 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +26 -0
- package/dist/paths.js.map +1 -0
- package/dist/provider-ref.d.ts +8 -0
- package/dist/provider-ref.d.ts.map +1 -0
- package/dist/provider-ref.js +8 -0
- package/dist/provider-ref.js.map +1 -0
- package/dist/provider.d.ts +71 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +137 -0
- package/dist/provider.js.map +1 -0
- package/dist/rpc.d.ts +65 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +200 -0
- package/dist/rpc.js.map +1 -0
- package/dist/runtime-support.d.ts +27 -0
- package/dist/runtime-support.d.ts.map +1 -0
- package/dist/runtime-support.js +57 -0
- package/dist/runtime-support.js.map +1 -0
- package/dist/runtime.d.ts +246 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +648 -0
- package/dist/runtime.js.map +1 -0
- package/dist/supervisor.d.ts +55 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +183 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/turn-manager.d.ts +92 -0
- package/dist/turn-manager.d.ts.map +1 -0
- package/dist/turn-manager.js +271 -0
- package/dist/turn-manager.js.map +1 -0
- package/dist/types.d.ts +143 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +16 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +33 -0
- package/dist/version.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 excitedjs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @excitedjs/agent-runtime-codex
|
|
2
|
+
|
|
3
|
+
The built-in **Codex** Agent Runtime provider for
|
|
4
|
+
[Dreamux](https://github.com/excitedjs/dreamux), published behind the stable
|
|
5
|
+
`builtin:codex` alias.
|
|
6
|
+
|
|
7
|
+
It implements the public `AgentRuntimeProvider` contract from
|
|
8
|
+
[`@excitedjs/dreamux-types`](../../dreamux-types) against the Codex
|
|
9
|
+
`app-server`: process supervision, the WebSocket RPC client, the `initialize`
|
|
10
|
+
handshake, thread start/resume, the per-runtime turn manager, teammate
|
|
11
|
+
completion delivery, and Codex doctor diagnostics.
|
|
12
|
+
|
|
13
|
+
## Boundary
|
|
14
|
+
|
|
15
|
+
This package depends on `@excitedjs/dreamux-types` **only**. It never imports
|
|
16
|
+
`@excitedjs/dreamux` core. Everything host-specific — per-dispatcher paths, the
|
|
17
|
+
volatile rendezvous-socket root, the durable state sink, the process `PATH`
|
|
18
|
+
seeded from the host package bins, and bundled-skill installation — is supplied
|
|
19
|
+
by the Dreamux host through the neutral `AgentRuntimeCreateContext` and the
|
|
20
|
+
provider factory options. The package owns only Codex-engine mechanics and its
|
|
21
|
+
own `~/.codex` home/config paths.
|
|
22
|
+
|
|
23
|
+
The host resolves `builtin:codex` to this package and wraps it with a
|
|
24
|
+
core-owned adapter that maps its private dispatcher objects onto the neutral
|
|
25
|
+
contract; see
|
|
26
|
+
`.agents/decisions/npm-package-split-and-channel-targets.md`.
|
|
27
|
+
|
|
28
|
+
## Logger
|
|
29
|
+
|
|
30
|
+
The package logs through the optional `DreamuxLogger` the host passes in. With
|
|
31
|
+
no logger it falls back to a minimal `console.error`-backed sink for standalone
|
|
32
|
+
use and tests.
|
|
33
|
+
|
|
34
|
+
## Standalone use
|
|
35
|
+
|
|
36
|
+
External callers can register this provider directly:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { createCodexAgentRuntimeProvider } from '@excitedjs/agent-runtime-codex';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The factory accepts the neutral create context plus optional host hooks
|
|
43
|
+
(socket allocator, base process env, workspace skill preparation, and test
|
|
44
|
+
factories for the Codex process / WS client / home doctor).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Approval handler for Codex server→client requests.
|
|
3
|
+
*
|
|
4
|
+
* Issue #2 §"信任模型" + §"实现陷阱":
|
|
5
|
+
* - MVP runs Codex with approval-policy=never (or auto-approve).
|
|
6
|
+
* - If a server-request still arrives (e.g. because policy was misconfigured
|
|
7
|
+
* or codex escalates anyway), fail loudly — never return null. Silent null
|
|
8
|
+
* is the trap that hangs the daemon.
|
|
9
|
+
*
|
|
10
|
+
* `onReject` is an observer hook for logs or metrics. Feishu user-visible
|
|
11
|
+
* output is MCP reply-only, so this handler must not send channel messages.
|
|
12
|
+
*/
|
|
13
|
+
import type { ServerRequest } from './types.js';
|
|
14
|
+
export interface ApprovalHandlerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Called when a server-request is rejected. Errors thrown here are swallowed
|
|
17
|
+
* because the rejection itself still propagates to codex.
|
|
18
|
+
*/
|
|
19
|
+
onReject?: (req: ServerRequest) => void | Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare function looksLikeApprovalRequest(method: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Build a fail-fast server-request handler.
|
|
24
|
+
*
|
|
25
|
+
* The handler always throws — i.e. every server-request becomes an `error`
|
|
26
|
+
* response on the wire — but it tags approval-related methods with a
|
|
27
|
+
* user-readable message and notifies `onReject`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createFailFastApprovalHandler(opts?: ApprovalHandlerOptions): (req: ServerRequest) => Promise<unknown>;
|
|
30
|
+
//# sourceMappingURL=approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../src/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAKD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,GAAE,sBAA2B,IAEnB,KAAK,aAAa,KAAG,OAAO,CAAC,OAAO,CAAC,CAiBpD"}
|
package/dist/approval.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Approval handler for Codex server→client requests.
|
|
3
|
+
*
|
|
4
|
+
* Issue #2 §"信任模型" + §"实现陷阱":
|
|
5
|
+
* - MVP runs Codex with approval-policy=never (or auto-approve).
|
|
6
|
+
* - If a server-request still arrives (e.g. because policy was misconfigured
|
|
7
|
+
* or codex escalates anyway), fail loudly — never return null. Silent null
|
|
8
|
+
* is the trap that hangs the daemon.
|
|
9
|
+
*
|
|
10
|
+
* `onReject` is an observer hook for logs or metrics. Feishu user-visible
|
|
11
|
+
* output is MCP reply-only, so this handler must not send channel messages.
|
|
12
|
+
*/
|
|
13
|
+
/** A method name like `exec_command_approval`, `apply_patch_approval`, etc. */
|
|
14
|
+
const APPROVAL_METHOD_HINTS = ['approval', 'approve', 'confirm', 'review'];
|
|
15
|
+
export function looksLikeApprovalRequest(method) {
|
|
16
|
+
const m = method.toLowerCase();
|
|
17
|
+
return APPROVAL_METHOD_HINTS.some((h) => m.includes(h));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a fail-fast server-request handler.
|
|
21
|
+
*
|
|
22
|
+
* The handler always throws — i.e. every server-request becomes an `error`
|
|
23
|
+
* response on the wire — but it tags approval-related methods with a
|
|
24
|
+
* user-readable message and notifies `onReject`.
|
|
25
|
+
*/
|
|
26
|
+
export function createFailFastApprovalHandler(opts = {}) {
|
|
27
|
+
return async (req) => {
|
|
28
|
+
if (opts.onReject !== undefined) {
|
|
29
|
+
try {
|
|
30
|
+
await opts.onReject(req);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* observer hook, must not mask the rejection itself */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (looksLikeApprovalRequest(req.method)) {
|
|
37
|
+
throw new Error(`当前版本不支持审批(${req.method})。请配置 codex approval-policy=never 或将本 dispatcher 部署在 trusted-local 环境。`);
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`dispatcher 收到未支持的 codex server-request:${req.method}(id=${req.id})`);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../src/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,+EAA+E;AAC/E,MAAM,qBAAqB,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAE3E,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAA+B,EAAE;IAEjC,OAAO,KAAK,EAAE,GAAkB,EAAoB,EAAE;QACpD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,uDAAuD;YACzD,CAAC;QACH,CAAC;QACD,IAAI,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,aAAa,GAAG,CAAC,MAAM,wEAAwE,CAChG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CACb,0CAA0C,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,EAAE,GAAG,CACrE,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse `dispatchers.codex_args_json` into the CLI-arg array passed to
|
|
3
|
+
* the codex app-server child, AND validate that the trusted-local
|
|
4
|
+
* invariants from issue #2 §"信任模型" hold.
|
|
5
|
+
*
|
|
6
|
+
* Canonical shape:
|
|
7
|
+
* {
|
|
8
|
+
* "approvalPolicy": "never", // from dispatchers[].runtime.config
|
|
9
|
+
* "sandboxMode": "workspace-write", // from dispatchers[].runtime.config
|
|
10
|
+
* "extraArgs": ["--model", "..."] // from runtime.config.extra_args
|
|
11
|
+
* }
|
|
12
|
+
*
|
|
13
|
+
* This JSON is encoded per dispatcher from
|
|
14
|
+
* `dispatchers[].runtime.config` (every field carries a dispatcher-local
|
|
15
|
+
* default), so it is the sole source of truth. The optional `defaults` param
|
|
16
|
+
* remains a thin seam; with the top-level `codex` block removed there is no
|
|
17
|
+
* global layer, and a caller normally passes nothing.
|
|
18
|
+
*
|
|
19
|
+
* Precedence for each field (highest wins):
|
|
20
|
+
* 1. dispatchers.codex_args_json (this JSON)
|
|
21
|
+
* 2. `defaults` (optional caller seam)
|
|
22
|
+
* 3. hardcoded fallbacks (`'never'`, `'workspace-write'`, `[]`)
|
|
23
|
+
*
|
|
24
|
+
* `approvalPolicy` not in the trusted-local allowlist fails-fast at startup
|
|
25
|
+
* (issue #2 §"实现陷阱"): dispatcher refuses to come up if the policy may
|
|
26
|
+
* request approval AND no approval handler is wired.
|
|
27
|
+
*
|
|
28
|
+
* `sandboxMode` is similarly validated against the codex 0.134 enum so a
|
|
29
|
+
* typo doesn't reach the daemon (where the only feedback is a fatal early
|
|
30
|
+
* exit).
|
|
31
|
+
*/
|
|
32
|
+
export interface ParsedCodexArgs {
|
|
33
|
+
approvalPolicy: string;
|
|
34
|
+
sandboxMode: string;
|
|
35
|
+
extraArgs: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface CodexArgsDefaults {
|
|
38
|
+
approvalPolicy?: string;
|
|
39
|
+
sandboxMode?: string;
|
|
40
|
+
extraArgs?: string[];
|
|
41
|
+
}
|
|
42
|
+
export declare function parseCodexArgs(json: string, defaults?: CodexArgsDefaults): ParsedCodexArgs;
|
|
43
|
+
/**
|
|
44
|
+
* Build the codex CLI-arg model directly from the structured codex config
|
|
45
|
+
* block (`dispatchers[].runtime.config`), without round-tripping through JSON.
|
|
46
|
+
* Behavior-equivalent to encoding that block and calling {@link parseCodexArgs}:
|
|
47
|
+
* the same trusted-local invariants are enforced.
|
|
48
|
+
*/
|
|
49
|
+
export declare function codexArgsFromConfig(config: {
|
|
50
|
+
approval_policy: string;
|
|
51
|
+
sandbox_mode: string;
|
|
52
|
+
extra_args: string[];
|
|
53
|
+
}): ParsedCodexArgs;
|
|
54
|
+
export declare function codexArgsToCli(parsed: ParsedCodexArgs): string[];
|
|
55
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAeH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,iBAAsB,GAC/B,eAAe,CAkCjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,eAAe,CAMlB;AAmBD,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAahE"}
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse `dispatchers.codex_args_json` into the CLI-arg array passed to
|
|
3
|
+
* the codex app-server child, AND validate that the trusted-local
|
|
4
|
+
* invariants from issue #2 §"信任模型" hold.
|
|
5
|
+
*
|
|
6
|
+
* Canonical shape:
|
|
7
|
+
* {
|
|
8
|
+
* "approvalPolicy": "never", // from dispatchers[].runtime.config
|
|
9
|
+
* "sandboxMode": "workspace-write", // from dispatchers[].runtime.config
|
|
10
|
+
* "extraArgs": ["--model", "..."] // from runtime.config.extra_args
|
|
11
|
+
* }
|
|
12
|
+
*
|
|
13
|
+
* This JSON is encoded per dispatcher from
|
|
14
|
+
* `dispatchers[].runtime.config` (every field carries a dispatcher-local
|
|
15
|
+
* default), so it is the sole source of truth. The optional `defaults` param
|
|
16
|
+
* remains a thin seam; with the top-level `codex` block removed there is no
|
|
17
|
+
* global layer, and a caller normally passes nothing.
|
|
18
|
+
*
|
|
19
|
+
* Precedence for each field (highest wins):
|
|
20
|
+
* 1. dispatchers.codex_args_json (this JSON)
|
|
21
|
+
* 2. `defaults` (optional caller seam)
|
|
22
|
+
* 3. hardcoded fallbacks (`'never'`, `'workspace-write'`, `[]`)
|
|
23
|
+
*
|
|
24
|
+
* `approvalPolicy` not in the trusted-local allowlist fails-fast at startup
|
|
25
|
+
* (issue #2 §"实现陷阱"): dispatcher refuses to come up if the policy may
|
|
26
|
+
* request approval AND no approval handler is wired.
|
|
27
|
+
*
|
|
28
|
+
* `sandboxMode` is similarly validated against the codex 0.134 enum so a
|
|
29
|
+
* typo doesn't reach the daemon (where the only feedback is a fatal early
|
|
30
|
+
* exit).
|
|
31
|
+
*/
|
|
32
|
+
const TRUSTED_LOCAL_APPROVAL_POLICIES = new Set([
|
|
33
|
+
'never',
|
|
34
|
+
'auto',
|
|
35
|
+
'auto-approve',
|
|
36
|
+
'on-failure',
|
|
37
|
+
]);
|
|
38
|
+
const ALLOWED_SANDBOX_MODES = new Set([
|
|
39
|
+
'read-only',
|
|
40
|
+
'workspace-write',
|
|
41
|
+
'danger-full-access',
|
|
42
|
+
]);
|
|
43
|
+
export function parseCodexArgs(json, defaults = {}) {
|
|
44
|
+
let raw;
|
|
45
|
+
try {
|
|
46
|
+
raw = json.trim() === '' ? {} : JSON.parse(json);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new Error(`codex_args_json is not valid JSON: ${e.message}`);
|
|
50
|
+
}
|
|
51
|
+
if (typeof raw !== 'object' || raw === null) {
|
|
52
|
+
throw new Error('codex_args_json must be a JSON object');
|
|
53
|
+
}
|
|
54
|
+
const obj = raw;
|
|
55
|
+
const approvalPolicy = typeof obj['approvalPolicy'] === 'string'
|
|
56
|
+
? obj['approvalPolicy']
|
|
57
|
+
: (defaults.approvalPolicy ?? 'never');
|
|
58
|
+
const sandboxMode = typeof obj['sandboxMode'] === 'string'
|
|
59
|
+
? obj['sandboxMode']
|
|
60
|
+
: (defaults.sandboxMode ?? 'workspace-write');
|
|
61
|
+
const perDispatcherExtra = Array.isArray(obj['extraArgs'])
|
|
62
|
+
? obj['extraArgs'].map((x) => String(x))
|
|
63
|
+
: [];
|
|
64
|
+
// Any caller-provided default extraArgs go first; the dispatcher's own
|
|
65
|
+
// extraArgs are appended. codex's CLI is order-sensitive for `-c key=value`
|
|
66
|
+
// overrides — last write wins — so the dispatcher value overrides a same-key
|
|
67
|
+
// default.
|
|
68
|
+
const extraArgs = [
|
|
69
|
+
...(defaults.extraArgs ?? []),
|
|
70
|
+
...perDispatcherExtra,
|
|
71
|
+
];
|
|
72
|
+
return validateCodexArgs({ approvalPolicy, sandboxMode, extraArgs });
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the codex CLI-arg model directly from the structured codex config
|
|
76
|
+
* block (`dispatchers[].runtime.config`), without round-tripping through JSON.
|
|
77
|
+
* Behavior-equivalent to encoding that block and calling {@link parseCodexArgs}:
|
|
78
|
+
* the same trusted-local invariants are enforced.
|
|
79
|
+
*/
|
|
80
|
+
export function codexArgsFromConfig(config) {
|
|
81
|
+
return validateCodexArgs({
|
|
82
|
+
approvalPolicy: config.approval_policy,
|
|
83
|
+
sandboxMode: config.sandbox_mode,
|
|
84
|
+
extraArgs: [...config.extra_args],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function validateCodexArgs(parsed) {
|
|
88
|
+
if (!TRUSTED_LOCAL_APPROVAL_POLICIES.has(parsed.approvalPolicy)) {
|
|
89
|
+
throw new Error(`dispatcher startup refused: approvalPolicy='${parsed.approvalPolicy}' may request approval, ` +
|
|
90
|
+
`but the dreamux MVP only ships with a fail-fast approval handler ` +
|
|
91
|
+
`(issue #2 §"信任模型"). Configure approvalPolicy='never' or extend the trust model first.`);
|
|
92
|
+
}
|
|
93
|
+
if (!ALLOWED_SANDBOX_MODES.has(parsed.sandboxMode)) {
|
|
94
|
+
throw new Error(`dispatcher startup refused: sandboxMode='${parsed.sandboxMode}' is not one of ` +
|
|
95
|
+
`${Array.from(ALLOWED_SANDBOX_MODES).join(' | ')} (codex 0.134 enum).`);
|
|
96
|
+
}
|
|
97
|
+
return parsed;
|
|
98
|
+
}
|
|
99
|
+
export function codexArgsToCli(parsed) {
|
|
100
|
+
// codex >= 0.134 dropped --approval-policy and --sandbox at the
|
|
101
|
+
// app-server level; the remaining mechanism is `-c key=value` config
|
|
102
|
+
// overrides for both. Pass approval_policy first, then sandbox_mode,
|
|
103
|
+
// then the dispatcher's extra args — letting extra_args contain a same-key
|
|
104
|
+
// `-c` override that wins (codex parses last write wins).
|
|
105
|
+
return [
|
|
106
|
+
'-c',
|
|
107
|
+
`approval_policy=${parsed.approvalPolicy}`,
|
|
108
|
+
'-c',
|
|
109
|
+
`sandbox_mode=${parsed.sandboxMode}`,
|
|
110
|
+
...parsed.extraArgs,
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DreamuxEnvironment } from '@excitedjs/dreamux-types';
|
|
2
|
+
/**
|
|
3
|
+
* Final codex binary path for one runtime. The `CODEX_HOST_CODEX_BIN`
|
|
4
|
+
* environment variable is a deliberate host-level override that takes precedence
|
|
5
|
+
* over the configured `runtime.config.bin`; otherwise the configured bin
|
|
6
|
+
* (default `"codex"`) is used. `env` defaults to the live process environment
|
|
7
|
+
* for the runtime spawn path; doctor passes the installed service unit's
|
|
8
|
+
* environment so it checks what the service will run.
|
|
9
|
+
*
|
|
10
|
+
* Lives in its own module so both the provider (spawn path) and the diagnostic
|
|
11
|
+
* (doctor path) import it without forming an import cycle.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveCodexBinPath(configBin: string, env?: DreamuxEnvironment): string;
|
|
14
|
+
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,kBAAgC,GACpC,MAAM,CAIR"}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Final codex binary path for one runtime. The `CODEX_HOST_CODEX_BIN`
|
|
3
|
+
* environment variable is a deliberate host-level override that takes precedence
|
|
4
|
+
* over the configured `runtime.config.bin`; otherwise the configured bin
|
|
5
|
+
* (default `"codex"`) is used. `env` defaults to the live process environment
|
|
6
|
+
* for the runtime spawn path; doctor passes the installed service unit's
|
|
7
|
+
* environment so it checks what the service will run.
|
|
8
|
+
*
|
|
9
|
+
* Lives in its own module so both the provider (spawn path) and the diagnostic
|
|
10
|
+
* (doctor path) import it without forming an import cycle.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveCodexBinPath(configBin, env = process.env) {
|
|
13
|
+
const fromEnv = env['CODEX_HOST_CODEX_BIN'];
|
|
14
|
+
if (fromEnv !== undefined && fromEnv.trim() !== '')
|
|
15
|
+
return fromEnv;
|
|
16
|
+
return configBin;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,MAA0B,OAAO,CAAC,GAAG;IAErC,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC5C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,OAAO,CAAC;IACnE,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { DreamuxEnvironment } from '@excitedjs/dreamux-types';
|
|
2
|
+
export declare const DISPATCHER_APP_SERVER_SOCKET_PATH_MAX_BYTES = 103;
|
|
3
|
+
export interface DispatcherCodexHomeDoctorContext {
|
|
4
|
+
dispatcherId: string;
|
|
5
|
+
codexHome: string;
|
|
6
|
+
configPath: string;
|
|
7
|
+
/**
|
|
8
|
+
* The runtime working directory. Optional/empty by default: the validation
|
|
9
|
+
* never reads it, so a caller that does not have it (e.g. doctor) omits it.
|
|
10
|
+
*/
|
|
11
|
+
dispatcherCwd: string;
|
|
12
|
+
/**
|
|
13
|
+
* A representative socket allocation (issue #182: sockets are random per
|
|
14
|
+
* start, so this is a sample of the policy, not the path a runtime will
|
|
15
|
+
* bind). Doctor checks placement (never shared /tmp) and the path budget. An
|
|
16
|
+
* empty string skips the socket checks (no host candidate dirs were supplied).
|
|
17
|
+
*/
|
|
18
|
+
socketPath: string;
|
|
19
|
+
codexCliArgs: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface DispatcherCodexHomeDoctorResult {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
errors: string[];
|
|
24
|
+
context: DispatcherCodexHomeDoctorContext;
|
|
25
|
+
}
|
|
26
|
+
export type DispatcherCodexHomeDoctor = (context: DispatcherCodexHomeDoctorContext) => void | Promise<void>;
|
|
27
|
+
interface DoctorContextOptions {
|
|
28
|
+
codexCliArgs?: string[];
|
|
29
|
+
dispatcherCwd?: string;
|
|
30
|
+
/** Representative socket sample (from the path context's `runtimeSocketDirs()`). */
|
|
31
|
+
socketPath?: string;
|
|
32
|
+
}
|
|
33
|
+
interface DoctorOptions {
|
|
34
|
+
env?: DreamuxEnvironment;
|
|
35
|
+
codexCliArgs?: string[];
|
|
36
|
+
}
|
|
37
|
+
export declare function dispatcherCodexHomeDoctorContext(dispatcherId: string, options?: DoctorContextOptions): DispatcherCodexHomeDoctorContext;
|
|
38
|
+
export declare function validateDispatcherCodexHome(input: string | DispatcherCodexHomeDoctorContext, options?: DoctorOptions): Promise<DispatcherCodexHomeDoctorResult>;
|
|
39
|
+
export declare function assertDispatcherCodexHomeReady(context: DispatcherCodexHomeDoctorContext): Promise<void>;
|
|
40
|
+
export declare function formatDispatcherCodexHomeErrors(result: DispatcherCodexHomeDoctorResult): string;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=codex-home.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-home.d.ts","sourceRoot":"","sources":["../src/codex-home.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,eAAO,MAAM,2CAA2C,MACpB,CAAC;AAErC,MAAM,WAAW,gCAAgC;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,gCAAgC,CAAC;CAC3C;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,gCAAgC,KACtC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,oBAAyB,GACjC,gCAAgC,CASlC;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,MAAM,GAAG,gCAAgC,EAChD,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,+BAA+B,CAAC,CAyD1C;AAED,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,+BAA+B,GACtC,MAAM,CAGR"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex home/auth pre-start validation (issue #209 cleanup — relocated from
|
|
3
|
+
* Dreamux core into the owning package).
|
|
4
|
+
*
|
|
5
|
+
* This is the codex-engine readiness check: it validates that Codex's own global
|
|
6
|
+
* home (`~/.codex`) exists, parses its `config.toml`, carries usable auth, and
|
|
7
|
+
* that the representative app-server socket placement is sane. It is
|
|
8
|
+
* codex-specific and carries NO `~/.dreamux` knowledge — the host's socket
|
|
9
|
+
* placement arrives as a neutral sample (`socketPath`) computed from the path
|
|
10
|
+
* context's `runtimeSocketDirs()`, and `dispatcherCwd` is optional (the
|
|
11
|
+
* validation never reads it).
|
|
12
|
+
*/
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import { join, normalize, sep } from 'node:path';
|
|
15
|
+
import { parse as parseToml, TomlError } from 'smol-toml';
|
|
16
|
+
import { DREAMUX_UNIX_SOCKET_PATH_MAX_BYTES, pathExists, unixSocketPathFitsBudget, } from '@excitedjs/dreamux-utils';
|
|
17
|
+
import { dispatcherCodexConfigPath, dispatcherCodexHome } from './paths.js';
|
|
18
|
+
export const DISPATCHER_APP_SERVER_SOCKET_PATH_MAX_BYTES = DREAMUX_UNIX_SOCKET_PATH_MAX_BYTES;
|
|
19
|
+
export function dispatcherCodexHomeDoctorContext(dispatcherId, options = {}) {
|
|
20
|
+
return {
|
|
21
|
+
dispatcherId,
|
|
22
|
+
codexHome: dispatcherCodexHome(dispatcherId),
|
|
23
|
+
configPath: dispatcherCodexConfigPath(dispatcherId),
|
|
24
|
+
dispatcherCwd: options.dispatcherCwd ?? '',
|
|
25
|
+
socketPath: options.socketPath ?? '',
|
|
26
|
+
codexCliArgs: options.codexCliArgs ?? [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function validateDispatcherCodexHome(input, options = {}) {
|
|
30
|
+
const context = typeof input === 'string'
|
|
31
|
+
? dispatcherCodexHomeDoctorContext(input, {
|
|
32
|
+
codexCliArgs: options.codexCliArgs,
|
|
33
|
+
})
|
|
34
|
+
: {
|
|
35
|
+
...input,
|
|
36
|
+
codexCliArgs: options.codexCliArgs ?? input.codexCliArgs,
|
|
37
|
+
};
|
|
38
|
+
const errors = [];
|
|
39
|
+
const env = options.env ?? process.env;
|
|
40
|
+
if (await pathExists(context.configPath)) {
|
|
41
|
+
try {
|
|
42
|
+
const parsed = parseToml(await readFile(context.configPath, 'utf8'));
|
|
43
|
+
if (!isRecord(parsed)) {
|
|
44
|
+
errors.push(`Codex config must be a TOML table: ${context.configPath}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
errors.push(formatTomlError(err, context.configPath));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!(await pathExists(context.codexHome))) {
|
|
52
|
+
errors.push(`missing Codex home directory: ${context.codexHome}`);
|
|
53
|
+
}
|
|
54
|
+
// An empty socketPath means no host candidate dirs were supplied — skip the
|
|
55
|
+
// placement/budget checks (a real allocation still fails loud at start time).
|
|
56
|
+
if (context.socketPath !== '') {
|
|
57
|
+
if (isTmpPath(context.socketPath)) {
|
|
58
|
+
errors.push(`dispatcher app-server socket must not be under /tmp: ${context.socketPath}`);
|
|
59
|
+
}
|
|
60
|
+
if (!unixSocketPathFitsBudget(context.socketPath)) {
|
|
61
|
+
const bytes = Buffer.byteLength(context.socketPath, 'utf8');
|
|
62
|
+
errors.push(`dispatcher app-server socket path is too long for Unix sockets (${bytes} bytes > ${DISPATCHER_APP_SERVER_SOCKET_PATH_MAX_BYTES} safe bytes): ${context.socketPath}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// The bundled dispatcher skill is no longer symlinked into the workspace
|
|
66
|
+
// (issue #209 slice 6); core injects it at runtime by role via
|
|
67
|
+
// `skills/extraRoots/set`, so the doctor no longer checks for an on-disk skill.
|
|
68
|
+
if (!(await hasAuth(context.codexHome, env))) {
|
|
69
|
+
errors.push(`missing Codex auth state in ${context.codexHome} or a supported auth environment variable`);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
ok: errors.length === 0,
|
|
73
|
+
errors,
|
|
74
|
+
context,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export async function assertDispatcherCodexHomeReady(context) {
|
|
78
|
+
const result = await validateDispatcherCodexHome(context);
|
|
79
|
+
if (result.ok)
|
|
80
|
+
return;
|
|
81
|
+
throw new Error(formatDispatcherCodexHomeErrors(result));
|
|
82
|
+
}
|
|
83
|
+
export function formatDispatcherCodexHomeErrors(result) {
|
|
84
|
+
const header = `dispatcher '${result.context.dispatcherId}' Codex home is not ready`;
|
|
85
|
+
return [header, ...result.errors.map((e) => `- ${e}`)].join('\n');
|
|
86
|
+
}
|
|
87
|
+
function formatTomlError(err, file) {
|
|
88
|
+
if (err instanceof TomlError) {
|
|
89
|
+
const where = typeof err.line === 'number' && typeof err.column === 'number'
|
|
90
|
+
? `${file}:${err.line}:${err.column}`
|
|
91
|
+
: file;
|
|
92
|
+
return `Codex config parse error at ${where}: ${err.message}`;
|
|
93
|
+
}
|
|
94
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
95
|
+
return `Codex config parse error in ${file}: ${msg}`;
|
|
96
|
+
}
|
|
97
|
+
async function hasAuth(codexHome, env) {
|
|
98
|
+
if (await pathExists(join(codexHome, 'auth.json')))
|
|
99
|
+
return true;
|
|
100
|
+
return ['OPENAI_API_KEY', 'CODEX_API_KEY', 'CODEX_ACCESS_TOKEN'].some((name) => {
|
|
101
|
+
const value = env[name];
|
|
102
|
+
return value !== undefined && value.trim() !== '';
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function isTmpPath(path) {
|
|
106
|
+
const normalized = normalize(path);
|
|
107
|
+
return normalized === '/tmp' || normalized.startsWith(`/tmp${sep}`);
|
|
108
|
+
}
|
|
109
|
+
function isRecord(value) {
|
|
110
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=codex-home.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-home.js","sourceRoot":"","sources":["../src/codex-home.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builtin `builtin:codex` runtime config: schema type, defaults, reader, and
|
|
3
|
+
* the typed accessor.
|
|
4
|
+
*
|
|
5
|
+
* Codex runtime config is owned by this package (the `builtin:codex` provider),
|
|
6
|
+
* not by the Dreamux host config module. It depends only on the shared neutral
|
|
7
|
+
* validation primitives (`@excitedjs/dreamux-utils`) and the package-local
|
|
8
|
+
* provider ref, never on `@excitedjs/dreamux` core. The Dreamux host config
|
|
9
|
+
* module re-exports these so
|
|
10
|
+
* the non-builtin callers (doctor, daemon, tests) keep their import paths.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Builtin Codex runtime settings under a named `agents[].config` entry (provider
|
|
14
|
+
* `builtin:codex`), referenced by a dispatcher via `dispatchers[].agentRuntime`.
|
|
15
|
+
* Every field carries a built-in default, so an agent that omits any config
|
|
16
|
+
* field runs with these constants. There is no top-level `codex` block anymore;
|
|
17
|
+
* runtime config lives in `agents[]`.
|
|
18
|
+
*
|
|
19
|
+
* `bin` is the dispatcher's Codex binary path; the `CODEX_HOST_CODEX_BIN`
|
|
20
|
+
* environment variable is a host-level override that takes precedence over it
|
|
21
|
+
* (resolved by the codex builtin's `resolveCodexBinPath`).
|
|
22
|
+
* `initialize_timeout_ms` is that
|
|
23
|
+
* dispatcher's handshake timeout. `turn_timeout_ms` bounds a single TeamMate
|
|
24
|
+
* worker turn (issue #126): if a per-task Codex app-server reaches `running`
|
|
25
|
+
* but its turn never emits `turn/completed` (a stall in turn execution —
|
|
26
|
+
* commonly auth, network, or model quota), the worker fails that task instead
|
|
27
|
+
* of leaving it `running` forever. It does not affect the dispatcher's own
|
|
28
|
+
* long-lived runtime, only per-task workers.
|
|
29
|
+
*/
|
|
30
|
+
export interface DispatcherCodexConfig {
|
|
31
|
+
bin: string;
|
|
32
|
+
approval_policy: string;
|
|
33
|
+
sandbox_mode: string;
|
|
34
|
+
extra_args: string[];
|
|
35
|
+
extra_env: Record<string, string>;
|
|
36
|
+
initialize_timeout_ms: number;
|
|
37
|
+
turn_timeout_ms: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Default `dispatchers[].runtime.config.bin`. The Codex binary path is
|
|
41
|
+
* dispatcher-local; `CODEX_HOST_CODEX_BIN` is a host-level override above it,
|
|
42
|
+
* not the source.
|
|
43
|
+
*/
|
|
44
|
+
export declare const DEFAULT_CODEX_BIN = "codex";
|
|
45
|
+
/** Default `dispatchers[].runtime.config.initialize_timeout_ms` (handshake timeout, ms). */
|
|
46
|
+
export declare const DEFAULT_INITIALIZE_TIMEOUT_MS = 10000;
|
|
47
|
+
/**
|
|
48
|
+
* Default per-turn deadline for a `builtin:codex` TeamMate worker (ms).
|
|
49
|
+
* Generous enough not to interrupt a legitimately long tool-using turn, but
|
|
50
|
+
* finite so a worker whose turn stalls after start cannot sit `running` with no
|
|
51
|
+
* visible outcome (issue #126). Operators override via
|
|
52
|
+
* `dispatchers[].runtime.config.turn_timeout_ms`.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEFAULT_CODEX_TURN_TIMEOUT_MS = 600000;
|
|
55
|
+
/** Default `dispatchers[].runtime.config.approval_policy` when omitted. */
|
|
56
|
+
export declare const DEFAULT_APPROVAL_POLICY = "never";
|
|
57
|
+
/** Default `dispatchers[].runtime.config.sandbox_mode` when omitted. */
|
|
58
|
+
export declare const DEFAULT_SANDBOX_MODE = "workspace-write";
|
|
59
|
+
export declare const ALLOWED_APPROVAL_POLICIES: Set<string>;
|
|
60
|
+
export declare const ALLOWED_SANDBOX_MODES: Set<string>;
|
|
61
|
+
export declare function defaultDispatcherCodexConfig(): DispatcherCodexConfig;
|
|
62
|
+
export declare function readDispatcherCodexConfig(rawCodex: Record<string, unknown>, file: string, prefix: string): DispatcherCodexConfig;
|
|
63
|
+
/**
|
|
64
|
+
* Typed accessor for a dispatcher's resolved codex runtime config. Typed
|
|
65
|
+
* structurally (not against `DispatcherConfig`) so this module never imports
|
|
66
|
+
* the host config type — a full `DispatcherConfig` still satisfies it at the
|
|
67
|
+
* call sites.
|
|
68
|
+
*/
|
|
69
|
+
export declare function dispatcherCodexConfig(dispatcher: {
|
|
70
|
+
id: string;
|
|
71
|
+
runtime: {
|
|
72
|
+
provider: string;
|
|
73
|
+
config: unknown;
|
|
74
|
+
};
|
|
75
|
+
}): DispatcherCodexConfig;
|
|
76
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,4FAA4F;AAC5F,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AAErD,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAE/C,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD,eAAO,MAAM,yBAAyB,aAKpC,CAAC;AAEH,eAAO,MAAM,qBAAqB,aAIhC,CAAC;AAEH,wBAAgB,4BAA4B,IAAI,qBAAqB,CAUpE;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,qBAAqB,CA0EvB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;CAChD,GAAG,qBAAqB,CAOxB"}
|