@axhub/genie 0.1.5 → 0.1.7
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/api-docs.html +351 -909
- package/dist/assets/index-C2r-Jzfw.js +897 -0
- package/dist/assets/index-COkoBQi5.css +32 -0
- package/dist/index.html +2 -2
- package/package.json +6 -2
- package/server/gemini-cli.js +280 -0
- package/server/index.js +206 -8
- package/server/openai-codex.js +102 -7
- package/server/opencode-cli.js +673 -0
- package/server/projects.js +645 -5
- package/server/routes/agent.js +35 -11
- package/server/routes/cli-auth.js +271 -0
- package/server/routes/commands.js +29 -3
- package/server/routes/git.js +15 -5
- package/server/routes/opencode.js +72 -0
- package/shared/modelConstants.js +62 -17
- package/dist/assets/index-Bue8nA1L.js +0 -1249
- package/dist/assets/index-CtRxrKDm.css +0 -32
- package/server/database/auth.db +0 -0
package/server/openai-codex.js
CHANGED
|
@@ -140,7 +140,7 @@ function transformCodexEvent(event) {
|
|
|
140
140
|
case 'thread.started':
|
|
141
141
|
return {
|
|
142
142
|
type: 'thread_started',
|
|
143
|
-
threadId: event.id
|
|
143
|
+
threadId: event.thread_id || event.id
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
case 'error':
|
|
@@ -157,6 +157,42 @@ function transformCodexEvent(event) {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Extract thread id from thread.started events (SDK uses thread_id)
|
|
162
|
+
* @param {object} event
|
|
163
|
+
* @returns {string|null}
|
|
164
|
+
*/
|
|
165
|
+
function getThreadIdFromEvent(event) {
|
|
166
|
+
const threadId = event?.thread_id || event?.id;
|
|
167
|
+
return typeof threadId === 'string' && threadId.trim() ? threadId.trim() : null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Extract text-bearing item info from Codex item events.
|
|
172
|
+
* Only agent_message and reasoning currently stream textual deltas.
|
|
173
|
+
* @param {object} item
|
|
174
|
+
* @returns {{itemId: string, itemType: string, text: string, isReasoning: boolean}|null}
|
|
175
|
+
*/
|
|
176
|
+
function getTextItemInfo(item) {
|
|
177
|
+
if (!item || (item.type !== 'agent_message' && item.type !== 'reasoning')) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const itemId = typeof item.id === 'string' && item.id.trim()
|
|
182
|
+
? item.id.trim()
|
|
183
|
+
: null;
|
|
184
|
+
if (!itemId) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
itemId,
|
|
190
|
+
itemType: item.type,
|
|
191
|
+
text: typeof item.text === 'string' ? item.text : '',
|
|
192
|
+
isReasoning: item.type === 'reasoning'
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
160
196
|
/**
|
|
161
197
|
* Map permission mode to Codex SDK options
|
|
162
198
|
* @param {string} permissionMode - 'default', 'acceptEdits', or 'bypassPermissions'
|
|
@@ -195,7 +231,8 @@ export async function queryCodex(command, options = {}, ws) {
|
|
|
195
231
|
cwd,
|
|
196
232
|
projectPath,
|
|
197
233
|
model,
|
|
198
|
-
permissionMode = 'default'
|
|
234
|
+
permissionMode = 'default',
|
|
235
|
+
modelReasoningEffort
|
|
199
236
|
} = options;
|
|
200
237
|
|
|
201
238
|
const workingDirectory = cwd || projectPath || process.cwd();
|
|
@@ -205,6 +242,7 @@ export async function queryCodex(command, options = {}, ws) {
|
|
|
205
242
|
let thread;
|
|
206
243
|
let currentSessionId = sessionId;
|
|
207
244
|
let resolvedSessionIdFromEvent = null;
|
|
245
|
+
const streamedTextByItemId = new Map();
|
|
208
246
|
|
|
209
247
|
const syncResolvedSessionId = (broadcastUpdate = false) => {
|
|
210
248
|
const resolvedThreadId = typeof thread?.id === 'string' && thread.id.trim()
|
|
@@ -252,7 +290,8 @@ export async function queryCodex(command, options = {}, ws) {
|
|
|
252
290
|
skipGitRepoCheck: true,
|
|
253
291
|
sandboxMode,
|
|
254
292
|
approvalPolicy,
|
|
255
|
-
model
|
|
293
|
+
model,
|
|
294
|
+
...(modelReasoningEffort ? { modelReasoningEffort } : {})
|
|
256
295
|
};
|
|
257
296
|
|
|
258
297
|
// Start or resume thread
|
|
@@ -289,8 +328,11 @@ export async function queryCodex(command, options = {}, ws) {
|
|
|
289
328
|
syncResolvedSessionId(true);
|
|
290
329
|
|
|
291
330
|
for await (const event of streamedTurn.events) {
|
|
292
|
-
if (event?.type === 'thread.started'
|
|
293
|
-
|
|
331
|
+
if (event?.type === 'thread.started') {
|
|
332
|
+
const eventThreadId = getThreadIdFromEvent(event);
|
|
333
|
+
if (eventThreadId) {
|
|
334
|
+
resolvedSessionIdFromEvent = eventThreadId;
|
|
335
|
+
}
|
|
294
336
|
}
|
|
295
337
|
|
|
296
338
|
syncResolvedSessionId(true);
|
|
@@ -301,8 +343,61 @@ export async function queryCodex(command, options = {}, ws) {
|
|
|
301
343
|
break;
|
|
302
344
|
}
|
|
303
345
|
|
|
304
|
-
|
|
305
|
-
|
|
346
|
+
const isItemEvent = event.type === 'item.started' || event.type === 'item.updated' || event.type === 'item.completed';
|
|
347
|
+
if (isItemEvent) {
|
|
348
|
+
const textItemInfo = getTextItemInfo(event.item);
|
|
349
|
+
|
|
350
|
+
if (textItemInfo) {
|
|
351
|
+
const previousText = streamedTextByItemId.get(textItemInfo.itemId) || '';
|
|
352
|
+
const nextText = textItemInfo.text || '';
|
|
353
|
+
|
|
354
|
+
let delta = '';
|
|
355
|
+
if (nextText.startsWith(previousText)) {
|
|
356
|
+
delta = nextText.slice(previousText.length);
|
|
357
|
+
} else if (nextText !== previousText) {
|
|
358
|
+
// Fallback when text is rewritten rather than appended
|
|
359
|
+
delta = nextText;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
streamedTextByItemId.set(textItemInfo.itemId, nextText);
|
|
363
|
+
|
|
364
|
+
if (delta) {
|
|
365
|
+
sendMessage(ws, {
|
|
366
|
+
type: 'codex-response',
|
|
367
|
+
data: {
|
|
368
|
+
type: 'item_delta',
|
|
369
|
+
itemType: textItemInfo.itemType,
|
|
370
|
+
itemId: textItemInfo.itemId,
|
|
371
|
+
isReasoning: textItemInfo.isReasoning,
|
|
372
|
+
delta
|
|
373
|
+
},
|
|
374
|
+
sessionId: currentSessionId
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (event.type === 'item.completed') {
|
|
379
|
+
sendMessage(ws, {
|
|
380
|
+
type: 'codex-response',
|
|
381
|
+
data: {
|
|
382
|
+
type: 'item_done',
|
|
383
|
+
itemType: textItemInfo.itemType,
|
|
384
|
+
itemId: textItemInfo.itemId,
|
|
385
|
+
isReasoning: textItemInfo.isReasoning,
|
|
386
|
+
content: nextText
|
|
387
|
+
},
|
|
388
|
+
sessionId: currentSessionId
|
|
389
|
+
});
|
|
390
|
+
streamedTextByItemId.delete(textItemInfo.itemId);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Non-text items can be noisy during started/updated phases.
|
|
397
|
+
// Keep existing behavior: emit them when completed.
|
|
398
|
+
if (event.type !== 'item.completed') {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
306
401
|
}
|
|
307
402
|
|
|
308
403
|
const transformed = transformCodexEvent(event);
|