@meetopenbot/codex 1.1.1 → 1.2.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.
- package/README.md +6 -7
- package/dist/index.js +129 -302
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -2,22 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
OpenAI Codex runtime plugin for OpenBot. Each `agent:invoke` starts or resumes a Codex SDK thread in the channel workspace.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Auth
|
|
6
|
+
|
|
7
|
+
On cloud, `authMode: credits` (the default) uses your workspace credit balance via OpenBot. For BYOK, set `authMode: byok` and add `OPENAI_API_KEY` (or `CODEX_API_KEY`) under workspace settings — there is no API key field in plugin config.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Locally, Codex always uses BYOK from `CODEX_API_KEY` / `OPENAI_API_KEY`.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
- `CODEX_API_KEY`
|
|
11
|
-
- `OPENAI_API_KEY`
|
|
11
|
+
## Config
|
|
12
12
|
|
|
13
13
|
Optional:
|
|
14
14
|
|
|
15
|
+
- `authMode` — cloud only: `credits` (default) or `byok`
|
|
15
16
|
- `model` — Codex model id (e.g. `gpt-5.6`). Omit to use the CLI default.
|
|
16
17
|
- `sandboxMode` — `read-only` | `workspace-write` | `danger-full-access` (default `workspace-write`)
|
|
17
18
|
- `approvalPolicy` — `never` | `on-request` | `on-failure` | `untrusted` (default `never`)
|
|
18
|
-
- `workingDirectory` — override the channel cwd
|
|
19
19
|
- `skipGitRepoCheck` — default `true` for non-git channel workspaces
|
|
20
|
-
- `baseURL` — custom OpenAI-compatible endpoint
|
|
21
20
|
- `codexPathOverride` — path to a local `codex` binary (`CODEX_PATH` / `CODEX_CLI_PATH` also work)
|
|
22
21
|
|
|
23
22
|
Codex conversation state is stored as `codexThreadId` on the OpenBot thread, not as the OpenBot thread id.
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
// index.ts
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { defineAgentPlugin } from "@meetopenbot/plugin-sdk";
|
|
3
|
+
|
|
4
|
+
// src/config.ts
|
|
2
5
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
agentOutput,
|
|
6
|
-
uiWidget,
|
|
7
|
-
toolTraceWidget,
|
|
8
|
-
buildDiffWidget,
|
|
9
|
-
diffFileFromWrite,
|
|
10
|
-
resolveRunDiffFiles,
|
|
11
|
-
snapshotWorkspace
|
|
6
|
+
trimmedString,
|
|
7
|
+
vendorModelId
|
|
12
8
|
} from "@meetopenbot/plugin-sdk";
|
|
13
|
-
import { readFileSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import {
|
|
16
|
-
Codex
|
|
17
|
-
} from "@openai/codex-sdk";
|
|
18
9
|
var SANDBOX_MODES = [
|
|
19
10
|
"read-only",
|
|
20
11
|
"workspace-write",
|
|
@@ -26,303 +17,139 @@ var APPROVAL_MODES = [
|
|
|
26
17
|
"on-failure",
|
|
27
18
|
"untrusted"
|
|
28
19
|
];
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"not logged in",
|
|
45
|
-
"login"
|
|
46
|
-
];
|
|
47
|
-
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
48
|
-
var asString = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
49
|
-
var isAuthErrorMessage = (message) => {
|
|
50
|
-
const lower = message.toLowerCase();
|
|
51
|
-
return AUTH_ERROR_PATTERNS.some((pattern) => lower.includes(pattern));
|
|
52
|
-
};
|
|
53
|
-
var readPersistedThreadId = (state) => {
|
|
54
|
-
const source = state.threadDetails?.state ?? state.channelDetails?.state;
|
|
55
|
-
const record = asRecord(source);
|
|
56
|
-
return asString(record.codexThreadId);
|
|
57
|
-
};
|
|
58
|
-
var persistThreadId = async (state, storage, codexThreadId) => {
|
|
59
|
-
if (!storage || !state.channelId) return;
|
|
60
|
-
const patch = { codexThreadId };
|
|
61
|
-
if (state.threadId) {
|
|
62
|
-
await storage.patchThreadState({
|
|
63
|
-
channelId: state.channelId,
|
|
64
|
-
threadId: state.threadId,
|
|
65
|
-
state: patch
|
|
66
|
-
});
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
await storage.patchChannelState({ channelId: state.channelId, state: patch });
|
|
70
|
-
};
|
|
71
|
-
var parseSandboxMode = (value) => {
|
|
72
|
-
const raw = asString(value);
|
|
73
|
-
if (!raw) return "workspace-write";
|
|
74
|
-
if (SANDBOX_MODES.includes(raw)) return raw;
|
|
75
|
-
return LEGACY_SANDBOX[raw] ?? "workspace-write";
|
|
76
|
-
};
|
|
77
|
-
var parseApprovalPolicy = (value) => {
|
|
78
|
-
const raw = asString(value);
|
|
79
|
-
if (!raw) return "never";
|
|
80
|
-
if (APPROVAL_MODES.includes(raw)) return raw;
|
|
81
|
-
return LEGACY_APPROVAL[raw] ?? "never";
|
|
82
|
-
};
|
|
83
|
-
var parseModel = (value) => {
|
|
84
|
-
const raw = asString(value);
|
|
85
|
-
if (!raw) return void 0;
|
|
86
|
-
return raw.split("/").pop() || void 0;
|
|
87
|
-
};
|
|
88
|
-
var itemWidget = (item) => {
|
|
89
|
-
switch (item.type) {
|
|
90
|
-
case "command_execution":
|
|
91
|
-
return {
|
|
92
|
-
title: "Command",
|
|
93
|
-
body: [item.command, item.aggregated_output].filter(Boolean).join("\n\n")
|
|
94
|
-
};
|
|
95
|
-
case "file_change":
|
|
96
|
-
return {
|
|
97
|
-
title: "File change",
|
|
98
|
-
body: item.changes.map((change) => `${change.kind} ${change.path}`).join("\n")
|
|
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 };
|
|
107
|
-
case "error":
|
|
108
|
-
return { title: "Error", body: item.message };
|
|
109
|
-
default:
|
|
110
|
-
return null;
|
|
20
|
+
var pluginConfigSchema = {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
sandboxMode: {
|
|
24
|
+
type: "string",
|
|
25
|
+
enum: [...SANDBOX_MODES],
|
|
26
|
+
description: "Filesystem sandbox: read-only | workspace-write | danger-full-access",
|
|
27
|
+
default: "workspace-write"
|
|
28
|
+
},
|
|
29
|
+
approvalPolicy: {
|
|
30
|
+
type: "string",
|
|
31
|
+
enum: [...APPROVAL_MODES],
|
|
32
|
+
description: "When to require approval: never | on-request | on-failure | untrusted",
|
|
33
|
+
default: "never"
|
|
34
|
+
}
|
|
111
35
|
}
|
|
112
36
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
37
|
+
function resolveCodexConfig(config) {
|
|
38
|
+
const sandboxRaw = trimmedString(config.sandboxMode);
|
|
39
|
+
const approvalRaw = trimmedString(config.approvalPolicy);
|
|
40
|
+
return {
|
|
41
|
+
model: vendorModelId(trimmedString(config.model)),
|
|
42
|
+
sandboxMode: sandboxRaw && SANDBOX_MODES.includes(sandboxRaw) ? sandboxRaw : "workspace-write",
|
|
43
|
+
approvalPolicy: approvalRaw && APPROVAL_MODES.includes(approvalRaw) ? approvalRaw : "never",
|
|
44
|
+
skipGitRepoCheck: true,
|
|
45
|
+
codexPathOverride: trimmedString(process.env.CODEX_PATH) ?? trimmedString(process.env.CODEX_CLI_PATH)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/runtime.ts
|
|
50
|
+
import {
|
|
51
|
+
isCloudMode,
|
|
52
|
+
llmAuthNotConfiguredMessage,
|
|
53
|
+
resolveByokApiKey
|
|
54
|
+
} from "@meetopenbot/plugin-sdk";
|
|
55
|
+
import { Codex } from "@openai/codex-sdk";
|
|
56
|
+
|
|
57
|
+
// src/credits.ts
|
|
58
|
+
import {
|
|
59
|
+
CREDITS_API_KEY_PLACEHOLDER,
|
|
60
|
+
CREDITS_NOT_CONFIGURED_MESSAGE,
|
|
61
|
+
INTEGRATIONS_TOKEN_HEADER,
|
|
62
|
+
creditsErrorMessage as mapCreditsError,
|
|
63
|
+
creditsProviderBaseUrl,
|
|
64
|
+
isAuthErrorMessage,
|
|
65
|
+
resolveCreditsAuthConfig
|
|
66
|
+
} from "@meetopenbot/plugin-sdk";
|
|
67
|
+
var CREDITS_PROVIDER_ID = "openbot_credits";
|
|
68
|
+
function buildCreditsCodexConfig(config) {
|
|
69
|
+
return {
|
|
70
|
+
model_provider: CREDITS_PROVIDER_ID,
|
|
71
|
+
model_providers: {
|
|
72
|
+
[CREDITS_PROVIDER_ID]: {
|
|
73
|
+
name: "OpenBot Credits",
|
|
74
|
+
base_url: creditsProviderBaseUrl(config),
|
|
75
|
+
env_key: "CODEX_API_KEY",
|
|
76
|
+
wire_api: "responses",
|
|
77
|
+
supports_websockets: false,
|
|
78
|
+
http_headers: {
|
|
79
|
+
[INTEGRATIONS_TOKEN_HEADER]: config.token
|
|
80
|
+
}
|
|
81
|
+
}
|
|
119
82
|
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function creditsErrorMessage(message) {
|
|
86
|
+
return mapCreditsError(message, { agentName: "Codex", providerLabel: "OpenAI" });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/session.ts
|
|
90
|
+
import { threadSession } from "@meetopenbot/plugin-sdk";
|
|
91
|
+
var codexSession = threadSession("codexThreadId");
|
|
92
|
+
|
|
93
|
+
// src/runtime.ts
|
|
94
|
+
async function runCodexTurn({
|
|
95
|
+
prompt,
|
|
96
|
+
handlerCtx,
|
|
97
|
+
context
|
|
98
|
+
}) {
|
|
99
|
+
const byok = resolveByokApiKey("openai", ["CODEX_API_KEY"]);
|
|
100
|
+
const credits = !byok && isCloudMode() ? resolveCreditsAuthConfig() : void 0;
|
|
101
|
+
if (!byok && !credits) {
|
|
102
|
+
return llmAuthNotConfiguredMessage("OPENAI_API_KEY");
|
|
120
103
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
104
|
+
const config = resolveCodexConfig(context.config);
|
|
105
|
+
const client = new Codex({
|
|
106
|
+
apiKey: byok ?? credits?.token ?? CREDITS_API_KEY_PLACEHOLDER,
|
|
107
|
+
...config.codexPathOverride && { codexPathOverride: config.codexPathOverride },
|
|
108
|
+
...credits ? { config: buildCreditsCodexConfig(credits) } : {}
|
|
124
109
|
});
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
110
|
+
const workingDirectory = handlerCtx.state.channelDetails?.cwd || process.cwd();
|
|
111
|
+
const threadOptions = {
|
|
112
|
+
workingDirectory,
|
|
113
|
+
skipGitRepoCheck: config.skipGitRepoCheck,
|
|
114
|
+
sandboxMode: config.sandboxMode,
|
|
115
|
+
approvalPolicy: config.approvalPolicy,
|
|
116
|
+
...config.model && { model: config.model }
|
|
117
|
+
};
|
|
118
|
+
const savedId = codexSession.read(handlerCtx.state);
|
|
119
|
+
const thread = savedId ? client.resumeThread(savedId, threadOptions) : client.startThread(threadOptions);
|
|
120
|
+
const { events } = await thread.runStreamed(prompt, {
|
|
121
|
+
signal: context.abortSignal
|
|
122
|
+
});
|
|
123
|
+
let text = "";
|
|
124
|
+
for await (const chunk of events) {
|
|
125
|
+
if (chunk.type === "thread.started") {
|
|
126
|
+
await codexSession.write(handlerCtx.state, context.storage, chunk.thread_id);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (chunk.type === "turn.failed") {
|
|
130
|
+
return creditsErrorMessage(chunk.error.message) ?? chunk.error.message;
|
|
131
|
+
}
|
|
132
|
+
if (chunk.type === "error") {
|
|
133
|
+
return creditsErrorMessage(chunk.message) ?? chunk.message;
|
|
134
|
+
}
|
|
135
|
+
if (chunk.type === "item.completed" && chunk.item.type === "agent_message" && chunk.item.text.trim()) {
|
|
136
|
+
text = chunk.item.text.trim();
|
|
150
137
|
}
|
|
151
138
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
139
|
+
return text;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/index.ts
|
|
143
|
+
var plugin = await defineAgentPlugin({
|
|
155
144
|
name: "Codex",
|
|
156
145
|
description: "OpenAI Codex agent. Uses the Codex SDK to read code, edit files, and run shell commands inside the channel's workspace.",
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
type: "string",
|
|
162
|
-
description: "OpenAI API key (falls back to CODEX_API_KEY / OPENAI_API_KEY)",
|
|
163
|
-
format: "password"
|
|
164
|
-
},
|
|
165
|
-
model: {
|
|
166
|
-
type: "string",
|
|
167
|
-
description: "Codex model id (e.g. gpt-5.6). Leave empty to use the CLI default."
|
|
168
|
-
},
|
|
169
|
-
sandboxMode: {
|
|
170
|
-
type: "string",
|
|
171
|
-
enum: [...SANDBOX_MODES],
|
|
172
|
-
description: "Filesystem sandbox: read-only | workspace-write | danger-full-access",
|
|
173
|
-
default: "workspace-write"
|
|
174
|
-
},
|
|
175
|
-
approvalPolicy: {
|
|
176
|
-
type: "string",
|
|
177
|
-
enum: [...APPROVAL_MODES],
|
|
178
|
-
description: "When to require approval: never | on-request | on-failure | untrusted",
|
|
179
|
-
default: "never"
|
|
180
|
-
},
|
|
181
|
-
workingDirectory: {
|
|
182
|
-
type: "string",
|
|
183
|
-
description: "Override the channel working directory"
|
|
184
|
-
},
|
|
185
|
-
skipGitRepoCheck: {
|
|
186
|
-
type: "boolean",
|
|
187
|
-
description: "Skip the Codex git-repo check (needed for non-git channel workspaces)",
|
|
188
|
-
default: true
|
|
189
|
-
},
|
|
190
|
-
baseURL: {
|
|
191
|
-
type: "string",
|
|
192
|
-
description: "Custom OpenAI-compatible endpoint"
|
|
193
|
-
},
|
|
194
|
-
codexPathOverride: {
|
|
195
|
-
type: "string",
|
|
196
|
-
description: "Path to a local Codex CLI binary"
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
factory: (context) => {
|
|
201
|
-
const config = context.config;
|
|
202
|
-
const apiKey = asString(config.apiKey) ?? process.env.CODEX_API_KEY ?? process.env.OPENAI_API_KEY;
|
|
203
|
-
const codexPathOverride = asString(config.codexPathOverride) ?? process.env.CODEX_PATH ?? process.env.CODEX_CLI_PATH;
|
|
204
|
-
const model = parseModel(config.model);
|
|
205
|
-
const sandboxMode = parseSandboxMode(config.sandboxMode);
|
|
206
|
-
const approvalPolicy = parseApprovalPolicy(config.approvalPolicy);
|
|
207
|
-
const skipGitRepoCheck = config.skipGitRepoCheck !== false;
|
|
208
|
-
const workingDirectoryOverride = asString(config.workingDirectory);
|
|
209
|
-
const baseUrl = asString(config.baseURL);
|
|
210
|
-
let client;
|
|
211
|
-
const getClient = () => {
|
|
212
|
-
if (!client) {
|
|
213
|
-
client = new Codex({
|
|
214
|
-
...apiKey && { apiKey },
|
|
215
|
-
...codexPathOverride && { codexPathOverride },
|
|
216
|
-
...baseUrl && { baseUrl }
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
return client;
|
|
220
|
-
};
|
|
221
|
-
return (builder) => {
|
|
222
|
-
builder.on("agent:invoke", async function* (event, ctx) {
|
|
223
|
-
if (!shouldHandleInvoke(event, context.agentId)) return;
|
|
224
|
-
const content = asString(event.data?.content);
|
|
225
|
-
const openbotThreadId = event.meta?.threadId || ctx.state.threadId;
|
|
226
|
-
if (!content) {
|
|
227
|
-
yield agentOutput({
|
|
228
|
-
agentId: context.agentId,
|
|
229
|
-
content: "No content provided.",
|
|
230
|
-
threadId: openbotThreadId
|
|
231
|
-
});
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const workingDirectory = workingDirectoryOverride || ctx.state.channelDetails?.cwd || process.cwd();
|
|
235
|
-
const threadOptions = {
|
|
236
|
-
workingDirectory,
|
|
237
|
-
skipGitRepoCheck,
|
|
238
|
-
sandboxMode,
|
|
239
|
-
approvalPolicy,
|
|
240
|
-
...model && { model }
|
|
241
|
-
};
|
|
242
|
-
const savedId = readPersistedThreadId(ctx.state);
|
|
243
|
-
const thread = savedId ? getClient().resumeThread(savedId, threadOptions) : getClient().startThread(threadOptions);
|
|
244
|
-
const fail = function* (message) {
|
|
245
|
-
if (isAuthErrorMessage(message)) {
|
|
246
|
-
yield buildApiKeyWidget(context.agentId, openbotThreadId, message);
|
|
247
|
-
}
|
|
248
|
-
yield agentOutput({
|
|
249
|
-
agentId: context.agentId,
|
|
250
|
-
content: `Error: ${message}`,
|
|
251
|
-
threadId: openbotThreadId
|
|
252
|
-
});
|
|
253
|
-
};
|
|
254
|
-
try {
|
|
255
|
-
const { events } = await thread.runStreamed(content, {
|
|
256
|
-
signal: context.abortSignal
|
|
257
|
-
});
|
|
258
|
-
const snapshot = snapshotWorkspace(workingDirectory);
|
|
259
|
-
const changedFiles = /* @__PURE__ */ new Map();
|
|
260
|
-
for await (const chunk of events) {
|
|
261
|
-
if (chunk.type === "thread.started") {
|
|
262
|
-
await persistThreadId(ctx.state, context.storage, chunk.thread_id);
|
|
263
|
-
continue;
|
|
264
|
-
}
|
|
265
|
-
if (chunk.type === "turn.failed") {
|
|
266
|
-
yield* fail(chunk.error.message);
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
if (chunk.type === "error") {
|
|
270
|
-
yield* fail(chunk.message);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
if (chunk.type !== "item.started" && chunk.type !== "item.completed") continue;
|
|
274
|
-
if (chunk.item.type === "agent_message") {
|
|
275
|
-
if (chunk.type === "item.completed") {
|
|
276
|
-
yield agentOutput({
|
|
277
|
-
agentId: context.agentId,
|
|
278
|
-
content: chunk.item.text,
|
|
279
|
-
threadId: openbotThreadId
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
continue;
|
|
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
|
-
}
|
|
289
|
-
const widget = itemWidget(chunk.item);
|
|
290
|
-
if (!widget) continue;
|
|
291
|
-
yield uiWidget({
|
|
292
|
-
agentId: context.agentId,
|
|
293
|
-
threadId: openbotThreadId,
|
|
294
|
-
widget: toolTraceWidget({
|
|
295
|
-
widgetId: `codex_${chunk.item.id}`,
|
|
296
|
-
groupId: "codex:tools",
|
|
297
|
-
title: widget.title,
|
|
298
|
-
body: widget.body,
|
|
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
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
} catch (error) {
|
|
318
|
-
yield* fail(errorText(error));
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
};
|
|
322
|
-
}
|
|
146
|
+
models: { providers: ["openai"], default: "openai/gpt-5.6-luna" },
|
|
147
|
+
configSchema: pluginConfigSchema,
|
|
148
|
+
emptyPrompt: "Send a message to run Codex in this workspace.",
|
|
149
|
+
run: runCodexTurn
|
|
323
150
|
});
|
|
324
|
-
var
|
|
151
|
+
var src_default = plugin;
|
|
325
152
|
export {
|
|
326
|
-
|
|
153
|
+
src_default as default,
|
|
327
154
|
plugin
|
|
328
155
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/codex",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenAI Codex agent plugin for OpenBot",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@openai/codex-sdk": "0.148.0",
|
|
22
|
-
"@meetopenbot/plugin-sdk": "^0.
|
|
22
|
+
"@meetopenbot/plugin-sdk": "^0.3.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^25.6.0",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"types": "./dist/index.d.ts",
|
|
30
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
|
|
31
|
+
"build": "esbuild src/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 src/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 -p tsconfig.json --noEmit"
|
|
34
34
|
}
|
|
35
35
|
}
|