@vellumai/assistant 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +54 -54
- package/docs/architecture/integrations.md +62 -67
- package/docs/credential-execution-service.md +3 -3
- package/package.json +1 -1
- package/src/__tests__/agent-loop.test.ts +111 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +3 -4
- package/src/__tests__/app-builder-tool-scripts.test.ts +13 -151
- package/src/__tests__/app-dir-path-guard.test.ts +78 -0
- package/src/__tests__/app-executors.test.ts +1 -291
- package/src/__tests__/app-git-history.test.ts +4 -4
- package/src/__tests__/app-routes-csp.test.ts +1 -0
- package/src/__tests__/app-store-dir-names.test.ts +426 -0
- package/src/__tests__/attachments-store.test.ts +169 -21
- package/src/__tests__/attachments.test.ts +115 -1
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/canonical-guardian-store.test.ts +38 -0
- package/src/__tests__/channel-reply-delivery.test.ts +55 -0
- package/src/__tests__/checker.test.ts +54 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +2 -0
- package/src/__tests__/claude-code-tool-profiles.test.ts +2 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -1
- package/src/__tests__/config-schema-cmd.test.ts +68 -21
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +149 -5
- package/src/__tests__/conversation-agent-loop.test.ts +290 -2
- package/src/__tests__/conversation-attachments.test.ts +17 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +277 -0
- package/src/__tests__/conversation-disk-view.test.ts +810 -0
- package/src/__tests__/conversation-error.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +551 -0
- package/src/__tests__/conversation-fork-route.test.ts +386 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +130 -0
- package/src/__tests__/conversation-media-retry.test.ts +8 -2
- package/src/__tests__/conversation-queue.test.ts +36 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +439 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +17 -2
- package/src/__tests__/conversation-skill-tools.test.ts +4 -9
- package/src/__tests__/conversation-slash-commands.test.ts +149 -0
- package/src/__tests__/conversation-store.test.ts +24 -21
- package/src/__tests__/conversation-surfaces-state-update.test.ts +246 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -0
- package/src/__tests__/conversation-title-service.test.ts +137 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +25 -315
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +44 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +11 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-vault-unit.test.ts +5 -10
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +241 -0
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +214 -0
- package/src/__tests__/diagnostics-export.test.ts +70 -1
- package/src/__tests__/first-greeting.test.ts +80 -0
- package/src/__tests__/gateway-only-guard.test.ts +1 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -7
- package/src/__tests__/history-repair.test.ts +32 -10
- package/src/__tests__/http-conversation-lineage.test.ts +251 -0
- package/src/__tests__/image-source-path-reinject.test.ts +136 -0
- package/src/__tests__/llm-context-normalization.test.ts +1116 -0
- package/src/__tests__/llm-context-route-provider.test.ts +217 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +270 -0
- package/src/__tests__/media-generate-image.test.ts +47 -94
- package/src/__tests__/memory-lifecycle-e2e.test.ts +3 -1
- package/src/__tests__/memory-recall-quality.test.ts +5 -5
- package/src/__tests__/migration-cross-version-compatibility.test.ts +4 -1
- package/src/__tests__/migration-export-http.test.ts +3 -1
- package/src/__tests__/migration-import-commit-http.test.ts +18 -4
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -3
- package/src/__tests__/mime-builder.test.ts +3 -2
- package/src/__tests__/non-member-access-request.test.ts +12 -1
- package/src/__tests__/notification-decision-identity.test.ts +52 -0
- package/src/__tests__/oauth-apps-routes.test.ts +103 -0
- package/src/__tests__/oauth-store.test.ts +115 -0
- package/src/__tests__/provider-error-scenarios.test.ts +1 -3
- package/src/__tests__/provider-failover-actual-provider.test.ts +66 -0
- package/src/__tests__/recording-handler.test.ts +17 -0
- package/src/__tests__/registry.test.ts +3 -8
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/runtime-attachment-metadata.test.ts +7 -3
- package/src/__tests__/schema-transforms.test.ts +165 -5
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -2
- package/src/__tests__/starter-task-flow.test.ts +1 -0
- package/src/__tests__/suggestion-routes.test.ts +443 -0
- package/src/__tests__/swarm-conversation-integration.test.ts +1 -0
- package/src/__tests__/swarm-recursion.test.ts +1 -0
- package/src/__tests__/swarm-tool.test.ts +1 -0
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -5
- package/src/__tests__/top-level-renderer.test.ts +22 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +243 -0
- package/src/__tests__/web-fetch.test.ts +6 -2
- package/src/__tests__/workspace-migration-006-services-config.test.ts +335 -0
- package/src/__tests__/workspace-migration-007-web-search-provider-rename.test.ts +312 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +278 -0
- package/src/__tests__/workspace-migration-010-app-dir-rename.test.ts +275 -0
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +77 -0
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +401 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +328 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +6 -10
- package/src/agent/attachments.ts +27 -1
- package/src/agent/loop.ts +29 -1
- package/src/avatar/traits-png-sync.ts +80 -25
- package/src/bundler/app-bundler.ts +4 -4
- package/src/calls/call-domain.ts +1 -0
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/commands/auth.ts +92 -0
- package/src/cli/commands/avatar.ts +7 -6
- package/src/cli/commands/config.ts +2 -0
- package/src/cli/commands/oauth/providers.ts +29 -0
- package/src/cli/program.ts +12 -0
- package/src/cli.ts +15 -48
- package/src/config/bundled-skills/app-builder/SKILL.md +103 -28
- package/src/config/bundled-skills/app-builder/TOOLS.json +5 -199
- package/src/config/bundled-skills/app-builder/tools/{app-query.ts → app-refresh.ts} +2 -2
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +6 -9
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +2 -3
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -2
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +45 -72
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -3
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/bundled-skills/slack/tools/shared.ts +19 -4
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +2 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -1
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -6
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +19 -83
- package/src/config/bundled-tool-registry.ts +2 -14
- package/src/config/feature-flag-registry.json +8 -0
- package/src/config/loader.ts +64 -0
- package/src/config/raw-config-utils.ts +30 -0
- package/src/config/schema-utils.ts +28 -7
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/elevenlabs.ts +18 -0
- package/src/config/schemas/memory-lifecycle.ts +4 -2
- package/src/config/schemas/memory-storage.ts +1 -1
- package/src/config/schemas/services.ts +8 -6
- package/src/contacts/contact-store.ts +13 -6
- package/src/contacts/contacts-write.ts +0 -1
- package/src/context/window-manager.ts +13 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +48 -7
- package/src/daemon/conversation-agent-loop.ts +56 -19
- package/src/daemon/conversation-attachments.ts +18 -36
- package/src/daemon/conversation-error.ts +2 -1
- package/src/daemon/conversation-history.ts +18 -4
- package/src/daemon/conversation-lifecycle.ts +39 -15
- package/src/daemon/conversation-messaging.ts +70 -26
- package/src/daemon/conversation-process.ts +58 -34
- package/src/daemon/conversation-runtime-assembly.ts +21 -38
- package/src/daemon/conversation-slash.ts +121 -256
- package/src/daemon/conversation-surfaces.ts +143 -20
- package/src/daemon/conversation-tool-setup.ts +0 -6
- package/src/daemon/conversation-workspace.ts +21 -1
- package/src/daemon/conversation.ts +51 -29
- package/src/daemon/first-greeting.ts +35 -0
- package/src/daemon/handlers/config-embeddings.ts +148 -0
- package/src/daemon/handlers/config-model.ts +71 -26
- package/src/daemon/handlers/conversations.ts +0 -23
- package/src/daemon/handlers/recording.ts +26 -21
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/lifecycle.ts +106 -64
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +19 -0
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/shared.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/upgrades.ts +23 -0
- package/src/daemon/server.ts +83 -12
- package/src/daemon/shutdown-handlers.ts +8 -5
- package/src/daemon/startup-error.ts +9 -0
- package/src/daemon/tool-side-effects.ts +11 -28
- package/src/events/tool-permission-telemetry-listener.ts +1 -3
- package/src/instrument.ts +0 -4
- package/src/media/app-icon-generator.ts +2 -2
- package/src/memory/app-git-service.ts +28 -16
- package/src/memory/app-store.ts +230 -41
- package/src/memory/attachments-store.ts +558 -130
- package/src/memory/conversation-attention-store.ts +70 -0
- package/src/memory/conversation-crud.ts +442 -3
- package/src/memory/conversation-directories.ts +125 -0
- package/src/memory/conversation-disk-view.ts +390 -0
- package/src/memory/conversation-key-store.ts +17 -5
- package/src/memory/conversation-queries.ts +5 -1
- package/src/memory/conversation-title-service.ts +21 -49
- package/src/memory/db-init.ts +28 -0
- package/src/memory/embedding-backend.ts +42 -53
- package/src/memory/embedding-gemini.test.ts +4 -4
- package/src/memory/embedding-local.ts +1 -3
- package/src/memory/embedding-ollama.ts +1 -3
- package/src/memory/embedding-openai.ts +1 -3
- package/src/memory/indexer.ts +9 -7
- package/src/memory/items-extractor.ts +42 -13
- package/src/memory/job-handlers/conversation-starters.ts +6 -1
- package/src/memory/job-handlers/embedding.test.ts +1 -4
- package/src/memory/llm-request-log-store.ts +100 -1
- package/src/memory/migrations/102-alter-table-columns.ts +5 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +3 -3
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +66 -70
- package/src/memory/migrations/148-drop-reminders-table.ts +5 -9
- package/src/memory/migrations/160-drop-loopback-port-column.ts +1 -3
- package/src/memory/migrations/174-rename-thread-starters-table.ts +0 -7
- package/src/memory/migrations/178-oauth-providers-managed-service-config-key.ts +15 -0
- package/src/memory/migrations/179-llm-request-log-message-id.ts +16 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +66 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +46 -0
- package/src/memory/migrations/182-oauth-providers-display-metadata.ts +20 -0
- package/src/memory/migrations/183-add-conversation-fork-lineage.ts +22 -0
- package/src/memory/migrations/184-llm-request-log-provider.ts +12 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/migrations/registry.ts +13 -0
- package/src/memory/retriever.test.ts +601 -2
- package/src/memory/retriever.ts +85 -9
- package/src/memory/schema/conversations.ts +6 -0
- package/src/memory/schema/infrastructure.ts +13 -7
- package/src/memory/schema/oauth.ts +6 -0
- package/src/messaging/providers/gmail/mime-builder.ts +3 -1
- package/src/notifications/copy-composer.ts +26 -0
- package/src/notifications/decision-engine.ts +14 -1
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +36 -0
- package/src/oauth/byo-connection.test.ts +1 -45
- package/src/oauth/byo-connection.ts +2 -8
- package/src/oauth/connect-orchestrator.ts +15 -11
- package/src/oauth/connection-resolver.test.ts +191 -0
- package/src/oauth/connection-resolver.ts +66 -38
- package/src/oauth/connection.ts +0 -1
- package/src/oauth/oauth-store.ts +97 -47
- package/src/oauth/platform-connection.test.ts +0 -1
- package/src/oauth/platform-connection.ts +11 -3
- package/src/oauth/seed-providers.ts +78 -3
- package/src/oauth/token-persistence.ts +16 -10
- package/src/permissions/checker.ts +71 -8
- package/src/prompts/templates/BOOTSTRAP.md +2 -0
- package/src/providers/anthropic/client.ts +8 -1
- package/src/providers/failover.ts +4 -1
- package/src/providers/gemini/client.ts +50 -0
- package/src/providers/model-catalog.ts +92 -0
- package/src/providers/model-intents.ts +29 -20
- package/src/providers/openai/client.ts +49 -0
- package/src/providers/types.ts +2 -0
- package/src/runtime/access-request-helper.ts +16 -7
- package/src/runtime/auth/credential-service.ts +3 -1
- package/src/runtime/auth/route-policy.ts +14 -1
- package/src/runtime/btw-sidechain.ts +101 -0
- package/src/runtime/channel-reply-delivery.ts +17 -1
- package/src/runtime/http-router.ts +3 -1
- package/src/runtime/http-server.ts +196 -141
- package/src/runtime/http-types.ts +1 -0
- package/src/runtime/migrations/vbundle-builder.ts +5 -1
- package/src/runtime/routes/access-request-decision.ts +41 -0
- package/src/runtime/routes/app-management-routes.ts +6 -3
- package/src/runtime/routes/app-routes.ts +7 -3
- package/src/runtime/routes/approval-routes.ts +1 -0
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +34 -2
- package/src/runtime/routes/attachment-routes.ts +45 -15
- package/src/runtime/routes/btw-routes.ts +21 -61
- package/src/runtime/routes/conversation-management-routes.ts +68 -0
- package/src/runtime/routes/conversation-query-routes.ts +180 -10
- package/src/runtime/routes/conversation-routes.ts +222 -28
- package/src/runtime/routes/conversation-starter-routes.ts +9 -11
- package/src/runtime/routes/diagnostics-routes.ts +1 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -2
- package/src/runtime/routes/llm-context-normalization.ts +1199 -0
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/memory-item-routes.test.ts +34 -0
- package/src/runtime/routes/memory-item-routes.ts +4 -0
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/oauth-apps.ts +291 -0
- package/src/runtime/routes/secret-routes.ts +28 -1
- package/src/runtime/routes/settings-routes.ts +14 -0
- package/src/runtime/routes/trace-event-routes.ts +4 -1
- package/src/schedule/schedule-store.ts +9 -21
- package/src/security/secure-keys.ts +21 -0
- package/src/signals/bash.ts +1 -1
- package/src/swarm/backend-claude-code.ts +3 -6
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +3 -1
- package/src/tools/AGENTS.md +6 -10
- package/src/tools/apps/executors.ts +17 -232
- package/src/tools/claude-code/claude-code.ts +2 -3
- package/src/tools/credentials/vault.ts +7 -12
- package/src/tools/host-filesystem/read.ts +13 -10
- package/src/tools/network/__tests__/web-search.test.ts +4 -2
- package/src/tools/schedule/list.ts +2 -7
- package/src/tools/schema-transforms.ts +5 -0
- package/src/tools/shared/filesystem/format-diff.ts +2 -7
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/tool-manifest.ts +0 -6
- package/src/tools/ui-surface/definitions.ts +2 -2
- package/src/util/device-id.ts +28 -5
- package/src/util/platform.ts +6 -0
- package/src/util/pricing.ts +1 -0
- package/src/util/retry.ts +1 -3
- package/src/workspace/migrations/002-backfill-installation-id.ts +23 -12
- package/src/workspace/migrations/003-seed-device-id.ts +3 -4
- package/src/workspace/migrations/006-services-config.ts +5 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +12 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +10 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +223 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +64 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +11 -0
- package/src/workspace/migrations/rebuild-conversation-disk-view.ts +186 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/top-level-renderer.ts +12 -0
- package/src/__tests__/asset-materialize-tool.test.ts +0 -523
- package/src/__tests__/asset-search-tool.test.ts +0 -536
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +0 -56
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -762
- package/src/__tests__/media-visibility-policy.test.ts +0 -190
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +0 -21
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -23
- package/src/daemon/media-visibility-policy.ts +0 -59
- package/src/tools/assets/materialize.ts +0 -248
- package/src/tools/assets/search.ts +0 -400
|
@@ -70,21 +70,53 @@ describe("injectActivityField", () => {
|
|
|
70
70
|
expect("activity" in props0).toBe(false);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
test("
|
|
73
|
+
test("returns unchanged when activity is in top-level properties but not required", () => {
|
|
74
74
|
const defs = [
|
|
75
75
|
makeDef("my_tool", {
|
|
76
76
|
type: "object",
|
|
77
77
|
properties: { activity: { type: "number" } },
|
|
78
|
-
required: [],
|
|
78
|
+
required: ["foo"],
|
|
79
79
|
}),
|
|
80
80
|
];
|
|
81
81
|
const result = injectActivityField(defs);
|
|
82
|
-
// Should be the exact same object reference (no
|
|
82
|
+
// Should be the exact same object reference (no modification)
|
|
83
83
|
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
84
84
|
const schema = result[0].input_schema as Record<string, unknown>;
|
|
85
85
|
const props = schema.properties as Record<string, unknown>;
|
|
86
86
|
// Original activity type preserved
|
|
87
87
|
expect(props.activity).toEqual({ type: "number" });
|
|
88
|
+
// required NOT modified — don't promote server-defined optional activity
|
|
89
|
+
expect(schema.required).toEqual(["foo"]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("returns unchanged when activity is in both top-level properties AND required", () => {
|
|
93
|
+
const defs = [
|
|
94
|
+
makeDef("my_tool", {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: { activity: { type: "string" } },
|
|
97
|
+
required: ["activity"],
|
|
98
|
+
}),
|
|
99
|
+
];
|
|
100
|
+
const result = injectActivityField(defs);
|
|
101
|
+
const schema = result[0].input_schema as Record<string, unknown>;
|
|
102
|
+
const props = schema.properties as Record<string, unknown>;
|
|
103
|
+
// Original activity type preserved
|
|
104
|
+
expect(props.activity).toEqual({ type: "string" });
|
|
105
|
+
// activity must be in required even though it was already in properties
|
|
106
|
+
expect(schema.required).toEqual(["activity"]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("skips tools that already have activity in both properties and required", () => {
|
|
110
|
+
const defs = [
|
|
111
|
+
makeDef("my_tool", {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: { activity: { type: "number" } },
|
|
114
|
+
required: ["activity"],
|
|
115
|
+
}),
|
|
116
|
+
];
|
|
117
|
+
const result = injectActivityField(defs);
|
|
118
|
+
// Should be the exact same object reference (no clone needed)
|
|
119
|
+
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
88
120
|
});
|
|
89
121
|
|
|
90
122
|
test("does NOT mutate original definition objects", () => {
|
|
@@ -125,6 +157,60 @@ describe("injectActivityField", () => {
|
|
|
125
157
|
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
126
158
|
});
|
|
127
159
|
|
|
160
|
+
test("does NOT add activity to top-level required when only in oneOf branch", () => {
|
|
161
|
+
const defs = [
|
|
162
|
+
makeDef("my_tool", {
|
|
163
|
+
type: "object",
|
|
164
|
+
properties: { shared: { type: "string" } },
|
|
165
|
+
oneOf: [
|
|
166
|
+
{
|
|
167
|
+
properties: {
|
|
168
|
+
activity: { type: "string" },
|
|
169
|
+
branch_a: { type: "number" },
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
properties: { branch_b: { type: "boolean" } },
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
required: ["shared"],
|
|
177
|
+
}),
|
|
178
|
+
];
|
|
179
|
+
const result = injectActivityField(defs);
|
|
180
|
+
// Should be the exact same object reference (no modification)
|
|
181
|
+
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
182
|
+
const schema = result[0].input_schema as Record<string, unknown>;
|
|
183
|
+
// Top-level required should NOT include activity
|
|
184
|
+
expect(schema.required).toEqual(["shared"]);
|
|
185
|
+
// Top-level properties should NOT have activity injected
|
|
186
|
+
const props = schema.properties as Record<string, unknown>;
|
|
187
|
+
expect("activity" in props).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test("does NOT add activity to top-level required when only in allOf sub-schema with additionalProperties: false", () => {
|
|
191
|
+
const defs = [
|
|
192
|
+
makeDef("my_tool", {
|
|
193
|
+
type: "object",
|
|
194
|
+
properties: { foo: { type: "string" } },
|
|
195
|
+
additionalProperties: false,
|
|
196
|
+
allOf: [
|
|
197
|
+
{
|
|
198
|
+
properties: { activity: { type: "string" } },
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
required: ["foo"],
|
|
202
|
+
}),
|
|
203
|
+
];
|
|
204
|
+
const result = injectActivityField(defs);
|
|
205
|
+
// Should be the exact same object reference (no modification)
|
|
206
|
+
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
207
|
+
const schema = result[0].input_schema as Record<string, unknown>;
|
|
208
|
+
// Top-level required should NOT include activity
|
|
209
|
+
expect(schema.required).toEqual(["foo"]);
|
|
210
|
+
const props = schema.properties as Record<string, unknown>;
|
|
211
|
+
expect("activity" in props).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
|
|
128
214
|
test("skips tools with activity defined inside allOf member (composite schema)", () => {
|
|
129
215
|
const defs = [
|
|
130
216
|
makeDef("my_tool", {
|
|
@@ -139,18 +225,92 @@ describe("injectActivityField", () => {
|
|
|
139
225
|
}),
|
|
140
226
|
];
|
|
141
227
|
const result = injectActivityField(defs);
|
|
142
|
-
// Should be the exact same object reference (no
|
|
228
|
+
// Should be the exact same object reference (no modification)
|
|
143
229
|
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
144
230
|
const schema = result[0].input_schema as Record<string, unknown>;
|
|
145
231
|
const props = schema.properties as Record<string, unknown>;
|
|
146
|
-
// Top-level properties should NOT have activity injected
|
|
232
|
+
// Top-level properties should NOT have activity injected (it's in allOf)
|
|
147
233
|
expect("activity" in props).toBe(false);
|
|
234
|
+
// Top-level required should NOT include activity (it's only in composite sub-schemas)
|
|
235
|
+
expect(schema.required).toEqual([]);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("skips allOf composite schema where activity is already required", () => {
|
|
239
|
+
const defs = [
|
|
240
|
+
makeDef("my_tool", {
|
|
241
|
+
type: "object",
|
|
242
|
+
properties: { foo: { type: "string" } },
|
|
243
|
+
allOf: [
|
|
244
|
+
{
|
|
245
|
+
properties: { activity: { type: "string" } },
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
required: ["activity"],
|
|
249
|
+
}),
|
|
250
|
+
];
|
|
251
|
+
const result = injectActivityField(defs);
|
|
252
|
+
// Should be the exact same object reference (no change needed)
|
|
253
|
+
expect(Object.is(result[0], defs[0])).toBe(true);
|
|
148
254
|
});
|
|
149
255
|
|
|
150
256
|
test("handles empty definitions array", () => {
|
|
151
257
|
const result = injectActivityField([]);
|
|
152
258
|
expect(result).toEqual([]);
|
|
153
259
|
});
|
|
260
|
+
|
|
261
|
+
test("injects activity only on tools that don't define it at all", () => {
|
|
262
|
+
const defs = [
|
|
263
|
+
// Normal tool without activity — should get it injected
|
|
264
|
+
makeDef("tool_a", {
|
|
265
|
+
type: "object",
|
|
266
|
+
properties: { foo: { type: "string" } },
|
|
267
|
+
required: ["foo"],
|
|
268
|
+
}),
|
|
269
|
+
// Tool defines activity in properties but NOT in required — left unchanged
|
|
270
|
+
makeDef("tool_b", {
|
|
271
|
+
type: "object",
|
|
272
|
+
properties: {
|
|
273
|
+
bar: { type: "string" },
|
|
274
|
+
activity: { type: "string", description: "custom activity" },
|
|
275
|
+
},
|
|
276
|
+
required: ["bar"],
|
|
277
|
+
}),
|
|
278
|
+
// Tool that defines activity in both properties AND required — left unchanged
|
|
279
|
+
makeDef("tool_c", {
|
|
280
|
+
type: "object",
|
|
281
|
+
properties: {
|
|
282
|
+
baz: { type: "number" },
|
|
283
|
+
activity: { type: "string", description: "custom activity" },
|
|
284
|
+
},
|
|
285
|
+
required: ["baz", "activity"],
|
|
286
|
+
}),
|
|
287
|
+
// Non-object schema — should be left alone
|
|
288
|
+
makeDef("tool_d", { type: "string" }),
|
|
289
|
+
// Object schema without properties — should be left alone
|
|
290
|
+
makeDef("tool_e", { type: "object" }),
|
|
291
|
+
];
|
|
292
|
+
|
|
293
|
+
const result = injectActivityField(defs);
|
|
294
|
+
|
|
295
|
+
// tool_a: activity injected and required
|
|
296
|
+
const schemaA = result[0].input_schema as Record<string, unknown>;
|
|
297
|
+
expect(
|
|
298
|
+
(schemaA.properties as Record<string, unknown>).activity,
|
|
299
|
+
).toBeDefined();
|
|
300
|
+
expect(schemaA.required).toEqual(["foo", "activity"]);
|
|
301
|
+
|
|
302
|
+
// tool_b: unchanged (activity optional, not promoted)
|
|
303
|
+
expect(Object.is(result[1], defs[1])).toBe(true);
|
|
304
|
+
const schemaB = result[1].input_schema as Record<string, unknown>;
|
|
305
|
+
expect(schemaB.required).toEqual(["bar"]);
|
|
306
|
+
|
|
307
|
+
// tool_c: unchanged (activity already present and required)
|
|
308
|
+
expect(Object.is(result[2], defs[2])).toBe(true);
|
|
309
|
+
|
|
310
|
+
// tool_d, tool_e: unchanged
|
|
311
|
+
expect(Object.is(result[3], defs[3])).toBe(true);
|
|
312
|
+
expect(Object.is(result[4], defs[4])).toBe(true);
|
|
313
|
+
});
|
|
154
314
|
});
|
|
155
315
|
|
|
156
316
|
describe("schemaDefinesProperty", () => {
|
|
@@ -330,7 +330,7 @@ describe("getAttachmentsForMessage", () => {
|
|
|
330
330
|
|
|
331
331
|
test("returns attachments linked to a message", async () => {
|
|
332
332
|
const msgId = await createMessage("assistant", "Here is a chart");
|
|
333
|
-
const stored = uploadAttachment("chart.png", "image/png", "
|
|
333
|
+
const stored = uploadAttachment("chart.png", "image/png", "iVBORw==");
|
|
334
334
|
linkAttachmentToMessage(msgId, stored.id, 0);
|
|
335
335
|
|
|
336
336
|
const result = getAttachmentsForMessage(msgId);
|
|
@@ -338,7 +338,7 @@ describe("getAttachmentsForMessage", () => {
|
|
|
338
338
|
expect(result[0].id).toBe(stored.id);
|
|
339
339
|
expect(result[0].originalFilename).toBe("chart.png");
|
|
340
340
|
expect(result[0].mimeType).toBe("image/png");
|
|
341
|
-
expect(result[0].dataBase64).toBe("
|
|
341
|
+
expect(result[0].dataBase64).toBe("iVBORw==");
|
|
342
342
|
});
|
|
343
343
|
|
|
344
344
|
test("returns empty array when no attachments are linked", () => {
|
|
@@ -9,7 +9,9 @@ const skillContent = readFileSync(SKILL_PATH, "utf-8");
|
|
|
9
9
|
|
|
10
10
|
describe("slack-app-setup skill regression", () => {
|
|
11
11
|
test("keeps Slack token collection on the secure credential prompt path", () => {
|
|
12
|
-
expect(skillContent).toContain(
|
|
12
|
+
expect(skillContent).toContain(
|
|
13
|
+
'`credential_store` with `action: "prompt"`',
|
|
14
|
+
);
|
|
13
15
|
expect(skillContent).toContain(
|
|
14
16
|
"same Slack settings handler used by Settings",
|
|
15
17
|
);
|
|
@@ -163,11 +163,11 @@ describe("Slack inbound trusted contact verification", () => {
|
|
|
163
163
|
// Verification code is NOT sent to the requester — only the guardian
|
|
164
164
|
// receives it via the access request notification flow
|
|
165
165
|
|
|
166
|
-
// Channel reply tells user
|
|
166
|
+
// Channel reply tells user they're not recognized yet
|
|
167
167
|
expect(deliverReplyCalls.length).toBe(1);
|
|
168
168
|
expect(
|
|
169
169
|
(deliverReplyCalls[0].payload as Record<string, unknown>).text,
|
|
170
|
-
).toContain("
|
|
170
|
+
).toContain("I don't recognize you yet");
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
test("verification session is identity-bound to the Slack user", async () => {
|
|
@@ -39,6 +39,7 @@ function makeContext(): SurfaceConversationContext {
|
|
|
39
39
|
>(),
|
|
40
40
|
surfaceState: new Map(),
|
|
41
41
|
surfaceUndoStacks: new Map(),
|
|
42
|
+
accumulatedSurfaceState: new Map(),
|
|
42
43
|
surfaceActionRequestIds: new Set<string>(),
|
|
43
44
|
currentTurnSurfaces: [],
|
|
44
45
|
isProcessing: () => false,
|