@pellux/goodvibes-tui 0.18.10 → 0.18.12
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/CHANGELOG.md +56 -0
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +2 -2
- package/src/core/conversation-rendering.ts +2 -2
- package/src/core/conversation.ts +5 -5
- package/src/core/orchestrator.ts +13 -11
- package/src/daemon/facade-composition.ts +8 -8
- package/src/daemon/facade.ts +8 -8
- package/src/daemon/types.ts +3 -3
- package/src/input/command-registry.ts +3 -3
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/session-workflow.ts +1 -1
- package/src/input/handler-feed.ts +1 -1
- package/src/input/session-picker-modal.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -0
- package/src/panels/builtin/operations.ts +1 -0
- package/src/panels/builtin/session.ts +1 -1
- package/src/panels/builtin/shared.ts +2 -2
- package/src/panels/context-visualizer-panel.ts +4 -1
- package/src/panels/provider-health-domains.ts +5 -1
- package/src/panels/provider-health-panel.ts +5 -1
- package/src/panels/session-browser-panel.ts +1 -1
- package/src/panels/token-budget-panel.ts +6 -2
- package/src/plugins/loader.ts +2 -2
- package/src/runtime/bootstrap-command-context.ts +3 -3
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +2 -2
- package/src/runtime/bootstrap-hook-bridge.ts +1 -1
- package/src/runtime/bootstrap-shell.ts +1 -1
- package/src/runtime/bootstrap.ts +5 -4
- package/src/runtime/services.ts +2 -2
- package/src/runtime/ui-read-models-observability-security.ts +2 -2
- package/src/runtime/ui-read-models-observability-system.ts +1 -1
- package/src/runtime/ui-service-queries.ts +1 -1
- package/src/tools/index.ts +1 -1
- package/src/version.ts +1 -1
- package/src/acp/connection.ts +0 -447
- package/src/acp/index.ts +0 -7
- package/src/acp/manager.ts +0 -1
- package/src/adapters/bluebubbles/index.ts +0 -127
- package/src/adapters/discord/index.ts +0 -297
- package/src/adapters/github/index.ts +0 -73
- package/src/adapters/google-chat/index.ts +0 -119
- package/src/adapters/imessage/index.ts +0 -92
- package/src/adapters/index.ts +0 -15
- package/src/adapters/matrix/index.ts +0 -116
- package/src/adapters/mattermost/index.ts +0 -151
- package/src/adapters/msteams/index.ts +0 -180
- package/src/adapters/ntfy/index.ts +0 -118
- package/src/adapters/signal/index.ts +0 -92
- package/src/adapters/slack/index.ts +0 -323
- package/src/adapters/telegram/index.ts +0 -160
- package/src/adapters/types.ts +0 -97
- package/src/adapters/webhook/index.ts +0 -178
- package/src/adapters/whatsapp/index.ts +0 -135
- package/src/agents/message-bus-core.ts +0 -312
- package/src/agents/message-bus.ts +0 -2
- package/src/agents/orchestrator-prompts.ts +0 -351
- package/src/agents/orchestrator-runner.ts +0 -668
- package/src/agents/orchestrator.ts +0 -438
- package/src/agents/session.ts +0 -108
- package/src/agents/worktree.ts +0 -153
- package/src/agents/wrfc-config.ts +0 -47
- package/src/agents/wrfc-controller.ts +0 -747
- package/src/agents/wrfc-gate-runtime.ts +0 -75
- package/src/agents/wrfc-reporting.ts +0 -284
- package/src/agents/wrfc-runtime-events.ts +0 -150
- package/src/agents/wrfc-types.ts +0 -67
- package/src/automation/delivery-manager.ts +0 -368
- package/src/automation/index.ts +0 -72
- package/src/automation/manager-runtime-delivery.ts +0 -139
- package/src/automation/manager-runtime-events.ts +0 -131
- package/src/automation/manager-runtime-execution.ts +0 -511
- package/src/automation/manager-runtime-helpers.ts +0 -433
- package/src/automation/manager-runtime-job-mutations.ts +0 -175
- package/src/automation/manager-runtime-reconcile.ts +0 -148
- package/src/automation/manager-runtime-scheduling.ts +0 -189
- package/src/automation/manager-runtime-sync.ts +0 -54
- package/src/automation/manager-runtime.ts +0 -721
- package/src/automation/manager.ts +0 -10
- package/src/automation/service.ts +0 -242
- package/src/channels/builtin/account-actions.ts +0 -490
- package/src/channels/builtin/accounts.ts +0 -433
- package/src/channels/builtin/contracts.ts +0 -405
- package/src/channels/builtin/plugins.ts +0 -308
- package/src/channels/builtin/rendering.ts +0 -174
- package/src/channels/builtin/setup-schema.ts +0 -504
- package/src/channels/builtin/shared.ts +0 -96
- package/src/channels/builtin/surfaces.ts +0 -57
- package/src/channels/builtin/targets.ts +0 -693
- package/src/channels/builtin-runtime.ts +0 -443
- package/src/channels/delivery/shared.ts +0 -199
- package/src/channels/delivery/strategies-bridge.ts +0 -246
- package/src/channels/delivery/strategies-core.ts +0 -299
- package/src/channels/delivery/strategies-enterprise.ts +0 -178
- package/src/channels/delivery/types.ts +0 -59
- package/src/channels/delivery-router.ts +0 -127
- package/src/channels/index.ts +0 -77
- package/src/channels/plugin-registry.ts +0 -551
- package/src/channels/provider-runtime.ts +0 -330
- package/src/channels/reply-pipeline.ts +0 -522
- package/src/channels/route-manager.ts +0 -340
- package/src/channels/surface-registry.ts +0 -186
- package/src/config/helper-model.ts +0 -1
- package/src/config/manager.ts +0 -8
- package/src/config/subscription-auth.ts +0 -31
- package/src/config/tool-llm.ts +0 -110
- package/src/control-plane/approval-broker.ts +0 -351
- package/src/control-plane/gateway.ts +0 -1
- package/src/control-plane/index.ts +0 -54
- package/src/control-plane/media-contract-schemas.ts +0 -1
- package/src/control-plane/method-catalog-admin.ts +0 -1
- package/src/control-plane/method-catalog-channels.ts +0 -1
- package/src/control-plane/method-catalog-control-automation.ts +0 -1
- package/src/control-plane/method-catalog-control-core.ts +0 -1
- package/src/control-plane/method-catalog-control.ts +0 -1
- package/src/control-plane/method-catalog-events.ts +0 -1
- package/src/control-plane/method-catalog-knowledge.ts +0 -1
- package/src/control-plane/method-catalog-media.ts +0 -1
- package/src/control-plane/method-catalog-runtime.ts +0 -1
- package/src/control-plane/method-catalog-shared.ts +0 -1
- package/src/control-plane/method-catalog.ts +0 -1
- package/src/control-plane/operator-contract-schemas-admin.ts +0 -1
- package/src/control-plane/operator-contract-schemas-channels.ts +0 -1
- package/src/control-plane/operator-contract-schemas-control.ts +0 -1
- package/src/control-plane/operator-contract-schemas-domains.ts +0 -1
- package/src/control-plane/operator-contract-schemas-knowledge.ts +0 -1
- package/src/control-plane/operator-contract-schemas-media.ts +0 -1
- package/src/control-plane/operator-contract-schemas-permissions.ts +0 -1
- package/src/control-plane/operator-contract-schemas-remote.ts +0 -1
- package/src/control-plane/operator-contract-schemas-runtime.ts +0 -1
- package/src/control-plane/operator-contract-schemas-shared.ts +0 -1
- package/src/control-plane/operator-contract-schemas-telemetry.ts +0 -1
- package/src/control-plane/operator-contract-schemas.ts +0 -1
- package/src/control-plane/operator-contract.ts +0 -165
- package/src/control-plane/session-broker.ts +0 -780
- package/src/core/compaction-sections.ts +0 -492
- package/src/core/compaction-types.ts +0 -147
- package/src/core/context-compaction.ts +0 -542
- package/src/core/conversation-compaction.ts +0 -68
- package/src/core/conversation-diff.ts +0 -55
- package/src/core/conversation-utils.ts +0 -72
- package/src/core/event-replay.ts +0 -287
- package/src/core/orchestrator-context-runtime.ts +0 -407
- package/src/core/orchestrator-follow-up-runtime.ts +0 -134
- package/src/core/orchestrator-runtime.ts +0 -132
- package/src/core/orchestrator-tool-runtime.ts +0 -468
- package/src/core/orchestrator-turn-helpers.ts +0 -355
- package/src/core/orchestrator-turn-loop.ts +0 -443
- package/src/core/plan-command-handler.ts +0 -169
- package/src/core/transcript-events/classify.ts +0 -95
- package/src/core/transcript-events/index.ts +0 -15
- package/src/daemon/control-plane.ts +0 -522
- package/src/daemon/helpers.ts +0 -74
- package/src/daemon/http/router-route-contexts.ts +0 -370
- package/src/daemon/http/router.ts +0 -531
- package/src/daemon/http-listener.ts +0 -301
- package/src/daemon/index.ts +0 -1
- package/src/daemon/server.ts +0 -1
- package/src/daemon/service-manager.ts +0 -413
- package/src/daemon/surface-actions.ts +0 -183
- package/src/daemon/surface-delivery.ts +0 -530
- package/src/daemon/transport-events.ts +0 -110
- package/src/export/markdown.ts +0 -213
- package/src/export/session-export.ts +0 -1
- package/src/git/index.ts +0 -1
- package/src/git/service.ts +0 -414
- package/src/hooks/chain-engine.ts +0 -414
- package/src/hooks/dispatcher.ts +0 -414
- package/src/hooks/hook-api.ts +0 -170
- package/src/hooks/index.ts +0 -48
- package/src/hooks/runners/agent.ts +0 -93
- package/src/hooks/runners/prompt.ts +0 -69
- package/src/hooks/workbench.ts +0 -360
- package/src/integrations/index.ts +0 -42
- package/src/integrations/notifier.ts +0 -206
- package/src/integrations/webhooks.ts +0 -1
- package/src/knowledge/consolidation.ts +0 -346
- package/src/knowledge/graphql.ts +0 -324
- package/src/knowledge/index.ts +0 -60
- package/src/knowledge/ingest-compile.ts +0 -386
- package/src/knowledge/ingest-context.ts +0 -18
- package/src/knowledge/ingest-inputs.ts +0 -387
- package/src/knowledge/ingest.ts +0 -1
- package/src/knowledge/internal.ts +0 -257
- package/src/knowledge/knowledge-api.ts +0 -432
- package/src/knowledge/lint.ts +0 -121
- package/src/knowledge/memory-sync.ts +0 -62
- package/src/knowledge/packet.ts +0 -370
- package/src/knowledge/scheduling.ts +0 -283
- package/src/knowledge/service.ts +0 -715
- package/src/mcp/client.ts +0 -383
- package/src/mcp/index.ts +0 -12
- package/src/mcp/mcp-api.ts +0 -90
- package/src/mcp/registry.ts +0 -1
- package/src/media/builtin-image-understanding.ts +0 -303
- package/src/media/builtin-providers.ts +0 -26
- package/src/media/index.ts +0 -18
- package/src/multimodal/index.ts +0 -13
- package/src/multimodal/service.ts +0 -492
- package/src/permissions/briefs/build.ts +0 -88
- package/src/permissions/manager.ts +0 -1
- package/src/plugins/api.ts +0 -383
- package/src/plugins/manager.ts +0 -481
- package/src/profiles/shape.ts +0 -58
- package/src/providers/amazon-bedrock-mantle.ts +0 -50
- package/src/providers/amazon-bedrock.ts +0 -61
- package/src/providers/anthropic-compat.ts +0 -373
- package/src/providers/anthropic-sdk-provider.ts +0 -230
- package/src/providers/anthropic-vertex.ts +0 -59
- package/src/providers/anthropic.ts +0 -469
- package/src/providers/auto-register.ts +0 -417
- package/src/providers/builtin-catalog.ts +0 -326
- package/src/providers/builtin-registry.ts +0 -575
- package/src/providers/cache-planner.ts +0 -258
- package/src/providers/capabilities.ts +0 -1
- package/src/providers/custom-loader.ts +0 -425
- package/src/providers/discovered-compat.ts +0 -7
- package/src/providers/discovered-factory.ts +0 -61
- package/src/providers/discovered-traits.ts +0 -138
- package/src/providers/gemini.ts +0 -462
- package/src/providers/github-copilot.ts +0 -254
- package/src/providers/index.ts +0 -1
- package/src/providers/interface.ts +0 -185
- package/src/providers/llama-cpp.ts +0 -402
- package/src/providers/lm-studio-helpers.ts +0 -367
- package/src/providers/lm-studio.ts +0 -484
- package/src/providers/model-catalog-cache.ts +0 -221
- package/src/providers/model-catalog-notifications.ts +0 -97
- package/src/providers/model-catalog-synthetic.ts +0 -202
- package/src/providers/model-catalog.ts +0 -211
- package/src/providers/model-limits.ts +0 -1
- package/src/providers/ollama.ts +0 -469
- package/src/providers/openai-codex.ts +0 -472
- package/src/providers/openai-compat.ts +0 -615
- package/src/providers/openai.ts +0 -231
- package/src/providers/optimizer.ts +0 -1
- package/src/providers/provider-api.ts +0 -1
- package/src/providers/registry-helpers.ts +0 -34
- package/src/providers/registry-models.ts +0 -77
- package/src/providers/registry-types.ts +0 -67
- package/src/providers/registry.ts +0 -1
- package/src/providers/runtime-metadata.ts +0 -149
- package/src/providers/runtime-snapshot.ts +0 -130
- package/src/providers/synthetic.ts +0 -561
- package/src/providers/tier-prompts.ts +0 -84
- package/src/providers/tool-formats.ts +0 -414
- package/src/runtime/auth/inspection.ts +0 -125
- package/src/runtime/bootstrap-background.ts +0 -157
- package/src/runtime/bootstrap-helpers.ts +0 -88
- package/src/runtime/bootstrap-runtime-events.ts +0 -254
- package/src/runtime/bootstrap-services.ts +0 -197
- package/src/runtime/compaction/index.ts +0 -1
- package/src/runtime/compaction/lifecycle.ts +0 -1
- package/src/runtime/compaction/manager.ts +0 -474
- package/src/runtime/compaction/quality-score.ts +0 -1
- package/src/runtime/compaction/resume-repair.ts +0 -1
- package/src/runtime/compaction/strategies/autocompact.ts +0 -1
- package/src/runtime/compaction/strategies/boundary-commit.ts +0 -1
- package/src/runtime/compaction/strategies/collapse.ts +0 -1
- package/src/runtime/compaction/strategies/index.ts +0 -1
- package/src/runtime/compaction/strategies/microcompact.ts +0 -1
- package/src/runtime/compaction/strategies/reactive.ts +0 -1
- package/src/runtime/compaction/types.ts +0 -1
- package/src/runtime/ecosystem/recommendations.ts +0 -117
- package/src/runtime/emitters/agents.ts +0 -96
- package/src/runtime/emitters/automation.ts +0 -112
- package/src/runtime/emitters/communication.ts +0 -53
- package/src/runtime/emitters/compaction.ts +0 -161
- package/src/runtime/emitters/control-plane.ts +0 -65
- package/src/runtime/emitters/deliveries.ts +0 -65
- package/src/runtime/emitters/forensics.ts +0 -17
- package/src/runtime/emitters/index.ts +0 -59
- package/src/runtime/emitters/knowledge.ts +0 -129
- package/src/runtime/emitters/mcp.ts +0 -95
- package/src/runtime/emitters/ops.ts +0 -163
- package/src/runtime/emitters/orchestration.ts +0 -87
- package/src/runtime/emitters/permissions.ts +0 -98
- package/src/runtime/emitters/planner.ts +0 -23
- package/src/runtime/emitters/plugins.ts +0 -78
- package/src/runtime/emitters/providers.ts +0 -30
- package/src/runtime/emitters/routes.ts +0 -57
- package/src/runtime/emitters/security.ts +0 -53
- package/src/runtime/emitters/session.ts +0 -93
- package/src/runtime/emitters/surfaces.ts +0 -57
- package/src/runtime/emitters/tasks.ts +0 -69
- package/src/runtime/emitters/tools.ts +0 -140
- package/src/runtime/emitters/transport.ts +0 -78
- package/src/runtime/emitters/turn.ts +0 -155
- package/src/runtime/emitters/ui.ts +0 -57
- package/src/runtime/emitters/watchers.ts +0 -57
- package/src/runtime/emitters/workflows.ts +0 -79
- package/src/runtime/eval/index.ts +0 -48
- package/src/runtime/eval/runner.ts +0 -163
- package/src/runtime/eval/suites.ts +0 -264
- package/src/runtime/events/domain-map.ts +0 -148
- package/src/runtime/events/index.ts +0 -1
- package/src/runtime/events/turn.ts +0 -1
- package/src/runtime/events/workflows.ts +0 -1
- package/src/runtime/forensics/collector.ts +0 -693
- package/src/runtime/forensics/index.ts +0 -23
- package/src/runtime/foundation-clients.ts +0 -78
- package/src/runtime/foundation-services.ts +0 -96
- package/src/runtime/guidance.ts +0 -183
- package/src/runtime/health/effect-handlers.ts +0 -189
- package/src/runtime/health/index.ts +0 -70
- package/src/runtime/health/wiring.ts +0 -115
- package/src/runtime/integration/helpers.ts +0 -640
- package/src/runtime/lifecycle.ts +0 -107
- package/src/runtime/mcp/index.ts +0 -68
- package/src/runtime/mcp/manager.ts +0 -513
- package/src/runtime/network/inbound.ts +0 -131
- package/src/runtime/network/index.ts +0 -30
- package/src/runtime/network/outbound.ts +0 -292
- package/src/runtime/network/shared.ts +0 -82
- package/src/runtime/operator-client.ts +0 -235
- package/src/runtime/ops/control-plane.ts +0 -363
- package/src/runtime/ops/index.ts +0 -122
- package/src/runtime/ops/playbooks/index.ts +0 -10
- package/src/runtime/ops/playbooks/session-unrecoverable.ts +0 -196
- package/src/runtime/ops/playbooks/stuck-turn.ts +0 -197
- package/src/runtime/ops/runtime-context.ts +0 -100
- package/src/runtime/ops-api.ts +0 -27
- package/src/runtime/orchestration/spawn-policy.ts +0 -83
- package/src/runtime/peer-client.ts +0 -404
- package/src/runtime/perf/index.ts +0 -57
- package/src/runtime/perf/slo-collector.ts +0 -375
- package/src/runtime/permissions/index.ts +0 -190
- package/src/runtime/permissions/policy-runtime.ts +0 -1
- package/src/runtime/permissions/preflight.ts +0 -101
- package/src/runtime/permissions/rule-suggestions.ts +0 -36
- package/src/runtime/plugins/hot-reload.ts +0 -221
- package/src/runtime/plugins/index.ts +0 -84
- package/src/runtime/plugins/lifecycle.ts +0 -95
- package/src/runtime/plugins/manager.ts +0 -474
- package/src/runtime/plugins/manifest.ts +0 -167
- package/src/runtime/plugins/quarantine.ts +0 -202
- package/src/runtime/plugins/trust.ts +0 -291
- package/src/runtime/plugins/types.ts +0 -205
- package/src/runtime/provider-accounts/registry.ts +0 -326
- package/src/runtime/remote/distributed-runtime-contract-schemas.ts +0 -386
- package/src/runtime/remote/index.ts +0 -488
- package/src/runtime/remote/runner-registry.ts +0 -438
- package/src/runtime/remote/supervisor.ts +0 -70
- package/src/runtime/runtime-hook-api.ts +0 -5
- package/src/runtime/runtime-knowledge-api.ts +0 -14
- package/src/runtime/runtime-mcp-api.ts +0 -5
- package/src/runtime/runtime-ops-api.ts +0 -86
- package/src/runtime/runtime-provider-api.ts +0 -18
- package/src/runtime/session-maintenance.ts +0 -188
- package/src/runtime/session-persistence.ts +0 -288
- package/src/runtime/session-return-context.ts +0 -195
- package/src/runtime/settings/control-plane-store.ts +0 -258
- package/src/runtime/settings/control-plane.ts +0 -599
- package/src/runtime/shell-command-extensions.ts +0 -54
- package/src/runtime/shell-command-ops.ts +0 -207
- package/src/runtime/shell-command-platform.ts +0 -47
- package/src/runtime/shell-command-services.ts +0 -143
- package/src/runtime/shell-command-workspace.ts +0 -31
- package/src/runtime/tasks/adapters/acp-adapter.ts +0 -211
- package/src/runtime/tasks/adapters/agent-adapter.ts +0 -208
- package/src/runtime/tasks/adapters/index.ts +0 -16
- package/src/runtime/tasks/adapters/process-adapter.ts +0 -214
- package/src/runtime/tasks/adapters/scheduler-adapter.ts +0 -193
- package/src/runtime/tasks/index.ts +0 -68
- package/src/runtime/tasks/manager.ts +0 -415
- package/src/runtime/telemetry/api-helpers.ts +0 -517
- package/src/runtime/telemetry/api.ts +0 -768
- package/src/runtime/telemetry/index.ts +0 -178
- package/src/runtime/telemetry/instrumentation/domain-bridge-agent-session.ts +0 -440
- package/src/runtime/telemetry/instrumentation/domain-bridge-plugin-mcp.ts +0 -200
- package/src/runtime/telemetry/instrumentation/domain-bridge-shared.ts +0 -18
- package/src/runtime/telemetry/instrumentation/domain-bridge-transport-task.ts +0 -204
- package/src/runtime/telemetry/instrumentation/domain-bridge.ts +0 -125
- package/src/runtime/telemetry/instrumentation/index.ts +0 -67
- package/src/runtime/tools/context.ts +0 -114
- package/src/runtime/tools/index.ts +0 -46
- package/src/runtime/tools/phased-executor.ts +0 -448
- package/src/runtime/tools/phases/budget.ts +0 -130
- package/src/runtime/tools/phases/execute.ts +0 -69
- package/src/runtime/tools/phases/index.ts +0 -13
- package/src/runtime/tools/phases/map-output.ts +0 -98
- package/src/runtime/tools/phases/permission.ts +0 -133
- package/src/runtime/tools/phases/posthook.ts +0 -57
- package/src/runtime/tools/phases/prehook.ts +0 -68
- package/src/runtime/tools/phases/validate.ts +0 -53
- package/src/runtime/transports/direct.ts +0 -73
- package/src/runtime/transports/http-helpers.ts +0 -218
- package/src/runtime/transports/http-types.ts +0 -364
- package/src/runtime/transports/http.ts +0 -629
- package/src/runtime/transports/realtime.ts +0 -50
- package/src/runtime/transports/remote-events.ts +0 -16
- package/src/runtime/transports/shared.ts +0 -39
- package/src/runtime/transports/ui-runtime-events.ts +0 -35
- package/src/runtime/ui-events.ts +0 -46
- package/src/runtime/worktree/registry.ts +0 -252
- package/src/sessions/manager.ts +0 -14
- package/src/state/file-watcher.ts +0 -294
- package/src/state/index.ts +0 -56
- package/src/state/knowledge-injection.ts +0 -214
- package/src/state/memory-embedding-http.ts +0 -642
- package/src/state/memory-embeddings.ts +0 -312
- package/src/state/memory-ingest.ts +0 -132
- package/src/state/memory-registry.ts +0 -111
- package/src/state/memory-store-helpers.ts +0 -160
- package/src/state/memory-store.ts +0 -728
- package/src/state/memory-vector-store.ts +0 -418
- package/src/templates/manager.ts +0 -187
- package/src/tools/agent/index.ts +0 -610
- package/src/tools/agent/manager.ts +0 -476
- package/src/tools/analyze/git-modes.ts +0 -380
- package/src/tools/analyze/index.ts +0 -128
- package/src/tools/channel/agent-tools.ts +0 -16
- package/src/tools/channel/index.ts +0 -268
- package/src/tools/control/index.ts +0 -90
- package/src/tools/edit/core.ts +0 -619
- package/src/tools/edit/index.ts +0 -4
- package/src/tools/edit/phased.ts +0 -33
- package/src/tools/fetch/index.ts +0 -3
- package/src/tools/fetch/phased.ts +0 -34
- package/src/tools/fetch/runtime.ts +0 -499
- package/src/tools/mcp/index.ts +0 -190
- package/src/tools/remote-trigger/index.ts +0 -130
- package/src/tools/shared/auto-heal.ts +0 -282
- package/src/tools/state/index.ts +0 -688
- package/src/tools/web-search/index.ts +0 -38
- package/src/tools/write/index.ts +0 -604
- package/src/tools/write/phased.ts +0 -41
- package/src/types/generated/foundation-client-types.ts +0 -22
- package/src/watchers/index.ts +0 -11
- package/src/watchers/registry.ts +0 -517
- package/src/web-search/index.ts +0 -26
- package/src/web-search/provider-registry.ts +0 -64
- package/src/web-search/providers/brave.ts +0 -100
- package/src/web-search/providers/duckduckgo.ts +0 -270
- package/src/web-search/providers/exa.ts +0 -77
- package/src/web-search/providers/firecrawl.ts +0 -90
- package/src/web-search/providers/perplexity.ts +0 -86
- package/src/web-search/providers/searxng.ts +0 -88
- package/src/web-search/providers/shared.ts +0 -249
- package/src/web-search/providers/tavily.ts +0 -90
- package/src/web-search/service.ts +0 -142
|
@@ -1,615 +0,0 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import type {
|
|
3
|
-
LLMProvider,
|
|
4
|
-
ChatRequest,
|
|
5
|
-
ChatResponse,
|
|
6
|
-
ProviderEmbeddingRequest,
|
|
7
|
-
ProviderEmbeddingResult,
|
|
8
|
-
ProviderRuntimeMetadata,
|
|
9
|
-
ProviderRuntimeMetadataDeps,
|
|
10
|
-
} from '@pellux/goodvibes-sdk/platform/providers/interface';
|
|
11
|
-
import type { ProviderCapability } from '@pellux/goodvibes-sdk/platform/providers/capabilities';
|
|
12
|
-
import { ProviderError } from '@pellux/goodvibes-sdk/platform/types/errors';
|
|
13
|
-
import { withRetry } from '@pellux/goodvibes-sdk/platform/utils/retry';
|
|
14
|
-
import {
|
|
15
|
-
toOpenAITools,
|
|
16
|
-
toOpenAIMessages,
|
|
17
|
-
fromOpenAIToolCalls,
|
|
18
|
-
extractTextToolCalls,
|
|
19
|
-
} from '@pellux/goodvibes-sdk/platform/providers/tool-formats';
|
|
20
|
-
import type { OpenAIToolCall } from '@pellux/goodvibes-sdk/platform/providers/tool-formats';
|
|
21
|
-
import { getCacheCapability } from '@pellux/goodvibes-sdk/platform/providers/cache-capability';
|
|
22
|
-
import type { ProviderCacheCapability } from '@pellux/goodvibes-sdk/platform/providers/cache-capability';
|
|
23
|
-
import type { CacheHitTracker } from '@pellux/goodvibes-sdk/platform/providers/cache-strategy';
|
|
24
|
-
import { extractOpenAIStreamTextDelta } from '@pellux/goodvibes-sdk/platform/providers/openai-stream-delta';
|
|
25
|
-
import { logger } from '@pellux/goodvibes-sdk/platform/utils/logger';
|
|
26
|
-
import { summarizeError, toProviderError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
27
|
-
|
|
28
|
-
const NOOP_CACHE_HIT_TRACKER: Pick<CacheHitTracker, 'recordTurn'> = {
|
|
29
|
-
recordTurn: () => {},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
interface ChatRequestFingerprint {
|
|
33
|
-
readonly model: string;
|
|
34
|
-
readonly messageCount: number;
|
|
35
|
-
readonly userMessages: number;
|
|
36
|
-
readonly assistantMessages: number;
|
|
37
|
-
readonly toolMessages: number;
|
|
38
|
-
readonly contentChars: number;
|
|
39
|
-
readonly imageParts: number;
|
|
40
|
-
readonly toolCount: number;
|
|
41
|
-
readonly systemPromptChars: number;
|
|
42
|
-
readonly reasoningEffort: ChatRequest['reasoningEffort'] | null;
|
|
43
|
-
readonly reasoningSummary: boolean;
|
|
44
|
-
readonly maxTokens: number | null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface OpenAICompatErrorDiagnostic {
|
|
48
|
-
readonly status?: number;
|
|
49
|
-
readonly code?: string;
|
|
50
|
-
readonly type?: string;
|
|
51
|
-
readonly requestId?: string;
|
|
52
|
-
readonly detail?: string;
|
|
53
|
-
readonly rawMessage: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function summarizeContent(
|
|
57
|
-
content: ChatRequest['messages'][number]['content'],
|
|
58
|
-
): { readonly textChars: number; readonly imageParts: number } {
|
|
59
|
-
if (typeof content === 'string') {
|
|
60
|
-
return { textChars: content.length, imageParts: 0 };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let textChars = 0;
|
|
64
|
-
let imageParts = 0;
|
|
65
|
-
for (const part of content) {
|
|
66
|
-
if (part.type === 'text') textChars += part.text.length;
|
|
67
|
-
if (part.type === 'image') imageParts += 1;
|
|
68
|
-
}
|
|
69
|
-
return { textChars, imageParts };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function buildChatRequestFingerprint(
|
|
73
|
-
request: ChatRequest,
|
|
74
|
-
model: string,
|
|
75
|
-
): ChatRequestFingerprint {
|
|
76
|
-
let userMessages = 0;
|
|
77
|
-
let assistantMessages = 0;
|
|
78
|
-
let toolMessages = 0;
|
|
79
|
-
let contentChars = 0;
|
|
80
|
-
let imageParts = 0;
|
|
81
|
-
|
|
82
|
-
for (const message of request.messages) {
|
|
83
|
-
if (message.role === 'user') {
|
|
84
|
-
userMessages += 1;
|
|
85
|
-
const content = summarizeContent(message.content);
|
|
86
|
-
contentChars += content.textChars;
|
|
87
|
-
imageParts += content.imageParts;
|
|
88
|
-
} else if (message.role === 'assistant') {
|
|
89
|
-
assistantMessages += 1;
|
|
90
|
-
contentChars += message.content.length;
|
|
91
|
-
} else if (message.role === 'tool') {
|
|
92
|
-
toolMessages += 1;
|
|
93
|
-
contentChars += message.content.length;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
model,
|
|
99
|
-
messageCount: request.messages.length,
|
|
100
|
-
userMessages,
|
|
101
|
-
assistantMessages,
|
|
102
|
-
toolMessages,
|
|
103
|
-
contentChars,
|
|
104
|
-
imageParts,
|
|
105
|
-
toolCount: request.tools?.length ?? 0,
|
|
106
|
-
systemPromptChars: request.systemPrompt?.length ?? 0,
|
|
107
|
-
reasoningEffort: request.reasoningEffort ?? null,
|
|
108
|
-
reasoningSummary: Boolean(request.reasoningSummary),
|
|
109
|
-
maxTokens: request.maxTokens ?? null,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function truncateDetail(detail: string, max = 280): string {
|
|
114
|
-
if (detail.length <= max) return detail;
|
|
115
|
-
return `${detail.slice(0, max - 3)}...`;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function extractStringField(record: Record<string, unknown>, key: string): string | undefined {
|
|
119
|
-
const value = record[key];
|
|
120
|
-
return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function extractHeaderValue(headers: unknown, name: string): string | undefined {
|
|
124
|
-
if (!headers) return undefined;
|
|
125
|
-
if (headers instanceof Headers) return headers.get(name) ?? undefined;
|
|
126
|
-
if (Array.isArray(headers)) {
|
|
127
|
-
const loweredName = name.toLowerCase();
|
|
128
|
-
const match = headers.find((entry) =>
|
|
129
|
-
Array.isArray(entry) &&
|
|
130
|
-
entry.length >= 2 &&
|
|
131
|
-
typeof entry[0] === 'string' &&
|
|
132
|
-
entry[0].toLowerCase() === loweredName &&
|
|
133
|
-
typeof entry[1] === 'string');
|
|
134
|
-
return Array.isArray(match) ? match[1] : undefined;
|
|
135
|
-
}
|
|
136
|
-
if (typeof headers === 'object') {
|
|
137
|
-
const loweredName = name.toLowerCase();
|
|
138
|
-
for (const [key, value] of Object.entries(headers as Record<string, unknown>)) {
|
|
139
|
-
if (key.toLowerCase() !== loweredName) continue;
|
|
140
|
-
if (typeof value === 'string' && value.trim().length > 0) return value;
|
|
141
|
-
if (Array.isArray(value)) {
|
|
142
|
-
const parts = value.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0);
|
|
143
|
-
if (parts.length > 0) return parts.join(', ');
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return undefined;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function formatErrorBodyDetail(value: unknown): string | undefined {
|
|
151
|
-
if (typeof value === 'string' && value.trim().length > 0) return truncateDetail(value.trim());
|
|
152
|
-
if (!value || typeof value !== 'object') return undefined;
|
|
153
|
-
|
|
154
|
-
const record = value as Record<string, unknown>;
|
|
155
|
-
const detailParts: string[] = [];
|
|
156
|
-
const message = extractStringField(record, 'message');
|
|
157
|
-
const code = extractStringField(record, 'code');
|
|
158
|
-
const type = extractStringField(record, 'type');
|
|
159
|
-
const param = extractStringField(record, 'param');
|
|
160
|
-
|
|
161
|
-
if (message) detailParts.push(message);
|
|
162
|
-
if (code && !detailParts.some((part) => part.includes(code))) detailParts.push(`code=${code}`);
|
|
163
|
-
if (type && !detailParts.some((part) => part.includes(type))) detailParts.push(`type=${type}`);
|
|
164
|
-
if (param && !detailParts.some((part) => part.includes(param))) detailParts.push(`param=${param}`);
|
|
165
|
-
|
|
166
|
-
if (detailParts.length > 0) return truncateDetail(detailParts.join(', '));
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
return truncateDetail(JSON.stringify(record));
|
|
170
|
-
} catch {
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function extractOpenAICompatErrorDiagnostic(err: unknown): OpenAICompatErrorDiagnostic {
|
|
176
|
-
const rawMessage = summarizeError(err);
|
|
177
|
-
const status = err && typeof err === 'object' && 'status' in err && typeof (err as { status?: unknown }).status === 'number'
|
|
178
|
-
? (err as { status: number }).status
|
|
179
|
-
: undefined;
|
|
180
|
-
|
|
181
|
-
if (!err || typeof err !== 'object') {
|
|
182
|
-
return { status, rawMessage };
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const record = err as Record<string, unknown>;
|
|
186
|
-
const detail = formatErrorBodyDetail(record.error) ?? (rawMessage.trim().length > 0 ? truncateDetail(rawMessage.trim()) : undefined);
|
|
187
|
-
return {
|
|
188
|
-
status,
|
|
189
|
-
code: extractStringField(record, 'code'),
|
|
190
|
-
type: extractStringField(record, 'type'),
|
|
191
|
-
requestId: extractStringField(record, 'requestID')
|
|
192
|
-
?? extractHeaderValue(record.headers, 'x-request-id')
|
|
193
|
-
?? extractHeaderValue(record.headers, 'request-id'),
|
|
194
|
-
detail,
|
|
195
|
-
rawMessage,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function buildOpenAICompatErrorMessage(
|
|
200
|
-
providerName: string,
|
|
201
|
-
phase: 'request' | 'stream',
|
|
202
|
-
diagnostic: OpenAICompatErrorDiagnostic,
|
|
203
|
-
): string {
|
|
204
|
-
const prefix = `${providerName} chat ${phase} failed${diagnostic.status !== undefined ? ` ${diagnostic.status}` : ''}`;
|
|
205
|
-
const messageParts = [prefix];
|
|
206
|
-
|
|
207
|
-
if (diagnostic.detail && diagnostic.detail !== diagnostic.rawMessage) {
|
|
208
|
-
messageParts.push(diagnostic.detail);
|
|
209
|
-
} else if (diagnostic.rawMessage.trim().length > 0) {
|
|
210
|
-
messageParts.push(truncateDetail(diagnostic.rawMessage.trim()));
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const metadata: string[] = [];
|
|
214
|
-
if (diagnostic.code && !messageParts.some((part) => part.includes(diagnostic.code!))) metadata.push(`code=${diagnostic.code}`);
|
|
215
|
-
if (diagnostic.type && !messageParts.some((part) => part.includes(diagnostic.type!))) metadata.push(`type=${diagnostic.type}`);
|
|
216
|
-
if (diagnostic.requestId) metadata.push(`request_id=${diagnostic.requestId}`);
|
|
217
|
-
|
|
218
|
-
return metadata.length > 0
|
|
219
|
-
? `${messageParts.join(': ')} (${metadata.join(', ')})`
|
|
220
|
-
: messageParts.join(': ');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export interface OpenAICompatOptions {
|
|
224
|
-
name: string;
|
|
225
|
-
baseURL: string;
|
|
226
|
-
apiKey: string;
|
|
227
|
-
defaultModel: string;
|
|
228
|
-
models: string[];
|
|
229
|
-
embeddingModel?: string;
|
|
230
|
-
capabilities?: Partial<ProviderCapability>;
|
|
231
|
-
/** Optional extra HTTP headers sent with every request to this provider. */
|
|
232
|
-
defaultHeaders?: Record<string, string>;
|
|
233
|
-
/** How to send reasoning params. Default: 'none' (don't send). */
|
|
234
|
-
reasoningFormat?: 'mercury' | 'openrouter' | 'llamacpp' | 'none';
|
|
235
|
-
/** Optional env vars or secret keys that can satisfy API-key auth for this provider. */
|
|
236
|
-
authEnvVars?: readonly string[];
|
|
237
|
-
/** Optional service names that expose service-owned OAuth for this provider. */
|
|
238
|
-
serviceNames?: readonly string[];
|
|
239
|
-
/** Optional subscription-provider identity when this provider can use a stored OAuth session. */
|
|
240
|
-
subscriptionProviderId?: string;
|
|
241
|
-
/** Optional provider-owned model suppression list for runtime clients. */
|
|
242
|
-
suppressedModels?: readonly string[];
|
|
243
|
-
/** Optional provider aliases exposed to runtime metadata consumers. */
|
|
244
|
-
aliases?: readonly string[];
|
|
245
|
-
/** Optional explicit stream protocol label for diagnostics. */
|
|
246
|
-
streamProtocol?: string;
|
|
247
|
-
/** Optional anonymous/local access posture. */
|
|
248
|
-
allowAnonymous?: boolean;
|
|
249
|
-
anonymousConfigured?: boolean;
|
|
250
|
-
anonymousDetail?: string;
|
|
251
|
-
/** Override runtime auth posture when apiKey is an internal transport placeholder. */
|
|
252
|
-
authConfigured?: boolean;
|
|
253
|
-
/** Shared cache-hit tracker owned by the runtime service graph. */
|
|
254
|
-
cacheHitTracker?: Pick<CacheHitTracker, 'recordTurn'>;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* OpenAICompatProvider — generic OpenAI-compatible provider.
|
|
259
|
-
* Configured for InceptionLabs Mercury-2 with reasoning_effort and
|
|
260
|
-
* reasoning_summary extensions, but usable with any OAI-compatible API.
|
|
261
|
-
*/
|
|
262
|
-
export class OpenAICompatProvider implements LLMProvider {
|
|
263
|
-
readonly name: string;
|
|
264
|
-
readonly models: string[];
|
|
265
|
-
readonly capabilities?: Partial<ProviderCapability>;
|
|
266
|
-
|
|
267
|
-
private client: OpenAI;
|
|
268
|
-
private defaultModel: string;
|
|
269
|
-
private embeddingModel: string;
|
|
270
|
-
private readonly configured: boolean;
|
|
271
|
-
private reasoningFormat: 'mercury' | 'openrouter' | 'llamacpp' | 'none';
|
|
272
|
-
private cacheCapability: ProviderCacheCapability;
|
|
273
|
-
private readonly authEnvVars: readonly string[];
|
|
274
|
-
private readonly serviceNames: readonly string[];
|
|
275
|
-
private readonly subscriptionProviderId?: string;
|
|
276
|
-
private readonly suppressedModels: readonly string[];
|
|
277
|
-
private readonly aliases: readonly string[];
|
|
278
|
-
private readonly streamProtocol?: string;
|
|
279
|
-
private readonly allowAnonymous: boolean;
|
|
280
|
-
private readonly anonymousConfigured: boolean;
|
|
281
|
-
private readonly anonymousDetail?: string;
|
|
282
|
-
private readonly cacheHitTracker: Pick<CacheHitTracker, 'recordTurn'>;
|
|
283
|
-
private readonly baseURL: string;
|
|
284
|
-
private readonly endpointHost: string;
|
|
285
|
-
|
|
286
|
-
constructor(opts: OpenAICompatOptions) {
|
|
287
|
-
this.name = opts.name;
|
|
288
|
-
this.models = opts.models;
|
|
289
|
-
this.capabilities = opts.capabilities;
|
|
290
|
-
this.defaultModel = opts.defaultModel;
|
|
291
|
-
this.embeddingModel = opts.embeddingModel ?? opts.defaultModel;
|
|
292
|
-
this.configured = opts.authConfigured ?? Boolean(opts.apiKey);
|
|
293
|
-
this.reasoningFormat = opts.reasoningFormat ?? 'none';
|
|
294
|
-
this.cacheCapability = getCacheCapability(opts.name);
|
|
295
|
-
this.authEnvVars = opts.authEnvVars ?? [];
|
|
296
|
-
this.serviceNames = opts.serviceNames ?? [];
|
|
297
|
-
this.subscriptionProviderId = opts.subscriptionProviderId;
|
|
298
|
-
this.suppressedModels = opts.suppressedModels ?? [];
|
|
299
|
-
this.aliases = opts.aliases ?? [];
|
|
300
|
-
this.streamProtocol = opts.streamProtocol;
|
|
301
|
-
this.allowAnonymous = opts.allowAnonymous ?? false;
|
|
302
|
-
this.anonymousConfigured = opts.anonymousConfigured ?? false;
|
|
303
|
-
this.anonymousDetail = opts.anonymousDetail;
|
|
304
|
-
this.cacheHitTracker = opts.cacheHitTracker ?? NOOP_CACHE_HIT_TRACKER;
|
|
305
|
-
this.baseURL = opts.baseURL;
|
|
306
|
-
this.endpointHost = (() => {
|
|
307
|
-
try {
|
|
308
|
-
return new URL(opts.baseURL).host;
|
|
309
|
-
} catch {
|
|
310
|
-
return opts.baseURL;
|
|
311
|
-
}
|
|
312
|
-
})();
|
|
313
|
-
this.client = new OpenAI({
|
|
314
|
-
apiKey: opts.apiKey,
|
|
315
|
-
baseURL: opts.baseURL,
|
|
316
|
-
...(opts.defaultHeaders ? { defaultHeaders: opts.defaultHeaders } : {}),
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async chat(params: ChatRequest): Promise<ChatResponse> {
|
|
321
|
-
const {
|
|
322
|
-
messages,
|
|
323
|
-
tools,
|
|
324
|
-
model,
|
|
325
|
-
maxTokens,
|
|
326
|
-
signal,
|
|
327
|
-
systemPrompt,
|
|
328
|
-
reasoningEffort,
|
|
329
|
-
reasoningSummary,
|
|
330
|
-
onDelta,
|
|
331
|
-
} = params;
|
|
332
|
-
|
|
333
|
-
return withRetry(async () => {
|
|
334
|
-
const allowReasoningStream = this.reasoningFormat !== 'none';
|
|
335
|
-
let responseText = '';
|
|
336
|
-
let inputTokens = 0;
|
|
337
|
-
let outputTokens = 0;
|
|
338
|
-
let cacheReadTokens = 0;
|
|
339
|
-
let stopReason: ChatResponse['stopReason'] = 'end';
|
|
340
|
-
let reasoningSummaryText: string | undefined;
|
|
341
|
-
let rawToolCalls: OpenAIToolCall[] = [];
|
|
342
|
-
const selectedModel = model ?? this.defaultModel;
|
|
343
|
-
const requestFingerprint = buildChatRequestFingerprint(params, selectedModel);
|
|
344
|
-
|
|
345
|
-
const openaiMessages = toOpenAIMessages(messages, systemPrompt);
|
|
346
|
-
const openaiTools = tools && tools.length > 0 ? toOpenAITools(tools) : undefined;
|
|
347
|
-
|
|
348
|
-
// Provider-specific reasoning params
|
|
349
|
-
const extraBody: Record<string, unknown> = {};
|
|
350
|
-
if (reasoningEffort && this.reasoningFormat === 'mercury') {
|
|
351
|
-
extraBody['reasoning_effort'] = reasoningEffort;
|
|
352
|
-
} else if (reasoningEffort && this.reasoningFormat === 'openrouter') {
|
|
353
|
-
extraBody['reasoning'] = { effort: reasoningEffort };
|
|
354
|
-
} else if (this.reasoningFormat === 'llamacpp') {
|
|
355
|
-
// llama.cpp auto-enables thinking for capable models; explicitly control it
|
|
356
|
-
extraBody['enable_thinking'] = reasoningEffort !== undefined && reasoningEffort !== 'instant';
|
|
357
|
-
}
|
|
358
|
-
// reasoningFormat === 'none': don't send anything
|
|
359
|
-
|
|
360
|
-
if (reasoningSummary && this.reasoningFormat === 'mercury') {
|
|
361
|
-
extraBody['reasoning_summary'] = true;
|
|
362
|
-
// Wait for the full reasoning summary before streaming text
|
|
363
|
-
extraBody['reasoning_summary_wait'] = true;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Build per-request headers for cache optimization
|
|
367
|
-
const requestHeaders: Record<string, string> = {};
|
|
368
|
-
if (this.cacheCapability.type === 'automatic' && this.cacheCapability.sessionAffinityHeader) {
|
|
369
|
-
requestHeaders[this.cacheCapability.sessionAffinityHeader] = 'true';
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
let streamOpened = false;
|
|
373
|
-
logger.debug('OpenAICompatProvider.chat request', {
|
|
374
|
-
provider: this.name,
|
|
375
|
-
endpointHost: this.endpointHost,
|
|
376
|
-
endpoint: this.baseURL,
|
|
377
|
-
request: requestFingerprint,
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
try {
|
|
381
|
-
const stream = await this.client.chat.completions.create(
|
|
382
|
-
{
|
|
383
|
-
model: selectedModel,
|
|
384
|
-
messages: openaiMessages as Parameters<typeof this.client.chat.completions.create>[0]['messages'],
|
|
385
|
-
...(openaiTools ? { tools: openaiTools as Parameters<typeof this.client.chat.completions.create>[0]['tools'] } : {}),
|
|
386
|
-
...(maxTokens ? { max_tokens: maxTokens } : {}),
|
|
387
|
-
stream: true,
|
|
388
|
-
stream_options: { include_usage: true },
|
|
389
|
-
...extraBody,
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
signal,
|
|
393
|
-
...(Object.keys(requestHeaders).length > 0 ? { headers: requestHeaders } : {}),
|
|
394
|
-
},
|
|
395
|
-
);
|
|
396
|
-
streamOpened = true;
|
|
397
|
-
logger.debug('OpenAICompatProvider.chat stream opened', {
|
|
398
|
-
provider: this.name,
|
|
399
|
-
endpointHost: this.endpointHost,
|
|
400
|
-
model: selectedModel,
|
|
401
|
-
messageCount: requestFingerprint.messageCount,
|
|
402
|
-
toolCount: requestFingerprint.toolCount,
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
const accToolCalls: Map<number, { id: string; name: string; args: string }> = new Map();
|
|
406
|
-
|
|
407
|
-
for await (const chunk of stream) {
|
|
408
|
-
const raw = chunk as typeof chunk & {
|
|
409
|
-
usage?: { prompt_tokens?: number; completion_tokens?: number };
|
|
410
|
-
reasoning_summary?: string;
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
const delta = raw.choices[0]?.delta;
|
|
414
|
-
const textDelta = extractOpenAIStreamTextDelta(raw, { allowReasoning: allowReasoningStream });
|
|
415
|
-
for (const contentDelta of textDelta.content) {
|
|
416
|
-
responseText += contentDelta;
|
|
417
|
-
if (onDelta) onDelta({ content: contentDelta });
|
|
418
|
-
}
|
|
419
|
-
for (const reasoningDelta of textDelta.reasoning) {
|
|
420
|
-
if (onDelta) onDelta({ reasoning: reasoningDelta });
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Mercury-2: reasoning_summary may appear on any chunk — capture and emit
|
|
424
|
-
if (allowReasoningStream && raw.reasoning_summary) {
|
|
425
|
-
reasoningSummaryText = raw.reasoning_summary;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Accumulate streaming tool_calls deltas
|
|
429
|
-
if (delta?.tool_calls) {
|
|
430
|
-
for (const tc of delta.tool_calls) {
|
|
431
|
-
const idx = tc.index;
|
|
432
|
-
if (!accToolCalls.has(idx)) {
|
|
433
|
-
accToolCalls.set(idx, { id: tc.id ?? '', name: tc.function?.name ?? '', args: '' });
|
|
434
|
-
}
|
|
435
|
-
const entry = accToolCalls.get(idx)!;
|
|
436
|
-
if (tc.id) entry.id = tc.id;
|
|
437
|
-
if (tc.function?.name) entry.name = tc.function.name;
|
|
438
|
-
if (tc.function?.arguments) entry.args += tc.function.arguments;
|
|
439
|
-
if (onDelta) {
|
|
440
|
-
onDelta({ toolCalls: [{ index: idx, id: tc.id, name: tc.function?.name, arguments: tc.function?.arguments }] });
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const finishReason = raw.choices[0]?.finish_reason;
|
|
446
|
-
if (finishReason === 'tool_calls') stopReason = 'tool_use';
|
|
447
|
-
else if (finishReason === 'length') stopReason = 'max_tokens';
|
|
448
|
-
|
|
449
|
-
if (raw.usage) {
|
|
450
|
-
const rawUsage = raw.usage as {
|
|
451
|
-
prompt_tokens?: number;
|
|
452
|
-
completion_tokens?: number;
|
|
453
|
-
prompt_tokens_details?: { cached_tokens?: number };
|
|
454
|
-
};
|
|
455
|
-
inputTokens = rawUsage.prompt_tokens ?? 0;
|
|
456
|
-
outputTokens = rawUsage.completion_tokens ?? 0;
|
|
457
|
-
cacheReadTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? cacheReadTokens;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
for (const [, tc] of [...accToolCalls.entries()].sort(([a], [b]) => a - b)) {
|
|
462
|
-
rawToolCalls.push({
|
|
463
|
-
id: tc.id,
|
|
464
|
-
type: 'function',
|
|
465
|
-
function: { name: tc.name, arguments: tc.args },
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
} catch (err: unknown) {
|
|
469
|
-
const diagnostic = extractOpenAICompatErrorDiagnostic(err);
|
|
470
|
-
const phase = streamOpened ? 'stream' : 'request';
|
|
471
|
-
const message = buildOpenAICompatErrorMessage(this.name, phase, diagnostic);
|
|
472
|
-
logger.error('OpenAICompatProvider.chat failed', {
|
|
473
|
-
provider: this.name,
|
|
474
|
-
endpointHost: this.endpointHost,
|
|
475
|
-
endpoint: this.baseURL,
|
|
476
|
-
phase,
|
|
477
|
-
requestAccepted: streamOpened,
|
|
478
|
-
request: requestFingerprint,
|
|
479
|
-
status: diagnostic.status,
|
|
480
|
-
code: diagnostic.code,
|
|
481
|
-
type: diagnostic.type,
|
|
482
|
-
requestId: diagnostic.requestId,
|
|
483
|
-
detail: diagnostic.detail,
|
|
484
|
-
rawMessage: diagnostic.rawMessage,
|
|
485
|
-
});
|
|
486
|
-
throw new ProviderError(message, {
|
|
487
|
-
statusCode: diagnostic.status,
|
|
488
|
-
provider: this.name,
|
|
489
|
-
operation: 'chat',
|
|
490
|
-
phase,
|
|
491
|
-
requestId: diagnostic.requestId,
|
|
492
|
-
providerCode: diagnostic.code,
|
|
493
|
-
providerType: diagnostic.type,
|
|
494
|
-
detail: diagnostic.detail,
|
|
495
|
-
rawMessage: diagnostic.rawMessage,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// Some models (e.g. kimi-k2-thinking via ollama-cloud) emit tool calls as
|
|
500
|
-
// raw text tokens instead of the OpenAI function-calling wire format.
|
|
501
|
-
// Fall back to text extraction when no structured tool calls were found.
|
|
502
|
-
let toolCalls = rawToolCalls.length > 0 ? fromOpenAIToolCalls(rawToolCalls) : [];
|
|
503
|
-
if (toolCalls.length === 0 && (responseText.includes('<|toolcallbegin|>') || responseText.includes('<|tool_call_begin|>'))) {
|
|
504
|
-
const extracted = extractTextToolCalls(responseText);
|
|
505
|
-
if (extracted.toolCalls.length > 0) {
|
|
506
|
-
toolCalls = extracted.toolCalls;
|
|
507
|
-
responseText = extracted.cleanedContent;
|
|
508
|
-
stopReason = 'tool_use';
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const response: ChatResponse = {
|
|
513
|
-
content: responseText,
|
|
514
|
-
toolCalls,
|
|
515
|
-
usage: {
|
|
516
|
-
inputTokens,
|
|
517
|
-
outputTokens,
|
|
518
|
-
...(cacheReadTokens > 0 ? { cacheReadTokens } : {}),
|
|
519
|
-
},
|
|
520
|
-
stopReason,
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
if (reasoningSummaryText) {
|
|
524
|
-
response.reasoningSummary = reasoningSummaryText;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
this.cacheHitTracker.recordTurn({
|
|
528
|
-
inputTokens,
|
|
529
|
-
cacheReadTokens,
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
return response;
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
async embed(request: ProviderEmbeddingRequest): Promise<ProviderEmbeddingResult> {
|
|
537
|
-
let response;
|
|
538
|
-
try {
|
|
539
|
-
response = await this.client.embeddings.create(
|
|
540
|
-
{
|
|
541
|
-
model: request.model ?? this.embeddingModel,
|
|
542
|
-
input: request.text,
|
|
543
|
-
...(request.dimensions ? { dimensions: request.dimensions } : {}),
|
|
544
|
-
},
|
|
545
|
-
request.signal ? { signal: request.signal } : undefined,
|
|
546
|
-
);
|
|
547
|
-
} catch (error: unknown) {
|
|
548
|
-
throw toProviderError(error, {
|
|
549
|
-
provider: this.name,
|
|
550
|
-
operation: 'embed',
|
|
551
|
-
phase: 'request',
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
const embedding = response.data[0]?.embedding ?? [];
|
|
555
|
-
return {
|
|
556
|
-
vector: Float32Array.from(embedding),
|
|
557
|
-
dimensions: embedding.length,
|
|
558
|
-
modelId: response.model,
|
|
559
|
-
metadata: {
|
|
560
|
-
usage: request.usage,
|
|
561
|
-
provider: this.name,
|
|
562
|
-
},
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
async describeRuntime(deps: ProviderRuntimeMetadataDeps): Promise<ProviderRuntimeMetadata> {
|
|
567
|
-
const { buildStandardProviderAuthRoutes } = await import('./runtime-metadata.ts');
|
|
568
|
-
const authRoutes = await buildStandardProviderAuthRoutes({
|
|
569
|
-
providerId: this.name,
|
|
570
|
-
apiKeyEnvVars: this.authEnvVars,
|
|
571
|
-
secretKeys: this.authEnvVars,
|
|
572
|
-
serviceNames: this.serviceNames,
|
|
573
|
-
...(this.subscriptionProviderId ? { subscriptionProviderId: this.subscriptionProviderId } : {}),
|
|
574
|
-
allowAnonymous: this.allowAnonymous,
|
|
575
|
-
anonymousConfigured: this.anonymousConfigured,
|
|
576
|
-
anonymousDetail: this.anonymousDetail,
|
|
577
|
-
}, deps);
|
|
578
|
-
return {
|
|
579
|
-
auth: {
|
|
580
|
-
mode: this.allowAnonymous && !this.configured ? 'anonymous' : 'api-key',
|
|
581
|
-
configured: this.configured || this.anonymousConfigured,
|
|
582
|
-
detail: this.configured
|
|
583
|
-
? `${this.name} API key available`
|
|
584
|
-
: this.allowAnonymous
|
|
585
|
-
? (this.anonymousDetail ?? `${this.name} can be used without a stored API key`)
|
|
586
|
-
: `API key for ${this.name} is not configured`,
|
|
587
|
-
...(this.authEnvVars.length > 0 ? { envVars: this.authEnvVars } : {}),
|
|
588
|
-
routes: authRoutes,
|
|
589
|
-
},
|
|
590
|
-
models: {
|
|
591
|
-
defaultModel: this.defaultModel,
|
|
592
|
-
models: this.models,
|
|
593
|
-
embeddingModel: this.embeddingModel,
|
|
594
|
-
...(this.aliases.length > 0 ? { aliases: this.aliases } : {}),
|
|
595
|
-
...(this.suppressedModels.length > 0 ? { suppressedModels: this.suppressedModels } : {}),
|
|
596
|
-
},
|
|
597
|
-
usage: {
|
|
598
|
-
streaming: true,
|
|
599
|
-
toolCalling: this.capabilities?.toolCalling ?? true,
|
|
600
|
-
parallelTools: this.capabilities?.parallelTools ?? false,
|
|
601
|
-
promptCaching: this.cacheCapability.type !== 'none',
|
|
602
|
-
notes: this.reasoningFormat !== 'none'
|
|
603
|
-
? ['Provider supports reasoning-aware request routing.']
|
|
604
|
-
: undefined,
|
|
605
|
-
},
|
|
606
|
-
policy: {
|
|
607
|
-
local: false,
|
|
608
|
-
streamProtocol: this.streamProtocol ?? 'openai-chat-completions',
|
|
609
|
-
reasoningMode: this.reasoningFormat === 'none' ? 'provider-default' : this.reasoningFormat,
|
|
610
|
-
supportedReasoningEfforts: ['instant', 'low', 'medium', 'high'],
|
|
611
|
-
cacheStrategy: this.cacheCapability.type,
|
|
612
|
-
},
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
}
|