@vellumai/assistant 0.11.4-staging.2 → 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.
Files changed (189) hide show
  1. package/AGENTS.md +8 -2
  2. package/ARCHITECTURE.md +2 -0
  3. package/docs/architecture/memory.md +15 -0
  4. package/docs/browser-use-architecture-phase2.md +128 -56
  5. package/docs/flux-turn-detection-spike.md +11 -6
  6. package/knip.json +3 -0
  7. package/openapi.yaml +136 -76
  8. package/package.json +1 -1
  9. package/scripts/write-plugin-api-shim.ts +10 -0
  10. package/src/__tests__/app-control-flow.test.ts +1 -0
  11. package/src/__tests__/approval-routes-http.test.ts +2 -2
  12. package/src/__tests__/assistant-feature-flag-guard.test.ts +25 -3
  13. package/src/__tests__/channel-setup-panel-ack.test.ts +1 -1
  14. package/src/__tests__/compaction-events.test.ts +8 -10
  15. package/src/__tests__/conversation-agent-loop.test.ts +4 -1
  16. package/src/__tests__/conversation-confirmation-signals.test.ts +112 -0
  17. package/src/__tests__/conversation-notifiers-provenance.test.ts +1 -1
  18. package/src/__tests__/conversation-queue.test.ts +39 -62
  19. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
  20. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +1 -1
  21. package/src/__tests__/conversation-routes-guardian-reply.test.ts +9 -9
  22. package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -1
  23. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -1
  24. package/src/__tests__/conversation-slash-queue.test.ts +3 -0
  25. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +1 -0
  26. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -0
  27. package/src/__tests__/conversation-surfaces-app-control.test.ts +1 -0
  28. package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -1
  29. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -1
  30. package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -14
  31. package/src/__tests__/conversation-surfaces-queued-emit.test.ts +1 -0
  32. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1 -0
  33. package/src/__tests__/conversation-surfaces-standalone.test.ts +1 -0
  34. package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -1
  35. package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -1
  36. package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -1
  37. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
  38. package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
  39. package/src/__tests__/cu-unified-flow.test.ts +1 -0
  40. package/src/__tests__/document-sync-tags.test.ts +0 -75
  41. package/src/__tests__/gateway-only-guard.test.ts +2 -5
  42. package/src/__tests__/http-user-message-parity.test.ts +1 -1
  43. package/src/__tests__/init-feature-flag-overrides.test.ts +49 -0
  44. package/src/__tests__/managed-skill-lifecycle.test.ts +7 -0
  45. package/src/__tests__/media-generate-image.test.ts +131 -21
  46. package/src/__tests__/memory-retrieval-hook.test.ts +94 -2
  47. package/src/__tests__/plugin-api-webhook-url.test.ts +10 -7
  48. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +7 -3
  49. package/src/__tests__/proxy-approval-callback.test.ts +1 -0
  50. package/src/__tests__/qdrant-manager.test.ts +14 -1
  51. package/src/__tests__/run-due-schedules.test.ts +21 -0
  52. package/src/__tests__/scaffold-managed-skill-tool.test.ts +187 -18
  53. package/src/__tests__/schedule-routes.test.ts +23 -0
  54. package/src/__tests__/schedule-store.test.ts +17 -0
  55. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  56. package/src/__tests__/send-endpoint-busy.test.ts +3 -3
  57. package/src/__tests__/starter-task-flow.test.ts +5 -4
  58. package/src/__tests__/subagent-fork-prompt-role.test.ts +1 -1
  59. package/src/__tests__/subagent-spawn-and-await.test.ts +4 -7
  60. package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
  61. package/src/__tests__/subagent-tools.test.ts +81 -101
  62. package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +1 -0
  63. package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
  64. package/src/__tests__/ui-visual-surface.test.ts +1 -1
  65. package/src/__tests__/ui-voice-picker-surface.test.ts +1 -1
  66. package/src/__tests__/ui-work-result-surface.test.ts +1 -1
  67. package/src/__tests__/voice-scoped-grant-consumer.test.ts +5 -3
  68. package/src/__tests__/voice-session-bridge.test.ts +85 -29
  69. package/src/acp/session-manager.ts +8 -1
  70. package/src/api/surfaces.ts +5 -0
  71. package/src/calls/__tests__/voice-session-bridge.test.ts +21 -10
  72. package/src/calls/__tests__/voice-triage-escalate.test.ts +8 -0
  73. package/src/calls/voice-session-bridge.ts +44 -25
  74. package/src/calls/voice-triage-escalate.ts +1 -0
  75. package/src/cli/bundled-modules.ts +29 -0
  76. package/src/cli/commands/db/repair.ts +4 -8
  77. package/src/cli/commands/domain.ts +6 -3
  78. package/src/cli/commands/email.ts +6 -3
  79. package/src/cli/commands/keys.ts +8 -3
  80. package/src/cli/commands/plugins.ts +85 -36
  81. package/src/cli/commands/schedules.ts +35 -1
  82. package/src/cli/lib/bundled-marketplace.json +1 -1
  83. package/src/config/__tests__/balanced-model-experiment.test.ts +278 -0
  84. package/src/config/assistant-feature-flags.ts +36 -15
  85. package/src/config/balanced-model-experiment.ts +35 -0
  86. package/src/config/bundled-skills/image-studio/SKILL.md +5 -4
  87. package/src/config/bundled-skills/image-studio/TOOLS.json +1 -1
  88. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +101 -0
  89. package/src/config/bundled-skills/skill-management/TOOLS.json +9 -3
  90. package/src/config/bundled-skills/subagent/SKILL.md +17 -12
  91. package/src/config/bundled-skills/subagent/TOOLS.json +4 -4
  92. package/src/config/call-site-defaults.ts +7 -0
  93. package/src/config/default-profile-catalog.ts +96 -4
  94. package/src/config/feature-flag-registry.json +11 -11
  95. package/src/config/skills.ts +9 -2
  96. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
  97. package/src/daemon/conversation-agent-loop.ts +14 -13
  98. package/src/daemon/conversation-notifiers.ts +11 -9
  99. package/src/daemon/conversation-process.ts +0 -27
  100. package/src/daemon/conversation-store.ts +4 -4
  101. package/src/daemon/conversation-surfaces.ts +27 -13
  102. package/src/daemon/conversation-tool-setup.ts +2 -4
  103. package/src/daemon/conversation.ts +81 -44
  104. package/src/daemon/doordash-steps.ts +2 -2
  105. package/src/daemon/lifecycle.ts +14 -1
  106. package/src/daemon/process-message.ts +0 -13
  107. package/src/daemon/windows-compiled-entry.ts +4 -0
  108. package/src/documents/document-store.ts +5 -235
  109. package/src/hooks/types.ts +5 -0
  110. package/src/ipc/gateway-flag-listener.ts +17 -3
  111. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +118 -0
  112. package/src/live-voice/live-voice-manager.ts +16 -3
  113. package/src/live-voice/live-voice-session.ts +63 -9
  114. package/src/live-voice/windows-compiled-live-voice.ts +4 -0
  115. package/src/monitoring/control.ts +1 -0
  116. package/src/monitoring/db-integrity-sample.ts +4 -5
  117. package/src/permissions/prompter.ts +1 -5
  118. package/src/persistence/conversation-queries.ts +66 -16
  119. package/src/persistence/embeddings/qdrant-manager.ts +84 -49
  120. package/src/persistence/migrations/360-add-document-workspace-path.ts +5 -14
  121. package/src/persistence/schema/documents.ts +4 -4
  122. package/src/plugin-api/constants.ts +8 -0
  123. package/src/plugin-api/index.ts +5 -1
  124. package/src/plugin-api/webhook-url.ts +13 -11
  125. package/src/plugins/defaults/main.ts +6 -7
  126. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +77 -0
  127. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +24 -6
  128. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +53 -5
  129. package/src/plugins/defaults/memory/memory-retrospective-job.ts +4 -4
  130. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -0
  131. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +66 -1
  132. package/src/plugins/defaults/memory/v3/injector.ts +8 -0
  133. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +23 -9
  134. package/src/plugins/defaults/memory/worker-control.ts +1 -0
  135. package/src/plugins/defaults/worker-entrypoints.ts +3 -0
  136. package/src/plugins/mtime-cache.ts +17 -0
  137. package/src/prompts/templates/system-sections.ts +0 -7
  138. package/src/providers/__tests__/context-overflow-error.test.ts +24 -0
  139. package/src/providers/__tests__/retry-callsite.test.ts +20 -0
  140. package/src/providers/openai/chat-completions-provider.ts +11 -1
  141. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +11 -6
  142. package/src/providers/speech-to-text/deepgram-flux-realtime.ts +9 -49
  143. package/src/routes/control.ts +1 -0
  144. package/src/routes/route-host-client.ts +1 -0
  145. package/src/runtime/AGENTS.md +16 -17
  146. package/src/runtime/agent-wake.ts +15 -12
  147. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +170 -1
  148. package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +215 -0
  149. package/src/runtime/routes/conversation-list-routes.ts +54 -22
  150. package/src/runtime/routes/conversation-management-routes.ts +2 -3
  151. package/src/runtime/routes/conversation-routes.ts +11 -13
  152. package/src/runtime/routes/documents-routes.ts +3 -222
  153. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +2 -0
  154. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -0
  155. package/src/runtime/routes/playground/inject-failures.ts +2 -2
  156. package/src/runtime/routes/playground/reset-circuit.ts +1 -1
  157. package/src/runtime/routes/schedule-routes.ts +94 -7
  158. package/src/runtime/routes/workspace-routes.ts +0 -9
  159. package/src/runtime/routes/workspace-utils.ts +3 -13
  160. package/src/runtime/services/conversation-serializer.ts +7 -2
  161. package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +68 -5
  162. package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +81 -0
  163. package/src/schedule/plugin-schedule-availability.ts +58 -0
  164. package/src/schedule/plugin-schedule-declarations.ts +23 -27
  165. package/src/schedule/plugin-schedule-reconciler.ts +12 -3
  166. package/src/schedule/schedule-store.ts +5 -1
  167. package/src/schedule/scheduler.ts +9 -4
  168. package/src/schedule/worker-control.ts +1 -0
  169. package/src/subagent/__tests__/consult-prompt.test.ts +26 -15
  170. package/src/subagent/consult-context.ts +11 -11
  171. package/src/subagent/consult-prompt.ts +26 -35
  172. package/src/subagent/manager.ts +20 -37
  173. package/src/subagent/notify.ts +7 -1
  174. package/src/subagent/types.ts +8 -6
  175. package/src/tools/acp/spawn.ts +6 -4
  176. package/src/tools/skills/scaffold-managed.ts +25 -7
  177. package/src/tools/subagent/spawn.ts +28 -88
  178. package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
  179. package/src/util/__tests__/worker-process-command.test.ts +37 -0
  180. package/src/util/logger.ts +16 -0
  181. package/src/util/worker-process.ts +37 -4
  182. package/src/windows-compiled-cli.ts +32 -0
  183. package/src/windows-compiled-entry.ts +4 -0
  184. package/src/windows-compiled-logger.ts +6 -0
  185. package/src/windows-compiled-worker-entry.ts +29 -0
  186. package/src/__tests__/document-workspace-file.test.ts +0 -467
  187. package/src/daemon/interactive-turn-sender.ts +0 -59
  188. package/src/subagent/__tests__/consult-transcript.test.ts +0 -184
  189. package/src/subagent/consult-transcript.ts +0 -90
