@vellumai/assistant 0.5.9 → 0.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +48 -48
- package/Dockerfile +2 -0
- package/README.md +1 -1
- package/docs/architecture/integrations.md +6 -13
- package/docs/architecture/memory.md +7 -12
- package/docs/architecture/security.md +5 -5
- package/docs/credential-execution-service.md +9 -9
- package/docs/skills.md +1 -1
- package/node_modules/@vellumai/credential-storage/src/index.ts +2 -2
- package/node_modules/@vellumai/credential-storage/src/static-credentials.ts +1 -1
- package/openapi.yaml +7130 -0
- package/package.json +2 -1
- package/scripts/generate-openapi.ts +562 -0
- package/src/__tests__/acp-session.test.ts +239 -44
- package/src/__tests__/assistant-feature-flag-guard.test.ts +8 -8
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +5 -86
- package/src/__tests__/assistant-feature-flags-integration.test.ts +7 -14
- package/src/__tests__/browser-skill-endstate.test.ts +1 -1
- package/src/__tests__/btw-routes.test.ts +8 -0
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +10 -10
- package/src/__tests__/channel-approvals.test.ts +7 -7
- package/src/__tests__/channel-readiness-service.test.ts +41 -0
- package/src/__tests__/config-schema.test.ts +10 -2
- package/src/__tests__/context-memory-e2e.test.ts +2 -6
- package/src/__tests__/conversation-skill-tools.test.ts +1 -3
- package/src/__tests__/conversation-title-service.test.ts +2 -15
- package/src/__tests__/credential-execution-feature-gates.test.ts +4 -8
- package/src/__tests__/credential-execution-managed-contract.test.ts +8 -8
- package/src/__tests__/credential-security-e2e.test.ts +4 -4
- package/src/__tests__/credential-security-invariants.test.ts +3 -3
- package/src/__tests__/credentials-cli.test.ts +3 -3
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/heartbeat-service.test.ts +35 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +3 -3
- package/src/__tests__/llm-request-log-turn-query.test.ts +64 -0
- package/src/__tests__/log-export-workspace.test.ts +1 -1
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/memory-lifecycle-e2e.test.ts +2 -2
- package/src/__tests__/memory-recall-log-store.test.ts +182 -0
- package/src/__tests__/memory-recall-quality.test.ts +6 -8
- package/src/__tests__/memory-regressions.test.ts +53 -42
- package/src/__tests__/memory-retrieval.benchmark.test.ts +5 -9
- package/src/__tests__/messaging-skill-split.test.ts +2 -17
- package/src/__tests__/oauth-cli.test.ts +98 -551
- package/src/__tests__/platform-callback-registration.test.ts +119 -0
- package/src/__tests__/secret-ingress-channel.test.ts +261 -0
- package/src/__tests__/secret-ingress-cli.test.ts +201 -0
- package/src/__tests__/secret-ingress-http.test.ts +312 -0
- package/src/__tests__/secret-ingress.test.ts +283 -0
- package/src/__tests__/secret-onetime-send.test.ts +4 -4
- package/src/__tests__/skill-feature-flags-integration.test.ts +4 -4
- package/src/__tests__/skill-feature-flags.test.ts +11 -19
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
- package/src/__tests__/skill-load-inline-command.test.ts +3 -3
- package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
- package/src/__tests__/skill-memory.test.ts +2 -4
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -4
- package/src/__tests__/skill-projection.benchmark.test.ts +1 -3
- package/src/__tests__/skills.test.ts +16 -2
- package/src/__tests__/slack-channel-config.test.ts +1 -1
- package/src/__tests__/slack-skill.test.ts +5 -69
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -1
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +5 -238
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +5 -206
- package/src/__tests__/workspace-migration-018-rekey-compound-credential-keys.test.ts +181 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +15 -7
- package/src/acp/client-handler.ts +113 -31
- package/src/acp/session-manager.ts +29 -27
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/cli/AGENTS.md +73 -0
- package/src/cli/commands/autonomy.ts +3 -5
- package/src/cli/commands/credential-execution.ts +1 -2
- package/src/cli/commands/credentials.ts +4 -4
- package/src/cli/commands/memory.ts +2 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +785 -0
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +760 -0
- package/src/cli/commands/oauth/__tests__/mode.test.ts +672 -0
- package/src/cli/commands/oauth/__tests__/ping.test.ts +690 -0
- package/src/cli/commands/oauth/__tests__/status.test.ts +579 -0
- package/src/cli/commands/oauth/__tests__/token.test.ts +467 -0
- package/src/cli/commands/oauth/apps.ts +29 -11
- package/src/cli/commands/oauth/connect.ts +373 -0
- package/src/cli/commands/oauth/connections.ts +14 -493
- package/src/cli/commands/oauth/disconnect.ts +333 -0
- package/src/cli/commands/oauth/index.ts +62 -10
- package/src/cli/commands/oauth/mode.ts +263 -0
- package/src/cli/commands/oauth/ping.ts +222 -0
- package/src/cli/commands/oauth/providers.ts +30 -3
- package/src/cli/commands/oauth/request.ts +576 -0
- package/src/cli/commands/oauth/shared.ts +132 -0
- package/src/cli/commands/oauth/status.ts +202 -0
- package/src/cli/commands/oauth/token.ts +159 -0
- package/src/cli/commands/platform.ts +20 -14
- package/src/cli.ts +82 -17
- package/src/config/assistant-feature-flags.ts +74 -11
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +13 -36
- package/src/config/bundled-skills/messaging/TOOLS.json +9 -9
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
- package/src/config/bundled-skills/notifications/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/SKILL.md +2 -2
- package/src/config/bundled-skills/settings/SKILL.md +5 -3
- package/src/config/bundled-skills/settings/TOOLS.json +17 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +50 -0
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +7 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +6 -1
- package/src/config/bundled-skills/settings/tools/identity-avatar.ts +55 -0
- package/src/config/bundled-skills/skills-catalog/SKILL.md +3 -3
- package/src/config/bundled-skills/slack/SKILL.md +58 -44
- package/src/config/bundled-tool-registry.ts +2 -19
- package/src/config/env.ts +5 -1
- package/src/config/feature-flag-registry.json +57 -41
- package/src/config/loader.ts +4 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/security.ts +9 -1
- package/src/config/schemas/services.ts +1 -1
- package/src/config/skill-state.ts +1 -3
- package/src/config/skills.ts +2 -4
- package/src/credential-execution/feature-gates.ts +9 -16
- package/src/credential-execution/process-manager.ts +12 -0
- package/src/daemon/config-watcher.ts +4 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -0
- package/src/daemon/conversation-agent-loop.ts +49 -2
- package/src/daemon/conversation-memory.ts +0 -1
- package/src/daemon/handlers/config-slack-channel.ts +43 -1
- package/src/daemon/handlers/conversations.ts +41 -33
- package/src/daemon/lifecycle.ts +28 -5
- package/src/daemon/message-types/acp.ts +0 -15
- package/src/daemon/message-types/memory.ts +0 -1
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/schedules.ts +9 -0
- package/src/daemon/server.ts +19 -7
- package/src/email/feature-gate.ts +3 -3
- package/src/heartbeat/heartbeat-service.ts +48 -0
- package/src/inbound/platform-callback-registration.ts +61 -7
- package/src/mcp/mcp-oauth-provider.ts +3 -3
- package/src/memory/app-store.ts +3 -3
- package/src/memory/conversation-crud.ts +124 -0
- package/src/memory/conversation-title-service.ts +7 -17
- package/src/memory/db-init.ts +8 -0
- package/src/memory/embedding-local.ts +47 -2
- package/src/memory/indexer.ts +13 -10
- package/src/memory/items-extractor.ts +12 -4
- package/src/memory/job-utils.ts +5 -0
- package/src/memory/jobs-store.ts +10 -2
- package/src/memory/journal-memory.ts +6 -2
- package/src/memory/llm-request-log-store.ts +88 -21
- package/src/memory/memory-recall-log-store.ts +128 -0
- package/src/memory/migrations/194-memory-recall-logs.ts +50 -0
- package/src/memory/migrations/195-oauth-providers-ping-config.ts +23 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/migrations/validate-migration-state.ts +14 -1
- package/src/memory/retriever.test.ts +4 -5
- package/src/memory/schema/infrastructure.ts +31 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +54 -0
- package/src/oauth/manual-token-connection.ts +5 -5
- package/src/oauth/oauth-store.ts +26 -5
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +2 -2
- package/src/permissions/trust-client.ts +2 -2
- package/src/platform/client.ts +2 -2
- package/src/prompts/journal-context.ts +6 -1
- package/src/providers/anthropic/client.ts +143 -1
- package/src/runtime/auth/__tests__/middleware.test.ts +19 -0
- package/src/runtime/auth/route-policy.ts +0 -1
- package/src/runtime/btw-sidechain.ts +7 -1
- package/src/runtime/channel-approvals.ts +2 -2
- package/src/runtime/channel-readiness-service.ts +30 -7
- package/src/runtime/http-router.ts +31 -0
- package/src/runtime/http-server.ts +21 -4
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/pending-interactions.ts +21 -3
- package/src/runtime/routes/acp-routes.ts +46 -28
- package/src/runtime/routes/app-management-routes.ts +123 -0
- package/src/runtime/routes/app-routes.ts +31 -0
- package/src/runtime/routes/approval-routes.ts +108 -3
- package/src/runtime/routes/attachment-routes.ts +45 -0
- package/src/runtime/routes/avatar-routes.ts +16 -0
- package/src/runtime/routes/brain-graph-routes.ts +18 -0
- package/src/runtime/routes/btw-routes.ts +20 -0
- package/src/runtime/routes/call-routes.ts +81 -0
- package/src/runtime/routes/channel-readiness-routes.ts +48 -7
- package/src/runtime/routes/channel-routes.ts +18 -0
- package/src/runtime/routes/channel-verification-routes.ts +49 -1
- package/src/runtime/routes/contact-routes.ts +77 -0
- package/src/runtime/routes/conversation-attention-routes.ts +37 -0
- package/src/runtime/routes/conversation-management-routes.ts +94 -0
- package/src/runtime/routes/conversation-query-routes.ts +78 -0
- package/src/runtime/routes/conversation-routes.ts +115 -38
- package/src/runtime/routes/conversation-starter-routes.ts +29 -0
- package/src/runtime/routes/debug-routes.ts +23 -0
- package/src/runtime/routes/diagnostics-routes.ts +30 -0
- package/src/runtime/routes/documents-routes.ts +42 -0
- package/src/runtime/routes/events-routes.ts +10 -0
- package/src/runtime/routes/global-search-routes.ts +35 -0
- package/src/runtime/routes/guardian-action-routes.ts +47 -2
- package/src/runtime/routes/guardian-approval-prompt.ts +77 -2
- package/src/runtime/routes/heartbeat-routes.ts +278 -0
- package/src/runtime/routes/host-bash-routes.ts +16 -1
- package/src/runtime/routes/host-cu-routes.ts +23 -1
- package/src/runtime/routes/host-file-routes.ts +18 -1
- package/src/runtime/routes/identity-routes.ts +35 -0
- package/src/runtime/routes/inbound-message-handler.ts +46 -25
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +30 -2
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -2
- package/src/runtime/routes/integrations/twilio.ts +32 -22
- package/src/runtime/routes/invite-routes.ts +83 -0
- package/src/runtime/routes/log-export-routes.ts +14 -0
- package/src/runtime/routes/memory-item-routes.ts +99 -1
- package/src/runtime/routes/migration-rollback-routes.ts +25 -0
- package/src/runtime/routes/migration-routes.ts +40 -0
- package/src/runtime/routes/notification-routes.ts +20 -0
- package/src/runtime/routes/oauth-apps.ts +11 -3
- package/src/runtime/routes/pairing-routes.ts +15 -0
- package/src/runtime/routes/recording-routes.ts +72 -0
- package/src/runtime/routes/schedule-routes.ts +77 -5
- package/src/runtime/routes/secret-routes.ts +63 -1
- package/src/runtime/routes/settings-routes.ts +91 -1
- package/src/runtime/routes/skills-routes.ts +98 -16
- package/src/runtime/routes/subagents-routes.ts +38 -3
- package/src/runtime/routes/surface-action-routes.ts +66 -24
- package/src/runtime/routes/surface-content-routes.ts +20 -0
- package/src/runtime/routes/telemetry-routes.ts +12 -0
- package/src/runtime/routes/trace-event-routes.ts +25 -0
- package/src/runtime/routes/trust-rules-routes.ts +46 -0
- package/src/runtime/routes/tts-routes.ts +15 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +38 -0
- package/src/runtime/routes/usage-routes.ts +59 -0
- package/src/runtime/routes/watch-routes.ts +28 -0
- package/src/runtime/routes/work-items-routes.ts +59 -0
- package/src/runtime/routes/workspace-commit-routes.ts +12 -0
- package/src/runtime/routes/workspace-routes.ts +102 -0
- package/src/schedule/scheduler.ts +7 -1
- package/src/security/AGENTS.md +7 -0
- package/src/security/credential-backend.ts +1 -1
- package/src/security/encrypted-store.ts +3 -3
- package/src/security/oauth2.ts +55 -0
- package/src/security/secret-ingress.ts +174 -0
- package/src/security/secret-patterns.ts +133 -0
- package/src/security/secret-scanner.ts +28 -117
- package/src/signals/confirm.ts +12 -8
- package/src/signals/user-message.ts +18 -3
- package/src/skills/skill-memory.ts +1 -2
- package/src/tasks/task-runner.ts +7 -1
- package/src/tools/credentials/broker.ts +1 -1
- package/src/tools/credentials/metadata-store.ts +1 -1
- package/src/tools/credentials/vault.ts +2 -3
- package/src/tools/memory/definitions.ts +1 -1
- package/src/tools/memory/handlers.test.ts +2 -4
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/tool-manifest.ts +1 -1
- package/src/util/log-redact.ts +9 -34
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +13 -148
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +7 -145
- package/src/workspace/migrations/AGENTS.md +11 -0
- package/src/workspace/migrations/runner.ts +16 -6
- package/src/workspace/migrations/types.ts +7 -0
- package/docs/architecture/keychain-broker.md +0 -69
- package/src/__tests__/keychain-broker-client.test.ts +0 -800
- package/src/cli/commands/oauth/platform.ts +0 -525
- package/src/config/bundled-skills/slack/TOOLS.json +0 -272
- package/src/config/bundled-skills/slack/tools/shared.ts +0 -34
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +0 -38
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +0 -146
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +0 -105
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +0 -26
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +0 -25
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +0 -372
- package/src/security/keychain-broker-client.ts +0 -446
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { and, asc, count, desc, eq, inArray, like, ne, or } from "drizzle-orm";
|
|
12
12
|
import { v4 as uuid } from "uuid";
|
|
13
|
+
import { z } from "zod";
|
|
13
14
|
|
|
14
15
|
import { getConfig } from "../../config/loader.js";
|
|
15
16
|
import { getDb } from "../../memory/db.js";
|
|
@@ -597,7 +598,11 @@ export async function handleUpdateMemoryItem(
|
|
|
597
598
|
// If sourceType was set (either directly or via mapping), also write verificationState
|
|
598
599
|
if (body.sourceType !== undefined && body.verificationState === undefined) {
|
|
599
600
|
set.verificationState =
|
|
600
|
-
body.sourceType === "tool"
|
|
601
|
+
body.sourceType === "tool"
|
|
602
|
+
? "user_confirmed"
|
|
603
|
+
: existing.verificationState === "user_reported"
|
|
604
|
+
? "user_reported"
|
|
605
|
+
: "assistant_inferred";
|
|
601
606
|
}
|
|
602
607
|
|
|
603
608
|
// If subject, statement, or kind changed, recompute fingerprint
|
|
@@ -717,29 +722,122 @@ export function memoryItemRouteDefinitions(): RouteDefinition[] {
|
|
|
717
722
|
{
|
|
718
723
|
endpoint: "memory-items",
|
|
719
724
|
method: "GET",
|
|
725
|
+
summary: "List memory items",
|
|
726
|
+
description:
|
|
727
|
+
"Return memory items with filtering, search, sorting, and pagination.",
|
|
728
|
+
tags: ["memory"],
|
|
729
|
+
queryParams: [
|
|
730
|
+
{
|
|
731
|
+
name: "kind",
|
|
732
|
+
schema: { type: "string" },
|
|
733
|
+
description: "Filter by kind",
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
name: "status",
|
|
737
|
+
schema: { type: "string" },
|
|
738
|
+
description: "Filter by status (default active)",
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
name: "search",
|
|
742
|
+
schema: { type: "string" },
|
|
743
|
+
description: "Full-text search query",
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
name: "sort",
|
|
747
|
+
schema: { type: "string" },
|
|
748
|
+
description: "Sort field (default lastSeenAt)",
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
name: "order",
|
|
752
|
+
schema: { type: "string" },
|
|
753
|
+
description: "asc or desc (default desc)",
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
name: "limit",
|
|
757
|
+
schema: { type: "integer" },
|
|
758
|
+
description: "Max results (default 100)",
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
name: "offset",
|
|
762
|
+
schema: { type: "integer" },
|
|
763
|
+
description: "Pagination offset",
|
|
764
|
+
},
|
|
765
|
+
],
|
|
766
|
+
responseBody: z.object({
|
|
767
|
+
items: z.array(z.unknown()).describe("Memory item objects"),
|
|
768
|
+
total: z.number(),
|
|
769
|
+
}),
|
|
720
770
|
handler: (ctx) => handleListMemoryItems(ctx.url),
|
|
721
771
|
},
|
|
722
772
|
{
|
|
723
773
|
endpoint: "memory-items/:id",
|
|
724
774
|
method: "GET",
|
|
725
775
|
policyKey: "memory-items",
|
|
776
|
+
summary: "Get a memory item",
|
|
777
|
+
description:
|
|
778
|
+
"Return a single memory item by ID with supersession metadata.",
|
|
779
|
+
tags: ["memory"],
|
|
780
|
+
responseBody: z.object({
|
|
781
|
+
item: z
|
|
782
|
+
.object({})
|
|
783
|
+
.passthrough()
|
|
784
|
+
.describe("Memory item with scopeLabel and supersession info"),
|
|
785
|
+
}),
|
|
726
786
|
handler: (ctx) => handleGetMemoryItem(ctx),
|
|
727
787
|
},
|
|
728
788
|
{
|
|
729
789
|
endpoint: "memory-items",
|
|
730
790
|
method: "POST",
|
|
791
|
+
summary: "Create a memory item",
|
|
792
|
+
description: "Create a new memory item and enqueue embedding.",
|
|
793
|
+
tags: ["memory"],
|
|
794
|
+
requestBody: z.object({
|
|
795
|
+
kind: z
|
|
796
|
+
.string()
|
|
797
|
+
.describe("Memory kind (identity, preference, project, etc.)"),
|
|
798
|
+
subject: z.string().describe("Subject line"),
|
|
799
|
+
statement: z.string().describe("Statement content"),
|
|
800
|
+
importance: z
|
|
801
|
+
.number()
|
|
802
|
+
.describe("Importance score (default 0.8)")
|
|
803
|
+
.optional(),
|
|
804
|
+
}),
|
|
805
|
+
responseBody: z.object({
|
|
806
|
+
item: z.object({}).passthrough().describe("Created memory item"),
|
|
807
|
+
}),
|
|
731
808
|
handler: (ctx) => handleCreateMemoryItem(ctx),
|
|
732
809
|
},
|
|
733
810
|
{
|
|
734
811
|
endpoint: "memory-items/:id",
|
|
735
812
|
method: "PATCH",
|
|
736
813
|
policyKey: "memory-items",
|
|
814
|
+
summary: "Update a memory item",
|
|
815
|
+
description: "Partially update fields on an existing memory item.",
|
|
816
|
+
tags: ["memory"],
|
|
817
|
+
requestBody: z.object({
|
|
818
|
+
subject: z.string(),
|
|
819
|
+
statement: z.string(),
|
|
820
|
+
kind: z.string(),
|
|
821
|
+
status: z.string(),
|
|
822
|
+
importance: z.number(),
|
|
823
|
+
sourceType: z.string(),
|
|
824
|
+
verificationState: z.string(),
|
|
825
|
+
}),
|
|
826
|
+
responseBody: z.object({
|
|
827
|
+
item: z.object({}).passthrough().describe("Updated memory item"),
|
|
828
|
+
}),
|
|
737
829
|
handler: (ctx) => handleUpdateMemoryItem(ctx),
|
|
738
830
|
},
|
|
739
831
|
{
|
|
740
832
|
endpoint: "memory-items/:id",
|
|
741
833
|
method: "DELETE",
|
|
742
834
|
policyKey: "memory-items",
|
|
835
|
+
summary: "Delete a memory item",
|
|
836
|
+
description: "Delete a memory item and its embeddings.",
|
|
837
|
+
tags: ["memory"],
|
|
838
|
+
responseBody: z.object({
|
|
839
|
+
ok: z.boolean(),
|
|
840
|
+
}),
|
|
743
841
|
handler: (ctx) => handleDeleteMemoryItem(ctx),
|
|
744
842
|
},
|
|
745
843
|
];
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* the same pattern as other gateway-forwarded control-plane endpoints.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
10
12
|
import { getDb } from "../../memory/db-connection.js";
|
|
11
13
|
import { getMaxMigrationVersion } from "../../memory/migrations/registry.js";
|
|
12
14
|
import { rollbackMemoryMigration } from "../../memory/migrations/validate-migration-state.js";
|
|
@@ -25,6 +27,29 @@ export function migrationRollbackRouteDefinitions(): RouteDefinition[] {
|
|
|
25
27
|
{
|
|
26
28
|
endpoint: "admin/rollback-migrations",
|
|
27
29
|
method: "POST",
|
|
30
|
+
summary: "Rollback migrations",
|
|
31
|
+
description:
|
|
32
|
+
"Roll back DB and/or workspace migrations to a specified target version. Restricted to gateway service principals.",
|
|
33
|
+
tags: ["admin"],
|
|
34
|
+
requestBody: z.object({
|
|
35
|
+
targetDbVersion: z
|
|
36
|
+
.number()
|
|
37
|
+
.int()
|
|
38
|
+
.describe("Target DB migration version"),
|
|
39
|
+
targetWorkspaceMigrationId: z
|
|
40
|
+
.string()
|
|
41
|
+
.describe("Target workspace migration ID"),
|
|
42
|
+
rollbackToRegistryCeiling: z
|
|
43
|
+
.boolean()
|
|
44
|
+
.describe("Auto-determine targets from daemon registry ceilings"),
|
|
45
|
+
}),
|
|
46
|
+
responseBody: z.object({
|
|
47
|
+
ok: z.boolean(),
|
|
48
|
+
rolledBack: z
|
|
49
|
+
.object({})
|
|
50
|
+
.passthrough()
|
|
51
|
+
.describe("Lists of rolled-back DB and workspace migrations"),
|
|
52
|
+
}),
|
|
28
53
|
handler: async ({ req }) => {
|
|
29
54
|
let body: unknown;
|
|
30
55
|
try {
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
import { Database } from "bun:sqlite";
|
|
16
16
|
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
|
|
17
19
|
import { invalidateConfigCache } from "../../config/loader.js";
|
|
18
20
|
import { getDb, resetDb } from "../../memory/db-connection.js";
|
|
19
21
|
import { validateMigrationState } from "../../memory/migrations/validate-migration-state.js";
|
|
@@ -474,21 +476,59 @@ export function migrationRouteDefinitions(): RouteDefinition[] {
|
|
|
474
476
|
{
|
|
475
477
|
endpoint: "migrations/validate",
|
|
476
478
|
method: "POST",
|
|
479
|
+
summary: "Validate a .vbundle archive",
|
|
480
|
+
description:
|
|
481
|
+
"Upload a .vbundle archive for validation. Accepts raw binary or multipart form data.",
|
|
482
|
+
tags: ["migrations"],
|
|
483
|
+
responseBody: z.object({
|
|
484
|
+
is_valid: z.boolean(),
|
|
485
|
+
errors: z.array(z.unknown()),
|
|
486
|
+
manifest: z.object({}).passthrough(),
|
|
487
|
+
}),
|
|
477
488
|
handler: async ({ req }) => handleMigrationValidate(req),
|
|
478
489
|
},
|
|
479
490
|
{
|
|
480
491
|
endpoint: "migrations/export",
|
|
481
492
|
method: "POST",
|
|
493
|
+
summary: "Export a .vbundle archive",
|
|
494
|
+
description:
|
|
495
|
+
"Generate and download a .vbundle archive of the assistant's data. Optional JSON body for metadata.",
|
|
496
|
+
tags: ["migrations"],
|
|
497
|
+
requestBody: z.object({
|
|
498
|
+
description: z.string().describe("Human-readable export description"),
|
|
499
|
+
}),
|
|
482
500
|
handler: async ({ req }) => handleMigrationExport(req),
|
|
483
501
|
},
|
|
484
502
|
{
|
|
485
503
|
endpoint: "migrations/import-preflight",
|
|
486
504
|
method: "POST",
|
|
505
|
+
summary: "Dry-run import analysis",
|
|
506
|
+
description:
|
|
507
|
+
"Validate a .vbundle archive and return a report of what would change on import without modifying data.",
|
|
508
|
+
tags: ["migrations"],
|
|
509
|
+
responseBody: z.object({
|
|
510
|
+
can_import: z.boolean(),
|
|
511
|
+
summary: z.object({}).passthrough(),
|
|
512
|
+
files: z.array(z.unknown()),
|
|
513
|
+
conflicts: z.array(z.unknown()),
|
|
514
|
+
manifest: z.object({}).passthrough(),
|
|
515
|
+
}),
|
|
487
516
|
handler: async ({ req }) => handleMigrationImportPreflight(req),
|
|
488
517
|
},
|
|
489
518
|
{
|
|
490
519
|
endpoint: "migrations/import",
|
|
491
520
|
method: "POST",
|
|
521
|
+
summary: "Import a .vbundle archive",
|
|
522
|
+
description:
|
|
523
|
+
"Commit a .vbundle archive import to disk — destructive. Backs up existing files before overwriting.",
|
|
524
|
+
tags: ["migrations"],
|
|
525
|
+
responseBody: z.object({
|
|
526
|
+
success: z.boolean(),
|
|
527
|
+
summary: z.object({}).passthrough(),
|
|
528
|
+
files: z.array(z.unknown()),
|
|
529
|
+
manifest: z.object({}).passthrough(),
|
|
530
|
+
warnings: z.array(z.unknown()),
|
|
531
|
+
}),
|
|
492
532
|
handler: async ({ req }) => handleMigrationImport(req),
|
|
493
533
|
},
|
|
494
534
|
];
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { eq } from "drizzle-orm";
|
|
9
|
+
import { z } from "zod";
|
|
9
10
|
|
|
10
11
|
import { getDb } from "../../memory/db.js";
|
|
11
12
|
import { notificationDeliveries } from "../../memory/schema.js";
|
|
@@ -19,6 +20,25 @@ export function notificationRouteDefinitions(): RouteDefinition[] {
|
|
|
19
20
|
endpoint: "notification-intent-result",
|
|
20
21
|
method: "POST",
|
|
21
22
|
policyKey: "notification-intent-result",
|
|
23
|
+
summary: "Report notification delivery result",
|
|
24
|
+
description:
|
|
25
|
+
"Client acknowledgment for local notification delivery outcome.",
|
|
26
|
+
tags: ["notifications"],
|
|
27
|
+
requestBody: z.object({
|
|
28
|
+
deliveryId: z.string().describe("Notification delivery ID"),
|
|
29
|
+
success: z.boolean().describe("Whether delivery succeeded").optional(),
|
|
30
|
+
errorMessage: z
|
|
31
|
+
.string()
|
|
32
|
+
.describe("Error message if delivery failed")
|
|
33
|
+
.optional(),
|
|
34
|
+
errorCode: z
|
|
35
|
+
.string()
|
|
36
|
+
.describe("Error code if delivery failed")
|
|
37
|
+
.optional(),
|
|
38
|
+
}),
|
|
39
|
+
responseBody: z.object({
|
|
40
|
+
ok: z.boolean(),
|
|
41
|
+
}),
|
|
22
42
|
handler: async ({ req }) => {
|
|
23
43
|
const body = (await req.json()) as {
|
|
24
44
|
deliveryId?: string;
|
|
@@ -21,9 +21,13 @@ import {
|
|
|
21
21
|
import { httpError } from "../http-errors.js";
|
|
22
22
|
import type { RouteDefinition } from "../http-router.js";
|
|
23
23
|
|
|
24
|
-
function parseGrantedScopes(
|
|
24
|
+
function parseGrantedScopes(
|
|
25
|
+
grantedScopes: string | string[] | null | undefined,
|
|
26
|
+
): string[] {
|
|
25
27
|
if (Array.isArray(grantedScopes)) {
|
|
26
|
-
return grantedScopes.filter(
|
|
28
|
+
return grantedScopes.filter(
|
|
29
|
+
(scope): scope is string => typeof scope === "string",
|
|
30
|
+
);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
if (typeof grantedScopes !== "string" || grantedScopes.trim() === "") {
|
|
@@ -159,7 +163,11 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
159
163
|
handler: async ({ params }) => {
|
|
160
164
|
const app = getApp(params.id);
|
|
161
165
|
if (!app) {
|
|
162
|
-
return httpError(
|
|
166
|
+
return httpError(
|
|
167
|
+
"NOT_FOUND",
|
|
168
|
+
`OAuth app not found: ${params.id}`,
|
|
169
|
+
404,
|
|
170
|
+
);
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
// Disconnect all connections for this app first to clean up tokens.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Pairing HTTP route handlers for device pairing flow.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
|
|
5
7
|
import {
|
|
6
8
|
hashDeviceId,
|
|
7
9
|
isDeviceApproved,
|
|
@@ -417,6 +419,19 @@ export function pairingRouteDefinitions(deps: {
|
|
|
417
419
|
{
|
|
418
420
|
endpoint: "pairing/register",
|
|
419
421
|
method: "POST",
|
|
422
|
+
summary: "Register pairing request",
|
|
423
|
+
description:
|
|
424
|
+
"Pre-register a pairing request when the QR code is displayed.",
|
|
425
|
+
tags: ["pairing"],
|
|
426
|
+
requestBody: z.object({
|
|
427
|
+
pairingRequestId: z.string(),
|
|
428
|
+
pairingSecret: z.string(),
|
|
429
|
+
gatewayUrl: z.string(),
|
|
430
|
+
localLanUrl: z.string().optional(),
|
|
431
|
+
}),
|
|
432
|
+
responseBody: z.object({
|
|
433
|
+
ok: z.boolean(),
|
|
434
|
+
}),
|
|
420
435
|
handler: async ({ req }) =>
|
|
421
436
|
handlePairingRegister(req, deps.getPairingContext()),
|
|
422
437
|
},
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* require `settings.read`.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
12
14
|
import {
|
|
13
15
|
getActiveRestartToken,
|
|
14
16
|
handleRecordingPause,
|
|
@@ -298,36 +300,106 @@ export function recordingRouteDefinitions(deps: {
|
|
|
298
300
|
endpoint: "recordings/start",
|
|
299
301
|
method: "POST",
|
|
300
302
|
policyKey: "recordings/start",
|
|
303
|
+
summary: "Start recording",
|
|
304
|
+
description: "Start a screen recording for a conversation.",
|
|
305
|
+
tags: ["recordings"],
|
|
306
|
+
requestBody: z.object({
|
|
307
|
+
conversationId: z.string(),
|
|
308
|
+
options: z
|
|
309
|
+
.object({})
|
|
310
|
+
.passthrough()
|
|
311
|
+
.describe("Recording options")
|
|
312
|
+
.optional(),
|
|
313
|
+
}),
|
|
314
|
+
responseBody: z.object({
|
|
315
|
+
recordingId: z.string(),
|
|
316
|
+
}),
|
|
301
317
|
handler: async ({ req }) => handleStartRecording(req, getDeps()),
|
|
302
318
|
},
|
|
303
319
|
{
|
|
304
320
|
endpoint: "recordings/stop",
|
|
305
321
|
method: "POST",
|
|
306
322
|
policyKey: "recordings/stop",
|
|
323
|
+
summary: "Stop recording",
|
|
324
|
+
description: "Stop the active screen recording.",
|
|
325
|
+
tags: ["recordings"],
|
|
326
|
+
requestBody: z.object({
|
|
327
|
+
conversationId: z.string(),
|
|
328
|
+
}),
|
|
329
|
+
responseBody: z.object({
|
|
330
|
+
recordingId: z.string(),
|
|
331
|
+
stopped: z.boolean(),
|
|
332
|
+
}),
|
|
307
333
|
handler: async ({ req }) => handleStopRecording(req, getDeps()),
|
|
308
334
|
},
|
|
309
335
|
{
|
|
310
336
|
endpoint: "recordings/pause",
|
|
311
337
|
method: "POST",
|
|
312
338
|
policyKey: "recordings/pause",
|
|
339
|
+
summary: "Pause recording",
|
|
340
|
+
description: "Pause the active screen recording.",
|
|
341
|
+
tags: ["recordings"],
|
|
342
|
+
requestBody: z.object({
|
|
343
|
+
conversationId: z.string(),
|
|
344
|
+
}),
|
|
345
|
+
responseBody: z.object({
|
|
346
|
+
recordingId: z.string(),
|
|
347
|
+
paused: z.boolean(),
|
|
348
|
+
}),
|
|
313
349
|
handler: async ({ req }) => handlePauseRecording(req, getDeps()),
|
|
314
350
|
},
|
|
315
351
|
{
|
|
316
352
|
endpoint: "recordings/resume",
|
|
317
353
|
method: "POST",
|
|
318
354
|
policyKey: "recordings/resume",
|
|
355
|
+
summary: "Resume recording",
|
|
356
|
+
description: "Resume a paused screen recording.",
|
|
357
|
+
tags: ["recordings"],
|
|
358
|
+
requestBody: z.object({
|
|
359
|
+
conversationId: z.string(),
|
|
360
|
+
}),
|
|
361
|
+
responseBody: z.object({
|
|
362
|
+
recordingId: z.string(),
|
|
363
|
+
resumed: z.boolean(),
|
|
364
|
+
}),
|
|
319
365
|
handler: async ({ req }) => handleResumeRecording(req, getDeps()),
|
|
320
366
|
},
|
|
321
367
|
{
|
|
322
368
|
endpoint: "recordings/status",
|
|
323
369
|
method: "GET",
|
|
324
370
|
policyKey: "recordings/status",
|
|
371
|
+
summary: "Get recording status",
|
|
372
|
+
description: "Return the current recording state.",
|
|
373
|
+
tags: ["recordings"],
|
|
374
|
+
responseBody: z.object({
|
|
375
|
+
idle: z.boolean(),
|
|
376
|
+
restartInProgress: z.boolean(),
|
|
377
|
+
}),
|
|
325
378
|
handler: () => handleGetRecordingStatus(),
|
|
326
379
|
},
|
|
327
380
|
{
|
|
328
381
|
endpoint: "recordings/status",
|
|
329
382
|
method: "POST",
|
|
330
383
|
policyKey: "recordings/status:POST",
|
|
384
|
+
summary: "Post recording status",
|
|
385
|
+
description: "Recording lifecycle callback from the client.",
|
|
386
|
+
tags: ["recordings"],
|
|
387
|
+
requestBody: z.object({
|
|
388
|
+
conversationId: z.string(),
|
|
389
|
+
status: z
|
|
390
|
+
.string()
|
|
391
|
+
.describe(
|
|
392
|
+
"started, stopped, failed, restart_cancelled, paused, resumed",
|
|
393
|
+
),
|
|
394
|
+
filePath: z.string().optional(),
|
|
395
|
+
durationMs: z.number().optional(),
|
|
396
|
+
error: z.string().optional(),
|
|
397
|
+
attachToConversationId: z.string().optional(),
|
|
398
|
+
operationToken: z.string().optional(),
|
|
399
|
+
}),
|
|
400
|
+
responseBody: z.object({
|
|
401
|
+
ok: z.boolean(),
|
|
402
|
+
}),
|
|
331
403
|
handler: async ({ req }) => handlePostRecordingStatus(req, getDeps()),
|
|
332
404
|
},
|
|
333
405
|
];
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* HTTP route handlers for schedule management.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
7
9
|
import { bootstrapConversation } from "../../memory/conversation-bootstrap.js";
|
|
8
10
|
import {
|
|
9
11
|
cancelSchedule,
|
|
@@ -112,11 +114,27 @@ function handleUpdateSchedule(
|
|
|
112
114
|
): Response {
|
|
113
115
|
const updates: Record<string, unknown> = {};
|
|
114
116
|
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
+
if (
|
|
118
|
+
"mode" in body &&
|
|
119
|
+
!VALID_MODES.includes(body.mode as (typeof VALID_MODES)[number])
|
|
120
|
+
) {
|
|
121
|
+
return httpError(
|
|
122
|
+
"BAD_REQUEST",
|
|
123
|
+
`Invalid mode: must be one of ${VALID_MODES.join(", ")}`,
|
|
124
|
+
400,
|
|
125
|
+
);
|
|
117
126
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
127
|
+
if (
|
|
128
|
+
"routingIntent" in body &&
|
|
129
|
+
!VALID_ROUTING_INTENTS.includes(
|
|
130
|
+
body.routingIntent as (typeof VALID_ROUTING_INTENTS)[number],
|
|
131
|
+
)
|
|
132
|
+
) {
|
|
133
|
+
return httpError(
|
|
134
|
+
"BAD_REQUEST",
|
|
135
|
+
`Invalid routingIntent: must be one of ${VALID_ROUTING_INTENTS.join(", ")}`,
|
|
136
|
+
400,
|
|
137
|
+
);
|
|
120
138
|
}
|
|
121
139
|
|
|
122
140
|
for (const key of [
|
|
@@ -276,12 +294,27 @@ export function scheduleRouteDefinitions(deps: {
|
|
|
276
294
|
endpoint: "schedules",
|
|
277
295
|
method: "GET",
|
|
278
296
|
policyKey: "schedules",
|
|
297
|
+
summary: "List schedules",
|
|
298
|
+
description: "Return all scheduled jobs.",
|
|
299
|
+
tags: ["schedules"],
|
|
300
|
+
responseBody: z.object({
|
|
301
|
+
schedules: z.array(z.unknown()).describe("Schedule objects"),
|
|
302
|
+
}),
|
|
279
303
|
handler: () => handleListSchedules(),
|
|
280
304
|
},
|
|
281
305
|
{
|
|
282
306
|
endpoint: "schedules/:id/toggle",
|
|
283
307
|
method: "POST",
|
|
284
308
|
policyKey: "schedules/toggle",
|
|
309
|
+
summary: "Toggle schedule",
|
|
310
|
+
description: "Enable or disable a schedule.",
|
|
311
|
+
tags: ["schedules"],
|
|
312
|
+
requestBody: z.object({
|
|
313
|
+
enabled: z.boolean().describe("New enabled state"),
|
|
314
|
+
}),
|
|
315
|
+
responseBody: z.object({
|
|
316
|
+
schedules: z.array(z.unknown()).describe("Updated schedule list"),
|
|
317
|
+
}),
|
|
285
318
|
handler: async ({ req, params }) => {
|
|
286
319
|
const body = (await req.json()) as { enabled?: boolean };
|
|
287
320
|
if (body.enabled === undefined) {
|
|
@@ -294,16 +327,43 @@ export function scheduleRouteDefinitions(deps: {
|
|
|
294
327
|
endpoint: "schedules/:id",
|
|
295
328
|
method: "DELETE",
|
|
296
329
|
policyKey: "schedules",
|
|
330
|
+
summary: "Delete schedule",
|
|
331
|
+
description: "Remove a schedule by ID.",
|
|
332
|
+
tags: ["schedules"],
|
|
333
|
+
responseBody: z.object({
|
|
334
|
+
schedules: z.array(z.unknown()).describe("Updated schedule list"),
|
|
335
|
+
}),
|
|
297
336
|
handler: ({ params }) => handleDeleteSchedule(params.id),
|
|
298
337
|
},
|
|
299
338
|
{
|
|
300
339
|
endpoint: "schedules/:id",
|
|
301
340
|
method: "PATCH",
|
|
302
341
|
policyKey: "schedules",
|
|
342
|
+
summary: "Update schedule",
|
|
343
|
+
description: "Partially update fields on a schedule.",
|
|
344
|
+
tags: ["schedules"],
|
|
345
|
+
requestBody: z.object({
|
|
346
|
+
name: z.string(),
|
|
347
|
+
expression: z.string(),
|
|
348
|
+
timezone: z.string(),
|
|
349
|
+
message: z.string(),
|
|
350
|
+
mode: z.string().describe("notify or execute"),
|
|
351
|
+
routingIntent: z
|
|
352
|
+
.string()
|
|
353
|
+
.describe("single_channel, multi_channel, or all_channels"),
|
|
354
|
+
quiet: z.boolean(),
|
|
355
|
+
}),
|
|
356
|
+
responseBody: z.object({
|
|
357
|
+
schedules: z.array(z.unknown()).describe("Updated schedule list"),
|
|
358
|
+
}),
|
|
303
359
|
handler: async ({ req, params }) => {
|
|
304
360
|
const body: unknown = await req.json();
|
|
305
361
|
if (typeof body !== "object" || !body || Array.isArray(body)) {
|
|
306
|
-
return httpError(
|
|
362
|
+
return httpError(
|
|
363
|
+
"BAD_REQUEST",
|
|
364
|
+
"Request body must be a JSON object",
|
|
365
|
+
400,
|
|
366
|
+
);
|
|
307
367
|
}
|
|
308
368
|
return handleUpdateSchedule(params.id, body as Record<string, unknown>);
|
|
309
369
|
},
|
|
@@ -312,6 +372,12 @@ export function scheduleRouteDefinitions(deps: {
|
|
|
312
372
|
endpoint: "schedules/:id/run",
|
|
313
373
|
method: "POST",
|
|
314
374
|
policyKey: "schedules/run",
|
|
375
|
+
summary: "Run schedule now",
|
|
376
|
+
description: "Trigger an immediate execution of a schedule.",
|
|
377
|
+
tags: ["schedules"],
|
|
378
|
+
responseBody: z.object({
|
|
379
|
+
schedules: z.array(z.unknown()).describe("Updated schedule list"),
|
|
380
|
+
}),
|
|
315
381
|
handler: async ({ params }) =>
|
|
316
382
|
handleRunScheduleNow(params.id, deps.sendMessageDeps),
|
|
317
383
|
},
|
|
@@ -319,6 +385,12 @@ export function scheduleRouteDefinitions(deps: {
|
|
|
319
385
|
endpoint: "schedules/:id/cancel",
|
|
320
386
|
method: "POST",
|
|
321
387
|
policyKey: "schedules/cancel",
|
|
388
|
+
summary: "Cancel schedule",
|
|
389
|
+
description: "Cancel a pending schedule.",
|
|
390
|
+
tags: ["schedules"],
|
|
391
|
+
responseBody: z.object({
|
|
392
|
+
schedules: z.array(z.unknown()).describe("Updated schedule list"),
|
|
393
|
+
}),
|
|
322
394
|
handler: ({ params }) => handleCancelSchedule(params.id),
|
|
323
395
|
},
|
|
324
396
|
];
|