replicas-engine 0.1.630 → 0.1.632

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.
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AGENT,
4
+ AppServerProcess,
5
+ headlessAgentRequestSchema
6
+ } from "./chunk-2WNJA3MT.js";
7
+
8
+ // src/headless-agent.ts
9
+ import { readFile, writeFile } from "fs/promises";
10
+ import { query } from "@anthropic-ai/claude-agent-sdk";
11
+ var TURN_TIMEOUT_MS = 3e5;
12
+ async function runClaude(request) {
13
+ const response = query({
14
+ prompt: request.prompt,
15
+ options: {
16
+ cwd: request.workingDirectory,
17
+ model: request.model,
18
+ tools: [],
19
+ permissionMode: "dontAsk",
20
+ settingSources: [],
21
+ persistSession: false,
22
+ outputFormat: { type: "json_schema", schema: request.outputSchema },
23
+ env: { ...process.env, CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1" }
24
+ }
25
+ });
26
+ let result = null;
27
+ try {
28
+ for await (const message of response) {
29
+ if (message.type === "result") result = message;
30
+ }
31
+ } finally {
32
+ response.close();
33
+ }
34
+ if (!result) throw new Error("Claude Agent SDK returned no result");
35
+ if (result.subtype !== "success") throw new Error(result.errors.join("\n") || result.subtype);
36
+ return result.structured_output ?? JSON.parse(result.result);
37
+ }
38
+ function runCodexTurn(client, params) {
39
+ return new Promise((resolve, reject) => {
40
+ const cleanup = () => {
41
+ clearTimeout(timeout);
42
+ client.off("notification", onNotification);
43
+ client.off("dispose", onDispose);
44
+ };
45
+ const onNotification = (notification) => {
46
+ if (notification.method !== "turn/completed" || notification.params.threadId !== params.threadId) return;
47
+ cleanup();
48
+ resolve(notification.params.turn);
49
+ };
50
+ const onDispose = (error) => {
51
+ cleanup();
52
+ reject(error);
53
+ };
54
+ const timeout = setTimeout(() => {
55
+ cleanup();
56
+ reject(new Error("Codex ASP turn timed out"));
57
+ }, TURN_TIMEOUT_MS);
58
+ client.on("notification", onNotification);
59
+ client.on("dispose", onDispose);
60
+ void client.request("turn/start", params).catch((error) => {
61
+ cleanup();
62
+ reject(error);
63
+ });
64
+ });
65
+ }
66
+ async function runCodex(request) {
67
+ const appServer = new AppServerProcess({
68
+ cwd: request.workingDirectory,
69
+ configOverrides: ["shell_environment_policy.inherit=none", "tools.web_search=false"]
70
+ });
71
+ try {
72
+ const { client } = await appServer.start();
73
+ client.on("serverRequest", (serverRequest) => {
74
+ client.reject(serverRequest.id, -32601, "Headless agents do not accept server requests");
75
+ });
76
+ const thread = await client.request("thread/start", {
77
+ model: request.model,
78
+ cwd: request.workingDirectory,
79
+ approvalPolicy: "never",
80
+ approvalsReviewer: "user",
81
+ sandbox: "read-only",
82
+ ephemeral: true,
83
+ environments: [],
84
+ dynamicTools: [],
85
+ selectedCapabilityRoots: []
86
+ });
87
+ const turn = await runCodexTurn(client, {
88
+ threadId: thread.thread.id,
89
+ input: [{ type: "text", text: request.prompt, text_elements: [] }],
90
+ outputSchema: request.outputSchema,
91
+ approvalPolicy: "never",
92
+ approvalsReviewer: "user",
93
+ environments: []
94
+ });
95
+ if (turn.status === "failed") throw new Error(turn.error?.message ?? "Codex ASP turn failed");
96
+ const message = turn.items.findLast((item) => item.type === "agentMessage");
97
+ if (!message || message.type !== "agentMessage") throw new Error("Codex ASP returned no final message");
98
+ return JSON.parse(message.text);
99
+ } finally {
100
+ await appServer.stop();
101
+ }
102
+ }
103
+ async function main() {
104
+ const [requestPath, outputPath] = process.argv.slice(2);
105
+ if (!requestPath || !outputPath) throw new Error("Usage: replicas-headless-agent <request.json> <output.json>");
106
+ const request = headlessAgentRequestSchema.parse(JSON.parse(await readFile(requestPath, "utf8")));
107
+ let result;
108
+ switch (request.agent) {
109
+ case AGENT.CLAUDE:
110
+ result = await runClaude(request);
111
+ break;
112
+ case AGENT.CODEX:
113
+ result = await runCodex(request);
114
+ break;
115
+ default:
116
+ throw new Error(`Unsupported headless agent: ${request.agent}`);
117
+ }
118
+ await writeFile(outputPath, JSON.stringify(result), { mode: 384 });
119
+ }
120
+ main().catch((error) => {
121
+ process.exitCode = 1;
122
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}
123
+ `);
124
+ });