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
|
@@ -15,12 +15,30 @@ import { getLogger } from '../util/logger.js';
|
|
|
15
15
|
import { NetworkRecorder } from '../tools/browser/network-recorder.js';
|
|
16
16
|
import { saveRecording } from '../tools/browser/recording-store.js';
|
|
17
17
|
import type { SessionRecording } from '../tools/browser/network-recording-types.js';
|
|
18
|
+
import { navigateXPages } from '../tools/browser/x-auto-navigate.js';
|
|
19
|
+
import { autoNavigate } from '../tools/browser/auto-navigate.js';
|
|
18
20
|
|
|
19
21
|
const log = getLogger('ride-shotgun-handler');
|
|
20
22
|
|
|
21
23
|
/** Active network recorders keyed by watchId. */
|
|
22
24
|
const activeRecorders = new Map<string, NetworkRecorder>();
|
|
23
25
|
|
|
26
|
+
/** Return domain-specific URL patterns that indicate a successful login. */
|
|
27
|
+
function getLoginSignals(targetDomain?: string): string[] {
|
|
28
|
+
if (targetDomain === 'x.com' || targetDomain === 'twitter.com') {
|
|
29
|
+
return [
|
|
30
|
+
'/i/api/graphql/', // any authenticated GraphQL call
|
|
31
|
+
'/1.1/account/settings', // legacy API session check
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
// DoorDash and general fallback
|
|
35
|
+
return [
|
|
36
|
+
'/graphql/postLoginQuery',
|
|
37
|
+
'/graphql/homePageFacetFeed',
|
|
38
|
+
'/graphql/getConsumerOrdersWithDetails',
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
|
|
24
42
|
/**
|
|
25
43
|
* Complete a session — finalize recording (if learn mode), generate summary, fire notifier.
|
|
26
44
|
* Shared by both the duration timeout and the early-stop handler.
|
|
@@ -106,11 +124,7 @@ export async function handleRideShotgunStart(
|
|
|
106
124
|
}
|
|
107
125
|
try {
|
|
108
126
|
const recorder = new NetworkRecorder(targetDomain);
|
|
109
|
-
recorder.loginSignals =
|
|
110
|
-
'/graphql/postLoginQuery',
|
|
111
|
-
'/graphql/homePageFacetFeed',
|
|
112
|
-
'/graphql/getConsumerOrdersWithDetails',
|
|
113
|
-
];
|
|
127
|
+
recorder.loginSignals = getLoginSignals(targetDomain);
|
|
114
128
|
await recorder.startDirect();
|
|
115
129
|
// If session completed while we were connecting, stop immediately to avoid leak
|
|
116
130
|
if (session.status !== 'active') {
|
|
@@ -118,13 +132,63 @@ export async function handleRideShotgunStart(
|
|
|
118
132
|
await recorder.stop();
|
|
119
133
|
return;
|
|
120
134
|
}
|
|
121
|
-
// Auto-stop when login is detected
|
|
122
|
-
recorder.onLoginDetected = () => {
|
|
123
|
-
log.info({ watchId }, 'Login detected — auto-stopping learn session');
|
|
124
|
-
completeSession(session);
|
|
125
|
-
};
|
|
126
135
|
activeRecorders.set(watchId, recorder);
|
|
127
136
|
log.info({ watchId, targetDomain, attempt }, 'Network recording started for learn session');
|
|
137
|
+
|
|
138
|
+
// For x.com, auto-navigate Chrome through key pages to capture the full API surface.
|
|
139
|
+
// Skip login detection — auto-navigation will complete the session when done.
|
|
140
|
+
if (targetDomain === 'x.com' || targetDomain === 'twitter.com') {
|
|
141
|
+
// Don't set onLoginDetected — it would kill the session after the first
|
|
142
|
+
// GraphQL call (5s grace), before auto-navigation finishes.
|
|
143
|
+
const abortSignal = { aborted: false };
|
|
144
|
+
const checkInterval = setInterval(() => {
|
|
145
|
+
if (session.status !== 'active') {
|
|
146
|
+
abortSignal.aborted = true;
|
|
147
|
+
clearInterval(checkInterval);
|
|
148
|
+
}
|
|
149
|
+
}, 1000);
|
|
150
|
+
navigateXPages(abortSignal).then(completed => {
|
|
151
|
+
clearInterval(checkInterval);
|
|
152
|
+
log.info({ watchId, completedSteps: completed.length }, 'X auto-navigation finished');
|
|
153
|
+
if (session.status === 'active') {
|
|
154
|
+
completeSession(session);
|
|
155
|
+
}
|
|
156
|
+
}).catch(err => {
|
|
157
|
+
clearInterval(checkInterval);
|
|
158
|
+
log.warn({ err, watchId }, 'X auto-navigation failed');
|
|
159
|
+
if (session.status === 'active') {
|
|
160
|
+
completeSession(session);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
} else if (msg.autoNavigate && targetDomain) {
|
|
164
|
+
const abortSignal = { aborted: false };
|
|
165
|
+
const checkInterval = setInterval(() => {
|
|
166
|
+
if (session.status !== 'active') {
|
|
167
|
+
abortSignal.aborted = true;
|
|
168
|
+
clearInterval(checkInterval);
|
|
169
|
+
}
|
|
170
|
+
}, 1000);
|
|
171
|
+
autoNavigate(targetDomain, abortSignal).then(visited => {
|
|
172
|
+
clearInterval(checkInterval);
|
|
173
|
+
log.info({ watchId, visitedPages: visited.length }, 'Generic auto-navigation finished');
|
|
174
|
+
if (session.status === 'active') {
|
|
175
|
+
completeSession(session);
|
|
176
|
+
}
|
|
177
|
+
}).catch(err => {
|
|
178
|
+
clearInterval(checkInterval);
|
|
179
|
+
log.warn({ err, watchId }, 'Generic auto-navigation failed');
|
|
180
|
+
if (session.status === 'active') {
|
|
181
|
+
completeSession(session);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
} else {
|
|
185
|
+
// No targetDomain: use login detection as before
|
|
186
|
+
recorder.onLoginDetected = () => {
|
|
187
|
+
log.info({ watchId }, 'Login detected — auto-stopping learn session');
|
|
188
|
+
completeSession(session);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
128
192
|
return;
|
|
129
193
|
} catch (err) {
|
|
130
194
|
if (attempt < 9) {
|
package/src/daemon/server.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as net from 'node:net';
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
|
-
import { existsSync, chmodSync, writeFileSync, unlinkSync, readdirSync, watch, type FSWatcher } from 'node:fs';
|
|
3
|
+
import { existsSync, chmodSync, readFileSync, writeFileSync, unlinkSync, readdirSync, watch, type FSWatcher } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { getSocketPath, getSessionTokenPath, getRootDir, getWorkspaceDir, getWorkspaceSkillsDir, getSandboxWorkingDir, removeSocketFile, getTCPPort, getTCPHost, isTCPEnabled } from '../util/platform.js';
|
|
6
6
|
import { hasNoAuthOverride } from './connection-policy.js';
|
|
@@ -10,7 +10,7 @@ import { RateLimitProvider } from '../providers/ratelimit.js';
|
|
|
10
10
|
import { getConfig, invalidateConfigCache } from '../config/loader.js';
|
|
11
11
|
import { buildSystemPrompt } from '../config/system-prompt.js';
|
|
12
12
|
import { clearCache as clearTrustCache } from '../permissions/trust-store.js';
|
|
13
|
-
import { resetAllowlist } from '../security/secret-allowlist.js';
|
|
13
|
+
import { resetAllowlist, validateAllowlistFile } from '../security/secret-allowlist.js';
|
|
14
14
|
import { checkIngressForSecrets } from '../security/secret-ingress.js';
|
|
15
15
|
import { IngressBlockedError } from '../util/errors.js';
|
|
16
16
|
import { clearEmbeddingBackendCache } from '../memory/embedding-backend.js';
|
|
@@ -36,9 +36,24 @@ import { assistantEventHub } from '../runtime/assistant-event-hub.js';
|
|
|
36
36
|
import { buildAssistantEvent } from '../runtime/assistant-event.js';
|
|
37
37
|
import { SessionEvictor } from './session-evictor.js';
|
|
38
38
|
import { getSubagentManager } from '../subagent/index.js';
|
|
39
|
+
import { tryHandlePendingCallAnswer } from '../calls/call-bridge.js';
|
|
40
|
+
import { resolveSlash } from './session-slash.js';
|
|
41
|
+
import { createUserMessage, createAssistantMessage } from '../agent/message-types.js';
|
|
39
42
|
|
|
40
43
|
const log = getLogger('server');
|
|
41
44
|
|
|
45
|
+
function readPackageVersion(): string | undefined {
|
|
46
|
+
try {
|
|
47
|
+
const pkgPath = join(import.meta.dir, '../../package.json');
|
|
48
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as { version?: string };
|
|
49
|
+
return pkg.version;
|
|
50
|
+
} catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const daemonVersion = readPackageVersion();
|
|
56
|
+
|
|
42
57
|
export class DaemonServer {
|
|
43
58
|
private server: net.Server | null = null;
|
|
44
59
|
private tcpServer: net.Server | null = null;
|
|
@@ -125,21 +140,23 @@ export class DaemonServer {
|
|
|
125
140
|
};
|
|
126
141
|
// When a subagent finishes, inject the result into the parent session
|
|
127
142
|
// so the LLM automatically informs the user.
|
|
128
|
-
getSubagentManager().onSubagentFinished = (parentSessionId, message, sendToClient) => {
|
|
143
|
+
getSubagentManager().onSubagentFinished = (parentSessionId, message, sendToClient, notification) => {
|
|
129
144
|
const parentSession = this.sessions.get(parentSessionId);
|
|
130
145
|
if (!parentSession) {
|
|
131
146
|
log.warn({ parentSessionId }, 'Subagent finished but parent session not found');
|
|
132
147
|
return;
|
|
133
148
|
}
|
|
134
149
|
const requestId = `subagent-notify-${Date.now()}`;
|
|
135
|
-
|
|
150
|
+
// Store structured notification data in the DB for history reconstruction
|
|
151
|
+
const metadata = { subagentNotification: notification };
|
|
152
|
+
const enqueueResult = parentSession.enqueueMessage(message, [], sendToClient, requestId, undefined, undefined, metadata);
|
|
136
153
|
if (enqueueResult.rejected) {
|
|
137
154
|
log.warn({ parentSessionId }, 'Parent session queue full, dropping subagent notification');
|
|
138
155
|
return;
|
|
139
156
|
}
|
|
140
157
|
if (!enqueueResult.queued) {
|
|
141
158
|
// Parent is idle — send directly.
|
|
142
|
-
const messageId = parentSession.persistUserMessage(message, []);
|
|
159
|
+
const messageId = parentSession.persistUserMessage(message, [], undefined, metadata);
|
|
143
160
|
parentSession.runAgentLoop(message, messageId, sendToClient).catch((err) => {
|
|
144
161
|
log.error({ parentSessionId, err }, 'Failed to process subagent notification in parent');
|
|
145
162
|
});
|
|
@@ -330,6 +347,16 @@ export class DaemonServer {
|
|
|
330
347
|
},
|
|
331
348
|
'secret-allowlist.json': () => {
|
|
332
349
|
resetAllowlist();
|
|
350
|
+
try {
|
|
351
|
+
const errors = validateAllowlistFile();
|
|
352
|
+
if (errors && errors.length > 0) {
|
|
353
|
+
for (const e of errors) {
|
|
354
|
+
log.warn({ index: e.index, pattern: e.pattern }, `Invalid regex in secret-allowlist.json: ${e.message}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} catch (err) {
|
|
358
|
+
log.warn({ err }, 'Failed to validate secret-allowlist.json');
|
|
359
|
+
}
|
|
333
360
|
},
|
|
334
361
|
};
|
|
335
362
|
|
|
@@ -381,6 +408,7 @@ export class DaemonServer {
|
|
|
381
408
|
this.broadcast({
|
|
382
409
|
type: 'daemon_status',
|
|
383
410
|
httpPort: port,
|
|
411
|
+
version: daemonVersion,
|
|
384
412
|
});
|
|
385
413
|
}
|
|
386
414
|
|
|
@@ -744,10 +772,7 @@ export class DaemonServer {
|
|
|
744
772
|
('sessionId' in msg && typeof msgRecord.sessionId === 'string'
|
|
745
773
|
? msgRecord.sessionId as string
|
|
746
774
|
: undefined) ?? this.socketToSession.get(socket);
|
|
747
|
-
|
|
748
|
-
const socketSession = sessionId ? this.sessions.get(sessionId) : undefined;
|
|
749
|
-
const assistantId = socketSession?.assistantId ?? this.assistantId;
|
|
750
|
-
this.publishAssistantEvent(msg, sessionId, assistantId);
|
|
775
|
+
this.publishAssistantEvent(msg, sessionId, this.assistantId);
|
|
751
776
|
}
|
|
752
777
|
|
|
753
778
|
broadcast(msg: ServerMessage, excludeSocket?: net.Socket): void {
|
|
@@ -763,10 +788,7 @@ export class DaemonServer {
|
|
|
763
788
|
('sessionId' in msg && typeof msgRecord.sessionId === 'string'
|
|
764
789
|
? msgRecord.sessionId as string
|
|
765
790
|
: undefined) ?? (excludeSocket ? this.socketToSession.get(excludeSocket) : undefined);
|
|
766
|
-
|
|
767
|
-
const originSession = sessionId ? this.sessions.get(sessionId) : undefined;
|
|
768
|
-
const assistantId = originSession?.assistantId ?? this.assistantId;
|
|
769
|
-
this.publishAssistantEvent(msg, sessionId, assistantId);
|
|
791
|
+
this.publishAssistantEvent(msg, sessionId, this.assistantId);
|
|
770
792
|
}
|
|
771
793
|
|
|
772
794
|
/**
|
|
@@ -797,6 +819,7 @@ export class DaemonServer {
|
|
|
797
819
|
this.send(socket, {
|
|
798
820
|
type: 'daemon_status',
|
|
799
821
|
httpPort: this.httpPort,
|
|
822
|
+
version: daemonVersion,
|
|
800
823
|
});
|
|
801
824
|
return;
|
|
802
825
|
}
|
|
@@ -815,6 +838,7 @@ export class DaemonServer {
|
|
|
815
838
|
this.send(socket, {
|
|
816
839
|
type: 'daemon_status',
|
|
817
840
|
httpPort: this.httpPort,
|
|
841
|
+
version: daemonVersion,
|
|
818
842
|
});
|
|
819
843
|
}
|
|
820
844
|
|
|
@@ -967,7 +991,6 @@ export class DaemonServer {
|
|
|
967
991
|
* is not blocked for the duration of the agent loop.
|
|
968
992
|
*/
|
|
969
993
|
async persistAndProcessMessage(
|
|
970
|
-
assistantId: string,
|
|
971
994
|
conversationId: string,
|
|
972
995
|
content: string,
|
|
973
996
|
attachmentIds?: string[],
|
|
@@ -988,14 +1011,11 @@ export class DaemonServer {
|
|
|
988
1011
|
throw new Error('Session is already processing a message');
|
|
989
1012
|
}
|
|
990
1013
|
|
|
991
|
-
// Set assistantId AFTER the isProcessing check so a rejected request
|
|
992
|
-
// doesn't mutate the session state visible to an in-flight request.
|
|
993
|
-
session.setAssistantId(assistantId);
|
|
994
1014
|
session.setChannelCapabilities(resolveChannelCapabilities(sourceChannel));
|
|
995
1015
|
|
|
996
1016
|
// Resolve attachment IDs to full attachment data for the session
|
|
997
1017
|
const attachments = attachmentIds
|
|
998
|
-
? attachmentsStore.getAttachmentsByIds(
|
|
1018
|
+
? attachmentsStore.getAttachmentsByIds(attachmentIds).map((a) => ({
|
|
999
1019
|
id: a.id,
|
|
1000
1020
|
filename: a.originalFilename,
|
|
1001
1021
|
mimeType: a.mimeType,
|
|
@@ -1003,10 +1023,32 @@ export class DaemonServer {
|
|
|
1003
1023
|
}))
|
|
1004
1024
|
: [];
|
|
1005
1025
|
|
|
1006
|
-
//
|
|
1026
|
+
// Persist the user message immediately after the isProcessing() guard.
|
|
1027
|
+
// This synchronously sets session.processing = true, closing the race
|
|
1028
|
+
// window that previously existed between the guard and the async bridge
|
|
1029
|
+
// check (two concurrent requests could both pass isProcessing() and
|
|
1030
|
+
// race into message handling).
|
|
1007
1031
|
const requestId = crypto.randomUUID();
|
|
1008
1032
|
const messageId = session.persistUserMessage(content, attachments, requestId);
|
|
1009
1033
|
|
|
1034
|
+
// Now that the processing lock is held, check the call-answer bridge.
|
|
1035
|
+
let bridgeHandled = false;
|
|
1036
|
+
try {
|
|
1037
|
+
const bridgeResult = await tryHandlePendingCallAnswer(conversationId, content, messageId);
|
|
1038
|
+
bridgeHandled = bridgeResult.handled;
|
|
1039
|
+
} catch (err) {
|
|
1040
|
+
log.warn({ err, conversationId }, 'Call-answer bridge check failed (non-fatal), proceeding with agent loop');
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
if (bridgeHandled) {
|
|
1044
|
+
// The message was consumed by the call system. Release the session.
|
|
1045
|
+
resetSessionProcessingState(session);
|
|
1046
|
+
// Drain any queued messages that arrived while processing was true.
|
|
1047
|
+
session.drainQueue('loop_complete');
|
|
1048
|
+
log.info({ conversationId, messageId }, 'User message consumed by call-answer bridge, skipping agent loop');
|
|
1049
|
+
return { messageId };
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1010
1052
|
// Fire-and-forget the agent loop. Errors are logged but do not
|
|
1011
1053
|
// affect the HTTP response (the client polls GET /messages).
|
|
1012
1054
|
session.runAgentLoop(content, messageId, () => {}).catch((err) => {
|
|
@@ -1022,7 +1064,6 @@ export class DaemonServer {
|
|
|
1022
1064
|
* Used by the channel inbound endpoint which needs the assistant reply.
|
|
1023
1065
|
*/
|
|
1024
1066
|
async processMessage(
|
|
1025
|
-
assistantId: string,
|
|
1026
1067
|
conversationId: string,
|
|
1027
1068
|
content: string,
|
|
1028
1069
|
attachmentIds?: string[],
|
|
@@ -1041,14 +1082,11 @@ export class DaemonServer {
|
|
|
1041
1082
|
throw new Error('Session is already processing a message');
|
|
1042
1083
|
}
|
|
1043
1084
|
|
|
1044
|
-
// Set assistantId AFTER the isProcessing check so a rejected request
|
|
1045
|
-
// doesn't mutate the session state visible to an in-flight request.
|
|
1046
|
-
session.setAssistantId(assistantId);
|
|
1047
1085
|
session.setChannelCapabilities(resolveChannelCapabilities(sourceChannel));
|
|
1048
1086
|
|
|
1049
1087
|
// Resolve attachment IDs to full attachment data for the session
|
|
1050
1088
|
const attachments = attachmentIds
|
|
1051
|
-
? attachmentsStore.getAttachmentsByIds(
|
|
1089
|
+
? attachmentsStore.getAttachmentsByIds(attachmentIds).map((a) => ({
|
|
1052
1090
|
id: a.id,
|
|
1053
1091
|
filename: a.originalFilename,
|
|
1054
1092
|
mimeType: a.mimeType,
|
|
@@ -1056,12 +1094,74 @@ export class DaemonServer {
|
|
|
1056
1094
|
}))
|
|
1057
1095
|
: [];
|
|
1058
1096
|
|
|
1059
|
-
|
|
1097
|
+
// Resolve slash commands before persistence (synchronous — no race window).
|
|
1098
|
+
const slashResult = resolveSlash(content);
|
|
1099
|
+
|
|
1100
|
+
// Unknown slash command — persist the exchange (user + assistant) and
|
|
1101
|
+
// return immediately. This path doesn't set processing=true since no
|
|
1102
|
+
// agent loop runs, so there is no race concern.
|
|
1103
|
+
if (slashResult.kind === 'unknown') {
|
|
1104
|
+
const userMsg = createUserMessage(content, attachments);
|
|
1105
|
+
const persisted = conversationStore.addMessage(
|
|
1106
|
+
conversationId,
|
|
1107
|
+
'user',
|
|
1108
|
+
JSON.stringify(userMsg.content),
|
|
1109
|
+
);
|
|
1110
|
+
session.getMessages().push(userMsg);
|
|
1111
|
+
|
|
1112
|
+
const assistantMsg = createAssistantMessage(slashResult.message);
|
|
1113
|
+
conversationStore.addMessage(
|
|
1114
|
+
conversationId,
|
|
1115
|
+
'assistant',
|
|
1116
|
+
JSON.stringify(assistantMsg.content),
|
|
1117
|
+
);
|
|
1118
|
+
session.getMessages().push(assistantMsg);
|
|
1119
|
+
return { messageId: persisted.id };
|
|
1120
|
+
}
|
|
1060
1121
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1122
|
+
const resolvedContent = slashResult.content;
|
|
1123
|
+
|
|
1124
|
+
// Preactivate skill tools when slash resolution identifies a known skill
|
|
1125
|
+
if (slashResult.kind === 'rewritten') {
|
|
1126
|
+
(session as unknown as { preactivatedSkillIds?: string[] }).preactivatedSkillIds = [slashResult.skillId];
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// Persist the user message immediately after the isProcessing() guard.
|
|
1130
|
+
// This synchronously sets session.processing = true, closing the race
|
|
1131
|
+
// window that previously existed between the guard and the async bridge
|
|
1132
|
+
// check.
|
|
1133
|
+
const requestId = crypto.randomUUID();
|
|
1134
|
+
let messageId: string;
|
|
1135
|
+
try {
|
|
1136
|
+
messageId = session.persistUserMessage(resolvedContent, attachments, requestId);
|
|
1137
|
+
} catch (err) {
|
|
1138
|
+
// runAgentLoop never ran, so its finally block won't clear this
|
|
1139
|
+
(session as unknown as { preactivatedSkillIds?: string[] }).preactivatedSkillIds = undefined;
|
|
1140
|
+
throw err;
|
|
1063
1141
|
}
|
|
1064
1142
|
|
|
1143
|
+
// Now that the processing lock is held, check the call-answer bridge.
|
|
1144
|
+
let bridgeHandled = false;
|
|
1145
|
+
try {
|
|
1146
|
+
const bridgeResult = await tryHandlePendingCallAnswer(conversationId, content, messageId);
|
|
1147
|
+
bridgeHandled = bridgeResult.handled;
|
|
1148
|
+
} catch (err) {
|
|
1149
|
+
log.warn({ err, conversationId }, 'Call-answer bridge check failed (non-fatal), proceeding with agent loop');
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
if (bridgeHandled) {
|
|
1153
|
+
// The message was consumed by the call system. Release the session.
|
|
1154
|
+
(session as unknown as { preactivatedSkillIds?: string[] }).preactivatedSkillIds = undefined;
|
|
1155
|
+
resetSessionProcessingState(session);
|
|
1156
|
+
// Drain any queued messages that arrived while processing was true.
|
|
1157
|
+
session.drainQueue('loop_complete');
|
|
1158
|
+
log.info({ conversationId, messageId }, 'User message consumed by call-answer bridge, skipping agent loop');
|
|
1159
|
+
return { messageId };
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// Run the agent loop (blocking — the channel inbound endpoint needs the reply).
|
|
1163
|
+
await session.runAgentLoop(resolvedContent, messageId, () => {});
|
|
1164
|
+
|
|
1065
1165
|
return { messageId };
|
|
1066
1166
|
}
|
|
1067
1167
|
|
|
@@ -1072,8 +1172,8 @@ export class DaemonServer {
|
|
|
1072
1172
|
return new RunOrchestrator({
|
|
1073
1173
|
getOrCreateSession: (conversationId) =>
|
|
1074
1174
|
this.getOrCreateSession(conversationId),
|
|
1075
|
-
resolveAttachments: (
|
|
1076
|
-
attachmentsStore.getAttachmentsByIds(
|
|
1175
|
+
resolveAttachments: (attachmentIds) =>
|
|
1176
|
+
attachmentsStore.getAttachmentsByIds(attachmentIds).map((a) => ({
|
|
1077
1177
|
id: a.id,
|
|
1078
1178
|
filename: a.originalFilename,
|
|
1079
1179
|
mimeType: a.mimeType,
|
|
@@ -1083,3 +1183,18 @@ export class DaemonServer {
|
|
|
1083
1183
|
}
|
|
1084
1184
|
|
|
1085
1185
|
}
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* Reset the processing state set by `persistUserMessage` when the agent loop
|
|
1189
|
+
* is intentionally skipped (e.g. call-answer bridge consumed the message).
|
|
1190
|
+
*/
|
|
1191
|
+
function resetSessionProcessingState(session: Session): void {
|
|
1192
|
+
const s = session as unknown as {
|
|
1193
|
+
processing: boolean;
|
|
1194
|
+
abortController: AbortController | null;
|
|
1195
|
+
currentRequestId: string | undefined;
|
|
1196
|
+
};
|
|
1197
|
+
s.processing = false;
|
|
1198
|
+
s.abortController = null;
|
|
1199
|
+
s.currentRequestId = undefined;
|
|
1200
|
+
}
|