vellum 0.2.1 → 0.2.7
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/README.md +15 -2
- package/bun.lock +71 -100
- package/package.json +5 -3
- package/scripts/capture-x-graphql.ts +562 -0
- package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
- package/scripts/test.sh +5 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +133 -34
- package/src/__tests__/account-registry.test.ts +2 -1
- package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
- package/src/__tests__/asset-materialize-tool.test.ts +16 -15
- package/src/__tests__/asset-search-tool.test.ts +23 -22
- package/src/__tests__/attachments-store.test.ts +56 -127
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
- package/src/__tests__/browser-skill-endstate.test.ts +4 -3
- package/src/__tests__/call-bridge.test.ts +385 -0
- package/src/__tests__/call-constants.test.ts +40 -0
- package/src/__tests__/call-orchestrator.test.ts +130 -4
- package/src/__tests__/call-recovery.test.ts +518 -0
- package/src/__tests__/call-routes-http.test.ts +459 -0
- package/src/__tests__/call-state-machine.test.ts +143 -0
- package/src/__tests__/call-store.test.ts +216 -1
- package/src/__tests__/cli-discover.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +148 -7
- package/src/__tests__/compaction.benchmark.test.ts +176 -0
- package/src/__tests__/computer-use-tools.test.ts +250 -0
- package/src/__tests__/config-schema.test.ts +305 -3
- package/src/__tests__/conflict-store.test.ts +2 -1
- package/src/__tests__/contacts-tools.test.ts +331 -0
- package/src/__tests__/conversation-store.test.ts +30 -32
- package/src/__tests__/credential-security-invariants.test.ts +4 -0
- package/src/__tests__/date-context.test.ts +373 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
- package/src/__tests__/followup-tools.test.ts +303 -0
- package/src/__tests__/handlers-twilio-config.test.ts +221 -0
- package/src/__tests__/handlers-twitter-config.test.ts +718 -0
- package/src/__tests__/intent-routing.test.ts +64 -57
- package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
- package/src/__tests__/ipc-snapshot.test.ts +71 -28
- package/src/__tests__/llm-usage-store.test.ts +3 -8
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
- package/src/__tests__/memory-regressions.test.ts +100 -2
- package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
- package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
- package/src/__tests__/playbook-tools.test.ts +342 -0
- package/src/__tests__/profile-compiler.test.ts +2 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +303 -0
- package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
- package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
- package/src/__tests__/recurrence-engine.test.ts +69 -0
- package/src/__tests__/recurrence-types.test.ts +71 -0
- package/src/__tests__/registry.test.ts +5 -3
- package/src/__tests__/relay-server.test.ts +633 -0
- package/src/__tests__/reminder-store.test.ts +6 -3
- package/src/__tests__/reminder.test.ts +43 -77
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +8 -4
- package/src/__tests__/run-orchestrator.test.ts +4 -4
- package/src/__tests__/runtime-attachment-metadata.test.ts +7 -6
- package/src/__tests__/runtime-runs-http.test.ts +4 -4
- package/src/__tests__/runtime-runs.test.ts +4 -4
- package/src/__tests__/schedule-store.test.ts +482 -0
- package/src/__tests__/schedule-tools.test.ts +700 -0
- package/src/__tests__/scheduler-recurrence.test.ts +329 -0
- package/src/__tests__/server-history-render.test.ts +14 -13
- package/src/__tests__/session-conflict-gate.test.ts +28 -25
- package/src/__tests__/session-error.test.ts +28 -0
- package/src/__tests__/session-init.benchmark.test.ts +462 -0
- package/src/__tests__/session-queue.test.ts +71 -48
- package/src/__tests__/session-runtime-assembly.test.ts +161 -0
- package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
- package/src/__tests__/signup-e2e.test.ts +2 -1
- package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
- package/src/__tests__/skill-script-runner.test.ts +159 -0
- package/src/__tests__/speaker-identification.test.ts +52 -0
- package/src/__tests__/subagent-manager-notify.test.ts +42 -10
- package/src/__tests__/subagent-tools.test.ts +141 -41
- package/src/__tests__/task-compiler.test.ts +2 -1
- package/src/__tests__/task-runner.test.ts +2 -1
- package/src/__tests__/task-scheduler.test.ts +2 -1
- package/src/__tests__/task-tools.test.ts +49 -56
- package/src/__tests__/tool-audit-listener.test.ts +1 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
- package/src/__tests__/tool-executor.test.ts +13 -17
- package/src/__tests__/turn-commit.test.ts +218 -3
- package/src/__tests__/twilio-provider.test.ts +143 -0
- package/src/__tests__/twilio-routes.test.ts +789 -0
- package/src/__tests__/twitter-auth-handler.test.ts +581 -0
- package/src/__tests__/view-image-tool.test.ts +217 -0
- package/src/__tests__/workspace-git-service.test.ts +186 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +13 -3
- package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
- package/src/bundler/app-bundler.ts +12 -8
- package/src/calls/__tests__/twilio-webhook-urls.test.ts +162 -0
- package/src/calls/call-bridge.ts +95 -0
- package/src/calls/call-constants.ts +43 -5
- package/src/calls/call-domain.ts +276 -0
- package/src/calls/call-orchestrator.ts +43 -17
- package/src/calls/call-recovery.ts +207 -0
- package/src/calls/call-state-machine.ts +68 -0
- package/src/calls/call-store.ts +192 -5
- package/src/calls/relay-server.ts +41 -4
- package/src/calls/speaker-identification.ts +213 -0
- package/src/calls/twilio-config.ts +8 -8
- package/src/calls/twilio-provider.ts +13 -9
- package/src/calls/twilio-routes.ts +90 -76
- package/src/calls/twilio-webhook-urls.ts +50 -0
- package/src/calls/types.ts +1 -1
- package/src/cli/config-commands.ts +334 -0
- package/src/cli/core-commands.ts +776 -0
- package/src/cli/doordash.ts +251 -1
- package/src/cli/ipc-client.ts +82 -0
- package/src/cli/map.ts +270 -0
- package/src/cli/twitter.ts +575 -0
- package/src/cli.ts +7 -5
- package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
- package/src/commands/cc-command-registry.ts +209 -0
- package/src/config/bundled-skills/contacts/SKILL.md +39 -0
- package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
- package/src/config/bundled-skills/document/SKILL.md +18 -0
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
- package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
- package/src/config/bundled-skills/doordash/SKILL.md +82 -23
- package/src/config/bundled-skills/followups/SKILL.md +32 -0
- package/src/config/bundled-skills/followups/TOOLS.json +100 -0
- package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -23
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
- package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
- package/src/config/bundled-skills/reminder/SKILL.md +20 -0
- package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
- package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
- package/src/config/bundled-skills/schedule/SKILL.md +74 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
- package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
- package/src/config/bundled-skills/subagent/SKILL.md +25 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
- package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
- package/src/config/bundled-skills/tasks/SKILL.md +28 -0
- package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
- package/src/config/bundled-skills/twitter/SKILL.md +134 -0
- package/src/config/bundled-skills/watcher/SKILL.md +27 -0
- package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
- package/src/config/defaults.ts +34 -0
- package/src/config/loader.ts +4 -1
- package/src/config/schema.ts +165 -1
- package/src/config/system-prompt.ts +61 -16
- package/src/config/templates/IDENTITY.md +7 -0
- package/src/config/types.ts +4 -0
- package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -5
- package/src/contacts/contact-store.ts +4 -4
- package/src/daemon/assistant-attachments.ts +10 -0
- package/src/daemon/classifier.ts +3 -1
- package/src/daemon/computer-use-session.ts +3 -1
- package/src/daemon/date-context.ts +136 -0
- package/src/daemon/handlers/apps.ts +16 -1
- package/src/daemon/handlers/browser.ts +54 -0
- package/src/daemon/handlers/computer-use.ts +7 -1
- package/src/daemon/handlers/config.ts +205 -5
- package/src/daemon/handlers/diagnostics.ts +5 -1
- package/src/daemon/handlers/documents.ts +18 -29
- package/src/daemon/handlers/home-base.ts +5 -1
- package/src/daemon/handlers/index.ts +40 -277
- package/src/daemon/handlers/misc.ts +9 -1
- package/src/daemon/handlers/publish.ts +6 -1
- package/src/daemon/handlers/sessions.ts +65 -12
- package/src/daemon/handlers/shared.ts +36 -1
- package/src/daemon/handlers/signing.ts +37 -0
- package/src/daemon/handlers/skills.ts +20 -6
- package/src/daemon/handlers/subagents.ts +8 -3
- package/src/daemon/handlers/twitter-auth.ts +169 -0
- package/src/daemon/handlers/work-items.ts +384 -68
- package/src/daemon/ipc-contract-inventory.json +32 -4
- package/src/daemon/ipc-contract.ts +156 -37
- package/src/daemon/ipc-protocol.ts +7 -2
- package/src/daemon/lifecycle.ts +21 -0
- package/src/daemon/main.ts +10 -4
- package/src/daemon/ride-shotgun-handler.ts +75 -10
- package/src/daemon/server.ts +143 -26
- package/src/daemon/session-agent-loop.ts +922 -0
- package/src/daemon/session-attachments.ts +28 -5
- package/src/daemon/session-conflict-gate.ts +18 -109
- package/src/daemon/session-error.ts +24 -3
- package/src/daemon/session-lifecycle.ts +147 -0
- package/src/daemon/session-media-retry.ts +147 -0
- package/src/daemon/session-messaging.ts +145 -0
- package/src/daemon/session-notifiers.ts +164 -0
- package/src/daemon/session-process.ts +2 -2
- package/src/daemon/session-queue-manager.ts +1 -0
- package/src/daemon/session-runtime-assembly.ts +52 -0
- package/src/daemon/session-skill-tools.ts +124 -5
- package/src/daemon/session-slash.ts +3 -0
- package/src/daemon/session-surfaces.ts +77 -2
- package/src/daemon/session-tool-setup.ts +216 -2
- package/src/daemon/session-usage.ts +0 -2
- package/src/daemon/session.ts +114 -1404
- package/src/daemon/video-thumbnail.ts +60 -0
- package/src/doordash/client.ts +121 -27
- package/src/doordash/queries.ts +1 -2
- package/src/export/formatter.ts +3 -1
- package/src/followups/followup-store.ts +4 -2
- package/src/followups/types.ts +6 -0
- package/src/hooks/templates.ts +1 -1
- package/src/index.ts +32 -1153
- package/src/memory/attachments-store.ts +28 -83
- package/src/memory/channel-delivery-store.ts +7 -21
- package/src/memory/clarification-resolver.ts +6 -5
- package/src/memory/conflict-intent.ts +114 -0
- package/src/memory/contradiction-checker.ts +3 -2
- package/src/memory/conversation-key-store.ts +10 -29
- package/src/memory/conversation-store.ts +2 -1
- package/src/memory/db.ts +96 -2
- package/src/memory/entity-extractor.ts +6 -3
- package/src/memory/items-extractor.ts +5 -4
- package/src/memory/job-handlers/conflict.ts +23 -1
- package/src/memory/jobs-store.ts +3 -2
- package/src/memory/llm-usage-store.ts +1 -2
- package/src/memory/runs-store.ts +1 -2
- package/src/memory/schema.ts +23 -2
- package/src/messaging/style-analyzer.ts +3 -2
- package/src/messaging/thread-summarizer.ts +8 -12
- package/src/messaging/triage-engine.ts +4 -2
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/registry.ts +8 -0
- package/src/runtime/gateway-client.ts +36 -0
- package/src/runtime/http-server.ts +166 -22
- package/src/runtime/routes/attachment-routes.ts +2 -3
- package/src/runtime/routes/call-routes.ts +140 -0
- package/src/runtime/routes/channel-routes.ts +125 -88
- package/src/runtime/routes/conversation-routes.ts +5 -5
- package/src/runtime/routes/run-routes.ts +2 -2
- package/src/runtime/run-orchestrator.ts +9 -3
- package/src/schedule/recurrence-engine.ts +138 -0
- package/src/schedule/recurrence-types.ts +67 -0
- package/src/schedule/schedule-store.ts +102 -57
- package/src/schedule/scheduler.ts +9 -6
- package/src/security/oauth2.ts +29 -4
- package/src/security/secret-allowlist.ts +46 -0
- package/src/skills/clawhub.ts +1 -1
- package/src/subagent/manager.ts +40 -8
- package/src/swarm/backend-claude-code.ts +64 -9
- package/src/swarm/worker-prompts.ts +2 -1
- package/src/tasks/SPEC.md +34 -28
- package/src/tasks/ephemeral-permissions.ts +16 -7
- package/src/tasks/task-compiler.ts +5 -4
- package/src/tasks/task-runner.ts +10 -5
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/tasks/tool-sanitizer.ts +36 -0
- package/src/tools/assets/search.ts +4 -4
- package/src/tools/browser/api-map.ts +293 -0
- package/src/tools/browser/auto-navigate.ts +270 -0
- package/src/tools/browser/browser-execution.ts +2 -1
- package/src/tools/browser/browser-manager.ts +2 -2
- package/src/tools/browser/network-recorder.ts +5 -4
- package/src/tools/browser/x-auto-navigate.ts +207 -0
- package/src/tools/calls/call-end.ts +17 -67
- package/src/tools/calls/call-start.ts +24 -85
- package/src/tools/calls/call-status.ts +35 -51
- package/src/tools/claude-code/claude-code.ts +207 -11
- package/src/tools/contacts/contact-merge.ts +46 -78
- package/src/tools/contacts/contact-search.ts +35 -79
- package/src/tools/contacts/contact-upsert.ts +35 -108
- package/src/tools/credentials/vault.ts +20 -4
- package/src/tools/document/document-tool.ts +71 -144
- package/src/tools/executor.ts +129 -10
- package/src/tools/followups/followup_create.ts +46 -88
- package/src/tools/followups/followup_list.ts +34 -74
- package/src/tools/followups/followup_resolve.ts +31 -66
- package/src/tools/host-terminal/cli-discover.ts +2 -1
- package/src/tools/host-terminal/host-shell.ts +10 -0
- package/src/tools/memory/handlers.ts +5 -4
- package/src/tools/network/__tests__/web-search.test.ts +427 -0
- package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
- package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
- package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
- package/src/tools/network/web-fetch.ts +18 -6
- package/src/tools/playbooks/index.ts +4 -5
- package/src/tools/playbooks/playbook-create.ts +3 -47
- package/src/tools/playbooks/playbook-delete.ts +1 -25
- package/src/tools/playbooks/playbook-list.ts +1 -28
- package/src/tools/playbooks/playbook-update.ts +3 -51
- package/src/tools/reminder/reminder.ts +5 -78
- package/src/tools/schedule/create.ts +69 -74
- package/src/tools/schedule/delete.ts +21 -47
- package/src/tools/schedule/list.ts +55 -74
- package/src/tools/schedule/update.ts +77 -84
- package/src/tools/subagent/abort.ts +29 -58
- package/src/tools/subagent/message.ts +30 -63
- package/src/tools/subagent/read.ts +53 -84
- package/src/tools/subagent/spawn.ts +43 -82
- package/src/tools/subagent/status.ts +42 -71
- package/src/tools/swarm/delegate.ts +2 -1
- package/src/tools/tasks/index.ts +8 -8
- package/src/tools/tasks/task-delete.ts +60 -88
- package/src/tools/tasks/task-list.ts +31 -52
- package/src/tools/tasks/task-run.ts +72 -108
- package/src/tools/tasks/task-save.ts +33 -65
- package/src/tools/tasks/work-item-enqueue.ts +183 -215
- package/src/tools/tasks/work-item-list.ts +33 -63
- package/src/tools/tasks/work-item-remove.ts +45 -97
- package/src/tools/tasks/work-item-update.ts +91 -163
- package/src/tools/terminal/backends/native.ts +3 -1
- package/src/tools/tool-manifest.ts +0 -62
- package/src/tools/types.ts +6 -0
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/tools/watch/screen-watch.ts +3 -1
- package/src/tools/watcher/create.ts +52 -98
- package/src/tools/watcher/delete.ts +20 -46
- package/src/tools/watcher/digest.ts +36 -70
- package/src/tools/watcher/list.ts +49 -79
- package/src/tools/watcher/update.ts +45 -91
- package/src/twitter/client.ts +690 -0
- package/src/twitter/session.ts +91 -0
- package/src/usage/types.ts +0 -1
- package/src/util/truncate.ts +6 -0
- package/src/watcher/providers/slack.ts +2 -1
- package/src/watcher/watcher-store.ts +3 -2
- package/src/work-items/work-item-store.ts +27 -2
- package/src/workspace/commit-message-enrichment-service.ts +31 -7
- package/src/workspace/git-service.ts +87 -22
- package/src/workspace/provider-commit-message-generator.ts +269 -0
- package/src/workspace/turn-commit.ts +62 -3
- package/src/tools/contacts/index.ts +0 -4
- package/src/tools/document/index.ts +0 -5
- package/src/tools/followups/index.ts +0 -3
- package/src/tools/subagent/index.ts +0 -5
- /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
ServerMessage,
|
|
5
5
|
SurfaceType,
|
|
6
6
|
SurfaceData,
|
|
7
|
+
CardSurfaceData,
|
|
7
8
|
DynamicPageSurfaceData,
|
|
8
9
|
FileUploadSurfaceData,
|
|
9
10
|
UiSurfaceShow,
|
|
@@ -20,6 +21,74 @@ import {
|
|
|
20
21
|
const log = getLogger('session-surfaces');
|
|
21
22
|
|
|
22
23
|
const MAX_UNDO_DEPTH = 10;
|
|
24
|
+
const TASK_PROGRESS_TEMPLATE_FIELDS = ['title', 'status', 'steps'] as const;
|
|
25
|
+
|
|
26
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
27
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function normalizeCardShowData(input: Record<string, unknown>, rawData: Record<string, unknown>): CardSurfaceData {
|
|
31
|
+
const normalized: Record<string, unknown> = { ...rawData };
|
|
32
|
+
|
|
33
|
+
// Older prompt examples sent template/templateData at the top level.
|
|
34
|
+
if (typeof normalized.template !== 'string' && typeof input.template === 'string') {
|
|
35
|
+
normalized.template = input.template;
|
|
36
|
+
}
|
|
37
|
+
if (!isPlainObject(normalized.templateData) && isPlainObject(input.templateData)) {
|
|
38
|
+
normalized.templateData = input.templateData;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// task_progress cards need a title for Swift parsing; fall back when missing.
|
|
42
|
+
if (normalized.template === 'task_progress' && typeof normalized.title !== 'string') {
|
|
43
|
+
if (typeof input.title === 'string' && input.title.trim().length > 0) {
|
|
44
|
+
normalized.title = input.title;
|
|
45
|
+
} else if (isPlainObject(normalized.templateData) && typeof normalized.templateData.title === 'string') {
|
|
46
|
+
normalized.title = normalized.templateData.title;
|
|
47
|
+
} else {
|
|
48
|
+
normalized.title = 'Task Progress';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (normalized.template === 'task_progress' && typeof normalized.body !== 'string') {
|
|
53
|
+
normalized.body = '';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return normalized as unknown as CardSurfaceData;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeTaskProgressCardPatch(existingCard: CardSurfaceData, patch: Record<string, unknown>): Record<string, unknown> {
|
|
60
|
+
if (existingCard.template !== 'task_progress') {
|
|
61
|
+
return patch;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const normalizedPatch: Record<string, unknown> = { ...patch };
|
|
65
|
+
const mergedTemplateData: Record<string, unknown> = isPlainObject(existingCard.templateData)
|
|
66
|
+
? { ...existingCard.templateData }
|
|
67
|
+
: {};
|
|
68
|
+
|
|
69
|
+
let updatedTemplateData = false;
|
|
70
|
+
|
|
71
|
+
if (isPlainObject(normalizedPatch.templateData)) {
|
|
72
|
+
Object.assign(mergedTemplateData, normalizedPatch.templateData);
|
|
73
|
+
updatedTemplateData = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Accept top-level task_progress fields from older prompt examples and
|
|
77
|
+
// move them into templateData where the Swift client expects them.
|
|
78
|
+
for (const key of TASK_PROGRESS_TEMPLATE_FIELDS) {
|
|
79
|
+
if (key in normalizedPatch) {
|
|
80
|
+
mergedTemplateData[key] = normalizedPatch[key];
|
|
81
|
+
delete normalizedPatch[key];
|
|
82
|
+
updatedTemplateData = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (updatedTemplateData) {
|
|
87
|
+
normalizedPatch.templateData = mergedTemplateData;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return normalizedPatch;
|
|
91
|
+
}
|
|
23
92
|
|
|
24
93
|
/**
|
|
25
94
|
* Subset of Session state that surface helpers need access to.
|
|
@@ -447,7 +516,10 @@ export async function surfaceProxyResolver(
|
|
|
447
516
|
const surfaceId = uuid();
|
|
448
517
|
const surfaceType = input.surface_type as SurfaceType;
|
|
449
518
|
const title = typeof input.title === 'string' ? input.title : undefined;
|
|
450
|
-
const
|
|
519
|
+
const rawData = isPlainObject(input.data) ? input.data : {};
|
|
520
|
+
const data = (surfaceType === 'card'
|
|
521
|
+
? normalizeCardShowData(input, rawData)
|
|
522
|
+
: rawData) as SurfaceData;
|
|
451
523
|
const actions = input.actions as Array<{ id: string; label: string; style?: string }> | undefined;
|
|
452
524
|
// Interactive surfaces default to awaiting user action.
|
|
453
525
|
const hasActions = Array.isArray(actions) && actions.length > 0;
|
|
@@ -502,12 +574,15 @@ export async function surfaceProxyResolver(
|
|
|
502
574
|
|
|
503
575
|
if (toolName === 'ui_update') {
|
|
504
576
|
const surfaceId = input.surface_id as string;
|
|
505
|
-
|
|
577
|
+
let patch = (isPlainObject(input.data) ? input.data : {}) as Record<string, unknown>;
|
|
506
578
|
|
|
507
579
|
// Merge the partial patch into the stored full surface data
|
|
508
580
|
const stored = ctx.surfaceState.get(surfaceId);
|
|
509
581
|
let mergedData: SurfaceData;
|
|
510
582
|
if (stored) {
|
|
583
|
+
if (stored.surfaceType === 'card') {
|
|
584
|
+
patch = normalizeTaskProgressCardPatch(stored.data as CardSurfaceData, patch);
|
|
585
|
+
}
|
|
511
586
|
// Push current HTML to undo stack for dynamic pages
|
|
512
587
|
if (stored.surfaceType === 'dynamic_page') {
|
|
513
588
|
const currentHtml = (stored.data as DynamicPageSurfaceData).html;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* keeping the constructor body focused on wiring.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { ToolDefinition } from '../providers/types.js';
|
|
9
|
+
import type { Message, ToolDefinition } from '../providers/types.js';
|
|
10
10
|
import type { ToolExecutionResult, ToolLifecycleEventHandler } from '../tools/types.js';
|
|
11
11
|
import type { ServerMessage, UiSurfaceShow } from './ipc-protocol.js';
|
|
12
12
|
import type { ToolExecutor } from '../tools/executor.js';
|
|
@@ -26,6 +26,7 @@ import type { SurfaceSessionContext } from './session-surfaces.js';
|
|
|
26
26
|
import { updatePublishedAppDeployment } from '../services/published-app-updater.js';
|
|
27
27
|
import { registerSessionSender } from '../tools/browser/browser-screencast.js';
|
|
28
28
|
import type { ProxyApprovalCallback, ProxyApprovalRequest } from '../tools/network/script-proxy/index.js';
|
|
29
|
+
import { projectSkillTools, type SkillProjectionCache } from './session-skill-tools.js';
|
|
29
30
|
|
|
30
31
|
// ── Context Interface ────────────────────────────────────────────────
|
|
31
32
|
|
|
@@ -46,6 +47,10 @@ export interface ToolSetupContext extends SurfaceSessionContext {
|
|
|
46
47
|
memoryPolicy: { scopeId: string; strictSideEffects: boolean };
|
|
47
48
|
/** True when the session has no connected IPC client (HTTP-only path). */
|
|
48
49
|
hasNoClient?: boolean;
|
|
50
|
+
/** When true, the session is executing a task run and must not become interactive. */
|
|
51
|
+
headlessLock?: boolean;
|
|
52
|
+
/** When set, this session is executing a task run. Used to retrieve ephemeral permission rules. */
|
|
53
|
+
taskRunId?: string;
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
// ── buildToolDefinitions ─────────────────────────────────────────────
|
|
@@ -65,6 +70,59 @@ export function buildToolDefinitions(): ToolDefinition[] {
|
|
|
65
70
|
];
|
|
66
71
|
}
|
|
67
72
|
|
|
73
|
+
// ── DoorDash task_progress auto-update ────────────────────────────────
|
|
74
|
+
|
|
75
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
76
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface DoordashStep { label: string; status: string; detail?: string }
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Map a `vellum doordash <subcommand>` to the step label it corresponds to.
|
|
83
|
+
*/
|
|
84
|
+
function doordashCommandToStep(cmd: string): string | null {
|
|
85
|
+
if (/vellum doordash status\b/.test(cmd) || /vellum doordash refresh\b/.test(cmd) || /vellum doordash login\b/.test(cmd)) return 'Check session';
|
|
86
|
+
if (/vellum doordash search\b/.test(cmd) || /vellum doordash search-items\b/.test(cmd)) return 'Search restaurants';
|
|
87
|
+
if (/vellum doordash menu\b/.test(cmd) || /vellum doordash item\b/.test(cmd) || /vellum doordash store-search\b/.test(cmd)) return 'Browse menu';
|
|
88
|
+
if (/vellum doordash cart\b/.test(cmd)) return 'Add to cart';
|
|
89
|
+
if (/vellum doordash checkout\b/.test(cmd) || /vellum doordash payment-methods\b/.test(cmd)) return 'Add to cart';
|
|
90
|
+
if (/vellum doordash order\b/.test(cmd)) return 'Place order';
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Given a completed DoorDash CLI command, return updated steps array or null if no change.
|
|
96
|
+
*/
|
|
97
|
+
function updateDoordashSteps(cmd: string, steps: DoordashStep[], isError: boolean): DoordashStep[] | null {
|
|
98
|
+
const stepLabel = doordashCommandToStep(cmd);
|
|
99
|
+
if (!stepLabel) return null;
|
|
100
|
+
|
|
101
|
+
const stepIndex = steps.findIndex(s => s.label === stepLabel);
|
|
102
|
+
if (stepIndex < 0) return null;
|
|
103
|
+
|
|
104
|
+
const updated = steps.map((s, i) => {
|
|
105
|
+
if (i < stepIndex) {
|
|
106
|
+
// Steps before current should be completed
|
|
107
|
+
return s.status === 'completed' ? s : { ...s, status: 'completed' };
|
|
108
|
+
}
|
|
109
|
+
if (i === stepIndex) {
|
|
110
|
+
if (isError) {
|
|
111
|
+
// If the command failed, mark as in_progress still (will retry)
|
|
112
|
+
return { ...s, status: 'in_progress' };
|
|
113
|
+
}
|
|
114
|
+
return { ...s, status: 'completed' };
|
|
115
|
+
}
|
|
116
|
+
if (i === stepIndex + 1 && !isError) {
|
|
117
|
+
// Next step becomes waiting (user may need to respond before it starts)
|
|
118
|
+
return { ...s, status: 'waiting' };
|
|
119
|
+
}
|
|
120
|
+
return s;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return updated;
|
|
124
|
+
}
|
|
125
|
+
|
|
68
126
|
// ── createToolExecutor ───────────────────────────────────────────────
|
|
69
127
|
|
|
70
128
|
/**
|
|
@@ -85,11 +143,47 @@ export function createToolExecutor(
|
|
|
85
143
|
registerSessionSender(ctx.conversationId, (msg) => ctx.sendToClient(msg));
|
|
86
144
|
|
|
87
145
|
return async (name: string, input: Record<string, unknown>, onOutput?: (chunk: string) => void) => {
|
|
146
|
+
// Pre-execution: mark the current DoorDash step as in_progress when command starts
|
|
147
|
+
if (name === 'bash' || name === 'host_bash') {
|
|
148
|
+
const preCmd = input.command as string | undefined;
|
|
149
|
+
if (preCmd?.includes('vellum doordash')) {
|
|
150
|
+
const surfaceId = 'doordash-progress';
|
|
151
|
+
const stored = ctx.surfaceState.get(surfaceId);
|
|
152
|
+
if (stored && stored.surfaceType === 'card') {
|
|
153
|
+
const card = stored.data as import('./ipc-contract.js').CardSurfaceData;
|
|
154
|
+
if (card.template === 'task_progress' && isPlainObject(card.templateData)) {
|
|
155
|
+
const steps = (card.templateData as Record<string, unknown>).steps;
|
|
156
|
+
if (Array.isArray(steps)) {
|
|
157
|
+
const stepLabel = doordashCommandToStep(preCmd);
|
|
158
|
+
if (stepLabel) {
|
|
159
|
+
const stepIndex = (steps as DoordashStep[]).findIndex(s => s.label === stepLabel);
|
|
160
|
+
if (stepIndex >= 0 && (steps as DoordashStep[])[stepIndex].status !== 'in_progress') {
|
|
161
|
+
const updatedSteps = (steps as DoordashStep[]).map((s, i) =>
|
|
162
|
+
i === stepIndex ? { ...s, status: 'in_progress' } : s
|
|
163
|
+
);
|
|
164
|
+
const updatedTemplateData = { ...card.templateData as Record<string, unknown>, steps: updatedSteps };
|
|
165
|
+
const updatedData = { ...card, templateData: updatedTemplateData };
|
|
166
|
+
stored.data = updatedData as import('./ipc-contract.js').CardSurfaceData;
|
|
167
|
+
ctx.sendToClient({
|
|
168
|
+
type: 'ui_surface_update',
|
|
169
|
+
sessionId: ctx.conversationId,
|
|
170
|
+
surfaceId,
|
|
171
|
+
data: updatedData,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
88
181
|
const result = await executor.execute(name, input, {
|
|
89
182
|
workingDir: ctx.workingDir,
|
|
90
183
|
sessionId: ctx.conversationId,
|
|
91
184
|
conversationId: ctx.conversationId,
|
|
92
185
|
requestId: ctx.currentRequestId,
|
|
186
|
+
taskRunId: ctx.taskRunId,
|
|
93
187
|
onOutput,
|
|
94
188
|
signal: ctx.abortController?.signal,
|
|
95
189
|
sandboxOverride: ctx.sandboxOverride,
|
|
@@ -114,7 +208,7 @@ export function createToolExecutor(
|
|
|
114
208
|
});
|
|
115
209
|
}
|
|
116
210
|
},
|
|
117
|
-
isInteractive: !ctx.hasNoClient,
|
|
211
|
+
isInteractive: !ctx.hasNoClient && !ctx.headlessLock,
|
|
118
212
|
proxyToolResolver: (toolName: string, proxyInput: Record<string, unknown>) => surfaceProxyResolver(ctx, toolName, proxyInput),
|
|
119
213
|
proxyApprovalCallback: createProxyApprovalCallback(prompter, ctx),
|
|
120
214
|
requestSecret: async (params) => {
|
|
@@ -198,6 +292,74 @@ export function createToolExecutor(
|
|
|
198
292
|
}
|
|
199
293
|
}
|
|
200
294
|
|
|
295
|
+
// Auto-emit task_progress card on first DoorDash CLI command
|
|
296
|
+
if (name === 'bash' || name === 'host_bash') {
|
|
297
|
+
const cmd = input.command as string | undefined;
|
|
298
|
+
if (cmd?.includes('vellum doordash')) {
|
|
299
|
+
const surfaceId = 'doordash-progress';
|
|
300
|
+
|
|
301
|
+
if (!ctx.surfaceState.has(surfaceId)) {
|
|
302
|
+
// First DoorDash command — auto-emit the task_progress card
|
|
303
|
+
const data = {
|
|
304
|
+
title: 'Ordering from DoorDash',
|
|
305
|
+
body: '',
|
|
306
|
+
template: 'task_progress' as const,
|
|
307
|
+
templateData: {
|
|
308
|
+
title: 'Ordering from DoorDash',
|
|
309
|
+
status: 'in_progress',
|
|
310
|
+
steps: [
|
|
311
|
+
{ label: 'Check session', status: 'in_progress' },
|
|
312
|
+
{ label: 'Search restaurants', status: 'pending' },
|
|
313
|
+
{ label: 'Browse menu', status: 'pending' },
|
|
314
|
+
{ label: 'Add to cart', status: 'pending' },
|
|
315
|
+
{ label: 'Place order', status: 'pending' },
|
|
316
|
+
],
|
|
317
|
+
},
|
|
318
|
+
} satisfies import('./ipc-contract.js').CardSurfaceData;
|
|
319
|
+
ctx.surfaceState.set(surfaceId, { surfaceType: 'card', data });
|
|
320
|
+
ctx.sendToClient({
|
|
321
|
+
type: 'ui_surface_show',
|
|
322
|
+
sessionId: ctx.conversationId,
|
|
323
|
+
surfaceId,
|
|
324
|
+
surfaceType: 'card',
|
|
325
|
+
title: 'Ordering from DoorDash',
|
|
326
|
+
data,
|
|
327
|
+
display: 'inline',
|
|
328
|
+
});
|
|
329
|
+
ctx.currentTurnSurfaces.push({
|
|
330
|
+
surfaceId,
|
|
331
|
+
surfaceType: 'card',
|
|
332
|
+
title: 'Ordering from DoorDash',
|
|
333
|
+
data,
|
|
334
|
+
display: 'inline',
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Auto-update step statuses based on the command that just ran
|
|
339
|
+
const stored = ctx.surfaceState.get(surfaceId);
|
|
340
|
+
if (stored && stored.surfaceType === 'card') {
|
|
341
|
+
const card = stored.data as import('./ipc-contract.js').CardSurfaceData;
|
|
342
|
+
if (card.template === 'task_progress' && isPlainObject(card.templateData)) {
|
|
343
|
+
const steps = (card.templateData as Record<string, unknown>).steps;
|
|
344
|
+
if (Array.isArray(steps)) {
|
|
345
|
+
const updatedSteps = updateDoordashSteps(cmd, steps as Array<{ label: string; status: string; detail?: string }>, result.isError);
|
|
346
|
+
if (updatedSteps) {
|
|
347
|
+
const updatedTemplateData = { ...card.templateData as Record<string, unknown>, steps: updatedSteps };
|
|
348
|
+
const updatedData = { ...card, templateData: updatedTemplateData };
|
|
349
|
+
stored.data = updatedData as import('./ipc-contract.js').CardSurfaceData;
|
|
350
|
+
ctx.sendToClient({
|
|
351
|
+
type: 'ui_surface_update',
|
|
352
|
+
sessionId: ctx.conversationId,
|
|
353
|
+
surfaceId,
|
|
354
|
+
data: updatedData,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
201
363
|
return result;
|
|
202
364
|
};
|
|
203
365
|
}
|
|
@@ -290,3 +452,55 @@ export function createProxyApprovalCallback(
|
|
|
290
452
|
|| response.decision === 'always_allow_high_risk';
|
|
291
453
|
};
|
|
292
454
|
}
|
|
455
|
+
|
|
456
|
+
// ── createResolveToolsCallback ───────────────────────────────────────
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Bundled skills that must always be active regardless of conversation
|
|
460
|
+
* history or explicit preactivation. Without this, their tools are
|
|
461
|
+
* unavailable in fresh sessions until `skill_load` is called.
|
|
462
|
+
*/
|
|
463
|
+
const DEFAULT_PREACTIVATED_SKILL_IDS = ['tasks'];
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Subset of Session state that the resolveTools callback reads at each
|
|
467
|
+
* agent turn. Properties are read lazily from this reference.
|
|
468
|
+
*/
|
|
469
|
+
export interface SkillProjectionContext {
|
|
470
|
+
preactivatedSkillIds?: string[];
|
|
471
|
+
readonly skillProjectionState: Map<string, string>;
|
|
472
|
+
readonly skillProjectionCache: SkillProjectionCache;
|
|
473
|
+
readonly coreToolNames: Set<string>;
|
|
474
|
+
allowedToolNames?: Set<string>;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Build a resolveTools callback that merges base tool definitions with
|
|
479
|
+
* dynamically projected skill tools on each agent turn. Also updates
|
|
480
|
+
* allowedToolNames so newly-activated skill tools aren't blocked by
|
|
481
|
+
* the executor's stale gate.
|
|
482
|
+
*/
|
|
483
|
+
export function createResolveToolsCallback(
|
|
484
|
+
toolDefs: ToolDefinition[],
|
|
485
|
+
ctx: SkillProjectionContext,
|
|
486
|
+
): ((history: Message[]) => ToolDefinition[]) | undefined {
|
|
487
|
+
if (toolDefs.length === 0) return undefined;
|
|
488
|
+
|
|
489
|
+
return (history: Message[]) => {
|
|
490
|
+
const effectivePreactivated = [
|
|
491
|
+
...DEFAULT_PREACTIVATED_SKILL_IDS,
|
|
492
|
+
...(ctx.preactivatedSkillIds ?? []),
|
|
493
|
+
];
|
|
494
|
+
const projection = projectSkillTools(history, {
|
|
495
|
+
preactivatedSkillIds: effectivePreactivated,
|
|
496
|
+
previouslyActiveSkillIds: ctx.skillProjectionState,
|
|
497
|
+
cache: ctx.skillProjectionCache,
|
|
498
|
+
});
|
|
499
|
+
const turnAllowed = new Set(ctx.coreToolNames);
|
|
500
|
+
for (const name of projection.allowedToolNames) {
|
|
501
|
+
turnAllowed.add(name);
|
|
502
|
+
}
|
|
503
|
+
ctx.allowedToolNames = turnAllowed;
|
|
504
|
+
return [...toolDefs, ...projection.toolDefinitions];
|
|
505
|
+
};
|
|
506
|
+
}
|
|
@@ -11,7 +11,6 @@ const log = getLogger('session-usage');
|
|
|
11
11
|
export interface UsageContext {
|
|
12
12
|
conversationId: string;
|
|
13
13
|
providerName: string;
|
|
14
|
-
assistantId: string | null;
|
|
15
14
|
usageStats: UsageStats;
|
|
16
15
|
}
|
|
17
16
|
|
|
@@ -60,7 +59,6 @@ export function recordUsage(
|
|
|
60
59
|
outputTokens,
|
|
61
60
|
cacheCreationInputTokens: null,
|
|
62
61
|
cacheReadInputTokens: null,
|
|
63
|
-
assistantId: ctx.assistantId,
|
|
64
62
|
conversationId: ctx.conversationId,
|
|
65
63
|
runId: null,
|
|
66
64
|
requestId,
|