@xuda.io/ai_module 1.1.5606 → 1.1.5607
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/index.mjs +67 -4
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -111,6 +111,26 @@ const parse_codex_jsonl = function (stdout) {
|
|
|
111
111
|
return events;
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
+
const get_number_value = function (...values) {
|
|
115
|
+
for (const value of values) {
|
|
116
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
117
|
+
if (typeof value === 'string' && value.trim() && Number.isFinite(Number(value))) return Number(value);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return 0;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const normalize_codex_usage = function (usage) {
|
|
124
|
+
if (!usage || typeof usage !== 'object') {
|
|
125
|
+
return { input_tokens: 0, output_tokens: 0 };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const input_tokens = get_number_value(usage.input_tokens, usage.inputTokens, usage.prompt_tokens, usage.promptTokens, usage.total_input_tokens, usage.totalInputTokens, usage.total_token_usage?.input_tokens, usage.totalTokenUsage?.inputTokens);
|
|
129
|
+
const output_tokens = get_number_value(usage.output_tokens, usage.outputTokens, usage.completion_tokens, usage.completionTokens, usage.total_output_tokens, usage.totalOutputTokens, usage.total_token_usage?.output_tokens, usage.totalTokenUsage?.outputTokens);
|
|
130
|
+
|
|
131
|
+
return { input_tokens, output_tokens };
|
|
132
|
+
};
|
|
133
|
+
|
|
114
134
|
const create_codex_jsonl_stream_parser = function (onEvent) {
|
|
115
135
|
let buffer = '';
|
|
116
136
|
|
|
@@ -137,11 +157,24 @@ const get_openai_codex_cli_command = function () {
|
|
|
137
157
|
return _conf.openai_codex_command || 'codex';
|
|
138
158
|
};
|
|
139
159
|
|
|
140
|
-
const
|
|
160
|
+
const get_openai_codex_model = function () {
|
|
161
|
+
return _conf.openai_codex_model || _conf.ai_models?.openai_codex_model?.model || null;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const get_openai_codex_usage_model = function (codex_model, requested_codex_model) {
|
|
165
|
+
if (requested_codex_model) return codex_model;
|
|
166
|
+
return _conf.ai_models?.openai_codex_model ? 'openai_codex_model' : codex_model || _conf.openai_codex_command || 'openai_codex_cli';
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const get_openai_codex_exec_args = function (codex_model) {
|
|
141
170
|
const args = ['exec', '--json'];
|
|
142
171
|
const bypass_approvals_and_sandbox = typeof _conf.openai_codex_bypass_approvals_and_sandbox === 'undefined' ? true : _conf.openai_codex_bypass_approvals_and_sandbox;
|
|
143
172
|
const sandbox = _conf.openai_codex_sandbox;
|
|
144
173
|
|
|
174
|
+
if (codex_model) {
|
|
175
|
+
args.push('--model', codex_model);
|
|
176
|
+
}
|
|
177
|
+
|
|
145
178
|
if (bypass_approvals_and_sandbox) {
|
|
146
179
|
args.push('--dangerously-bypass-approvals-and-sandbox');
|
|
147
180
|
} else if (sandbox) {
|
|
@@ -1216,11 +1249,14 @@ export const execute_codex_request = async function (req_or_ip, prompt_arg, atta
|
|
|
1216
1249
|
const prompt = is_req_call ? req_or_ip.prompt : prompt_arg;
|
|
1217
1250
|
let attachments = is_req_call ? req_or_ip.attachments || [] : attachments_arg;
|
|
1218
1251
|
const uid = is_req_call ? req_or_ip.uid : undefined;
|
|
1252
|
+
const account_profile_info = is_req_call && uid ? req_or_ip.account_profile_info || (await get_active_account_profile_info(uid, req_or_ip.profile_id)) : undefined;
|
|
1253
|
+
const requested_codex_model = is_req_call ? req_or_ip.codex_model || req_or_ip.model : null;
|
|
1254
|
+
const codex_model = requested_codex_model || get_openai_codex_model();
|
|
1219
1255
|
const conversation_id = is_req_call ? req_or_ip.conversation_id || req_or_ip.conversation_doc?._id : undefined;
|
|
1220
1256
|
const job_id = is_req_call ? prompt_arg || req_or_ip.job_id : undefined;
|
|
1221
1257
|
stream_enabled = is_req_call ? req_or_ip.stream !== false && req_or_ip.stream !== 'false' : false;
|
|
1222
|
-
const prompt_conversation_item_id = is_req_call ? await _common.xuda_get_uuid('chat_conversation_item') : undefined;
|
|
1223
|
-
const response_conversation_item_id = is_req_call ? await _common.xuda_get_uuid('chat_conversation_item') : undefined;
|
|
1258
|
+
const prompt_conversation_item_id = is_req_call && uid ? await _common.xuda_get_uuid('chat_conversation_item') : undefined;
|
|
1259
|
+
const response_conversation_item_id = is_req_call && uid ? await _common.xuda_get_uuid('chat_conversation_item') : undefined;
|
|
1224
1260
|
|
|
1225
1261
|
let stream_delta_seq = 0;
|
|
1226
1262
|
let stream_delta_text = '';
|
|
@@ -1286,6 +1322,7 @@ export const execute_codex_request = async function (req_or_ip, prompt_arg, atta
|
|
|
1286
1322
|
}
|
|
1287
1323
|
|
|
1288
1324
|
const reasoning = [];
|
|
1325
|
+
let codex_usage = { input_tokens: 0, output_tokens: 0 };
|
|
1289
1326
|
let streamed_agent_messages = new Set();
|
|
1290
1327
|
const pushReasoning = function (type, text, metadata = {}) {
|
|
1291
1328
|
if (!text) return;
|
|
@@ -1345,6 +1382,7 @@ export const execute_codex_request = async function (req_or_ip, prompt_arg, atta
|
|
|
1345
1382
|
emitToDashboard('stream_phase', event.message, { update: true, error: true });
|
|
1346
1383
|
break;
|
|
1347
1384
|
case 'turn.completed':
|
|
1385
|
+
codex_usage = normalize_codex_usage(event.usage);
|
|
1348
1386
|
emitToDashboard('stream_phase', 'Codex request completed', { update: true, usage: event.usage });
|
|
1349
1387
|
break;
|
|
1350
1388
|
case 'turn.failed':
|
|
@@ -1401,7 +1439,7 @@ ${prompt}`;
|
|
|
1401
1439
|
}
|
|
1402
1440
|
|
|
1403
1441
|
const openai_codex_command = get_openai_codex_cli_command();
|
|
1404
|
-
const codex_args = get_openai_codex_exec_args();
|
|
1442
|
+
const codex_args = get_openai_codex_exec_args(codex_model);
|
|
1405
1443
|
for (const image_path of image_paths) {
|
|
1406
1444
|
codex_args.push('--image', image_path);
|
|
1407
1445
|
}
|
|
@@ -1415,6 +1453,29 @@ ${prompt}`;
|
|
|
1415
1453
|
onStdout: create_codex_jsonl_stream_parser(handleCodexEvent),
|
|
1416
1454
|
});
|
|
1417
1455
|
const events = parse_codex_jsonl(ret.stdout);
|
|
1456
|
+
if (!codex_usage.input_tokens && !codex_usage.output_tokens && Array.isArray(events)) {
|
|
1457
|
+
const completed_event_with_usage = events.findLast((event) => event?.type === 'turn.completed' && event.usage);
|
|
1458
|
+
codex_usage = normalize_codex_usage(completed_event_with_usage?.usage);
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
if (uid && account_profile_info && (codex_usage.input_tokens || codex_usage.output_tokens)) {
|
|
1462
|
+
account_msa.record_ai_usage(
|
|
1463
|
+
uid,
|
|
1464
|
+
codex_usage.input_tokens,
|
|
1465
|
+
codex_usage.output_tokens,
|
|
1466
|
+
'execute codex request',
|
|
1467
|
+
prompt,
|
|
1468
|
+
get_openai_codex_usage_model(codex_model, requested_codex_model),
|
|
1469
|
+
{
|
|
1470
|
+
conversation_id,
|
|
1471
|
+
job_id,
|
|
1472
|
+
remote_host: get_codex_remote_host(ip),
|
|
1473
|
+
exit_code: ret.exit_code,
|
|
1474
|
+
attachments_count: attachments.length,
|
|
1475
|
+
},
|
|
1476
|
+
account_profile_info,
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1418
1479
|
|
|
1419
1480
|
if (ret.exit_code !== 0) {
|
|
1420
1481
|
emitToDashboard('stream_phase', 'Codex request failed', { update: true });
|
|
@@ -1432,6 +1493,7 @@ ${prompt}`;
|
|
|
1432
1493
|
stderr: ret.stderr,
|
|
1433
1494
|
events,
|
|
1434
1495
|
reasoning,
|
|
1496
|
+
usage: codex_usage,
|
|
1435
1497
|
},
|
|
1436
1498
|
};
|
|
1437
1499
|
}
|
|
@@ -1448,6 +1510,7 @@ ${prompt}`;
|
|
|
1448
1510
|
stderr: ret.stderr,
|
|
1449
1511
|
events,
|
|
1450
1512
|
reasoning,
|
|
1513
|
+
usage: codex_usage,
|
|
1451
1514
|
},
|
|
1452
1515
|
};
|
|
1453
1516
|
} catch (err) {
|