vellum 0.2.0 → 0.2.2
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 +5 -2
- package/package.json +4 -2
- 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 +161 -34
- package/src/__tests__/account-registry.test.ts +2 -1
- package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
- package/src/__tests__/app-bundler.test.ts +12 -33
- 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 +5 -8
- 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 +454 -0
- 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-state.test.ts +133 -0
- package/src/__tests__/call-store.test.ts +691 -0
- package/src/__tests__/cli-discover.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +550 -0
- 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 +348 -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__/doordash-session.test.ts +9 -0
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
- package/src/__tests__/followup-tools.test.ts +303 -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 +96 -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-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-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 +17 -10
- 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 +222 -0
- package/src/__tests__/run-orchestrator.test.ts +7 -7
- package/src/__tests__/runtime-attachment-metadata.test.ts +19 -20
- package/src/__tests__/runtime-runs-http.test.ts +5 -23
- package/src/__tests__/runtime-runs.test.ts +11 -11
- 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-error.test.ts +28 -0
- package/src/__tests__/session-init.benchmark.test.ts +462 -0
- package/src/__tests__/session-queue.test.ts +89 -16
- 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 +273 -2
- 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 +403 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +141 -2
- package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
- package/src/bundler/app-bundler.ts +35 -14
- package/src/calls/call-bridge.ts +95 -0
- package/src/calls/call-constants.ts +48 -0
- package/src/calls/call-domain.ts +276 -0
- package/src/calls/call-orchestrator.ts +390 -0
- package/src/calls/call-recovery.ts +207 -0
- package/src/calls/call-state-machine.ts +68 -0
- package/src/calls/call-state.ts +64 -0
- package/src/calls/call-store.ts +416 -0
- package/src/calls/relay-server.ts +335 -0
- package/src/calls/speaker-identification.ts +213 -0
- package/src/calls/twilio-config.ts +34 -0
- package/src/calls/twilio-provider.ts +173 -0
- package/src/calls/twilio-routes.ts +250 -0
- package/src/calls/types.ts +37 -0
- package/src/calls/voice-provider.ts +14 -0
- package/src/cli/config-commands.ts +334 -0
- package/src/cli/core-commands.ts +776 -0
- package/src/cli/doordash.ts +256 -25
- package/src/cli/ipc-client.ts +82 -0
- package/src/cli/map.ts +246 -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 +163 -0
- 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.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -24
- 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 +44 -0
- package/src/config/loader.ts +4 -1
- package/src/config/schema.ts +218 -1
- package/src/config/system-prompt.ts +100 -6
- package/src/config/templates/IDENTITY.md +7 -0
- package/src/config/types.ts +5 -0
- 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 +192 -4
- 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 -271
- 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 +495 -39
- package/src/daemon/ipc-contract-inventory.json +40 -4
- package/src/daemon/ipc-contract.ts +185 -37
- package/src/daemon/ipc-protocol.ts +7 -2
- package/src/daemon/lifecycle.ts +48 -5
- package/src/daemon/main.ts +10 -4
- package/src/daemon/ride-shotgun-handler.ts +74 -10
- package/src/daemon/server.ts +144 -29
- package/src/daemon/session-agent-loop.ts +887 -0
- package/src/daemon/session-attachments.ts +28 -5
- 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 +222 -2
- package/src/daemon/session-usage.ts +0 -2
- package/src/daemon/session.ts +114 -1365
- 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 -1151
- package/src/media/gemini-image-service.ts +1 -1
- 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/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 +362 -2
- package/src/memory/entity-extractor.ts +6 -3
- package/src/memory/items-extractor.ts +5 -4
- 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 +65 -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/http-server.ts +277 -25
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/routes/attachment-routes.ts +5 -6
- package/src/runtime/routes/call-routes.ts +140 -0
- package/src/runtime/routes/channel-routes.ts +12 -19
- package/src/runtime/routes/conversation-routes.ts +5 -9
- package/src/runtime/routes/run-routes.ts +4 -8
- package/src/runtime/run-orchestrator.ts +39 -6
- 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 +220 -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 +67 -0
- package/src/tools/calls/call-start.ts +73 -0
- package/src/tools/calls/call-status.ts +81 -0
- package/src/tools/claude-code/claude-code.ts +77 -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 +21 -5
- 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/registry.ts +2 -4
- 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 -6
- package/src/tools/tasks/task-delete.ts +69 -56
- package/src/tools/tasks/task-list.ts +31 -52
- package/src/tools/tasks/task-run.ts +74 -102
- package/src/tools/tasks/task-save.ts +33 -65
- package/src/tools/tasks/work-item-enqueue.ts +192 -134
- package/src/tools/tasks/work-item-list.ts +33 -78
- package/src/tools/tasks/work-item-remove.ts +60 -0
- package/src/tools/tasks/work-item-update.ts +114 -0
- package/src/tools/terminal/backends/native.ts +3 -1
- package/src/tools/tool-manifest.ts +20 -74
- package/src/tools/types.ts +6 -0
- package/src/tools/ui-surface/definitions.ts +6 -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 +236 -2
- package/src/workspace/commit-message-enrichment-service.ts +284 -0
- package/src/workspace/commit-message-provider.ts +95 -0
- package/src/workspace/git-service.ts +272 -52
- package/src/workspace/heartbeat-service.ts +70 -13
- package/src/workspace/provider-commit-message-generator.ts +242 -0
- package/src/workspace/turn-commit.ts +100 -51
- 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
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Watcher"
|
|
3
|
+
description: "Polling watcher system for monitoring external sources"
|
|
4
|
+
metadata: {"vellum": {"emoji": "👀"}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Create and manage watchers that poll external services for events and process them with an action prompt.
|
|
8
|
+
|
|
9
|
+
## Concepts
|
|
10
|
+
|
|
11
|
+
- **Provider** — The external service to poll (e.g. "gmail"). Each provider defines how to fetch and parse events.
|
|
12
|
+
- **Action prompt** — LLM instructions for handling detected events. Sent along with event data to a background conversation.
|
|
13
|
+
- **Poll interval** — How often to check for new events (minimum 15 seconds, default 60 seconds).
|
|
14
|
+
- **Digest** — Summary of recent watcher activity, grouped by watcher with time-based filtering.
|
|
15
|
+
|
|
16
|
+
## Lifecycle
|
|
17
|
+
|
|
18
|
+
1. Create a watcher with a name, provider, and action prompt.
|
|
19
|
+
2. The system polls the provider at the configured interval.
|
|
20
|
+
3. Detected events are processed according to the action prompt.
|
|
21
|
+
4. Use `watcher_digest` to review recent activity.
|
|
22
|
+
|
|
23
|
+
## Usage Notes
|
|
24
|
+
|
|
25
|
+
- Use `watcher_create` when the user wants to monitor an external source (e.g. "watch my Gmail for important emails").
|
|
26
|
+
- `watcher_digest` is the go-to tool when the user asks "what happened with my email?" or similar questions about watcher activity.
|
|
27
|
+
- Watchers can be enabled/disabled via `watcher_update` without deleting them.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"tools": [
|
|
4
|
+
{
|
|
5
|
+
"name": "watcher_create",
|
|
6
|
+
"description": "Create a new watcher that polls an external service for events and processes them with an action prompt",
|
|
7
|
+
"category": "watcher",
|
|
8
|
+
"risk": "medium",
|
|
9
|
+
"input_schema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "A human-readable name for this watcher (e.g. \"My Gmail\")"
|
|
15
|
+
},
|
|
16
|
+
"provider": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The provider to poll (e.g. \"gmail\")"
|
|
19
|
+
},
|
|
20
|
+
"action_prompt": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Instructions for the LLM on how to handle detected events. This prompt is sent along with event data to a background conversation."
|
|
23
|
+
},
|
|
24
|
+
"poll_interval_ms": {
|
|
25
|
+
"type": "number",
|
|
26
|
+
"description": "How often to poll in milliseconds. Defaults to 60000 (1 minute). Minimum 15000."
|
|
27
|
+
},
|
|
28
|
+
"credential_service": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "Override the credential service to use. Defaults to the provider's required service."
|
|
31
|
+
},
|
|
32
|
+
"config": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"description": "Provider-specific configuration (e.g. filter criteria)"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": ["name", "provider", "action_prompt"]
|
|
38
|
+
},
|
|
39
|
+
"executor": "tools/watcher-create.ts",
|
|
40
|
+
"execution_target": "host"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "watcher_list",
|
|
44
|
+
"description": "List all watchers with their status, or show details for a specific watcher",
|
|
45
|
+
"category": "watcher",
|
|
46
|
+
"risk": "low",
|
|
47
|
+
"input_schema": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {
|
|
50
|
+
"watcher_id": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "If provided, show detailed info for this specific watcher including recent events."
|
|
53
|
+
},
|
|
54
|
+
"enabled_only": {
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
"description": "When true, only show enabled watchers. Defaults to false."
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"required": []
|
|
60
|
+
},
|
|
61
|
+
"executor": "tools/watcher-list.ts",
|
|
62
|
+
"execution_target": "host"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "watcher_update",
|
|
66
|
+
"description": "Update a watcher's configuration (name, action prompt, interval, enabled state)",
|
|
67
|
+
"category": "watcher",
|
|
68
|
+
"risk": "medium",
|
|
69
|
+
"input_schema": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"properties": {
|
|
72
|
+
"watcher_id": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "The ID of the watcher to update"
|
|
75
|
+
},
|
|
76
|
+
"name": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "New name for the watcher"
|
|
79
|
+
},
|
|
80
|
+
"action_prompt": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"description": "New action prompt for event processing"
|
|
83
|
+
},
|
|
84
|
+
"poll_interval_ms": {
|
|
85
|
+
"type": "number",
|
|
86
|
+
"description": "New poll interval in milliseconds (minimum 15000)"
|
|
87
|
+
},
|
|
88
|
+
"enabled": {
|
|
89
|
+
"type": "boolean",
|
|
90
|
+
"description": "Enable or disable the watcher"
|
|
91
|
+
},
|
|
92
|
+
"config": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"description": "New provider-specific configuration"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"required": ["watcher_id"]
|
|
98
|
+
},
|
|
99
|
+
"executor": "tools/watcher-update.ts",
|
|
100
|
+
"execution_target": "host"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "watcher_delete",
|
|
104
|
+
"description": "Delete a watcher and all its event history",
|
|
105
|
+
"category": "watcher",
|
|
106
|
+
"risk": "medium",
|
|
107
|
+
"input_schema": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"properties": {
|
|
110
|
+
"watcher_id": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"description": "The ID of the watcher to delete"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"required": ["watcher_id"]
|
|
116
|
+
},
|
|
117
|
+
"executor": "tools/watcher-delete.ts",
|
|
118
|
+
"execution_target": "host"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "watcher_digest",
|
|
122
|
+
"description": "Get a summary of recent watcher activity. Use this when the user asks about what happened with their email, notifications, etc.",
|
|
123
|
+
"category": "watcher",
|
|
124
|
+
"risk": "low",
|
|
125
|
+
"input_schema": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"properties": {
|
|
128
|
+
"watcher_id": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "Filter to events from a specific watcher. If omitted, shows events from all watchers."
|
|
131
|
+
},
|
|
132
|
+
"hours": {
|
|
133
|
+
"type": "number",
|
|
134
|
+
"description": "How many hours back to look. Defaults to 24."
|
|
135
|
+
},
|
|
136
|
+
"limit": {
|
|
137
|
+
"type": "number",
|
|
138
|
+
"description": "Maximum number of events to return. Defaults to 50."
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"required": []
|
|
142
|
+
},
|
|
143
|
+
"executor": "tools/watcher-digest.ts",
|
|
144
|
+
"execution_target": "host"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
|
|
2
|
+
import { executeWatcherCreate } from '../../../../tools/watcher/create.js';
|
|
3
|
+
|
|
4
|
+
export async function run(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
return executeWatcherCreate(input, context);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
|
|
2
|
+
import { executeWatcherDelete } from '../../../../tools/watcher/delete.js';
|
|
3
|
+
|
|
4
|
+
export async function run(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
return executeWatcherDelete(input, context);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
|
|
2
|
+
import { executeWatcherDigest } from '../../../../tools/watcher/digest.js';
|
|
3
|
+
|
|
4
|
+
export async function run(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
return executeWatcherDigest(input, context);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
|
|
2
|
+
import { executeWatcherList } from '../../../../tools/watcher/list.js';
|
|
3
|
+
|
|
4
|
+
export async function run(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
return executeWatcherList(input, context);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
|
|
2
|
+
import { executeWatcherUpdate } from '../../../../tools/watcher/update.js';
|
|
3
|
+
|
|
4
|
+
export async function run(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
return executeWatcherUpdate(input, context);
|
|
9
|
+
}
|
package/src/config/defaults.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AssistantConfig } from './types.js';
|
|
|
4
4
|
export const DEFAULT_CONFIG: AssistantConfig = {
|
|
5
5
|
provider: 'anthropic',
|
|
6
6
|
model: 'claude-opus-4-6', // alias: claude-opus-4
|
|
7
|
+
imageGenModel: 'gemini-2.5-flash-image',
|
|
7
8
|
apiKeys: {},
|
|
8
9
|
webSearchProvider: 'perplexity',
|
|
9
10
|
providerOrder: [],
|
|
@@ -168,6 +169,10 @@ export const DEFAULT_CONFIG: AssistantConfig = {
|
|
|
168
169
|
retentionDays: 30,
|
|
169
170
|
},
|
|
170
171
|
pricingOverrides: [],
|
|
172
|
+
agentHeartbeat: {
|
|
173
|
+
enabled: false,
|
|
174
|
+
intervalMs: 3_600_000,
|
|
175
|
+
},
|
|
171
176
|
swarm: {
|
|
172
177
|
enabled: true,
|
|
173
178
|
maxWorkers: 3,
|
|
@@ -183,4 +188,43 @@ export const DEFAULT_CONFIG: AssistantConfig = {
|
|
|
183
188
|
install: { nodeManager: 'npm' },
|
|
184
189
|
allowBundled: null,
|
|
185
190
|
},
|
|
191
|
+
workspaceGit: {
|
|
192
|
+
turnCommitMaxWaitMs: 4000,
|
|
193
|
+
failureBackoffBaseMs: 2000,
|
|
194
|
+
failureBackoffMaxMs: 60000,
|
|
195
|
+
interactiveGitTimeoutMs: 10000,
|
|
196
|
+
enrichmentQueueSize: 50,
|
|
197
|
+
enrichmentConcurrency: 1,
|
|
198
|
+
enrichmentJobTimeoutMs: 30000,
|
|
199
|
+
enrichmentMaxRetries: 2,
|
|
200
|
+
commitMessageLLM: {
|
|
201
|
+
enabled: false,
|
|
202
|
+
useConfiguredProvider: true,
|
|
203
|
+
providerFastModelOverrides: {},
|
|
204
|
+
timeoutMs: 600,
|
|
205
|
+
maxTokens: 120,
|
|
206
|
+
temperature: 0.2,
|
|
207
|
+
maxFilesInPrompt: 30,
|
|
208
|
+
maxDiffBytes: 12000,
|
|
209
|
+
minRemainingTurnBudgetMs: 1000,
|
|
210
|
+
breaker: {
|
|
211
|
+
openAfterFailures: 3,
|
|
212
|
+
backoffBaseMs: 2000,
|
|
213
|
+
backoffMaxMs: 60000,
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
calls: {
|
|
218
|
+
enabled: true,
|
|
219
|
+
provider: 'twilio' as const,
|
|
220
|
+
maxDurationSeconds: 3600,
|
|
221
|
+
userConsultTimeoutSeconds: 120,
|
|
222
|
+
disclosure: {
|
|
223
|
+
enabled: true,
|
|
224
|
+
text: 'At the very beginning of the call, disclose that you are an AI assistant calling on behalf of the user.',
|
|
225
|
+
},
|
|
226
|
+
safety: {
|
|
227
|
+
denyCategories: [],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
186
230
|
};
|
package/src/config/loader.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { AssistantConfig } from './types.js';
|
|
|
10
10
|
const log = getLogger('config');
|
|
11
11
|
|
|
12
12
|
// Providers that store API keys in secure storage (superset of VALID_PROVIDERS)
|
|
13
|
-
export const API_KEY_PROVIDERS = ['anthropic', 'openai', 'gemini', 'ollama', 'fireworks', 'brave', 'perplexity'] as const;
|
|
13
|
+
export const API_KEY_PROVIDERS = ['anthropic', 'openai', 'gemini', 'ollama', 'fireworks', 'openrouter', 'brave', 'perplexity'] as const;
|
|
14
14
|
|
|
15
15
|
let cached: AssistantConfig | null = null;
|
|
16
16
|
let loading = false;
|
|
@@ -198,6 +198,9 @@ export function loadConfig(): AssistantConfig {
|
|
|
198
198
|
if (process.env.FIREWORKS_API_KEY) {
|
|
199
199
|
config.apiKeys.fireworks = process.env.FIREWORKS_API_KEY;
|
|
200
200
|
}
|
|
201
|
+
if (process.env.OPENROUTER_API_KEY) {
|
|
202
|
+
config.apiKeys.openrouter = process.env.OPENROUTER_API_KEY;
|
|
203
|
+
}
|
|
201
204
|
if (process.env.BRAVE_API_KEY) {
|
|
202
205
|
config.apiKeys.brave = process.env.BRAVE_API_KEY;
|
|
203
206
|
}
|
package/src/config/schema.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { getDataDir } from '../util/platform.js';
|
|
3
3
|
|
|
4
|
-
const VALID_PROVIDERS = ['anthropic', 'openai', 'gemini', 'ollama', 'fireworks'] as const;
|
|
4
|
+
const VALID_PROVIDERS = ['anthropic', 'openai', 'gemini', 'ollama', 'fireworks', 'openrouter'] as const;
|
|
5
5
|
const VALID_WEB_SEARCH_PROVIDERS = ['perplexity', 'brave', 'anthropic-native'] as const;
|
|
6
6
|
const VALID_SECRET_ACTIONS = ['redact', 'warn', 'block', 'prompt'] as const;
|
|
7
7
|
const VALID_MEMORY_EMBEDDING_PROVIDERS = ['auto', 'local', 'openai', 'gemini', 'ollama'] as const;
|
|
8
8
|
const VALID_SANDBOX_BACKENDS = ['native', 'docker'] as const;
|
|
9
9
|
const VALID_DOCKER_NETWORKS = ['none', 'bridge'] as const;
|
|
10
10
|
const VALID_PERMISSIONS_MODES = ['legacy', 'strict'] as const;
|
|
11
|
+
const VALID_CALL_PROVIDERS = ['twilio'] as const;
|
|
11
12
|
|
|
12
13
|
export const TimeoutConfigSchema = z.object({
|
|
13
14
|
shellMaxTimeoutSec: z
|
|
@@ -703,6 +704,126 @@ export const SkillsInstallConfigSchema = z.object({
|
|
|
703
704
|
}).default('npm'),
|
|
704
705
|
});
|
|
705
706
|
|
|
707
|
+
export const WorkspaceGitConfigSchema = z.object({
|
|
708
|
+
turnCommitMaxWaitMs: z
|
|
709
|
+
.number({ error: 'workspaceGit.turnCommitMaxWaitMs must be a number' })
|
|
710
|
+
.int('workspaceGit.turnCommitMaxWaitMs must be an integer')
|
|
711
|
+
.positive('workspaceGit.turnCommitMaxWaitMs must be a positive integer')
|
|
712
|
+
.default(4000),
|
|
713
|
+
failureBackoffBaseMs: z
|
|
714
|
+
.number({ error: 'workspaceGit.failureBackoffBaseMs must be a number' })
|
|
715
|
+
.int('workspaceGit.failureBackoffBaseMs must be an integer')
|
|
716
|
+
.positive('workspaceGit.failureBackoffBaseMs must be a positive integer')
|
|
717
|
+
.default(2000),
|
|
718
|
+
failureBackoffMaxMs: z
|
|
719
|
+
.number({ error: 'workspaceGit.failureBackoffMaxMs must be a number' })
|
|
720
|
+
.int('workspaceGit.failureBackoffMaxMs must be an integer')
|
|
721
|
+
.positive('workspaceGit.failureBackoffMaxMs must be a positive integer')
|
|
722
|
+
.default(60000),
|
|
723
|
+
interactiveGitTimeoutMs: z
|
|
724
|
+
.number({ error: 'workspaceGit.interactiveGitTimeoutMs must be a number' })
|
|
725
|
+
.int('workspaceGit.interactiveGitTimeoutMs must be an integer')
|
|
726
|
+
.positive('workspaceGit.interactiveGitTimeoutMs must be a positive integer')
|
|
727
|
+
.default(10000),
|
|
728
|
+
enrichmentQueueSize: z
|
|
729
|
+
.number({ error: 'workspaceGit.enrichmentQueueSize must be a number' })
|
|
730
|
+
.int('workspaceGit.enrichmentQueueSize must be an integer')
|
|
731
|
+
.positive('workspaceGit.enrichmentQueueSize must be a positive integer')
|
|
732
|
+
.default(50),
|
|
733
|
+
enrichmentConcurrency: z
|
|
734
|
+
.number({ error: 'workspaceGit.enrichmentConcurrency must be a number' })
|
|
735
|
+
.int('workspaceGit.enrichmentConcurrency must be an integer')
|
|
736
|
+
.positive('workspaceGit.enrichmentConcurrency must be a positive integer')
|
|
737
|
+
.default(1),
|
|
738
|
+
enrichmentJobTimeoutMs: z
|
|
739
|
+
.number({ error: 'workspaceGit.enrichmentJobTimeoutMs must be a number' })
|
|
740
|
+
.int('workspaceGit.enrichmentJobTimeoutMs must be an integer')
|
|
741
|
+
.positive('workspaceGit.enrichmentJobTimeoutMs must be a positive integer')
|
|
742
|
+
.default(30000),
|
|
743
|
+
enrichmentMaxRetries: z
|
|
744
|
+
.number({ error: 'workspaceGit.enrichmentMaxRetries must be a number' })
|
|
745
|
+
.int('workspaceGit.enrichmentMaxRetries must be an integer')
|
|
746
|
+
.nonnegative('workspaceGit.enrichmentMaxRetries must be non-negative')
|
|
747
|
+
.default(2),
|
|
748
|
+
commitMessageLLM: z.object({
|
|
749
|
+
enabled: z.boolean({ error: 'workspaceGit.commitMessageLLM.enabled must be a boolean' }).default(false),
|
|
750
|
+
useConfiguredProvider: z.boolean({ error: 'workspaceGit.commitMessageLLM.useConfiguredProvider must be a boolean' }).default(true),
|
|
751
|
+
providerFastModelOverrides: z.record(z.string(), z.string()).default({}),
|
|
752
|
+
timeoutMs: z.number({ error: 'workspaceGit.commitMessageLLM.timeoutMs must be a number' })
|
|
753
|
+
.int('workspaceGit.commitMessageLLM.timeoutMs must be an integer')
|
|
754
|
+
.positive('workspaceGit.commitMessageLLM.timeoutMs must be a positive integer')
|
|
755
|
+
.default(600),
|
|
756
|
+
maxTokens: z.number({ error: 'workspaceGit.commitMessageLLM.maxTokens must be a number' })
|
|
757
|
+
.int('workspaceGit.commitMessageLLM.maxTokens must be an integer')
|
|
758
|
+
.positive('workspaceGit.commitMessageLLM.maxTokens must be a positive integer')
|
|
759
|
+
.default(120),
|
|
760
|
+
temperature: z.number({ error: 'workspaceGit.commitMessageLLM.temperature must be a number' })
|
|
761
|
+
.min(0, 'workspaceGit.commitMessageLLM.temperature must be >= 0')
|
|
762
|
+
.max(2, 'workspaceGit.commitMessageLLM.temperature must be <= 2')
|
|
763
|
+
.default(0.2),
|
|
764
|
+
maxFilesInPrompt: z.number({ error: 'workspaceGit.commitMessageLLM.maxFilesInPrompt must be a number' })
|
|
765
|
+
.int('workspaceGit.commitMessageLLM.maxFilesInPrompt must be an integer')
|
|
766
|
+
.positive('workspaceGit.commitMessageLLM.maxFilesInPrompt must be a positive integer')
|
|
767
|
+
.default(30),
|
|
768
|
+
maxDiffBytes: z.number({ error: 'workspaceGit.commitMessageLLM.maxDiffBytes must be a number' })
|
|
769
|
+
.int('workspaceGit.commitMessageLLM.maxDiffBytes must be an integer')
|
|
770
|
+
.positive('workspaceGit.commitMessageLLM.maxDiffBytes must be a positive integer')
|
|
771
|
+
.default(12000),
|
|
772
|
+
minRemainingTurnBudgetMs: z.number({ error: 'workspaceGit.commitMessageLLM.minRemainingTurnBudgetMs must be a number' })
|
|
773
|
+
.int('workspaceGit.commitMessageLLM.minRemainingTurnBudgetMs must be an integer')
|
|
774
|
+
.nonnegative('workspaceGit.commitMessageLLM.minRemainingTurnBudgetMs must be non-negative')
|
|
775
|
+
.default(1000),
|
|
776
|
+
breaker: z.object({
|
|
777
|
+
openAfterFailures: z.number({ error: 'workspaceGit.commitMessageLLM.breaker.openAfterFailures must be a number' })
|
|
778
|
+
.int().positive().default(3),
|
|
779
|
+
backoffBaseMs: z.number({ error: 'workspaceGit.commitMessageLLM.breaker.backoffBaseMs must be a number' })
|
|
780
|
+
.int().positive().default(2000),
|
|
781
|
+
backoffMaxMs: z.number({ error: 'workspaceGit.commitMessageLLM.breaker.backoffMaxMs must be a number' })
|
|
782
|
+
.int().positive().default(60000),
|
|
783
|
+
}).default({}),
|
|
784
|
+
}).default({}),
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
export const AgentHeartbeatConfigSchema = z.object({
|
|
788
|
+
enabled: z
|
|
789
|
+
.boolean({ error: 'agentHeartbeat.enabled must be a boolean' })
|
|
790
|
+
.default(false),
|
|
791
|
+
intervalMs: z
|
|
792
|
+
.number({ error: 'agentHeartbeat.intervalMs must be a number' })
|
|
793
|
+
.int('agentHeartbeat.intervalMs must be an integer')
|
|
794
|
+
.positive('agentHeartbeat.intervalMs must be a positive integer')
|
|
795
|
+
.default(3_600_000),
|
|
796
|
+
activeHoursStart: z
|
|
797
|
+
.number({ error: 'agentHeartbeat.activeHoursStart must be a number' })
|
|
798
|
+
.int('agentHeartbeat.activeHoursStart must be an integer')
|
|
799
|
+
.min(0, 'agentHeartbeat.activeHoursStart must be >= 0')
|
|
800
|
+
.max(23, 'agentHeartbeat.activeHoursStart must be <= 23')
|
|
801
|
+
.optional(),
|
|
802
|
+
activeHoursEnd: z
|
|
803
|
+
.number({ error: 'agentHeartbeat.activeHoursEnd must be a number' })
|
|
804
|
+
.int('agentHeartbeat.activeHoursEnd must be an integer')
|
|
805
|
+
.min(0, 'agentHeartbeat.activeHoursEnd must be >= 0')
|
|
806
|
+
.max(23, 'agentHeartbeat.activeHoursEnd must be <= 23')
|
|
807
|
+
.optional(),
|
|
808
|
+
}).superRefine((config, ctx) => {
|
|
809
|
+
const hasStart = config.activeHoursStart != null;
|
|
810
|
+
const hasEnd = config.activeHoursEnd != null;
|
|
811
|
+
if (hasStart !== hasEnd) {
|
|
812
|
+
ctx.addIssue({
|
|
813
|
+
code: z.ZodIssueCode.custom,
|
|
814
|
+
path: [hasStart ? 'activeHoursEnd' : 'activeHoursStart'],
|
|
815
|
+
message: 'agentHeartbeat.activeHoursStart and agentHeartbeat.activeHoursEnd must both be set or both be omitted',
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
if (hasStart && hasEnd && config.activeHoursStart === config.activeHoursEnd) {
|
|
819
|
+
ctx.addIssue({
|
|
820
|
+
code: z.ZodIssueCode.custom,
|
|
821
|
+
path: ['activeHoursEnd'],
|
|
822
|
+
message: 'agentHeartbeat.activeHoursStart and agentHeartbeat.activeHoursEnd must not be equal (would create an empty window)',
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
706
827
|
export const SwarmConfigSchema = z.object({
|
|
707
828
|
enabled: z
|
|
708
829
|
.boolean({ error: 'swarm.enabled must be a boolean' })
|
|
@@ -738,6 +859,51 @@ export const SwarmConfigSchema = z.object({
|
|
|
738
859
|
.default('claude-sonnet-4-6'),
|
|
739
860
|
});
|
|
740
861
|
|
|
862
|
+
export const CallsDisclosureConfigSchema = z.object({
|
|
863
|
+
enabled: z
|
|
864
|
+
.boolean({ error: 'calls.disclosure.enabled must be a boolean' })
|
|
865
|
+
.default(true),
|
|
866
|
+
text: z
|
|
867
|
+
.string({ error: 'calls.disclosure.text must be a string' })
|
|
868
|
+
.default('At the very beginning of the call, disclose that you are an AI assistant calling on behalf of the user.'),
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
export const CallsSafetyConfigSchema = z.object({
|
|
872
|
+
denyCategories: z
|
|
873
|
+
.array(z.string({ error: 'calls.safety.denyCategories values must be strings' }))
|
|
874
|
+
.default([]),
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
export const CallsConfigSchema = z.object({
|
|
878
|
+
enabled: z
|
|
879
|
+
.boolean({ error: 'calls.enabled must be a boolean' })
|
|
880
|
+
.default(true),
|
|
881
|
+
provider: z
|
|
882
|
+
.enum(VALID_CALL_PROVIDERS, {
|
|
883
|
+
error: `calls.provider must be one of: ${VALID_CALL_PROVIDERS.join(', ')}`,
|
|
884
|
+
})
|
|
885
|
+
.default('twilio'),
|
|
886
|
+
maxDurationSeconds: z
|
|
887
|
+
.number({ error: 'calls.maxDurationSeconds must be a number' })
|
|
888
|
+
.int('calls.maxDurationSeconds must be an integer')
|
|
889
|
+
.positive('calls.maxDurationSeconds must be a positive integer')
|
|
890
|
+
.max(2_147_483, 'calls.maxDurationSeconds must be at most 2147483 (setTimeout-safe limit)')
|
|
891
|
+
.default(3600),
|
|
892
|
+
userConsultTimeoutSeconds: z
|
|
893
|
+
.number({ error: 'calls.userConsultTimeoutSeconds must be a number' })
|
|
894
|
+
.int('calls.userConsultTimeoutSeconds must be an integer')
|
|
895
|
+
.positive('calls.userConsultTimeoutSeconds must be a positive integer')
|
|
896
|
+
.max(2_147_483, 'calls.userConsultTimeoutSeconds must be at most 2147483 (setTimeout-safe limit)')
|
|
897
|
+
.default(120),
|
|
898
|
+
disclosure: CallsDisclosureConfigSchema.default({
|
|
899
|
+
enabled: true,
|
|
900
|
+
text: 'At the very beginning of the call, disclose that you are an AI assistant calling on behalf of the user.',
|
|
901
|
+
}),
|
|
902
|
+
safety: CallsSafetyConfigSchema.default({
|
|
903
|
+
denyCategories: [],
|
|
904
|
+
}),
|
|
905
|
+
});
|
|
906
|
+
|
|
741
907
|
export const SkillsConfigSchema = z.object({
|
|
742
908
|
entries: z.record(z.string(), SkillEntryConfigSchema).default({}),
|
|
743
909
|
load: SkillsLoadConfigSchema.default({ extraDirs: [], watch: true, watchDebounceMs: 250 }),
|
|
@@ -754,6 +920,9 @@ export const AssistantConfigSchema = z.object({
|
|
|
754
920
|
model: z
|
|
755
921
|
.string({ error: 'model must be a string' })
|
|
756
922
|
.default('claude-opus-4-6'),
|
|
923
|
+
imageGenModel: z
|
|
924
|
+
.string({ error: 'imageGenModel must be a string' })
|
|
925
|
+
.default('gemini-2.5-flash-image'),
|
|
757
926
|
apiKeys: z
|
|
758
927
|
.record(z.string(), z.string({ error: 'Each apiKeys value must be a string' }))
|
|
759
928
|
.default({}),
|
|
@@ -932,6 +1101,10 @@ export const AssistantConfigSchema = z.object({
|
|
|
932
1101
|
pricingOverrides: z
|
|
933
1102
|
.array(ModelPricingOverrideSchema)
|
|
934
1103
|
.default([]),
|
|
1104
|
+
agentHeartbeat: AgentHeartbeatConfigSchema.default({
|
|
1105
|
+
enabled: false,
|
|
1106
|
+
intervalMs: 3_600_000,
|
|
1107
|
+
}),
|
|
935
1108
|
swarm: SwarmConfigSchema.default({
|
|
936
1109
|
enabled: true,
|
|
937
1110
|
maxWorkers: 3,
|
|
@@ -947,6 +1120,45 @@ export const AssistantConfigSchema = z.object({
|
|
|
947
1120
|
install: { nodeManager: 'npm' },
|
|
948
1121
|
allowBundled: null,
|
|
949
1122
|
}),
|
|
1123
|
+
workspaceGit: WorkspaceGitConfigSchema.default({
|
|
1124
|
+
turnCommitMaxWaitMs: 4000,
|
|
1125
|
+
failureBackoffBaseMs: 2000,
|
|
1126
|
+
failureBackoffMaxMs: 60000,
|
|
1127
|
+
interactiveGitTimeoutMs: 10000,
|
|
1128
|
+
enrichmentQueueSize: 50,
|
|
1129
|
+
enrichmentConcurrency: 1,
|
|
1130
|
+
enrichmentJobTimeoutMs: 30000,
|
|
1131
|
+
enrichmentMaxRetries: 2,
|
|
1132
|
+
commitMessageLLM: {
|
|
1133
|
+
enabled: false,
|
|
1134
|
+
useConfiguredProvider: true,
|
|
1135
|
+
providerFastModelOverrides: {},
|
|
1136
|
+
timeoutMs: 600,
|
|
1137
|
+
maxTokens: 120,
|
|
1138
|
+
temperature: 0.2,
|
|
1139
|
+
maxFilesInPrompt: 30,
|
|
1140
|
+
maxDiffBytes: 12000,
|
|
1141
|
+
minRemainingTurnBudgetMs: 1000,
|
|
1142
|
+
breaker: {
|
|
1143
|
+
openAfterFailures: 3,
|
|
1144
|
+
backoffBaseMs: 2000,
|
|
1145
|
+
backoffMaxMs: 60000,
|
|
1146
|
+
},
|
|
1147
|
+
},
|
|
1148
|
+
}),
|
|
1149
|
+
calls: CallsConfigSchema.default({
|
|
1150
|
+
enabled: true,
|
|
1151
|
+
provider: 'twilio',
|
|
1152
|
+
maxDurationSeconds: 3600,
|
|
1153
|
+
userConsultTimeoutSeconds: 120,
|
|
1154
|
+
disclosure: {
|
|
1155
|
+
enabled: true,
|
|
1156
|
+
text: 'At the very beginning of the call, disclose that you are an AI assistant calling on behalf of the user.',
|
|
1157
|
+
},
|
|
1158
|
+
safety: {
|
|
1159
|
+
denyCategories: [],
|
|
1160
|
+
},
|
|
1161
|
+
}),
|
|
950
1162
|
}).superRefine((config, ctx) => {
|
|
951
1163
|
if (config.contextWindow.targetInputTokens >= config.contextWindow.maxInputTokens) {
|
|
952
1164
|
ctx.addIssue({
|
|
@@ -1000,5 +1212,10 @@ export type ModelPricingOverride = z.infer<typeof ModelPricingOverrideSchema>;
|
|
|
1000
1212
|
export type SkillEntryConfig = z.infer<typeof SkillEntryConfigSchema>;
|
|
1001
1213
|
export type SkillsLoadConfig = z.infer<typeof SkillsLoadConfigSchema>;
|
|
1002
1214
|
export type SkillsInstallConfig = z.infer<typeof SkillsInstallConfigSchema>;
|
|
1215
|
+
export type AgentHeartbeatConfig = z.infer<typeof AgentHeartbeatConfigSchema>;
|
|
1003
1216
|
export type SwarmConfig = z.infer<typeof SwarmConfigSchema>;
|
|
1004
1217
|
export type SkillsConfig = z.infer<typeof SkillsConfigSchema>;
|
|
1218
|
+
export type WorkspaceGitConfig = z.infer<typeof WorkspaceGitConfigSchema>;
|
|
1219
|
+
export type CallsConfig = z.infer<typeof CallsConfigSchema>;
|
|
1220
|
+
export type CallsDisclosureConfig = z.infer<typeof CallsDisclosureConfigSchema>;
|
|
1221
|
+
export type CallsSafetyConfig = z.infer<typeof CallsSafetyConfigSchema>;
|