@messenger-agent/codex-agent 0.28.0 → 0.29.0-alpha.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/dynamic-tools.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import l from"node:path";import{mkdir as f,writeFile as y}from"node:fs/promises";import{generateImage as T}from"ai";import{createOpenAI as w}from"@ai-sdk/openai";import{Agent as I,fetch as x}from"undici";import{z as r}from"zod";import{executeManagedTaskTool as S,isManagedTaskToolName as b,MANAGED_TASK_TOOL_DEFINITIONS as A}from"@messenger-agent/shared/managed-task-tools";import{AgentFileError as k,resolveAgentFilePath as v}from"@messenger-agent/shared/agent-files";import{executeScheduleTool as E,SCHEDULE_TOOL_DEFINITION as c,ScheduleToolError as _}from"@messenger-agent/shared/schedule-tools";const
|
|
1
|
+
import l from"node:path";import{mkdir as f,writeFile as y}from"node:fs/promises";import{generateImage as T}from"ai";import{createOpenAI as w}from"@ai-sdk/openai";import{Agent as I,fetch as x}from"undici";import{z as r}from"zod";import{executeManagedTaskTool as S,isManagedTaskToolName as b,MANAGED_TASK_TOOL_DEFINITIONS as A}from"@messenger-agent/shared/managed-task-tools";import{AgentFileError as k,resolveAgentFilePath as v}from"@messenger-agent/shared/agent-files";import{executeScheduleTool as E,SCHEDULE_TOOL_DEFINITION as c,ScheduleToolError as _}from"@messenger-agent/shared/schedule-tools";const d=1200*1e3,M=new I({headersTimeout:d,bodyTimeout:d}),R=(t,e)=>x(t,{...e,dispatcher:M}),p=r.object({prompt:r.string().describe("The text prompt describing the image to generate"),store_path:r.string().describe("Absolute file path (including filename) to save the image. If omitted, saves to the current working directory with an auto-generated name.").optional(),size:r.enum(["1024x1024","1536x1024","1024x1536"]).describe("Image size. Leave it undefined to use the auto size.").optional()}),m=r.object({path:r.string().describe("File to send. Absolute paths use the system path; relative paths resolve from the active workspace.")}),N=r.toJSONSchema(p),O=r.toJSONSchema(m);function g(t){return{contentItems:[{type:"inputText",text:JSON.stringify(t)}],success:!0}}const a=new Map;function F(t,e){const o=e.threadRef?.trim();a.set(t,{workspaceRoot:e.workspaceRoot,...o?{threadRef:o}:null,...e.matrixEvent?{matrixEvent:e.matrixEvent}:null,...e.llmProxyBinding?{llmProxyBinding:e.llmProxyBinding}:null})}function u(t,e){const o=a.get(t);if(o)for(const n of e)n&&n!==t&&F(n,o)}function $(t,e){if(t!=="item/started"&&t!=="item/completed"||!e||typeof e!="object")return;const o=e,n=o.item;if(!n||typeof n!="object")return;const i=n;if(i.type==="subAgentActivity"&&i.kind==="started"&&typeof o.threadId=="string"&&typeof i.agentThreadId=="string"){u(o.threadId,[i.agentThreadId]);return}i.type==="collabAgentToolCall"&&i.tool==="spawnAgent"&&typeof i.senderThreadId=="string"&&Array.isArray(i.receiverThreadIds)&&u(i.senderThreadId,i.receiverThreadIds.filter(s=>typeof s=="string"))}async function h(t){const e=a.get(t);if(e)return e.workspaceRoot;const{sessionManager:o}=await import("./codex.js"),n=o.workdirFor(t);if(!n)throw new Error(`No workspace context for thread ${t}; the session may not exist in this process`);return n}async function L(t){const{appConfig:e}=await import("./config.js");if(!e.openai.apiKey)throw new Error("Missing openai.api_key in LLM config");return{apiKey:e.openai.apiKey,baseURL:e.openai.baseUrl,imageModel:e.openai.imageModel,llmProxyBinding:a.get(t)?.llmProxyBinding}}async function C(){const{appConfig:t}=await import("./config.js");return t.schedule}function H(t=!1){const e=[{name:"generate_image",description:"Generate an image from a text prompt. The image is saved to the specified path (absolute path including filename) or the current working directory if not specified. Returns the saved file path.",inputSchema:N},{name:"send_file",description:"Send any readable file to the client. Absolute paths use the system path; relative paths resolve from the active workspace. The agent runtime captures this tool call and performs the actual send.",inputSchema:O},...A.map(o=>({name:o.name,description:o.description,inputSchema:o.inputSchema}))];return t&&e.push({name:c.name,description:c.description,inputSchema:c.inputSchema}),e}async function V(t){try{if(t.tool==="generate_image"){const e=p.parse(t.arguments),o=await L(t.threadId),n=w({apiKey:o.apiKey,baseURL:o.baseURL,fetch:R,...o.llmProxyBinding?{headers:{"X-Elevo-LLM-Binding":o.llmProxyBinding}}:null}),{image:i}=await T({model:n.image(o.imageModel),prompt:e.prompt,size:e.size,maxRetries:0,abortSignal:AbortSignal.timeout(d)}),s=e.store_path?l.resolve(e.store_path):l.join(process.cwd(),`generated_${Date.now()}.png`);return await f(l.dirname(s),{recursive:!0}),await y(s,Buffer.from(i.uint8Array)),{contentItems:[{type:"inputText",text:s}],success:!0}}if(t.tool==="send_file"){const e=m.parse(t.arguments),o=await v(e.path,await h(t.threadId));return{contentItems:[{type:"inputText",text:JSON.stringify({path:o})}],success:!0}}if(b(t.tool)){const e=await S(await h(t.threadId),t.tool,t.arguments,a.get(t.threadId));return g(e)}if(t.tool===c.name)return g(await E(await C(),a.get(t.threadId),t.arguments,fetch,t.callId));throw new Error(`Unknown dynamic tool: ${t.tool}`)}catch(e){const o=e instanceof k&&e.code==="INVALID_PATH"||e instanceof Error?e.message:String(e),n=e instanceof _?{error:{code:e.code,message:e.message,retryable:e.retryable,currentRevision:e.currentRevision}}:o;return{contentItems:[{type:"inputText",text:typeof n=="string"?n:JSON.stringify(n)}],success:!1}}}export{H as dynamicToolSpecs,V as handleDynamicToolCall,u as inheritManagedTaskToolContext,$ as inheritManagedTaskToolContextFromNotification,F as setManagedTaskToolContext};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync as c,readFileSync as
|
|
2
|
-
${
|
|
1
|
+
import{existsSync as c,readFileSync as i}from"node:fs";import{fileURLToPath as a}from"node:url";import{logger as d}from"@messenger-agent/shared/logger";const l=[a(new URL("./assets/codex-home/AGENTS.md",import.meta.url)),a(new URL("../../../assets/codex-home/AGENTS.md",import.meta.url)),"/app/assets/codex-home/AGENTS.md"],n="## Codex Managed Task Tools\n\nWhen using managed task tools in Codex, call these tool names directly: `search_managed_tasks`, `get_managed_task`, `create_managed_task`, `update_managed_task`, `apply_managed_task_patch`, and `delete_managed_task`.\n",m="## Schedule Tool\n\nUse the single `schedule` tool to prepare create/update proposals or list, inspect, pause, resume, and cancel schedules in the current trusted Matrix context. The action is selected inside `input.action`; never ask for or invent a Room ID, actor ID, source event, or service credential. A successful create/update result is a proposal awaiting one explicit Messenger confirmation, not an active schedule. Summarize it, but do not ask for a chat reply or invoke another confirmation tool.\n";function h(s,r=!1){const e=r?`
|
|
2
|
+
${m}`:"",t=[s??process.env.CODEX_AGENTS_TEMPLATE_PATH,...l].find(o=>!!(o&&c(o)));return t?`${i(t,"utf-8").trimEnd()}
|
|
3
3
|
|
|
4
|
-
${
|
|
4
|
+
${n}${e}`:(d.warn("Codex platform instructions template not found"),`${n}${e}`)}export{h as loadCodexPlatformInstructions};
|
package/dist/tunnel-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as p}from"node:module";import h from"ws";import{ChatBodySchema as y}from"./schemas.js";import{appConfig as C}from"./config.js";import{cancelCodexConversation as
|
|
1
|
+
import{createRequire as p}from"node:module";import h from"ws";import{ChatBodySchema as y}from"./schemas.js";import{appConfig as C}from"./config.js";import{cancelCodexConversation as m,ChatRequestError as b,handleCodexChatStream as g}from"./routes/chat.js";import{logger as l}from"@messenger-agent/shared/logger";import{reconnectDelayWithJitter as w}from"@messenger-agent/shared/reconnect-backoff";import{sendHttpTunnelResponse as f}from"@messenger-agent/shared/tunnel-http";import{CODING_AGENT_TUNNEL_DUPLICATE_CLOSE_CODE as v,CODING_AGENT_TUNNEL_PROTOCOL_VERSION as T}from"@messenger-agent/shared/tunnel-protocol";const _=p(import.meta.url)("../package.json").version;function k(r){return new Promise(e=>setTimeout(e,r))}function I(r){try{const e=JSON.parse(r.toString());return!e||typeof e!="object"||!("type"in e)?void 0:e}catch{return}}function O(r){const e=new Headers;for(const[t,d]of Object.entries(r??{}))e.set(t,d);return e}function q(r){if(r.method==="POST")try{const e=new URL(r.path,"http://coding-agent-tunnel.local").pathname,t=/^\/v1\/chat\/([^/]+)\/cancel$/.exec(e);return t?decodeURIComponent(t[1]):void 0}catch{return}}class x{config;stopped=!1;socket;running=new Map;constructor(e){this.config=e}async start(){if(!this.config.enabled)return;if(!this.config.serverUrl||!this.config.tunnelId||!this.config.token)throw new Error("Tunnel config requires server_url, tunnel_id, and token when enabled");let e=this.config.reconnectInitialMs;for(;!this.stopped;){try{await this.connectOnce(),e=this.config.reconnectInitialMs}catch(t){if(this.stopped)break;l.warn("[TunnelClient] websocket tunnel connection failed:",t)}this.stopped||(await k(w(e)),e=Math.min(e*2,this.config.reconnectMaxMs))}}stop(){this.stopped=!0;for(const e of this.running.values())e.abortController.abort();this.running.clear(),this.socket?.close()}connectOnce(){return new Promise((e,t)=>{const d={Authorization:`Bearer ${this.config.token}`},i=new h(this.config.serverUrl,{headers:d});this.socket=i;let n,a=!1;const s=()=>{n&&clearInterval(n),this.socket===i&&(this.socket=void 0);for(const c of this.running.values())c.abortController.abort(new Error("Tunnel connection closed"));this.running.clear()};i.on("open",()=>{this.send({type:"hello",protocolVersion:T,tunnelId:this.config.tunnelId,agentType:"codex",clientVersion:_}),n=setInterval(()=>{this.send({type:"heartbeat"})},this.config.heartbeatIntervalMs),l.info(`[TunnelClient] connected to ${this.config.serverUrl} as ${this.config.tunnelId}`)}),i.on("message",c=>{const o=I(c);if(!o){l.warn("[TunnelClient] received invalid websocket message");return}if(o.type!=="heartbeat"){if(o.type==="cancel"){this.running.get(o.id)?.abortController.abort();return}o.type==="request"&&this.handleRequest(o).catch(u=>{l.error(`[TunnelClient] request ${o.id} failed:`,u)})}}),i.once("error",c=>{a||(a=!0,s(),t(c))}),i.once("close",(c,o)=>{s(),c===v&&(this.stopped=!0,l.warn(`[TunnelClient] duplicate websocket tunnel connection rejected; reconnect disabled: ${o.toString()}`)),a||(a=!0,e())})})}send(e){const t=this.socket;!t||t.readyState!==h.OPEN||t.send(JSON.stringify(e))}async handleRequest(e){const t=q(e);if(t){let n;try{n=await m(t)}catch(s){const c=s instanceof Error?s.message:"Failed to interrupt Codex conversation",o=Response.json({error:{type:"server_error",code:"cancel_failed",message:c}},{status:500});await f(e.id,o,u=>this.send(u));return}const a=Response.json(n?{success:!0}:{error:{type:"not_found_error",code:"conversation_not_found",message:`Conversation not found or already completed: ${t}`,param:"conversation_id"}},{status:n?200:404});await f(e.id,a,s=>this.send(s));return}if(e.method!=="POST"||e.path!=="/v1/chat/stream"){this.send({type:"response.error",id:e.id,code:"unsupported_request",errorText:`Unsupported tunnel request: ${e.method} ${e.path}`});return}const d=y.safeParse(e.body);if(!d.success){this.send({type:"response.error",id:e.id,code:"invalid_request",errorText:`Invalid chat request body: ${d.error.message}`});return}const i=new AbortController;this.running.set(e.id,{abortController:i}),this.send({type:"response.start",id:e.id,mode:"sse"});try{await g({body:d.data,headers:O(e.headers),signal:i.signal},{writeData:async n=>this.send({type:"response.chunk",id:e.id,data:n}),writeDone:async()=>this.send({type:"response.end",id:e.id})})}catch(n){const a=n instanceof Error?n.message:"Tunnel request failed",s=n instanceof b?`http_${n.status}`:"request_failed";this.send({type:"response.error",id:e.id,code:s,errorText:a})}finally{this.running.delete(e.id)}}}function j(r=C.tunnel){if(!r.enabled)return;const e=new x(r);return e.start().catch(t=>{l.error("[TunnelClient] stopped unexpectedly:",t)}),e}export{x as CodexTunnelClient,j as startCodexTunnelClient};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@messenger-agent/codex-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"ws": "^8.21.0",
|
|
23
23
|
"yaml": "^2.9.0",
|
|
24
24
|
"zod": "^4.4.3",
|
|
25
|
-
"@messenger-agent/shared": "0.
|
|
25
|
+
"@messenger-agent/shared": "0.29.0-alpha.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/ws": "^8.18.1"
|