@@ -1,184 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
-
3
- import type { ContentBlock, Message } from "../../providers/types.js";
4
- import { sanitizeConsultTranscript } from "../consult-transcript.js";
5
-
6
- const text = (t: string): ContentBlock => ({ type: "text", text: t });
7
-
8
- describe("sanitizeConsultTranscript", () => {
9
- test("drops thinking and redacted-thinking blocks", () => {
10
- const messages: Message[] = [
11
- { role: "user", content: [text("do the task")] },
12
- {
13
- role: "assistant",
14
- content: [
15
- { type: "thinking", thinking: "secret", signature: "sig" },
16
- { type: "redacted_thinking", data: "blob" },
17
- text("here is my answer"),
18
- ],
19
- },
20
- ];
21
- const out = sanitizeConsultTranscript(messages);
22
- expect(out).toHaveLength(2);
23
- expect(out[1].content).toEqual([text("here is my answer")]);
24
- });
25
-
26
- test("drops a file block", () => {
27
- const messages: Message[] = [
28
- {
29
- role: "user",
30
- content: [
31
- text("read this"),
32
- {
33
- type: "file",
34
- source: {
35
- type: "base64",
36
- media_type: "application/pdf",
37
- data: "z",
38
- filename: "f.pdf",
39
- },
40
- },
41
- ],
42
- },
43
- ];
44
- const out = sanitizeConsultTranscript(messages);
45
- expect(out[0].content).toEqual([text("read this")]);
46
- });
47
-
48
- test("strips the pending tool_use from the final assistant turn", () => {
49
- const messages: Message[] = [
50
- { role: "user", content: [text("task")] },
51
- {
52
- role: "assistant",
53
- content: [
54
- text("let me consult the advisor"),
55
- { type: "tool_use", id: "t1", name: "advisor", input: {} },
56
- ],
57
- },
58
- ];
59
- const out = sanitizeConsultTranscript(messages);
60
- expect(out[1].content).toEqual([text("let me consult the advisor")]);
61
- });
62
-
63
- test("preserves completed client tool_use / tool_result pairs in earlier turns", () => {
64
- const messages: Message[] = [
65
- { role: "user", content: [text("task")] },
66
- {
67
- role: "assistant",
68
- content: [{ type: "tool_use", id: "a", name: "bash", input: {} }],
69
- },
70
- {
71
- role: "user",
72
- content: [{ type: "tool_result", tool_use_id: "a", content: "output" }],
73
- },
74
- { role: "assistant", content: [text("done")] },
75
- ];
76
- const out = sanitizeConsultTranscript(messages);
77
- expect(out[1].content[0]).toEqual({
78
- type: "tool_use",
79
- id: "a",
80
- name: "bash",
81
- input: {},
82
- });
83
- expect(out[2].content[0]).toEqual({
84
- type: "tool_result",
85
- tool_use_id: "a",
86
- content: "output",
87
- });
88
- });
89
-
90
- test("drops a web-search server_tool_use AND its result together — no orphan", () => {
91
- const messages: Message[] = [
92
- { role: "user", content: [text("look it up")] },
93
- {
94
- role: "assistant",
95
- content: [
96
- text("searching"),
97
- { type: "server_tool_use", id: "ws1", name: "web_search", input: {} },
98
- ],
99
- },
100
- {
101
- role: "user",
102
- content: [
103
- {
104
- type: "web_search_tool_result",
105
- tool_use_id: "ws1",
106
- content: [{ title: "x", url: "y" }],
107
- },
108
- ],
109
- },
110
- { role: "assistant", content: [text("found it; here is the answer")] },
111
- ];
112
- const out = sanitizeConsultTranscript(messages);
113
- const flat = out.flatMap((m) => m.content);
114
- expect(flat.some((b) => b.type === "server_tool_use")).toBe(false);
115
- expect(flat.some((b) => b.type === "web_search_tool_result")).toBe(false);
116
- expect(flat).toContainEqual(text("searching"));
117
- expect(flat).toContainEqual(text("found it; here is the answer"));
118
- });
119
-
120
- test("keeps top-level image blocks", () => {
121
- const img: ContentBlock = {
122
- type: "image",
123
- source: { type: "base64", media_type: "image/png", data: "x" },
124
- };
125
- const messages: Message[] = [
126
- { role: "user", content: [text("look at this"), img] },
127
- ];
128
- const out = sanitizeConsultTranscript(messages);
129
- expect(out[0].content).toEqual([text("look at this"), img]);
130
- });
131
-
132
- test("keeps image contentBlocks on a tool_result, dropping disallowed ones", () => {
133
- const img: ContentBlock = {
134
- type: "image",
135
- source: { type: "base64", media_type: "image/png", data: "x" },
136
- };
137
- const messages: Message[] = [
138
- {
139
- role: "user",
140
- content: [
141
- {
142
- type: "tool_result",
143
- tool_use_id: "a",
144
- content: "screenshot",
145
- contentBlocks: [
146
- img,
147
- {
148
- type: "file",
149
- source: {
150
- type: "base64",
151
- media_type: "application/pdf",
152
- data: "z",
153
- filename: "f.pdf",
154
- },
155
- },
156
- ],
157
- },
158
- ],
159
- },
160
- ];
161
- const out = sanitizeConsultTranscript(messages);
162
- expect(out[0].content[0]).toEqual({
163
- type: "tool_result",
164
- tool_use_id: "a",
165
- content: "screenshot",
166
- contentBlocks: [img],
167
- });
168
- });
169
-
170
- test("drops messages that are empty after sanitization", () => {
171
- const messages: Message[] = [
172
- { role: "user", content: [text("task")] },
173
- {
174
- role: "assistant",
175
- content: [{ type: "thinking", thinking: "secret", signature: "sig" }],
176
- },
177
- { role: "assistant", content: [text("answer")] },
178
- ];
179
- const out = sanitizeConsultTranscript(messages);
180
- expect(out).toHaveLength(2);
181
- expect(out[0].content).toEqual([text("task")]);
182
- expect(out[1].content).toEqual([text("answer")]);
183
- });
184
- });
@@ -1,90 +0,0 @@
1
- /**
2
- * Sanitize an inherited parent transcript before it is injected into a
3
- * advisor consult subagent.
4
- *
5
- * `Conversation.injectInheritedContext` injects the parent's messages VERBATIM
6
- * with no sanitization, so the advisor path must run this over the parent
7
- * messages before they are injected.
8
- *
9
- * Strips blocks the advisor shouldn't (or can't) replay:
10
- * - thinking / redacted-thinking (the advisor tool drops thinking),
11
- * - files,
12
- * - `server_tool_use` AND `web_search_tool_result` — provider-side tool calls
13
- * (e.g. web search) and their results are dropped *together*. Dropping the
14
- * result without its paired `server_tool_use` would leave an orphaned call
15
- * block the provider rejects, so any consult after prior web-search history
16
- * would fail; dropping both keeps the sequence valid.
17
- *
18
- * Images are preserved — top-level and nested inside `tool_result.contentBlocks`
19
- * (which are recursively sanitized) — so the advisor sees what the executor saw.
20
- * Visual tasks depend on it; the advisor profile is expected to be vision-capable.
21
- *
22
- * It also strips the *pending* client tool calls from the final assistant turn:
23
- * at capture time the last assistant message can carry a `tool_use` with no
24
- * matching `tool_result` yet, so sending it would be a dangling call. Earlier,
25
- * completed `tool_use` / `tool_result` pairs are preserved intact.
26
- *
27
- * In-flight-turn parity — ensuring the assistant's just-written plan from the
28
- * current turn is included while its dangling tool_use is stripped — is handled
29
- * by the consumer (the wiring that calls this before injection); this function
30
- * only strips a dangling `tool_use` IF it appears on the final assistant turn.
31
- */
32
-
33
- import type { ContentBlock, Message } from "../providers/types.js";
34
-
35
- /** Drop disallowed blocks; recursively sanitize tool_result content. `null` = drop. */
36
- function sanitize(block: ContentBlock): ContentBlock | null {
37
- switch (block.type) {
38
- case "thinking":
39
- case "redacted_thinking":
40
- case "file":
41
- case "server_tool_use":
42
- case "web_search_tool_result":
43
- return null;
44
- case "tool_result": {
45
- if (!block.contentBlocks) {
46
- return block;
47
- }
48
- // Keep images (and other allowed blocks) nested in the tool result; drop
49
- // the disallowed ones.
50
- const contentBlocks = block.contentBlocks
51
- .map(sanitize)
52
- .filter((b): b is ContentBlock => b !== null);
53
- return {
54
- ...block,
55
- contentBlocks: contentBlocks.length > 0 ? contentBlocks : undefined,
56
- };
57
- }
58
- default:
59
- // text, image, tool_use — kept.
60
- return block;
61
- }
62
- }
63
-
64
- export function sanitizeConsultTranscript(
65
- messages: ReadonlyArray<Message>,
66
- ): Message[] {
67
- const out: Message[] = [];
68
- const lastIndex = messages.length - 1;
69
-
70
- messages.forEach((message, index) => {
71
- let content = message.content
72
- .map(sanitize)
73
- .filter((b): b is ContentBlock => b !== null);
74
-
75
- // The final assistant turn's client tool calls have no results yet — drop
76
- // them so we never send a dangling tool_use. (server_tool_use is already
77
- // dropped above.)
78
- if (index === lastIndex && message.role === "assistant") {
79
- content = content.filter(
80
- (b) => b.type !== "tool_use" && b.type !== "server_tool_use",
81
- );
82
- }
83
-
84
- if (content.length > 0) {
85
- out.push({ role: message.role, content });
86
- }
87
- });
88
-
89
- return out;
90
- }