@vellumai/assistant 0.8.7-dev.202606052232.2ddc989 → 0.8.8
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/bun.lock +2 -2
- package/docs/plugins.md +832 -0
- package/examples/plugins/echo/README.md +60 -61
- package/examples/plugins/echo/package.json +2 -1
- package/examples/plugins/echo/register.ts +143 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -7
- package/openapi.yaml +5 -15
- package/package.json +2 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +56 -3
- package/src/__tests__/anthropic-provider.test.ts +1 -1
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +1 -4
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +405 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +251 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +7 -3
- package/src/__tests__/conversation-agent-loop.test.ts +39 -42
- package/src/__tests__/conversation-clean-command.test.ts +2 -5
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +71 -140
- package/src/__tests__/conversation-runtime-workspace.test.ts +27 -108
- package/src/__tests__/conversation-starter-routes.test.ts +6 -14
- package/src/__tests__/conversation-workspace-cache-state.test.ts +16 -17
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -61
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -7
- package/src/__tests__/db-acp-history.test.ts +0 -101
- package/src/__tests__/dynamic-page-surface.test.ts +0 -31
- package/src/__tests__/file-write-tool.test.ts +0 -63
- package/src/__tests__/gateway-only-guard.test.ts +2 -12
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +4 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -1
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +6 -34
- package/src/__tests__/injector-disk-pressure.test.ts +34 -77
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/list-messages-hidden-metadata.test.ts +0 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/{overflow-reduction-loop.test.ts → overflow-reduce-pipeline.test.ts} +284 -64
- package/src/__tests__/pipeline-runner.test.ts +554 -0
- package/src/__tests__/plugin-api-shim.test.ts +6 -3
- package/src/__tests__/plugin-bootstrap.test.ts +23 -12
- package/src/__tests__/plugin-registry.test.ts +49 -3
- package/src/__tests__/plugin-types.test.ts +70 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +1 -4
- package/src/__tests__/skill-feature-flags-integration.test.ts +0 -33
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-fork-notifications.test.ts +3 -1
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +3 -1
- package/src/__tests__/subagent-notify-parent.test.ts +3 -1
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +286 -54
- package/src/acp/__tests__/client-handler.test.ts +0 -40
- package/src/acp/__tests__/prepare-agent-env.test.ts +0 -137
- package/src/acp/__tests__/session-manager-persistence.test.ts +28 -95
- package/src/acp/agent-process.ts +1 -61
- package/src/acp/client-handler.ts +0 -31
- package/src/acp/prepare-agent-env.ts +29 -83
- package/src/acp/resolve-agent.test.ts +7 -320
- package/src/acp/resolve-agent.ts +18 -182
- package/src/acp/session-manager.ts +73 -495
- package/src/acp/types.ts +0 -8
- package/src/agent/compaction-circuit.ts +102 -60
- package/src/agent/loop.ts +59 -32
- package/src/api/responses/conversation-message.ts +1 -7
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/background-wake/next-wake.ts +0 -1
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +0 -10
- package/src/config/acp-defaults.ts +0 -6
- package/src/config/bundled-skills/acp/SKILL.md +31 -83
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +381 -224
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -29
- package/src/config/bundled-skills/document-editor/SKILL.md +23 -28
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +5 -14
- package/src/config/schemas/heartbeat.ts +0 -9
- package/src/context/strip-injections.ts +2 -8
- package/src/context/window-manager.ts +1 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +11 -0
- package/src/daemon/conversation-agent-loop.ts +279 -62
- package/src/daemon/conversation-runtime-assembly.ts +69 -106
- package/src/daemon/conversation-store.ts +90 -9
- package/src/daemon/conversation-workspace.ts +0 -17
- package/src/daemon/conversation.ts +6 -0
- package/src/daemon/external-plugins-bootstrap.ts +11 -11
- package/src/daemon/handlers/conversations.ts +1 -3
- package/src/daemon/handlers/skills.ts +1 -4
- package/src/daemon/lifecycle.ts +0 -21
- package/src/daemon/server.ts +0 -2
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -3
- package/src/heartbeat/heartbeat-run-store.ts +1 -23
- package/src/heartbeat/heartbeat-service.ts +0 -26
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -15
- package/src/ipc/skill-routes/memory.ts +2 -4
- package/src/memory/conversation-starter-checkpoints.ts +0 -1
- package/src/memory/db-init.ts +0 -2
- package/src/memory/job-handlers/conversation-starters.ts +2 -13
- package/src/memory/jobs-worker.ts +1 -1
- package/src/memory/migrations/index.ts +0 -1
- package/src/memory/schema/acp.ts +0 -4
- package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
- package/src/memory/v2/consolidation-job.ts +4 -13
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/assign.test.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/live-integration.test.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/maintain-job.test.ts +5 -5
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/orchestrate.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/reconcile.test.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/render-injection.test.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/router.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selector.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/shadow-plugin.test.ts +12 -12
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/assign.ts +5 -5
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/capabilities.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/maintain-job.ts +8 -8
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/page-content.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/provider-blocks.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/reconcile.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/render-injection.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/router.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selection-log-store.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selector.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/shadow-plugin.ts +90 -28
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/tree.ts +1 -1
- package/src/plugin-api/index.ts +5 -0
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/{memory-v3-shadow → circuit-breaker}/package.json +2 -2
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +19 -8
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/index.ts +5 -3
- package/src/plugins/defaults/{memory-retrieval/injectors.ts → injectors/register.ts} +7 -45
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +7 -11
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +126 -0
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +293 -6
- package/src/plugins/registry.ts +37 -9
- package/src/plugins/types.ts +336 -32
- package/src/plugins/user-loader.ts +127 -30
- package/src/proactive-artifact/aux-message-injector.ts +1 -1
- package/src/proactive-artifact/job.test.ts +1 -1
- package/src/prompts/__tests__/system-prompt.test.ts +0 -6
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +2 -4
- package/src/runtime/__tests__/agent-wake.test.ts +5 -5
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +3 -0
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +55 -283
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +4 -5
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -4
- package/src/runtime/routes/acp-routes.test.ts +25 -89
- package/src/runtime/routes/acp-routes.ts +29 -81
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +10 -6
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +2 -15
- package/src/runtime/routes/conversation-starter-routes.ts +7 -13
- package/src/runtime/routes/conversations-import-routes.ts +7 -24
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +3 -18
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/memory-v3-routes.ts +6 -16
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -4
- package/src/runtime/routes/work-items-routes.ts +4 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/signals/cancel.ts +4 -2
- package/src/subagent/manager.ts +5 -17
- package/src/tools/acp/list-agents.test.ts +1 -7
- package/src/tools/acp/spawn.test.ts +55 -158
- package/src/tools/acp/spawn.ts +72 -47
- package/src/tools/acp/steer.test.ts +8 -105
- package/src/tools/acp/steer.ts +17 -48
- package/src/tools/apps/executors.ts +8 -13
- package/src/tools/filesystem/write.ts +0 -34
- package/src/tools/subagent/spawn.ts +4 -2
- package/src/tools/ui-surface/definitions.ts +4 -25
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +5 -4
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +45 -69
- package/examples/plugins/echo/hooks/post-tool-use.ts +0 -18
- package/examples/plugins/echo/hooks/stop.ts +0 -16
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +0 -18
- package/examples/plugins/echo/src/emit.ts +0 -19
- package/src/__tests__/compaction-circuit.test.ts +0 -258
- package/src/__tests__/compaction-direct.test.ts +0 -132
- package/src/__tests__/conversations-import-system-filter.test.ts +0 -101
- package/src/acp/__tests__/agent-process.test.ts +0 -161
- package/src/acp/__tests__/helpers/acp-history-db.ts +0 -82
- package/src/acp/__tests__/helpers/exec-file-stub.ts +0 -101
- package/src/acp/__tests__/session-manager-resume.test.ts +0 -736
- package/src/acp/auto-install.test.ts +0 -196
- package/src/acp/auto-install.ts +0 -177
- package/src/acp/feature-gate.test.ts +0 -48
- package/src/acp/feature-gate.ts +0 -34
- package/src/acp/resume-hint.ts +0 -25
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +0 -48
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +0 -57
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +0 -38
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -62
- package/src/daemon/conversation-registry.ts +0 -159
- package/src/daemon/overflow-reduction-loop.ts +0 -230
- package/src/memory/migrations/272-acp-session-history-cwd.ts +0 -36
- package/src/plugins/defaults/compaction/compact.ts +0 -59
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +0 -14
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +0 -19
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +0 -75
- package/src/plugins/defaults/memory-v3-shadow/register.ts +0 -26
- package/src/tools/acp/context.ts +0 -20
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/capabilities.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/core.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/health.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/needle.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/provider-blocks.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/snapshot.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/tree.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/types.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/core.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/README.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/assignments.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/core.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/health.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/llm-retry.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/needle.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/orchestrate.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/snapshot.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/types.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/working-set.ts +0 -0
|
@@ -2,19 +2,26 @@
|
|
|
2
2
|
* Tests for the plugin registry (PR 13).
|
|
3
3
|
*
|
|
4
4
|
* Covers successful registration, required-field and duplicate-name
|
|
5
|
-
* validation, capability-version negotiation error messaging,
|
|
6
|
-
*
|
|
5
|
+
* validation, capability-version negotiation error messaging, injector
|
|
6
|
+
* ordering, and middleware collection order.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
closeRegistration,
|
|
13
|
+
getMiddlewaresFor,
|
|
13
14
|
getRegisteredPlugins,
|
|
14
15
|
registerPlugin,
|
|
15
16
|
resetPluginRegistryForTests,
|
|
16
17
|
} from "../plugins/registry.js";
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
type CompactionArgs,
|
|
20
|
+
type CompactionResult,
|
|
21
|
+
type Middleware,
|
|
22
|
+
type Plugin,
|
|
23
|
+
PluginExecutionError,
|
|
24
|
+
} from "../plugins/types.js";
|
|
18
25
|
|
|
19
26
|
/** Build a minimal, valid plugin with the given name and optional extras. */
|
|
20
27
|
function buildPlugin(
|
|
@@ -140,6 +147,45 @@ describe("plugin registry", () => {
|
|
|
140
147
|
expect(() => registerPlugin(bad)).toThrow(/manifest\.version is required/);
|
|
141
148
|
});
|
|
142
149
|
|
|
150
|
+
test("getMiddlewaresFor returns middleware in registration order", () => {
|
|
151
|
+
const firstMw: Middleware<CompactionArgs, CompactionResult> = async (
|
|
152
|
+
args,
|
|
153
|
+
next,
|
|
154
|
+
) => next(args);
|
|
155
|
+
const secondMw: Middleware<CompactionArgs, CompactionResult> = async (
|
|
156
|
+
args,
|
|
157
|
+
next,
|
|
158
|
+
) => next(args);
|
|
159
|
+
|
|
160
|
+
registerPlugin(
|
|
161
|
+
buildPlugin("plugin-first", { middleware: { compaction: firstMw } }),
|
|
162
|
+
);
|
|
163
|
+
registerPlugin(
|
|
164
|
+
buildPlugin("plugin-second", { middleware: { compaction: secondMw } }),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const middlewares = getMiddlewaresFor("compaction");
|
|
168
|
+
expect(middlewares).toHaveLength(2);
|
|
169
|
+
// Identity comparison proves the middleware instances come back in
|
|
170
|
+
// registration order — outer→inner composition semantics belong to the
|
|
171
|
+
// pipeline runner (PR 12), not the registry.
|
|
172
|
+
expect(middlewares[0]).toBe(firstMw);
|
|
173
|
+
expect(middlewares[1]).toBe(secondMw);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("getMiddlewaresFor skips plugins without a middleware for the pipeline", () => {
|
|
177
|
+
const mw: Middleware<CompactionArgs, CompactionResult> = async (
|
|
178
|
+
args,
|
|
179
|
+
next,
|
|
180
|
+
) => next(args);
|
|
181
|
+
registerPlugin(buildPlugin("bare"));
|
|
182
|
+
registerPlugin(buildPlugin("has-mw", { middleware: { compaction: mw } }));
|
|
183
|
+
|
|
184
|
+
const middlewares = getMiddlewaresFor("compaction");
|
|
185
|
+
expect(middlewares).toHaveLength(1);
|
|
186
|
+
expect(middlewares[0]).toBe(mw);
|
|
187
|
+
});
|
|
188
|
+
|
|
143
189
|
test("getRegisteredPlugins reflects registration order", () => {
|
|
144
190
|
registerPlugin(buildPlugin("one"));
|
|
145
191
|
registerPlugin(buildPlugin("two"));
|
|
@@ -13,10 +13,18 @@ import { describe, expect, test } from "bun:test";
|
|
|
13
13
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
14
14
|
import { RiskLevel } from "../permissions/types.js";
|
|
15
15
|
import {
|
|
16
|
+
type CircuitBreakerArgs,
|
|
17
|
+
type CircuitBreakerResult,
|
|
18
|
+
type CompactionArgs,
|
|
19
|
+
type CompactionResult,
|
|
20
|
+
type Middleware,
|
|
21
|
+
type OverflowReduceArgs,
|
|
22
|
+
type OverflowReduceResult,
|
|
16
23
|
type Plugin,
|
|
17
24
|
PluginExecutionError,
|
|
18
25
|
type PluginInitContext,
|
|
19
26
|
type PluginManifest,
|
|
27
|
+
PluginTimeoutError,
|
|
20
28
|
type TurnContext,
|
|
21
29
|
} from "../plugins/types.js";
|
|
22
30
|
import type { Tool } from "../tools/types.js";
|
|
@@ -30,6 +38,7 @@ const sampleTurnContext: TurnContext = {
|
|
|
30
38
|
requestId: "req-abc",
|
|
31
39
|
conversationId: "conv-xyz",
|
|
32
40
|
turnIndex: 0,
|
|
41
|
+
pluginName: "sample-plugin",
|
|
33
42
|
trust: sampleTrust,
|
|
34
43
|
};
|
|
35
44
|
|
|
@@ -43,6 +52,43 @@ describe("plugin core types", () => {
|
|
|
43
52
|
config: { parse: (input: unknown) => input },
|
|
44
53
|
};
|
|
45
54
|
|
|
55
|
+
// `overflowReduce` has a concrete arg/result shape (PR 23). Uses a
|
|
56
|
+
// dedicated passthrough that returns a structurally-correct result so
|
|
57
|
+
// `satisfies Plugin` keeps verifying the signature.
|
|
58
|
+
const overflowReducePassthrough: Middleware<
|
|
59
|
+
OverflowReduceArgs,
|
|
60
|
+
OverflowReduceResult
|
|
61
|
+
> = async (args, _next, _ctx) => ({
|
|
62
|
+
messages: args.messages,
|
|
63
|
+
runMessages: args.runMessages,
|
|
64
|
+
injectionMode: "full",
|
|
65
|
+
reducerState: {
|
|
66
|
+
appliedTiers: [],
|
|
67
|
+
injectionMode: "full",
|
|
68
|
+
exhausted: true,
|
|
69
|
+
},
|
|
70
|
+
reducerCompacted: false,
|
|
71
|
+
attempts: 0,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Slot-specific passthrough for the `compaction` pipeline — PR 25
|
|
75
|
+
// narrowed its args/result away from the generic `{ input: unknown }`
|
|
76
|
+
// placeholder, so the generic `passthrough` no longer satisfies its
|
|
77
|
+
// middleware signature. This dedicated middleware keeps the shape-only
|
|
78
|
+
// assertion for the slot without forcing every other slot to narrow.
|
|
79
|
+
const compactionPassthrough: Middleware<
|
|
80
|
+
CompactionArgs,
|
|
81
|
+
CompactionResult
|
|
82
|
+
> = async (args, next, _ctx) => next(args);
|
|
83
|
+
|
|
84
|
+
// `circuitBreaker` carries a concrete arg shape (pipeline wrapping
|
|
85
|
+
// landed ahead of the other slots) so it needs its own passthrough
|
|
86
|
+
// rather than reusing the generic placeholder.
|
|
87
|
+
const circuitPassthrough: Middleware<
|
|
88
|
+
CircuitBreakerArgs,
|
|
89
|
+
CircuitBreakerResult
|
|
90
|
+
> = async (args, next, _ctx) => next(args);
|
|
91
|
+
|
|
46
92
|
const sampleTool: Tool = {
|
|
47
93
|
name: "sample-tool",
|
|
48
94
|
description: "Sample plugin tool",
|
|
@@ -86,10 +132,34 @@ describe("plugin core types", () => {
|
|
|
86
132
|
body: "## Sample\n\nPlugin-provided skill body.",
|
|
87
133
|
},
|
|
88
134
|
],
|
|
135
|
+
middleware: {
|
|
136
|
+
compaction: compactionPassthrough,
|
|
137
|
+
overflowReduce: overflowReducePassthrough,
|
|
138
|
+
circuitBreaker: circuitPassthrough,
|
|
139
|
+
},
|
|
89
140
|
} satisfies Plugin;
|
|
90
141
|
|
|
91
142
|
// Minimal runtime check so the test body is non-empty.
|
|
92
143
|
expect(plugin.manifest.name).toBe("sample-plugin");
|
|
144
|
+
expect(plugin.middleware.compaction).toBe(compactionPassthrough);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("PluginTimeoutError carries pipeline, plugin, and elapsed fields", () => {
|
|
148
|
+
const err = new PluginTimeoutError("compaction", "sample-plugin", 30000);
|
|
149
|
+
expect(err).toBeInstanceOf(Error);
|
|
150
|
+
expect(err.name).toBe("PluginTimeoutError");
|
|
151
|
+
expect(err.pipeline).toBe("compaction");
|
|
152
|
+
expect(err.pluginName).toBe("sample-plugin");
|
|
153
|
+
expect(err.elapsedMs).toBe(30000);
|
|
154
|
+
expect(err.message).toContain("compaction");
|
|
155
|
+
expect(err.message).toContain("30000");
|
|
156
|
+
expect(err.message).toContain("sample-plugin");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("PluginTimeoutError omits plugin suffix when unknown", () => {
|
|
160
|
+
const err = new PluginTimeoutError("circuitBreaker", undefined, 1234);
|
|
161
|
+
expect(err.pluginName).toBeUndefined();
|
|
162
|
+
expect(err.message).not.toContain("offending plugin");
|
|
93
163
|
});
|
|
94
164
|
|
|
95
165
|
test("PluginExecutionError carries the plugin name and message", () => {
|
|
@@ -27,7 +27,7 @@ mock.module("../config/env.js", () => ({
|
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
29
|
const _conversationMocks = new Map<string, unknown>();
|
|
30
|
-
mock.module("../daemon/conversation-
|
|
30
|
+
mock.module("../daemon/conversation-store.js", () => ({
|
|
31
31
|
findConversation: (id: string) => _conversationMocks.get(id),
|
|
32
32
|
}));
|
|
33
33
|
|
|
@@ -91,14 +91,11 @@ mock.module("../config/loader.js", () => ({
|
|
|
91
91
|
let _conversationFactory: (() => Conversation) | undefined;
|
|
92
92
|
let _approvalGenerator: unknown;
|
|
93
93
|
|
|
94
|
-
mock.module("../daemon/conversation-
|
|
94
|
+
mock.module("../daemon/conversation-store.js", () => ({
|
|
95
95
|
findConversation: () => {
|
|
96
96
|
if (!_conversationFactory) return undefined;
|
|
97
97
|
return _conversationFactory();
|
|
98
98
|
},
|
|
99
|
-
}));
|
|
100
|
-
|
|
101
|
-
mock.module("../daemon/conversation-store.js", () => ({
|
|
102
99
|
getOrCreateConversation: async (..._args: unknown[]) => {
|
|
103
100
|
if (!_conversationFactory)
|
|
104
101
|
throw new Error("_conversationFactory not set in test");
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* parses it via the real frontmatter parser, and verifies that `skillFlagKey()`
|
|
6
6
|
* returns the correct key and `resolveSkillStates()` correctly gates the skill.
|
|
7
7
|
*/
|
|
8
|
-
import { readFileSync } from "node:fs";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
8
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
11
9
|
|
|
12
10
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
@@ -227,34 +225,3 @@ describe("frontmatter feature-flag integration", () => {
|
|
|
227
225
|
expect(resolvedOff.length).toBe(0);
|
|
228
226
|
});
|
|
229
227
|
});
|
|
230
|
-
|
|
231
|
-
// ---------------------------------------------------------------------------
|
|
232
|
-
// Bundled ACP skill: discoverability when ACP is disabled
|
|
233
|
-
// ---------------------------------------------------------------------------
|
|
234
|
-
|
|
235
|
-
describe("bundled acp skill discoverability", () => {
|
|
236
|
-
test("acp skill resolves with the flag off and config.acp disabled (no frontmatter flag gate)", () => {
|
|
237
|
-
// The ACP skill carries its own first-time-setup instructions, so it must
|
|
238
|
-
// stay visible even when the acp flag and config.acp.enabled are both off.
|
|
239
|
-
// Runtime enforcement happens in the ACP tools via isAcpEnabled instead.
|
|
240
|
-
const skillMdPath = fileURLToPath(
|
|
241
|
-
new URL("../config/bundled-skills/acp/SKILL.md", import.meta.url),
|
|
242
|
-
);
|
|
243
|
-
const skillMd = readFileSync(skillMdPath, "utf8");
|
|
244
|
-
|
|
245
|
-
const skill = buildSkillSummary("acp", skillMd);
|
|
246
|
-
expect(skill).not.toBeNull();
|
|
247
|
-
expect(skill!.featureFlag).toBeUndefined();
|
|
248
|
-
expect(skillFlagKey(skill!)).toBeUndefined();
|
|
249
|
-
|
|
250
|
-
// acp flag at its registry default (off) and config.acp disabled.
|
|
251
|
-
const config = makeConfig({
|
|
252
|
-
acp: { enabled: false, maxConcurrentSessions: 4, agents: {} },
|
|
253
|
-
} as Partial<AssistantConfig>);
|
|
254
|
-
|
|
255
|
-
const resolved = resolveSkillStates([skill!], config);
|
|
256
|
-
expect(resolved.length).toBe(1);
|
|
257
|
-
expect(resolved[0].summary.id).toBe("acp");
|
|
258
|
-
expect(resolved[0].state).toBe("enabled");
|
|
259
|
-
});
|
|
260
|
-
});
|
|
@@ -174,7 +174,7 @@ import { LLMSchema } from "../config/schemas/llm.js";
|
|
|
174
174
|
import {
|
|
175
175
|
clearConversations,
|
|
176
176
|
setConversation,
|
|
177
|
-
} from "../daemon/conversation-
|
|
177
|
+
} from "../daemon/conversation-store.js";
|
|
178
178
|
import { CallSiteRoutingProvider } from "../providers/call-site-routing.js";
|
|
179
179
|
import { SubagentManager } from "../subagent/manager.js";
|
|
180
180
|
|
|
@@ -11,7 +11,7 @@ const capturedNotifications: {
|
|
|
11
11
|
message: string;
|
|
12
12
|
}[] = [];
|
|
13
13
|
|
|
14
|
-
mock.module("../daemon/conversation-
|
|
14
|
+
mock.module("../daemon/conversation-store.js", () => ({
|
|
15
15
|
findConversation: (id: string) => ({
|
|
16
16
|
enqueueMessage: (options: { content: string }) => {
|
|
17
17
|
capturedNotifications.push({
|
|
@@ -23,6 +23,8 @@ mock.module("../daemon/conversation-registry.js", () => ({
|
|
|
23
23
|
persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
|
|
24
24
|
runAgentLoop: async () => {},
|
|
25
25
|
}),
|
|
26
|
+
addConversation: () => {},
|
|
27
|
+
removeConversation: () => {},
|
|
26
28
|
}));
|
|
27
29
|
|
|
28
30
|
mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
clearConversations,
|
|
5
5
|
findConversation,
|
|
6
6
|
setConversation,
|
|
7
|
-
} from "../daemon/conversation-
|
|
7
|
+
} from "../daemon/conversation-store.js";
|
|
8
8
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
9
9
|
import type { Message } from "../providers/types.js";
|
|
10
10
|
import { SubagentManager } from "../subagent/manager.js";
|
|
@@ -11,7 +11,7 @@ const capturedNotifications: {
|
|
|
11
11
|
message: string;
|
|
12
12
|
}[] = [];
|
|
13
13
|
|
|
14
|
-
mock.module("../daemon/conversation-
|
|
14
|
+
mock.module("../daemon/conversation-store.js", () => ({
|
|
15
15
|
findConversation: (id: string) => ({
|
|
16
16
|
enqueueMessage: (options: { content: string }) => {
|
|
17
17
|
capturedNotifications.push({
|
|
@@ -23,6 +23,8 @@ mock.module("../daemon/conversation-registry.js", () => ({
|
|
|
23
23
|
persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
|
|
24
24
|
runAgentLoop: async () => {},
|
|
25
25
|
}),
|
|
26
|
+
addConversation: () => {},
|
|
27
|
+
removeConversation: () => {},
|
|
26
28
|
}));
|
|
27
29
|
|
|
28
30
|
mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
@@ -36,7 +36,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
36
36
|
*/
|
|
37
37
|
const capturedMessages: string[] = [];
|
|
38
38
|
|
|
39
|
-
mock.module("../daemon/conversation-
|
|
39
|
+
mock.module("../daemon/conversation-store.js", () => ({
|
|
40
40
|
findConversation: (_id: string) => ({
|
|
41
41
|
enqueueMessage: (options: { content: string }) => {
|
|
42
42
|
capturedMessages.push(options.content);
|
|
@@ -45,6 +45,8 @@ mock.module("../daemon/conversation-registry.js", () => ({
|
|
|
45
45
|
persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
|
|
46
46
|
runAgentLoop: async () => {},
|
|
47
47
|
}),
|
|
48
|
+
addConversation: () => {},
|
|
49
|
+
removeConversation: () => {},
|
|
48
50
|
}));
|
|
49
51
|
|
|
50
52
|
mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
@@ -32,7 +32,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
32
32
|
import {
|
|
33
33
|
clearConversations,
|
|
34
34
|
setConversation,
|
|
35
|
-
} from "../daemon/conversation-
|
|
35
|
+
} from "../daemon/conversation-store.js";
|
|
36
36
|
import type { Message } from "../providers/types.js";
|
|
37
37
|
import { getSubagentManager } from "../subagent/index.js";
|
|
38
38
|
import { executeSubagentSpawn } from "../tools/subagent/spawn.js";
|