@ouro.bot/cli 0.1.0-alpha.56 → 0.1.0-alpha.560
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 +127 -23
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/changelog.json +3596 -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 +837 -26
- package/dist/heart/agent-entry.js +58 -3
- 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 +479 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +114 -118
- package/dist/heart/core.js +913 -246
- package/dist/heart/cross-chat-delivery.js +3 -18
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +102 -3
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7457 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1592 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1698
- package/dist/heart/daemon/daemon-entry.js +387 -2
- package/dist/heart/daemon/daemon-health.js +176 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +796 -71
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +826 -0
- package/dist/heart/daemon/health-monitor.js +122 -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/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +375 -33
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/pulse.js +475 -0
- package/dist/heart/daemon/readiness-repair.js +365 -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 +3 -31
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +389 -38
- 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 +158 -11
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -17
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -1
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
- package/dist/heart/identity.js +203 -57
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +362 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +683 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +97 -13
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +13 -4
- package/dist/heart/session-activity.js +43 -22
- package/dist/heart/session-events.js +1149 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +44 -27
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +9 -5
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-description.js +139 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +389 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +426 -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 +6 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +674 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +720 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +430 -0
- package/dist/mailroom/mbox-import.js +383 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +233 -0
- package/dist/mailroom/search-cache.js +256 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +165 -101
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +62 -75
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +39 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/types.js +2 -2
- 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 +4 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1011 -123
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- 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/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +129 -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/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +152 -0
- package/dist/nerves/runtime.js +5 -1
- 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 +963 -0
- package/dist/repertoire/bundle-templates.js +72 -0
- package/dist/repertoire/bw-installer.js +180 -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 +178 -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 +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -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 +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- 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 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-base.js +47 -1075
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +142 -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 +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1857 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-session.js +750 -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 +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +108 -100
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -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/active-turns.js +216 -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} +219 -18
- package/dist/senses/bluebubbles/entry.js +77 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +2305 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- 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 +607 -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 +85 -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 +60 -8
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +520 -209
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +175 -21
- package/dist/senses/inner-dialog.js +330 -27
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +549 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +248 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +387 -98
- package/dist/senses/trust-gate.js +100 -5
- package/dist/senses/voice/elevenlabs.js +125 -0
- package/dist/senses/voice/index.js +22 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +85 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +133 -0
- package/dist/senses/voice-entry.js +80 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +38 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +101 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1177
- package/dist/senses/debug-activity.js +0 -148
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /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
|
@@ -1,39 +1,114 @@
|
|
|
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");
|
|
9
|
-
|
|
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. Run `ouro auth --agent <agent> --provider azure`, 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 store azure.managedIdentityClientId in the agent vault.");
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createAzureProviderRuntime(model, azureConfig = (0, config_1.getAzureConfig)()) {
|
|
78
|
+
const useApiKey = !!azureConfig.apiKey;
|
|
79
|
+
const authMethod = useApiKey ? "key" : "managed-identity";
|
|
10
80
|
(0, runtime_1.emitNervesEvent)({
|
|
11
81
|
component: "engine",
|
|
12
82
|
event: "engine.provider_init",
|
|
13
83
|
message: "azure provider init",
|
|
14
|
-
meta: { provider: "azure" },
|
|
84
|
+
meta: { provider: "azure", authMethod },
|
|
15
85
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
throw new Error("provider 'azure' is selected in agent.json but providers.azure is incomplete in secrets.json.");
|
|
86
|
+
if (!(azureConfig.endpoint && azureConfig.deployment)) {
|
|
87
|
+
throw new Error("provider 'azure' is selected but azure endpoint/deployment is incomplete in the agent vault. Run `ouro auth --agent <agent> --provider azure`.");
|
|
19
88
|
}
|
|
20
|
-
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(
|
|
89
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
21
90
|
const capabilities = new Set();
|
|
22
91
|
if (modelCaps.reasoningEffort)
|
|
23
92
|
capabilities.add("reasoning-effort");
|
|
24
|
-
const
|
|
25
|
-
apiKey: azureConfig.apiKey,
|
|
93
|
+
const clientOptions = {
|
|
26
94
|
endpoint: azureConfig.endpoint.replace(/\/openai.*$/, ""),
|
|
27
95
|
deployment: azureConfig.deployment,
|
|
28
96
|
apiVersion: azureConfig.apiVersion,
|
|
29
|
-
timeout: 30000,
|
|
30
97
|
maxRetries: 0,
|
|
31
|
-
}
|
|
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);
|
|
32
107
|
let nativeInput = null;
|
|
33
108
|
let nativeInstructions = "";
|
|
34
109
|
return {
|
|
35
110
|
id: "azure",
|
|
36
|
-
model
|
|
111
|
+
model,
|
|
37
112
|
client,
|
|
38
113
|
capabilities,
|
|
39
114
|
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
@@ -45,7 +120,7 @@ function createAzureProviderRuntime() {
|
|
|
45
120
|
appendToolOutput(callId, output) {
|
|
46
121
|
if (!nativeInput)
|
|
47
122
|
return;
|
|
48
|
-
nativeInput.push({ type: "function_call_output", call_id: callId, output });
|
|
123
|
+
nativeInput.push({ type: "function_call_output", call_id: callId, output: (0, streaming_1.truncateResponsesFunctionCallOutput)(output) });
|
|
49
124
|
},
|
|
50
125
|
async streamTurn(request) {
|
|
51
126
|
if (!nativeInput)
|
|
@@ -64,10 +139,19 @@ function createAzureProviderRuntime() {
|
|
|
64
139
|
params.metadata = { trace_id: request.traceId };
|
|
65
140
|
if (request.toolChoiceRequired)
|
|
66
141
|
params.tool_choice = "required";
|
|
67
|
-
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);
|
|
68
143
|
for (const item of result.outputItems)
|
|
69
144
|
nativeInput.push(item);
|
|
70
145
|
return result;
|
|
71
146
|
},
|
|
147
|
+
/* v8 ignore start -- ping: tested via provider-ping.test.ts @preserve */
|
|
148
|
+
async ping(signal) {
|
|
149
|
+
await this.client.responses.create({ model: this.model, input: "ping", max_output_tokens: 16 }, { signal });
|
|
150
|
+
},
|
|
151
|
+
/* v8 ignore stop */
|
|
152
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyAzureError @preserve */
|
|
153
|
+
classifyError(error) {
|
|
154
|
+
return classifyAzureError(error);
|
|
155
|
+
},
|
|
72
156
|
};
|
|
73
157
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isNetworkError = isNetworkError;
|
|
4
|
+
exports.classifyHttpError = classifyHttpError;
|
|
5
|
+
exports.extractProviderErrorDetails = extractProviderErrorDetails;
|
|
6
|
+
exports.summarizeProviderError = summarizeProviderError;
|
|
7
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
8
|
+
// Node socket / DNS error codes that indicate a transient network failure.
|
|
9
|
+
const NETWORK_ERROR_CODES = new Set([
|
|
10
|
+
"ECONNRESET",
|
|
11
|
+
"ECONNREFUSED",
|
|
12
|
+
"ENOTFOUND",
|
|
13
|
+
"ETIMEDOUT",
|
|
14
|
+
"EPIPE",
|
|
15
|
+
"EAI_AGAIN",
|
|
16
|
+
"EHOSTUNREACH",
|
|
17
|
+
"ENETUNREACH",
|
|
18
|
+
"ECONNABORTED",
|
|
19
|
+
]);
|
|
20
|
+
// Substrings the OpenAI/Anthropic SDKs use when wrapping fetch/socket failures
|
|
21
|
+
// into Error.message instead of an err.code.
|
|
22
|
+
const NETWORK_ERROR_MESSAGE_PATTERNS = [
|
|
23
|
+
"fetch failed",
|
|
24
|
+
"socket hang up",
|
|
25
|
+
"getaddrinfo",
|
|
26
|
+
"request timed out", // OpenAI SDK timeout — see SDK source
|
|
27
|
+
"request timeout",
|
|
28
|
+
"connection error",
|
|
29
|
+
];
|
|
30
|
+
// True if the error looks like a transient network issue (no HTTP status, just
|
|
31
|
+
// a socket/DNS/timeout failure from the underlying transport).
|
|
32
|
+
function isNetworkError(error) {
|
|
33
|
+
const code = error.code || "";
|
|
34
|
+
if (NETWORK_ERROR_CODES.has(code))
|
|
35
|
+
return true;
|
|
36
|
+
const msg = (error.message || "").toLowerCase();
|
|
37
|
+
return NETWORK_ERROR_MESSAGE_PATTERNS.some((pat) => msg.includes(pat));
|
|
38
|
+
}
|
|
39
|
+
// Standard HTTP error → ProviderErrorClassification mapping. Providers wrap
|
|
40
|
+
// this with their own overrides.
|
|
41
|
+
function classifyHttpError(error, overrides) {
|
|
42
|
+
const status = error.status;
|
|
43
|
+
if (overrides?.isAuthFailure?.(error) || status === 401 || status === 403) {
|
|
44
|
+
return "auth-failure";
|
|
45
|
+
}
|
|
46
|
+
if (status === 429) {
|
|
47
|
+
if (overrides?.isUsageLimit?.(error))
|
|
48
|
+
return "usage-limit";
|
|
49
|
+
return "rate-limit";
|
|
50
|
+
}
|
|
51
|
+
if (overrides?.isServerError?.(error) || (status !== undefined && status >= 500)) {
|
|
52
|
+
return "server-error";
|
|
53
|
+
}
|
|
54
|
+
if (isNetworkError(error))
|
|
55
|
+
return "network-error";
|
|
56
|
+
return "unknown";
|
|
57
|
+
}
|
|
58
|
+
// Pull HTTP status and a redacted body excerpt off a provider error if
|
|
59
|
+
// either is present. SDK shapes: OpenAI puts `status` on the error, body
|
|
60
|
+
// often on `error.error` or `error.response`. Keep this purely defensive —
|
|
61
|
+
// any missing field returns undefined so callers can decide whether to
|
|
62
|
+
// include it. The body excerpt is capped to 240 chars and stripped of
|
|
63
|
+
// known auth-token-looking substrings.
|
|
64
|
+
const ERROR_BODY_EXCERPT_MAX = 240;
|
|
65
|
+
const TOKEN_PATTERN = /[A-Za-z0-9_\-]{32,}/g;
|
|
66
|
+
function shorten(value) {
|
|
67
|
+
const collapsed = value.replace(/\s+/g, " ").trim();
|
|
68
|
+
if (collapsed.length === 0)
|
|
69
|
+
return "";
|
|
70
|
+
const redacted = collapsed.replace(TOKEN_PATTERN, "[redacted]");
|
|
71
|
+
return redacted.length > ERROR_BODY_EXCERPT_MAX
|
|
72
|
+
? `${redacted.slice(0, ERROR_BODY_EXCERPT_MAX - 3)}...`
|
|
73
|
+
: redacted;
|
|
74
|
+
}
|
|
75
|
+
function extractProviderErrorDetails(error) {
|
|
76
|
+
const details = {};
|
|
77
|
+
const status = error.status;
|
|
78
|
+
if (typeof status === "number" && Number.isFinite(status))
|
|
79
|
+
details.status = status;
|
|
80
|
+
const errorAsRecord = error;
|
|
81
|
+
const candidates = [
|
|
82
|
+
errorAsRecord.error,
|
|
83
|
+
errorAsRecord.response,
|
|
84
|
+
errorAsRecord.body,
|
|
85
|
+
error.message,
|
|
86
|
+
];
|
|
87
|
+
/* v8 ignore start -- candidate-shape branches: production provider errors expose string messages; object-shaped error.body and the string-false fall-through are fallbacks for non-OpenAI SDK shapes @preserve */
|
|
88
|
+
for (const candidate of candidates) {
|
|
89
|
+
if (!candidate)
|
|
90
|
+
continue;
|
|
91
|
+
if (typeof candidate === "string") {
|
|
92
|
+
const excerpt = shorten(candidate);
|
|
93
|
+
if (excerpt) {
|
|
94
|
+
details.bodyExcerpt = excerpt;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (typeof candidate === "object") {
|
|
99
|
+
try {
|
|
100
|
+
const excerpt = shorten(JSON.stringify(candidate));
|
|
101
|
+
if (excerpt) {
|
|
102
|
+
details.bodyExcerpt = excerpt;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Circular structure or otherwise unstringifyable; skip.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/* v8 ignore stop */
|
|
112
|
+
return details;
|
|
113
|
+
}
|
|
114
|
+
function summarizeProviderError(error, classification, providerId, model) {
|
|
115
|
+
const details = extractProviderErrorDetails(error);
|
|
116
|
+
const statusPart = details.status !== undefined ? ` HTTP ${details.status}` : "";
|
|
117
|
+
const excerptPart = details.bodyExcerpt ? ` — ${details.bodyExcerpt}` : "";
|
|
118
|
+
return `provider ${providerId}/${model}: ${classification}${statusPart}${excerptPart}`;
|
|
119
|
+
}
|
|
120
|
+
/* v8 ignore start — module-level observability event */
|
|
121
|
+
(0, runtime_1.emitNervesEvent)({
|
|
122
|
+
component: "engine",
|
|
123
|
+
event: "engine.error_classification_loaded",
|
|
124
|
+
message: "shared provider error classification loaded",
|
|
125
|
+
meta: {},
|
|
126
|
+
});
|
|
127
|
+
/* v8 ignore stop */
|
|
@@ -0,0 +1,145 @@
|
|
|
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, config = (0, config_1.getGithubCopilotConfig)()) {
|
|
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
|
+
if (!config.githubToken) {
|
|
25
|
+
throw new Error("provider 'github-copilot' is selected but github-copilot.githubToken is missing in the agent vault. Run `ouro auth --agent <agent> --provider github-copilot`.");
|
|
26
|
+
}
|
|
27
|
+
if (!config.baseUrl) {
|
|
28
|
+
throw new Error("provider 'github-copilot' is selected but github-copilot.baseUrl is missing in the agent vault. Run `ouro auth --agent <agent> --provider github-copilot`.");
|
|
29
|
+
}
|
|
30
|
+
const isCompletionsModel = model.startsWith("claude");
|
|
31
|
+
const modelCaps = (0, model_capabilities_1.getModelCapabilities)(model);
|
|
32
|
+
const capabilities = new Set();
|
|
33
|
+
/* v8 ignore next -- branch: capability detection tested via unit test @preserve */
|
|
34
|
+
if (modelCaps.reasoningEffort)
|
|
35
|
+
capabilities.add("reasoning-effort");
|
|
36
|
+
const client = new openai_1.default({
|
|
37
|
+
apiKey: config.githubToken,
|
|
38
|
+
baseURL: config.baseUrl,
|
|
39
|
+
maxRetries: 0,
|
|
40
|
+
});
|
|
41
|
+
if (isCompletionsModel) {
|
|
42
|
+
// Chat completions path (Claude models via Copilot)
|
|
43
|
+
return {
|
|
44
|
+
id: "github-copilot",
|
|
45
|
+
model,
|
|
46
|
+
client,
|
|
47
|
+
capabilities,
|
|
48
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
49
|
+
resetTurnState(_messages) {
|
|
50
|
+
// No provider-owned turn state for chat-completions path.
|
|
51
|
+
},
|
|
52
|
+
appendToolOutput(_callId, _output) {
|
|
53
|
+
// Chat-completions providers rely on canonical messages only.
|
|
54
|
+
},
|
|
55
|
+
/* v8 ignore start -- streamTurn: tested via mock assertions in github-copilot.test.ts @preserve */
|
|
56
|
+
async streamTurn(request) {
|
|
57
|
+
const params = {
|
|
58
|
+
messages: request.messages,
|
|
59
|
+
tools: request.activeTools,
|
|
60
|
+
stream: true,
|
|
61
|
+
};
|
|
62
|
+
if (this.model)
|
|
63
|
+
params.model = this.model;
|
|
64
|
+
if (request.traceId)
|
|
65
|
+
params.metadata = { trace_id: request.traceId };
|
|
66
|
+
if (request.toolChoiceRequired)
|
|
67
|
+
params.tool_choice = "required";
|
|
68
|
+
try {
|
|
69
|
+
return await (0, streaming_1.streamChatCompletion)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
/* v8 ignore stop */
|
|
76
|
+
/* v8 ignore start -- ping: tested via provider-ping.test.ts @preserve */
|
|
77
|
+
async ping(signal) {
|
|
78
|
+
await this.client.chat.completions.create({ model: this.model, max_tokens: 1, messages: [{ role: "user", content: "ping" }] }, { signal });
|
|
79
|
+
},
|
|
80
|
+
/* v8 ignore stop */
|
|
81
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
|
|
82
|
+
classifyError(error) {
|
|
83
|
+
return classifyGithubCopilotError(error);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Responses API path (GPT models via Copilot)
|
|
88
|
+
let nativeInput = null;
|
|
89
|
+
let nativeInstructions = "";
|
|
90
|
+
return {
|
|
91
|
+
id: "github-copilot",
|
|
92
|
+
model,
|
|
93
|
+
client,
|
|
94
|
+
capabilities,
|
|
95
|
+
supportedReasoningEfforts: modelCaps.reasoningEffort,
|
|
96
|
+
/* v8 ignore start -- responses path: tested via mock assertions in github-copilot.test.ts @preserve */
|
|
97
|
+
resetTurnState(messages) {
|
|
98
|
+
const { instructions, input } = (0, streaming_1.toResponsesInput)(messages);
|
|
99
|
+
nativeInput = input;
|
|
100
|
+
nativeInstructions = instructions;
|
|
101
|
+
},
|
|
102
|
+
appendToolOutput(callId, output) {
|
|
103
|
+
if (!nativeInput)
|
|
104
|
+
return;
|
|
105
|
+
nativeInput.push({ type: "function_call_output", call_id: callId, output: (0, streaming_1.truncateResponsesFunctionCallOutput)(output) });
|
|
106
|
+
},
|
|
107
|
+
async streamTurn(request) {
|
|
108
|
+
if (!nativeInput)
|
|
109
|
+
this.resetTurnState(request.messages);
|
|
110
|
+
const params = {
|
|
111
|
+
model: this.model,
|
|
112
|
+
input: nativeInput,
|
|
113
|
+
instructions: nativeInstructions,
|
|
114
|
+
tools: (0, streaming_1.toResponsesTools)(request.activeTools),
|
|
115
|
+
reasoning: { effort: request.reasoningEffort ?? "medium", summary: "detailed" },
|
|
116
|
+
stream: true,
|
|
117
|
+
store: false,
|
|
118
|
+
include: ["reasoning.encrypted_content"],
|
|
119
|
+
};
|
|
120
|
+
if (request.traceId)
|
|
121
|
+
params.metadata = { trace_id: request.traceId };
|
|
122
|
+
if (request.toolChoiceRequired)
|
|
123
|
+
params.tool_choice = "required";
|
|
124
|
+
try {
|
|
125
|
+
const result = await (0, streaming_1.streamResponsesApi)(this.client, params, request.callbacks, request.signal, request.eagerSettleStreaming);
|
|
126
|
+
for (const item of result.outputItems)
|
|
127
|
+
nativeInput.push(item);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
/* v8 ignore stop */
|
|
135
|
+
/* v8 ignore start -- ping: tested via provider-ping.test.ts @preserve */
|
|
136
|
+
async ping(signal) {
|
|
137
|
+
await this.client.responses.create({ model: this.model, input: "ping", max_output_tokens: 16 }, { signal });
|
|
138
|
+
},
|
|
139
|
+
/* v8 ignore stop */
|
|
140
|
+
/* v8 ignore next 3 -- delegation: classification logic tested via classifyGithubCopilotError @preserve */
|
|
141
|
+
classifyError(error) {
|
|
142
|
+
return classifyGithubCopilotError(error);
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.minimaxVlmDescribe = minimaxVlmDescribe;
|
|
4
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
5
|
+
const error_classification_1 = require("./error-classification");
|
|
6
|
+
// No default timeout — if the caller doesn't pass `timeoutMs`, we don't
|
|
7
|
+
// layer an AbortSignal on top of fetch, which means undici's own defaults
|
|
8
|
+
// (headersTimeout and bodyTimeout, both 5 minutes in the current Node) are
|
|
9
|
+
// the ceiling. That's the right ceiling: long enough to tolerate any
|
|
10
|
+
// legitimate MiniMax VLM slow window, short enough to eventually give up on
|
|
11
|
+
// a dead endpoint, and — unlike a number we picked — it's the stack's
|
|
12
|
+
// actual default rather than a harness-imposed fiction.
|
|
13
|
+
//
|
|
14
|
+
// Tests that want to exercise the timeout branch pass an explicit
|
|
15
|
+
// `timeoutMs`; production callers omit it and get undici's behavior.
|
|
16
|
+
//
|
|
17
|
+
// Same reasoning as PR #322 (dropped the 30s SDK timeout from the LLM
|
|
18
|
+
// providers): the harness shouldn't impose artificially tight request
|
|
19
|
+
// ceilings when the underlying stack already has correct defaults.
|
|
20
|
+
const MODEL_NAME = "minimax-vlm";
|
|
21
|
+
const SUPPORTED_DATA_URL_PATTERN = /^data:image\/(png|jpeg|webp);base64,/i;
|
|
22
|
+
function buildVlmUrl(baseURL) {
|
|
23
|
+
const stripped = baseURL.replace(/\/v1\/?$/, "").replace(/\/$/, "");
|
|
24
|
+
return `${stripped}/v1/coding_plan/vlm`;
|
|
25
|
+
}
|
|
26
|
+
function extractMimeType(imageDataUrl) {
|
|
27
|
+
const match = /^data:([^;,]+)[;,]/.exec(imageDataUrl);
|
|
28
|
+
return match?.[1]?.toLowerCase();
|
|
29
|
+
}
|
|
30
|
+
function emitStart(params) {
|
|
31
|
+
(0, runtime_1.emitNervesEvent)({
|
|
32
|
+
level: "warn",
|
|
33
|
+
component: "senses",
|
|
34
|
+
event: "senses.bluebubbles_vlm_describe_start",
|
|
35
|
+
message: "minimax vlm describe start",
|
|
36
|
+
meta: {
|
|
37
|
+
attachmentGuid: params.attachmentGuid,
|
|
38
|
+
mimeType: params.mimeType,
|
|
39
|
+
promptLength: params.prompt.length,
|
|
40
|
+
model: MODEL_NAME,
|
|
41
|
+
chatModel: params.chatModel,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function emitEnd(params, descriptionLength, latencyMs) {
|
|
46
|
+
(0, runtime_1.emitNervesEvent)({
|
|
47
|
+
level: "warn",
|
|
48
|
+
component: "senses",
|
|
49
|
+
event: "senses.bluebubbles_vlm_describe_end",
|
|
50
|
+
message: "minimax vlm describe end",
|
|
51
|
+
meta: {
|
|
52
|
+
attachmentGuid: params.attachmentGuid,
|
|
53
|
+
descriptionLength,
|
|
54
|
+
latencyMs,
|
|
55
|
+
model: MODEL_NAME,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function emitError(params, reason, status, traceId) {
|
|
60
|
+
(0, runtime_1.emitNervesEvent)({
|
|
61
|
+
level: "warn",
|
|
62
|
+
component: "senses",
|
|
63
|
+
event: "senses.bluebubbles_vlm_describe_error",
|
|
64
|
+
message: "minimax vlm describe error",
|
|
65
|
+
meta: {
|
|
66
|
+
attachmentGuid: params.attachmentGuid,
|
|
67
|
+
mimeType: params.mimeType,
|
|
68
|
+
model: MODEL_NAME,
|
|
69
|
+
reason,
|
|
70
|
+
status,
|
|
71
|
+
traceId,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function throwAndEmit(params, message, status, traceId) {
|
|
76
|
+
emitError(params, message, status, traceId);
|
|
77
|
+
const err = new Error(message);
|
|
78
|
+
if (status !== undefined)
|
|
79
|
+
err.status = status;
|
|
80
|
+
if (traceId)
|
|
81
|
+
err.traceId = traceId;
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
async function minimaxVlmDescribe(params) {
|
|
85
|
+
if (!params.apiKey) {
|
|
86
|
+
// We deliberately do NOT emit _start for param-validation errors — there's
|
|
87
|
+
// no meaningful "started a request" to pair with. Only the _error fires.
|
|
88
|
+
emitError(params, "minimax VLM: API key is empty — run `ouro auth --agent <agent> --provider minimax`");
|
|
89
|
+
throw new Error("minimax VLM: API key is empty — run `ouro auth --agent <agent> --provider minimax`");
|
|
90
|
+
}
|
|
91
|
+
if (!params.prompt) {
|
|
92
|
+
emitError(params, "minimax VLM: missing prompt — supply a targeted question (e.g. 'what's the flight number in the bottom-right?') and retry");
|
|
93
|
+
throw new Error("minimax VLM: missing prompt — supply a targeted question (e.g. 'what's the flight number in the bottom-right?') and retry");
|
|
94
|
+
}
|
|
95
|
+
if (!params.imageDataUrl) {
|
|
96
|
+
emitError(params, "minimax VLM: missing image data URL — verify the attachment downloaded OK or ask the user to resend the image");
|
|
97
|
+
throw new Error("minimax VLM: missing image data URL — verify the attachment downloaded OK or ask the user to resend the image");
|
|
98
|
+
}
|
|
99
|
+
if (!SUPPORTED_DATA_URL_PATTERN.test(params.imageDataUrl)) {
|
|
100
|
+
const mime = extractMimeType(params.imageDataUrl) ?? "unknown";
|
|
101
|
+
const msg = `minimax VLM: image must be a data:image/(png|jpeg|webp);base64,... URL but got ${mime} — ask the user to resend as a screenshot (png or jpeg)`;
|
|
102
|
+
emitError({ ...params, mimeType: params.mimeType ?? mime }, msg);
|
|
103
|
+
throw new Error(msg);
|
|
104
|
+
}
|
|
105
|
+
const fetchImpl = params.fetchImpl ?? fetch;
|
|
106
|
+
const url = buildVlmUrl(params.baseURL);
|
|
107
|
+
emitStart(params);
|
|
108
|
+
const startTs = Date.now();
|
|
109
|
+
// Only layer an AbortSignal if the caller explicitly asked for one.
|
|
110
|
+
// Omitting it lets undici's defaults (headersTimeout + bodyTimeout = 5min
|
|
111
|
+
// each in current Node) act as the ceiling — see the long comment on
|
|
112
|
+
// DEFAULT_TIMEOUT_MS above for the rationale.
|
|
113
|
+
const fetchOptions = {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: {
|
|
116
|
+
"Authorization": `Bearer ${params.apiKey}`,
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
"MM-API-Source": "Ouroboros",
|
|
119
|
+
},
|
|
120
|
+
body: JSON.stringify({
|
|
121
|
+
prompt: params.prompt,
|
|
122
|
+
image_url: params.imageDataUrl,
|
|
123
|
+
}),
|
|
124
|
+
};
|
|
125
|
+
if (typeof params.timeoutMs === "number" && params.timeoutMs > 0) {
|
|
126
|
+
fetchOptions.signal = AbortSignal.timeout(params.timeoutMs);
|
|
127
|
+
}
|
|
128
|
+
let response;
|
|
129
|
+
try {
|
|
130
|
+
response = await fetchImpl(url, fetchOptions);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const err = (error instanceof Error ? error : new Error(String(error)));
|
|
134
|
+
if (err.name === "AbortError" || err.name === "TimeoutError") {
|
|
135
|
+
const seconds = typeof params.timeoutMs === "number" ? Math.round(params.timeoutMs / 1000) : null;
|
|
136
|
+
const hint = seconds !== null
|
|
137
|
+
? `request timed out after ${seconds}s — retry or ask the user to resend the image`
|
|
138
|
+
: `request timed out (underlying stack default) — retry or ask the user to resend the image`;
|
|
139
|
+
throwAndEmit(params, `minimax VLM: ${hint}`);
|
|
140
|
+
}
|
|
141
|
+
if ((0, error_classification_1.isNetworkError)(err)) {
|
|
142
|
+
throwAndEmit(params, `minimax VLM: network error talking to the vlm endpoint (${err.message}) — retry in a moment`);
|
|
143
|
+
}
|
|
144
|
+
throwAndEmit(params, `minimax VLM: unexpected transport error (${err.message}) — retry, and if it persists surface 'image understanding is unavailable' to the user`);
|
|
145
|
+
}
|
|
146
|
+
const traceId = response.headers.get("Trace-Id") ?? response.headers.get("trace-id") ?? undefined;
|
|
147
|
+
const status = response.status;
|
|
148
|
+
if (status === 401 || status === 403) {
|
|
149
|
+
throwAndEmit(params, `minimax VLM: rejected credentials (HTTP ${status}) — the minimax key for this agent is invalid, re-run credential setup or rotate the key`, status, traceId);
|
|
150
|
+
}
|
|
151
|
+
if (status === 429) {
|
|
152
|
+
throwAndEmit(params, `minimax VLM: rate limited (HTTP 429) — wait and retry in a moment`, status, traceId);
|
|
153
|
+
}
|
|
154
|
+
if (status >= 500) {
|
|
155
|
+
throwAndEmit(params, `minimax VLM: server error (HTTP ${status}) — retry, and if it persists surface 'image understanding is unavailable' to the user`, status, traceId);
|
|
156
|
+
}
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
throwAndEmit(params, `minimax VLM: unexpected HTTP ${status} — retry, and if it persists surface 'image understanding is unavailable' to the user`, status, traceId);
|
|
159
|
+
}
|
|
160
|
+
let body;
|
|
161
|
+
try {
|
|
162
|
+
body = await response.json();
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
const err = error;
|
|
166
|
+
throwAndEmit(params, `minimax VLM: malformed response (not JSON: ${err.message}) — this is a provider bug, retry or surface 'image understanding is unavailable' to the user`, status, traceId);
|
|
167
|
+
}
|
|
168
|
+
const parsed = body;
|
|
169
|
+
const providerStatus = parsed?.base_resp?.status_code ?? 0;
|
|
170
|
+
if (providerStatus !== 0) {
|
|
171
|
+
const providerMsg = parsed?.base_resp?.status_msg ?? "unknown";
|
|
172
|
+
throwAndEmit(params, `minimax VLM: provider returned status_code=${providerStatus} (${providerMsg}) — check the minimax account or retry, and if it persists surface 'image understanding is unavailable' to the user`, status, traceId);
|
|
173
|
+
}
|
|
174
|
+
const content = parsed?.content;
|
|
175
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
176
|
+
throwAndEmit(params, `minimax VLM: returned no description (empty content field) — this is a provider bug, retry or surface 'image understanding is unavailable' to the user`, status, traceId);
|
|
177
|
+
}
|
|
178
|
+
const latencyMs = Date.now() - startTs;
|
|
179
|
+
emitEnd(params, content.length, latencyMs);
|
|
180
|
+
return content;
|
|
181
|
+
}
|
|
182
|
+
/* v8 ignore start — module-level observability event */
|
|
183
|
+
(0, runtime_1.emitNervesEvent)({
|
|
184
|
+
component: "engine",
|
|
185
|
+
event: "engine.minimax_vlm_loaded",
|
|
186
|
+
message: "minimax vlm client loaded",
|
|
187
|
+
meta: {},
|
|
188
|
+
});
|
|
189
|
+
/* v8 ignore stop */
|