@meetopenbot/codex 1.1.0 → 1.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +65 -13
  2. package/package.json +10 -11
package/dist/index.js CHANGED
@@ -3,8 +3,15 @@ import {
3
3
  definePlugin,
4
4
  shouldHandleInvoke,
5
5
  agentOutput,
6
- uiWidget
6
+ uiWidget,
7
+ toolTraceWidget,
8
+ buildDiffWidget,
9
+ diffFileFromWrite,
10
+ resolveRunDiffFiles,
11
+ snapshotWorkspace
7
12
  } from "@meetopenbot/plugin-sdk";
13
+ import { readFileSync } from "node:fs";
14
+ import { join } from "node:path";
8
15
  import {
9
16
  Codex
10
17
  } from "@openai/codex-sdk";
@@ -81,18 +88,41 @@ var parseModel = (value) => {
81
88
  var itemWidget = (item) => {
82
89
  switch (item.type) {
83
90
  case "command_execution":
84
- return { title: "Command", body: item.command };
91
+ return {
92
+ title: "Command",
93
+ body: [item.command, item.aggregated_output].filter(Boolean).join("\n\n")
94
+ };
85
95
  case "file_change":
86
96
  return {
87
97
  title: "File change",
88
98
  body: item.changes.map((change) => `${change.kind} ${change.path}`).join("\n")
89
99
  };
100
+ case "mcp_tool_call":
101
+ return {
102
+ title: `${item.server}: ${item.tool}`,
103
+ body: item.error?.message ?? (item.result ? JSON.stringify(item.result, null, 2) : "")
104
+ };
105
+ case "web_search":
106
+ return { title: "Web search", body: item.query };
90
107
  case "error":
91
108
  return { title: "Error", body: item.message };
92
109
  default:
93
110
  return null;
94
111
  }
95
112
  };
113
+ var collectCodexChange = (path, kind, cwd, files) => {
114
+ if (kind === "add") {
115
+ try {
116
+ files.set(path, diffFileFromWrite(path, readFileSync(join(cwd, path), "utf8")));
117
+ return;
118
+ } catch {
119
+ }
120
+ }
121
+ files.set(path, {
122
+ path,
123
+ status: kind === "delete" ? "deleted" : kind === "add" ? "added" : "modified"
124
+ });
125
+ };
96
126
  var errorText = (error) => error instanceof Error ? error.message : "Codex request failed.";
97
127
  var buildApiKeyWidget = (agentId, threadId, reason) => uiWidget({
98
128
  agentId,
@@ -225,6 +255,8 @@ var plugin = definePlugin({
225
255
  const { events } = await thread.runStreamed(content, {
226
256
  signal: context.abortSignal
227
257
  });
258
+ const snapshot = snapshotWorkspace(workingDirectory);
259
+ const changedFiles = /* @__PURE__ */ new Map();
228
260
  for await (const chunk of events) {
229
261
  if (chunk.type === "thread.started") {
230
262
  await persistThreadId(ctx.state, context.storage, chunk.thread_id);
@@ -238,28 +270,48 @@ var plugin = definePlugin({
238
270
  yield* fail(chunk.message);
239
271
  return;
240
272
  }
241
- if (chunk.type !== "item.completed") continue;
273
+ if (chunk.type !== "item.started" && chunk.type !== "item.completed") continue;
242
274
  if (chunk.item.type === "agent_message") {
243
- yield agentOutput({
244
- agentId: context.agentId,
245
- content: chunk.item.text,
246
- threadId: openbotThreadId
247
- });
275
+ if (chunk.type === "item.completed") {
276
+ yield agentOutput({
277
+ agentId: context.agentId,
278
+ content: chunk.item.text,
279
+ threadId: openbotThreadId
280
+ });
281
+ }
248
282
  continue;
249
283
  }
284
+ if (chunk.type === "item.completed" && chunk.item.type === "file_change" && chunk.item.status === "completed") {
285
+ for (const change of chunk.item.changes) {
286
+ collectCodexChange(change.path, change.kind, workingDirectory, changedFiles);
287
+ }
288
+ }
250
289
  const widget = itemWidget(chunk.item);
251
290
  if (!widget) continue;
252
291
  yield uiWidget({
253
292
  agentId: context.agentId,
254
293
  threadId: openbotThreadId,
255
- widget: {
256
- kind: "message",
294
+ widget: toolTraceWidget({
257
295
  widgetId: `codex_${chunk.item.id}`,
296
+ groupId: "codex:tools",
258
297
  title: widget.title,
259
298
  body: widget.body,
260
- variant: "basic",
261
- display: "collapsed"
262
- }
299
+ state: chunk.type === "item.completed" && (chunk.item.type === "command_execution" && chunk.item.status === "failed" || chunk.item.type === "file_change" && chunk.item.status === "failed" || chunk.item.type === "mcp_tool_call" && chunk.item.status === "failed" || chunk.item.type === "error") ? "error" : chunk.type === "item.completed" ? "submitted" : void 0
300
+ })
301
+ });
302
+ }
303
+ const diff = buildDiffWidget({
304
+ widgetId: `codex-diff:${openbotThreadId ?? "run"}:${Date.now()}`,
305
+ files: resolveRunDiffFiles({
306
+ snapshot,
307
+ fallback: changedFiles.values()
308
+ })
309
+ });
310
+ if (diff) {
311
+ yield uiWidget({
312
+ agentId: context.agentId,
313
+ threadId: openbotThreadId,
314
+ widget: diff
263
315
  });
264
316
  }
265
317
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meetopenbot/codex",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex agent plugin for OpenBot",
6
6
  "main": "./dist/index.js",
@@ -17,20 +17,19 @@
17
17
  "files": [
18
18
  "dist"
19
19
  ],
20
- "scripts": {
21
- "build": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod && node ../../scripts/write-plugin-declaration.mjs",
22
- "dev": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod --watch",
23
- "typecheck": "tsc --noEmit --allowImportingTsExtensions --module ESNext --moduleResolution Bundler --target ES2022 --skipLibCheck index.ts",
24
- "prepack": "pnpm build"
25
- },
26
20
  "dependencies": {
27
- "@meetopenbot/plugin-sdk": "workspace:^",
28
- "@openai/codex-sdk": "0.148.0"
21
+ "@openai/codex-sdk": "0.148.0",
22
+ "@meetopenbot/plugin-sdk": "^0.2.0"
29
23
  },
30
24
  "devDependencies": {
31
25
  "@types/node": "^25.6.0",
32
26
  "esbuild": "^0.21.0",
33
27
  "zod": "^4.4.3"
34
28
  },
35
- "types": "./dist/index.d.ts"
36
- }
29
+ "types": "./dist/index.d.ts",
30
+ "scripts": {
31
+ "build": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod && node ../../scripts/write-plugin-declaration.mjs",
32
+ "dev": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod --watch",
33
+ "typecheck": "tsc --noEmit --allowImportingTsExtensions --module ESNext --moduleResolution Bundler --target ES2022 --skipLibCheck index.ts"
34
+ }
35
+ }