@pellux/goodvibes-tui 0.18.11 → 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 +22 -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,88 +0,0 @@
|
|
|
1
|
-
import type { WebSearchProvider, WebSearchProviderResponse, WebSearchRequest } from '@pellux/goodvibes-sdk/platform/web-search/types';
|
|
2
|
-
import {
|
|
3
|
-
buildDescriptor,
|
|
4
|
-
executeJsonRequest,
|
|
5
|
-
firstString,
|
|
6
|
-
resultFromRecord,
|
|
7
|
-
type SearchProviderContext,
|
|
8
|
-
} from '@pellux/goodvibes-sdk/platform/web-search/providers/shared';
|
|
9
|
-
|
|
10
|
-
const SEARXNG_ENV_KEYS = ['SEARXNG_BASE_URL'] as const;
|
|
11
|
-
const SEARXNG_SERVICE_NAME = 'searxng';
|
|
12
|
-
|
|
13
|
-
function mapTimeRange(value: WebSearchRequest['timeRange']): string | undefined {
|
|
14
|
-
switch (value) {
|
|
15
|
-
case 'day':
|
|
16
|
-
return 'day';
|
|
17
|
-
case 'month':
|
|
18
|
-
return 'month';
|
|
19
|
-
case 'year':
|
|
20
|
-
return 'year';
|
|
21
|
-
default:
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function createSearxngSearchProvider(context: SearchProviderContext): WebSearchProvider {
|
|
27
|
-
const env = context.env;
|
|
28
|
-
const serviceRegistry = context.serviceRegistry;
|
|
29
|
-
return {
|
|
30
|
-
id: 'searxng',
|
|
31
|
-
label: 'SearXNG',
|
|
32
|
-
capabilities: ['search', 'evidence'],
|
|
33
|
-
descriptor() {
|
|
34
|
-
return buildDescriptor({
|
|
35
|
-
id: 'searxng',
|
|
36
|
-
label: 'SearXNG',
|
|
37
|
-
note: 'Uses a SearXNG instance via its JSON search API. Configure SEARXNG_BASE_URL or a searxng service entry.',
|
|
38
|
-
requiresAuth: false,
|
|
39
|
-
serviceName: SEARXNG_SERVICE_NAME,
|
|
40
|
-
baseUrlEnvCandidates: SEARXNG_ENV_KEYS,
|
|
41
|
-
}, { env, serviceRegistry });
|
|
42
|
-
},
|
|
43
|
-
async search(request: WebSearchRequest): Promise<WebSearchProviderResponse> {
|
|
44
|
-
const maxResults = Math.max(1, Math.min(25, request.maxResults ?? 10));
|
|
45
|
-
const baseUrl = (env.SEARXNG_BASE_URL ?? serviceRegistry.get(SEARXNG_SERVICE_NAME)?.baseUrl ?? '').trim().replace(/\/+$/, '');
|
|
46
|
-
if (!baseUrl) {
|
|
47
|
-
throw new Error('SearXNG requires SEARXNG_BASE_URL or a searxng service entry with baseUrl.');
|
|
48
|
-
}
|
|
49
|
-
const { payload } = await executeJsonRequest<Record<string, unknown>>({
|
|
50
|
-
url: `${baseUrl}/search`,
|
|
51
|
-
params: {
|
|
52
|
-
q: request.query,
|
|
53
|
-
format: 'json',
|
|
54
|
-
pageno: '1',
|
|
55
|
-
...(request.region ? { language: request.region } : {}),
|
|
56
|
-
...(mapTimeRange(request.timeRange) ? { time_range: mapTimeRange(request.timeRange)! } : {}),
|
|
57
|
-
},
|
|
58
|
-
headers: { Accept: 'application/json' },
|
|
59
|
-
service: serviceRegistry.get(SEARXNG_SERVICE_NAME) ? SEARXNG_SERVICE_NAME : undefined,
|
|
60
|
-
fetcher: context.fetcher,
|
|
61
|
-
});
|
|
62
|
-
const results = Array.isArray(payload.results)
|
|
63
|
-
? payload.results
|
|
64
|
-
.slice(0, maxResults)
|
|
65
|
-
.map((entry, index) => {
|
|
66
|
-
if (!entry || typeof entry !== 'object') return null;
|
|
67
|
-
const record = entry as Record<string, unknown>;
|
|
68
|
-
return resultFromRecord('searxng', index + 1, record, {
|
|
69
|
-
urlKeys: ['url'],
|
|
70
|
-
titleKeys: ['title'],
|
|
71
|
-
snippetKeys: ['content'],
|
|
72
|
-
metadata: {
|
|
73
|
-
engine: firstString(record, ['engine']),
|
|
74
|
-
publishedDate: firstString(record, ['publishedDate', 'published_date']),
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
})
|
|
78
|
-
.filter((entry): entry is NonNullable<typeof entry> => entry !== null)
|
|
79
|
-
: [];
|
|
80
|
-
return {
|
|
81
|
-
results,
|
|
82
|
-
metadata: {
|
|
83
|
-
numberOfResults: typeof payload.number_of_results === 'number' ? payload.number_of_results : undefined,
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import type { ServiceRegistry } from '../../config/service-registry.ts';
|
|
2
|
-
import { executeFetchInput, type FetchOutput, type FetchUrlResult } from '@pellux/goodvibes-sdk/platform/tools/fetch/index';
|
|
3
|
-
import type { FetchAuthInput, FetchInput, FetchUrlInput } from '@pellux/goodvibes-sdk/platform/tools/fetch/schema';
|
|
4
|
-
import type { WebSearchEvidence, WebSearchProviderDescriptor, WebSearchResult } from '@pellux/goodvibes-sdk/platform/web-search/types';
|
|
5
|
-
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
6
|
-
|
|
7
|
-
type EnvMap = Record<string, string | undefined>;
|
|
8
|
-
type FetchExecutor = (input: FetchInput) => Promise<FetchOutput>;
|
|
9
|
-
|
|
10
|
-
export interface SearchProviderContext {
|
|
11
|
-
readonly fetcher?: FetchExecutor;
|
|
12
|
-
readonly env: EnvMap;
|
|
13
|
-
readonly serviceRegistry: Pick<ServiceRegistry, 'get'>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface SearchProviderConfig {
|
|
17
|
-
readonly id: string;
|
|
18
|
-
readonly label: string;
|
|
19
|
-
readonly note: string;
|
|
20
|
-
readonly envKeyCandidates?: readonly string[];
|
|
21
|
-
readonly serviceName?: string;
|
|
22
|
-
readonly baseUrlEnvCandidates?: readonly string[];
|
|
23
|
-
readonly defaultBaseUrl?: string;
|
|
24
|
-
readonly requiresAuth?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface JsonRequestConfig {
|
|
28
|
-
readonly url: string;
|
|
29
|
-
readonly method?: 'GET' | 'POST';
|
|
30
|
-
readonly params?: Record<string, string>;
|
|
31
|
-
readonly body?: Record<string, unknown>;
|
|
32
|
-
readonly headers?: Record<string, string>;
|
|
33
|
-
readonly service?: string;
|
|
34
|
-
readonly auth?: FetchAuthInput;
|
|
35
|
-
readonly fetcher?: FetchExecutor;
|
|
36
|
-
readonly maxContentLength?: number;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface JsonRequestResult<T = unknown> {
|
|
40
|
-
readonly payload: T;
|
|
41
|
-
readonly response: FetchUrlResult;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function resolveDomain(url: string): string | undefined {
|
|
45
|
-
try {
|
|
46
|
-
return new URL(url).hostname;
|
|
47
|
-
} catch {
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function trimSnippet(value: unknown, limit = 320): string | undefined {
|
|
53
|
-
if (typeof value !== 'string') return undefined;
|
|
54
|
-
const normalized = value.replace(/\s+/g, ' ').trim();
|
|
55
|
-
if (!normalized) return undefined;
|
|
56
|
-
if (normalized.length <= limit) return normalized;
|
|
57
|
-
return `${normalized.slice(0, Math.max(0, limit - 3)).trimEnd()}...`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function makeEvidence(
|
|
61
|
-
url: string,
|
|
62
|
-
content: unknown,
|
|
63
|
-
metadata: Record<string, unknown> = {},
|
|
64
|
-
extract: 'raw' | 'text' | 'json' | 'markdown' | 'readable' | 'code_blocks' | 'links' | 'metadata' | 'structured' | 'tables' | 'pdf' | 'summary' = 'summary',
|
|
65
|
-
): WebSearchEvidence[] | undefined {
|
|
66
|
-
if (typeof content !== 'string') return undefined;
|
|
67
|
-
const normalized = content.trim();
|
|
68
|
-
if (!normalized) return undefined;
|
|
69
|
-
return [{
|
|
70
|
-
url,
|
|
71
|
-
extract,
|
|
72
|
-
content: normalized,
|
|
73
|
-
tokensUsed: Math.ceil(normalized.length / 4),
|
|
74
|
-
metadata,
|
|
75
|
-
}];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function withInlineApiKey(
|
|
79
|
-
env: EnvMap,
|
|
80
|
-
envKeys: readonly string[] | undefined,
|
|
81
|
-
headerName: string,
|
|
82
|
-
): FetchAuthInput | undefined {
|
|
83
|
-
if (!envKeys || envKeys.length === 0) return undefined;
|
|
84
|
-
for (const key of envKeys) {
|
|
85
|
-
const value = env[key];
|
|
86
|
-
if (typeof value === 'string' && value.trim().length > 0) {
|
|
87
|
-
return {
|
|
88
|
-
type: 'api-key',
|
|
89
|
-
header: headerName,
|
|
90
|
-
key: value.trim(),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function withInlineBearer(
|
|
98
|
-
env: EnvMap,
|
|
99
|
-
envKeys: readonly string[] | undefined,
|
|
100
|
-
): FetchAuthInput | undefined {
|
|
101
|
-
if (!envKeys || envKeys.length === 0) return undefined;
|
|
102
|
-
for (const key of envKeys) {
|
|
103
|
-
const value = env[key];
|
|
104
|
-
if (typeof value === 'string' && value.trim().length > 0) {
|
|
105
|
-
return {
|
|
106
|
-
type: 'bearer',
|
|
107
|
-
token: value.trim(),
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return undefined;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export function hasConfiguredCredential(
|
|
115
|
-
serviceRegistry: Pick<ServiceRegistry, 'get'>,
|
|
116
|
-
env: EnvMap,
|
|
117
|
-
envKeys: readonly string[] | undefined,
|
|
118
|
-
serviceName?: string,
|
|
119
|
-
): boolean {
|
|
120
|
-
const envConfigured = (envKeys ?? []).some((key) => typeof env[key] === 'string' && env[key]!.trim().length > 0);
|
|
121
|
-
if (envConfigured) return true;
|
|
122
|
-
return Boolean(serviceName && serviceRegistry.get(serviceName));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export function resolveBaseUrl(
|
|
126
|
-
serviceRegistry: Pick<ServiceRegistry, 'get'>,
|
|
127
|
-
env: EnvMap,
|
|
128
|
-
envKeys: readonly string[] | undefined,
|
|
129
|
-
serviceName: string | undefined,
|
|
130
|
-
defaultBaseUrl?: string,
|
|
131
|
-
): string | null {
|
|
132
|
-
for (const key of envKeys ?? []) {
|
|
133
|
-
const value = env[key];
|
|
134
|
-
if (typeof value === 'string' && value.trim().length > 0) {
|
|
135
|
-
return value.trim().replace(/\/+$/, '');
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const configuredService = serviceName ? serviceRegistry.get(serviceName) : null;
|
|
139
|
-
const serviceUrl = configuredService?.baseUrl?.trim();
|
|
140
|
-
if (serviceUrl) return serviceUrl.replace(/\/+$/, '');
|
|
141
|
-
return defaultBaseUrl ? defaultBaseUrl.replace(/\/+$/, '') : null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function buildDescriptor(
|
|
145
|
-
config: SearchProviderConfig,
|
|
146
|
-
context: SearchProviderContext,
|
|
147
|
-
): WebSearchProviderDescriptor {
|
|
148
|
-
const configured = config.requiresAuth === false
|
|
149
|
-
? resolveBaseUrl(context.serviceRegistry, context.env, config.baseUrlEnvCandidates, config.serviceName, config.defaultBaseUrl) != null
|
|
150
|
-
: hasConfiguredCredential(context.serviceRegistry, context.env, config.envKeyCandidates, config.serviceName);
|
|
151
|
-
return {
|
|
152
|
-
id: config.id,
|
|
153
|
-
label: config.label,
|
|
154
|
-
capabilities: ['search', 'evidence'],
|
|
155
|
-
requiresAuth: config.requiresAuth ?? true,
|
|
156
|
-
configured,
|
|
157
|
-
note: config.note,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export async function executeJsonRequest<T = unknown>(config: JsonRequestConfig): Promise<JsonRequestResult<T>> {
|
|
162
|
-
const fetcher = config.fetcher ?? executeFetchInput;
|
|
163
|
-
const urlInput: FetchUrlInput = {
|
|
164
|
-
url: config.url,
|
|
165
|
-
method: config.method ?? 'GET',
|
|
166
|
-
extract: 'json',
|
|
167
|
-
...(config.params ? { params: config.params } : {}),
|
|
168
|
-
...(config.headers ? { headers: config.headers } : {}),
|
|
169
|
-
...(config.body ? { body_type: 'json', body: JSON.stringify(config.body) } : {}),
|
|
170
|
-
...(config.service ? { service: config.service } : {}),
|
|
171
|
-
...(config.auth ? { auth: config.auth } : {}),
|
|
172
|
-
...(config.maxContentLength ? { max_content_length: config.maxContentLength } : {}),
|
|
173
|
-
};
|
|
174
|
-
const output = await fetcher({
|
|
175
|
-
urls: [urlInput],
|
|
176
|
-
parallel: false,
|
|
177
|
-
verbosity: 'standard',
|
|
178
|
-
sanitize_mode: 'safe-text',
|
|
179
|
-
max_content_length: config.maxContentLength ?? 512_000,
|
|
180
|
-
});
|
|
181
|
-
const response = output.results?.[0];
|
|
182
|
-
if (!response || response.error || typeof response.content !== 'string') {
|
|
183
|
-
throw new Error(response?.error ?? `Search provider request failed for ${config.url}`);
|
|
184
|
-
}
|
|
185
|
-
let payload: T;
|
|
186
|
-
try {
|
|
187
|
-
payload = JSON.parse(response.content) as T;
|
|
188
|
-
} catch (error) {
|
|
189
|
-
throw new Error(`Search provider returned invalid JSON for ${config.url}: ${summarizeError(error)}`);
|
|
190
|
-
}
|
|
191
|
-
return { payload, response };
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function resultFromRecord(
|
|
195
|
-
providerId: string,
|
|
196
|
-
rank: number,
|
|
197
|
-
record: Record<string, unknown>,
|
|
198
|
-
options: {
|
|
199
|
-
readonly urlKeys?: readonly string[];
|
|
200
|
-
readonly titleKeys?: readonly string[];
|
|
201
|
-
readonly snippetKeys?: readonly string[];
|
|
202
|
-
readonly displayUrlKeys?: readonly string[];
|
|
203
|
-
readonly evidenceKeys?: readonly string[];
|
|
204
|
-
readonly metadata?: Record<string, unknown>;
|
|
205
|
-
} = {},
|
|
206
|
-
): WebSearchResult | null {
|
|
207
|
-
const url = firstString(record, options.urlKeys ?? ['url', 'link', 'id']);
|
|
208
|
-
if (!url) return null;
|
|
209
|
-
return {
|
|
210
|
-
rank,
|
|
211
|
-
url,
|
|
212
|
-
...(firstString(record, options.titleKeys ?? ['title', 'name', 'heading']) ? { title: firstString(record, options.titleKeys ?? ['title', 'name', 'heading']) } : {}),
|
|
213
|
-
...(trimSnippet(firstString(record, options.snippetKeys ?? ['snippet', 'description', 'content', 'text'])) ? { snippet: trimSnippet(firstString(record, options.snippetKeys ?? ['snippet', 'description', 'content', 'text'])) } : {}),
|
|
214
|
-
...(firstString(record, options.displayUrlKeys ?? ['displayUrl', 'display_url']) ? { displayUrl: firstString(record, options.displayUrlKeys ?? ['displayUrl', 'display_url']) } : {}),
|
|
215
|
-
...(resolveDomain(url) ? { domain: resolveDomain(url) } : {}),
|
|
216
|
-
type: 'organic',
|
|
217
|
-
providerId,
|
|
218
|
-
metadata: {
|
|
219
|
-
...(options.metadata ?? {}),
|
|
220
|
-
...(options.evidenceKeys
|
|
221
|
-
? {
|
|
222
|
-
hasProviderEvidence: options.evidenceKeys.some((key) => typeof record[key] === 'string' && String(record[key]).trim().length > 0),
|
|
223
|
-
}
|
|
224
|
-
: {}),
|
|
225
|
-
},
|
|
226
|
-
...(providerEvidence(url, record, options.evidenceKeys) ? { evidence: providerEvidence(url, record, options.evidenceKeys) } : {}),
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function firstString(record: Record<string, unknown>, keys: readonly string[]): string | undefined {
|
|
231
|
-
for (const key of keys) {
|
|
232
|
-
const value = record[key];
|
|
233
|
-
if (typeof value === 'string' && value.trim().length > 0) return value.trim();
|
|
234
|
-
}
|
|
235
|
-
return undefined;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function providerEvidence(
|
|
239
|
-
url: string,
|
|
240
|
-
record: Record<string, unknown>,
|
|
241
|
-
keys: readonly string[] | undefined,
|
|
242
|
-
): WebSearchEvidence[] | undefined {
|
|
243
|
-
for (const key of keys ?? []) {
|
|
244
|
-
const value = record[key];
|
|
245
|
-
if (typeof value !== 'string' || value.trim().length === 0) continue;
|
|
246
|
-
return makeEvidence(url, value, { providerField: key });
|
|
247
|
-
}
|
|
248
|
-
return undefined;
|
|
249
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import type { WebSearchInstantAnswer, WebSearchProvider, WebSearchProviderResponse, WebSearchRequest } from '@pellux/goodvibes-sdk/platform/web-search/types';
|
|
2
|
-
import {
|
|
3
|
-
buildDescriptor,
|
|
4
|
-
executeJsonRequest,
|
|
5
|
-
firstString,
|
|
6
|
-
resultFromRecord,
|
|
7
|
-
withInlineBearer,
|
|
8
|
-
type SearchProviderContext,
|
|
9
|
-
} from '@pellux/goodvibes-sdk/platform/web-search/providers/shared';
|
|
10
|
-
|
|
11
|
-
const TAVILY_DEFAULT_BASE_URL = 'https://api.tavily.com';
|
|
12
|
-
const TAVILY_ENV_KEYS = ['TAVILY_API_KEY'] as const;
|
|
13
|
-
const TAVILY_SERVICE_NAME = 'tavily';
|
|
14
|
-
|
|
15
|
-
function buildInstantAnswer(payload: Record<string, unknown>): WebSearchInstantAnswer | undefined {
|
|
16
|
-
const answer = firstString(payload, ['answer']);
|
|
17
|
-
if (!answer) return undefined;
|
|
18
|
-
return {
|
|
19
|
-
heading: 'Tavily Answer',
|
|
20
|
-
answer,
|
|
21
|
-
type: 'answer',
|
|
22
|
-
related: [],
|
|
23
|
-
metadata: {},
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function createTavilySearchProvider(context: SearchProviderContext): WebSearchProvider {
|
|
28
|
-
const env = context.env;
|
|
29
|
-
const serviceRegistry = context.serviceRegistry;
|
|
30
|
-
return {
|
|
31
|
-
id: 'tavily',
|
|
32
|
-
label: 'Tavily',
|
|
33
|
-
capabilities: ['search', 'instant_answer', 'evidence'],
|
|
34
|
-
descriptor() {
|
|
35
|
-
return buildDescriptor({
|
|
36
|
-
id: 'tavily',
|
|
37
|
-
label: 'Tavily',
|
|
38
|
-
note: 'Uses Tavily Search JSON results. Configure via TAVILY_API_KEY or a tavily service entry.',
|
|
39
|
-
envKeyCandidates: TAVILY_ENV_KEYS,
|
|
40
|
-
serviceName: TAVILY_SERVICE_NAME,
|
|
41
|
-
defaultBaseUrl: TAVILY_DEFAULT_BASE_URL,
|
|
42
|
-
}, { env, serviceRegistry });
|
|
43
|
-
},
|
|
44
|
-
async search(request: WebSearchRequest): Promise<WebSearchProviderResponse> {
|
|
45
|
-
const maxResults = Math.max(1, Math.min(20, request.maxResults ?? 10));
|
|
46
|
-
const baseUrl = (serviceRegistry.get(TAVILY_SERVICE_NAME)?.baseUrl ?? TAVILY_DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
47
|
-
const { payload } = await executeJsonRequest<Record<string, unknown>>({
|
|
48
|
-
url: `${baseUrl}/search`,
|
|
49
|
-
method: 'POST',
|
|
50
|
-
headers: { Accept: 'application/json' },
|
|
51
|
-
body: {
|
|
52
|
-
query: request.query,
|
|
53
|
-
max_results: maxResults,
|
|
54
|
-
include_answer: request.includeInstantAnswer !== false,
|
|
55
|
-
search_depth: request.includeEvidence || request.verbosity === 'evidence' || request.verbosity === 'full'
|
|
56
|
-
? 'advanced'
|
|
57
|
-
: 'basic',
|
|
58
|
-
},
|
|
59
|
-
service: serviceRegistry.get(TAVILY_SERVICE_NAME) ? TAVILY_SERVICE_NAME : undefined,
|
|
60
|
-
auth: serviceRegistry.get(TAVILY_SERVICE_NAME) ? undefined : withInlineBearer(env, TAVILY_ENV_KEYS),
|
|
61
|
-
fetcher: context.fetcher,
|
|
62
|
-
});
|
|
63
|
-
const results = Array.isArray(payload.results)
|
|
64
|
-
? payload.results
|
|
65
|
-
.map((entry, index) => {
|
|
66
|
-
if (!entry || typeof entry !== 'object') return null;
|
|
67
|
-
const record = entry as Record<string, unknown>;
|
|
68
|
-
return resultFromRecord('tavily', index + 1, record, {
|
|
69
|
-
urlKeys: ['url'],
|
|
70
|
-
titleKeys: ['title'],
|
|
71
|
-
snippetKeys: ['content'],
|
|
72
|
-
evidenceKeys: ['raw_content'],
|
|
73
|
-
metadata: {
|
|
74
|
-
score: typeof record.score === 'number' ? record.score : undefined,
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
})
|
|
78
|
-
.filter((entry): entry is NonNullable<typeof entry> => entry !== null)
|
|
79
|
-
: [];
|
|
80
|
-
return {
|
|
81
|
-
results,
|
|
82
|
-
...(buildInstantAnswer(payload) ? { instantAnswer: buildInstantAnswer(payload) } : {}),
|
|
83
|
-
metadata: {
|
|
84
|
-
requestId: firstString(payload, ['request_id']),
|
|
85
|
-
responseTime: firstString(payload, ['response_time']),
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { FetchRuntimeService, type FetchRuntimeDeps } from '@pellux/goodvibes-sdk/platform/tools/fetch/index';
|
|
2
|
-
import type { FetchExtractMode } from '@pellux/goodvibes-sdk/platform/tools/fetch/schema';
|
|
3
|
-
import { WebSearchProviderRegistry } from '@pellux/goodvibes-sdk/platform/web-search/provider-registry';
|
|
4
|
-
import type {
|
|
5
|
-
WebSearchEvidence,
|
|
6
|
-
WebSearchProvider,
|
|
7
|
-
WebSearchRequest,
|
|
8
|
-
WebSearchResponse,
|
|
9
|
-
WebSearchResult,
|
|
10
|
-
WebSearchVerbosity,
|
|
11
|
-
} from '@pellux/goodvibes-sdk/platform/web-search/types';
|
|
12
|
-
|
|
13
|
-
export interface WebSearchServiceStatus {
|
|
14
|
-
readonly enabled: boolean;
|
|
15
|
-
readonly providerCount: number;
|
|
16
|
-
readonly providers: ReturnType<WebSearchProviderRegistry['list']>;
|
|
17
|
-
readonly note: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function selectEvidenceExtract(request: WebSearchRequest, verbosity: WebSearchVerbosity): FetchExtractMode {
|
|
21
|
-
if (request.evidenceExtract) return request.evidenceExtract;
|
|
22
|
-
return verbosity === 'full' ? 'readable' : 'summary';
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function shapeResultForVerbosity(result: WebSearchResult, verbosity: WebSearchVerbosity): WebSearchResult {
|
|
26
|
-
switch (verbosity) {
|
|
27
|
-
case 'urls_only':
|
|
28
|
-
return {
|
|
29
|
-
rank: result.rank,
|
|
30
|
-
url: result.url,
|
|
31
|
-
...(result.domain ? { domain: result.domain } : {}),
|
|
32
|
-
type: result.type,
|
|
33
|
-
providerId: result.providerId,
|
|
34
|
-
metadata: result.metadata,
|
|
35
|
-
};
|
|
36
|
-
case 'titles':
|
|
37
|
-
return {
|
|
38
|
-
...shapeResultForVerbosity(result, 'urls_only'),
|
|
39
|
-
...(result.title ? { title: result.title } : {}),
|
|
40
|
-
...(result.displayUrl ? { displayUrl: result.displayUrl } : {}),
|
|
41
|
-
};
|
|
42
|
-
case 'snippets':
|
|
43
|
-
return {
|
|
44
|
-
...shapeResultForVerbosity(result, 'titles'),
|
|
45
|
-
...(result.snippet ? { snippet: result.snippet } : {}),
|
|
46
|
-
};
|
|
47
|
-
default:
|
|
48
|
-
return result;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export class WebSearchService {
|
|
53
|
-
private readonly fetchRuntime = new FetchRuntimeService();
|
|
54
|
-
|
|
55
|
-
constructor(
|
|
56
|
-
private readonly registry: WebSearchProviderRegistry,
|
|
57
|
-
private readonly fetchDeps: FetchRuntimeDeps = {},
|
|
58
|
-
) {}
|
|
59
|
-
|
|
60
|
-
async getStatus(): Promise<WebSearchServiceStatus> {
|
|
61
|
-
const providers = this.registry.list();
|
|
62
|
-
return {
|
|
63
|
-
enabled: providers.length > 0,
|
|
64
|
-
providerCount: providers.length,
|
|
65
|
-
providers,
|
|
66
|
-
note: 'Web search uses provider-backed discovery and normalizes results before they reach the model.',
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async search(request: WebSearchRequest): Promise<WebSearchResponse> {
|
|
71
|
-
const provider = this.registry.find(request.providerId);
|
|
72
|
-
if (!provider) {
|
|
73
|
-
throw new Error(request.providerId ? `Web search provider unavailable: ${request.providerId}` : 'No web search provider is registered');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const verbosity = request.verbosity ?? 'snippets';
|
|
77
|
-
const baseResponse = await provider.search(request);
|
|
78
|
-
const evidenceEnabled = request.includeEvidence || verbosity === 'evidence' || verbosity === 'full';
|
|
79
|
-
const resultsWithEvidence = evidenceEnabled
|
|
80
|
-
? await this.attachEvidence(baseResponse.results, request)
|
|
81
|
-
: baseResponse.results;
|
|
82
|
-
const shapedResults = resultsWithEvidence.map((result) => shapeResultForVerbosity(result, verbosity));
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
providerId: provider.id,
|
|
86
|
-
providerLabel: provider.label,
|
|
87
|
-
query: request.query,
|
|
88
|
-
verbosity,
|
|
89
|
-
results: shapedResults,
|
|
90
|
-
...(baseResponse.instantAnswer ? { instantAnswer: baseResponse.instantAnswer } : {}),
|
|
91
|
-
metadata: baseResponse.metadata,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private async attachEvidence(results: readonly WebSearchResult[], request: WebSearchRequest): Promise<readonly WebSearchResult[]> {
|
|
96
|
-
const evidenceTopN = Math.max(1, Math.min(10, request.evidenceTopN ?? 3));
|
|
97
|
-
const extract = selectEvidenceExtract(request, request.verbosity ?? 'snippets');
|
|
98
|
-
const selectedIndexes = results
|
|
99
|
-
.map((result, index) => ({ result, index }))
|
|
100
|
-
.filter(({ result, index }) => index < evidenceTopN && (!result.evidence || result.evidence.length === 0));
|
|
101
|
-
if (selectedIndexes.length === 0) return results;
|
|
102
|
-
|
|
103
|
-
const fetched = await this.fetchRuntime.execute({
|
|
104
|
-
urls: selectedIndexes.map(({ result }) => ({
|
|
105
|
-
url: result.url,
|
|
106
|
-
extract,
|
|
107
|
-
max_content_length: extract === 'readable' ? 20_000 : 10_000,
|
|
108
|
-
})),
|
|
109
|
-
parallel: true,
|
|
110
|
-
verbosity: 'standard',
|
|
111
|
-
sanitize_mode: 'safe-text',
|
|
112
|
-
...(request.trustedHosts ? { trusted_hosts: [...request.trustedHosts] } : {}),
|
|
113
|
-
...(request.blockedHosts ? { blocked_hosts: [...request.blockedHosts] } : {}),
|
|
114
|
-
}, this.fetchDeps);
|
|
115
|
-
|
|
116
|
-
const evidenceByUrl = new Map<string, WebSearchEvidence>();
|
|
117
|
-
for (const result of fetched.results ?? []) {
|
|
118
|
-
if (!result.content || result.error) continue;
|
|
119
|
-
evidenceByUrl.set(result.url, {
|
|
120
|
-
url: result.final_url ?? result.url,
|
|
121
|
-
extract,
|
|
122
|
-
content: result.content,
|
|
123
|
-
tokensUsed: result.tokens_used ?? Math.ceil(result.content.length / 4),
|
|
124
|
-
...(result.status ? { status: result.status } : {}),
|
|
125
|
-
...(result.contentType ? { contentType: result.contentType } : {}),
|
|
126
|
-
...(result.truncated ? { truncated: true } : {}),
|
|
127
|
-
metadata: {
|
|
128
|
-
redirected: result.redirected ?? false,
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return results.map((result) => {
|
|
134
|
-
const evidence = evidenceByUrl.get(result.url);
|
|
135
|
-
if (!evidence) return result;
|
|
136
|
-
return {
|
|
137
|
-
...result,
|
|
138
|
-
evidence: [...(result.evidence ?? []), evidence],
|
|
139
|
-
};
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|