@ouro.bot/cli 0.1.0-alpha.13 → 0.1.0-alpha.131

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 (126) hide show
  1. package/AdoptionSpecialist.ouro/psyche/SOUL.md +2 -2
  2. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +2 -2
  3. package/README.md +147 -205
  4. package/changelog.json +814 -0
  5. package/dist/heart/active-work.js +622 -0
  6. package/dist/heart/bridges/manager.js +358 -0
  7. package/dist/heart/bridges/state-machine.js +135 -0
  8. package/dist/heart/bridges/store.js +123 -0
  9. package/dist/heart/commitments.js +105 -0
  10. package/dist/heart/config.js +66 -21
  11. package/dist/heart/core.js +518 -100
  12. package/dist/heart/cross-chat-delivery.js +146 -0
  13. package/dist/heart/daemon/agent-discovery.js +81 -0
  14. package/dist/heart/daemon/auth-flow.js +457 -0
  15. package/dist/heart/daemon/daemon-cli.js +1516 -195
  16. package/dist/heart/daemon/daemon-entry.js +43 -2
  17. package/dist/heart/daemon/daemon-runtime-sync.js +212 -0
  18. package/dist/heart/daemon/daemon.js +261 -1
  19. package/dist/heart/daemon/hatch-animation.js +10 -3
  20. package/dist/heart/daemon/hatch-flow.js +7 -72
  21. package/dist/heart/daemon/hooks/bundle-meta.js +92 -0
  22. package/dist/heart/daemon/launchd.js +159 -0
  23. package/dist/heart/daemon/log-tailer.js +4 -3
  24. package/dist/heart/daemon/message-router.js +17 -8
  25. package/dist/heart/daemon/ouro-bot-global-installer.js +128 -0
  26. package/dist/heart/daemon/ouro-path-installer.js +57 -29
  27. package/dist/heart/daemon/ouro-version-manager.js +171 -0
  28. package/dist/heart/daemon/process-manager.js +13 -0
  29. package/dist/heart/daemon/run-hooks.js +37 -0
  30. package/dist/heart/daemon/runtime-logging.js +58 -15
  31. package/dist/heart/daemon/runtime-metadata.js +219 -0
  32. package/dist/heart/daemon/runtime-mode.js +67 -0
  33. package/dist/heart/daemon/sense-manager.js +50 -2
  34. package/dist/heart/daemon/skill-management-installer.js +94 -0
  35. package/dist/heart/daemon/socket-client.js +202 -0
  36. package/dist/heart/daemon/specialist-orchestrator.js +2 -2
  37. package/dist/heart/daemon/specialist-prompt.js +7 -4
  38. package/dist/heart/daemon/specialist-tools.js +52 -3
  39. package/dist/heart/daemon/staged-restart.js +114 -0
  40. package/dist/heart/daemon/thoughts.js +507 -0
  41. package/dist/heart/daemon/update-checker.js +111 -0
  42. package/dist/heart/daemon/update-hooks.js +138 -0
  43. package/dist/heart/daemon/wrapper-publish-guard.js +86 -0
  44. package/dist/heart/delegation.js +62 -0
  45. package/dist/heart/identity.js +64 -21
  46. package/dist/heart/kicks.js +1 -19
  47. package/dist/heart/model-capabilities.js +48 -0
  48. package/dist/heart/obligations.js +197 -0
  49. package/dist/heart/progress-story.js +42 -0
  50. package/dist/heart/provider-failover.js +88 -0
  51. package/dist/heart/provider-ping.js +159 -0
  52. package/dist/heart/providers/anthropic-token.js +163 -0
  53. package/dist/heart/providers/anthropic.js +195 -34
  54. package/dist/heart/providers/azure.js +115 -9
  55. package/dist/heart/providers/github-copilot.js +157 -0
  56. package/dist/heart/providers/minimax.js +33 -3
  57. package/dist/heart/providers/openai-codex.js +49 -14
  58. package/dist/heart/safe-workspace.js +381 -0
  59. package/dist/heart/session-activity.js +173 -0
  60. package/dist/heart/session-recall.js +216 -0
  61. package/dist/heart/streaming.js +108 -24
  62. package/dist/heart/target-resolution.js +123 -0
  63. package/dist/heart/tool-loop.js +194 -0
  64. package/dist/heart/turn-coordinator.js +28 -0
  65. package/dist/mind/associative-recall.js +14 -2
  66. package/dist/mind/bundle-manifest.js +12 -0
  67. package/dist/mind/context.js +60 -14
  68. package/dist/mind/first-impressions.js +16 -2
  69. package/dist/mind/friends/channel.js +35 -0
  70. package/dist/mind/friends/group-context.js +144 -0
  71. package/dist/mind/friends/store-file.js +19 -0
  72. package/dist/mind/friends/trust-explanation.js +74 -0
  73. package/dist/mind/friends/types.js +8 -0
  74. package/dist/mind/memory.js +27 -26
  75. package/dist/mind/obligation-steering.js +221 -0
  76. package/dist/mind/pending.js +76 -9
  77. package/dist/mind/phrases.js +1 -0
  78. package/dist/mind/prompt.js +456 -77
  79. package/dist/mind/token-estimate.js +8 -12
  80. package/dist/nerves/cli-logging.js +15 -2
  81. package/dist/nerves/coverage/run-artifacts.js +1 -1
  82. package/dist/nerves/index.js +12 -0
  83. package/dist/nerves/runtime.js +5 -1
  84. package/dist/repertoire/ado-client.js +4 -2
  85. package/dist/repertoire/coding/context-pack.js +254 -0
  86. package/dist/repertoire/coding/feedback.js +301 -0
  87. package/dist/repertoire/coding/index.js +4 -1
  88. package/dist/repertoire/coding/manager.js +210 -4
  89. package/dist/repertoire/coding/spawner.js +39 -9
  90. package/dist/repertoire/coding/tools.js +171 -4
  91. package/dist/repertoire/data/ado-endpoints.json +188 -0
  92. package/dist/repertoire/guardrails.js +290 -0
  93. package/dist/repertoire/mcp-client.js +254 -0
  94. package/dist/repertoire/mcp-manager.js +198 -0
  95. package/dist/repertoire/skills.js +3 -26
  96. package/dist/repertoire/tasks/board.js +12 -0
  97. package/dist/repertoire/tasks/index.js +23 -9
  98. package/dist/repertoire/tasks/transitions.js +1 -2
  99. package/dist/repertoire/tools-base.js +925 -250
  100. package/dist/repertoire/tools-bluebubbles.js +93 -0
  101. package/dist/repertoire/tools-teams.js +58 -25
  102. package/dist/repertoire/tools.js +106 -53
  103. package/dist/senses/bluebubbles-client.js +210 -5
  104. package/dist/senses/bluebubbles-entry.js +2 -0
  105. package/dist/senses/bluebubbles-inbound-log.js +109 -0
  106. package/dist/senses/bluebubbles-media.js +339 -0
  107. package/dist/senses/bluebubbles-model.js +12 -4
  108. package/dist/senses/bluebubbles-mutation-log.js +45 -5
  109. package/dist/senses/bluebubbles-runtime-state.js +109 -0
  110. package/dist/senses/bluebubbles-session-cleanup.js +72 -0
  111. package/dist/senses/bluebubbles.js +915 -45
  112. package/dist/senses/cli-layout.js +187 -0
  113. package/dist/senses/cli.js +374 -131
  114. package/dist/senses/continuity.js +94 -0
  115. package/dist/senses/debug-activity.js +154 -0
  116. package/dist/senses/inner-dialog-worker.js +47 -18
  117. package/dist/senses/inner-dialog.js +388 -83
  118. package/dist/senses/pipeline.js +444 -0
  119. package/dist/senses/teams.js +607 -129
  120. package/dist/senses/trust-gate.js +112 -2
  121. package/package.json +9 -3
  122. package/subagents/README.md +4 -70
  123. package/dist/heart/daemon/subagent-installer.js +0 -134
  124. package/subagents/work-doer.md +0 -233
  125. package/subagents/work-merger.md +0 -624
  126. package/subagents/work-planner.md +0 -373
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.classifyGithubCopilotError = classifyGithubCopilotError;
7
+ exports.createGithubCopilotProviderRuntime = createGithubCopilotProviderRuntime;
8
+ const openai_1 = __importDefault(require("openai"));
9
+ const config_1 = require("../config");
10
+ const runtime_1 = require("../../nerves/runtime");
11
+ const streaming_1 = require("../streaming");
12
+ const model_capabilities_1 = require("../model-capabilities");
13
+ /* v8 ignore start -- duplicated from shared provider utils, tested there @preserve */
14
+ function isNetworkError(error) {
15
+ const code = error.code || "";
16
+ if (["ECONNRESET", "ECONNREFUSED", "ENOTFOUND", "ETIMEDOUT", "EPIPE",
17
+ "EAI_AGAIN", "EHOSTUNREACH", "ENETUNREACH", "ECONNABORTED"].includes(code))
18
+ return true;
19
+ const msg = error.message || "";
20
+ return msg.includes("fetch failed") || msg.includes("socket hang up") || msg.includes("getaddrinfo");
21
+ }
22
+ /* v8 ignore stop */
23
+ /* v8 ignore start -- duplicated classification pattern, tested via provider unit tests @preserve */
24
+ function classifyGithubCopilotError(error) {
25
+ const status = error.status;
26
+ if (status === 401 || status === 403)
27
+ return "auth-failure";
28
+ if (status === 429)
29
+ return "rate-limit";
30
+ if (status && status >= 500)
31
+ return "server-error";
32
+ if (isNetworkError(error))
33
+ return "network-error";
34
+ return "unknown";
35
+ }
36
+ /* v8 ignore stop */
37
+ function createGithubCopilotProviderRuntime(injectedConfig) {
38
+ (0, runtime_1.emitNervesEvent)({
39
+ component: "engine",
40
+ event: "engine.provider_init",
41
+ message: "github-copilot provider init",
42
+ meta: { provider: "github-copilot" },
43
+ });
44
+ const config = injectedConfig ?? (0, config_1.getGithubCopilotConfig)();
45
+ if (!config.githubToken) {
46
+ throw new Error("provider 'github-copilot' is selected in agent.json but providers.github-copilot.githubToken is missing in secrets.json.");
47
+ }
48
+ if (!config.baseUrl) {
49
+ throw new Error("provider 'github-copilot' is selected in agent.json but providers.github-copilot.baseUrl is missing in secrets.json.");
50
+ }
51
+ const isCompletionsModel = config.model.startsWith("claude");
52
+ const modelCaps = (0, model_capabilities_1.getModelCapabilities)(config.model);
53
+ const capabilities = new Set();
54
+ /* v8 ignore next -- branch: capability detection tested via unit test @preserve */
55
+ if (modelCaps.reasoningEffort)
56
+ capabilities.add("reasoning-effort");
57
+ const client = new openai_1.default({
58
+ apiKey: config.githubToken,
59
+ baseURL: config.baseUrl,
60
+ timeout: 30000,
61
+ maxRetries: 0,
62
+ });
63
+ if (isCompletionsModel) {
64
+ // Chat completions path (Claude models via Copilot)
65
+ return {
66
+ id: "github-copilot",
67
+ model: config.model,
68
+ client,
69
+ capabilities,
70
+ supportedReasoningEfforts: modelCaps.reasoningEffort,
71
+ resetTurnState(_messages) {
72
+ // No provider-owned turn state for chat-completions path.
73
+ },
74
+ appendToolOutput(_callId, _output) {
75
+ // Chat-completions providers rely on canonical messages only.
76
+ },
77
+ /* v8 ignore start -- streamTurn: tested via mock assertions in github-copilot.test.ts @preserve */
78
+ async streamTurn(request) {
79
+ const params = {
80
+ messages: request.messages,
81
+ tools: request.activeTools,
82
+ stream: true,
83
+ };
84
+ if (this.model)
85
+ params.model = this.model;
86
+ if (request.traceId)
87
+ params.metadata = { trace_id: request.traceId };
88
+ if (request.toolChoiceRequired)
89
+ params.tool_choice = "required";
90
+ try {
91
+ return await (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal, request.eagerFinalAnswerStreaming);
92
+ }
93
+ catch (error) {
94
+ throw error instanceof Error ? error : new Error(String(error));
95
+ }
96
+ },
97
+ /* v8 ignore stop */
98
+ /* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
99
+ classifyError(error) {
100
+ return classifyGithubCopilotError(error);
101
+ },
102
+ };
103
+ }
104
+ // Responses API path (GPT models via Copilot)
105
+ let nativeInput = null;
106
+ let nativeInstructions = "";
107
+ return {
108
+ id: "github-copilot",
109
+ model: config.model,
110
+ client,
111
+ capabilities,
112
+ supportedReasoningEfforts: modelCaps.reasoningEffort,
113
+ /* v8 ignore start -- responses path: tested via mock assertions in github-copilot.test.ts @preserve */
114
+ resetTurnState(messages) {
115
+ const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
116
+ nativeInput = input;
117
+ nativeInstructions = instructions;
118
+ },
119
+ appendToolOutput(callId, output) {
120
+ if (!nativeInput)
121
+ return;
122
+ nativeInput.push({ type: "function_call_output", call_id: callId, output });
123
+ },
124
+ async streamTurn(request) {
125
+ if (!nativeInput)
126
+ this.resetTurnState(request.messages);
127
+ const params = {
128
+ model: this.model,
129
+ input: nativeInput,
130
+ instructions: nativeInstructions,
131
+ tools: (0, streaming_1.toResponsesTools)(request.activeTools),
132
+ reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
133
+ stream: true,
134
+ store: false,
135
+ include: ["reasoning.encrypted_content"],
136
+ };
137
+ if (request.traceId)
138
+ params.metadata = { trace_id: request.traceId };
139
+ if (request.toolChoiceRequired)
140
+ params.tool_choice = "required";
141
+ try {
142
+ const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerFinalAnswerStreaming);
143
+ for (const item of result.outputItems)
144
+ nativeInput.push(item);
145
+ return result;
146
+ }
147
+ catch (error) {
148
+ throw error instanceof Error ? error : new Error(String(error));
149
+ }
150
+ },
151
+ /* v8 ignore stop */
152
+ /* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
153
+ classifyError(error) {
154
+ return classifyGithubCopilotError(error);
155
+ },
156
+ };
157
+ }
@@ -3,22 +3,48 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.classifyMinimaxError = classifyMinimaxError;
6
7
  exports.createMinimaxProviderRuntime = createMinimaxProviderRuntime;
7
8
  const openai_1 = __importDefault(require("openai"));
8
9
  const config_1 = require("../config");
9
10
  const runtime_1 = require("../../nerves/runtime");
11
+ /* v8 ignore start -- shared network error utility, tested via classification tests @preserve */
12
+ function isNetworkError(error) {
13
+ const code = error.code || "";
14
+ if (["ECONNRESET", "ECONNREFUSED", "ENOTFOUND", "ETIMEDOUT", "EPIPE",
15
+ "EAI_AGAIN", "EHOSTUNREACH", "ENETUNREACH", "ECONNABORTED"].includes(code))
16
+ return true;
17
+ const msg = error.message || "";
18
+ return msg.includes("fetch failed") || msg.includes("socket hang up") || msg.includes("getaddrinfo");
19
+ }
20
+ /* v8 ignore stop */
21
+ function classifyMinimaxError(error) {
22
+ const status = error.status;
23
+ if (status === 401 || status === 403)
24
+ return "auth-failure";
25
+ if (status === 429)
26
+ return "rate-limit";
27
+ if (status && status >= 500)
28
+ return "server-error";
29
+ if (isNetworkError(error))
30
+ return "network-error";
31
+ return "unknown";
32
+ }
10
33
  const streaming_1 = require("../streaming");
11
- function createMinimaxProviderRuntime() {
34
+ const model_capabilities_1 = require("../model-capabilities");
35
+ function createMinimaxProviderRuntime(config) {
12
36
  (0, runtime_1.emitNervesEvent)({
13
37
  component: "engine",
14
38
  event: "engine.provider_init",
15
39
  message: "minimax provider init",
16
40
  meta: { provider: "minimax" },
17
41
  });
18
- const minimaxConfig = (0, config_1.getMinimaxConfig)();
42
+ const minimaxConfig = config ?? (0, config_1.getMinimaxConfig)();
19
43
  if (!minimaxConfig.apiKey) {
20
44
  throw new Error("provider 'minimax' is selected in agent.json but providers.minimax.apiKey is missing in secrets.json.");
21
45
  }
46
+ // Registry consulted; MiniMax models return empty defaults (no capabilities to derive)
47
+ (0, model_capabilities_1.getModelCapabilities)(minimaxConfig.model);
22
48
  const client = new openai_1.default({
23
49
  apiKey: minimaxConfig.apiKey,
24
50
  baseURL: "https://api.minimaxi.chat/v1",
@@ -29,6 +55,7 @@ function createMinimaxProviderRuntime() {
29
55
  id: "minimax",
30
56
  model: minimaxConfig.model,
31
57
  client,
58
+ capabilities: new Set(),
32
59
  resetTurnState(_messages) {
33
60
  // No provider-owned turn state for chat-completions providers.
34
61
  },
@@ -47,7 +74,10 @@ function createMinimaxProviderRuntime() {
47
74
  params.metadata = { trace_id: request.traceId };
48
75
  if (request.toolChoiceRequired)
49
76
  params.tool_choice = "required";
50
- return (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal);
77
+ return (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal, request.eagerFinalAnswerStreaming);
78
+ },
79
+ classifyError(error) {
80
+ return classifyMinimaxError(error);
51
81
  },
52
82
  };
53
83
  }
@@ -3,12 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.classifyOpenAICodexError = classifyOpenAICodexError;
6
7
  exports.createOpenAICodexProviderRuntime = createOpenAICodexProviderRuntime;
7
8
  const openai_1 = __importDefault(require("openai"));
8
9
  const config_1 = require("../config");
9
10
  const identity_1 = require("../identity");
10
11
  const runtime_1 = require("../../nerves/runtime");
11
12
  const streaming_1 = require("../streaming");
13
+ const model_capabilities_1 = require("../model-capabilities");
12
14
  const OPENAI_CODEX_AUTH_FAILURE_MARKERS = [
13
15
  "authentication failed",
14
16
  "unauthorized",
@@ -27,11 +29,11 @@ function getOpenAICodexOAuthInstructions() {
27
29
  const agentName = getOpenAICodexAgentNameForGuidance();
28
30
  return [
29
31
  "Fix:",
30
- ` 1. Run \`npm run auth:openai-codex -- --agent ${agentName}\``,
31
- " (or run `codex login` and set the OAuth token manually)",
32
+ ` 1. Run \`ouro auth --agent ${agentName}\``,
32
33
  ` 2. Open ${getOpenAICodexSecretsPathForGuidance()}`,
33
34
  " 3. Confirm providers.openai-codex.oauthAccessToken is set",
34
35
  " 4. This provider uses chatgpt.com/backend-api/codex/responses (not api.openai.com/responses).",
36
+ " 5. After reauth, retry the failed ouro command or reconnect this session.",
35
37
  ].join("\n");
36
38
  }
37
39
  function getOpenAICodexReauthGuidance(reason) {
@@ -41,6 +43,33 @@ function getOpenAICodexReauthGuidance(reason) {
41
43
  getOpenAICodexOAuthInstructions(),
42
44
  ].join("\n");
43
45
  }
46
+ /* v8 ignore start -- shared network error utility, tested via classification tests @preserve */
47
+ function isNetworkError(error) {
48
+ const code = error.code || "";
49
+ if (["ECONNRESET", "ECONNREFUSED", "ENOTFOUND", "ETIMEDOUT", "EPIPE",
50
+ "EAI_AGAIN", "EHOSTUNREACH", "ENETUNREACH", "ECONNABORTED"].includes(code))
51
+ return true;
52
+ const msg = error.message || "";
53
+ return msg.includes("fetch failed") || msg.includes("socket hang up") || msg.includes("getaddrinfo");
54
+ }
55
+ /* v8 ignore stop */
56
+ function classifyOpenAICodexError(error) {
57
+ const status = error.status;
58
+ if (status === 401 || status === 403 || isOpenAICodexAuthFailure(error))
59
+ return "auth-failure";
60
+ if (status === 429) {
61
+ const lower = error.message.toLowerCase();
62
+ if (lower.includes("usage") || lower.includes("quota") || lower.includes("exceeded your"))
63
+ return "usage-limit";
64
+ return "rate-limit";
65
+ }
66
+ if (status && status >= 500)
67
+ return "server-error";
68
+ if (isNetworkError(error))
69
+ return "network-error";
70
+ return "unknown";
71
+ }
72
+ /* v8 ignore start -- auth detection: only called from classifyOpenAICodexError which always passes Error @preserve */
44
73
  function isOpenAICodexAuthFailure(error) {
45
74
  if (!(error instanceof Error))
46
75
  return false;
@@ -50,13 +79,7 @@ function isOpenAICodexAuthFailure(error) {
50
79
  const lower = error.message.toLowerCase();
51
80
  return OPENAI_CODEX_AUTH_FAILURE_MARKERS.some((marker) => lower.includes(marker));
52
81
  }
53
- function withOpenAICodexAuthGuidance(error) {
54
- const base = error instanceof Error ? error.message : String(error);
55
- if (isOpenAICodexAuthFailure(error)) {
56
- return new Error(getOpenAICodexReauthGuidance(`OpenAI Codex authentication failed (${base}).`));
57
- }
58
- return error instanceof Error ? error : new Error(String(error));
59
- }
82
+ /* v8 ignore stop */
60
83
  function decodeJwtPayload(token) {
61
84
  const parts = token.split(".");
62
85
  if (parts.length < 2)
@@ -87,14 +110,14 @@ function getChatGPTAccountIdFromToken(token) {
87
110
  return "";
88
111
  return accountId.trim();
89
112
  }
90
- function createOpenAICodexProviderRuntime() {
113
+ function createOpenAICodexProviderRuntime(config) {
91
114
  (0, runtime_1.emitNervesEvent)({
92
115
  component: "engine",
93
116
  event: "engine.provider_init",
94
117
  message: "openai-codex provider init",
95
118
  meta: { provider: "openai-codex" },
96
119
  });
97
- const codexConfig = (0, config_1.getOpenAICodexConfig)();
120
+ const codexConfig = config ?? (0, config_1.getOpenAICodexConfig)();
98
121
  if (!(codexConfig.model && codexConfig.oauthAccessToken)) {
99
122
  throw new Error(getOpenAICodexReauthGuidance("provider 'openai-codex' is selected in agent.json but providers.openai-codex.model/oauthAccessToken is incomplete in secrets.json."));
100
123
  }
@@ -106,6 +129,12 @@ function createOpenAICodexProviderRuntime() {
106
129
  if (!chatgptAccountId) {
107
130
  throw new Error(getOpenAICodexReauthGuidance("OpenAI Codex OAuth access token is missing a chatgpt_account_id claim required for chatgpt.com/backend-api/codex."));
108
131
  }
132
+ const modelCaps = (0, model_capabilities_1.getModelCapabilities)(codexConfig.model);
133
+ const capabilities = new Set();
134
+ if (modelCaps.reasoningEffort)
135
+ capabilities.add("reasoning-effort");
136
+ if (modelCaps.phase)
137
+ capabilities.add("phase-annotation");
109
138
  const client = new openai_1.default({
110
139
  apiKey: token,
111
140
  baseURL: OPENAI_CODEX_BACKEND_BASE_URL,
@@ -123,6 +152,8 @@ function createOpenAICodexProviderRuntime() {
123
152
  id: "openai-codex",
124
153
  model: codexConfig.model,
125
154
  client,
155
+ capabilities,
156
+ supportedReasoningEfforts: modelCaps.reasoningEffort,
126
157
  resetTurnState(messages) {
127
158
  const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
128
159
  nativeInput = input;
@@ -141,7 +172,7 @@ function createOpenAICodexProviderRuntime() {
141
172
  input: nativeInput,
142
173
  instructions: nativeInstructions,
143
174
  tools: (0, streaming_1.toResponsesTools)(request.activeTools),
144
- reasoning: { effort: "medium", summary: "detailed" },
175
+ reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
145
176
  stream: true,
146
177
  store: false,
147
178
  include: ["reasoning.encrypted_content"],
@@ -149,14 +180,18 @@ function createOpenAICodexProviderRuntime() {
149
180
  if (request.toolChoiceRequired)
150
181
  params.tool_choice = "required";
151
182
  try {
152
- const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal);
183
+ const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerFinalAnswerStreaming);
153
184
  for (const item of result.outputItems)
154
185
  nativeInput.push(item);
155
186
  return result;
156
187
  }
157
188
  catch (error) {
158
- throw withOpenAICodexAuthGuidance(error);
189
+ throw error instanceof Error ? error : new Error(String(error));
159
190
  }
160
191
  },
192
+ /* v8 ignore next 3 -- delegation: classification logic tested via classifyOpenAICodexError @preserve */
193
+ classifyError(error) {
194
+ return classifyOpenAICodexError(error);
195
+ },
161
196
  };
162
197
  }