@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
|
@@ -202,6 +202,85 @@ export function deleteQueuedMessage(
|
|
|
202
202
|
return { removed: false, reason: "message_not_found" };
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Steer a conversation to a specific queued message.
|
|
207
|
+
* Promotes the message to the head of the queue, marks the conversation
|
|
208
|
+
* as needing tool-result repair, and aborts the current generation so the
|
|
209
|
+
* drain path picks up the promoted message.
|
|
210
|
+
*
|
|
211
|
+
* Returns `{ steered: true }` on success, or `{ steered: false, reason }` on failure.
|
|
212
|
+
*/
|
|
213
|
+
export function steerToMessage(
|
|
214
|
+
conversationId: string,
|
|
215
|
+
requestId: string,
|
|
216
|
+
):
|
|
217
|
+
| { steered: true }
|
|
218
|
+
| {
|
|
219
|
+
steered: false;
|
|
220
|
+
reason:
|
|
221
|
+
| "conversation_not_found"
|
|
222
|
+
| "message_not_found"
|
|
223
|
+
| "not_processing";
|
|
224
|
+
} {
|
|
225
|
+
const conversation = findConversation(conversationId);
|
|
226
|
+
if (!conversation) {
|
|
227
|
+
log.warn(
|
|
228
|
+
{ conversationId, requestId },
|
|
229
|
+
"No conversation found for steer_to_message",
|
|
230
|
+
);
|
|
231
|
+
return { steered: false, reason: "conversation_not_found" };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!conversation.isProcessing()) {
|
|
235
|
+
log.warn(
|
|
236
|
+
{ conversationId, requestId },
|
|
237
|
+
"Cannot steer: conversation is not processing",
|
|
238
|
+
);
|
|
239
|
+
return { steered: false, reason: "not_processing" };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const promoted = conversation.queue.promoteToHead(requestId);
|
|
243
|
+
if (!promoted) {
|
|
244
|
+
log.warn(
|
|
245
|
+
{ conversationId, requestId },
|
|
246
|
+
"Queued message not found for steering",
|
|
247
|
+
);
|
|
248
|
+
return { steered: false, reason: "message_not_found" };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Mark the conversation for tool-result repair so the drain path can
|
|
252
|
+
// inject synthetic tool results for any pending tool_use blocks that
|
|
253
|
+
// were abandoned by the aborted generation.
|
|
254
|
+
conversation.pendingSteerRepair = true;
|
|
255
|
+
|
|
256
|
+
// Broadcast the steer event so clients can update their UI.
|
|
257
|
+
broadcastMessage({
|
|
258
|
+
type: "message_steered",
|
|
259
|
+
conversationId,
|
|
260
|
+
requestId,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
log.info(
|
|
264
|
+
{ conversationId, requestId },
|
|
265
|
+
"Steering to queued message — aborting current generation",
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
// Abort the in-flight generation. The agent loop's finally block calls
|
|
269
|
+
// drainQueue, which will pick up the promoted message at the head.
|
|
270
|
+
// Unlike abortConversation, we do NOT clear the queue or dispose
|
|
271
|
+
// prompters — we want the queue to drain with the promoted message first.
|
|
272
|
+
const reason = createAbortReason(
|
|
273
|
+
"preempted_by_new_message",
|
|
274
|
+
"steerToMessage",
|
|
275
|
+
conversationId,
|
|
276
|
+
);
|
|
277
|
+
conversation.abortController?.abort(reason);
|
|
278
|
+
// Deny pending confirmations so the abort unblocks immediately.
|
|
279
|
+
conversation.denyAllPendingConfirmations();
|
|
280
|
+
|
|
281
|
+
return { steered: true };
|
|
282
|
+
}
|
|
283
|
+
|
|
205
284
|
// ---------------------------------------------------------------------------
|
|
206
285
|
// HTTP handler (delegates to shared logic)
|
|
207
286
|
// ---------------------------------------------------------------------------
|
|
@@ -92,6 +92,19 @@ export interface HistorySurface {
|
|
|
92
92
|
completionSummary?: string;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Positional reference to a file attachment captured while walking the
|
|
97
|
+
* content array. The index of an entry in `RenderedHistoryContent.attachments`
|
|
98
|
+
* is what `contentOrder` references as `attachment:N`.
|
|
99
|
+
*/
|
|
100
|
+
export interface HistoryAttachmentRef {
|
|
101
|
+
/** Stable DB attachment id when persisted on the file block (`_attachmentId`). */
|
|
102
|
+
attachmentId?: string;
|
|
103
|
+
filename: string;
|
|
104
|
+
mimeType: string;
|
|
105
|
+
sizeBytes: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
export interface RenderedHistoryContent {
|
|
96
109
|
text: string;
|
|
97
110
|
toolCalls: HistoryToolCall[];
|
|
@@ -99,12 +112,18 @@ export interface RenderedHistoryContent {
|
|
|
99
112
|
toolCallsBeforeText: boolean;
|
|
100
113
|
/** Text segments split by tool-call boundaries. */
|
|
101
114
|
textSegments: string[];
|
|
102
|
-
/** Content block ordering using "text:N", "tool:N", "surface:N" encoding. */
|
|
115
|
+
/** Content block ordering using "text:N", "tool:N", "surface:N", "attachment:N" encoding. */
|
|
103
116
|
contentOrder: string[];
|
|
104
117
|
/** UI surfaces (widgets) embedded in the message. */
|
|
105
118
|
surfaces: HistorySurface[];
|
|
106
119
|
/** Thinking segments extracted from thinking blocks. */
|
|
107
120
|
thinkingSegments: string[];
|
|
121
|
+
/**
|
|
122
|
+
* File attachments captured in content order. Index `N` matches an
|
|
123
|
+
* `attachment:N` entry in `contentOrder`. Callers align their DB-sourced
|
|
124
|
+
* attachment metadata to this ordering for inline placement.
|
|
125
|
+
*/
|
|
126
|
+
attachments: HistoryAttachmentRef[];
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
/**
|
|
@@ -115,6 +134,8 @@ export interface RenderedHistoryContent {
|
|
|
115
134
|
export interface SlackInboundMessageMetadata {
|
|
116
135
|
/** Slack channel id (conversation external id) — recorded as `channelId`. */
|
|
117
136
|
channelId: string;
|
|
137
|
+
/** Human-readable Slack channel name, when the gateway supplied it. */
|
|
138
|
+
channelName?: string;
|
|
118
139
|
/** Slack `ts` for this message — required so persistence can record `channelTs`. */
|
|
119
140
|
channelTs: string;
|
|
120
141
|
/** Parent `thread_ts` when the message lives inside a thread; absent for top-level. */
|
|
@@ -123,6 +144,18 @@ export interface SlackInboundMessageMetadata {
|
|
|
123
144
|
displayName?: string;
|
|
124
145
|
/** Canonical Slack external user id for the sender, when available. */
|
|
125
146
|
actorExternalUserId?: string;
|
|
147
|
+
/** Raw Slack profile timezone for the sender, when supplied. */
|
|
148
|
+
actorTimezone?: string;
|
|
149
|
+
/** Compact Slack profile timezone label for the sender, when supplied. */
|
|
150
|
+
actorTimezoneLabel?: string;
|
|
151
|
+
/** Raw Slack profile timezone offset in seconds, when supplied. */
|
|
152
|
+
actorTimezoneOffsetSeconds?: number;
|
|
153
|
+
/** Timezone used to render this message's timestamp. */
|
|
154
|
+
timestampTimezone?: string;
|
|
155
|
+
/** Compact label for the rendered timestamp timezone. */
|
|
156
|
+
timestampTimezoneLabel?: string;
|
|
157
|
+
/** Compact timezone label appended to the rendered speaker name. */
|
|
158
|
+
speakerTimezoneLabel?: string;
|
|
126
159
|
}
|
|
127
160
|
|
|
128
161
|
/**
|
|
@@ -144,8 +177,6 @@ export interface ConversationCreateOptions {
|
|
|
144
177
|
authContext?: AuthContext;
|
|
145
178
|
/** Whether this turn can block on interactive approval prompts. */
|
|
146
179
|
isInteractive?: boolean;
|
|
147
|
-
/** Slack-only non-persisted notice injected into the active model turn. */
|
|
148
|
-
slackRuntimeContextNotice?: string;
|
|
149
180
|
/**
|
|
150
181
|
* Persisted user-facing content. When present, storage/UI use this value
|
|
151
182
|
* while the model-facing turn continues to use `content`.
|
|
@@ -192,22 +223,42 @@ function clampAttachmentText(text: string): string {
|
|
|
192
223
|
return `${text.slice(0, HISTORY_ATTACHMENT_TEXT_LIMIT)}<truncated />`;
|
|
193
224
|
}
|
|
194
225
|
|
|
195
|
-
|
|
226
|
+
interface FileBlockMetadata {
|
|
227
|
+
mediaType: string;
|
|
228
|
+
filename: string;
|
|
229
|
+
sizeBytes: number;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function extractFileBlockMetadata(
|
|
233
|
+
block: Record<string, unknown>,
|
|
234
|
+
): FileBlockMetadata {
|
|
196
235
|
const source = isRecord(block.source) ? block.source : null;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
236
|
+
return {
|
|
237
|
+
mediaType:
|
|
238
|
+
source && typeof source.media_type === "string"
|
|
239
|
+
? source.media_type
|
|
240
|
+
: "application/octet-stream",
|
|
241
|
+
filename:
|
|
242
|
+
source && typeof source.filename === "string"
|
|
243
|
+
? source.filename
|
|
244
|
+
: "attachment",
|
|
245
|
+
sizeBytes:
|
|
246
|
+
source && typeof source.data === "string"
|
|
247
|
+
? estimateBase64Bytes(source.data)
|
|
248
|
+
: 0,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function renderFileBlockForHistory(
|
|
253
|
+
block: Record<string, unknown>,
|
|
254
|
+
meta: FileBlockMetadata,
|
|
255
|
+
): string {
|
|
256
|
+
const summaryParts = [
|
|
257
|
+
`[File attachment] ${meta.filename}`,
|
|
258
|
+
`type=${meta.mediaType}`,
|
|
259
|
+
];
|
|
260
|
+
if (meta.sizeBytes > 0)
|
|
261
|
+
summaryParts.push(`size=${formatBytes(meta.sizeBytes)}`);
|
|
211
262
|
|
|
212
263
|
const extractedText =
|
|
213
264
|
typeof block.extracted_text === "string" ? block.extracted_text.trim() : "";
|
|
@@ -237,11 +288,13 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
237
288
|
contentOrder: text ? ["text:0"] : [],
|
|
238
289
|
surfaces: [],
|
|
239
290
|
thinkingSegments: [],
|
|
291
|
+
attachments: [],
|
|
240
292
|
};
|
|
241
293
|
}
|
|
242
294
|
|
|
243
295
|
const textParts: string[] = [];
|
|
244
296
|
const attachmentParts: string[] = [];
|
|
297
|
+
const attachments: HistoryAttachmentRef[] = [];
|
|
245
298
|
const toolCalls: HistoryToolCall[] = [];
|
|
246
299
|
const surfaces: HistorySurface[] = [];
|
|
247
300
|
const thinkingSegments: string[] = [];
|
|
@@ -351,7 +404,19 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
351
404
|
continue;
|
|
352
405
|
}
|
|
353
406
|
if (block.type === "file") {
|
|
354
|
-
|
|
407
|
+
const meta = extractFileBlockMetadata(block);
|
|
408
|
+
attachmentParts.push(renderFileBlockForHistory(block, meta));
|
|
409
|
+
finalizeSegment();
|
|
410
|
+
const ref: HistoryAttachmentRef = {
|
|
411
|
+
filename: meta.filename,
|
|
412
|
+
mimeType: meta.mediaType,
|
|
413
|
+
sizeBytes: meta.sizeBytes,
|
|
414
|
+
};
|
|
415
|
+
if (typeof block._attachmentId === "string" && block._attachmentId) {
|
|
416
|
+
ref.attachmentId = block._attachmentId;
|
|
417
|
+
}
|
|
418
|
+
attachments.push(ref);
|
|
419
|
+
contentOrder.push(`attachment:${attachments.length - 1}`);
|
|
355
420
|
continue;
|
|
356
421
|
}
|
|
357
422
|
if (block.type === "image") {
|
|
@@ -495,17 +560,14 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
495
560
|
matched.imageData = imageDataList[0];
|
|
496
561
|
matched.imageDataList = imageDataList;
|
|
497
562
|
}
|
|
498
|
-
} else {
|
|
499
|
-
toolCalls.push({
|
|
500
|
-
name: "unknown",
|
|
501
|
-
input: {},
|
|
502
|
-
result: resultContent,
|
|
503
|
-
isError,
|
|
504
|
-
...(imageDataList.length > 0
|
|
505
|
-
? { imageData: imageDataList[0], imageDataList }
|
|
506
|
-
: {}),
|
|
507
|
-
});
|
|
508
563
|
}
|
|
564
|
+
// Orphan tool_result with no matching tool_use — drop it. Synthesizing
|
|
565
|
+
// a "name: 'unknown'" phantom entry rendered in chat as "Used unknown"
|
|
566
|
+
// / "Completed 1 step" with no context, with a timestamp later than
|
|
567
|
+
// the assistant's final answer. Most commonly orphans appear when
|
|
568
|
+
// context-window compaction trims the parent tool_use block while
|
|
569
|
+
// leaving the paired tool_result. Losing the orphan's result content
|
|
570
|
+
// is correct: without the parent we can't tell the user what tool ran.
|
|
509
571
|
continue;
|
|
510
572
|
}
|
|
511
573
|
}
|
|
@@ -541,6 +603,7 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
541
603
|
contentOrder,
|
|
542
604
|
surfaces,
|
|
543
605
|
thinkingSegments,
|
|
606
|
+
attachments,
|
|
544
607
|
};
|
|
545
608
|
}
|
|
546
609
|
|
|
@@ -280,7 +280,7 @@ export class HostCuProxy {
|
|
|
280
280
|
observation: CuObservationResult,
|
|
281
281
|
): ToolExecutionResult | undefined {
|
|
282
282
|
this._ownedRequests.delete(requestId);
|
|
283
|
-
const interaction = pendingInteractions.resolve(requestId);
|
|
283
|
+
const interaction = pendingInteractions.resolve(requestId, "answered");
|
|
284
284
|
if (!interaction?.rpcResolve) {
|
|
285
285
|
log.warn({ requestId }, "No pending host CU request for response");
|
|
286
286
|
return undefined;
|
|
@@ -227,7 +227,7 @@ export class HostFileProxy {
|
|
|
227
227
|
requestId: string,
|
|
228
228
|
response: { content: string; isError: boolean; imageData?: string },
|
|
229
229
|
): void {
|
|
230
|
-
const interaction = pendingInteractions.resolve(requestId);
|
|
230
|
+
const interaction = pendingInteractions.resolve(requestId, "answered");
|
|
231
231
|
if (!interaction?.rpcResolve) {
|
|
232
232
|
log.warn({ requestId }, "No pending host file request for response");
|
|
233
233
|
return;
|
|
@@ -508,7 +508,7 @@ export class HostTransferProxy {
|
|
|
508
508
|
errorMessage?: string;
|
|
509
509
|
},
|
|
510
510
|
): void {
|
|
511
|
-
const interaction = pendingInteractions.resolve(requestId);
|
|
511
|
+
const interaction = pendingInteractions.resolve(requestId, "answered");
|
|
512
512
|
if (!interaction?.rpcResolve) {
|
|
513
513
|
log.warn({ requestId }, "No pending host transfer request for response");
|
|
514
514
|
return;
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from "../credential-execution/startup-timeout.js";
|
|
33
33
|
import { FilingService } from "../filing/filing-service.js";
|
|
34
34
|
import { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
35
|
+
import { startHomeContentRefresh } from "../home/home-content-refresh.js";
|
|
35
36
|
import { backfillRelationshipStateIfMissing } from "../home/relationship-state-writer.js";
|
|
36
37
|
import { closeSentry, initSentry, setSentryDeviceId } from "../instrument.js";
|
|
37
38
|
import { getMcpServerManager } from "../mcp/manager.js";
|
|
@@ -121,7 +122,6 @@ import {
|
|
|
121
122
|
registerMessagingProviders,
|
|
122
123
|
registerWatcherProviders,
|
|
123
124
|
} from "./providers-setup.js";
|
|
124
|
-
import { seedInterfaceFiles } from "./seed-files.js";
|
|
125
125
|
import { DaemonServer } from "./server.js";
|
|
126
126
|
import { installShutdownHandlers } from "./shutdown-handlers.js";
|
|
127
127
|
import { refreshSkillCapabilityMemories } from "./skill-memory-refresh.js";
|
|
@@ -269,8 +269,13 @@ async function startCesProcess(
|
|
|
269
269
|
|
|
270
270
|
// Entry point for the daemon process itself
|
|
271
271
|
export async function runDaemon(): Promise<void> {
|
|
272
|
+
const startupStartedAt = Date.now();
|
|
273
|
+
// dotenv loads before the first log call so the lazy root logger
|
|
274
|
+
// initializes against the final VELLUM_WORKSPACE_DIR / log path, not
|
|
275
|
+
// whatever was in the live environment at process spawn.
|
|
272
276
|
loadDotEnv();
|
|
273
277
|
validateEnv();
|
|
278
|
+
log.info({ version: APP_VERSION }, "Daemon starting");
|
|
274
279
|
|
|
275
280
|
try {
|
|
276
281
|
// Initialize crash reporting eagerly so early startup failures are
|
|
@@ -353,8 +358,6 @@ export async function runDaemon(): Promise<void> {
|
|
|
353
358
|
log.warn({ err }, "Background feature flag init failed"),
|
|
354
359
|
);
|
|
355
360
|
|
|
356
|
-
seedInterfaceFiles();
|
|
357
|
-
|
|
358
361
|
log.info("Daemon startup: initializing DB");
|
|
359
362
|
ensurePromptFiles();
|
|
360
363
|
|
|
@@ -470,6 +473,10 @@ export async function runDaemon(): Promise<void> {
|
|
|
470
473
|
);
|
|
471
474
|
});
|
|
472
475
|
|
|
476
|
+
// Pre-warm LLM-generated home page content (greeting + suggestion
|
|
477
|
+
// prompts) so the GET handler never triggers LLM calls.
|
|
478
|
+
startHomeContentRefresh();
|
|
479
|
+
|
|
473
480
|
// Backfill injection templates on Slack bot token credentials so the
|
|
474
481
|
// credential proxy can inject Authorization headers. Safe on every startup.
|
|
475
482
|
try {
|
|
@@ -1228,7 +1235,6 @@ export async function runDaemon(): Promise<void> {
|
|
|
1228
1235
|
}
|
|
1229
1236
|
|
|
1230
1237
|
writePid(process.pid);
|
|
1231
|
-
log.info({ pid: process.pid }, "Daemon started");
|
|
1232
1238
|
|
|
1233
1239
|
// Install the `assistant` CLI symlink idempotently on every daemon start.
|
|
1234
1240
|
// Non-blocking — failures are logged but don't affect startup.
|
|
@@ -1345,6 +1351,14 @@ export async function runDaemon(): Promise<void> {
|
|
|
1345
1351
|
cleanupPidFile();
|
|
1346
1352
|
},
|
|
1347
1353
|
});
|
|
1354
|
+
|
|
1355
|
+
log.info(
|
|
1356
|
+
{
|
|
1357
|
+
durationMs: Date.now() - startupStartedAt,
|
|
1358
|
+
pid: process.pid,
|
|
1359
|
+
},
|
|
1360
|
+
"Daemon started",
|
|
1361
|
+
);
|
|
1348
1362
|
} catch (err) {
|
|
1349
1363
|
log.error({ err }, "Daemon startup failed — cleaning up");
|
|
1350
1364
|
stopDiskPressureGuardForLifecycle();
|
|
@@ -22,6 +22,7 @@ export * from "./message-types/contacts.js";
|
|
|
22
22
|
export * from "./message-types/conversations.js";
|
|
23
23
|
export * from "./message-types/diagnostics.js";
|
|
24
24
|
export * from "./message-types/disk-pressure.js";
|
|
25
|
+
export * from "./message-types/document-comments.js";
|
|
25
26
|
export * from "./message-types/documents.js";
|
|
26
27
|
export * from "./message-types/guardian-actions.js";
|
|
27
28
|
export * from "./message-types/home.js";
|
|
@@ -45,6 +46,7 @@ export * from "./message-types/subagents.js";
|
|
|
45
46
|
export * from "./message-types/surfaces.js";
|
|
46
47
|
export * from "./message-types/sync.js";
|
|
47
48
|
export * from "./message-types/upgrades.js";
|
|
49
|
+
export * from "./message-types/web-activity.js";
|
|
48
50
|
export * from "./message-types/work-items.js";
|
|
49
51
|
export * from "./message-types/workspace.js";
|
|
50
52
|
|
|
@@ -76,6 +78,7 @@ import type {
|
|
|
76
78
|
_DiagnosticsServerMessages,
|
|
77
79
|
} from "./message-types/diagnostics.js";
|
|
78
80
|
import type { _DiskPressureServerMessages } from "./message-types/disk-pressure.js";
|
|
81
|
+
import type { _DocumentCommentsServerMessages } from "./message-types/document-comments.js";
|
|
79
82
|
import type {
|
|
80
83
|
_DocumentsClientMessages,
|
|
81
84
|
_DocumentsServerMessages,
|
|
@@ -192,6 +195,7 @@ export type ServerMessage =
|
|
|
192
195
|
| _BrowserServerMessages
|
|
193
196
|
| _SubagentsServerMessages
|
|
194
197
|
| _DocumentsServerMessages
|
|
198
|
+
| _DocumentCommentsServerMessages
|
|
195
199
|
| _GuardianActionsServerMessages
|
|
196
200
|
| _SyncInvalidationServerMessages
|
|
197
201
|
| _HomeServerMessages
|
|
@@ -224,6 +224,7 @@ export interface ConversationTitleUpdated {
|
|
|
224
224
|
interface ChannelBinding {
|
|
225
225
|
sourceChannel: ChannelId;
|
|
226
226
|
externalChatId: string;
|
|
227
|
+
externalChatName?: string | null;
|
|
227
228
|
externalThreadId?: string | null;
|
|
228
229
|
externalUserId?: string | null;
|
|
229
230
|
displayName?: string | null;
|
|
@@ -236,6 +237,13 @@ interface ChannelBinding {
|
|
|
236
237
|
webUrl?: string;
|
|
237
238
|
};
|
|
238
239
|
};
|
|
240
|
+
slackChannel?: {
|
|
241
|
+
channelId: string;
|
|
242
|
+
name?: string;
|
|
243
|
+
link?: {
|
|
244
|
+
webUrl?: string;
|
|
245
|
+
};
|
|
246
|
+
};
|
|
239
247
|
}
|
|
240
248
|
|
|
241
249
|
/** Attention state metadata for a conversation's latest assistant message. */
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Document comment event types (Server → Client).
|
|
2
|
+
|
|
3
|
+
export interface DocumentCommentCreated {
|
|
4
|
+
type: "document_comment_created";
|
|
5
|
+
conversationId: string;
|
|
6
|
+
surfaceId: string;
|
|
7
|
+
comment: {
|
|
8
|
+
id: string;
|
|
9
|
+
surfaceId: string;
|
|
10
|
+
author: string;
|
|
11
|
+
content: string;
|
|
12
|
+
anchorStart?: number;
|
|
13
|
+
anchorEnd?: number;
|
|
14
|
+
anchorText?: string;
|
|
15
|
+
parentCommentId?: string;
|
|
16
|
+
status: string;
|
|
17
|
+
createdAt: number;
|
|
18
|
+
updatedAt: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface DocumentCommentResolved {
|
|
23
|
+
type: "document_comment_resolved";
|
|
24
|
+
conversationId: string;
|
|
25
|
+
surfaceId: string;
|
|
26
|
+
commentId: string;
|
|
27
|
+
resolvedBy: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DocumentCommentReopened {
|
|
31
|
+
type: "document_comment_reopened";
|
|
32
|
+
conversationId: string;
|
|
33
|
+
surfaceId: string;
|
|
34
|
+
commentId: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface DocumentCommentDeleted {
|
|
38
|
+
type: "document_comment_deleted";
|
|
39
|
+
conversationId: string;
|
|
40
|
+
surfaceId: string;
|
|
41
|
+
commentId: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --- Domain-level union alias (consumed by the barrel file) ---
|
|
45
|
+
|
|
46
|
+
export type _DocumentCommentsServerMessages =
|
|
47
|
+
| DocumentCommentCreated
|
|
48
|
+
| DocumentCommentResolved
|
|
49
|
+
| DocumentCommentReopened
|
|
50
|
+
| DocumentCommentDeleted;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type { ChannelId, InterfaceId } from "../../channels/types.js";
|
|
4
4
|
import type { CommandIntent, UserMessageAttachment } from "./shared.js";
|
|
5
|
+
import type { ToolActivityMetadata } from "./web-activity.js";
|
|
5
6
|
|
|
6
7
|
// === Client → Server ===
|
|
7
8
|
|
|
@@ -175,6 +176,9 @@ export interface ToolResult {
|
|
|
175
176
|
approvalReason?: string;
|
|
176
177
|
/** Snapshot of the auto-approve threshold at execution time. */
|
|
177
178
|
riskThreshold?: string;
|
|
179
|
+
/** Structured activity metadata for rich client rendering. Optional; old
|
|
180
|
+
* clients that key off `result` continue to work unchanged. */
|
|
181
|
+
activityMetadata?: ToolActivityMetadata;
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
export interface ConfirmationRequest {
|
|
@@ -363,6 +367,12 @@ export interface MessageQueuedDeleted {
|
|
|
363
367
|
requestId: string;
|
|
364
368
|
}
|
|
365
369
|
|
|
370
|
+
export interface MessageSteered {
|
|
371
|
+
type: "message_steered";
|
|
372
|
+
conversationId: string;
|
|
373
|
+
requestId: string;
|
|
374
|
+
}
|
|
375
|
+
|
|
366
376
|
export interface SuggestionResponse {
|
|
367
377
|
type: "suggestion_response";
|
|
368
378
|
requestId: string;
|
|
@@ -390,6 +400,45 @@ export interface ConfirmationStateChanged {
|
|
|
390
400
|
toolUseId?: string;
|
|
391
401
|
}
|
|
392
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Lifecycle states reported by `interaction_resolved`.
|
|
405
|
+
*
|
|
406
|
+
* - `"approved"` / `"rejected"` — user-supplied verdict on a confirmation.
|
|
407
|
+
* - `"answered"` — user/client provided a response (secret value, question
|
|
408
|
+
* answer, host-proxy result).
|
|
409
|
+
* - `"cancelled"` — the interaction was torn down without a user response
|
|
410
|
+
* (timeout, abort, dispose, prompter shutdown).
|
|
411
|
+
* - `"superseded"` — invalidated by a newer event (auto-deny on enqueue, a
|
|
412
|
+
* fresh user message arriving while a confirmation was outstanding).
|
|
413
|
+
*/
|
|
414
|
+
export type InteractionResolutionState =
|
|
415
|
+
| "approved"
|
|
416
|
+
| "rejected"
|
|
417
|
+
| "answered"
|
|
418
|
+
| "cancelled"
|
|
419
|
+
| "superseded";
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Broadcast when a pending interaction (confirmation, secret, question,
|
|
423
|
+
* host-proxy request) transitions to a resolved state. Clients use this to
|
|
424
|
+
* drop attention/processing indicators without polling.
|
|
425
|
+
*/
|
|
426
|
+
export interface InteractionResolved {
|
|
427
|
+
type: "interaction_resolved";
|
|
428
|
+
requestId: string;
|
|
429
|
+
/**
|
|
430
|
+
* Conversation key for the interaction. The daemon's internal conversation
|
|
431
|
+
* id and the web client's conversation key coincide today (see
|
|
432
|
+
* `conversation-key-store.ts`); the field is named after the client-facing
|
|
433
|
+
* concept.
|
|
434
|
+
*/
|
|
435
|
+
conversationKey: string;
|
|
436
|
+
state: InteractionResolutionState;
|
|
437
|
+
/** Kind of the resolved interaction (e.g. "confirmation", "secret", "host_bash"). */
|
|
438
|
+
kind: string;
|
|
439
|
+
conversationId?: string;
|
|
440
|
+
}
|
|
441
|
+
|
|
393
442
|
/**
|
|
394
443
|
* Server-side assistant activity lifecycle for thinking indicator placement.
|
|
395
444
|
*
|
|
@@ -426,6 +475,21 @@ export interface AssistantActivityState {
|
|
|
426
475
|
statusText?: string;
|
|
427
476
|
}
|
|
428
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Emitted when the query complexity auto-router selects a non-default
|
|
480
|
+
* profile for the current turn. Clients use this to show an inline
|
|
481
|
+
* notification (e.g. "Using Quality for this response"). Only fires when
|
|
482
|
+
* the router picks a profile — not when the user explicitly pinned one.
|
|
483
|
+
*/
|
|
484
|
+
export interface TurnProfileAutoRouted {
|
|
485
|
+
type: "turn_profile_auto_routed";
|
|
486
|
+
conversationId: string;
|
|
487
|
+
/** Profile key (e.g. "quality-optimized"). */
|
|
488
|
+
profile: string;
|
|
489
|
+
/** Human-readable label (e.g. "Quality"). */
|
|
490
|
+
profileLabel: string;
|
|
491
|
+
}
|
|
492
|
+
|
|
429
493
|
/**
|
|
430
494
|
* Broadcast to clients when a conversation's inference-profile override
|
|
431
495
|
* changes. `profile` is the profile name (a key in `llm.profiles`) or
|
|
@@ -497,8 +561,11 @@ export type _MessagesServerMessages =
|
|
|
497
561
|
| MessageDequeued
|
|
498
562
|
| MessageRequestComplete
|
|
499
563
|
| MessageQueuedDeleted
|
|
564
|
+
| MessageSteered
|
|
500
565
|
| SuggestionResponse
|
|
501
566
|
| TraceEvent
|
|
502
567
|
| ConfirmationStateChanged
|
|
503
568
|
| AssistantActivityState
|
|
504
|
-
|
|
|
569
|
+
| TurnProfileAutoRouted
|
|
570
|
+
| ConversationInferenceProfileUpdated
|
|
571
|
+
| InteractionResolved;
|
|
@@ -10,13 +10,15 @@ export type SurfaceType =
|
|
|
10
10
|
| "confirmation"
|
|
11
11
|
| "dynamic_page"
|
|
12
12
|
| "file_upload"
|
|
13
|
-
| "document_preview"
|
|
13
|
+
| "document_preview"
|
|
14
|
+
| "task_preferences";
|
|
14
15
|
|
|
15
16
|
export const INTERACTIVE_SURFACE_TYPES: SurfaceType[] = [
|
|
16
17
|
"form",
|
|
17
18
|
"confirmation",
|
|
18
19
|
"dynamic_page",
|
|
19
20
|
"file_upload",
|
|
21
|
+
"task_preferences",
|
|
20
22
|
];
|
|
21
23
|
|
|
22
24
|
export interface SurfaceAction {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Shared structured result types for web-search and web-fetch tool activity.
|
|
2
|
+
//
|
|
3
|
+
// These types describe live (SSE-time) metadata that producers (search/fetch
|
|
4
|
+
// tool executors) emit and consumers (clients) render alongside the existing
|
|
5
|
+
// `result: string` payload. Persistence to conversation history is out of
|
|
6
|
+
// scope for this plan; the metadata is live-only.
|
|
7
|
+
|
|
8
|
+
export type WebSearchProviderId =
|
|
9
|
+
| "anthropic-native"
|
|
10
|
+
| "brave"
|
|
11
|
+
| "perplexity"
|
|
12
|
+
| "tavily";
|
|
13
|
+
|
|
14
|
+
export interface WebSearchResultItem {
|
|
15
|
+
rank: number; // 1-indexed
|
|
16
|
+
title: string;
|
|
17
|
+
url: string;
|
|
18
|
+
domain: string; // lowercased host
|
|
19
|
+
faviconUrl?: string;
|
|
20
|
+
snippet?: string; // not populated for anthropic-native (content encrypted)
|
|
21
|
+
age?: string; // Brave-only freshness hint
|
|
22
|
+
score?: number; // Tavily-only
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WebSearchMetadata {
|
|
26
|
+
query: string;
|
|
27
|
+
provider: WebSearchProviderId;
|
|
28
|
+
resultCount: number;
|
|
29
|
+
durationMs: number;
|
|
30
|
+
results: WebSearchResultItem[];
|
|
31
|
+
/** Present when search itself failed; results[] will be empty. */
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WebFetchMetadata {
|
|
36
|
+
url: string;
|
|
37
|
+
finalUrl: string;
|
|
38
|
+
status: number;
|
|
39
|
+
contentType?: string;
|
|
40
|
+
byteCount: number;
|
|
41
|
+
charCount: number;
|
|
42
|
+
truncated: boolean;
|
|
43
|
+
title?: string;
|
|
44
|
+
domain: string;
|
|
45
|
+
faviconUrl?: string;
|
|
46
|
+
redirectCount: number;
|
|
47
|
+
durationMs: number;
|
|
48
|
+
errorMessage?: string;
|
|
49
|
+
/** Set when extracted text is dramatically smaller than raw HTML — likely a JS-rendered SPA whose meaningful content the static fetcher missed. */
|
|
50
|
+
mayRequireJavaScript?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Discriminated container so future tools can add their own metadata. */
|
|
54
|
+
export interface ToolActivityMetadata {
|
|
55
|
+
webSearch?: WebSearchMetadata;
|
|
56
|
+
webFetch?: WebFetchMetadata;
|
|
57
|
+
}
|