@4yi/cli 0.1.9 → 0.1.10

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/package.json +1 -1
  2. package/src/connect.mjs +34 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4yi/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "4YI command-line launcher for OAuth login and OpenCode runtime",
5
5
  "type": "module",
6
6
  "bin": {
package/src/connect.mjs CHANGED
@@ -320,9 +320,16 @@ function buildCodexCatalog(models, template) {
320
320
  }
321
321
 
322
322
  async function checkCodex(session, codexBaseUrl, model) {
323
- await requestJson(codexBaseUrl.replace(/\/+$/, ""), "/responses", {
323
+ const response = await fetch(`${codexBaseUrl.replace(/\/+$/, "")}/responses`, {
324
324
  method: "POST",
325
- token: session.token,
325
+ headers: {
326
+ "content-type": "application/json",
327
+ authorization: `Bearer ${session.token}`,
328
+ // The Responses ingress only accepts the native Codex request shape.
329
+ // Keep this synthetic compatibility check aligned with the real client
330
+ // so it exercises the same authorization and routing path.
331
+ originator: "codex_cli_rs",
332
+ },
326
333
  body: JSON.stringify({
327
334
  model,
328
335
  instructions: "Reply with pong.",
@@ -331,16 +338,39 @@ async function checkCodex(session, codexBaseUrl, model) {
331
338
  tool_choice: "auto",
332
339
  parallel_tool_calls: true,
333
340
  store: false,
334
- stream: false,
341
+ // Safe Responses ingress deliberately requires streaming requests. A
342
+ // JSON/non-streaming probe is rejected before routing, even though the
343
+ // same credential and model work in Codex itself.
344
+ stream: true,
335
345
  include: [],
346
+ client_metadata: {
347
+ session_id: "4yi-cli-preflight",
348
+ thread_id: "4yi-cli-preflight",
349
+ },
336
350
  }),
337
351
  });
352
+
353
+ if (!response.ok) {
354
+ const text = await response.text();
355
+ let body;
356
+ try { body = text ? JSON.parse(text) : null; } catch { body = null; }
357
+ const message = body?.error?.message || body?.error || text || `HTTP ${response.status}`;
358
+ const error = new Error(typeof message === "string" ? message : JSON.stringify(message));
359
+ error.status = response.status;
360
+ error.body = body;
361
+ throw error;
362
+ }
363
+
364
+ // A successful native probe is an SSE stream. Compatibility is established
365
+ // once the response starts; do not consume a model response just for setup.
366
+ if (response.body) await response.body.cancel();
338
367
  }
339
368
 
340
369
  async function connectCodex({ session, home, codexHome, codexBaseUrl, stdout, skipCheck = false, tooling = {} }) {
341
370
  const paths = connectionPaths({ home, codexHome });
342
371
  const { models, defaultModel } = await loadCodexModels(session);
343
372
  if (!skipCheck) await checkCodex(session, codexBaseUrl, defaultModel);
373
+ ensureDir(path.dirname(paths.codexConfig));
344
374
  const template = parseBundledCatalog(tooling);
345
375
  const catalog = buildCodexCatalog(models, template);
346
376
  atomicWrite(paths.codexCatalog, `${JSON.stringify(catalog, null, 2)}\n`);
@@ -437,6 +467,7 @@ export function restoreConnection({ target = "all", home = os.homedir(), stdout
437
467
 
438
468
  export const __testing = {
439
469
  buildCodexCatalog,
470
+ checkCodex,
440
471
  commandAvailable,
441
472
  desktopAppCandidates,
442
473
  ensureToolCli,