@ouro.bot/cli 0.1.0-alpha.35 → 0.1.0-alpha.351
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 +188 -187
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/changelog.json +2098 -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/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +832 -0
- package/dist/heart/agent-entry.js +37 -2
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/adapter.js +2 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +463 -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/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +53 -21
- package/dist/heart/core.js +744 -252
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +561 -0
- package/dist/heart/daemon/agent-discovery.js +79 -3
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/agentic-repair.js +170 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +591 -0
- package/dist/heart/daemon/cli-exec.js +2633 -0
- package/dist/heart/daemon/cli-help.js +306 -0
- package/dist/heart/daemon/cli-parse.js +913 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +512 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/daemon-cli.js +30 -1171
- package/dist/heart/daemon/daemon-entry.js +358 -3
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +157 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +751 -58
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +465 -0
- package/dist/heart/daemon/health-monitor.js +79 -1
- 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/http-health-probe.js +80 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +91 -0
- package/dist/heart/daemon/launchd.js +46 -9
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +105 -0
- 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 +201 -0
- package/dist/heart/daemon/provider-discovery.js +105 -0
- package/dist/heart/daemon/pulse.js +463 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +67 -16
- 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 +307 -0
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +237 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/thoughts.js +510 -0
- package/dist/heart/daemon/up-progress.js +135 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +181 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-scheduler.js +371 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -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 +56 -10
- package/dist/heart/identity.js +154 -59
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +127 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http-hooks.js +64 -0
- package/dist/heart/outlook/outlook-http-response.js +7 -0
- package/dist/heart/outlook/outlook-http-routes.js +232 -0
- package/dist/heart/outlook/outlook-http-static.js +99 -0
- package/dist/heart/outlook/outlook-http-transport.js +116 -0
- package/dist/heart/outlook/outlook-http.js +99 -0
- package/dist/heart/outlook/outlook-read.js +28 -0
- package/dist/heart/outlook/outlook-types.js +27 -0
- package/dist/heart/outlook/outlook-view.js +194 -0
- package/dist/heart/outlook/readers/agent-machine.js +355 -0
- package/dist/heart/outlook/readers/continuity-readers.js +332 -0
- package/dist/heart/outlook/readers/runtime-readers.js +660 -0
- package/dist/heart/outlook/readers/sessions.js +231 -0
- package/dist/heart/outlook/readers/shared.js +111 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-attempt.js +133 -0
- package/dist/heart/provider-binding-resolver.js +240 -0
- package/dist/heart/provider-credential-pool.js +395 -0
- package/dist/heart/provider-failover.js +135 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +258 -0
- package/dist/heart/provider-state.js +208 -0
- package/dist/heart/providers/anthropic-token.js +163 -0
- package/dist/heart/providers/anthropic.js +171 -50
- package/dist/heart/providers/azure.js +97 -11
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +135 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +23 -6
- package/dist/heart/providers/openai-codex.js +33 -23
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +727 -0
- package/dist/heart/session-transcript.js +162 -0
- package/dist/heart/start-of-turn-packet.js +341 -0
- package/dist/heart/streaming.js +36 -27
- package/dist/heart/sync.js +332 -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-friction.js +55 -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/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +296 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +140 -94
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +84 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +14 -1
- package/dist/mind/friends/channel.js +56 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +38 -1
- package/dist/mind/friends/store-file.js +58 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +9 -1
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +74 -7
- package/dist/mind/prompt.js +1001 -112
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/file-completeness.js +83 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
- package/dist/outlook-ui/assets/index-xTdv64BV.js +61 -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/bundle-templates.js +72 -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 +158 -9
- 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 +527 -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 +375 -0
- package/dist/repertoire/mcp-client.js +255 -0
- package/dist/repertoire/mcp-manager.js +305 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- 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 +16 -79
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +316 -0
- package/dist/repertoire/tools-base.js +45 -771
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +141 -0
- package/dist/repertoire/tools-bundle.js +984 -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 +105 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-notes.js +376 -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 +144 -138
- 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 +116 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +225 -9
- package/dist/senses/bluebubbles/entry.js +13 -0
- package/dist/senses/bluebubbles/inbound-log.js +113 -0
- package/dist/senses/bluebubbles/index.js +1616 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/replay.js +129 -0
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +605 -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 +240 -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 +603 -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 +633 -86
- package/dist/senses/pipeline.js +567 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +199 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams.js +690 -160
- package/dist/senses/trust-gate.js +112 -2
- package/package.json +29 -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/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -134
- package/dist/mind/associative-recall.js +0 -197
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles.js +0 -548
- package/dist/senses/debug-activity.js +0 -127
- 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-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}/wrapper-publish-guard.js +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
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.needsRefresh = needsRefresh;
|
|
37
|
+
exports.refreshAnthropicToken = refreshAnthropicToken;
|
|
38
|
+
exports.persistTokenState = persistTokenState;
|
|
39
|
+
exports.ensureFreshToken = ensureFreshToken;
|
|
40
|
+
/* v8 ignore start -- OAuth token lifecycle: requires live API calls, tested via integration @preserve */
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
43
|
+
const identity_1 = require("../identity");
|
|
44
|
+
const OAUTH_TOKEN_ENDPOINT = "https://console.anthropic.com/v1/oauth/token";
|
|
45
|
+
const OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
46
|
+
const REFRESH_MARGIN_MS = 5 * 60 * 1000; // refresh 5 minutes before expiry
|
|
47
|
+
/**
|
|
48
|
+
* Check if the Anthropic OAuth token needs refreshing.
|
|
49
|
+
* Returns true if no expiresAt is set (legacy token) or if within 5 min of expiry.
|
|
50
|
+
*/
|
|
51
|
+
function needsRefresh(expiresAt) {
|
|
52
|
+
if (!expiresAt)
|
|
53
|
+
return true; // legacy token with no expiry — always try refresh
|
|
54
|
+
return Date.now() > expiresAt - REFRESH_MARGIN_MS;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Refresh an Anthropic OAuth access token using the refresh token.
|
|
58
|
+
* Returns the new token state or null if refresh fails.
|
|
59
|
+
*/
|
|
60
|
+
async function refreshAnthropicToken(refreshToken, fetchImpl = fetch) {
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetchImpl(OAUTH_TOKEN_ENDPOINT, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { "Content-Type": "application/json" },
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
grant_type: "refresh_token",
|
|
67
|
+
refresh_token: refreshToken,
|
|
68
|
+
client_id: OAUTH_CLIENT_ID,
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
(0, runtime_1.emitNervesEvent)({
|
|
73
|
+
level: "warn",
|
|
74
|
+
component: "engine",
|
|
75
|
+
event: "engine.anthropic_token_refresh_failed",
|
|
76
|
+
message: `token refresh failed: ${response.status}`,
|
|
77
|
+
meta: { status: response.status },
|
|
78
|
+
});
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const json = await response.json();
|
|
82
|
+
if (!json.access_token) {
|
|
83
|
+
(0, runtime_1.emitNervesEvent)({
|
|
84
|
+
level: "warn",
|
|
85
|
+
component: "engine",
|
|
86
|
+
event: "engine.anthropic_token_refresh_failed",
|
|
87
|
+
message: "token refresh returned no access_token",
|
|
88
|
+
meta: {},
|
|
89
|
+
});
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const state = {
|
|
93
|
+
accessToken: json.access_token,
|
|
94
|
+
refreshToken: json.refresh_token ?? refreshToken, // keep old if not returned
|
|
95
|
+
expiresAt: Date.now() + (json.expires_in ?? 28800) * 1000, // default 8h
|
|
96
|
+
};
|
|
97
|
+
(0, runtime_1.emitNervesEvent)({
|
|
98
|
+
component: "engine",
|
|
99
|
+
event: "engine.anthropic_token_refreshed",
|
|
100
|
+
message: "anthropic OAuth token refreshed",
|
|
101
|
+
meta: { expiresAt: new Date(state.expiresAt).toISOString() },
|
|
102
|
+
});
|
|
103
|
+
return state;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
(0, runtime_1.emitNervesEvent)({
|
|
107
|
+
level: "warn",
|
|
108
|
+
component: "engine",
|
|
109
|
+
event: "engine.anthropic_token_refresh_error",
|
|
110
|
+
message: "token refresh threw",
|
|
111
|
+
meta: { error: error instanceof Error ? error.message : String(error) },
|
|
112
|
+
});
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Persist refreshed token state back to secrets.json.
|
|
118
|
+
*/
|
|
119
|
+
function persistTokenState(agentName, state) {
|
|
120
|
+
try {
|
|
121
|
+
const secretsPath = (0, identity_1.getAgentSecretsPath)(agentName);
|
|
122
|
+
const raw = fs.readFileSync(secretsPath, "utf-8");
|
|
123
|
+
const secrets = JSON.parse(raw);
|
|
124
|
+
secrets.providers = secrets.providers ?? {};
|
|
125
|
+
secrets.providers.anthropic = secrets.providers.anthropic ?? {};
|
|
126
|
+
secrets.providers.anthropic.setupToken = state.accessToken;
|
|
127
|
+
secrets.providers.anthropic.refreshToken = state.refreshToken;
|
|
128
|
+
secrets.providers.anthropic.expiresAt = state.expiresAt;
|
|
129
|
+
fs.writeFileSync(secretsPath, JSON.stringify(secrets, null, 2) + "\n", "utf-8");
|
|
130
|
+
/* v8 ignore start -- defensive: persistence failure must not crash the provider @preserve */
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
(0, runtime_1.emitNervesEvent)({
|
|
134
|
+
level: "warn",
|
|
135
|
+
component: "engine",
|
|
136
|
+
event: "engine.anthropic_token_persist_error",
|
|
137
|
+
message: "failed to persist refreshed token",
|
|
138
|
+
meta: { error: error instanceof Error ? error.message : String(error) },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/* v8 ignore stop */
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Ensure the Anthropic token is fresh. If expired, refresh and persist.
|
|
145
|
+
* Returns the current valid access token, or null if refresh failed and
|
|
146
|
+
* the existing token is expired.
|
|
147
|
+
*/
|
|
148
|
+
async function ensureFreshToken(currentToken, refreshToken, expiresAt, agentName, fetchImpl) {
|
|
149
|
+
if (!needsRefresh(expiresAt)) {
|
|
150
|
+
return currentToken; // still fresh
|
|
151
|
+
}
|
|
152
|
+
if (!refreshToken) {
|
|
153
|
+
// No refresh token — use the current token as-is (may be expired)
|
|
154
|
+
return currentToken;
|
|
155
|
+
}
|
|
156
|
+
const newState = await refreshAnthropicToken(refreshToken, fetchImpl);
|
|
157
|
+
if (!newState) {
|
|
158
|
+
return currentToken; // refresh failed — try the old token
|
|
159
|
+
}
|
|
160
|
+
persistTokenState(agentName, newState);
|
|
161
|
+
return newState.accessToken;
|
|
162
|
+
}
|
|
163
|
+
/* v8 ignore stop */
|
|
@@ -1,14 +1,51 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.toAnthropicMessages = toAnthropicMessages;
|
|
40
|
+
exports.classifyAnthropicError = classifyAnthropicError;
|
|
6
41
|
exports.createAnthropicProviderRuntime = createAnthropicProviderRuntime;
|
|
7
42
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
43
|
const config_1 = require("../config");
|
|
9
44
|
const identity_1 = require("../identity");
|
|
10
45
|
const runtime_1 = require("../../nerves/runtime");
|
|
11
46
|
const streaming_1 = require("../streaming");
|
|
47
|
+
const model_capabilities_1 = require("../model-capabilities");
|
|
48
|
+
const error_classification_1 = require("./error-classification");
|
|
12
49
|
const ANTHROPIC_SETUP_TOKEN_PREFIX = "sk-ant-oat01-";
|
|
13
50
|
const ANTHROPIC_SETUP_TOKEN_MIN_LENGTH = 80;
|
|
14
51
|
const ANTHROPIC_OAUTH_BETA_HEADER = "claude-code-20250219,oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14,interleaved-thinking-2025-05-14";
|
|
@@ -22,10 +59,10 @@ function getAnthropicSetupTokenInstructions() {
|
|
|
22
59
|
const agentName = getAnthropicAgentNameForGuidance();
|
|
23
60
|
return [
|
|
24
61
|
"Fix:",
|
|
25
|
-
` 1. Run \`
|
|
26
|
-
" (or run `claude setup-token` and paste the token manually)",
|
|
62
|
+
` 1. Run \`ouro auth --agent ${agentName}\``,
|
|
27
63
|
` 2. Open ${getAnthropicSecretsPathForGuidance()}`,
|
|
28
64
|
" 3. Confirm providers.anthropic.setupToken is set",
|
|
65
|
+
" 4. After reauth, retry the failed ouro command or reconnect this session.",
|
|
29
66
|
].join("\n");
|
|
30
67
|
}
|
|
31
68
|
function getAnthropicReauthGuidance(reason) {
|
|
@@ -35,8 +72,7 @@ function getAnthropicReauthGuidance(reason) {
|
|
|
35
72
|
getAnthropicSetupTokenInstructions(),
|
|
36
73
|
].join("\n");
|
|
37
74
|
}
|
|
38
|
-
function resolveAnthropicSetupTokenCredential() {
|
|
39
|
-
const anthropicConfig = (0, config_1.getAnthropicConfig)();
|
|
75
|
+
function resolveAnthropicSetupTokenCredential(anthropicConfig = (0, config_1.getAnthropicConfig)()) {
|
|
40
76
|
const token = anthropicConfig.setupToken?.trim();
|
|
41
77
|
if (!token) {
|
|
42
78
|
throw new Error(getAnthropicReauthGuidance("Anthropic provider is selected but no setup-token credential was found."));
|
|
@@ -93,6 +129,18 @@ function toAnthropicMessages(messages) {
|
|
|
93
129
|
if (msg.role === "assistant") {
|
|
94
130
|
const assistant = msg;
|
|
95
131
|
const blocks = [];
|
|
132
|
+
// Restore thinking blocks before text/tool_use blocks
|
|
133
|
+
const thinkingBlocks = assistant._thinking_blocks;
|
|
134
|
+
if (thinkingBlocks) {
|
|
135
|
+
for (const tb of thinkingBlocks) {
|
|
136
|
+
if (tb.type === "thinking") {
|
|
137
|
+
blocks.push({ type: "thinking", thinking: tb.thinking, signature: tb.signature });
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
blocks.push({ type: "redacted_thinking", data: tb.data });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
96
144
|
const text = toAnthropicTextContent(assistant.content);
|
|
97
145
|
if (text) {
|
|
98
146
|
blocks.push({ type: "text", text });
|
|
@@ -173,53 +221,64 @@ function mergeAnthropicToolArguments(current, partial) {
|
|
|
173
221
|
}
|
|
174
222
|
return current + partial;
|
|
175
223
|
}
|
|
224
|
+
function classifyAnthropicError(error) {
|
|
225
|
+
return (0, error_classification_1.classifyHttpError)(error, {
|
|
226
|
+
isAuthFailure: isAnthropicAuthFailure,
|
|
227
|
+
isServerError: (e) => e.status === 529,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
176
230
|
function isAnthropicAuthFailure(error) {
|
|
177
|
-
if (!(error instanceof Error))
|
|
178
|
-
return false;
|
|
179
|
-
const status = error.status;
|
|
180
|
-
if (status === 401 || status === 403)
|
|
181
|
-
return true;
|
|
182
231
|
const lower = error.message.toLowerCase();
|
|
183
232
|
return (lower.includes("oauth authentication") ||
|
|
184
233
|
lower.includes("authentication failed") ||
|
|
185
234
|
lower.includes("unauthorized") ||
|
|
186
235
|
lower.includes("invalid api key"));
|
|
187
236
|
}
|
|
188
|
-
function withAnthropicAuthGuidance(error) {
|
|
189
|
-
const base = error instanceof Error ? error.message : String(error);
|
|
190
|
-
if (isAnthropicAuthFailure(error)) {
|
|
191
|
-
return new Error(getAnthropicReauthGuidance(`Anthropic authentication failed (${base}).`));
|
|
192
|
-
}
|
|
193
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
194
|
-
}
|
|
195
237
|
async function streamAnthropicMessages(client, model, request) {
|
|
196
238
|
const { system, messages } = toAnthropicMessages(request.messages);
|
|
197
239
|
const anthropicTools = toAnthropicTools(request.activeTools);
|
|
240
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
241
|
+
const maxTokens = modelCaps.maxOutputTokens ?? 16384;
|
|
198
242
|
const params = {
|
|
199
243
|
model,
|
|
200
|
-
max_tokens:
|
|
244
|
+
max_tokens: maxTokens,
|
|
201
245
|
messages,
|
|
202
246
|
stream: true,
|
|
247
|
+
thinking: { type: "adaptive" },
|
|
248
|
+
output_config: { effort: request.reasoningEffort ?? "medium" },
|
|
203
249
|
};
|
|
204
|
-
|
|
205
|
-
|
|
250
|
+
// The Anthropic API requires a Claude Code identification block in the system
|
|
251
|
+
// prompt when using OAuth setup tokens (sk-ant-oat01). Without it, Opus/Sonnet
|
|
252
|
+
// 4.6 requests are rejected with 400. This is the API's validation that the
|
|
253
|
+
// token is being used by a Claude Code client.
|
|
254
|
+
const claudeCodePreamble = { type: "text", text: "You are Claude Code, Anthropic's official CLI for Claude." };
|
|
255
|
+
if (system) {
|
|
256
|
+
params.system = [claudeCodePreamble, { type: "text", text: system }];
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
params.system = [claudeCodePreamble];
|
|
260
|
+
}
|
|
206
261
|
if (anthropicTools.length > 0)
|
|
207
262
|
params.tools = anthropicTools;
|
|
208
263
|
if (request.toolChoiceRequired && anthropicTools.length > 0) {
|
|
209
|
-
|
|
264
|
+
// Thinking (adaptive or enabled) only supports tool_choice "auto" or "none".
|
|
265
|
+
// "any" forces tool use which is incompatible with extended thinking.
|
|
266
|
+
params.tool_choice = params.thinking ? { type: "auto" } : /* v8 ignore next -- no-thinking path: thinking always set for 4.6 models @preserve */ { type: "any" };
|
|
210
267
|
}
|
|
211
268
|
let response;
|
|
212
269
|
try {
|
|
213
270
|
response = await client.messages.create(params, request.signal ? { signal: request.signal } : {});
|
|
214
271
|
}
|
|
215
272
|
catch (error) {
|
|
216
|
-
throw
|
|
273
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
217
274
|
}
|
|
218
275
|
let content = "";
|
|
219
276
|
let streamStarted = false;
|
|
220
277
|
let usage;
|
|
221
278
|
const toolCalls = new Map();
|
|
222
|
-
const
|
|
279
|
+
const thinkingBlocks = new Map();
|
|
280
|
+
const redactedBlocks = new Map();
|
|
281
|
+
const answerStreamer = new streaming_1.SettleStreamer(request.callbacks, request.eagerSettleStreaming);
|
|
223
282
|
try {
|
|
224
283
|
for await (const event of response) {
|
|
225
284
|
if (request.signal?.aborted)
|
|
@@ -227,8 +286,14 @@ async function streamAnthropicMessages(client, model, request) {
|
|
|
227
286
|
const eventType = String(event.type ?? "");
|
|
228
287
|
if (eventType === "content_block_start") {
|
|
229
288
|
const block = event.content_block;
|
|
230
|
-
|
|
231
|
-
|
|
289
|
+
const index = Number(event.index);
|
|
290
|
+
if (block?.type === "thinking") {
|
|
291
|
+
thinkingBlocks.set(index, { type: "thinking", thinking: "", signature: "" });
|
|
292
|
+
}
|
|
293
|
+
else if (block?.type === "redacted_thinking") {
|
|
294
|
+
redactedBlocks.set(index, { type: "redacted_thinking", data: String(block.data ?? "") });
|
|
295
|
+
}
|
|
296
|
+
else if (block?.type === "tool_use") {
|
|
232
297
|
const rawInput = block.input;
|
|
233
298
|
const input = rawInput && typeof rawInput === "object"
|
|
234
299
|
? JSON.stringify(rawInput)
|
|
@@ -239,9 +304,9 @@ async function streamAnthropicMessages(client, model, request) {
|
|
|
239
304
|
name,
|
|
240
305
|
arguments: input,
|
|
241
306
|
});
|
|
242
|
-
// Activate eager streaming for sole
|
|
243
|
-
/* v8 ignore next --
|
|
244
|
-
if (name === "
|
|
307
|
+
// Activate eager streaming for sole settle tool call
|
|
308
|
+
/* v8 ignore next -- settle streaming activation, tested via SettleStreamer unit tests @preserve */
|
|
309
|
+
if (name === "settle" && toolCalls.size === 1) {
|
|
245
310
|
answerStreamer.activate();
|
|
246
311
|
}
|
|
247
312
|
}
|
|
@@ -265,7 +330,19 @@ async function streamAnthropicMessages(client, model, request) {
|
|
|
265
330
|
request.callbacks.onModelStreamStart();
|
|
266
331
|
streamStarted = true;
|
|
267
332
|
}
|
|
268
|
-
|
|
333
|
+
const thinkingText = String(delta?.thinking ?? "");
|
|
334
|
+
request.callbacks.onReasoningChunk(thinkingText);
|
|
335
|
+
const thinkingIndex = Number(event.index);
|
|
336
|
+
const thinkingBlock = thinkingBlocks.get(thinkingIndex);
|
|
337
|
+
if (thinkingBlock)
|
|
338
|
+
thinkingBlock.thinking += thinkingText;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (deltaType === "signature_delta") {
|
|
342
|
+
const sigIndex = Number(event.index);
|
|
343
|
+
const sigBlock = thinkingBlocks.get(sigIndex);
|
|
344
|
+
if (sigBlock)
|
|
345
|
+
sigBlock.signature += String(delta?.signature ?? "");
|
|
269
346
|
continue;
|
|
270
347
|
}
|
|
271
348
|
if (deltaType === "input_json_delta") {
|
|
@@ -274,8 +351,8 @@ async function streamAnthropicMessages(client, model, request) {
|
|
|
274
351
|
if (existing) {
|
|
275
352
|
const partialJson = String(delta?.partial_json ?? "");
|
|
276
353
|
existing.arguments = mergeAnthropicToolArguments(existing.arguments, partialJson);
|
|
277
|
-
/* v8 ignore next --
|
|
278
|
-
if (existing.name === "
|
|
354
|
+
/* v8 ignore next -- settle delta streaming, tested via SettleStreamer unit tests @preserve */
|
|
355
|
+
if (existing.name === "settle" && toolCalls.size === 1) {
|
|
279
356
|
answerStreamer.processDelta(partialJson);
|
|
280
357
|
}
|
|
281
358
|
}
|
|
@@ -299,48 +376,92 @@ async function streamAnthropicMessages(client, model, request) {
|
|
|
299
376
|
}
|
|
300
377
|
}
|
|
301
378
|
catch (error) {
|
|
302
|
-
throw
|
|
379
|
+
throw error instanceof Error ? error : /* v8 ignore next -- defensive: stream errors are always Error @preserve */ new Error(String(error));
|
|
303
380
|
}
|
|
381
|
+
// Collect all thinking blocks (regular + redacted) sorted by index to preserve ordering
|
|
382
|
+
const allThinkingIndices = [...thinkingBlocks.keys(), ...redactedBlocks.keys()].sort((a, b) => a - b);
|
|
383
|
+
const outputItems = allThinkingIndices.map((idx) => {
|
|
384
|
+
const tb = thinkingBlocks.get(idx);
|
|
385
|
+
if (tb)
|
|
386
|
+
return tb;
|
|
387
|
+
return redactedBlocks.get(idx);
|
|
388
|
+
});
|
|
304
389
|
return {
|
|
305
390
|
content,
|
|
306
391
|
toolCalls: [...toolCalls.values()],
|
|
307
|
-
outputItems
|
|
392
|
+
outputItems,
|
|
308
393
|
usage,
|
|
309
|
-
|
|
394
|
+
settleStreamed: answerStreamer.streamed,
|
|
310
395
|
};
|
|
311
396
|
}
|
|
312
|
-
function createAnthropicProviderRuntime() {
|
|
397
|
+
function createAnthropicProviderRuntime(model, anthropicConfig = (0, config_1.getAnthropicConfig)()) {
|
|
313
398
|
(0, runtime_1.emitNervesEvent)({
|
|
314
399
|
component: "engine",
|
|
315
400
|
event: "engine.provider_init",
|
|
316
401
|
message: "anthropic provider init",
|
|
317
402
|
meta: { provider: "anthropic" },
|
|
318
403
|
});
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
throw new Error(getAnthropicReauthGuidance("provider 'anthropic' is selected in agent.json but providers.anthropic.model/setupToken is incomplete in secrets.json."));
|
|
404
|
+
if (!anthropicConfig.setupToken) {
|
|
405
|
+
throw new Error(getAnthropicReauthGuidance("provider 'anthropic' is selected in agent.json but providers.anthropic.setupToken is missing in secrets.json."));
|
|
322
406
|
}
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
407
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
408
|
+
const capabilities = new Set();
|
|
409
|
+
if (modelCaps.reasoningEffort)
|
|
410
|
+
capabilities.add("reasoning-effort");
|
|
411
|
+
const credential = resolveAnthropicSetupTokenCredential(anthropicConfig);
|
|
412
|
+
const refreshToken = anthropicConfig.refreshToken;
|
|
413
|
+
const expiresAt = anthropicConfig.expiresAt;
|
|
414
|
+
function createClient(token) {
|
|
415
|
+
return new sdk_1.default({
|
|
416
|
+
authToken: token,
|
|
417
|
+
maxRetries: 0,
|
|
418
|
+
defaultHeaders: {
|
|
419
|
+
"anthropic-beta": ANTHROPIC_OAUTH_BETA_HEADER,
|
|
420
|
+
"anthropic-dangerous-direct-browser-access": "true",
|
|
421
|
+
"user-agent": "claude-cli/2.1.2 (external, cli)",
|
|
422
|
+
"x-app": "cli",
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
let currentToken = credential.token;
|
|
427
|
+
let client = createClient(currentToken);
|
|
428
|
+
/* v8 ignore start -- token refresh: dynamic import + ensureFreshToken, tested via integration @preserve */
|
|
429
|
+
async function ensureClient() {
|
|
430
|
+
try {
|
|
431
|
+
const { ensureFreshToken } = await Promise.resolve().then(() => __importStar(require("./anthropic-token")));
|
|
432
|
+
const { getAgentName } = await Promise.resolve().then(() => __importStar(require("../identity")));
|
|
433
|
+
const freshToken = await ensureFreshToken(currentToken, refreshToken, expiresAt, getAgentName());
|
|
434
|
+
if (freshToken !== currentToken) {
|
|
435
|
+
currentToken = freshToken;
|
|
436
|
+
client = createClient(freshToken);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
// refresh failed — use existing client
|
|
441
|
+
}
|
|
442
|
+
return client;
|
|
443
|
+
}
|
|
444
|
+
/* v8 ignore stop */
|
|
332
445
|
return {
|
|
333
446
|
id: "anthropic",
|
|
334
|
-
model
|
|
335
|
-
client
|
|
447
|
+
model,
|
|
448
|
+
/* v8 ignore next -- getter: returns mutable client ref @preserve */
|
|
449
|
+
get client() { return client; },
|
|
450
|
+
capabilities,
|
|
451
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
336
452
|
resetTurnState(_messages) {
|
|
337
453
|
// Anthropic request payload is derived from canonical messages each turn.
|
|
338
454
|
},
|
|
339
455
|
appendToolOutput(_callId, _output) {
|
|
340
456
|
// Anthropic uses canonical messages for tool_result tracking.
|
|
341
457
|
},
|
|
342
|
-
streamTurn(request) {
|
|
343
|
-
|
|
458
|
+
async streamTurn(request) {
|
|
459
|
+
const freshClient = await ensureClient();
|
|
460
|
+
return streamAnthropicMessages(freshClient, model, request);
|
|
461
|
+
},
|
|
462
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyAnthropicError @preserve */
|
|
463
|
+
classifyError(error) {
|
|
464
|
+
return classifyAnthropicError(error);
|
|
344
465
|
},
|
|
345
466
|
};
|
|
346
467
|
}
|
|
@@ -1,35 +1,117 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.classifyAzureError = classifyAzureError;
|
|
37
|
+
exports.createAzureTokenProvider = createAzureTokenProvider;
|
|
3
38
|
exports.createAzureProviderRuntime = createAzureProviderRuntime;
|
|
4
39
|
const openai_1 = require("openai");
|
|
5
40
|
const config_1 = require("../config");
|
|
6
41
|
const runtime_1 = require("../../nerves/runtime");
|
|
7
42
|
const streaming_1 = require("../streaming");
|
|
8
|
-
|
|
43
|
+
const model_capabilities_1 = require("../model-capabilities");
|
|
44
|
+
const error_classification_1 = require("./error-classification");
|
|
45
|
+
const COGNITIVE_SERVICES_SCOPE = "https://cognitiveservices.azure.com/.default";
|
|
46
|
+
function classifyAzureError(error) {
|
|
47
|
+
return (0, error_classification_1.classifyHttpError)(error);
|
|
48
|
+
}
|
|
49
|
+
// @azure/identity is imported dynamically (below) rather than at the top level
|
|
50
|
+
// because it's a heavy package (~30+ transitive deps) and we only need it when
|
|
51
|
+
// using the managed-identity auth path. API-key users and other providers
|
|
52
|
+
// shouldn't pay the cold-start cost.
|
|
53
|
+
function createAzureTokenProvider(managedIdentityClientId) {
|
|
54
|
+
let credential = null;
|
|
55
|
+
return async () => {
|
|
56
|
+
try {
|
|
57
|
+
if (!credential) {
|
|
58
|
+
const { DefaultAzureCredential } = await Promise.resolve().then(() => __importStar(require("@azure/identity")));
|
|
59
|
+
const credentialOptions = managedIdentityClientId
|
|
60
|
+
? { managedIdentityClientId }
|
|
61
|
+
: undefined;
|
|
62
|
+
credential = new DefaultAzureCredential(credentialOptions);
|
|
63
|
+
}
|
|
64
|
+
const tokenResponse = await credential.getToken(COGNITIVE_SERVICES_SCOPE);
|
|
65
|
+
return tokenResponse.token;
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
69
|
+
throw new Error(`Azure OpenAI authentication failed: ${detail}\n` +
|
|
70
|
+
"To fix this, either:\n" +
|
|
71
|
+
" 1. Set providers.azure.apiKey in secrets.json, or\n" +
|
|
72
|
+
" 2. Run 'az login' to authenticate with your Azure account (for local dev), or\n" +
|
|
73
|
+
" 3. Attach a managed identity to your App Service and set providers.azure.managedIdentityClientId in secrets.json (for deployed environments)");
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createAzureProviderRuntime(model, azureConfig = (0, config_1.getAzureConfig)()) {
|
|
78
|
+
const useApiKey = !!azureConfig.apiKey;
|
|
79
|
+
const authMethod = useApiKey ? "key" : "managed-identity";
|
|
9
80
|
(0, runtime_1.emitNervesEvent)({
|
|
10
81
|
component: "engine",
|
|
11
82
|
event: "engine.provider_init",
|
|
12
83
|
message: "azure provider init",
|
|
13
|
-
meta: { provider: "azure" },
|
|
84
|
+
meta: { provider: "azure", authMethod },
|
|
14
85
|
});
|
|
15
|
-
|
|
16
|
-
if (!(azureConfig.apiKey && azureConfig.endpoint && azureConfig.deployment && azureConfig.modelName)) {
|
|
86
|
+
if (!(azureConfig.endpoint && azureConfig.deployment)) {
|
|
17
87
|
throw new Error("provider 'azure' is selected in agent.json but providers.azure is incomplete in secrets.json.");
|
|
18
88
|
}
|
|
19
|
-
const
|
|
20
|
-
|
|
89
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
90
|
+
const capabilities = new Set();
|
|
91
|
+
if (modelCaps.reasoningEffort)
|
|
92
|
+
capabilities.add("reasoning-effort");
|
|
93
|
+
const clientOptions = {
|
|
21
94
|
endpoint: azureConfig.endpoint.replace(/\/openai.*$/, ""),
|
|
22
95
|
deployment: azureConfig.deployment,
|
|
23
96
|
apiVersion: azureConfig.apiVersion,
|
|
24
|
-
timeout: 30000,
|
|
25
97
|
maxRetries: 0,
|
|
26
|
-
}
|
|
98
|
+
};
|
|
99
|
+
if (useApiKey) {
|
|
100
|
+
clientOptions.apiKey = azureConfig.apiKey;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const managedIdentityClientId = azureConfig.managedIdentityClientId || undefined;
|
|
104
|
+
clientOptions.azureADTokenProvider = createAzureTokenProvider(managedIdentityClientId);
|
|
105
|
+
}
|
|
106
|
+
const client = new openai_1.AzureOpenAI(clientOptions);
|
|
27
107
|
let nativeInput = null;
|
|
28
108
|
let nativeInstructions = "";
|
|
29
109
|
return {
|
|
30
110
|
id: "azure",
|
|
31
|
-
model
|
|
111
|
+
model,
|
|
32
112
|
client,
|
|
113
|
+
capabilities,
|
|
114
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
33
115
|
resetTurnState(messages) {
|
|
34
116
|
const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
|
|
35
117
|
nativeInput = input;
|
|
@@ -48,7 +130,7 @@ function createAzureProviderRuntime() {
|
|
|
48
130
|
input: nativeInput,
|
|
49
131
|
instructions: nativeInstructions,
|
|
50
132
|
tools: (0, streaming_1.toResponsesTools)(request.activeTools),
|
|
51
|
-
reasoning: { effort: "medium", summary: "detailed" },
|
|
133
|
+
reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
|
|
52
134
|
stream: true,
|
|
53
135
|
store: false,
|
|
54
136
|
include: ["reasoning.encrypted_content"],
|
|
@@ -57,10 +139,14 @@ function createAzureProviderRuntime() {
|
|
|
57
139
|
params.metadata = { trace_id: request.traceId };
|
|
58
140
|
if (request.toolChoiceRequired)
|
|
59
141
|
params.tool_choice = "required";
|
|
60
|
-
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal);
|
|
142
|
+
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
61
143
|
for (const item of result.outputItems)
|
|
62
144
|
nativeInput.push(item);
|
|
63
145
|
return result;
|
|
64
146
|
},
|
|
147
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyAzureError @preserve */
|
|
148
|
+
classifyError(error) {
|
|
149
|
+
return classifyAzureError(error);
|
|
150
|
+
},
|
|
65
151
|
};
|
|
66
152
|
}
|