@vellumai/assistant 0.12.4 → 0.12.5-dev.202609251017.e467a6c
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/docs/architecture/memory.md +9 -1
- package/docs/architecture/scheduling.md +13 -5
- package/docs/desktop-browser-cli.md +3 -2
- package/docs/guardian-request-flow.md +1 -1
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/notification-avatar.test.ts +48 -4
- package/node_modules/@vellumai/avatar-manifest/src/notification-avatar.ts +12 -8
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/guardian-requests.test.ts +26 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +77 -3
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/guardian-requests.test.ts +26 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +77 -3
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +2 -4
- package/node_modules/@vellumai/service-contracts/src/__tests__/guardian-requests.test.ts +26 -0
- package/node_modules/@vellumai/service-contracts/src/guardian-requests.ts +77 -3
- package/openapi.yaml +152 -3
- package/package.json +1 -1
- package/src/__tests__/agent-loop.test.ts +76 -0
- package/src/__tests__/anthropic-error-formatting.test.ts +9 -0
- package/src/__tests__/background-shell-bash.test.ts +34 -0
- package/src/__tests__/background-shell-host-bash.test.ts +98 -1
- package/src/__tests__/background-tool-registry.test.ts +39 -0
- package/src/__tests__/channel-readiness-discord.test.ts +8 -0
- package/src/__tests__/channel-readiness-slack-remote.test.ts +8 -0
- package/src/__tests__/client-os-metadata-persistence.test.ts +4 -20
- package/src/__tests__/conversation-agent-loop.test.ts +529 -1
- package/src/__tests__/conversation-error.test.ts +18 -0
- package/src/__tests__/conversation-pairing.test.ts +69 -0
- package/src/__tests__/conversation-queue.test.ts +257 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +27 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +62 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +21 -0
- package/src/__tests__/gemini-provider.test.ts +9 -0
- package/src/__tests__/host-cu-proxy.test.ts +79 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +14 -5
- package/src/__tests__/introduction-card-resolver.test.ts +53 -8
- package/src/__tests__/job-handler-registration-guard.test.ts +1 -0
- package/src/__tests__/non-member-access-request.test.ts +48 -0
- package/src/__tests__/notification-events-source-context-probe.test.ts +48 -1
- package/src/__tests__/notification-platform-adapter.test.ts +97 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +103 -3
- package/src/__tests__/platform-callback-registration.test.ts +46 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +3 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +116 -66
- package/src/__tests__/scheduler-disk-pressure.test.ts +1 -0
- package/src/__tests__/scheduler-result-notification.test.ts +521 -7
- package/src/__tests__/scheduler-wake.test.ts +1 -0
- package/src/__tests__/skill-load-inline-command.test.ts +35 -0
- package/src/__tests__/subagent-cron-run-attribution.test.ts +41 -2
- package/src/__tests__/subagent-manager-notify.test.ts +48 -0
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +6 -6
- package/src/__tests__/usage-attribution.test.ts +31 -0
- package/src/__tests__/wake-schedule-escalation.test.ts +1 -0
- package/src/agent/loop.ts +23 -0
- package/src/api/ask-question-tool.ts +50 -0
- package/src/api/events/generation-handoff.ts +4 -0
- package/src/api/events/message-complete.ts +4 -0
- package/src/api/events/tool-result.ts +11 -0
- package/src/api/index.ts +11 -0
- package/src/api/requests/guardian-actions.test.ts +45 -0
- package/src/api/requests/guardian-actions.ts +20 -0
- package/src/api/responses/conversation-message.ts +4 -0
- package/src/api/responses/home.ts +27 -0
- package/src/approvals/guardian-decision-primitive.ts +6 -4
- package/src/approvals/guardian-request-resolvers.ts +35 -30
- package/src/avatar/notification-avatar.test.ts +42 -34
- package/src/avatar/notification-avatar.ts +1 -0
- package/src/calls/__tests__/call-controller.test.ts +18 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +6 -1
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +70 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +116 -4
- package/src/calls/__tests__/voice-triage-escalate.test.ts +77 -11
- package/src/calls/call-controller.ts +3 -1
- package/src/calls/voice-control-protocol.ts +12 -4
- package/src/calls/voice-escalation-judge.ts +2 -2
- package/src/calls/voice-leg-coordinator.ts +23 -5
- package/src/calls/voice-screen-annotation.ts +44 -0
- package/src/calls/voice-session-bridge.ts +63 -20
- package/src/calls/voice-triage-escalate.ts +82 -27
- package/src/cli/commands/__tests__/conversations-clear.test.ts +156 -0
- package/src/cli/commands/conversations.help.ts +7 -2
- package/src/cli/commands/conversations.ts +36 -30
- package/src/cli/commands/oauth/index.help.ts +8 -2
- package/src/cli/commands/oauth/request.test.ts +32 -0
- package/src/cli/commands/platform/index.help.ts +2 -1
- package/src/cli/commands/platform/index.ts +8 -2
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +60 -0
- package/src/cli/lib/__tests__/plugin-catalog-platform.test.ts +66 -2
- package/src/cli/lib/bundled-marketplace.json +35 -0
- package/src/cli/lib/bundled-plugin-packages.json +21 -0
- package/src/cli/lib/plugin-catalog-cache.ts +17 -2
- package/src/cli/lib/plugin-catalog-platform.ts +48 -9
- package/src/config/__tests__/default-profile-catalog.test.ts +28 -0
- package/src/config/__tests__/platform-identity.test.ts +59 -0
- package/src/config/__tests__/profile-order.test.ts +19 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +71 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +20 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +11 -11
- package/src/config/bundled-skills/screen-annotation/SKILL.md +41 -29
- package/src/config/bundled-skills/screen-annotation/TOOLS.json +5 -5
- package/src/config/call-site-defaults.ts +6 -0
- package/src/config/default-profile-catalog.ts +30 -1
- package/src/config/default-profile-names.ts +36 -2
- package/src/config/feature-flag-registry.json +9 -1
- package/src/config/platform-identity.ts +22 -5
- package/src/config/profile-order.ts +7 -1
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/llm.ts +21 -5
- package/src/config/sync-gated-profiles.ts +96 -44
- package/src/daemon/__tests__/abort-null-controller.test.ts +135 -1
- package/src/daemon/__tests__/auto-profile-router.test.ts +380 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +16 -0
- package/src/daemon/activity-trail.test.ts +206 -0
- package/src/daemon/activity-trail.ts +190 -0
- package/src/daemon/auto-profile-router.ts +431 -0
- package/src/daemon/computer-use-observation.test.ts +81 -0
- package/src/daemon/computer-use-observation.ts +23 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +11 -0
- package/src/daemon/conversation-agent-loop.ts +157 -32
- package/src/daemon/conversation-error.ts +19 -0
- package/src/daemon/conversation-lifecycle.ts +70 -7
- package/src/daemon/conversation-media-retry.ts +1 -2
- package/src/daemon/conversation-messaging.ts +31 -2
- package/src/daemon/conversation-process.ts +107 -16
- package/src/daemon/conversation-queue-manager.ts +7 -0
- package/src/daemon/conversation-runtime-assembly.ts +1 -0
- package/src/daemon/conversation-turn-finalize.ts +14 -0
- package/src/daemon/conversation.ts +25 -6
- package/src/daemon/event-loop-watchdog.test.ts +201 -2
- package/src/daemon/event-loop-watchdog.ts +182 -6
- package/src/daemon/host-cu-proxy.ts +34 -3
- package/src/daemon/pkb-reminder-builder.test.ts +10 -3
- package/src/daemon/pkb-reminder-builder.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -2
- package/src/desktop/desktop-computer-use.test.ts +14 -4
- package/src/home/feed-types.ts +2 -0
- package/src/inbound/platform-callback-registration.ts +19 -6
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +27 -0
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +83 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +48 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +34 -2
- package/src/live-voice/__tests__/protocol.test.ts +22 -0
- package/src/live-voice/continuation-judge.ts +1 -1
- package/src/live-voice/live-voice-session.ts +25 -19
- package/src/live-voice/protocol.ts +16 -5
- package/src/messaging/providers/discord/withdraw.ts +4 -5
- package/src/messaging/providers/gmail/client.ts +4 -0
- package/src/messaging/providers/slack/withdraw.ts +5 -5
- package/src/messaging/providers/telegram-bot/withdraw.ts +4 -5
- package/src/monitoring/__tests__/proc-fixtures.ts +28 -0
- package/src/monitoring/__tests__/proc-wait-state.test.ts +232 -0
- package/src/monitoring/__tests__/process-usage.test.ts +243 -0
- package/src/monitoring/proc-wait-state.ts +366 -0
- package/src/monitoring/process-memory.ts +4 -3
- package/src/monitoring/process-usage.ts +215 -0
- package/src/monitoring/resource-sample-types.ts +8 -0
- package/src/monitoring/resource-sampler.ts +17 -2
- package/src/monitoring/stall-capture.ts +12 -0
- package/src/notifications/README.md +88 -9
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +390 -119
- package/src/notifications/__tests__/background-result-producer.test.ts +1272 -0
- package/src/notifications/__tests__/broadcaster.test.ts +292 -1
- package/src/notifications/__tests__/completion-policy.test.ts +243 -0
- package/src/notifications/__tests__/decision-engine.test.ts +51 -4
- package/src/notifications/__tests__/has-pending-background-work.test.ts +281 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +161 -3
- package/src/notifications/__tests__/resolve-visible-in-source.test.ts +110 -1
- package/src/notifications/__tests__/schedule-result-producer.test.ts +11 -4
- package/src/notifications/adapters/macos.ts +24 -12
- package/src/notifications/adapters/platform.ts +16 -5
- package/src/notifications/assistant-reply-producer.ts +96 -71
- package/src/notifications/background-result-producer.ts +369 -0
- package/src/notifications/broadcaster.ts +28 -8
- package/src/notifications/completion-policy.ts +115 -0
- package/src/notifications/completion-work.ts +46 -0
- package/src/notifications/conversation-pairing.ts +32 -13
- package/src/notifications/decision-engine.ts +18 -24
- package/src/notifications/emit-signal.ts +16 -1
- package/src/notifications/events-store.ts +4 -0
- package/src/notifications/has-pending-background-work.ts +91 -0
- package/src/notifications/home-feed-mirror.ts +44 -0
- package/src/notifications/home-feed-side-effect.ts +54 -28
- package/src/notifications/resolve-visible-in-source.ts +56 -2
- package/src/notifications/result-output.ts +154 -0
- package/src/notifications/schedule-result-producer.ts +6 -187
- package/src/notifications/types.ts +2 -0
- package/src/oauth/AGENTS.md +9 -1
- package/src/oauth/byo-connection.test.ts +28 -0
- package/src/persistence/__tests__/recent-conversation-messages.test.ts +41 -0
- package/src/persistence/conversation-crud.ts +26 -0
- package/src/persistence/conversation-types.ts +15 -37
- package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +85 -14
- package/src/persistence/jobs-store.ts +229 -0
- package/src/persistence/migrations/383-normalize-opencode-host-connections.ts +44 -0
- package/src/persistence/migrations/__tests__/383-normalize-opencode-host-connections.test.ts +102 -0
- package/src/persistence/steps.ts +12 -0
- package/src/platform/sync-avatar.test.ts +29 -0
- package/src/plugins/defaults/memory/AGENTS.md +5 -3
- package/src/plugins/defaults/memory/__tests__/skill-update-receipt-boundary-guard.test.ts +45 -0
- package/src/plugins/defaults/memory/__tests__/skill-update-receipt-job.test.ts +580 -0
- package/src/plugins/defaults/memory/__tests__/turn-retrieval.test.ts +21 -0
- package/src/plugins/defaults/memory/graph/tools.ts +9 -5
- package/src/plugins/defaults/memory/hooks/conversation-deleted.ts +4 -0
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +7 -3
- package/src/plugins/defaults/memory/job-handlers.ts +8 -2
- package/src/plugins/defaults/memory/skill-update-receipt-job.ts +334 -0
- package/src/plugins/defaults/memory/tools.test.ts +17 -0
- package/src/plugins/defaults/memory/turn-retrieval.ts +8 -0
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +24 -0
- package/src/plugins/defaults/memory/v3/injector.ts +4 -4
- package/src/plugins/types.ts +2 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +8 -0
- package/src/providers/anthropic/client.ts +4 -0
- package/src/providers/gemini/client.ts +7 -1
- package/src/providers/inference/auth.ts +25 -0
- package/src/providers/inference/profile-probe.ts +1 -0
- package/src/{calls/__tests__/typesafe-noul.test.ts → providers/jev/ask.test.ts} +4 -4
- package/src/{calls/typesafe-noul.ts → providers/jev/ask.ts} +67 -34
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +12 -0
- package/src/providers/openai/api-error-normalization.ts +4 -0
- package/src/providers/retry.ts +2 -0
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/types.ts +7 -0
- package/src/providers/usage-tracking.ts +5 -3
- package/src/runtime/__tests__/agent-wake.test.ts +308 -0
- package/src/runtime/access-request-helper.ts +16 -9
- package/src/runtime/agent-wake-queue.ts +52 -0
- package/src/runtime/agent-wake.ts +111 -18
- package/src/runtime/channel-approval-types.ts +6 -38
- package/src/runtime/channel-approvals.ts +4 -5
- package/src/runtime/http-server.ts +4 -1
- package/src/runtime/introduction-policy.test.ts +17 -1
- package/src/runtime/introduction-policy.ts +25 -7
- package/src/runtime/migrations/vbundle-builder.ts +9 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +21 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +60 -0
- package/src/runtime/routes/__tests__/oauth-proxy-routes.test.ts +61 -3
- package/src/runtime/routes/auto-profile-routes.ts +83 -0
- package/src/runtime/routes/conversation-management-routes.ts +1 -3
- package/src/runtime/routes/conversation-routes.ts +9 -0
- package/src/runtime/routes/guardian-action-routes.ts +8 -23
- package/src/runtime/routes/host-cu-routes.ts +3 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profiles-routes.ts +5 -2
- package/src/runtime/routes/inference-provider-connection-routes.ts +25 -8
- package/src/runtime/routes/migration-routes.ts +8 -2
- package/src/runtime/routes/oauth-proxy-passthrough.test.ts +32 -0
- package/src/runtime/routes/platform-routes.ts +6 -1
- package/src/runtime/routes/user-route-dispatcher.ts +1 -2
- package/src/runtime/web-presence.ts +3 -4
- package/src/schedule/schedule-store.ts +10 -0
- package/src/schedule/scheduler.ts +92 -24
- package/src/subagent/manager.ts +32 -12
- package/src/telegram/__tests__/webhook-health.test.ts +8 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +1 -0
- package/src/tools/background-tool-registry.ts +30 -3
- package/src/tools/browser/cdp-client/local-cdp-client.ts +1 -2
- package/src/tools/host-terminal/host-shell.ts +7 -0
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +28 -1
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +34 -0
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +35 -1
- package/src/tools/network/__tests__/web-search.test.ts +96 -0
- package/src/tools/network/web-fetch.ts +30 -9
- package/src/tools/network/web-search.ts +235 -4
- package/src/tools/skills/load.ts +13 -17
- package/src/tools/skills/scaffold-managed.ts +86 -71
- package/src/tools/terminal/shell-launch.test.ts +27 -1
- package/src/tools/terminal/shell.ts +4 -0
- package/src/tools/workspace-tools/loader.ts +1 -2
- package/src/usage/attribution.ts +18 -1
- package/src/util/abort-reasons.ts +2 -0
- package/src/util/errors.ts +1 -0
- package/src/util/oauth-request-body.test.ts +5 -1
- package/src/util/provider-error-patterns.ts +11 -0
- package/src/util/single-flight.test.ts +6 -0
- package/src/util/single-flight.ts +2 -0
- package/src/util/worker-pipe.test.ts +56 -10
- package/src/util/worker-pipe.ts +9 -4
- package/src/workspace/git-service.ts +6 -1
- package/src/workspace/migrations/158-repoint-opencode-host-provider-fragments.ts +163 -0
- package/src/workspace/migrations/__tests__/158-repoint-opencode-host-provider-fragments.test.ts +188 -0
- package/src/workspace/migrations/registry.ts +2 -0
|
@@ -32,25 +32,24 @@ mock.module("../daemon/skill-memory-refresh.js", () => ({
|
|
|
32
32
|
refreshSkillCapabilityMemories: mockRefreshSkillCapabilityMemories,
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
// the
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}));
|
|
35
|
+
// Receipt recorder: the executor's one side effect for a background
|
|
36
|
+
// overwrite, captured at the job module's boundary so the tests read what
|
|
37
|
+
// was recorded rather than standing up the memory job queue.
|
|
38
|
+
import type * as ReceiptJob from "../plugins/defaults/memory/skill-update-receipt-job.js";
|
|
39
|
+
|
|
40
|
+
let recordedUpdates: Parameters<typeof ReceiptJob.recordSkillUpdate>[0][] = [];
|
|
41
|
+
let recordUpdateFails = false;
|
|
42
|
+
mock.module(
|
|
43
|
+
"../plugins/defaults/memory/skill-update-receipt-job.js",
|
|
44
|
+
(): Partial<typeof ReceiptJob> => ({
|
|
45
|
+
recordSkillUpdate: (input) => {
|
|
46
|
+
recordedUpdates.push(input);
|
|
47
|
+
if (recordUpdateFails) {
|
|
48
|
+
throw new Error("memory database unavailable");
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
54
53
|
|
|
55
54
|
// Skill-card enqueue recorder. Snapshot + override (rather than a full module
|
|
56
55
|
// replacement) because other modules in this import graph (e.g. the managed
|
|
@@ -152,7 +151,7 @@ beforeEach(() => {
|
|
|
152
151
|
skillCardJobUpserts = [];
|
|
153
152
|
skillCardUpsertThrows = false;
|
|
154
153
|
watchdogEvents.length = 0;
|
|
155
|
-
|
|
154
|
+
recordedUpdates = [];
|
|
156
155
|
});
|
|
157
156
|
|
|
158
157
|
afterEach(() => {
|
|
@@ -1771,7 +1770,8 @@ describe("background skill update notification", () => {
|
|
|
1771
1770
|
});
|
|
1772
1771
|
watchdogEvents.length = 0;
|
|
1773
1772
|
skillCardJobUpserts = [];
|
|
1774
|
-
|
|
1773
|
+
recordedUpdates = [];
|
|
1774
|
+
recordUpdateFails = false;
|
|
1775
1775
|
}
|
|
1776
1776
|
|
|
1777
1777
|
const lineage = () => ({
|
|
@@ -1781,9 +1781,73 @@ describe("background skill update notification", () => {
|
|
|
1781
1781
|
: null,
|
|
1782
1782
|
});
|
|
1783
1783
|
|
|
1784
|
-
test("a background overwrite of an existing skill
|
|
1784
|
+
test("a background overwrite of an existing skill records a receipt entry keyed to the tool call", async () => {
|
|
1785
1785
|
await seedAssistantSkill("weekly-export", "Old body.");
|
|
1786
1786
|
|
|
1787
|
+
const result = await executeScaffoldManagedSkill(
|
|
1788
|
+
{
|
|
1789
|
+
skill_id: "weekly-export",
|
|
1790
|
+
name: "Weekly Report Export",
|
|
1791
|
+
description: "export the weekly usage report",
|
|
1792
|
+
body_markdown: "1. Refined steps.",
|
|
1793
|
+
activation_hints: HINTS,
|
|
1794
|
+
overwrite: true,
|
|
1795
|
+
change_summary: "Refined the steps.",
|
|
1796
|
+
},
|
|
1797
|
+
makeRetrospectiveContext({
|
|
1798
|
+
conversationId: "retro-run-conv",
|
|
1799
|
+
toolUseId: "toolu_1",
|
|
1800
|
+
}),
|
|
1801
|
+
lineage(),
|
|
1802
|
+
);
|
|
1803
|
+
|
|
1804
|
+
expect(result.isError).toBe(false);
|
|
1805
|
+
// Nothing is announced here: the entry joins the pending receipt job,
|
|
1806
|
+
// which announces the burst once it has settled.
|
|
1807
|
+
expect(recordedUpdates).toEqual([
|
|
1808
|
+
{
|
|
1809
|
+
// The producing tool call, so a re-executed call records nothing new.
|
|
1810
|
+
entryId: "retro-run-conv:toolu_1",
|
|
1811
|
+
skillId: "weekly-export",
|
|
1812
|
+
name: "Weekly Report Export",
|
|
1813
|
+
changeSummary: "Refined the steps.",
|
|
1814
|
+
runConversationId: "retro-run-conv",
|
|
1815
|
+
// The receipt's link for this entry resolves through this id, so it
|
|
1816
|
+
// must be the conversation the work came from, not the hidden fork.
|
|
1817
|
+
sourceConversationId: "source-conv",
|
|
1818
|
+
},
|
|
1819
|
+
]);
|
|
1820
|
+
});
|
|
1821
|
+
|
|
1822
|
+
test("an entry without a tool call id gets a fresh key, so a second rewrite of the same skill is still recorded", async () => {
|
|
1823
|
+
await seedAssistantSkill("weekly-export", "Old body.");
|
|
1824
|
+
|
|
1825
|
+
for (const body of ["1. Refined steps.", "1. Refined again."]) {
|
|
1826
|
+
await executeScaffoldManagedSkill(
|
|
1827
|
+
{
|
|
1828
|
+
skill_id: "weekly-export",
|
|
1829
|
+
name: "Weekly Report Export",
|
|
1830
|
+
description: "export the weekly usage report",
|
|
1831
|
+
body_markdown: body,
|
|
1832
|
+
activation_hints: HINTS,
|
|
1833
|
+
overwrite: true,
|
|
1834
|
+
change_summary: `Refined: ${body}`,
|
|
1835
|
+
},
|
|
1836
|
+
makeRetrospectiveContext({ conversationId: "retro-run-conv" }),
|
|
1837
|
+
);
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
expect(recordedUpdates).toHaveLength(2);
|
|
1841
|
+
const [first, second] = recordedUpdates;
|
|
1842
|
+
expect(first?.entryId.startsWith("retro-run-conv:")).toBe(true);
|
|
1843
|
+
expect(second?.entryId.startsWith("retro-run-conv:")).toBe(true);
|
|
1844
|
+
expect(first?.entryId).not.toBe(second?.entryId);
|
|
1845
|
+
});
|
|
1846
|
+
|
|
1847
|
+
test("a receipt that cannot be recorded is logged and counted, and the skill write stands", async () => {
|
|
1848
|
+
await seedAssistantSkill("weekly-export", "Old body.");
|
|
1849
|
+
recordUpdateFails = true;
|
|
1850
|
+
|
|
1787
1851
|
const result = await executeScaffoldManagedSkill(
|
|
1788
1852
|
{
|
|
1789
1853
|
skill_id: "weekly-export",
|
|
@@ -1799,29 +1863,20 @@ describe("background skill update notification", () => {
|
|
|
1799
1863
|
);
|
|
1800
1864
|
|
|
1801
1865
|
expect(result.isError).toBe(false);
|
|
1802
|
-
expect(
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
expect(
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
);
|
|
1817
|
-
expect(signal.contextPayload?.body).toBe("Refined the steps.");
|
|
1818
|
-
// Deduped per skill per day so repeated refinements cannot flood the feed.
|
|
1819
|
-
expect(signal.dedupeKey).toBe(
|
|
1820
|
-
`skill-updated:weekly-export:${new Date().toISOString().slice(0, 10)}`,
|
|
1821
|
-
);
|
|
1822
|
-
});
|
|
1823
|
-
|
|
1824
|
-
test("the notice body is the pass's change_summary, so the feed says what changed", async () => {
|
|
1866
|
+
expect(
|
|
1867
|
+
readFileSync(
|
|
1868
|
+
join(TEST_DIR, "skills", "weekly-export", "SKILL.md"),
|
|
1869
|
+
"utf-8",
|
|
1870
|
+
),
|
|
1871
|
+
).toContain("Refined steps.");
|
|
1872
|
+
expect(watchdogEvents).toContainEqual(
|
|
1873
|
+
expect.objectContaining({
|
|
1874
|
+
checkName: "skill_update_receipt_record_failed",
|
|
1875
|
+
}),
|
|
1876
|
+
);
|
|
1877
|
+
});
|
|
1878
|
+
|
|
1879
|
+
test("the entry body is the pass's change_summary, so the receipt says what changed", async () => {
|
|
1825
1880
|
await seedAssistantSkill("weekly-export", "Old body.");
|
|
1826
1881
|
|
|
1827
1882
|
const result = await executeScaffoldManagedSkill(
|
|
@@ -1840,14 +1895,9 @@ describe("background skill update notification", () => {
|
|
|
1840
1895
|
);
|
|
1841
1896
|
|
|
1842
1897
|
expect(result.isError).toBe(false);
|
|
1843
|
-
expect(
|
|
1844
|
-
const payload = emittedSignals[0]!.contextPayload;
|
|
1845
|
-
// The title still names the skill; the body is the change itself.
|
|
1846
|
-
expect(payload?.title).toBe("Skill updated: Weekly Report Export");
|
|
1847
|
-
expect(payload?.body).toBe(
|
|
1898
|
+
expect(recordedUpdates[0]?.changeSummary).toBe(
|
|
1848
1899
|
"Added the retry after an expired session and the export endpoint that held steady.",
|
|
1849
1900
|
);
|
|
1850
|
-
expect(payload?.summary).toBe(payload?.body);
|
|
1851
1901
|
});
|
|
1852
1902
|
|
|
1853
1903
|
test("a background overwrite without a change_summary is refused before the write", async () => {
|
|
@@ -1881,7 +1931,7 @@ describe("background skill update notification", () => {
|
|
|
1881
1931
|
'Error: change_summary is required when updating an existing skill: pass one or two short sentences (under 200 characters) for the person who reads the "Skill updated" notice, naming what you changed and what in the trace prompted it (for example "Added the retry after an expired session and the export endpoint that held steady.").',
|
|
1882
1932
|
);
|
|
1883
1933
|
expect(readFileSync(skillFile, "utf-8")).toBe(before);
|
|
1884
|
-
expect(
|
|
1934
|
+
expect(recordedUpdates).toHaveLength(0);
|
|
1885
1935
|
}
|
|
1886
1936
|
});
|
|
1887
1937
|
|
|
@@ -1905,7 +1955,7 @@ describe("background skill update notification", () => {
|
|
|
1905
1955
|
expect(result.isError).toBe(true);
|
|
1906
1956
|
expect(result.content).toContain("Set overwrite=true to replace it.");
|
|
1907
1957
|
expect(result.content).not.toContain("change_summary");
|
|
1908
|
-
expect(
|
|
1958
|
+
expect(recordedUpdates).toHaveLength(0);
|
|
1909
1959
|
});
|
|
1910
1960
|
|
|
1911
1961
|
test("the ownership backstop speaks before the change_summary requirement", async () => {
|
|
@@ -1937,7 +1987,7 @@ describe("background skill update notification", () => {
|
|
|
1937
1987
|
expect(result.content).toContain("not verifiably assistant-authored");
|
|
1938
1988
|
});
|
|
1939
1989
|
|
|
1940
|
-
test("a user-directed overwrite needs no change_summary: it
|
|
1990
|
+
test("a user-directed overwrite needs no change_summary: it records no entry", async () => {
|
|
1941
1991
|
await executeScaffoldManagedSkill(
|
|
1942
1992
|
{
|
|
1943
1993
|
skill_id: "user-skill",
|
|
@@ -1964,7 +2014,7 @@ describe("background skill update notification", () => {
|
|
|
1964
2014
|
expect(result.isError).toBe(false);
|
|
1965
2015
|
});
|
|
1966
2016
|
|
|
1967
|
-
test("change_summary is sanitized like any
|
|
2017
|
+
test("change_summary is sanitized like any notification body", async () => {
|
|
1968
2018
|
await seedAssistantSkill("weekly-export", "Old body.");
|
|
1969
2019
|
|
|
1970
2020
|
await executeScaffoldManagedSkill(
|
|
@@ -1981,7 +2031,7 @@ describe("background skill update notification", () => {
|
|
|
1981
2031
|
lineage(),
|
|
1982
2032
|
);
|
|
1983
2033
|
|
|
1984
|
-
const body = String(
|
|
2034
|
+
const body = String(recordedUpdates[0]?.changeSummary);
|
|
1985
2035
|
// Control characters go, horizontal whitespace collapses, blank-line runs
|
|
1986
2036
|
// collapse to one paragraph break, and the whole thing is clamped to the
|
|
1987
2037
|
// shared notification preview budget.
|
|
@@ -2012,7 +2062,7 @@ describe("background skill update notification", () => {
|
|
|
2012
2062
|
|
|
2013
2063
|
expect(result.isError).toBe(true);
|
|
2014
2064
|
expect(result.content).toBe("Error: change_summary must be a string");
|
|
2015
|
-
expect(
|
|
2065
|
+
expect(recordedUpdates).toHaveLength(0);
|
|
2016
2066
|
});
|
|
2017
2067
|
|
|
2018
2068
|
test("the registered tool's schema declares change_summary as an optional string", () => {
|
|
@@ -2044,7 +2094,7 @@ describe("background skill update notification", () => {
|
|
|
2044
2094
|
expect(result.ok).toBe(true);
|
|
2045
2095
|
});
|
|
2046
2096
|
|
|
2047
|
-
test("
|
|
2097
|
+
test("an entry whose fork lineage does not resolve carries no source, never the run", async () => {
|
|
2048
2098
|
await seedAssistantSkill("weekly-export", "Old body.");
|
|
2049
2099
|
|
|
2050
2100
|
await executeScaffoldManagedSkill(
|
|
@@ -2061,10 +2111,10 @@ describe("background skill update notification", () => {
|
|
|
2061
2111
|
{ getConversation: () => null },
|
|
2062
2112
|
);
|
|
2063
2113
|
|
|
2064
|
-
//
|
|
2065
|
-
//
|
|
2066
|
-
expect(
|
|
2067
|
-
expect(
|
|
2114
|
+
// The run is an ephemeral fork; naming it as the source would have the
|
|
2115
|
+
// receipt job drop the entry once the fork is garbage collected.
|
|
2116
|
+
expect(recordedUpdates).toHaveLength(1);
|
|
2117
|
+
expect(recordedUpdates[0]).not.toHaveProperty("sourceConversationId");
|
|
2068
2118
|
});
|
|
2069
2119
|
|
|
2070
2120
|
test("a background CREATE gets the skill card instead, with no duplicate signal", async () => {
|
|
@@ -2082,10 +2132,10 @@ describe("background skill update notification", () => {
|
|
|
2082
2132
|
|
|
2083
2133
|
expect(result.isError).toBe(false);
|
|
2084
2134
|
expect(skillCardJobUpserts).toHaveLength(1);
|
|
2085
|
-
expect(
|
|
2135
|
+
expect(recordedUpdates).toHaveLength(0);
|
|
2086
2136
|
});
|
|
2087
2137
|
|
|
2088
|
-
test("a user-directed overwrite
|
|
2138
|
+
test("a user-directed overwrite records no receipt entry: it is not unattended work", async () => {
|
|
2089
2139
|
await executeScaffoldManagedSkill(
|
|
2090
2140
|
{
|
|
2091
2141
|
skill_id: "user-skill",
|
|
@@ -2096,7 +2146,7 @@ describe("background skill update notification", () => {
|
|
|
2096
2146
|
},
|
|
2097
2147
|
makeContext(),
|
|
2098
2148
|
);
|
|
2099
|
-
|
|
2149
|
+
recordedUpdates = [];
|
|
2100
2150
|
|
|
2101
2151
|
await executeScaffoldManagedSkill(
|
|
2102
2152
|
{
|
|
@@ -2113,6 +2163,6 @@ describe("background skill update notification", () => {
|
|
|
2113
2163
|
expect(
|
|
2114
2164
|
readFileSync(join(TEST_DIR, "skills", "user-skill", "SKILL.md"), "utf-8"),
|
|
2115
2165
|
).toContain("V2.");
|
|
2116
|
-
expect(
|
|
2166
|
+
expect(recordedUpdates).toHaveLength(0);
|
|
2117
2167
|
});
|
|
2118
2168
|
});
|