@ouro.bot/cli 0.1.0-alpha.25 → 0.1.0-alpha.250
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 +187 -191
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
- package/changelog.json +1507 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/presence.js +185 -0
- package/dist/heart/active-work.js +832 -0
- package/dist/heart/agent-entry.js +37 -2
- package/dist/heart/auth/auth-flow.js +447 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +63 -30
- package/dist/heart/core.js +644 -196
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +149 -0
- package/dist/heart/daemon/agent-discovery.js +145 -0
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +557 -0
- package/dist/heart/daemon/cli-exec.js +1875 -0
- package/dist/heart/daemon/cli-parse.js +759 -0
- package/dist/heart/daemon/cli-render.js +464 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1179
- package/dist/heart/daemon/daemon-entry.js +202 -4
- package/dist/heart/daemon/daemon-health.js +136 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
- package/dist/heart/daemon/daemon-tombstone.js +123 -0
- package/dist/heart/daemon/daemon.js +491 -20
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/launchd.js +39 -8
- package/dist/heart/daemon/log-tailer.js +4 -3
- package/dist/heart/daemon/message-router.js +17 -8
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- package/dist/heart/daemon/ouro-bot-entry.js +1 -1
- package/dist/heart/daemon/process-manager.js +123 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +58 -15
- package/dist/heart/daemon/runtime-metadata.js +101 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +72 -3
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +202 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/thoughts.js +507 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +181 -0
- package/dist/heart/habits/habit-parser.js +119 -0
- package/dist/heart/habits/habit-scheduler.js +369 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
- package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
- package/dist/heart/identity.js +157 -55
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/mcp/mcp-server.js +651 -0
- package/dist/heart/migrate-config.js +127 -0
- package/dist/heart/model-capabilities.js +48 -0
- package/dist/heart/outlook/outlook-http.js +439 -0
- package/dist/heart/outlook/outlook-read.js +1618 -0
- package/dist/heart/outlook/outlook-render.js +1032 -0
- package/dist/heart/outlook/outlook-types.js +7 -0
- package/dist/heart/outlook/outlook-view.js +194 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-failover.js +88 -0
- package/dist/heart/provider-ping.js +162 -0
- package/dist/heart/providers/anthropic-token.js +163 -0
- package/dist/heart/providers/anthropic.js +169 -46
- package/dist/heart/providers/azure.js +98 -11
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +136 -0
- package/dist/heart/providers/minimax.js +15 -4
- package/dist/heart/providers/openai-codex.js +33 -22
- package/dist/heart/session-activity.js +172 -0
- package/dist/heart/session-recall.js +216 -0
- package/dist/heart/start-of-turn-packet.js +330 -0
- package/dist/heart/streaming.js +36 -27
- package/dist/heart/sync.js +277 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +358 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
- package/dist/heart/versioning/ouro-version-manager.js +171 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +30 -6
- package/dist/heart/{daemon → versioning}/update-checker.js +9 -1
- package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +41 -3
- package/dist/mind/associative-recall.js +126 -66
- package/dist/mind/bundle-manifest.js +8 -1
- package/dist/mind/context.js +125 -14
- package/dist/mind/{memory.js → diary.js} +68 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +56 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +37 -0
- package/dist/mind/friends/store-file.js +58 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +8 -0
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +76 -9
- package/dist/mind/phrases.js +1 -0
- package/dist/mind/prompt.js +762 -109
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/coverage/audit.js +1 -1
- package/dist/nerves/coverage/file-completeness.js +50 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +64 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
- package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
- package/dist/outlook-ui/index.html +15 -0
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +319 -0
- package/dist/repertoire/bw-installer.js +79 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +149 -2
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +515 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +369 -0
- package/dist/repertoire/mcp-client.js +255 -0
- package/dist/repertoire/mcp-manager.js +303 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +14 -23
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +28 -10
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +11 -28
- package/dist/repertoire/tools-base.js +43 -771
- package/dist/repertoire/tools-bluebubbles.js +94 -0
- package/dist/repertoire/tools-bridge.js +141 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +182 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +62 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-memory.js +347 -0
- package/dist/repertoire/tools-session.js +739 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +12 -62
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +110 -0
- package/dist/repertoire/tools.js +147 -130
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +118 -0
- package/dist/repertoire/vault-setup.js +241 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +97 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +109 -10
- package/dist/senses/bluebubbles/entry.js +13 -0
- package/dist/senses/bluebubbles/inbound-log.js +109 -0
- package/dist/senses/bluebubbles/index.js +1374 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +119 -24
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +13 -5
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +393 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +83 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +236 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +1 -1
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +550 -246
- package/dist/senses/commands.js +65 -1
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +112 -19
- package/dist/senses/inner-dialog.js +593 -85
- package/dist/senses/pipeline.js +552 -0
- package/dist/senses/shared-turn.js +199 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams.js +664 -165
- package/dist/senses/trust-gate.js +112 -2
- package/package.json +14 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +110 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +81 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/subagent-installer.js +0 -134
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles.js +0 -421
- package/dist/senses/debug-activity.js +0 -107
- package/subagents/README.md +0 -73
- package/subagents/work-doer.md +0 -235
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -382
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/update-hooks.js +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
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
|
+
const error_classification_1 = require("./error-classification");
|
|
14
|
+
function classifyGithubCopilotError(error) {
|
|
15
|
+
return (0, error_classification_1.classifyHttpError)(error);
|
|
16
|
+
}
|
|
17
|
+
function createGithubCopilotProviderRuntime(model) {
|
|
18
|
+
(0, runtime_1.emitNervesEvent)({
|
|
19
|
+
component: "engine",
|
|
20
|
+
event: "engine.provider_init",
|
|
21
|
+
message: "github-copilot provider init",
|
|
22
|
+
meta: { provider: "github-copilot" },
|
|
23
|
+
});
|
|
24
|
+
const config = (0, config_1.getGithubCopilotConfig)();
|
|
25
|
+
if (!config.githubToken) {
|
|
26
|
+
throw new Error("provider 'github-copilot' is selected in agent.json but providers.github-copilot.githubToken is missing in secrets.json.");
|
|
27
|
+
}
|
|
28
|
+
if (!config.baseUrl) {
|
|
29
|
+
throw new Error("provider 'github-copilot' is selected in agent.json but providers.github-copilot.baseUrl is missing in secrets.json.");
|
|
30
|
+
}
|
|
31
|
+
const isCompletionsModel = model.startsWith("claude");
|
|
32
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
33
|
+
const capabilities = new Set();
|
|
34
|
+
/* v8 ignore next -- branch: capability detection tested via unit test @preserve */
|
|
35
|
+
if (modelCaps.reasoningEffort)
|
|
36
|
+
capabilities.add("reasoning-effort");
|
|
37
|
+
const client = new openai_1.default({
|
|
38
|
+
apiKey: config.githubToken,
|
|
39
|
+
baseURL: config.baseUrl,
|
|
40
|
+
maxRetries: 0,
|
|
41
|
+
});
|
|
42
|
+
if (isCompletionsModel) {
|
|
43
|
+
// Chat completions path (Claude models via Copilot)
|
|
44
|
+
return {
|
|
45
|
+
id: "github-copilot",
|
|
46
|
+
model,
|
|
47
|
+
client,
|
|
48
|
+
capabilities,
|
|
49
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
50
|
+
resetTurnState(_messages) {
|
|
51
|
+
// No provider-owned turn state for chat-completions path.
|
|
52
|
+
},
|
|
53
|
+
appendToolOutput(_callId, _output) {
|
|
54
|
+
// Chat-completions providers rely on canonical messages only.
|
|
55
|
+
},
|
|
56
|
+
/* v8 ignore start -- streamTurn: tested via mock assertions in github-copilot.test.ts @preserve */
|
|
57
|
+
async streamTurn(request) {
|
|
58
|
+
const params = {
|
|
59
|
+
messages: request.messages,
|
|
60
|
+
tools: request.activeTools,
|
|
61
|
+
stream: true,
|
|
62
|
+
};
|
|
63
|
+
if (this.model)
|
|
64
|
+
params.model = this.model;
|
|
65
|
+
if (request.traceId)
|
|
66
|
+
params.metadata = { trace_id: request.traceId };
|
|
67
|
+
if (request.toolChoiceRequired)
|
|
68
|
+
params.tool_choice = "required";
|
|
69
|
+
try {
|
|
70
|
+
return await (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
/* v8 ignore stop */
|
|
77
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
|
|
78
|
+
classifyError(error) {
|
|
79
|
+
return classifyGithubCopilotError(error);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Responses API path (GPT models via Copilot)
|
|
84
|
+
let nativeInput = null;
|
|
85
|
+
let nativeInstructions = "";
|
|
86
|
+
return {
|
|
87
|
+
id: "github-copilot",
|
|
88
|
+
model,
|
|
89
|
+
client,
|
|
90
|
+
capabilities,
|
|
91
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
92
|
+
/* v8 ignore start -- responses path: tested via mock assertions in github-copilot.test.ts @preserve */
|
|
93
|
+
resetTurnState(messages) {
|
|
94
|
+
const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
|
|
95
|
+
nativeInput = input;
|
|
96
|
+
nativeInstructions = instructions;
|
|
97
|
+
},
|
|
98
|
+
appendToolOutput(callId, output) {
|
|
99
|
+
if (!nativeInput)
|
|
100
|
+
return;
|
|
101
|
+
nativeInput.push({ type: "function_call_output", call_id: callId, output });
|
|
102
|
+
},
|
|
103
|
+
async streamTurn(request) {
|
|
104
|
+
if (!nativeInput)
|
|
105
|
+
this.resetTurnState(request.messages);
|
|
106
|
+
const params = {
|
|
107
|
+
model: this.model,
|
|
108
|
+
input: nativeInput,
|
|
109
|
+
instructions: nativeInstructions,
|
|
110
|
+
tools: (0, streaming_1.toResponsesTools)(request.activeTools),
|
|
111
|
+
reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
|
|
112
|
+
stream: true,
|
|
113
|
+
store: false,
|
|
114
|
+
include: ["reasoning.encrypted_content"],
|
|
115
|
+
};
|
|
116
|
+
if (request.traceId)
|
|
117
|
+
params.metadata = { trace_id: request.traceId };
|
|
118
|
+
if (request.toolChoiceRequired)
|
|
119
|
+
params.tool_choice = "required";
|
|
120
|
+
try {
|
|
121
|
+
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
122
|
+
for (const item of result.outputItems)
|
|
123
|
+
nativeInput.push(item);
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
/* v8 ignore stop */
|
|
131
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
|
|
132
|
+
classifyError(error) {
|
|
133
|
+
return classifyGithubCopilotError(error);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -3,12 +3,18 @@ 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
|
+
const error_classification_1 = require("./error-classification");
|
|
12
|
+
function classifyMinimaxError(error) {
|
|
13
|
+
return (0, error_classification_1.classifyHttpError)(error);
|
|
14
|
+
}
|
|
10
15
|
const streaming_1 = require("../streaming");
|
|
11
|
-
|
|
16
|
+
const model_capabilities_1 = require("../model-capabilities");
|
|
17
|
+
function createMinimaxProviderRuntime(model) {
|
|
12
18
|
(0, runtime_1.emitNervesEvent)({
|
|
13
19
|
component: "engine",
|
|
14
20
|
event: "engine.provider_init",
|
|
@@ -19,16 +25,18 @@ function createMinimaxProviderRuntime() {
|
|
|
19
25
|
if (!minimaxConfig.apiKey) {
|
|
20
26
|
throw new Error("provider 'minimax' is selected in agent.json but providers.minimax.apiKey is missing in secrets.json.");
|
|
21
27
|
}
|
|
28
|
+
// Registry consulted; MiniMax models return empty defaults (no capabilities to derive)
|
|
29
|
+
(0, model_capabilities_1.getModelCapabilities)(model);
|
|
22
30
|
const client = new openai_1.default({
|
|
23
31
|
apiKey: minimaxConfig.apiKey,
|
|
24
32
|
baseURL: "https://api.minimaxi.chat/v1",
|
|
25
|
-
timeout: 30000,
|
|
26
33
|
maxRetries: 0,
|
|
27
34
|
});
|
|
28
35
|
return {
|
|
29
36
|
id: "minimax",
|
|
30
|
-
model
|
|
37
|
+
model,
|
|
31
38
|
client,
|
|
39
|
+
capabilities: new Set(),
|
|
32
40
|
resetTurnState(_messages) {
|
|
33
41
|
// No provider-owned turn state for chat-completions providers.
|
|
34
42
|
},
|
|
@@ -47,7 +55,10 @@ function createMinimaxProviderRuntime() {
|
|
|
47
55
|
params.metadata = { trace_id: request.traceId };
|
|
48
56
|
if (request.toolChoiceRequired)
|
|
49
57
|
params.tool_choice = "required";
|
|
50
|
-
return (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal);
|
|
58
|
+
return (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
59
|
+
},
|
|
60
|
+
classifyError(error) {
|
|
61
|
+
return classifyMinimaxError(error);
|
|
51
62
|
},
|
|
52
63
|
};
|
|
53
64
|
}
|
|
@@ -3,12 +3,15 @@ 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");
|
|
14
|
+
const error_classification_1 = require("./error-classification");
|
|
12
15
|
const OPENAI_CODEX_AUTH_FAILURE_MARKERS = [
|
|
13
16
|
"authentication failed",
|
|
14
17
|
"unauthorized",
|
|
@@ -27,11 +30,11 @@ function getOpenAICodexOAuthInstructions() {
|
|
|
27
30
|
const agentName = getOpenAICodexAgentNameForGuidance();
|
|
28
31
|
return [
|
|
29
32
|
"Fix:",
|
|
30
|
-
` 1. Run \`
|
|
31
|
-
" (or run `codex login` and set the OAuth token manually)",
|
|
33
|
+
` 1. Run \`ouro auth --agent ${agentName}\``,
|
|
32
34
|
` 2. Open ${getOpenAICodexSecretsPathForGuidance()}`,
|
|
33
35
|
" 3. Confirm providers.openai-codex.oauthAccessToken is set",
|
|
34
36
|
" 4. This provider uses chatgpt.com/backend-api/codex/responses (not api.openai.com/responses).",
|
|
37
|
+
" 5. After reauth, retry the failed ouro command or reconnect this session.",
|
|
35
38
|
].join("\n");
|
|
36
39
|
}
|
|
37
40
|
function getOpenAICodexReauthGuidance(reason) {
|
|
@@ -41,22 +44,19 @@ function getOpenAICodexReauthGuidance(reason) {
|
|
|
41
44
|
getOpenAICodexOAuthInstructions(),
|
|
42
45
|
].join("\n");
|
|
43
46
|
}
|
|
47
|
+
function classifyOpenAICodexError(error) {
|
|
48
|
+
return (0, error_classification_1.classifyHttpError)(error, {
|
|
49
|
+
isAuthFailure: isOpenAICodexAuthFailure,
|
|
50
|
+
isUsageLimit: (e) => {
|
|
51
|
+
const lower = e.message.toLowerCase();
|
|
52
|
+
return lower.includes("usage") || lower.includes("quota") || lower.includes("exceeded your");
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
44
56
|
function isOpenAICodexAuthFailure(error) {
|
|
45
|
-
if (!(error instanceof Error))
|
|
46
|
-
return false;
|
|
47
|
-
const status = error.status;
|
|
48
|
-
if (status === 401 || status === 403)
|
|
49
|
-
return true;
|
|
50
57
|
const lower = error.message.toLowerCase();
|
|
51
58
|
return OPENAI_CODEX_AUTH_FAILURE_MARKERS.some((marker) => lower.includes(marker));
|
|
52
59
|
}
|
|
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
|
-
}
|
|
60
60
|
function decodeJwtPayload(token) {
|
|
61
61
|
const parts = token.split(".");
|
|
62
62
|
if (parts.length < 2)
|
|
@@ -87,7 +87,7 @@ function getChatGPTAccountIdFromToken(token) {
|
|
|
87
87
|
return "";
|
|
88
88
|
return accountId.trim();
|
|
89
89
|
}
|
|
90
|
-
function createOpenAICodexProviderRuntime() {
|
|
90
|
+
function createOpenAICodexProviderRuntime(model) {
|
|
91
91
|
(0, runtime_1.emitNervesEvent)({
|
|
92
92
|
component: "engine",
|
|
93
93
|
event: "engine.provider_init",
|
|
@@ -95,8 +95,8 @@ function createOpenAICodexProviderRuntime() {
|
|
|
95
95
|
meta: { provider: "openai-codex" },
|
|
96
96
|
});
|
|
97
97
|
const codexConfig = (0, config_1.getOpenAICodexConfig)();
|
|
98
|
-
if (!
|
|
99
|
-
throw new Error(getOpenAICodexReauthGuidance("provider 'openai-codex' is selected in agent.json but providers.openai-codex.
|
|
98
|
+
if (!codexConfig.oauthAccessToken) {
|
|
99
|
+
throw new Error(getOpenAICodexReauthGuidance("provider 'openai-codex' is selected in agent.json but providers.openai-codex.oauthAccessToken is missing in secrets.json."));
|
|
100
100
|
}
|
|
101
101
|
const token = codexConfig.oauthAccessToken.trim();
|
|
102
102
|
if (!token) {
|
|
@@ -106,6 +106,12 @@ function createOpenAICodexProviderRuntime() {
|
|
|
106
106
|
if (!chatgptAccountId) {
|
|
107
107
|
throw new Error(getOpenAICodexReauthGuidance("OpenAI Codex OAuth access token is missing a chatgpt_account_id claim required for chatgpt.com/backend-api/codex."));
|
|
108
108
|
}
|
|
109
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
110
|
+
const capabilities = new Set();
|
|
111
|
+
if (modelCaps.reasoningEffort)
|
|
112
|
+
capabilities.add("reasoning-effort");
|
|
113
|
+
if (modelCaps.phase)
|
|
114
|
+
capabilities.add("phase-annotation");
|
|
109
115
|
const client = new openai_1.default({
|
|
110
116
|
apiKey: token,
|
|
111
117
|
baseURL: OPENAI_CODEX_BACKEND_BASE_URL,
|
|
@@ -114,15 +120,16 @@ function createOpenAICodexProviderRuntime() {
|
|
|
114
120
|
"OpenAI-Beta": "responses=experimental",
|
|
115
121
|
originator: "ouroboros",
|
|
116
122
|
},
|
|
117
|
-
timeout: 30000,
|
|
118
123
|
maxRetries: 0,
|
|
119
124
|
});
|
|
120
125
|
let nativeInput = null;
|
|
121
126
|
let nativeInstructions = "";
|
|
122
127
|
return {
|
|
123
128
|
id: "openai-codex",
|
|
124
|
-
model
|
|
129
|
+
model,
|
|
125
130
|
client,
|
|
131
|
+
capabilities,
|
|
132
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
126
133
|
resetTurnState(messages) {
|
|
127
134
|
const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
|
|
128
135
|
nativeInput = input;
|
|
@@ -141,7 +148,7 @@ function createOpenAICodexProviderRuntime() {
|
|
|
141
148
|
input: nativeInput,
|
|
142
149
|
instructions: nativeInstructions,
|
|
143
150
|
tools: (0, streaming_1.toResponsesTools)(request.activeTools),
|
|
144
|
-
reasoning: { effort: "medium", summary: "detailed" },
|
|
151
|
+
reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
|
|
145
152
|
stream: true,
|
|
146
153
|
store: false,
|
|
147
154
|
include: ["reasoning.encrypted_content"],
|
|
@@ -149,14 +156,18 @@ function createOpenAICodexProviderRuntime() {
|
|
|
149
156
|
if (request.toolChoiceRequired)
|
|
150
157
|
params.tool_choice = "required";
|
|
151
158
|
try {
|
|
152
|
-
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal);
|
|
159
|
+
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
153
160
|
for (const item of result.outputItems)
|
|
154
161
|
nativeInput.push(item);
|
|
155
162
|
return result;
|
|
156
163
|
}
|
|
157
164
|
catch (error) {
|
|
158
|
-
throw
|
|
165
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
159
166
|
}
|
|
160
167
|
},
|
|
168
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyOpenAICodexError @preserve */
|
|
169
|
+
classifyError(error) {
|
|
170
|
+
return classifyOpenAICodexError(error);
|
|
171
|
+
},
|
|
161
172
|
};
|
|
162
173
|
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.listSessionActivity = listSessionActivity;
|
|
37
|
+
exports.findFreshestFriendSession = findFreshestFriendSession;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const runtime_1 = require("../nerves/runtime");
|
|
41
|
+
const config_1 = require("./config");
|
|
42
|
+
const DEFAULT_ACTIVE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
43
|
+
function activityPriority(source) {
|
|
44
|
+
return source === "friend-facing" ? 0 : 1;
|
|
45
|
+
}
|
|
46
|
+
function resolveFriendName(friendId, friendsDir, agentName) {
|
|
47
|
+
if (friendId === "self")
|
|
48
|
+
return agentName;
|
|
49
|
+
try {
|
|
50
|
+
const raw = fs.readFileSync(path.join(friendsDir, `${friendId}.json`), "utf-8");
|
|
51
|
+
const parsed = JSON.parse(raw);
|
|
52
|
+
return parsed.name ?? friendId;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return friendId;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parseFriendActivity(sessionPath) {
|
|
59
|
+
let mtimeMs;
|
|
60
|
+
try {
|
|
61
|
+
mtimeMs = fs.statSync(sessionPath).mtimeMs;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const raw = fs.readFileSync(sessionPath, "utf-8");
|
|
68
|
+
const parsed = JSON.parse(raw);
|
|
69
|
+
const explicit = parsed?.state?.lastFriendActivityAt;
|
|
70
|
+
if (typeof explicit === "string") {
|
|
71
|
+
const parsedMs = Date.parse(explicit);
|
|
72
|
+
if (Number.isFinite(parsedMs)) {
|
|
73
|
+
return {
|
|
74
|
+
lastActivityMs: parsedMs,
|
|
75
|
+
lastActivityAt: new Date(parsedMs).toISOString(),
|
|
76
|
+
activitySource: "friend-facing",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// fall back to file mtime below
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
lastActivityMs: mtimeMs,
|
|
86
|
+
lastActivityAt: new Date(mtimeMs).toISOString(),
|
|
87
|
+
activitySource: "mtime-fallback",
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function listSessionActivity(query) {
|
|
91
|
+
const { sessionsDir, friendsDir, agentName, activeThresholdMs = DEFAULT_ACTIVE_THRESHOLD_MS, nowMs = Date.now(), currentSession = null, } = query;
|
|
92
|
+
(0, runtime_1.emitNervesEvent)({
|
|
93
|
+
component: "daemon",
|
|
94
|
+
event: "daemon.session_activity_scan",
|
|
95
|
+
message: "scanning session activity",
|
|
96
|
+
meta: {
|
|
97
|
+
sessionsDir,
|
|
98
|
+
currentSession: currentSession ? `${currentSession.friendId}/${currentSession.channel}/${currentSession.key}` : null,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
if (!fs.existsSync(sessionsDir))
|
|
102
|
+
return [];
|
|
103
|
+
const results = [];
|
|
104
|
+
let friendDirs;
|
|
105
|
+
try {
|
|
106
|
+
friendDirs = fs.readdirSync(sessionsDir);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
for (const friendId of friendDirs) {
|
|
112
|
+
const friendPath = path.join(sessionsDir, friendId);
|
|
113
|
+
let channels;
|
|
114
|
+
try {
|
|
115
|
+
channels = fs.readdirSync(friendPath);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
for (const channel of channels) {
|
|
121
|
+
const channelPath = path.join(friendPath, channel);
|
|
122
|
+
let keys;
|
|
123
|
+
try {
|
|
124
|
+
keys = fs.readdirSync(channelPath);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
for (const keyFile of keys) {
|
|
130
|
+
if (!keyFile.endsWith(".json"))
|
|
131
|
+
continue;
|
|
132
|
+
const key = keyFile.replace(/\.json$/, "");
|
|
133
|
+
// Compare with sanitizeKey on both sides — session keys from the filesystem
|
|
134
|
+
// are already sanitized (colons → underscores), but the canonical key from
|
|
135
|
+
// the pipeline may still have colons (e.g. "chat:any" vs "chat_any").
|
|
136
|
+
if (currentSession && friendId === currentSession.friendId && channel === currentSession.channel && (0, config_1.sanitizeKey)(key) === (0, config_1.sanitizeKey)(currentSession.key)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const sessionPath = path.join(channelPath, keyFile);
|
|
140
|
+
const activity = parseFriendActivity(sessionPath);
|
|
141
|
+
if (!activity)
|
|
142
|
+
continue;
|
|
143
|
+
if (nowMs - activity.lastActivityMs > activeThresholdMs)
|
|
144
|
+
continue;
|
|
145
|
+
results.push({
|
|
146
|
+
friendId,
|
|
147
|
+
friendName: resolveFriendName(friendId, friendsDir, agentName),
|
|
148
|
+
channel,
|
|
149
|
+
key,
|
|
150
|
+
sessionPath,
|
|
151
|
+
lastActivityAt: activity.lastActivityAt,
|
|
152
|
+
lastActivityMs: activity.lastActivityMs,
|
|
153
|
+
activitySource: activity.activitySource,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return results.sort((a, b) => {
|
|
159
|
+
const sourceDiff = activityPriority(a.activitySource) - activityPriority(b.activitySource);
|
|
160
|
+
if (sourceDiff !== 0)
|
|
161
|
+
return sourceDiff;
|
|
162
|
+
return b.lastActivityMs - a.lastActivityMs;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function findFreshestFriendSession(query) {
|
|
166
|
+
const { activeOnly = false, activeThresholdMs = DEFAULT_ACTIVE_THRESHOLD_MS, nowMs, ...rest } = query;
|
|
167
|
+
const currentSession = rest.currentSession ?? null;
|
|
168
|
+
const all = activeOnly
|
|
169
|
+
? listSessionActivity({ ...rest, activeThresholdMs, nowMs, currentSession })
|
|
170
|
+
: listSessionActivity({ ...rest, activeThresholdMs: Number.MAX_SAFE_INTEGER, nowMs, currentSession });
|
|
171
|
+
return all.find((entry) => entry.friendId === query.friendId) ?? null;
|
|
172
|
+
}
|