@vellumai/assistant 0.4.49 → 0.4.51
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/ARCHITECTURE.md +24 -33
- package/README.md +3 -3
- package/docs/architecture/integrations.md +2 -2
- package/docs/architecture/keychain-broker.md +6 -6
- package/docs/architecture/memory.md +180 -119
- package/knip.json +32 -0
- package/package.json +3 -2
- package/src/__tests__/agent-loop.test.ts +3 -1
- package/src/__tests__/anthropic-provider.test.ts +114 -23
- package/src/__tests__/approval-cascade.test.ts +1 -15
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
- package/src/__tests__/btw-routes.test.ts +61 -5
- package/src/__tests__/canonical-guardian-store.test.ts +95 -0
- package/src/__tests__/checker.test.ts +13 -0
- package/src/__tests__/config-schema.test.ts +1 -68
- package/src/__tests__/config-watcher.test.ts +8 -0
- package/src/__tests__/context-memory-e2e.test.ts +11 -100
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +8 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-security-invariants.test.ts +8 -7
- package/src/__tests__/credential-vault-unit.test.ts +23 -18
- package/src/__tests__/credential-vault.test.ts +30 -18
- package/src/__tests__/credentials-cli.test.ts +257 -82
- package/src/__tests__/cu-unified-flow.test.ts +532 -0
- package/src/__tests__/date-context.test.ts +93 -77
- package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -0
- package/src/__tests__/history-repair.test.ts +245 -0
- package/src/__tests__/host-cu-proxy.test.ts +165 -3
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +36 -7
- package/src/__tests__/integration-status.test.ts +31 -30
- package/src/__tests__/invite-redemption-service.test.ts +166 -13
- package/src/__tests__/invite-routes-http.test.ts +166 -5
- package/src/__tests__/keychain-broker-client.test.ts +4 -4
- package/src/__tests__/list-messages-attachments.test.ts +193 -0
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
- package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
- package/src/__tests__/memory-recall-quality.test.ts +244 -407
- package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
- package/src/__tests__/memory-regressions.test.ts +477 -2841
- package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
- package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
- package/src/__tests__/mime-builder.test.ts +28 -0
- package/src/__tests__/native-web-search.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +824 -31
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +363 -17
- package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
- package/src/__tests__/registry.test.ts +0 -1
- package/src/__tests__/relay-server.test.ts +55 -1
- package/src/__tests__/schedule-tools.test.ts +32 -0
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +183 -0
- package/src/__tests__/secure-keys.test.ts +78 -18
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/session-abort-tool-results.test.ts +1 -14
- package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
- package/src/__tests__/session-agent-loop.test.ts +19 -15
- package/src/__tests__/session-confirmation-signals.test.ts +1 -15
- package/src/__tests__/session-error.test.ts +124 -2
- package/src/__tests__/session-history-web-search.test.ts +918 -0
- package/src/__tests__/session-pre-run-repair.test.ts +1 -14
- package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
- package/src/__tests__/session-queue.test.ts +37 -27
- package/src/__tests__/session-runtime-assembly.test.ts +54 -0
- package/src/__tests__/session-slash-known.test.ts +1 -15
- package/src/__tests__/session-slash-queue.test.ts +1 -15
- package/src/__tests__/session-slash-unknown.test.ts +1 -15
- package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
- package/src/__tests__/session-workspace-injection.test.ts +3 -37
- package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
- package/src/__tests__/skills-install-extract.test.ts +93 -0
- package/src/__tests__/skills.test.ts +2 -2
- package/src/__tests__/skillssh-registry.test.ts +451 -0
- package/src/__tests__/slack-channel-config.test.ts +10 -8
- package/src/__tests__/trust-store.test.ts +15 -0
- package/src/__tests__/twilio-config.test.ts +11 -10
- package/src/__tests__/twilio-provider.test.ts +9 -4
- package/src/__tests__/voice-invite-redemption.test.ts +85 -5
- package/src/agent/ax-tree-compaction.test.ts +51 -0
- package/src/agent/loop.ts +39 -12
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-request-resolvers.ts +14 -2
- package/src/bundler/compiler-tools.ts +66 -2
- package/src/calls/call-domain.ts +134 -3
- package/src/calls/call-store.ts +6 -0
- package/src/calls/relay-server.ts +44 -6
- package/src/calls/relay-setup-router.ts +17 -1
- package/src/calls/twilio-config.ts +5 -4
- package/src/calls/twilio-provider.ts +14 -9
- package/src/calls/twilio-rest.ts +10 -7
- package/src/calls/types.ts +3 -1
- package/src/cli/commands/config.ts +14 -9
- package/src/cli/commands/contacts.ts +3 -0
- package/src/cli/commands/credentials.ts +170 -174
- package/src/cli/commands/doctor.ts +11 -8
- package/src/cli/commands/keys.ts +9 -9
- package/src/cli/commands/mcp.ts +46 -59
- package/src/cli/commands/memory.ts +16 -165
- package/src/cli/commands/oauth/apps.ts +68 -10
- package/src/cli/commands/oauth/connections.ts +475 -105
- package/src/cli/commands/oauth/index.ts +3 -3
- package/src/cli/commands/oauth/providers.ts +18 -4
- package/src/cli/commands/sessions.ts +5 -2
- package/src/cli/commands/skills.ts +173 -1
- package/src/cli/http-client.ts +0 -20
- package/src/cli/main-screen.tsx +2 -2
- package/src/cli/program.ts +5 -6
- package/src/cli.ts +20 -22
- package/src/config/__tests__/feature-flag-registry-bundled.test.ts +39 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +1 -1
- package/src/config/bundled-skills/computer-use/tools/computer-use-observe.ts +12 -0
- package/src/config/bundled-skills/contacts/SKILL.md +35 -11
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/gmail/TOOLS.json +52 -0
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +13 -3
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +9 -2
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +9 -2
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +5 -1
- package/src/config/bundled-skills/google-calendar/TOOLS.json +20 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +8 -2
- package/src/config/bundled-skills/messaging/SKILL.md +1 -1
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +7 -5
- package/src/config/bundled-skills/slack/tools/shared.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +1 -1
- package/src/config/bundled-tool-registry.ts +2 -5
- package/src/config/loader.ts +6 -42
- package/src/config/schema.ts +1 -12
- package/src/config/schemas/memory-lifecycle.ts +0 -9
- package/src/config/schemas/memory-processing.ts +0 -180
- package/src/config/schemas/memory-retrieval.ts +32 -104
- package/src/config/schemas/memory.ts +0 -10
- package/src/config/types.ts +0 -4
- package/src/contacts/contact-store.ts +39 -2
- package/src/contacts/contacts-write.ts +9 -0
- package/src/context/window-manager.ts +4 -1
- package/src/daemon/config-watcher.ts +55 -2
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +114 -31
- package/src/daemon/handlers/config-ingress.ts +2 -2
- package/src/daemon/handlers/config-slack-channel.ts +59 -39
- package/src/daemon/handlers/config-telegram.ts +23 -14
- package/src/daemon/handlers/session-history.ts +1 -358
- package/src/daemon/handlers/sessions.ts +18 -13
- package/src/daemon/handlers/shared.ts +3 -17
- package/src/daemon/handlers/skills.ts +20 -1
- package/src/daemon/history-repair.ts +72 -8
- package/src/daemon/host-cu-proxy.ts +55 -26
- package/src/daemon/lifecycle.ts +39 -4
- package/src/daemon/mcp-reload-service.ts +2 -2
- package/src/daemon/message-types/computer-use.ts +1 -12
- package/src/daemon/message-types/memory.ts +4 -16
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/sessions.ts +4 -42
- package/src/daemon/server.ts +6 -1
- package/src/daemon/session-agent-loop-handlers.ts +38 -0
- package/src/daemon/session-agent-loop.ts +334 -48
- package/src/daemon/session-error.ts +89 -6
- package/src/daemon/session-history.ts +17 -7
- package/src/daemon/session-media-retry.ts +6 -2
- package/src/daemon/session-memory.ts +69 -149
- package/src/daemon/session-process.ts +10 -1
- package/src/daemon/session-runtime-assembly.ts +49 -19
- package/src/daemon/session-slash.ts +3 -5
- package/src/daemon/session-surfaces.ts +4 -1
- package/src/daemon/session-tool-setup.ts +7 -1
- package/src/daemon/session.ts +12 -2
- package/src/email/providers/index.ts +2 -2
- package/src/instrument.ts +61 -1
- package/src/media/avatar-router.ts +1 -1
- package/src/memory/admin.ts +2 -191
- package/src/memory/canonical-guardian-store.ts +38 -2
- package/src/memory/conversation-crud.ts +0 -33
- package/src/memory/conversation-queries.ts +25 -83
- package/src/memory/db-init.ts +32 -0
- package/src/memory/embedding-backend.ts +84 -8
- package/src/memory/embedding-types.ts +9 -1
- package/src/memory/indexer.ts +7 -46
- package/src/memory/invite-store.ts +19 -0
- package/src/memory/items-extractor.ts +274 -76
- package/src/memory/job-handlers/backfill.ts +2 -127
- package/src/memory/job-handlers/cleanup.ts +2 -16
- package/src/memory/job-handlers/extraction.ts +2 -138
- package/src/memory/job-handlers/index-maintenance.ts +1 -6
- package/src/memory/job-handlers/summarization.ts +3 -148
- package/src/memory/job-utils.ts +21 -59
- package/src/memory/jobs-store.ts +1 -159
- package/src/memory/jobs-worker.ts +9 -52
- package/src/memory/migrations/104-core-indexes.ts +3 -3
- package/src/memory/migrations/149-oauth-tables.ts +2 -0
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
- package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
- package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
- package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
- package/src/memory/migrations/154-drop-fts.ts +20 -0
- package/src/memory/migrations/155-drop-conflicts.ts +7 -0
- package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
- package/src/memory/migrations/157-invite-contact-id.ts +104 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/migrations/registry.ts +6 -0
- package/src/memory/qdrant-client.ts +148 -51
- package/src/memory/raw-query.ts +1 -1
- package/src/memory/retriever.test.ts +294 -273
- package/src/memory/retriever.ts +421 -645
- package/src/memory/schema/calls.ts +2 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/memory-core.ts +3 -48
- package/src/memory/schema/oauth.ts +2 -0
- package/src/memory/search/formatting.ts +263 -176
- package/src/memory/search/lexical.ts +1 -254
- package/src/memory/search/ranking.ts +0 -455
- package/src/memory/search/semantic.ts +100 -14
- package/src/memory/search/staleness.ts +47 -0
- package/src/memory/search/tier-classifier.ts +21 -0
- package/src/memory/search/types.ts +15 -77
- package/src/memory/task-memory-cleanup.ts +4 -6
- package/src/messaging/provider.ts +1 -1
- package/src/messaging/providers/gmail/adapter.ts +1 -1
- package/src/messaging/providers/gmail/mime-builder.ts +17 -7
- package/src/messaging/providers/telegram-bot/adapter.ts +17 -8
- package/src/messaging/providers/whatsapp/adapter.ts +13 -9
- package/src/messaging/registry.ts +9 -5
- package/src/oauth/byo-connection.test.ts +40 -25
- package/src/oauth/connect-orchestrator.ts +4 -10
- package/src/oauth/connection-resolver.ts +20 -6
- package/src/oauth/manual-token-connection.ts +5 -5
- package/src/oauth/oauth-store.ts +183 -31
- package/src/oauth/platform-connection.test.ts +1 -1
- package/src/oauth/provider-behaviors.ts +503 -4
- package/src/oauth/seed-providers.ts +214 -8
- package/src/oauth/token-persistence.ts +31 -16
- package/src/permissions/defaults.ts +1 -0
- package/src/permissions/trust-store.ts +23 -1
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/prompts/system-prompt.ts +18 -2
- package/src/providers/anthropic/client.ts +56 -126
- package/src/providers/types.ts +7 -1
- package/src/runtime/AGENTS.md +9 -0
- package/src/runtime/auth/route-policy.ts +6 -3
- package/src/runtime/channel-readiness-service.ts +48 -40
- package/src/runtime/guardian-reply-router.ts +24 -22
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/invite-redemption-service.ts +72 -12
- package/src/runtime/invite-service.ts +43 -0
- package/src/runtime/middleware/twilio-validation.ts +1 -1
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/brain-graph-routes.ts +10 -90
- package/src/runtime/routes/btw-routes.ts +10 -5
- package/src/runtime/routes/conversation-routes.ts +56 -11
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
- package/src/runtime/routes/integrations/slack/channel.ts +2 -2
- package/src/runtime/routes/integrations/telegram.ts +2 -2
- package/src/runtime/routes/integrations/twilio.ts +17 -17
- package/src/runtime/routes/invite-routes.ts +29 -4
- package/src/runtime/routes/memory-item-routes.test.ts +754 -0
- package/src/runtime/routes/memory-item-routes.ts +503 -0
- package/src/runtime/routes/secret-routes.ts +17 -0
- package/src/runtime/routes/session-management-routes.ts +3 -3
- package/src/runtime/routes/settings-routes.ts +3 -3
- package/src/runtime/routes/trust-rules-routes.ts +14 -0
- package/src/runtime/routes/workspace-routes.ts +9 -4
- package/src/runtime/routes/workspace-utils.ts +8 -2
- package/src/schedule/integration-status.ts +26 -19
- package/src/security/keychain-broker-client.ts +17 -4
- package/src/security/oauth2.ts +6 -7
- package/src/security/secure-keys.ts +44 -19
- package/src/security/token-manager.ts +46 -39
- package/src/services/vercel-deploy.ts +0 -24
- package/src/signals/confirm.ts +78 -0
- package/src/signals/mcp-reload.ts +18 -0
- package/src/skills/catalog-install.ts +74 -18
- package/src/skills/skillssh-registry.ts +503 -0
- package/src/tools/assets/search.ts +5 -1
- package/src/tools/computer-use/definitions.ts +0 -10
- package/src/tools/computer-use/registry.ts +1 -1
- package/src/tools/credentials/vault.ts +22 -7
- package/src/tools/memory/definitions.ts +4 -13
- package/src/tools/memory/handlers.test.ts +83 -103
- package/src/tools/memory/handlers.ts +50 -85
- package/src/tools/network/script-proxy/session-manager.ts +8 -8
- package/src/tools/schedule/create.ts +10 -3
- package/src/tools/schedule/update.ts +8 -1
- package/src/tools/skills/load.ts +25 -2
- package/src/watcher/provider-types.ts +1 -1
- package/src/watcher/providers/github.ts +1 -1
- package/src/watcher/providers/gmail.ts +3 -3
- package/src/watcher/providers/google-calendar.ts +3 -3
- package/src/watcher/providers/linear.ts +1 -1
- package/src/__tests__/clarification-resolver.test.ts +0 -193
- package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
- package/src/__tests__/conflict-policy.test.ts +0 -269
- package/src/__tests__/conflict-store.test.ts +0 -372
- package/src/__tests__/contradiction-checker.test.ts +0 -361
- package/src/__tests__/entity-extractor.test.ts +0 -211
- package/src/__tests__/entity-search.test.ts +0 -1117
- package/src/__tests__/profile-compiler.test.ts +0 -392
- package/src/__tests__/session-conflict-gate.test.ts +0 -1228
- package/src/__tests__/session-profile-injection.test.ts +0 -557
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
- package/src/daemon/session-conflict-gate.ts +0 -167
- package/src/daemon/session-dynamic-profile.ts +0 -77
- package/src/memory/clarification-resolver.ts +0 -417
- package/src/memory/conflict-intent.ts +0 -205
- package/src/memory/conflict-policy.ts +0 -127
- package/src/memory/conflict-store.ts +0 -410
- package/src/memory/contradiction-checker.ts +0 -508
- package/src/memory/entity-extractor.ts +0 -535
- package/src/memory/format-recall.ts +0 -47
- package/src/memory/fts-reconciler.ts +0 -165
- package/src/memory/job-handlers/conflict.ts +0 -200
- package/src/memory/profile-compiler.ts +0 -195
- package/src/memory/recall-cache.ts +0 -117
- package/src/memory/search/entity.ts +0 -535
- package/src/memory/search/query-expansion.test.ts +0 -70
- package/src/memory/search/query-expansion.ts +0 -118
- package/src/runtime/routes/mcp-routes.ts +0 -20
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { v4 as uuid } from "uuid";
|
|
11
11
|
|
|
12
|
+
import { escapeAxTreeContent } from "../agent/loop.js";
|
|
12
13
|
import type { ContentBlock } from "../providers/types.js";
|
|
13
14
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
14
15
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -65,6 +66,7 @@ interface PendingRequest {
|
|
|
65
66
|
export class HostCuProxy {
|
|
66
67
|
private pending = new Map<string, PendingRequest>();
|
|
67
68
|
private sendToClient: (msg: ServerMessage) => void;
|
|
69
|
+
private onInternalResolve?: (requestId: string) => void;
|
|
68
70
|
private clientConnected = false;
|
|
69
71
|
|
|
70
72
|
// CU state tracking (per-conversation)
|
|
@@ -76,9 +78,11 @@ export class HostCuProxy {
|
|
|
76
78
|
|
|
77
79
|
constructor(
|
|
78
80
|
sendToClient: (msg: ServerMessage) => void,
|
|
81
|
+
onInternalResolve?: (requestId: string) => void,
|
|
79
82
|
maxSteps = MAX_STEPS,
|
|
80
83
|
) {
|
|
81
84
|
this.sendToClient = sendToClient;
|
|
85
|
+
this.onInternalResolve = onInternalResolve;
|
|
82
86
|
this._maxSteps = maxSteps;
|
|
83
87
|
}
|
|
84
88
|
|
|
@@ -150,6 +154,7 @@ export class HostCuProxy {
|
|
|
150
154
|
return new Promise<ToolExecutionResult>((resolve, reject) => {
|
|
151
155
|
const timer = setTimeout(() => {
|
|
152
156
|
this.pending.delete(requestId);
|
|
157
|
+
this.onInternalResolve?.(requestId);
|
|
153
158
|
log.warn({ requestId, toolName }, "Host CU proxy request timed out");
|
|
154
159
|
resolve({
|
|
155
160
|
content: "Host CU proxy timed out waiting for client response",
|
|
@@ -164,6 +169,7 @@ export class HostCuProxy {
|
|
|
164
169
|
if (this.pending.has(requestId)) {
|
|
165
170
|
clearTimeout(timer);
|
|
166
171
|
this.pending.delete(requestId);
|
|
172
|
+
this.onInternalResolve?.(requestId);
|
|
167
173
|
resolve({ content: "Aborted", isError: true });
|
|
168
174
|
}
|
|
169
175
|
};
|
|
@@ -191,10 +197,13 @@ export class HostCuProxy {
|
|
|
191
197
|
clearTimeout(entry.timer);
|
|
192
198
|
this.pending.delete(requestId);
|
|
193
199
|
|
|
200
|
+
// Capture pre-update state so formatObservation sees the correct previous AX tree
|
|
201
|
+
const prevAXTree = this._previousAXTree;
|
|
202
|
+
|
|
194
203
|
// Update CU state from observation
|
|
195
204
|
this.updateStateFromObservation(observation);
|
|
196
205
|
|
|
197
|
-
const result = this.formatObservation(observation);
|
|
206
|
+
const result = this.formatObservation(observation, prevAXTree);
|
|
198
207
|
entry.resolve(result);
|
|
199
208
|
}
|
|
200
209
|
|
|
@@ -202,6 +211,10 @@ export class HostCuProxy {
|
|
|
202
211
|
return this.pending.has(requestId);
|
|
203
212
|
}
|
|
204
213
|
|
|
214
|
+
isAvailable(): boolean {
|
|
215
|
+
return this.clientConnected;
|
|
216
|
+
}
|
|
217
|
+
|
|
205
218
|
// ---------------------------------------------------------------------------
|
|
206
219
|
// CU state management
|
|
207
220
|
// ---------------------------------------------------------------------------
|
|
@@ -245,7 +258,11 @@ export class HostCuProxy {
|
|
|
245
258
|
* (AX tree wrapped in markers, diff, warnings) and optional screenshot
|
|
246
259
|
* as an image content block.
|
|
247
260
|
*/
|
|
248
|
-
formatObservation(
|
|
261
|
+
formatObservation(
|
|
262
|
+
obs: CuObservationResult,
|
|
263
|
+
previousAXTree?: string,
|
|
264
|
+
): ToolExecutionResult {
|
|
265
|
+
const prevTree = previousAXTree;
|
|
249
266
|
const parts: string[] = [];
|
|
250
267
|
|
|
251
268
|
// Surface user guidance prominently so the model sees it first
|
|
@@ -263,21 +280,30 @@ export class HostCuProxy {
|
|
|
263
280
|
if (obs.axDiff) {
|
|
264
281
|
parts.push(obs.axDiff);
|
|
265
282
|
parts.push("");
|
|
266
|
-
} else if (
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
this.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
283
|
+
} else if (prevTree != null && obs.axTree != null) {
|
|
284
|
+
// Skip unchanged warning after wait actions — they intentionally yield no immediate change
|
|
285
|
+
const lastAction =
|
|
286
|
+
this._actionHistory.length > 0
|
|
287
|
+
? this._actionHistory[this._actionHistory.length - 1]
|
|
288
|
+
: undefined;
|
|
289
|
+
const isWaitAction = lastAction?.toolName === "computer_use_wait";
|
|
290
|
+
|
|
291
|
+
if (!isWaitAction) {
|
|
292
|
+
// No diff means the screen didn't change
|
|
293
|
+
if (
|
|
294
|
+
this._consecutiveUnchangedSteps >=
|
|
295
|
+
CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD
|
|
296
|
+
) {
|
|
297
|
+
parts.push(
|
|
298
|
+
`WARNING: ${this._consecutiveUnchangedSteps} consecutive actions had NO VISIBLE EFFECT on the UI. You MUST try a completely different approach.`,
|
|
299
|
+
);
|
|
300
|
+
} else {
|
|
301
|
+
parts.push(
|
|
302
|
+
"Your last action had NO VISIBLE EFFECT on the UI. Try something different.",
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
parts.push("");
|
|
279
306
|
}
|
|
280
|
-
parts.push("");
|
|
281
307
|
}
|
|
282
308
|
|
|
283
309
|
// Loop detection: identical actions repeated
|
|
@@ -300,10 +326,20 @@ export class HostCuProxy {
|
|
|
300
326
|
if (obs.axTree) {
|
|
301
327
|
parts.push("<ax-tree>");
|
|
302
328
|
parts.push("CURRENT SCREEN STATE:");
|
|
303
|
-
parts.push(
|
|
329
|
+
parts.push(escapeAxTreeContent(obs.axTree));
|
|
304
330
|
parts.push("</ax-tree>");
|
|
305
331
|
}
|
|
306
332
|
|
|
333
|
+
// Secondary windows for cross-app awareness
|
|
334
|
+
if (obs.secondaryWindows) {
|
|
335
|
+
parts.push("");
|
|
336
|
+
parts.push(obs.secondaryWindows);
|
|
337
|
+
parts.push("");
|
|
338
|
+
parts.push(
|
|
339
|
+
"Note: The element [ID]s above are from other windows — you can reference them for context but can only interact with the focused window's elements.",
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
307
343
|
// Screenshot metadata
|
|
308
344
|
const screenshotMeta = this.formatScreenshotMetadata(obs);
|
|
309
345
|
if (screenshotMeta.length > 0) {
|
|
@@ -342,8 +378,9 @@ export class HostCuProxy {
|
|
|
342
378
|
// ---------------------------------------------------------------------------
|
|
343
379
|
|
|
344
380
|
dispose(): void {
|
|
345
|
-
for (const [
|
|
381
|
+
for (const [requestId, entry] of this.pending) {
|
|
346
382
|
clearTimeout(entry.timer);
|
|
383
|
+
this.onInternalResolve?.(requestId);
|
|
347
384
|
entry.reject(
|
|
348
385
|
new AssistantError("Host CU proxy disposed", ErrorCode.INTERNAL_ERROR),
|
|
349
386
|
);
|
|
@@ -390,12 +427,4 @@ export class HostCuProxy {
|
|
|
390
427
|
}
|
|
391
428
|
return lines;
|
|
392
429
|
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Escapes literal `</ax-tree>` inside AX tree content so compaction
|
|
396
|
-
* regex does not stop prematurely.
|
|
397
|
-
*/
|
|
398
|
-
static escapeAxTreeContent(content: string): string {
|
|
399
|
-
return content.replace(/<\/ax-tree>/gi, "</ax-tree>");
|
|
400
|
-
}
|
|
401
430
|
}
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -26,13 +26,18 @@ import { closeSentry, initSentry } from "../instrument.js";
|
|
|
26
26
|
import { disableLogfire, initLogfire } from "../logfire.js";
|
|
27
27
|
import { getMcpServerManager } from "../mcp/manager.js";
|
|
28
28
|
import * as attachmentsStore from "../memory/attachments-store.js";
|
|
29
|
+
import { expireAllPendingCanonicalRequests } from "../memory/canonical-guardian-store.js";
|
|
29
30
|
import {
|
|
30
31
|
deleteMessageById,
|
|
31
32
|
getConversationThreadType,
|
|
32
33
|
getMessages,
|
|
33
34
|
} from "../memory/conversation-crud.js";
|
|
34
35
|
import { initializeDb } from "../memory/db.js";
|
|
35
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
selectEmbeddingBackend,
|
|
38
|
+
SPARSE_EMBEDDING_VERSION,
|
|
39
|
+
} from "../memory/embedding-backend.js";
|
|
40
|
+
import { enqueueMemoryJob } from "../memory/jobs-store.js";
|
|
36
41
|
import { startMemoryJobsWorker } from "../memory/jobs-worker.js";
|
|
37
42
|
import { initQdrantClient } from "../memory/qdrant-client.js";
|
|
38
43
|
import { QdrantManager } from "../memory/qdrant-manager.js";
|
|
@@ -162,9 +167,28 @@ export async function runDaemon(): Promise<void> {
|
|
|
162
167
|
// Backfill oauth_connection rows for manual-token providers (Telegram,
|
|
163
168
|
// Slack channel) that already have keychain credentials from before the
|
|
164
169
|
// oauth_connection migration. Safe to call on every startup.
|
|
165
|
-
|
|
170
|
+
try {
|
|
171
|
+
await backfillManualTokenConnections();
|
|
172
|
+
} catch (err) {
|
|
173
|
+
log.warn(
|
|
174
|
+
{ err },
|
|
175
|
+
"Manual-token connection backfill failed — continuing startup",
|
|
176
|
+
);
|
|
177
|
+
}
|
|
166
178
|
log.info("Daemon startup: DB initialized");
|
|
167
179
|
|
|
180
|
+
// Expire any pending canonical guardian requests left over from before
|
|
181
|
+
// this process started. Their in-memory pending-interaction session
|
|
182
|
+
// references are gone, so they can never be completed. The agent loop
|
|
183
|
+
// will re-request tool approvals on the next turn.
|
|
184
|
+
const expiredCount = expireAllPendingCanonicalRequests();
|
|
185
|
+
if (expiredCount > 0) {
|
|
186
|
+
log.info(
|
|
187
|
+
{ event: "startup_expired_stale_requests", expiredCount },
|
|
188
|
+
`Expired ${expiredCount} stale pending canonical request(s) from previous process`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
168
192
|
// Ensure a vellum guardian binding exists and mint the CLI edge token
|
|
169
193
|
// as an actor token bound to the guardian principal.
|
|
170
194
|
let guardianPrincipalId: string | undefined;
|
|
@@ -305,9 +329,9 @@ export async function runDaemon(): Promise<void> {
|
|
|
305
329
|
await qdrantManager.start();
|
|
306
330
|
const embeddingSelection = selectEmbeddingBackend(config);
|
|
307
331
|
const embeddingModel = embeddingSelection.backend
|
|
308
|
-
? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}`
|
|
332
|
+
? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}:sparse-v${SPARSE_EMBEDDING_VERSION}`
|
|
309
333
|
: undefined;
|
|
310
|
-
initQdrantClient({
|
|
334
|
+
const qdrantClient = initQdrantClient({
|
|
311
335
|
url: qdrantUrl,
|
|
312
336
|
collection: config.memory.qdrant.collection,
|
|
313
337
|
vectorSize: config.memory.qdrant.vectorSize,
|
|
@@ -315,6 +339,17 @@ export async function runDaemon(): Promise<void> {
|
|
|
315
339
|
quantization: config.memory.qdrant.quantization,
|
|
316
340
|
embeddingModel,
|
|
317
341
|
});
|
|
342
|
+
|
|
343
|
+
// Eagerly ensure the collection exists so we detect migrations
|
|
344
|
+
// (unnamed→named vectors, dimension/model changes) at startup.
|
|
345
|
+
// If a destructive migration occurred, enqueue a rebuild_index job
|
|
346
|
+
// to re-embed all memory items from the SQLite cache.
|
|
347
|
+
const { migrated } = await qdrantClient.ensureCollection();
|
|
348
|
+
if (migrated) {
|
|
349
|
+
enqueueMemoryJob("rebuild_index", {});
|
|
350
|
+
log.info("Qdrant collection was migrated — enqueued rebuild_index job");
|
|
351
|
+
}
|
|
352
|
+
|
|
318
353
|
log.info("Qdrant vector store initialized");
|
|
319
354
|
} catch (err) {
|
|
320
355
|
log.warn(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared MCP reload business logic.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Called by the ConfigWatcher when config.json changes or a reload signal
|
|
5
|
+
* file is detected, so the daemon automatically reconnects MCP servers.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { getConfig, invalidateConfigCache } from "../config/loader.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Computer use
|
|
1
|
+
// Computer use and watch observation types.
|
|
2
2
|
|
|
3
3
|
import type { CommandIntent, UserMessageAttachment } from "./shared.js";
|
|
4
4
|
|
|
@@ -89,16 +89,6 @@ export interface RecordingResume {
|
|
|
89
89
|
recordingId: string;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export interface TaskRouted {
|
|
93
|
-
type: "task_routed";
|
|
94
|
-
sessionId: string;
|
|
95
|
-
interactionType: "computer_use" | "text_qa";
|
|
96
|
-
/** The task text passed to the escalated session. */
|
|
97
|
-
task?: string;
|
|
98
|
-
/** Set when a text_qa session escalates to computer_use. */
|
|
99
|
-
escalatedFrom?: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
92
|
export interface WatchStarted {
|
|
103
93
|
type: "watch_started";
|
|
104
94
|
sessionId: string;
|
|
@@ -121,7 +111,6 @@ export type _ComputerUseClientMessages =
|
|
|
121
111
|
| RecordingStatus;
|
|
122
112
|
|
|
123
113
|
export type _ComputerUseServerMessages =
|
|
124
|
-
| TaskRouted
|
|
125
114
|
| WatchStarted
|
|
126
115
|
| WatchCompleteRequest
|
|
127
116
|
| RecordingStart
|
|
@@ -11,7 +11,6 @@ export interface MemoryRecalledCandidateDebug {
|
|
|
11
11
|
type: string;
|
|
12
12
|
kind: string;
|
|
13
13
|
finalScore: number;
|
|
14
|
-
lexical: number;
|
|
15
14
|
semantic: number;
|
|
16
15
|
recency: number;
|
|
17
16
|
}
|
|
@@ -21,18 +20,14 @@ export interface MemoryRecalled {
|
|
|
21
20
|
provider: string;
|
|
22
21
|
model: string;
|
|
23
22
|
degradation?: MemoryRecalledDegradation;
|
|
24
|
-
lexicalHits: number;
|
|
25
23
|
semanticHits: number;
|
|
26
24
|
recencyHits: number;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
relationExpandedItemCount?: number;
|
|
32
|
-
earlyTerminated?: boolean;
|
|
25
|
+
tier1Count: number;
|
|
26
|
+
tier2Count: number;
|
|
27
|
+
hybridSearchLatencyMs: number;
|
|
28
|
+
sparseVectorUsed: boolean;
|
|
33
29
|
mergedCount: number;
|
|
34
30
|
selectedCount: number;
|
|
35
|
-
rerankApplied: boolean;
|
|
36
31
|
injectedTokens: number;
|
|
37
32
|
latencyMs: number;
|
|
38
33
|
topCandidates: MemoryRecalledCandidateDebug[];
|
|
@@ -46,13 +41,6 @@ export interface MemoryStatus {
|
|
|
46
41
|
reason?: string;
|
|
47
42
|
provider?: string;
|
|
48
43
|
model?: string;
|
|
49
|
-
conflictsPending: number;
|
|
50
|
-
conflictsResolved: number;
|
|
51
|
-
oldestPendingConflictAgeMs: number | null;
|
|
52
|
-
cleanupResolvedJobsPending: number;
|
|
53
|
-
cleanupSupersededJobsPending: number;
|
|
54
|
-
cleanupResolvedJobsCompleted24h: number;
|
|
55
|
-
cleanupSupersededJobsCompleted24h: number;
|
|
56
44
|
}
|
|
57
45
|
|
|
58
46
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
@@ -85,35 +85,6 @@ export interface ImageGenModelSetRequest {
|
|
|
85
85
|
model: string;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
export interface HistoryRequest {
|
|
89
|
-
type: "history_request";
|
|
90
|
-
sessionId: string;
|
|
91
|
-
/** Max messages to return. When omitted, all messages are returned (unlimited). */
|
|
92
|
-
limit?: number;
|
|
93
|
-
/** Pagination cursor: return messages with timestamp before this value. */
|
|
94
|
-
beforeTimestamp?: number;
|
|
95
|
-
/** Pagination cursor tie-breaker: exclude this message ID when beforeTimestamp matches. */
|
|
96
|
-
beforeMessageId?: string;
|
|
97
|
-
/** Include attachment base64 data. Defaults to false in light mode. */
|
|
98
|
-
includeAttachments?: boolean;
|
|
99
|
-
/** Include tool screenshot base64 data. Defaults to false in light mode. */
|
|
100
|
-
includeToolImages?: boolean;
|
|
101
|
-
/** Include surface HTML payloads. Defaults to false in light mode. */
|
|
102
|
-
includeSurfaceData?: boolean;
|
|
103
|
-
/** Shorthand: 'light' = all include flags false (default), 'full' = all include flags true. */
|
|
104
|
-
mode?: "light" | "full";
|
|
105
|
-
/** Truncate message text fields beyond this character limit. When omitted, full text is returned. */
|
|
106
|
-
maxTextChars?: number;
|
|
107
|
-
/** Truncate tool result strings beyond this character limit. When omitted, full results are returned. */
|
|
108
|
-
maxToolResultChars?: number;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export interface MessageContentRequest {
|
|
112
|
-
type: "message_content_request";
|
|
113
|
-
sessionId: string;
|
|
114
|
-
messageId: string;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
88
|
export interface MessageContentResponse {
|
|
118
89
|
type: "message_content_response";
|
|
119
90
|
sessionId: string;
|
|
@@ -145,16 +116,6 @@ export interface SessionsClearRequest {
|
|
|
145
116
|
type: "sessions_clear";
|
|
146
117
|
}
|
|
147
118
|
|
|
148
|
-
export interface ConversationSearchRequest {
|
|
149
|
-
type: "conversation_search";
|
|
150
|
-
/** The search query string. */
|
|
151
|
-
query: string;
|
|
152
|
-
/** Maximum number of conversations to return. Defaults to 20. */
|
|
153
|
-
limit?: number;
|
|
154
|
-
/** Maximum number of matching messages to return per conversation. Defaults to 3. */
|
|
155
|
-
maxMessagesPerConversation?: number;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
119
|
export interface ReorderThreadsRequest {
|
|
159
120
|
type: "reorder_threads";
|
|
160
121
|
updates: Array<{
|
|
@@ -394,6 +355,8 @@ export type SessionErrorCode =
|
|
|
394
355
|
| "PROVIDER_RATE_LIMIT"
|
|
395
356
|
| "PROVIDER_API"
|
|
396
357
|
| "PROVIDER_BILLING"
|
|
358
|
+
| "PROVIDER_ORDERING"
|
|
359
|
+
| "PROVIDER_WEB_SEARCH"
|
|
397
360
|
| "CONTEXT_TOO_LARGE"
|
|
398
361
|
| "SESSION_ABORTED"
|
|
399
362
|
| "SESSION_PROCESSING_FAILED"
|
|
@@ -407,6 +370,8 @@ export interface SessionErrorMessage {
|
|
|
407
370
|
userMessage: string;
|
|
408
371
|
retryable: boolean;
|
|
409
372
|
debugDetails?: string;
|
|
373
|
+
/** Machine-readable error category for log report metadata and triage. */
|
|
374
|
+
errorCategory?: string;
|
|
410
375
|
}
|
|
411
376
|
|
|
412
377
|
/** Server push — broadcast when a schedule creates a conversation, so the client can show it as a chat thread. */
|
|
@@ -427,7 +392,6 @@ export type _SessionsClientMessages =
|
|
|
427
392
|
| ModelGetRequest
|
|
428
393
|
| ModelSetRequest
|
|
429
394
|
| ImageGenModelSetRequest
|
|
430
|
-
| HistoryRequest
|
|
431
395
|
| UndoRequest
|
|
432
396
|
| RegenerateRequest
|
|
433
397
|
| UsageRequest
|
|
@@ -436,8 +400,6 @@ export type _SessionsClientMessages =
|
|
|
436
400
|
| SessionSwitchRequest
|
|
437
401
|
| SessionRenameRequest
|
|
438
402
|
| SessionsClearRequest
|
|
439
|
-
| ConversationSearchRequest
|
|
440
|
-
| MessageContentRequest
|
|
441
403
|
| ReorderThreadsRequest;
|
|
442
404
|
|
|
443
405
|
export type _SessionsServerMessages =
|
package/src/daemon/server.ts
CHANGED
|
@@ -663,8 +663,13 @@ export class DaemonServer {
|
|
|
663
663
|
);
|
|
664
664
|
}
|
|
665
665
|
if (!session.isProcessing() || !session.hostCuProxy) {
|
|
666
|
-
session.setHostCuProxy(
|
|
666
|
+
session.setHostCuProxy(
|
|
667
|
+
new HostCuProxy(session.getCurrentSender(), (requestId) => {
|
|
668
|
+
pendingInteractions.resolve(requestId);
|
|
669
|
+
}),
|
|
670
|
+
);
|
|
667
671
|
}
|
|
672
|
+
session.addPreactivatedSkillId("computer-use");
|
|
668
673
|
} else if (!session.isProcessing()) {
|
|
669
674
|
session.setHostBashProxy(undefined);
|
|
670
675
|
session.setHostFileProxy(undefined);
|
|
@@ -57,6 +57,8 @@ export interface EventHandlerState {
|
|
|
57
57
|
orderingErrorDetected: boolean;
|
|
58
58
|
deferredOrderingError: string | null;
|
|
59
59
|
contextTooLargeDetected: boolean;
|
|
60
|
+
/** The raw error message from the provider when context_too_large is detected. */
|
|
61
|
+
contextTooLargeErrorMessage: string | null;
|
|
60
62
|
providerErrorUserMessage: string | null;
|
|
61
63
|
lastAssistantMessageId: string | undefined;
|
|
62
64
|
readonly pendingToolResults: Map<string, PendingToolResult>;
|
|
@@ -121,6 +123,7 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
121
123
|
orderingErrorDetected: false,
|
|
122
124
|
deferredOrderingError: null,
|
|
123
125
|
contextTooLargeDetected: false,
|
|
126
|
+
contextTooLargeErrorMessage: null,
|
|
124
127
|
providerErrorUserMessage: null,
|
|
125
128
|
lastAssistantMessageId: undefined,
|
|
126
129
|
pendingToolResults: new Map(),
|
|
@@ -595,12 +598,22 @@ export function handleError(
|
|
|
595
598
|
state.deferredOrderingError = event.error.message;
|
|
596
599
|
} else if (isContextTooLarge(event.error.message)) {
|
|
597
600
|
state.contextTooLargeDetected = true;
|
|
601
|
+
state.contextTooLargeErrorMessage = event.error.message;
|
|
598
602
|
} else {
|
|
599
603
|
const classified = classifySessionError(event.error, {
|
|
600
604
|
phase: "agent_loop",
|
|
601
605
|
});
|
|
602
606
|
if (classified.code === "CONTEXT_TOO_LARGE") {
|
|
603
607
|
state.contextTooLargeDetected = true;
|
|
608
|
+
state.contextTooLargeErrorMessage = event.error.message;
|
|
609
|
+
} else if (
|
|
610
|
+
classified.code === "PROVIDER_ORDERING" ||
|
|
611
|
+
classified.code === "PROVIDER_WEB_SEARCH"
|
|
612
|
+
) {
|
|
613
|
+
// Ordering errors detected via classifySessionError (e.g. from ProviderError
|
|
614
|
+
// with statusCode 400 and ordering message) — trigger the retry path.
|
|
615
|
+
state.orderingErrorDetected = true;
|
|
616
|
+
state.deferredOrderingError = event.error.message;
|
|
604
617
|
} else {
|
|
605
618
|
deps.onEvent(
|
|
606
619
|
buildSessionErrorMessage(deps.ctx.conversationId, classified),
|
|
@@ -831,6 +844,31 @@ export async function dispatchAgentEvent(
|
|
|
831
844
|
deps.reqId,
|
|
832
845
|
statusText,
|
|
833
846
|
);
|
|
847
|
+
// Emit tool_use_start so the client renders a tool chip (like other tools)
|
|
848
|
+
deps.onEvent({
|
|
849
|
+
type: "tool_use_start",
|
|
850
|
+
toolName: event.name,
|
|
851
|
+
input: event.input,
|
|
852
|
+
sessionId: deps.ctx.conversationId,
|
|
853
|
+
toolUseId: event.toolUseId,
|
|
854
|
+
});
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
case "server_tool_complete": {
|
|
858
|
+
deps.ctx.emitActivityState(
|
|
859
|
+
"streaming",
|
|
860
|
+
"tool_result_received",
|
|
861
|
+
"assistant_turn",
|
|
862
|
+
deps.reqId,
|
|
863
|
+
);
|
|
864
|
+
deps.onEvent({
|
|
865
|
+
type: "tool_result",
|
|
866
|
+
toolName: "",
|
|
867
|
+
result: "",
|
|
868
|
+
isError: false,
|
|
869
|
+
sessionId: deps.ctx.conversationId,
|
|
870
|
+
toolUseId: event.toolUseId,
|
|
871
|
+
});
|
|
834
872
|
break;
|
|
835
873
|
}
|
|
836
874
|
case "error":
|