@vellumai/assistant 0.8.3 → 0.8.4
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/docker-entrypoint.sh +0 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +610 -16
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +272 -0
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/compaction-events.test.ts +1 -1
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +54 -3
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +31 -6
- package/src/__tests__/conversation-agent-loop.test.ts +25 -7
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +161 -0
- package/src/__tests__/conversation-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-load-cleaned-at.test.ts +279 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +6 -0
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +17 -16
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-resolver.test.ts +85 -1
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/openai-provider.test.ts +105 -0
- package/src/__tests__/openai-responses-provider.test.ts +4 -4
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +190 -0
- package/src/__tests__/platform.test.ts +0 -3
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/system-prompt.test.ts +51 -28
- package/src/__tests__/terminal-tools.test.ts +11 -1
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-executor.test.ts +90 -1
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +88 -5
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +57 -20
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +9 -12
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/memory-v2.ts +308 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +115 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +240 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +22 -12
- package/src/config/call-site-defaults.ts +19 -0
- package/src/config/feature-flag-registry.json +99 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +4 -0
- package/src/config/schemas/call-site-catalog.ts +21 -0
- package/src/config/schemas/llm.ts +3 -0
- package/src/config/schemas/memory-v2.ts +48 -1
- package/src/context/compactor.ts +8 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +153 -23
- package/src/daemon/conversation-agent-loop.ts +223 -54
- package/src/daemon/conversation-lifecycle.ts +142 -116
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +135 -75
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +7 -0
- package/src/daemon/conversation.ts +42 -5
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +79 -0
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-transfer-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +18 -4
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +8 -0
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/messages.ts +68 -1
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/query-complexity-router.ts +75 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +94 -0
- package/src/home/suggested-prompts.ts +177 -9
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +320 -6
- package/src/memory/conversation-crud.ts +133 -43
- package/src/memory/db-init.ts +16 -0
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/jobs-worker.ts +21 -1
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +3 -2
- package/src/memory/memory-retrospective-job.ts +408 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +26 -8
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/index.ts +17 -0
- package/src/memory/migrations/registry.ts +25 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +31 -14
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/router.test.ts +489 -1
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +21 -10
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/router.ts +209 -55
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +9 -1
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +4 -1
- package/src/plugins/defaults/injectors.ts +82 -9
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/sections.ts +32 -14
- package/src/prompts/system-prompt.ts +105 -68
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +8 -0
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +53 -3
- package/src/providers/anthropic/client.ts +132 -5
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +15 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/model-catalog.ts +48 -1
- package/src/providers/openai/chat-completions-provider.ts +57 -20
- package/src/providers/openai/responses-provider.ts +9 -3
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/types.ts +25 -0
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +151 -56
- package/src/runtime/auth/route-policy.ts +7 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -4
- package/src/runtime/pending-interactions.ts +51 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +55 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +271 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +146 -1
- package/src/runtime/routes/conversation-query-routes.ts +60 -1
- package/src/runtime/routes/conversation-routes.ts +281 -76
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +8 -1
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +12 -4
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-v2-routes.ts +217 -0
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/slack-channel-routes.ts +187 -0
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +80 -0
- package/src/tools/browser/browser-execution.ts +93 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +1 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +10 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +15 -1
- package/src/tools/browser/cdp-client/factory.ts +87 -3
- package/src/tools/browser/cdp-client/local-cdp-client.ts +9 -0
- package/src/tools/browser/cdp-client/types.ts +36 -0
- package/src/tools/browser/pinned-tabs.ts +90 -0
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +128 -2
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +213 -64
- package/src/tools/network/web-search.ts +191 -66
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/types.ts +4 -0
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/types/onboarding-context.ts +4 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/platform.ts +0 -5
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
TurnChannelContext,
|
|
14
14
|
TurnInterfaceContext,
|
|
15
15
|
} from "../channels/types.js";
|
|
16
|
+
import { getConfig } from "../config/loader.js";
|
|
16
17
|
import { recordEstimate } from "../context/estimator-calibration.js";
|
|
17
18
|
import { getCalibrationProviderKey } from "../context/token-estimator.js";
|
|
18
19
|
import {
|
|
@@ -31,6 +32,7 @@ import { backfillMemoryRecallLogMessageId } from "../memory/memory-recall-log-st
|
|
|
31
32
|
import { backfillMemoryV2ActivationMessageId } from "../memory/memory-v2-activation-log-store.js";
|
|
32
33
|
import { getThreadTs } from "../memory/slack-thread-store.js";
|
|
33
34
|
import {
|
|
35
|
+
formatSlackTimezoneLabel,
|
|
34
36
|
type SlackMessageMetadata,
|
|
35
37
|
writeSlackMetadata,
|
|
36
38
|
} from "../messaging/providers/slack/message-metadata.js";
|
|
@@ -46,7 +48,9 @@ import type {
|
|
|
46
48
|
import type { ContentBlock, ImageContent } from "../providers/types.js";
|
|
47
49
|
import { isContextOverflowError } from "../providers/types.js";
|
|
48
50
|
import { redactSecrets } from "../security/secret-scanner.js";
|
|
51
|
+
import { extractDomain } from "../tools/network/domain-normalize.js";
|
|
49
52
|
import { ProviderError } from "../util/errors.js";
|
|
53
|
+
import { faviconUrlForDomain } from "../util/favicon.js";
|
|
50
54
|
import { getLogger } from "../util/logger.js";
|
|
51
55
|
import type { DirectiveRequest } from "./assistant-attachments.js";
|
|
52
56
|
import {
|
|
@@ -60,7 +64,12 @@ import {
|
|
|
60
64
|
isContextTooLarge,
|
|
61
65
|
} from "./conversation-error.js";
|
|
62
66
|
import { isProviderOrderingError } from "./conversation-slash.js";
|
|
67
|
+
import { resolveTurnTimezoneContext } from "./date-context.js";
|
|
63
68
|
import type { ServerMessage } from "./message-protocol.js";
|
|
69
|
+
import type {
|
|
70
|
+
WebSearchMetadata,
|
|
71
|
+
WebSearchResultItem,
|
|
72
|
+
} from "./message-types/web-activity.js";
|
|
64
73
|
|
|
65
74
|
const log = getLogger("agent-loop-handlers");
|
|
66
75
|
|
|
@@ -199,6 +208,10 @@ export interface EventHandlerState {
|
|
|
199
208
|
currentTurnToolUseIds: string[];
|
|
200
209
|
/** Wall-clock time (ms since epoch) when the agent loop turn started, used as the display timestamp for assistant messages. */
|
|
201
210
|
turnStartedAt: number;
|
|
211
|
+
/** Wall-clock start time of native server tool calls, keyed by tool_use_id. */
|
|
212
|
+
readonly serverToolStartedAt: Map<string, number>;
|
|
213
|
+
/** Original input from server_tool_start, keyed by tool_use_id, so the complete handler can read the query. */
|
|
214
|
+
readonly serverToolInputs: Map<string, Record<string, unknown>>;
|
|
202
215
|
}
|
|
203
216
|
|
|
204
217
|
/** Immutable context shared across event handlers within a single agent loop run. */
|
|
@@ -257,6 +270,8 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
257
270
|
toolRiskOutcomes: new Map(),
|
|
258
271
|
currentTurnToolUseIds: [],
|
|
259
272
|
turnStartedAt: Date.now(),
|
|
273
|
+
serverToolStartedAt: new Map(),
|
|
274
|
+
serverToolInputs: new Map(),
|
|
260
275
|
};
|
|
261
276
|
}
|
|
262
277
|
|
|
@@ -324,6 +339,68 @@ function friendlyToolName(name: string): string {
|
|
|
324
339
|
return TOOL_FRIENDLY_NAMES[name] ?? name.replace(/_/g, " ");
|
|
325
340
|
}
|
|
326
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Status text shown to the client while a web search is in flight.
|
|
344
|
+
* Surfaces the actual query so the loading state is meaningful instead of
|
|
345
|
+
* a generic "Searching the web". Used for both Anthropic native server-tool
|
|
346
|
+
* starts and non-native `web_search` tool starts.
|
|
347
|
+
*/
|
|
348
|
+
export function formatSearchStatusText(
|
|
349
|
+
toolName: string,
|
|
350
|
+
query: string,
|
|
351
|
+
): string {
|
|
352
|
+
if (toolName !== "web_search") return `Running ${toolName}`;
|
|
353
|
+
const trimmed = query.trim();
|
|
354
|
+
if (!trimmed) return "Searching the web";
|
|
355
|
+
const truncated =
|
|
356
|
+
trimmed.length > 60 ? trimmed.slice(0, 57) + "..." : trimmed;
|
|
357
|
+
return `Searching "${truncated}"`;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Status text shown to the client while a web fetch is in flight.
|
|
362
|
+
* Surfaces the domain so users can tell what page is being read.
|
|
363
|
+
*/
|
|
364
|
+
export function formatFetchStatusText(url: unknown): string {
|
|
365
|
+
if (typeof url !== "string") return "Reading a page";
|
|
366
|
+
const domain = extractDomain(url);
|
|
367
|
+
if (!domain) return "Reading a page";
|
|
368
|
+
return `Reading ${domain}`;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function computeToolUseStatusText(
|
|
372
|
+
name: string,
|
|
373
|
+
input: Record<string, unknown>,
|
|
374
|
+
): string {
|
|
375
|
+
if (name === "web_search") {
|
|
376
|
+
const query = typeof input.query === "string" ? input.query : "";
|
|
377
|
+
return formatSearchStatusText("web_search", query);
|
|
378
|
+
}
|
|
379
|
+
if (name === "web_fetch") {
|
|
380
|
+
return formatFetchStatusText(input.url);
|
|
381
|
+
}
|
|
382
|
+
if (
|
|
383
|
+
name === "skill_execute" &&
|
|
384
|
+
typeof input.activity === "string" &&
|
|
385
|
+
input.activity.length > 0
|
|
386
|
+
) {
|
|
387
|
+
return input.activity;
|
|
388
|
+
}
|
|
389
|
+
return `Running ${friendlyToolName(name)}`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function resolveAssistantReplyTimestampTimezone(
|
|
393
|
+
ctx: AgentLoopConversationContext,
|
|
394
|
+
): string {
|
|
395
|
+
const config = getConfig();
|
|
396
|
+
return resolveTurnTimezoneContext({
|
|
397
|
+
configuredUserTimeZone: config.ui?.userTimezone ?? null,
|
|
398
|
+
clientTimezone: ctx.clientTimezone ?? null,
|
|
399
|
+
detectedTimezone: config.ui?.detectedTimezone ?? null,
|
|
400
|
+
hostTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
401
|
+
}).effectiveTimezone;
|
|
402
|
+
}
|
|
403
|
+
|
|
327
404
|
// ── Individual Handlers ──────────────────────────────────────────────
|
|
328
405
|
|
|
329
406
|
function handleTextDelta(
|
|
@@ -405,12 +482,7 @@ export function handleToolUse(
|
|
|
405
482
|
state.toolCallTimestamps.set(event.id, { startedAt: Date.now() });
|
|
406
483
|
state.currentToolUseId = event.id;
|
|
407
484
|
state.currentTurnToolUseIds.push(event.id);
|
|
408
|
-
const statusText =
|
|
409
|
-
event.name === "skill_execute" &&
|
|
410
|
-
typeof event.input.activity === "string" &&
|
|
411
|
-
event.input.activity.length > 0
|
|
412
|
-
? event.input.activity
|
|
413
|
-
: `Running ${friendlyToolName(event.name)}`;
|
|
485
|
+
const statusText = computeToolUseStatusText(event.name, event.input);
|
|
414
486
|
deps.ctx.emitActivityState(
|
|
415
487
|
"tool_running",
|
|
416
488
|
"tool_use_start",
|
|
@@ -677,6 +749,7 @@ export function handleToolResult(
|
|
|
677
749
|
approvalMode: event.approvalMode,
|
|
678
750
|
approvalReason: event.approvalReason,
|
|
679
751
|
riskThreshold: event.riskThreshold,
|
|
752
|
+
activityMetadata: event.activityMetadata,
|
|
680
753
|
});
|
|
681
754
|
}
|
|
682
755
|
|
|
@@ -985,11 +1058,20 @@ export async function handleMessageComplete(
|
|
|
985
1058
|
const channelId = deps.ctx.trustContext?.requesterChatId;
|
|
986
1059
|
if (channelId) {
|
|
987
1060
|
const threadTs = getThreadTs(deps.ctx.conversationId);
|
|
1061
|
+
const timestampTimezone = resolveAssistantReplyTimestampTimezone(
|
|
1062
|
+
deps.ctx,
|
|
1063
|
+
);
|
|
1064
|
+
const timestampTimezoneLabel = formatSlackTimezoneLabel(
|
|
1065
|
+
timestampTimezone,
|
|
1066
|
+
{ nowMs: state.turnStartedAt },
|
|
1067
|
+
);
|
|
988
1068
|
const partialSlackMeta: Partial<SlackMessageMetadata> = {
|
|
989
1069
|
source: "slack",
|
|
990
1070
|
eventKind: "message",
|
|
991
1071
|
channelId,
|
|
992
1072
|
...(threadTs ? { threadTs } : {}),
|
|
1073
|
+
timestampTimezone,
|
|
1074
|
+
...(timestampTimezoneLabel ? { timestampTimezoneLabel } : {}),
|
|
993
1075
|
};
|
|
994
1076
|
assistantChannelMetadata.slackMeta = writeSlackMetadata(
|
|
995
1077
|
// `channelTs` is filled in by the post-send reconciliation step in
|
|
@@ -1246,10 +1328,9 @@ export async function dispatchAgentEvent(
|
|
|
1246
1328
|
handleToolResult(state, deps, event);
|
|
1247
1329
|
break;
|
|
1248
1330
|
case "server_tool_start": {
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
const statusText = friendlyNames[event.name] ?? `Running ${event.name}`;
|
|
1331
|
+
const query =
|
|
1332
|
+
typeof event.input.query === "string" ? event.input.query : "";
|
|
1333
|
+
const statusText = formatSearchStatusText(event.name, query);
|
|
1253
1334
|
deps.ctx.emitActivityState(
|
|
1254
1335
|
"tool_running",
|
|
1255
1336
|
"tool_use_start",
|
|
@@ -1257,6 +1338,8 @@ export async function dispatchAgentEvent(
|
|
|
1257
1338
|
deps.reqId,
|
|
1258
1339
|
statusText,
|
|
1259
1340
|
);
|
|
1341
|
+
state.serverToolStartedAt.set(event.toolUseId, Date.now());
|
|
1342
|
+
state.serverToolInputs.set(event.toolUseId, event.input);
|
|
1260
1343
|
deps.onEvent({
|
|
1261
1344
|
type: "tool_use_start",
|
|
1262
1345
|
toolName: event.name,
|
|
@@ -1275,19 +1358,65 @@ export async function dispatchAgentEvent(
|
|
|
1275
1358
|
"Thinking",
|
|
1276
1359
|
);
|
|
1277
1360
|
|
|
1278
|
-
//
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1361
|
+
// Prefer `resolvedInput` (Anthropic's accumulated server-tool input,
|
|
1362
|
+
// populated on content_block_stop) over the input captured at
|
|
1363
|
+
// server_tool_start, which is `{}` on Anthropic until the deltas land.
|
|
1364
|
+
const inputForCall =
|
|
1365
|
+
event.resolvedInput ?? state.serverToolInputs.get(event.toolUseId);
|
|
1366
|
+
const query =
|
|
1367
|
+
typeof inputForCall?.query === "string" ? inputForCall.query : "";
|
|
1368
|
+
const startedAt =
|
|
1369
|
+
state.serverToolStartedAt.get(event.toolUseId) ?? Date.now();
|
|
1370
|
+
const durationMs = Date.now() - startedAt;
|
|
1371
|
+
state.serverToolStartedAt.delete(event.toolUseId);
|
|
1372
|
+
state.serverToolInputs.delete(event.toolUseId);
|
|
1373
|
+
|
|
1374
|
+
const rawBlocks = Array.isArray(event.content) ? event.content : [];
|
|
1375
|
+
const results: WebSearchResultItem[] = rawBlocks
|
|
1376
|
+
.filter(
|
|
1377
|
+
(r): r is { type: string; title: string; url: string } =>
|
|
1378
|
+
typeof r === "object" &&
|
|
1379
|
+
r != null &&
|
|
1380
|
+
(r as { type?: string }).type === "web_search_result",
|
|
1381
|
+
)
|
|
1382
|
+
.map((r, i) => {
|
|
1383
|
+
const domain = extractDomain(r.url);
|
|
1384
|
+
return {
|
|
1385
|
+
rank: i + 1,
|
|
1386
|
+
title: r.title,
|
|
1387
|
+
url: r.url,
|
|
1388
|
+
domain,
|
|
1389
|
+
faviconUrl: faviconUrlForDomain(domain),
|
|
1390
|
+
// snippet intentionally absent — Anthropic native content is encrypted/opaque
|
|
1391
|
+
};
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
// Only Anthropic produces structured `web_search_tool_result` blocks
|
|
1395
|
+
// that map cleanly onto `WebSearchMetadata` (provider-tagged
|
|
1396
|
+
// "anthropic-native"). Other providers (e.g. OpenAI's responses
|
|
1397
|
+
// `web_search_call`) share this event channel but their results are
|
|
1398
|
+
// woven into the text stream — emitting "anthropic-native" metadata
|
|
1399
|
+
// for them would mis-label the provider and ship empty results.
|
|
1400
|
+
const isAnthropicNative = deps.ctx.provider.name === "anthropic";
|
|
1401
|
+
|
|
1402
|
+
const errorMessage = event.isError
|
|
1403
|
+
? (event.errorMessage ?? event.errorCode ?? "Search failed")
|
|
1404
|
+
: undefined;
|
|
1405
|
+
|
|
1406
|
+
const metadata: WebSearchMetadata | undefined = isAnthropicNative
|
|
1407
|
+
? {
|
|
1408
|
+
query,
|
|
1409
|
+
provider: "anthropic-native",
|
|
1410
|
+
resultCount: results.length,
|
|
1411
|
+
durationMs,
|
|
1412
|
+
results,
|
|
1413
|
+
...(errorMessage ? { errorMessage } : {}),
|
|
1414
|
+
}
|
|
1415
|
+
: undefined;
|
|
1416
|
+
|
|
1417
|
+
const resultText = results
|
|
1418
|
+
.map((r) => `${r.title}\n${r.url}`)
|
|
1419
|
+
.join("\n\n");
|
|
1291
1420
|
|
|
1292
1421
|
deps.onEvent({
|
|
1293
1422
|
type: "tool_result",
|
|
@@ -1296,6 +1425,7 @@ export async function dispatchAgentEvent(
|
|
|
1296
1425
|
isError: event.isError,
|
|
1297
1426
|
conversationId: deps.ctx.conversationId,
|
|
1298
1427
|
toolUseId: event.toolUseId,
|
|
1428
|
+
...(metadata ? { activityMetadata: { webSearch: metadata } } : {}),
|
|
1299
1429
|
});
|
|
1300
1430
|
break;
|
|
1301
1431
|
}
|