@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
|
@@ -18,6 +18,8 @@ import { stat } from "node:fs/promises";
|
|
|
18
18
|
import { homedir } from "node:os";
|
|
19
19
|
import { dirname, join } from "node:path";
|
|
20
20
|
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
|
|
21
23
|
import { packageApp } from "../../bundler/app-bundler.js";
|
|
22
24
|
import { compileApp } from "../../bundler/app-compiler.js";
|
|
23
25
|
import { scanBundle } from "../../bundler/bundle-scanner.js";
|
|
@@ -378,6 +380,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
378
380
|
endpoint: "apps",
|
|
379
381
|
method: "GET",
|
|
380
382
|
policyKey: "apps",
|
|
383
|
+
summary: "List apps",
|
|
384
|
+
description: "Return all locally installed apps.",
|
|
385
|
+
tags: ["apps"],
|
|
386
|
+
responseBody: z.object({
|
|
387
|
+
apps: z.array(z.unknown()).describe("Array of app summary objects"),
|
|
388
|
+
}),
|
|
381
389
|
handler: () => {
|
|
382
390
|
try {
|
|
383
391
|
const apps = listAppsFiltered();
|
|
@@ -400,6 +408,13 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
400
408
|
endpoint: "apps/open-bundle",
|
|
401
409
|
method: "POST",
|
|
402
410
|
policyKey: "apps/open-bundle",
|
|
411
|
+
summary: "Open a .vbundle file",
|
|
412
|
+
description:
|
|
413
|
+
"Scan and validate a .vbundle file from disk and return its manifest.",
|
|
414
|
+
tags: ["apps"],
|
|
415
|
+
requestBody: z.object({
|
|
416
|
+
filePath: z.string().describe("Absolute path to the .vbundle file"),
|
|
417
|
+
}),
|
|
403
418
|
handler: async ({ req }) => {
|
|
404
419
|
try {
|
|
405
420
|
const body = (await req.json()) as { filePath?: string };
|
|
@@ -429,6 +444,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
429
444
|
endpoint: "apps/shared",
|
|
430
445
|
method: "GET",
|
|
431
446
|
policyKey: "apps/shared-list",
|
|
447
|
+
summary: "List shared apps",
|
|
448
|
+
description: "Return all apps available via cloud share links.",
|
|
449
|
+
tags: ["apps"],
|
|
450
|
+
responseBody: z.object({
|
|
451
|
+
apps: z.array(z.unknown()).describe("Array of shared app objects"),
|
|
452
|
+
}),
|
|
432
453
|
handler: () => {
|
|
433
454
|
try {
|
|
434
455
|
const apps = listSharedApps();
|
|
@@ -451,6 +472,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
451
472
|
endpoint: "apps/fork",
|
|
452
473
|
method: "POST",
|
|
453
474
|
policyKey: "apps/fork",
|
|
475
|
+
summary: "Fork a shared app",
|
|
476
|
+
description: "Create a local copy of a shared app by its UUID.",
|
|
477
|
+
tags: ["apps"],
|
|
478
|
+
requestBody: z.object({
|
|
479
|
+
uuid: z.string().describe("UUID of the shared app to fork"),
|
|
480
|
+
}),
|
|
454
481
|
handler: async ({ req }) => {
|
|
455
482
|
try {
|
|
456
483
|
const body = (await req.json()) as { uuid?: string };
|
|
@@ -479,6 +506,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
479
506
|
endpoint: "apps/gallery/install",
|
|
480
507
|
method: "POST",
|
|
481
508
|
policyKey: "apps/gallery/install",
|
|
509
|
+
summary: "Install a gallery app",
|
|
510
|
+
description: "Install an app from the built-in gallery by its ID.",
|
|
511
|
+
tags: ["apps"],
|
|
512
|
+
requestBody: z.object({
|
|
513
|
+
galleryAppId: z.string(),
|
|
514
|
+
}),
|
|
482
515
|
handler: async ({ req }) => {
|
|
483
516
|
try {
|
|
484
517
|
const body = (await req.json()) as { galleryAppId?: string };
|
|
@@ -505,6 +538,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
505
538
|
endpoint: "apps/gallery",
|
|
506
539
|
method: "GET",
|
|
507
540
|
policyKey: "apps/gallery",
|
|
541
|
+
summary: "List gallery apps",
|
|
542
|
+
description: "Return the built-in app gallery catalog.",
|
|
543
|
+
tags: ["apps"],
|
|
544
|
+
responseBody: z.object({
|
|
545
|
+
gallery: z.array(z.unknown()).describe("Gallery app entries"),
|
|
546
|
+
}),
|
|
508
547
|
handler: () => {
|
|
509
548
|
return Response.json({ gallery: defaultGallery });
|
|
510
549
|
},
|
|
@@ -516,6 +555,19 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
516
555
|
endpoint: "apps/sign-bundle",
|
|
517
556
|
method: "POST",
|
|
518
557
|
policyKey: "apps/sign-bundle",
|
|
558
|
+
summary: "Sign an app bundle",
|
|
559
|
+
description:
|
|
560
|
+
"Return a signing payload or complete the signing step when signature fields are provided.",
|
|
561
|
+
tags: ["apps"],
|
|
562
|
+
requestBody: z.object({
|
|
563
|
+
payload: z.string().describe("Canonical JSON payload to sign"),
|
|
564
|
+
signature: z
|
|
565
|
+
.string()
|
|
566
|
+
.describe("Ed25519 signature (optional, completes signing)")
|
|
567
|
+
.optional(),
|
|
568
|
+
keyId: z.string().optional(),
|
|
569
|
+
publicKey: z.string().optional(),
|
|
570
|
+
}),
|
|
519
571
|
handler: async ({ req }) => {
|
|
520
572
|
try {
|
|
521
573
|
const body = (await req.json()) as {
|
|
@@ -576,6 +628,10 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
576
628
|
endpoint: "apps/signing-identity",
|
|
577
629
|
method: "GET",
|
|
578
630
|
policyKey: "apps/signing-identity",
|
|
631
|
+
summary: "Get signing identity",
|
|
632
|
+
description:
|
|
633
|
+
"Return signing identity info. Signing is managed client-side over HTTP.",
|
|
634
|
+
tags: ["apps"],
|
|
579
635
|
handler: () => {
|
|
580
636
|
// Signing identity is a client-side concept. Over HTTP, the
|
|
581
637
|
// client already holds its own keys. Return a placeholder
|
|
@@ -597,6 +653,9 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
597
653
|
endpoint: "apps/:id/data",
|
|
598
654
|
method: "GET",
|
|
599
655
|
policyKey: "apps/data",
|
|
656
|
+
summary: "Query app data",
|
|
657
|
+
description: "Read records from an app's local data store.",
|
|
658
|
+
tags: ["apps"],
|
|
600
659
|
handler: ({ params, url }) => {
|
|
601
660
|
try {
|
|
602
661
|
const method = url.searchParams.get("method") ?? "query";
|
|
@@ -627,6 +686,15 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
627
686
|
endpoint: "apps/:id/data",
|
|
628
687
|
method: "POST",
|
|
629
688
|
policyKey: "apps/data",
|
|
689
|
+
summary: "Mutate app data",
|
|
690
|
+
description:
|
|
691
|
+
"Create, update, or delete records in an app's local data store.",
|
|
692
|
+
tags: ["apps"],
|
|
693
|
+
requestBody: z.object({
|
|
694
|
+
method: z.string().describe("'create', 'update', or 'delete'"),
|
|
695
|
+
recordId: z.string(),
|
|
696
|
+
data: z.object({}).passthrough(),
|
|
697
|
+
}),
|
|
630
698
|
handler: async ({ params, req }) => {
|
|
631
699
|
try {
|
|
632
700
|
const body = (await req.json()) as {
|
|
@@ -662,6 +730,16 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
662
730
|
endpoint: "apps/:id/open",
|
|
663
731
|
method: "POST",
|
|
664
732
|
policyKey: "apps/open",
|
|
733
|
+
summary: "Open an app",
|
|
734
|
+
description:
|
|
735
|
+
"Compile (if needed) and return the app's HTML for rendering.",
|
|
736
|
+
tags: ["apps"],
|
|
737
|
+
responseBody: z.object({
|
|
738
|
+
appId: z.string(),
|
|
739
|
+
dirName: z.string(),
|
|
740
|
+
name: z.string(),
|
|
741
|
+
html: z.string(),
|
|
742
|
+
}),
|
|
665
743
|
handler: async ({ params }) => {
|
|
666
744
|
try {
|
|
667
745
|
const appId = params.id;
|
|
@@ -719,6 +797,9 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
719
797
|
endpoint: "apps/:id/delete",
|
|
720
798
|
method: "POST",
|
|
721
799
|
policyKey: "apps/delete",
|
|
800
|
+
summary: "Delete an app",
|
|
801
|
+
description: "Permanently remove an app and its data.",
|
|
802
|
+
tags: ["apps"],
|
|
722
803
|
handler: ({ params }) => {
|
|
723
804
|
try {
|
|
724
805
|
deleteApp(params.id);
|
|
@@ -736,6 +817,9 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
736
817
|
endpoint: "apps/:id/preview",
|
|
737
818
|
method: "GET",
|
|
738
819
|
policyKey: "apps/preview",
|
|
820
|
+
summary: "Get app preview",
|
|
821
|
+
description: "Return the preview image or HTML for an app.",
|
|
822
|
+
tags: ["apps"],
|
|
739
823
|
handler: ({ params }) => {
|
|
740
824
|
try {
|
|
741
825
|
const preview = getAppPreview(params.id);
|
|
@@ -759,6 +843,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
759
843
|
endpoint: "apps/:id/preview",
|
|
760
844
|
method: "PUT",
|
|
761
845
|
policyKey: "apps/preview",
|
|
846
|
+
summary: "Update app preview",
|
|
847
|
+
description: "Set a new preview image or HTML for an app.",
|
|
848
|
+
tags: ["apps"],
|
|
849
|
+
requestBody: z.object({
|
|
850
|
+
preview: z.string().describe("Base64-encoded image or HTML string"),
|
|
851
|
+
}),
|
|
762
852
|
handler: async ({ params, req }) => {
|
|
763
853
|
try {
|
|
764
854
|
const body = (await req.json()) as { preview?: string };
|
|
@@ -785,6 +875,13 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
785
875
|
endpoint: "apps/:id/history",
|
|
786
876
|
method: "GET",
|
|
787
877
|
policyKey: "apps/history",
|
|
878
|
+
summary: "Get app version history",
|
|
879
|
+
description: "Return the git commit history of an app.",
|
|
880
|
+
tags: ["apps"],
|
|
881
|
+
responseBody: z.object({
|
|
882
|
+
appId: z.string(),
|
|
883
|
+
versions: z.array(z.unknown()),
|
|
884
|
+
}),
|
|
788
885
|
handler: async ({ params, url }) => {
|
|
789
886
|
try {
|
|
790
887
|
const limit = url.searchParams.get("limit")
|
|
@@ -808,6 +905,9 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
808
905
|
endpoint: "apps/:id/diff",
|
|
809
906
|
method: "GET",
|
|
810
907
|
policyKey: "apps/diff",
|
|
908
|
+
summary: "Get app diff",
|
|
909
|
+
description: "Return a git diff between two commits for an app.",
|
|
910
|
+
tags: ["apps"],
|
|
811
911
|
handler: async ({ params, url }) => {
|
|
812
912
|
try {
|
|
813
913
|
const fromCommit = url.searchParams.get("fromCommit");
|
|
@@ -837,6 +937,12 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
837
937
|
endpoint: "apps/:id/restore",
|
|
838
938
|
method: "POST",
|
|
839
939
|
policyKey: "apps/restore",
|
|
940
|
+
summary: "Restore app version",
|
|
941
|
+
description: "Restore an app to a previous git commit.",
|
|
942
|
+
tags: ["apps"],
|
|
943
|
+
requestBody: z.object({
|
|
944
|
+
commitHash: z.string(),
|
|
945
|
+
}),
|
|
840
946
|
handler: async ({ params, req }) => {
|
|
841
947
|
try {
|
|
842
948
|
const body = (await req.json()) as { commitHash?: string };
|
|
@@ -862,6 +968,15 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
862
968
|
endpoint: "apps/:id/bundle",
|
|
863
969
|
method: "POST",
|
|
864
970
|
policyKey: "apps/bundle",
|
|
971
|
+
summary: "Bundle an app",
|
|
972
|
+
description: "Package an app into a distributable .vbundle archive.",
|
|
973
|
+
tags: ["apps"],
|
|
974
|
+
responseBody: z.object({
|
|
975
|
+
type: z.string(),
|
|
976
|
+
bundlePath: z.string(),
|
|
977
|
+
iconImageBase64: z.string(),
|
|
978
|
+
manifest: z.object({}).passthrough(),
|
|
979
|
+
}),
|
|
865
980
|
handler: async ({ params }) => {
|
|
866
981
|
try {
|
|
867
982
|
const result = await packageApp(params.id);
|
|
@@ -889,6 +1004,14 @@ export function appManagementRouteDefinitions(): RouteDefinition[] {
|
|
|
889
1004
|
endpoint: "apps/:id/share-cloud",
|
|
890
1005
|
method: "POST",
|
|
891
1006
|
policyKey: "apps/share-cloud",
|
|
1007
|
+
summary: "Share app to cloud",
|
|
1008
|
+
description: "Package and upload an app to the cloud share service.",
|
|
1009
|
+
tags: ["apps"],
|
|
1010
|
+
responseBody: z.object({
|
|
1011
|
+
success: z.boolean(),
|
|
1012
|
+
shareToken: z.string(),
|
|
1013
|
+
shareUrl: z.string(),
|
|
1014
|
+
}),
|
|
892
1015
|
handler: async ({ params }) => {
|
|
893
1016
|
try {
|
|
894
1017
|
// Package without signing callback (HTTP clients handle signing
|
|
@@ -6,6 +6,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
6
6
|
import { extname, join } from "node:path";
|
|
7
7
|
|
|
8
8
|
import JSZip from "jszip";
|
|
9
|
+
import { z } from "zod";
|
|
9
10
|
|
|
10
11
|
import type { AppManifest } from "../../bundler/manifest.js";
|
|
11
12
|
import {
|
|
@@ -336,30 +337,60 @@ export function appRouteDefinitions(): RouteDefinition[] {
|
|
|
336
337
|
endpoint: "apps/:appId/dist/:filename",
|
|
337
338
|
method: "GET",
|
|
338
339
|
policyKey: "apps/dist",
|
|
340
|
+
summary: "Serve app dist file",
|
|
341
|
+
description:
|
|
342
|
+
"Serve a static asset from an app's compiled dist/ directory.",
|
|
343
|
+
tags: ["apps"],
|
|
339
344
|
handler: ({ params }) =>
|
|
340
345
|
handleServeDistFile(params.appId, params.filename),
|
|
341
346
|
},
|
|
342
347
|
{
|
|
343
348
|
endpoint: "apps/share",
|
|
344
349
|
method: "POST",
|
|
350
|
+
summary: "Share an app",
|
|
351
|
+
description: "Upload a zip app bundle and create a shareable link.",
|
|
352
|
+
tags: ["apps"],
|
|
353
|
+
responseBody: z.object({
|
|
354
|
+
shareToken: z.string(),
|
|
355
|
+
shareUrl: z.string(),
|
|
356
|
+
bundleSizeBytes: z.number(),
|
|
357
|
+
}),
|
|
345
358
|
handler: async ({ req }) => handleShareApp(req),
|
|
346
359
|
},
|
|
347
360
|
{
|
|
348
361
|
endpoint: "apps/shared/:token/metadata",
|
|
349
362
|
method: "GET",
|
|
350
363
|
policyKey: "apps/shared/metadata",
|
|
364
|
+
summary: "Get shared app metadata",
|
|
365
|
+
description: "Return metadata for a shared app bundle.",
|
|
366
|
+
tags: ["apps"],
|
|
367
|
+
responseBody: z.object({
|
|
368
|
+
name: z.string(),
|
|
369
|
+
description: z.string(),
|
|
370
|
+
icon: z.string(),
|
|
371
|
+
bundleSizeBytes: z.number(),
|
|
372
|
+
}),
|
|
351
373
|
handler: ({ params }) => handleGetSharedAppMetadata(params.token),
|
|
352
374
|
},
|
|
353
375
|
{
|
|
354
376
|
endpoint: "apps/shared/:token",
|
|
355
377
|
method: "GET",
|
|
356
378
|
policyKey: "apps/shared",
|
|
379
|
+
summary: "Download shared app",
|
|
380
|
+
description: "Download a shared app bundle as a zip file.",
|
|
381
|
+
tags: ["apps"],
|
|
357
382
|
handler: ({ params }) => handleDownloadSharedApp(params.token),
|
|
358
383
|
},
|
|
359
384
|
{
|
|
360
385
|
endpoint: "apps/shared/:token",
|
|
361
386
|
method: "DELETE",
|
|
362
387
|
policyKey: "apps/shared",
|
|
388
|
+
summary: "Delete shared app",
|
|
389
|
+
description: "Remove a shared app link.",
|
|
390
|
+
tags: ["apps"],
|
|
391
|
+
responseBody: z.object({
|
|
392
|
+
success: z.boolean(),
|
|
393
|
+
}),
|
|
363
394
|
handler: ({ params }) => handleDeleteSharedApp(params.token),
|
|
364
395
|
},
|
|
365
396
|
];
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* header. Guardian decisions additionally verify that the actor is the
|
|
9
9
|
* bound guardian.
|
|
10
10
|
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
11
13
|
import { getConversationByKey } from "../../memory/conversation-key-store.js";
|
|
12
14
|
import { addRule } from "../../permissions/trust-store.js";
|
|
13
15
|
import type { UserDecision } from "../../permissions/types.js";
|
|
@@ -69,6 +71,10 @@ export async function handleConfirm(
|
|
|
69
71
|
// pending interaction — the client can retry with corrected values.
|
|
70
72
|
const peeked = pendingInteractions.get(requestId);
|
|
71
73
|
if (!peeked) {
|
|
74
|
+
log.warn(
|
|
75
|
+
{ requestId, decision },
|
|
76
|
+
"Confirmation POST for unknown requestId (already consumed or never registered)",
|
|
77
|
+
);
|
|
72
78
|
return httpError(
|
|
73
79
|
"NOT_FOUND",
|
|
74
80
|
"No pending interaction found for this requestId",
|
|
@@ -129,7 +135,23 @@ export async function handleConfirm(
|
|
|
129
135
|
// Validation passed — consume the pending interaction.
|
|
130
136
|
const interaction = pendingInteractions.resolve(requestId)!;
|
|
131
137
|
|
|
132
|
-
|
|
138
|
+
log.info(
|
|
139
|
+
{
|
|
140
|
+
requestId,
|
|
141
|
+
decision,
|
|
142
|
+
toolName: interaction.confirmationDetails?.toolName,
|
|
143
|
+
conversationId: interaction.conversationId,
|
|
144
|
+
},
|
|
145
|
+
"Confirmation resolved via HTTP",
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// ACP permissions: resolve directly without a Conversation object.
|
|
149
|
+
if (interaction.directResolve) {
|
|
150
|
+
interaction.directResolve(decision as UserDecision);
|
|
151
|
+
return Response.json({ accepted: true });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interaction.conversation!.handleConfirmationResponse(
|
|
133
155
|
requestId,
|
|
134
156
|
decision as UserDecision,
|
|
135
157
|
selectedPattern,
|
|
@@ -187,7 +209,7 @@ export async function handleSecret(
|
|
|
187
209
|
);
|
|
188
210
|
}
|
|
189
211
|
|
|
190
|
-
interaction.conversation
|
|
212
|
+
interaction.conversation!.handleSecretResponse(
|
|
191
213
|
requestId,
|
|
192
214
|
value,
|
|
193
215
|
delivery as "store" | "transient_send" | undefined,
|
|
@@ -355,7 +377,9 @@ export function handleListPendingInteractions(
|
|
|
355
377
|
resolvedConversationId,
|
|
356
378
|
);
|
|
357
379
|
|
|
358
|
-
const confirmation = interactions.find(
|
|
380
|
+
const confirmation = interactions.find(
|
|
381
|
+
(i) => i.kind === "confirmation" || i.kind === "acp_confirmation",
|
|
382
|
+
);
|
|
359
383
|
const secret = interactions.find((i) => i.kind === "secret");
|
|
360
384
|
|
|
361
385
|
return Response.json({
|
|
@@ -377,6 +401,8 @@ export function handleListPendingInteractions(
|
|
|
377
401
|
confirmation.confirmationDetails?.persistentDecisionsAllowed,
|
|
378
402
|
temporaryOptionsAvailable:
|
|
379
403
|
confirmation.confirmationDetails?.temporaryOptionsAvailable,
|
|
404
|
+
acpToolKind: confirmation.confirmationDetails?.acpToolKind,
|
|
405
|
+
acpOptions: confirmation.confirmationDetails?.acpOptions,
|
|
380
406
|
}
|
|
381
407
|
: null,
|
|
382
408
|
pendingSecret: secret
|
|
@@ -396,22 +422,101 @@ export function approvalRouteDefinitions(): RouteDefinition[] {
|
|
|
396
422
|
{
|
|
397
423
|
endpoint: "confirm",
|
|
398
424
|
method: "POST",
|
|
425
|
+
summary: "Resolve a pending confirmation",
|
|
426
|
+
description: "Approve or deny a pending tool confirmation by requestId.",
|
|
427
|
+
tags: ["approvals"],
|
|
428
|
+
requestBody: z.object({
|
|
429
|
+
requestId: z.string().describe("Pending interaction request ID"),
|
|
430
|
+
decision: z
|
|
431
|
+
.string()
|
|
432
|
+
.describe(
|
|
433
|
+
"One of: allow, allow_10m, allow_conversation, deny, always_allow, always_deny, always_allow_high_risk",
|
|
434
|
+
),
|
|
435
|
+
selectedPattern: z
|
|
436
|
+
.string()
|
|
437
|
+
.describe("Allowlist pattern for persistent decisions")
|
|
438
|
+
.optional(),
|
|
439
|
+
selectedScope: z
|
|
440
|
+
.string()
|
|
441
|
+
.describe("Scope for persistent decisions")
|
|
442
|
+
.optional(),
|
|
443
|
+
}),
|
|
444
|
+
responseBody: z.object({
|
|
445
|
+
accepted: z.boolean(),
|
|
446
|
+
}),
|
|
399
447
|
handler: async ({ req, authContext }) => handleConfirm(req, authContext),
|
|
400
448
|
},
|
|
401
449
|
{
|
|
402
450
|
endpoint: "secret",
|
|
403
451
|
method: "POST",
|
|
452
|
+
summary: "Resolve a pending secret request",
|
|
453
|
+
description: "Provide a secret value for a pending secret request.",
|
|
454
|
+
tags: ["approvals"],
|
|
455
|
+
requestBody: z.object({
|
|
456
|
+
requestId: z.string().describe("Pending interaction request ID"),
|
|
457
|
+
value: z.string().describe("Secret value").optional(),
|
|
458
|
+
delivery: z
|
|
459
|
+
.string()
|
|
460
|
+
.describe("Delivery mode: store or transient_send")
|
|
461
|
+
.optional(),
|
|
462
|
+
}),
|
|
463
|
+
responseBody: z.object({
|
|
464
|
+
accepted: z.boolean(),
|
|
465
|
+
}),
|
|
404
466
|
handler: async ({ req, authContext }) => handleSecret(req, authContext),
|
|
405
467
|
},
|
|
406
468
|
{
|
|
407
469
|
endpoint: "trust-rules",
|
|
408
470
|
method: "POST",
|
|
471
|
+
summary: "Add a trust rule for a pending confirmation",
|
|
472
|
+
description:
|
|
473
|
+
"Add a trust rule bound to a pending confirmation without resolving it.",
|
|
474
|
+
tags: ["approvals"],
|
|
475
|
+
requestBody: z.object({
|
|
476
|
+
requestId: z.string().describe("Pending confirmation request ID"),
|
|
477
|
+
pattern: z.string().describe("Allowlist pattern"),
|
|
478
|
+
scope: z.string().describe("Scope for the rule"),
|
|
479
|
+
decision: z.string().describe("allow or deny"),
|
|
480
|
+
allowHighRisk: z
|
|
481
|
+
.boolean()
|
|
482
|
+
.describe("Allow high-risk invocations")
|
|
483
|
+
.optional(),
|
|
484
|
+
}),
|
|
485
|
+
responseBody: z.object({
|
|
486
|
+
accepted: z.boolean(),
|
|
487
|
+
}),
|
|
409
488
|
handler: async ({ req, authContext }) =>
|
|
410
489
|
handleTrustRule(req, authContext),
|
|
411
490
|
},
|
|
412
491
|
{
|
|
413
492
|
endpoint: "pending-interactions",
|
|
414
493
|
method: "GET",
|
|
494
|
+
summary: "List pending interactions",
|
|
495
|
+
description:
|
|
496
|
+
"Return pending confirmations and secrets for a conversation.",
|
|
497
|
+
tags: ["approvals"],
|
|
498
|
+
queryParams: [
|
|
499
|
+
{
|
|
500
|
+
name: "conversationKey",
|
|
501
|
+
schema: { type: "string" },
|
|
502
|
+
description: "Conversation key",
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: "conversationId",
|
|
506
|
+
schema: { type: "string" },
|
|
507
|
+
description: "Conversation ID",
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
responseBody: z.object({
|
|
511
|
+
pendingConfirmation: z
|
|
512
|
+
.object({})
|
|
513
|
+
.passthrough()
|
|
514
|
+
.describe("Pending confirmation details or null"),
|
|
515
|
+
pendingSecret: z
|
|
516
|
+
.object({})
|
|
517
|
+
.passthrough()
|
|
518
|
+
.describe("Pending secret request or null"),
|
|
519
|
+
}),
|
|
415
520
|
handler: ({ url, authContext }) =>
|
|
416
521
|
handleListPendingInteractions(url, authContext),
|
|
417
522
|
},
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
5
|
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
6
8
|
import * as attachmentsStore from "../../memory/attachments-store.js";
|
|
7
9
|
import {
|
|
8
10
|
AttachmentUploadError,
|
|
@@ -261,23 +263,66 @@ export function attachmentRouteDefinitions(): RouteDefinition[] {
|
|
|
261
263
|
{
|
|
262
264
|
endpoint: "attachments",
|
|
263
265
|
method: "POST",
|
|
266
|
+
summary: "Upload attachment",
|
|
267
|
+
description:
|
|
268
|
+
"Upload an attachment as base64 data or file path reference.",
|
|
269
|
+
tags: ["attachments"],
|
|
270
|
+
requestBody: z.object({
|
|
271
|
+
filename: z.string(),
|
|
272
|
+
mimeType: z.string(),
|
|
273
|
+
data: z.string().describe("Base64-encoded file data").optional(),
|
|
274
|
+
filePath: z
|
|
275
|
+
.string()
|
|
276
|
+
.describe("On-disk file path (file-backed upload)")
|
|
277
|
+
.optional(),
|
|
278
|
+
}),
|
|
279
|
+
responseBody: z.object({
|
|
280
|
+
id: z.string(),
|
|
281
|
+
original_filename: z.string(),
|
|
282
|
+
mime_type: z.string(),
|
|
283
|
+
size_bytes: z.number(),
|
|
284
|
+
kind: z.string(),
|
|
285
|
+
}),
|
|
264
286
|
handler: async ({ req }) => handleUploadAttachment(req),
|
|
265
287
|
},
|
|
266
288
|
{
|
|
267
289
|
endpoint: "attachments",
|
|
268
290
|
method: "DELETE",
|
|
291
|
+
summary: "Delete attachment",
|
|
292
|
+
description: "Delete an attachment by ID.",
|
|
293
|
+
tags: ["attachments"],
|
|
294
|
+
requestBody: z.object({
|
|
295
|
+
attachmentId: z.string(),
|
|
296
|
+
}),
|
|
269
297
|
handler: async ({ req }) => handleDeleteAttachment(req),
|
|
270
298
|
},
|
|
271
299
|
{
|
|
272
300
|
endpoint: "attachments/:id/content",
|
|
273
301
|
method: "GET",
|
|
274
302
|
policyKey: "attachments/content",
|
|
303
|
+
summary: "Get attachment content",
|
|
304
|
+
description:
|
|
305
|
+
"Serve raw file bytes for an attachment. Supports Range headers.",
|
|
306
|
+
tags: ["attachments"],
|
|
275
307
|
handler: ({ req, params }) => handleGetAttachmentContent(params.id, req),
|
|
276
308
|
},
|
|
277
309
|
{
|
|
278
310
|
endpoint: "attachments/:id",
|
|
279
311
|
method: "GET",
|
|
280
312
|
policyKey: "attachments",
|
|
313
|
+
summary: "Get attachment metadata",
|
|
314
|
+
description:
|
|
315
|
+
"Return metadata and optional base64 data for an attachment.",
|
|
316
|
+
tags: ["attachments"],
|
|
317
|
+
responseBody: z.object({
|
|
318
|
+
id: z.string(),
|
|
319
|
+
filename: z.string(),
|
|
320
|
+
mimeType: z.string(),
|
|
321
|
+
sizeBytes: z.number(),
|
|
322
|
+
kind: z.string(),
|
|
323
|
+
data: z.string().describe("Base64-encoded content"),
|
|
324
|
+
fileBacked: z.boolean(),
|
|
325
|
+
}),
|
|
281
326
|
handler: ({ params }) => handleGetAttachment(params.id),
|
|
282
327
|
},
|
|
283
328
|
];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
3
5
|
import { getCharacterComponents } from "../../avatar/character-components.js";
|
|
4
6
|
import {
|
|
5
7
|
type CharacterTraits,
|
|
@@ -39,11 +41,25 @@ export function avatarRouteDefinitions(): RouteDefinition[] {
|
|
|
39
41
|
{
|
|
40
42
|
endpoint: "avatar/character-components",
|
|
41
43
|
method: "GET",
|
|
44
|
+
summary: "Get character components",
|
|
45
|
+
description: "Return available avatar character components.",
|
|
46
|
+
tags: ["avatar"],
|
|
42
47
|
handler: () => Response.json(getCharacterComponents()),
|
|
43
48
|
},
|
|
44
49
|
{
|
|
45
50
|
endpoint: "avatar/render-from-traits",
|
|
46
51
|
method: "POST",
|
|
52
|
+
summary: "Render avatar from traits",
|
|
53
|
+
description: "Write character traits and render an avatar PNG.",
|
|
54
|
+
tags: ["avatar"],
|
|
55
|
+
requestBody: z.object({
|
|
56
|
+
bodyShape: z.string(),
|
|
57
|
+
eyeStyle: z.string(),
|
|
58
|
+
color: z.string(),
|
|
59
|
+
}),
|
|
60
|
+
responseBody: z.object({
|
|
61
|
+
ok: z.boolean(),
|
|
62
|
+
}),
|
|
47
63
|
handler: async ({ req }) => {
|
|
48
64
|
let body: CharacterTraits;
|
|
49
65
|
try {
|
|
@@ -9,6 +9,7 @@ import { readFileSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
11
|
import { count } from "drizzle-orm";
|
|
12
|
+
import { z } from "zod";
|
|
12
13
|
|
|
13
14
|
import { getDb } from "../../memory/db.js";
|
|
14
15
|
import { memoryItems } from "../../memory/schema.js";
|
|
@@ -136,11 +137,28 @@ export function brainGraphRouteDefinitions(deps: {
|
|
|
136
137
|
{
|
|
137
138
|
endpoint: "brain-graph",
|
|
138
139
|
method: "GET",
|
|
140
|
+
summary: "Get brain graph data",
|
|
141
|
+
description:
|
|
142
|
+
"Return a knowledge-graph shaped for brain-lobe visualization, with memory items mapped to brain regions.",
|
|
143
|
+
tags: ["brain-graph"],
|
|
144
|
+
responseBody: z.object({
|
|
145
|
+
entities: z.array(z.unknown()).describe("Graph entity nodes"),
|
|
146
|
+
relations: z.array(z.unknown()).describe("Graph relation edges"),
|
|
147
|
+
memorySummary: z
|
|
148
|
+
.array(z.unknown())
|
|
149
|
+
.describe("Memory kind counts and colors"),
|
|
150
|
+
totalKnowledgeCount: z.number().int(),
|
|
151
|
+
generatedAt: z.string().describe("ISO 8601 timestamp"),
|
|
152
|
+
}),
|
|
139
153
|
handler: () => handleGetBrainGraph(),
|
|
140
154
|
},
|
|
141
155
|
{
|
|
142
156
|
endpoint: "brain-graph-ui",
|
|
143
157
|
method: "GET",
|
|
158
|
+
summary: "Serve brain graph UI",
|
|
159
|
+
description:
|
|
160
|
+
"Return the brain-graph HTML visualization page with an embedded auth token.",
|
|
161
|
+
tags: ["brain-graph"],
|
|
144
162
|
handler: () => handleServeBrainGraphUI(deps.mintUiPageToken()),
|
|
145
163
|
},
|
|
146
164
|
];
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync, readFileSync } from "node:fs";
|
|
16
16
|
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
|
|
17
19
|
import { getConversationByKey } from "../../memory/conversation-key-store.js";
|
|
20
|
+
import {
|
|
21
|
+
resolveChannelPersona,
|
|
22
|
+
resolveGuardianPersona,
|
|
23
|
+
} from "../../prompts/persona-resolver.js";
|
|
18
24
|
import { getLogger } from "../../util/logger.js";
|
|
19
25
|
import { getWorkspacePromptPath } from "../../util/platform.js";
|
|
20
26
|
import type { AuthContext } from "../auth/types.js";
|
|
@@ -144,10 +150,14 @@ async function handleBtw(
|
|
|
144
150
|
(async () => {
|
|
145
151
|
try {
|
|
146
152
|
const isIntroRequest = conversationKey === IDENTITY_INTRO_KEY;
|
|
153
|
+
const userPersona = resolveGuardianPersona();
|
|
154
|
+
const channelPersona = resolveChannelPersona(undefined);
|
|
147
155
|
const result = await runBtwSidechain({
|
|
148
156
|
content: trimmedContent,
|
|
149
157
|
conversation,
|
|
150
158
|
signal: req.signal,
|
|
159
|
+
userPersona,
|
|
160
|
+
channelPersona,
|
|
151
161
|
onEvent: (event) => {
|
|
152
162
|
if (event.type === "text_delta") {
|
|
153
163
|
controller.enqueue(
|
|
@@ -222,6 +232,16 @@ export function btwRouteDefinitions(deps: {
|
|
|
222
232
|
endpoint: "btw",
|
|
223
233
|
method: "POST",
|
|
224
234
|
policyKey: "btw",
|
|
235
|
+
summary: "Run ephemeral LLM side-chain",
|
|
236
|
+
description:
|
|
237
|
+
"Stream an ephemeral LLM call reusing the conversation's provider and message history. Response is SSE (btw_text_delta, btw_complete, btw_error).",
|
|
238
|
+
tags: ["btw"],
|
|
239
|
+
requestBody: z.object({
|
|
240
|
+
conversationKey: z
|
|
241
|
+
.string()
|
|
242
|
+
.describe("Conversation key to scope the call"),
|
|
243
|
+
content: z.string().describe("User prompt content"),
|
|
244
|
+
}),
|
|
225
245
|
handler: async ({ req, authContext }) =>
|
|
226
246
|
handleBtw(req, deps, authContext),
|
|
227
247
|
},
|