@vellumai/assistant 0.5.6 → 0.5.7
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/.env.example +16 -2
- package/ARCHITECTURE.md +6 -75
- package/Dockerfile +1 -1
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/security.md +0 -17
- package/docs/credential-execution-service.md +2 -2
- package/node_modules/@vellumai/ces-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
- package/node_modules/@vellumai/credential-storage/package.json +1 -0
- package/node_modules/@vellumai/egress-proxy/package.json +1 -0
- package/package.json +2 -3
- package/src/__tests__/actor-token-service.test.ts +0 -114
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -5
- package/src/__tests__/channel-readiness-service.test.ts +1 -60
- package/src/__tests__/checker.test.ts +4 -2
- package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-title-service.test.ts +87 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
- package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
- package/src/__tests__/credential-security-e2e.test.ts +0 -66
- package/src/__tests__/credential-security-invariants.test.ts +4 -45
- package/src/__tests__/credentials-cli.test.ts +78 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/guardian-routing-state.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +6 -7
- package/src/__tests__/http-user-message-parity.test.ts +3 -103
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
- package/src/__tests__/intent-routing.test.ts +0 -13
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-import-commit-http.test.ts +2 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
- package/src/__tests__/migration-validate-http.test.ts +2 -2
- package/src/__tests__/non-member-access-request.test.ts +0 -5
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +83 -263
- package/src/__tests__/shell-identity.test.ts +96 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
- package/src/__tests__/skill-feature-flags.test.ts +46 -45
- package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
- package/src/__tests__/skill-load-inline-command.test.ts +8 -12
- package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
- package/src/__tests__/skill-load-tool.test.ts +0 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
- package/src/__tests__/skills.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +0 -4
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +85 -7
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +117 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/twilio-routes.ts +2 -1
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +26 -5
- package/src/calls/voice-session-bridge.ts +6 -12
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/credentials.ts +34 -4
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +179 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-tool-registry.ts +1 -11
- package/src/config/env-registry.ts +1 -1
- package/src/config/env.ts +8 -14
- package/src/config/feature-flag-registry.json +48 -8
- package/src/config/loader.ts +98 -31
- package/src/config/schema.ts +4 -13
- package/src/config/schemas/calls.ts +13 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/security.ts +0 -4
- package/src/config/types.ts +0 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- package/src/credential-execution/approval-bridge.ts +1 -0
- package/src/credential-execution/executable-discovery.ts +28 -4
- package/src/credential-execution/feature-gates.ts +16 -0
- package/src/credential-execution/process-manager.ts +38 -0
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +5 -0
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +10 -1
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +227 -51
- package/src/daemon/message-types/conversations.ts +3 -4
- package/src/daemon/message-types/diagnostics.ts +3 -22
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/message-types/upgrades.ts +8 -0
- package/src/daemon/server.ts +30 -92
- package/src/events/domain-events.ts +2 -1
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/conversation-title-service.ts +50 -1
- package/src/memory/db-init.ts +12 -0
- package/src/memory/items-extractor.ts +15 -1
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/jobs-store.ts +30 -5
- package/src/memory/jobs-worker.ts +31 -7
- package/src/memory/migrations/001-job-deferrals.ts +19 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
- package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
- package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
- package/src/memory/migrations/116-messages-fts.ts +106 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
- package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
- package/src/memory/migrations/141-rename-verification-table.ts +54 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
- package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
- package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
- package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
- package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
- package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
- package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +90 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/notifications/decision-engine.ts +4 -1
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/persona-resolver.ts +138 -0
- package/src/prompts/system-prompt.ts +36 -4
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/registry.ts +27 -40
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/token-service.ts +43 -138
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/http-server.ts +27 -2
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/conversation-query-routes.ts +63 -1
- package/src/runtime/routes/conversation-routes.ts +4 -44
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/identity-routes.ts +18 -29
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
- package/src/runtime/routes/integrations/vercel.ts +89 -0
- package/src/runtime/routes/log-export-routes.ts +5 -0
- package/src/runtime/routes/memory-item-routes.ts +24 -6
- package/src/runtime/routes/migration-rollback-routes.ts +209 -0
- package/src/runtime/routes/migration-routes.ts +17 -1
- package/src/runtime/routes/notification-routes.ts +58 -0
- package/src/runtime/routes/schedule-routes.ts +65 -0
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +86 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
- package/src/runtime/routes/workspace-commit-routes.ts +62 -0
- package/src/runtime/routes/workspace-routes.test.ts +22 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +86 -2
- package/src/security/ces-credential-client.ts +59 -22
- package/src/security/ces-rpc-credential-backend.ts +85 -0
- package/src/security/credential-backend.ts +12 -88
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +94 -113
- package/src/skills/catalog-install.ts +13 -7
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/executor.ts +0 -4
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/types.ts +0 -8
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +3 -50
- package/src/workspace/git-service.ts +5 -2
- package/src/workspace/migrations/001-avatar-rename.ts +15 -0
- package/src/workspace/migrations/003-seed-device-id.ts +17 -1
- package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
- package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
- package/src/workspace/migrations/006-services-config.ts +49 -0
- package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
- package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
- package/src/__tests__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
- package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
- package/src/__tests__/swarm-orchestrator.test.ts +0 -463
- package/src/__tests__/swarm-plan-validator.test.ts +0 -384
- package/src/__tests__/swarm-recursion.test.ts +0 -197
- package/src/__tests__/swarm-router-planner.test.ts +0 -234
- package/src/__tests__/swarm-tool.test.ts +0 -185
- package/src/__tests__/swarm-worker-backend.test.ts +0 -144
- package/src/__tests__/swarm-worker-runner.test.ts +0 -288
- package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
- package/src/commands/cc-command-registry.ts +0 -248
- package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
- package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
- package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
- package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
- package/src/config/schemas/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/runtime/local-gateway-health.ts +0 -275
- package/src/security/secret-ingress.ts +0 -68
- package/src/swarm/backend-claude-code.ts +0 -225
- package/src/swarm/checkpoint.ts +0 -137
- package/src/swarm/graph-utils.ts +0 -53
- package/src/swarm/index.ts +0 -55
- package/src/swarm/limits.ts +0 -66
- package/src/swarm/orchestrator.ts +0 -424
- package/src/swarm/plan-validator.ts +0 -117
- package/src/swarm/router-planner.ts +0 -162
- package/src/swarm/router-prompts.ts +0 -39
- package/src/swarm/synthesizer.ts +0 -81
- package/src/swarm/types.ts +0 -72
- package/src/swarm/worker-backend.ts +0 -131
- package/src/swarm/worker-prompts.ts +0 -80
- package/src/swarm/worker-runner.ts +0 -170
- package/src/tools/claude-code/claude-code.ts +0 -610
- package/src/tools/swarm/delegate.ts +0 -205
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP route handler for serving synthesized TTS audio.
|
|
3
|
+
*
|
|
4
|
+
* GET /v1/audio/:audioId — retrieve a previously stored audio segment.
|
|
5
|
+
*
|
|
6
|
+
* This endpoint is unauthenticated because Twilio fetches audio URLs
|
|
7
|
+
* directly; the audioId itself is an unguessable UUID that acts as a
|
|
8
|
+
* capability token.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { getAudio } from "../../calls/audio-store.js";
|
|
12
|
+
import { httpError } from "../http-errors.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Handle GET /v1/audio/:audioId.
|
|
16
|
+
*
|
|
17
|
+
* Returns the audio with its stored Content-Type. For complete audio,
|
|
18
|
+
* includes Content-Length for efficient playback. For in-progress
|
|
19
|
+
* streaming entries, uses chunked transfer encoding.
|
|
20
|
+
*/
|
|
21
|
+
export function handleGetAudio(audioId: string): Response {
|
|
22
|
+
const entry = getAudio(audioId);
|
|
23
|
+
if (!entry) {
|
|
24
|
+
return httpError("NOT_FOUND", "Audio not found", 404);
|
|
25
|
+
}
|
|
26
|
+
if (entry.type === "buffer") {
|
|
27
|
+
return new Response(new Uint8Array(entry.buffer), {
|
|
28
|
+
status: 200,
|
|
29
|
+
headers: {
|
|
30
|
+
"Content-Type": entry.contentType,
|
|
31
|
+
"Content-Length": entry.buffer.length.toString(),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// Streaming — Content-Length unknown, chunked transfer encoding
|
|
36
|
+
return new Response(entry.stream, {
|
|
37
|
+
status: 200,
|
|
38
|
+
headers: { "Content-Type": entry.contentType },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
import { existsSync, readFileSync } from "node:fs";
|
|
16
16
|
|
|
17
17
|
import { getConversationByKey } from "../../memory/conversation-key-store.js";
|
|
18
|
-
import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
19
18
|
import { getLogger } from "../../util/logger.js";
|
|
20
19
|
import { getWorkspacePromptPath } from "../../util/platform.js";
|
|
21
20
|
import type { AuthContext } from "../auth/types.js";
|
|
@@ -89,22 +88,6 @@ async function handleBtw(
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
const trimmedContent = content.trim();
|
|
92
|
-
const ingressCheck = checkIngressForSecrets(trimmedContent);
|
|
93
|
-
if (ingressCheck.blocked) {
|
|
94
|
-
log.warn(
|
|
95
|
-
{ detectedTypes: ingressCheck.detectedTypes },
|
|
96
|
-
"Blocked /v1/btw message containing secrets",
|
|
97
|
-
);
|
|
98
|
-
return Response.json(
|
|
99
|
-
{
|
|
100
|
-
accepted: false,
|
|
101
|
-
error: "secret_blocked",
|
|
102
|
-
message: ingressCheck.userNotice,
|
|
103
|
-
detectedTypes: ingressCheck.detectedTypes,
|
|
104
|
-
},
|
|
105
|
-
{ status: 422 },
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
91
|
|
|
109
92
|
// ----- Identity intro fast-path -----
|
|
110
93
|
// When the client requests the identity intro, check SOUL.md first (persisted
|
|
@@ -12,13 +12,20 @@
|
|
|
12
12
|
* PUT /v1/config/embeddings — set embedding provider/model
|
|
13
13
|
* GET /v1/config/permissions/skip — dangerouslySkipPermissions status
|
|
14
14
|
* PUT /v1/config/permissions/skip — toggle dangerouslySkipPermissions
|
|
15
|
+
* GET /v1/config — full raw workspace config
|
|
16
|
+
* PATCH /v1/config — deep-merge partial config
|
|
15
17
|
* GET /v1/conversations/search — search conversations
|
|
16
18
|
* GET /v1/messages/:id/content — full message content
|
|
17
19
|
* GET /v1/messages/:id/llm-context — LLM request logs for a message
|
|
18
20
|
* DELETE /v1/messages/queued/:id — delete queued message
|
|
19
21
|
*/
|
|
20
22
|
|
|
21
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
deepMergeOverwrite,
|
|
25
|
+
getConfig,
|
|
26
|
+
loadRawConfig,
|
|
27
|
+
saveRawConfig,
|
|
28
|
+
} from "../../config/loader.js";
|
|
22
29
|
import { VALID_MEMORY_EMBEDDING_PROVIDERS } from "../../config/schemas/memory-storage.js";
|
|
23
30
|
import { VALID_INFERENCE_PROVIDERS } from "../../config/schemas/services.js";
|
|
24
31
|
import {
|
|
@@ -292,6 +299,61 @@ export function conversationQueryRouteDefinitions(
|
|
|
292
299
|
},
|
|
293
300
|
},
|
|
294
301
|
|
|
302
|
+
// ── Full config read ─────────────────────────────────────────────
|
|
303
|
+
{
|
|
304
|
+
endpoint: "config",
|
|
305
|
+
method: "GET",
|
|
306
|
+
policyKey: "config",
|
|
307
|
+
handler: () => {
|
|
308
|
+
try {
|
|
309
|
+
const raw = loadRawConfig();
|
|
310
|
+
return Response.json(raw);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
313
|
+
return httpError(
|
|
314
|
+
"INTERNAL_ERROR",
|
|
315
|
+
`Failed to read config: ${message}`,
|
|
316
|
+
500,
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
// ── Generic config patch ──────────────────────────────────────────
|
|
323
|
+
{
|
|
324
|
+
endpoint: "config",
|
|
325
|
+
method: "PATCH",
|
|
326
|
+
policyKey: "config",
|
|
327
|
+
handler: async ({ req }) => {
|
|
328
|
+
const body = (await req.json()) as Record<string, unknown>;
|
|
329
|
+
if (
|
|
330
|
+
body == null ||
|
|
331
|
+
typeof body !== "object" ||
|
|
332
|
+
Array.isArray(body) ||
|
|
333
|
+
Object.keys(body).length === 0
|
|
334
|
+
) {
|
|
335
|
+
return httpError(
|
|
336
|
+
"BAD_REQUEST",
|
|
337
|
+
"Body must be a non-empty JSON object",
|
|
338
|
+
400,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
try {
|
|
342
|
+
const raw = loadRawConfig();
|
|
343
|
+
deepMergeOverwrite(raw, body);
|
|
344
|
+
saveRawConfig(raw);
|
|
345
|
+
return Response.json({ ok: true });
|
|
346
|
+
} catch (err) {
|
|
347
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
348
|
+
return httpError(
|
|
349
|
+
"INTERNAL_ERROR",
|
|
350
|
+
`Failed to patch config: ${message}`,
|
|
351
|
+
500,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
|
|
295
357
|
// ── Conversation search ───────────────────────────────────────────
|
|
296
358
|
{
|
|
297
359
|
endpoint: "conversations/search",
|
|
@@ -56,7 +56,6 @@ import {
|
|
|
56
56
|
import { searchConversations } from "../../memory/conversation-queries.js";
|
|
57
57
|
import { getConfiguredProvider } from "../../providers/provider-send-message.js";
|
|
58
58
|
import type { Provider } from "../../providers/types.js";
|
|
59
|
-
import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
60
59
|
import { getLogger } from "../../util/logger.js";
|
|
61
60
|
import { silentlyWithLog } from "../../util/silently.js";
|
|
62
61
|
import { buildAssistantEvent } from "../assistant-event.js";
|
|
@@ -637,7 +636,6 @@ export async function handleSendMessage(
|
|
|
637
636
|
interface?: string;
|
|
638
637
|
conversationType?: string;
|
|
639
638
|
automated?: boolean;
|
|
640
|
-
bypassSecretCheck?: boolean;
|
|
641
639
|
};
|
|
642
640
|
|
|
643
641
|
const { conversationKey, content, attachmentIds } = body;
|
|
@@ -705,29 +703,6 @@ export async function handleSendMessage(
|
|
|
705
703
|
}
|
|
706
704
|
}
|
|
707
705
|
|
|
708
|
-
// Block inbound messages containing secrets before they reach the model.
|
|
709
|
-
// This mirrors the legacy handleUserMessage behavior: secrets are
|
|
710
|
-
// detected and the message is rejected with a safe notice. The client
|
|
711
|
-
// should prompt the user to use the secure credential flow instead.
|
|
712
|
-
if (trimmedContent.length > 0 && !body.bypassSecretCheck) {
|
|
713
|
-
const ingressCheck = checkIngressForSecrets(trimmedContent);
|
|
714
|
-
if (ingressCheck.blocked) {
|
|
715
|
-
log.warn(
|
|
716
|
-
{ detectedTypes: ingressCheck.detectedTypes },
|
|
717
|
-
"Blocked user message containing secrets (POST /v1/messages)",
|
|
718
|
-
);
|
|
719
|
-
return Response.json(
|
|
720
|
-
{
|
|
721
|
-
accepted: false,
|
|
722
|
-
error: "secret_blocked",
|
|
723
|
-
message: ingressCheck.userNotice,
|
|
724
|
-
detectedTypes: ingressCheck.detectedTypes,
|
|
725
|
-
},
|
|
726
|
-
{ status: 422 },
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
|
|
731
706
|
if (!deps.sendMessageDeps) {
|
|
732
707
|
return httpError(
|
|
733
708
|
"SERVICE_UNAVAILABLE",
|
|
@@ -1259,12 +1234,12 @@ async function generateLlmSuggestion(
|
|
|
1259
1234
|
const truncated =
|
|
1260
1235
|
assistantText.length > 2000 ? assistantText.slice(-2000) : assistantText;
|
|
1261
1236
|
|
|
1262
|
-
const prompt = `Given this assistant message, write a very short tab-complete suggestion
|
|
1237
|
+
const prompt = `Given this assistant message, write a very short tab-complete suggestion the user could send next to keep the conversation going. Be casual, curious, or actionable — like a quick reply, not a formal request. Reply with ONLY the suggestion text.\n\nAssistant's message:\n${truncated}`;
|
|
1263
1238
|
const response = await provider.sendMessage(
|
|
1264
1239
|
[{ role: "user", content: [{ type: "text", text: prompt }] }],
|
|
1265
1240
|
[], // no tools
|
|
1266
1241
|
undefined, // no system prompt
|
|
1267
|
-
{ config: {
|
|
1242
|
+
{ config: { modelIntent: "latency-optimized" } },
|
|
1268
1243
|
);
|
|
1269
1244
|
|
|
1270
1245
|
const textBlock = response.content.find((b) => b.type === "text");
|
|
@@ -1276,7 +1251,7 @@ async function generateLlmSuggestion(
|
|
|
1276
1251
|
return null;
|
|
1277
1252
|
}
|
|
1278
1253
|
|
|
1279
|
-
// Take first line only
|
|
1254
|
+
// Take first line only
|
|
1280
1255
|
const firstLine = stripped.split("\n")[0].trim();
|
|
1281
1256
|
if (!firstLine) {
|
|
1282
1257
|
log.debug(
|
|
@@ -1285,22 +1260,7 @@ async function generateLlmSuggestion(
|
|
|
1285
1260
|
);
|
|
1286
1261
|
return null;
|
|
1287
1262
|
}
|
|
1288
|
-
|
|
1289
|
-
// Truncate at last word boundary within 50 chars.
|
|
1290
|
-
// Only strip the trailing partial word if the slice actually cut mid-word;
|
|
1291
|
-
// if the character right after the cut is whitespace, the slice is already clean.
|
|
1292
|
-
const sliced = firstLine.slice(0, 50);
|
|
1293
|
-
const wordTruncated = (
|
|
1294
|
-
/\s/.test(firstLine[50]) ? sliced : sliced.replace(/\s+\S*$/, "")
|
|
1295
|
-
).trim();
|
|
1296
|
-
if (wordTruncated.length < 15) {
|
|
1297
|
-
log.debug(
|
|
1298
|
-
{ rawLength: firstLine.length, truncatedLength: wordTruncated.length },
|
|
1299
|
-
"Suggestion rejected: too short after word-boundary truncation",
|
|
1300
|
-
);
|
|
1301
|
-
return null;
|
|
1302
|
-
}
|
|
1303
|
-
return wordTruncated;
|
|
1263
|
+
return firstLine;
|
|
1304
1264
|
}
|
|
1305
1265
|
|
|
1306
1266
|
export async function handleGetSuggestion(
|