@vellumai/assistant 0.11.4-staging.1 → 0.11.4-staging.3
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/AGENTS.md +8 -2
- package/ARCHITECTURE.md +2 -0
- package/docs/architecture/memory.md +15 -0
- package/docs/browser-use-architecture-phase2.md +128 -56
- package/docs/flux-turn-detection-spike.md +11 -6
- package/knip.json +3 -0
- package/openapi.yaml +135 -75
- package/package.json +1 -1
- package/scripts/write-plugin-api-shim.ts +10 -0
- package/src/__tests__/app-control-flow.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +2 -2
- package/src/__tests__/assistant-feature-flag-guard.test.ts +25 -3
- package/src/__tests__/byok-default-profile-ensure.test.ts +15 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +8 -10
- package/src/__tests__/conversation-agent-loop.test.ts +4 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +112 -0
- package/src/__tests__/conversation-notifiers-provenance.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +99 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +9 -9
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -1
- package/src/__tests__/conversation-slash-queue.test.ts +3 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -14
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/document-sync-tags.test.ts +0 -75
- package/src/__tests__/gateway-only-guard.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +1 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +49 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +7 -0
- package/src/__tests__/media-generate-image.test.ts +131 -21
- package/src/__tests__/memory-retrieval-hook.test.ts +94 -2
- package/src/__tests__/plugin-api-webhook-url.test.ts +10 -7
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +7 -3
- package/src/__tests__/proxy-approval-callback.test.ts +1 -0
- package/src/__tests__/qdrant-manager.test.ts +14 -1
- package/src/__tests__/run-due-schedules.test.ts +21 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +187 -18
- package/src/__tests__/schedule-routes.test.ts +23 -0
- package/src/__tests__/schedule-store.test.ts +17 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -3
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +1 -1
- package/src/__tests__/subagent-spawn-and-await.test.ts +4 -7
- package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
- package/src/__tests__/subagent-tools.test.ts +81 -101
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +1 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
- package/src/__tests__/ui-shape-teaching.test.ts +33 -0
- package/src/__tests__/ui-visual-surface.test.ts +1 -1
- package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
- package/src/__tests__/ui-work-result-surface.test.ts +1 -1
- package/src/__tests__/voice-config-update.test.ts +40 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +5 -3
- package/src/__tests__/voice-session-bridge.test.ts +85 -29
- package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +235 -0
- package/src/acp/session-manager.ts +8 -1
- package/src/api/surfaces.ts +12 -3
- package/src/calls/__tests__/voice-session-bridge.test.ts +21 -10
- package/src/calls/__tests__/voice-triage-escalate.test.ts +8 -0
- package/src/calls/call-controller.ts +16 -7
- package/src/calls/voice-session-bridge.ts +44 -25
- package/src/calls/voice-triage-escalate.ts +1 -0
- package/src/cli/bundled-modules.ts +29 -0
- package/src/cli/commands/db/repair.ts +4 -8
- package/src/cli/commands/domain.ts +6 -3
- package/src/cli/commands/email.ts +6 -3
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/plugins.ts +85 -36
- package/src/cli/commands/schedules.ts +35 -1
- package/src/cli/lib/bundled-marketplace.json +1 -1
- package/src/config/__tests__/balanced-model-experiment.test.ts +278 -0
- package/src/config/assistant-feature-flags.ts +36 -15
- package/src/config/balanced-model-experiment.ts +35 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +5 -4
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +101 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.test.ts +65 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +7 -1
- package/src/config/bundled-skills/settings/tools/shared.ts +16 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +9 -3
- package/src/config/bundled-skills/subagent/SKILL.md +17 -12
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -4
- package/src/config/call-site-defaults.ts +7 -0
- package/src/config/default-profile-catalog.ts +97 -5
- package/src/config/feature-flag-registry.json +11 -11
- package/src/config/skills.ts +9 -2
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
- package/src/daemon/conversation-agent-loop.ts +14 -13
- package/src/daemon/conversation-notifiers.ts +11 -9
- package/src/daemon/conversation-store.ts +4 -4
- package/src/daemon/conversation-surfaces.ts +54 -18
- package/src/daemon/conversation-tool-setup.ts +2 -4
- package/src/daemon/conversation.ts +81 -44
- package/src/daemon/doordash-steps.ts +2 -2
- package/src/daemon/lifecycle.ts +14 -1
- package/src/daemon/process-message.ts +0 -23
- package/src/daemon/windows-compiled-entry.ts +4 -0
- package/src/documents/document-store.ts +5 -235
- package/src/hooks/types.ts +5 -0
- package/src/ipc/gateway-flag-listener.ts +17 -3
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +118 -0
- package/src/live-voice/live-voice-manager.ts +16 -3
- package/src/live-voice/live-voice-session.ts +63 -9
- package/src/live-voice/windows-compiled-live-voice.ts +4 -0
- package/src/monitoring/control.ts +1 -0
- package/src/monitoring/db-integrity-sample.ts +4 -5
- package/src/permissions/prompter.ts +1 -5
- package/src/persistence/conversation-queries.ts +66 -16
- package/src/persistence/embeddings/qdrant-manager.ts +84 -49
- package/src/persistence/migrations/360-add-document-workspace-path.ts +5 -14
- package/src/persistence/schema/documents.ts +4 -4
- package/src/plugin-api/constants.ts +8 -0
- package/src/plugin-api/index.ts +5 -1
- package/src/plugin-api/vision-support.test.ts +1 -1
- package/src/plugin-api/webhook-url.ts +13 -11
- package/src/plugins/defaults/main.ts +6 -7
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +77 -0
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +24 -6
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +53 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +4 -4
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +66 -1
- package/src/plugins/defaults/memory/v3/injector.ts +8 -0
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +23 -9
- package/src/plugins/defaults/memory/worker-control.ts +1 -0
- package/src/plugins/defaults/worker-entrypoints.ts +3 -0
- package/src/plugins/mtime-cache.ts +17 -0
- package/src/prompts/templates/system-sections.ts +0 -7
- package/src/providers/__tests__/context-overflow-error.test.ts +24 -0
- package/src/providers/__tests__/retry-callsite.test.ts +20 -0
- package/src/providers/model-catalog.ts +3 -3
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +16 -7
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +11 -6
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +9 -49
- package/src/routes/control.ts +1 -0
- package/src/routes/route-host-client.ts +1 -0
- package/src/runtime/AGENTS.md +16 -17
- package/src/runtime/agent-wake.ts +15 -12
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +170 -1
- package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +215 -0
- package/src/runtime/routes/conversation-list-routes.ts +54 -22
- package/src/runtime/routes/conversation-management-routes.ts +2 -3
- package/src/runtime/routes/conversation-routes.ts +11 -13
- package/src/runtime/routes/documents-routes.ts +3 -222
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +2 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -2
- package/src/runtime/routes/playground/reset-circuit.ts +1 -1
- package/src/runtime/routes/schedule-routes.ts +94 -7
- package/src/runtime/routes/workspace-routes.ts +0 -9
- package/src/runtime/routes/workspace-utils.ts +3 -13
- package/src/runtime/services/conversation-serializer.ts +7 -2
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +68 -5
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +81 -0
- package/src/schedule/plugin-schedule-availability.ts +58 -0
- package/src/schedule/plugin-schedule-declarations.ts +23 -27
- package/src/schedule/plugin-schedule-reconciler.ts +12 -3
- package/src/schedule/schedule-store.ts +5 -1
- package/src/schedule/scheduler.ts +9 -4
- package/src/schedule/worker-control.ts +1 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +26 -15
- package/src/subagent/consult-context.ts +11 -11
- package/src/subagent/consult-prompt.ts +26 -35
- package/src/subagent/manager.ts +20 -37
- package/src/subagent/notify.ts +7 -1
- package/src/subagent/types.ts +8 -6
- package/src/tools/acp/spawn.ts +6 -4
- package/src/tools/skills/scaffold-managed.ts +25 -7
- package/src/tools/subagent/spawn.ts +28 -88
- package/src/tools/ui-surface/surface-shape-docs.ts +12 -1
- package/src/tts/__tests__/reasoning-tag-filter.test.ts +15 -0
- package/src/tts/reasoning-tag-filter.ts +11 -32
- package/src/util/__tests__/worker-process-command.test.ts +37 -0
- package/src/util/logger.ts +16 -0
- package/src/util/think-tag-stream.ts +95 -0
- package/src/util/worker-process.ts +37 -4
- package/src/windows-compiled-cli.ts +32 -0
- package/src/windows-compiled-entry.ts +4 -0
- package/src/windows-compiled-logger.ts +6 -0
- package/src/windows-compiled-worker-entry.ts +29 -0
- package/src/workspace/byok-default-profile-ensure.ts +15 -6
- package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +195 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/document-workspace-file.test.ts +0 -467
- package/src/subagent/__tests__/consult-transcript.test.ts +0 -184
- package/src/subagent/consult-transcript.ts +0 -90
package/openapi.yaml
CHANGED
|
@@ -6596,6 +6596,18 @@ paths:
|
|
|
6596
6596
|
"system:all" for conversations in no group, "system:pinned" for the Pinned section, or a custom group id. A
|
|
6597
6597
|
group-scoped request is recency-ordered like every list read (COALESCE(last_message_at, updated_at)
|
|
6598
6598
|
descending) and never has pinned rows appended to it. Omit to span every group.
|
|
6599
|
+
- name: needsAttention
|
|
6600
|
+
in: query
|
|
6601
|
+
required: false
|
|
6602
|
+
schema:
|
|
6603
|
+
type: string
|
|
6604
|
+
enum:
|
|
6605
|
+
- "true"
|
|
6606
|
+
description:
|
|
6607
|
+
'Pass "true" to return only conversations whose latest assistant message the user has not seen: the same
|
|
6608
|
+
predicate behind the unread count and the section index, so a client that keeps no complete conversation
|
|
6609
|
+
list can ask for exactly the rows its attention surfaces need. Composes with every other filter. Any value
|
|
6610
|
+
other than "true" is rejected. Omit to span every conversation.'
|
|
6599
6611
|
responses:
|
|
6600
6612
|
"200":
|
|
6601
6613
|
description: Successful response
|
|
@@ -6953,7 +6965,9 @@ paths:
|
|
|
6953
6965
|
get:
|
|
6954
6966
|
operationId: conversations_by_id_get
|
|
6955
6967
|
summary: Get conversation detail
|
|
6956
|
-
description:
|
|
6968
|
+
description:
|
|
6969
|
+
Retrieve a single conversation with full metadata. Rows the listing hides by type (legacy private rows) are
|
|
6970
|
+
not found here either.
|
|
6957
6971
|
tags:
|
|
6958
6972
|
- conversations
|
|
6959
6973
|
parameters:
|
|
@@ -10906,11 +10920,6 @@ paths:
|
|
|
10906
10920
|
type: number
|
|
10907
10921
|
updatedAt:
|
|
10908
10922
|
type: number
|
|
10909
|
-
workspacePath:
|
|
10910
|
-
anyOf:
|
|
10911
|
-
- type: string
|
|
10912
|
-
- type: "null"
|
|
10913
|
-
description: Workspace-relative file this document is bound to, or null
|
|
10914
10923
|
required:
|
|
10915
10924
|
- success
|
|
10916
10925
|
- surfaceId
|
|
@@ -10920,7 +10929,6 @@ paths:
|
|
|
10920
10929
|
- wordCount
|
|
10921
10930
|
- createdAt
|
|
10922
10931
|
- updatedAt
|
|
10923
|
-
- workspacePath
|
|
10924
10932
|
additionalProperties: false
|
|
10925
10933
|
/v1/documents/{id}/comments:
|
|
10926
10934
|
get:
|
|
@@ -11338,74 +11346,6 @@ paths:
|
|
|
11338
11346
|
schema:
|
|
11339
11347
|
type: string
|
|
11340
11348
|
format: binary
|
|
11341
|
-
/v1/documents/for-workspace-file:
|
|
11342
|
-
post:
|
|
11343
|
-
operationId: documents_forworkspacefile_post
|
|
11344
|
-
summary: Get or create the document for a workspace markdown file
|
|
11345
|
-
description:
|
|
11346
|
-
"Return the document bound to a workspace markdown file, creating it on first open. The file is the source
|
|
11347
|
-
of truth at open time: stored content that has drifted from the file is refreshed from disk before the document
|
|
11348
|
-
is returned."
|
|
11349
|
-
tags:
|
|
11350
|
-
- documents
|
|
11351
|
-
requestBody:
|
|
11352
|
-
required: true
|
|
11353
|
-
content:
|
|
11354
|
-
application/json:
|
|
11355
|
-
schema:
|
|
11356
|
-
type: object
|
|
11357
|
-
properties:
|
|
11358
|
-
path:
|
|
11359
|
-
type: string
|
|
11360
|
-
description: Workspace-relative path to a .md/.markdown file
|
|
11361
|
-
conversationId:
|
|
11362
|
-
type: string
|
|
11363
|
-
description: Conversation the document is opened from
|
|
11364
|
-
required:
|
|
11365
|
-
- path
|
|
11366
|
-
- conversationId
|
|
11367
|
-
responses:
|
|
11368
|
-
"200":
|
|
11369
|
-
description: Successful response
|
|
11370
|
-
content:
|
|
11371
|
-
application/json:
|
|
11372
|
-
schema:
|
|
11373
|
-
type: object
|
|
11374
|
-
properties:
|
|
11375
|
-
success:
|
|
11376
|
-
type: boolean
|
|
11377
|
-
surfaceId:
|
|
11378
|
-
type: string
|
|
11379
|
-
conversationId:
|
|
11380
|
-
type: string
|
|
11381
|
-
title:
|
|
11382
|
-
type: string
|
|
11383
|
-
content:
|
|
11384
|
-
type: string
|
|
11385
|
-
wordCount:
|
|
11386
|
-
type: number
|
|
11387
|
-
createdAt:
|
|
11388
|
-
type: number
|
|
11389
|
-
updatedAt:
|
|
11390
|
-
type: number
|
|
11391
|
-
workspacePath:
|
|
11392
|
-
anyOf:
|
|
11393
|
-
- type: string
|
|
11394
|
-
- type: "null"
|
|
11395
|
-
description: Workspace-relative file this document is bound to, or null
|
|
11396
|
-
required:
|
|
11397
|
-
- success
|
|
11398
|
-
- surfaceId
|
|
11399
|
-
- conversationId
|
|
11400
|
-
- title
|
|
11401
|
-
- content
|
|
11402
|
-
- wordCount
|
|
11403
|
-
- createdAt
|
|
11404
|
-
- updatedAt
|
|
11405
|
-
- workspacePath
|
|
11406
|
-
additionalProperties: false
|
|
11407
|
-
"422":
|
|
11408
|
-
description: Path is not a markdown file
|
|
11409
11349
|
/v1/domain/register:
|
|
11410
11350
|
post:
|
|
11411
11351
|
operationId: domain_register_post
|
|
@@ -25778,6 +25718,20 @@ paths:
|
|
|
25778
25718
|
description:
|
|
25779
25719
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
25780
25720
|
applies. Always null for user-created schedules.
|
|
25721
|
+
disarmReason:
|
|
25722
|
+
anyOf:
|
|
25723
|
+
- type: string
|
|
25724
|
+
enum:
|
|
25725
|
+
- user_disabled
|
|
25726
|
+
- plugin_removed
|
|
25727
|
+
- plugin_disabled
|
|
25728
|
+
- declaration_removed
|
|
25729
|
+
- declaration_disabled
|
|
25730
|
+
- type: "null"
|
|
25731
|
+
description:
|
|
25732
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
25733
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
25734
|
+
is on, and always null for user-created schedules."
|
|
25781
25735
|
isOneShot:
|
|
25782
25736
|
type: boolean
|
|
25783
25737
|
isDeferred:
|
|
@@ -25814,6 +25768,7 @@ paths:
|
|
|
25814
25768
|
- workflowName
|
|
25815
25769
|
- sourceKey
|
|
25816
25770
|
- userEnabled
|
|
25771
|
+
- disarmReason
|
|
25817
25772
|
- isOneShot
|
|
25818
25773
|
- isDeferred
|
|
25819
25774
|
additionalProperties: false
|
|
@@ -26011,6 +25966,20 @@ paths:
|
|
|
26011
25966
|
description:
|
|
26012
25967
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26013
25968
|
applies. Always null for user-created schedules.
|
|
25969
|
+
disarmReason:
|
|
25970
|
+
anyOf:
|
|
25971
|
+
- type: string
|
|
25972
|
+
enum:
|
|
25973
|
+
- user_disabled
|
|
25974
|
+
- plugin_removed
|
|
25975
|
+
- plugin_disabled
|
|
25976
|
+
- declaration_removed
|
|
25977
|
+
- declaration_disabled
|
|
25978
|
+
- type: "null"
|
|
25979
|
+
description:
|
|
25980
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
25981
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
25982
|
+
is on, and always null for user-created schedules."
|
|
26014
25983
|
isOneShot:
|
|
26015
25984
|
type: boolean
|
|
26016
25985
|
isDeferred:
|
|
@@ -26047,6 +26016,7 @@ paths:
|
|
|
26047
26016
|
- workflowName
|
|
26048
26017
|
- sourceKey
|
|
26049
26018
|
- userEnabled
|
|
26019
|
+
- disarmReason
|
|
26050
26020
|
- isOneShot
|
|
26051
26021
|
- isDeferred
|
|
26052
26022
|
additionalProperties: false
|
|
@@ -26196,6 +26166,20 @@ paths:
|
|
|
26196
26166
|
description:
|
|
26197
26167
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26198
26168
|
applies. Always null for user-created schedules.
|
|
26169
|
+
disarmReason:
|
|
26170
|
+
anyOf:
|
|
26171
|
+
- type: string
|
|
26172
|
+
enum:
|
|
26173
|
+
- user_disabled
|
|
26174
|
+
- plugin_removed
|
|
26175
|
+
- plugin_disabled
|
|
26176
|
+
- declaration_removed
|
|
26177
|
+
- declaration_disabled
|
|
26178
|
+
- type: "null"
|
|
26179
|
+
description:
|
|
26180
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
26181
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
26182
|
+
is on, and always null for user-created schedules."
|
|
26199
26183
|
isOneShot:
|
|
26200
26184
|
type: boolean
|
|
26201
26185
|
isDeferred:
|
|
@@ -26232,6 +26216,7 @@ paths:
|
|
|
26232
26216
|
- workflowName
|
|
26233
26217
|
- sourceKey
|
|
26234
26218
|
- userEnabled
|
|
26219
|
+
- disarmReason
|
|
26235
26220
|
- isOneShot
|
|
26236
26221
|
- isDeferred
|
|
26237
26222
|
additionalProperties: false
|
|
@@ -26378,6 +26363,20 @@ paths:
|
|
|
26378
26363
|
description:
|
|
26379
26364
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26380
26365
|
applies. Always null for user-created schedules.
|
|
26366
|
+
disarmReason:
|
|
26367
|
+
anyOf:
|
|
26368
|
+
- type: string
|
|
26369
|
+
enum:
|
|
26370
|
+
- user_disabled
|
|
26371
|
+
- plugin_removed
|
|
26372
|
+
- plugin_disabled
|
|
26373
|
+
- declaration_removed
|
|
26374
|
+
- declaration_disabled
|
|
26375
|
+
- type: "null"
|
|
26376
|
+
description:
|
|
26377
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
26378
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
26379
|
+
is on, and always null for user-created schedules."
|
|
26381
26380
|
isOneShot:
|
|
26382
26381
|
type: boolean
|
|
26383
26382
|
isDeferred:
|
|
@@ -26414,6 +26413,7 @@ paths:
|
|
|
26414
26413
|
- workflowName
|
|
26415
26414
|
- sourceKey
|
|
26416
26415
|
- userEnabled
|
|
26416
|
+
- disarmReason
|
|
26417
26417
|
- isOneShot
|
|
26418
26418
|
- isDeferred
|
|
26419
26419
|
additionalProperties: false
|
|
@@ -26620,6 +26620,20 @@ paths:
|
|
|
26620
26620
|
description:
|
|
26621
26621
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26622
26622
|
applies. Always null for user-created schedules.
|
|
26623
|
+
disarmReason:
|
|
26624
|
+
anyOf:
|
|
26625
|
+
- type: string
|
|
26626
|
+
enum:
|
|
26627
|
+
- user_disabled
|
|
26628
|
+
- plugin_removed
|
|
26629
|
+
- plugin_disabled
|
|
26630
|
+
- declaration_removed
|
|
26631
|
+
- declaration_disabled
|
|
26632
|
+
- type: "null"
|
|
26633
|
+
description:
|
|
26634
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
26635
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
26636
|
+
is on, and always null for user-created schedules."
|
|
26623
26637
|
isOneShot:
|
|
26624
26638
|
type: boolean
|
|
26625
26639
|
isDeferred:
|
|
@@ -26656,6 +26670,7 @@ paths:
|
|
|
26656
26670
|
- workflowName
|
|
26657
26671
|
- sourceKey
|
|
26658
26672
|
- userEnabled
|
|
26673
|
+
- disarmReason
|
|
26659
26674
|
- isOneShot
|
|
26660
26675
|
- isDeferred
|
|
26661
26676
|
additionalProperties: false
|
|
@@ -26805,6 +26820,20 @@ paths:
|
|
|
26805
26820
|
description:
|
|
26806
26821
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26807
26822
|
applies. Always null for user-created schedules.
|
|
26823
|
+
disarmReason:
|
|
26824
|
+
anyOf:
|
|
26825
|
+
- type: string
|
|
26826
|
+
enum:
|
|
26827
|
+
- user_disabled
|
|
26828
|
+
- plugin_removed
|
|
26829
|
+
- plugin_disabled
|
|
26830
|
+
- declaration_removed
|
|
26831
|
+
- declaration_disabled
|
|
26832
|
+
- type: "null"
|
|
26833
|
+
description:
|
|
26834
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
26835
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
26836
|
+
is on, and always null for user-created schedules."
|
|
26808
26837
|
isOneShot:
|
|
26809
26838
|
type: boolean
|
|
26810
26839
|
isDeferred:
|
|
@@ -26841,6 +26870,7 @@ paths:
|
|
|
26841
26870
|
- workflowName
|
|
26842
26871
|
- sourceKey
|
|
26843
26872
|
- userEnabled
|
|
26873
|
+
- disarmReason
|
|
26844
26874
|
- isOneShot
|
|
26845
26875
|
- isDeferred
|
|
26846
26876
|
additionalProperties: false
|
|
@@ -26992,6 +27022,20 @@ paths:
|
|
|
26992
27022
|
description:
|
|
26993
27023
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
26994
27024
|
applies. Always null for user-created schedules.
|
|
27025
|
+
disarmReason:
|
|
27026
|
+
anyOf:
|
|
27027
|
+
- type: string
|
|
27028
|
+
enum:
|
|
27029
|
+
- user_disabled
|
|
27030
|
+
- plugin_removed
|
|
27031
|
+
- plugin_disabled
|
|
27032
|
+
- declaration_removed
|
|
27033
|
+
- declaration_disabled
|
|
27034
|
+
- type: "null"
|
|
27035
|
+
description:
|
|
27036
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
27037
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
27038
|
+
is on, and always null for user-created schedules."
|
|
26995
27039
|
isOneShot:
|
|
26996
27040
|
type: boolean
|
|
26997
27041
|
isDeferred:
|
|
@@ -27028,6 +27072,7 @@ paths:
|
|
|
27028
27072
|
- workflowName
|
|
27029
27073
|
- sourceKey
|
|
27030
27074
|
- userEnabled
|
|
27075
|
+
- disarmReason
|
|
27031
27076
|
- isOneShot
|
|
27032
27077
|
- isDeferred
|
|
27033
27078
|
additionalProperties: false
|
|
@@ -27314,6 +27359,20 @@ paths:
|
|
|
27314
27359
|
description:
|
|
27315
27360
|
User enable/disable override on a plugin-sourced schedule; null when the declaration's own enabled value
|
|
27316
27361
|
applies. Always null for user-created schedules.
|
|
27362
|
+
disarmReason:
|
|
27363
|
+
anyOf:
|
|
27364
|
+
- type: string
|
|
27365
|
+
enum:
|
|
27366
|
+
- user_disabled
|
|
27367
|
+
- plugin_removed
|
|
27368
|
+
- plugin_disabled
|
|
27369
|
+
- declaration_removed
|
|
27370
|
+
- declaration_disabled
|
|
27371
|
+
- type: "null"
|
|
27372
|
+
description:
|
|
27373
|
+
"Why a plugin-sourced schedule is off: the user turned it off, the plugin is gone, the plugin is disabled,
|
|
27374
|
+
the declaration is gone, or the plugin's own files turned it off. Null whenever the schedule
|
|
27375
|
+
is on, and always null for user-created schedules."
|
|
27317
27376
|
isOneShot:
|
|
27318
27377
|
type: boolean
|
|
27319
27378
|
isDeferred:
|
|
@@ -27350,6 +27409,7 @@ paths:
|
|
|
27350
27409
|
- workflowName
|
|
27351
27410
|
- sourceKey
|
|
27352
27411
|
- userEnabled
|
|
27412
|
+
- disarmReason
|
|
27353
27413
|
- isOneShot
|
|
27354
27414
|
- isDeferred
|
|
27355
27415
|
additionalProperties: false
|
package/package.json
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
import { ensurePluginApiShim } from "../src/plugins/ensure-plugin-api-shim.js";
|
|
4
|
+
|
|
5
|
+
const outputDir = Bun.argv[2];
|
|
6
|
+
if (!outputDir || !path.isAbsolute(outputDir)) {
|
|
7
|
+
throw new Error("An absolute plugin API shim output directory is required.");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
await ensurePluginApiShim({ workspaceDir: outputDir });
|
|
@@ -113,7 +113,7 @@ function makeIdleSession(opts?: {
|
|
|
113
113
|
ensureActorScopedHistory: async () => {},
|
|
114
114
|
getMessages: () => [],
|
|
115
115
|
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
116
|
-
|
|
116
|
+
replayActivityState: () => {},
|
|
117
117
|
setHostBrowserProxy: () => {},
|
|
118
118
|
setHostCuProxy: () => {},
|
|
119
119
|
setHostAppControlProxy: () => {},
|
|
@@ -176,7 +176,7 @@ function makeConfirmationEmittingSession(opts?: {
|
|
|
176
176
|
ensureActorScopedHistory: async () => {},
|
|
177
177
|
getMessages: () => [],
|
|
178
178
|
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
179
|
-
|
|
179
|
+
replayActivityState: () => {},
|
|
180
180
|
setHostBrowserProxy: () => {},
|
|
181
181
|
setHostCuProxy: () => {},
|
|
182
182
|
setHostAppControlProxy: () => {},
|
|
@@ -40,7 +40,10 @@ interface RegistryFlag {
|
|
|
40
40
|
key: string;
|
|
41
41
|
label: string;
|
|
42
42
|
description: string;
|
|
43
|
-
|
|
43
|
+
/** Boolean for a gate; the winning variation's name for a multivariate flag. */
|
|
44
|
+
defaultEnabled: boolean | string;
|
|
45
|
+
/** Declared variations. Present only on multivariate flags. */
|
|
46
|
+
values?: string[];
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
interface Registry {
|
|
@@ -179,8 +182,27 @@ describe("assistant feature flag guard", () => {
|
|
|
179
182
|
const violations: string[] = [];
|
|
180
183
|
|
|
181
184
|
for (const flag of assistantFlags) {
|
|
182
|
-
|
|
183
|
-
|
|
185
|
+
// A gate declares a boolean default. A multivariate flag declares its
|
|
186
|
+
// variations in `values` and names the winning one in `defaultEnabled`,
|
|
187
|
+
// which the resolver serves verbatim to string consumers.
|
|
188
|
+
if (flag.values === undefined) {
|
|
189
|
+
if (typeof flag.defaultEnabled !== "boolean") {
|
|
190
|
+
violations.push(
|
|
191
|
+
`${flag.key}: missing or non-boolean 'defaultEnabled'`,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
} else if (
|
|
195
|
+
!Array.isArray(flag.values) ||
|
|
196
|
+
flag.values.length < 2 ||
|
|
197
|
+
flag.values.some((value) => typeof value !== "string")
|
|
198
|
+
) {
|
|
199
|
+
violations.push(
|
|
200
|
+
`${flag.key}: 'values' must list at least two string variations`,
|
|
201
|
+
);
|
|
202
|
+
} else if (!flag.values.includes(flag.defaultEnabled as string)) {
|
|
203
|
+
violations.push(
|
|
204
|
+
`${flag.key}: 'defaultEnabled' must name one of the declared 'values'`,
|
|
205
|
+
);
|
|
184
206
|
}
|
|
185
207
|
if (
|
|
186
208
|
typeof flag.description !== "string" ||
|
|
@@ -282,11 +282,26 @@ describe("ensureByokDefaultProfiles", () => {
|
|
|
282
282
|
["openai", "quality-optimized", "gpt-5.4"],
|
|
283
283
|
["fireworks", "balanced", "accounts/fireworks/models/kimi-k2p5"],
|
|
284
284
|
["fireworks", "balanced", "accounts/fireworks/models/kimi-k2p6"],
|
|
285
|
+
[
|
|
286
|
+
"fireworks",
|
|
287
|
+
"balanced",
|
|
288
|
+
"accounts/fireworks/models/deepseek-v4-flash-0731",
|
|
289
|
+
],
|
|
285
290
|
[
|
|
286
291
|
"fireworks",
|
|
287
292
|
"quality-optimized",
|
|
288
293
|
"accounts/fireworks/models/deepseek-v4-flash",
|
|
289
294
|
],
|
|
295
|
+
[
|
|
296
|
+
"fireworks",
|
|
297
|
+
"quality-optimized",
|
|
298
|
+
"accounts/fireworks/models/deepseek-v4-flash-0731",
|
|
299
|
+
],
|
|
300
|
+
[
|
|
301
|
+
"fireworks",
|
|
302
|
+
"cost-optimized",
|
|
303
|
+
"accounts/fireworks/models/deepseek-v4-flash",
|
|
304
|
+
],
|
|
290
305
|
] as const)(
|
|
291
306
|
"a historical intent-era copy converts (%s %s pinned to %s)",
|
|
292
307
|
(provider, key, model) => {
|
|
@@ -28,7 +28,7 @@ function makeContext(
|
|
|
28
28
|
): Conversation {
|
|
29
29
|
return asConversation({
|
|
30
30
|
conversationId: "session-1",
|
|
31
|
-
|
|
31
|
+
emit: (msg) => sent.push(msg),
|
|
32
32
|
pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
|
|
33
33
|
lastSurfaceAction: new Map<
|
|
34
34
|
string,
|
|
@@ -436,12 +436,11 @@ describe("forceCompact context-window usage push", () => {
|
|
|
436
436
|
expect(usageEvent.maxTokens).toBe(200_000);
|
|
437
437
|
});
|
|
438
438
|
|
|
439
|
-
test("pushes to the caller's sink
|
|
440
|
-
// A `/compact` draining
|
|
441
|
-
//
|
|
442
|
-
//
|
|
443
|
-
|
|
444
|
-
const stranded: AssistantEvent[] = [];
|
|
439
|
+
test("pushes to the caller's sink instead of the conversation sink when one is given", async () => {
|
|
440
|
+
// A `/compact` draining from the queue carries the queued item's own
|
|
441
|
+
// sink, the one its result card streams on. The push has to follow the
|
|
442
|
+
// card so the two can never be delivered to different places.
|
|
443
|
+
const conversationSink: AssistantEvent[] = [];
|
|
445
444
|
const cardSink: AssistantEvent[] = [];
|
|
446
445
|
mockCompactResult = {
|
|
447
446
|
messages: [],
|
|
@@ -460,11 +459,10 @@ describe("forceCompact context-window usage push", () => {
|
|
|
460
459
|
};
|
|
461
460
|
|
|
462
461
|
const conversation = makeConversation(
|
|
463
|
-
|
|
464
|
-
"conv-compact-
|
|
462
|
+
conversationSink,
|
|
463
|
+
"conv-compact-caller-sink",
|
|
465
464
|
[56_000, 18_000],
|
|
466
465
|
);
|
|
467
|
-
conversation.updateClient(() => {}, true);
|
|
468
466
|
|
|
469
467
|
const result = await conversation.forceCompact((msg) => cardSink.push(msg));
|
|
470
468
|
|
|
@@ -475,7 +473,7 @@ describe("forceCompact context-window usage push", () => {
|
|
|
475
473
|
.tokens,
|
|
476
474
|
).toBe(result.estimatedInputTokens);
|
|
477
475
|
expect(
|
|
478
|
-
|
|
476
|
+
conversationSink.filter((m) => m.type === "context_window_usage").length,
|
|
479
477
|
).toBe(0);
|
|
480
478
|
});
|
|
481
479
|
|
|
@@ -1345,7 +1345,10 @@ describe("session-agent-loop", () => {
|
|
|
1345
1345
|
});
|
|
1346
1346
|
const cleanupFlagDuringInjection = captureCleanupFlagDuringInjection(ctx);
|
|
1347
1347
|
|
|
1348
|
-
|
|
1348
|
+
// Presence is declared per turn; the policy input must carry it.
|
|
1349
|
+
await runAgentLoopImpl(ctx, "free up space", "msg-1", () => {}, {
|
|
1350
|
+
isInteractive: true,
|
|
1351
|
+
});
|
|
1349
1352
|
|
|
1350
1353
|
expect(classifyDiskPressureTurnPolicyMock).toHaveBeenCalledWith(
|
|
1351
1354
|
mockDiskPressureStatus,
|
|
@@ -431,3 +431,115 @@ describe("sendToClient receives state signals", () => {
|
|
|
431
431
|
});
|
|
432
432
|
});
|
|
433
433
|
});
|
|
434
|
+
|
|
435
|
+
describe("the sink is fixed for the conversation's life", () => {
|
|
436
|
+
test("a cold instance delivers activity state with no turn ever having run", () => {
|
|
437
|
+
// The summarize-up-to route resolves its conversation outside the send
|
|
438
|
+
// path and emits a thinking indicator before any turn: it must reach the
|
|
439
|
+
// sink the conversation was built with, not depend on a send having wired
|
|
440
|
+
// one (LUM-2987).
|
|
441
|
+
const clientMsgs: AssistantEvent[] = [];
|
|
442
|
+
const conversation = makeConversation((msg) => clientMsgs.push(msg));
|
|
443
|
+
|
|
444
|
+
conversation.emitActivityState("thinking", "context_compacting", {
|
|
445
|
+
statusText: "Summarizing conversation",
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
const activity = clientMsgs.filter(
|
|
449
|
+
(m) => m.type === "assistant_activity_state",
|
|
450
|
+
);
|
|
451
|
+
expect(activity).toHaveLength(1);
|
|
452
|
+
expect((activity[0] as { statusText?: string }).statusText).toBe(
|
|
453
|
+
"Summarizing conversation",
|
|
454
|
+
);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test("presence is a property of the turn, not of delivery", () => {
|
|
458
|
+
// Nothing is in flight, so no human is asserted present, even though the
|
|
459
|
+
// sink is live and delivering.
|
|
460
|
+
const clientMsgs: AssistantEvent[] = [];
|
|
461
|
+
const conversation = makeConversation((msg) => clientMsgs.push(msg));
|
|
462
|
+
expect(conversation.hasNoClient).toBe(true);
|
|
463
|
+
conversation.emitActivityState("thinking", "message_dequeued");
|
|
464
|
+
expect(clientMsgs).toHaveLength(1);
|
|
465
|
+
expect(conversation.hasNoClient).toBe(true);
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
describe("event observers", () => {
|
|
470
|
+
test("an observer sees each event after the sink delivered it, and detaches", () => {
|
|
471
|
+
const order: string[] = [];
|
|
472
|
+
const conversation = makeConversation((msg) => {
|
|
473
|
+
order.push(`sink:${msg.type}`);
|
|
474
|
+
});
|
|
475
|
+
const detach = conversation.addEventObserver((msg) => {
|
|
476
|
+
order.push(`observer:${msg.type}`);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
conversation.emitActivityState("thinking", "message_dequeued");
|
|
480
|
+
expect(order).toEqual([
|
|
481
|
+
"sink:assistant_activity_state",
|
|
482
|
+
"observer:assistant_activity_state",
|
|
483
|
+
]);
|
|
484
|
+
|
|
485
|
+
detach();
|
|
486
|
+
conversation.emitActivityState("idle", "message_complete");
|
|
487
|
+
expect(order).toEqual([
|
|
488
|
+
"sink:assistant_activity_state",
|
|
489
|
+
"observer:assistant_activity_state",
|
|
490
|
+
"sink:assistant_activity_state",
|
|
491
|
+
]);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
test("a throwing observer neither blocks the sink nor its siblings", () => {
|
|
495
|
+
const seen: string[] = [];
|
|
496
|
+
const conversation = makeConversation((msg) => {
|
|
497
|
+
seen.push(`sink:${msg.type}`);
|
|
498
|
+
});
|
|
499
|
+
conversation.addEventObserver(() => {
|
|
500
|
+
throw new Error("observer boom");
|
|
501
|
+
});
|
|
502
|
+
conversation.addEventObserver((msg) => {
|
|
503
|
+
seen.push(`second:${msg.type}`);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
conversation.emitActivityState("thinking", "message_dequeued");
|
|
507
|
+
expect(seen).toEqual([
|
|
508
|
+
"sink:assistant_activity_state",
|
|
509
|
+
"second:assistant_activity_state",
|
|
510
|
+
]);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
test("the prompter's confirmation_request reaches observers after the sink", () => {
|
|
514
|
+
// Voice auto-resolves approval prompts it has no UI for; it must observe
|
|
515
|
+
// the request only once the sink has put it on the wire, so its resolution
|
|
516
|
+
// lands after the request it answers.
|
|
517
|
+
const order: string[] = [];
|
|
518
|
+
const conversation = makeConversation((msg) => {
|
|
519
|
+
order.push(`sink:${msg.type}`);
|
|
520
|
+
});
|
|
521
|
+
conversation.addEventObserver((msg) => {
|
|
522
|
+
if (msg.type === "confirmation_request") {
|
|
523
|
+
order.push("observer:confirmation_request");
|
|
524
|
+
conversation.handleConfirmationResponse(msg.requestId, "deny", {
|
|
525
|
+
emissionContext: { source: "system" },
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
void conversation.prompter.prompt(
|
|
531
|
+
"bash",
|
|
532
|
+
{ command: "rm -rf /tmp/x" },
|
|
533
|
+
"high",
|
|
534
|
+
[],
|
|
535
|
+
[],
|
|
536
|
+
undefined,
|
|
537
|
+
conversation.conversationId,
|
|
538
|
+
"sandbox",
|
|
539
|
+
false,
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
expect(order[0]).toBe("sink:confirmation_request");
|
|
543
|
+
expect(order[1]).toBe("observer:confirmation_request");
|
|
544
|
+
});
|
|
545
|
+
});
|
|
@@ -35,7 +35,7 @@ describe("live-call question provenance", () => {
|
|
|
35
35
|
|
|
36
36
|
test("a row persisted after the turn settled carries the owner, not the stale turn actor", async () => {
|
|
37
37
|
registerConversationNotifiers("conv-n1", {
|
|
38
|
-
|
|
38
|
+
emit: () => {},
|
|
39
39
|
messages: [],
|
|
40
40
|
// Voice cleanup restored the owner; the per-turn field still holds the
|
|
41
41
|
// finished voice turn's contact.
|