@vellumai/assistant 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/ARCHITECTURE.md +68 -15
- package/Dockerfile +2 -2
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +42 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +7 -9
- package/openapi.yaml +539 -4
- package/package.json +5 -1
- package/src/__tests__/anthropic-provider.test.ts +160 -95
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -0
- package/src/__tests__/assistant-event-hub.test.ts +30 -0
- package/src/__tests__/checker.test.ts +138 -172
- package/src/__tests__/cli-command-risk-guard.test.ts +1 -1
- package/src/__tests__/config-schema.test.ts +5 -0
- package/src/__tests__/context-overflow-approval.test.ts +5 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +4 -6
- package/src/__tests__/conversation-agent-loop.test.ts +4 -51
- package/src/__tests__/conversation-analysis-routes.test.ts +169 -0
- package/src/__tests__/conversation-directories-parse.test.ts +105 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-wipe.test.ts +2 -6
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +0 -2
- package/src/__tests__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +167 -0
- package/src/__tests__/injection-block.test.ts +24 -0
- package/src/__tests__/inline-command-runner.test.ts +7 -5
- package/src/__tests__/install-skill-routing.test.ts +7 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +15 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +101 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +162 -0
- package/src/__tests__/log-export-workspace.test.ts +257 -100
- package/src/__tests__/managed-credential-catalog-cli.test.ts +12 -14
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-recall-log-store.test.ts +132 -0
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/navigate-settings-tab.test.ts +14 -1
- package/src/__tests__/notification-broadcaster.test.ts +65 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- package/src/__tests__/onboarding-template-contract.test.ts +63 -14
- package/src/__tests__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/pkb-autoinject.test.ts +96 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
- package/src/__tests__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/registry.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +0 -2
- package/src/__tests__/sandbox-diagnostics.test.ts +1 -32
- package/src/__tests__/sandbox-host-parity.test.ts +5 -4
- package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +4 -3
- package/src/__tests__/send-endpoint-busy.test.ts +42 -3
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +12 -0
- package/src/__tests__/skill-memory.test.ts +2 -783
- package/src/__tests__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- package/src/__tests__/task-memory-cleanup.test.ts +12 -12
- package/src/__tests__/terminal-sandbox.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +16 -29
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -8
- package/src/__tests__/tool-executor.test.ts +4 -27
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- package/src/__tests__/transport-hints-queue.test.ts +77 -0
- package/src/__tests__/trust-store.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +116 -2
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
- package/src/__tests__/workspace-migration-030-seed-pkb-autoinject.test.ts +168 -0
- package/src/__tests__/workspace-policy.test.ts +2 -7
- package/src/agent/loop.ts +6 -29
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- package/src/channels/types.ts +5 -0
- package/src/cli/__tests__/run-assistant-command.ts +56 -0
- package/src/cli/__tests__/unknown-command.test.ts +33 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/default-action.ts +68 -1
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +1 -34
- package/src/cli/commands/notifications.ts +7 -2
- package/src/cli/commands/oauth/__tests__/connect.test.ts +27 -0
- package/src/cli/commands/oauth/connect.ts +25 -5
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +1 -1
- package/src/cli/commands/routes.ts +396 -0
- package/src/cli/commands/skills.ts +130 -20
- package/src/cli/program.ts +11 -2
- package/src/cli.ts +1 -120
- package/src/config/assistant-feature-flags.ts +59 -55
- package/src/config/bundled-skills/app-builder/SKILL.md +91 -5
- package/src/config/bundled-skills/gmail/SKILL.md +13 -8
- package/src/config/bundled-skills/gmail/TOOLS.json +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -1
- package/src/config/bundled-skills/messaging/SKILL.md +7 -0
- package/src/config/bundled-skills/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/TOOLS.json +1 -1
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +8 -3
- package/src/config/bundled-skills/slack/SKILL.md +2 -0
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/env-registry.ts +63 -0
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/security.ts +14 -0
- package/src/config/schemas/services.ts +8 -0
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/managed-catalog.ts +3 -7
- package/src/daemon/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +85 -3
- package/src/daemon/context-overflow-approval.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +20 -0
- package/src/daemon/conversation-agent-loop.ts +179 -65
- package/src/daemon/conversation-attachments.ts +0 -1
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +8 -14
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +30 -8
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +359 -308
- package/src/daemon/conversation-surfaces.ts +65 -0
- package/src/daemon/conversation-tool-setup.ts +44 -17
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +19 -3
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +5 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +70 -5
- package/src/daemon/handlers/skills.ts +11 -18
- package/src/daemon/lifecycle.ts +220 -158
- package/src/daemon/message-types/conversations.ts +29 -6
- package/src/daemon/message-types/messages.ts +9 -2
- package/src/daemon/message-types/notifications.ts +12 -0
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +18 -0
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/server.ts +87 -10
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +23 -3
- package/src/daemon/transport-hints.ts +33 -0
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +96 -7
- package/src/index.ts +1 -1
- package/src/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +33 -32
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +1 -1
- package/src/memory/conversation-crud.ts +151 -117
- package/src/memory/conversation-directories.ts +39 -0
- package/src/memory/conversation-group-migration.ts +66 -6
- package/src/memory/conversation-queries.ts +58 -12
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +182 -376
- package/src/memory/embedding-local.ts +1 -1
- package/src/memory/graph/bootstrap.ts +75 -66
- package/src/memory/graph/capability-seed.ts +167 -17
- package/src/memory/graph/consolidation.ts +38 -4
- package/src/memory/graph/conversation-graph-memory.ts +133 -104
- package/src/memory/graph/extraction-job.ts +9 -4
- package/src/memory/graph/extraction.ts +66 -23
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +29 -15
- package/src/memory/graph/injection.ts +38 -8
- package/src/memory/graph/inspect.ts +12 -3
- package/src/memory/graph/retriever.ts +365 -262
- package/src/memory/graph/store.test.ts +48 -0
- package/src/memory/graph/store.ts +150 -11
- package/src/memory/graph/tool-handlers.ts +84 -209
- package/src/memory/graph/tools.ts +8 -52
- package/src/memory/graph/types.ts +24 -0
- package/src/memory/group-crud.ts +25 -9
- package/src/memory/job-handlers/cleanup.ts +44 -1
- package/src/memory/jobs-store.ts +70 -60
- package/src/memory/jobs-worker.ts +44 -28
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- package/src/memory/migrations/203-drop-memory-items-tables.ts +33 -1
- package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +15 -0
- package/src/memory/task-memory-cleanup.ts +30 -11
- package/src/messaging/provider.ts +1 -1
- package/src/notifications/broadcaster.ts +6 -0
- package/src/notifications/conversation-pairing.ts +12 -4
- package/src/notifications/copy-composer.ts +86 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/notifications/emit-signal.ts +14 -0
- package/src/notifications/signal.ts +11 -0
- package/src/oauth/platform-connection.test.ts +2 -2
- package/src/oauth/seed-providers.ts +1 -0
- package/src/permissions/checker.ts +15 -4
- package/src/permissions/defaults.ts +7 -8
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/prompter.ts +0 -2
- package/src/permissions/workspace-policy.ts +9 -0
- package/src/platform/client.ts +1 -1
- package/src/prompts/system-prompt.ts +59 -7
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +76 -162
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +30 -9
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +107 -219
- package/src/runtime/assistant-event-hub.ts +22 -0
- package/src/runtime/auth/route-policy.ts +23 -0
- package/src/runtime/auth/token-service.ts +8 -0
- package/src/runtime/http-server.ts +32 -2
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/btw-routes.ts +14 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +185 -0
- package/src/runtime/routes/conversation-management-routes.ts +1 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +270 -44
- package/src/runtime/routes/group-routes.ts +22 -8
- package/src/runtime/routes/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- package/src/runtime/routes/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export/AGENTS.md +104 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +103 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +716 -0
- package/src/runtime/routes/log-export/workspace-allowlist.ts +458 -0
- package/src/runtime/routes/log-export-routes.ts +41 -278
- package/src/runtime/routes/memory-item-routes.test.ts +168 -233
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +27 -12
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +45 -18
- package/src/skills/catalog-install.ts +10 -2
- package/src/skills/inline-command-runner.ts +12 -14
- package/src/skills/managed-store.ts +2 -2
- package/src/skills/skill-memory.ts +1 -293
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +4 -4
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/permission-checker.ts +78 -18
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/secret-detection-handler.ts +0 -1
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/skills/sandbox-runner.ts +3 -6
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +16 -1
- package/src/tools/terminal/sandbox-diagnostics.ts +4 -4
- package/src/tools/terminal/sandbox.ts +4 -1
- package/src/tools/terminal/shell.ts +3 -5
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +2 -3
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/watcher/provider-types.ts +1 -1
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +85 -0
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +73 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -377
- package/src/__tests__/clipboard.test.ts +0 -88
- package/src/cli/cli-memory.ts +0 -179
- package/src/util/clipboard.ts +0 -34
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { RiskLevel } from "../../permissions/types.js";
|
|
2
|
+
import type { ToolDefinition } from "../../providers/types.js";
|
|
3
|
+
import { getSubagentManager } from "../../subagent/index.js";
|
|
4
|
+
import { registerTool } from "../registry.js";
|
|
5
|
+
import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
6
|
+
|
|
7
|
+
export async function executeSubagentNotifyParent(
|
|
8
|
+
input: Record<string, unknown>,
|
|
9
|
+
context: ToolContext,
|
|
10
|
+
): Promise<ToolExecutionResult> {
|
|
11
|
+
const message = input.message as string;
|
|
12
|
+
const urgency = (input.urgency as string) || "info";
|
|
13
|
+
|
|
14
|
+
if (!message) {
|
|
15
|
+
return { content: '"message" is required.', isError: true };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const manager = getSubagentManager();
|
|
19
|
+
const sent = manager.notifyParent(context.conversationId, message, urgency);
|
|
20
|
+
|
|
21
|
+
if (!sent) {
|
|
22
|
+
return {
|
|
23
|
+
content:
|
|
24
|
+
"Could not notify parent. This tool is only available to subagents.",
|
|
25
|
+
isError: true,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
content: JSON.stringify({ sent: true, urgency }),
|
|
31
|
+
isError: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
class NotifyParentTool implements Tool {
|
|
36
|
+
name = "notify_parent";
|
|
37
|
+
description =
|
|
38
|
+
"Send a notification to the parent conversation. Use this for important findings, when you're blocked, or when you have preliminary results the parent should know about. Do not overuse — notify for significant findings, not after every tool call.";
|
|
39
|
+
category = "orchestration";
|
|
40
|
+
defaultRiskLevel = RiskLevel.Low;
|
|
41
|
+
|
|
42
|
+
getDefinition(): ToolDefinition {
|
|
43
|
+
return {
|
|
44
|
+
name: this.name,
|
|
45
|
+
description: this.description,
|
|
46
|
+
input_schema: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
message: {
|
|
50
|
+
type: "string",
|
|
51
|
+
description: "The notification content for the parent.",
|
|
52
|
+
},
|
|
53
|
+
urgency: {
|
|
54
|
+
type: "string",
|
|
55
|
+
enum: ["info", "important", "blocked"],
|
|
56
|
+
description:
|
|
57
|
+
"'info' for progress updates, 'important' for key findings, 'blocked' when you need guidance.",
|
|
58
|
+
},
|
|
59
|
+
activity: {
|
|
60
|
+
type: "string",
|
|
61
|
+
description:
|
|
62
|
+
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update.",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ["message", "activity"],
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async execute(
|
|
71
|
+
input: Record<string, unknown>,
|
|
72
|
+
context: ToolContext,
|
|
73
|
+
): Promise<ToolExecutionResult> {
|
|
74
|
+
return executeSubagentNotifyParent(input, context);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const notifyParentTool = new NotifyParentTool();
|
|
79
|
+
registerTool(notifyParentTool);
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { getMessages } from "../../memory/conversation-crud.js";
|
|
2
2
|
import { getSubagentManager, TERMINAL_STATUSES } from "../../subagent/index.js";
|
|
3
3
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
4
|
+
import { resolveSubagentId } from "./resolve.js";
|
|
4
5
|
|
|
5
6
|
export async function executeSubagentRead(
|
|
6
7
|
input: Record<string, unknown>,
|
|
7
8
|
context: ToolContext,
|
|
8
9
|
): Promise<ToolExecutionResult> {
|
|
9
|
-
const subagentId = input
|
|
10
|
+
const subagentId = resolveSubagentId(input, context);
|
|
11
|
+
if (!subagentId && input.label) {
|
|
12
|
+
return {
|
|
13
|
+
content: `No subagent found with label "${input.label as string}".`,
|
|
14
|
+
isError: true,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
10
17
|
if (!subagentId) {
|
|
11
|
-
return {
|
|
18
|
+
return {
|
|
19
|
+
content: '"subagent_id" or "label" is required.',
|
|
20
|
+
isError: true,
|
|
21
|
+
};
|
|
12
22
|
}
|
|
13
23
|
|
|
14
24
|
const manager = getSubagentManager();
|
|
@@ -45,32 +55,43 @@ export async function executeSubagentRead(
|
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
// Extract assistant messages only - that's the subagent's output.
|
|
48
|
-
|
|
58
|
+
// Group text blocks by message so last_n slices messages, not blocks.
|
|
59
|
+
const messageTexts: string[] = [];
|
|
49
60
|
for (const msg of dbMessages) {
|
|
50
61
|
if (msg.role !== "assistant") continue;
|
|
62
|
+
const blocks: string[] = [];
|
|
51
63
|
try {
|
|
52
64
|
const content = JSON.parse(msg.content);
|
|
53
65
|
if (Array.isArray(content)) {
|
|
54
66
|
for (const block of content) {
|
|
55
67
|
if (block.type === "text" && typeof block.text === "string") {
|
|
56
|
-
|
|
68
|
+
blocks.push(block.text);
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
} else if (typeof content === "string") {
|
|
60
|
-
|
|
72
|
+
blocks.push(content);
|
|
61
73
|
}
|
|
62
74
|
} catch {
|
|
63
75
|
// Content might be plain text.
|
|
64
|
-
|
|
76
|
+
blocks.push(msg.content);
|
|
77
|
+
}
|
|
78
|
+
if (blocks.length > 0) {
|
|
79
|
+
messageTexts.push(blocks.join("\n\n"));
|
|
65
80
|
}
|
|
66
81
|
}
|
|
67
82
|
|
|
68
|
-
if (
|
|
83
|
+
if (messageTexts.length === 0) {
|
|
69
84
|
return { content: "Subagent produced no text output.", isError: false };
|
|
70
85
|
}
|
|
71
86
|
|
|
87
|
+
const lastN =
|
|
88
|
+
typeof input.last_n === "number" && input.last_n > 0
|
|
89
|
+
? input.last_n
|
|
90
|
+
: undefined;
|
|
91
|
+
const sliced = lastN ? messageTexts.slice(-lastN) : messageTexts;
|
|
92
|
+
|
|
72
93
|
return {
|
|
73
|
-
content:
|
|
94
|
+
content: sliced.join("\n\n"),
|
|
74
95
|
isError: false,
|
|
75
96
|
};
|
|
76
97
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getSubagentManager } from "../../subagent/index.js";
|
|
2
|
+
import type { ToolContext } from "../types.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a subagent ID from tool input.
|
|
6
|
+
* Accepts either `subagent_id` (direct UUID) or `label` (case-insensitive lookup).
|
|
7
|
+
*/
|
|
8
|
+
export function resolveSubagentId(
|
|
9
|
+
input: Record<string, unknown>,
|
|
10
|
+
context: ToolContext,
|
|
11
|
+
): string | undefined {
|
|
12
|
+
if (input.subagent_id) return input.subagent_id as string;
|
|
13
|
+
if (input.label) {
|
|
14
|
+
const state = getSubagentManager().getByLabel(
|
|
15
|
+
input.label as string,
|
|
16
|
+
context.conversationId,
|
|
17
|
+
);
|
|
18
|
+
return state?.config.id;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
@@ -9,6 +9,7 @@ export async function executeSubagentSpawn(
|
|
|
9
9
|
const objective = input.objective as string;
|
|
10
10
|
const extraContext = input.context as string | undefined;
|
|
11
11
|
const sendResultToUser = input.send_result_to_user !== false;
|
|
12
|
+
const role = (input.role as string | undefined) ?? undefined;
|
|
12
13
|
|
|
13
14
|
if (!label || !objective) {
|
|
14
15
|
return {
|
|
@@ -36,6 +37,7 @@ export async function executeSubagentSpawn(
|
|
|
36
37
|
objective,
|
|
37
38
|
context: extraContext,
|
|
38
39
|
sendResultToUser,
|
|
40
|
+
...(role ? { role: role as import("../../subagent/types.js").SubagentRole } : {}),
|
|
39
41
|
},
|
|
40
42
|
sendToClient as (msg: unknown) => void,
|
|
41
43
|
);
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { getSubagentManager } from "../../subagent/index.js";
|
|
2
2
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
3
|
+
import { resolveSubagentId } from "./resolve.js";
|
|
3
4
|
|
|
4
5
|
export async function executeSubagentStatus(
|
|
5
6
|
input: Record<string, unknown>,
|
|
6
7
|
context: ToolContext,
|
|
7
8
|
): Promise<ToolExecutionResult> {
|
|
8
|
-
const subagentId = input
|
|
9
|
+
const subagentId = resolveSubagentId(input, context);
|
|
9
10
|
const manager = getSubagentManager();
|
|
10
11
|
|
|
12
|
+
// If a label was provided but didn't resolve, that's an error — don't fall
|
|
13
|
+
// through to the "list all" path.
|
|
14
|
+
if (!subagentId && input.label) {
|
|
15
|
+
return {
|
|
16
|
+
content: `No subagent found with label "${input.label as string}".`,
|
|
17
|
+
isError: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
if (subagentId) {
|
|
12
22
|
const state = manager.getState(subagentId);
|
|
13
23
|
if (
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
4
|
|
|
5
5
|
import { generateAvatar } from "../../media/avatar-router.js";
|
|
6
6
|
import { mapGeminiError } from "../../media/gemini-image-service.js";
|
|
7
7
|
import { getLogger } from "../../util/logger.js";
|
|
8
|
-
import {
|
|
8
|
+
import { getAvatarImagePath } from "../../util/platform.js";
|
|
9
9
|
|
|
10
10
|
const log = getLogger("avatar-generator");
|
|
11
11
|
|
|
12
12
|
/** Canonical path where the custom avatar PNG is stored. */
|
|
13
13
|
function getAvatarPath(): string {
|
|
14
|
-
return
|
|
14
|
+
return getAvatarImagePath();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export interface AvatarGenerationResult {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers feature-flag-gated system tools with the daemon's tool registry.
|
|
3
|
+
*
|
|
4
|
+
* Called once at daemon startup via initializeTools(). Tools that are always
|
|
5
|
+
* registered (e.g. request_system_permission) are handled via the tool
|
|
6
|
+
* manifest's explicit tools list; this module handles conditional registration.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
10
|
+
import { getConfig } from "../../config/loader.js";
|
|
11
|
+
import { registerTool } from "../registry.js";
|
|
12
|
+
import { setPermissionModeTool } from "./set-permission-mode.js";
|
|
13
|
+
|
|
14
|
+
export function registerSystemTools(): void {
|
|
15
|
+
try {
|
|
16
|
+
const config = getConfig();
|
|
17
|
+
if (isAssistantFeatureFlagEnabled("permission-controls-v2", config)) {
|
|
18
|
+
registerTool(setPermissionModeTool);
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
// Config not yet loaded (e.g. during test setup) — permission mode tool stays off.
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System tool: set_permission_mode
|
|
3
|
+
*
|
|
4
|
+
* Allows the LLM to deterministically switch permission mode axes via the
|
|
5
|
+
* PermissionModeStore rather than relying on model-generated text.
|
|
6
|
+
*
|
|
7
|
+
* This tool is always available (no permission check required) when the
|
|
8
|
+
* `permission-controls-v2` feature flag is enabled — it IS the permission
|
|
9
|
+
* mechanism.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
getMode,
|
|
14
|
+
setAskBeforeActing,
|
|
15
|
+
setHostAccess,
|
|
16
|
+
} from "../../permissions/permission-mode-store.js";
|
|
17
|
+
import { RiskLevel } from "../../permissions/types.js";
|
|
18
|
+
import type { ToolDefinition } from "../../providers/types.js";
|
|
19
|
+
import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
20
|
+
|
|
21
|
+
class SetPermissionModeTool implements Tool {
|
|
22
|
+
name = "set_permission_mode";
|
|
23
|
+
description =
|
|
24
|
+
"Change the assistant's permission mode. Supports partial updates — " +
|
|
25
|
+
"only the provided fields are changed. Use this to toggle whether the " +
|
|
26
|
+
"assistant asks before acting or whether host access is enabled.";
|
|
27
|
+
category = "system";
|
|
28
|
+
defaultRiskLevel = RiskLevel.Low;
|
|
29
|
+
|
|
30
|
+
getDefinition(): ToolDefinition {
|
|
31
|
+
return {
|
|
32
|
+
name: this.name,
|
|
33
|
+
description: this.description,
|
|
34
|
+
input_schema: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
askBeforeActing: {
|
|
38
|
+
type: "boolean",
|
|
39
|
+
description:
|
|
40
|
+
"When true, the assistant checks in with the user before taking actions.",
|
|
41
|
+
},
|
|
42
|
+
hostAccess: {
|
|
43
|
+
type: "boolean",
|
|
44
|
+
description:
|
|
45
|
+
"When true, the assistant can execute commands on the host machine without prompting.",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async execute(
|
|
53
|
+
input: Record<string, unknown>,
|
|
54
|
+
_context: ToolContext,
|
|
55
|
+
): Promise<ToolExecutionResult> {
|
|
56
|
+
const { askBeforeActing, hostAccess } = input;
|
|
57
|
+
|
|
58
|
+
// Validate that at least one field is provided
|
|
59
|
+
if (askBeforeActing === undefined && hostAccess === undefined) {
|
|
60
|
+
return {
|
|
61
|
+
content:
|
|
62
|
+
"Error: at least one of askBeforeActing or hostAccess must be provided.",
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Validate types of provided fields
|
|
68
|
+
if (askBeforeActing !== undefined && typeof askBeforeActing !== "boolean") {
|
|
69
|
+
return {
|
|
70
|
+
content: `Error: askBeforeActing must be a boolean, got ${typeof askBeforeActing}.`,
|
|
71
|
+
isError: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (hostAccess !== undefined && typeof hostAccess !== "boolean") {
|
|
75
|
+
return {
|
|
76
|
+
content: `Error: hostAccess must be a boolean, got ${typeof hostAccess}.`,
|
|
77
|
+
isError: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Apply changes for provided fields
|
|
82
|
+
if (typeof askBeforeActing === "boolean") {
|
|
83
|
+
setAskBeforeActing(askBeforeActing);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof hostAccess === "boolean") {
|
|
87
|
+
setHostAccess(hostAccess);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Return confirmation with the new state
|
|
91
|
+
const mode = getMode();
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
"Permission mode updated.",
|
|
95
|
+
` askBeforeActing: ${mode.askBeforeActing}`,
|
|
96
|
+
` hostAccess: ${mode.hostAccess}`,
|
|
97
|
+
].join("\n"),
|
|
98
|
+
isError: false,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const setPermissionModeTool = new SetPermissionModeTool();
|
|
@@ -49,9 +49,29 @@ const SCRIPT_INTERPRETERS = new Set([
|
|
|
49
49
|
"deno",
|
|
50
50
|
"bun",
|
|
51
51
|
]);
|
|
52
|
-
// Flags that make an interpreter
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
// Flags that make an interpreter read code from stdin rather than from a file.
|
|
53
|
+
const STDIN_EXEC_FLAGS = new Set(["-"]);
|
|
54
|
+
// Per-interpreter flags that provide code inline as an argument (e.g.
|
|
55
|
+
// `python -c 'code'`, `node -e 'code'`). When these are present the
|
|
56
|
+
// interpreter is NOT reading code from stdin — stdin is just data, so piping
|
|
57
|
+
// into the interpreter is no more dangerous than piping into grep or jq.
|
|
58
|
+
//
|
|
59
|
+
// This must be interpreter-specific because the same flag can mean different
|
|
60
|
+
// things across interpreters. For example, `perl -c` is syntax-check mode
|
|
61
|
+
// (still reads code from stdin and executes BEGIN blocks), while
|
|
62
|
+
// `python -c` provides inline code. Similarly, `ruby -c` is syntax-check.
|
|
63
|
+
const INTERPRETER_INLINE_CODE_FLAGS: ReadonlyMap<
|
|
64
|
+
string,
|
|
65
|
+
ReadonlySet<string>
|
|
66
|
+
> = new Map([
|
|
67
|
+
["python", new Set(["-c"])],
|
|
68
|
+
["python3", new Set(["-c"])],
|
|
69
|
+
["ruby", new Set(["-e"])],
|
|
70
|
+
["perl", new Set(["-e"])],
|
|
71
|
+
["node", new Set(["-e"])],
|
|
72
|
+
["deno", new Set(["-e"])],
|
|
73
|
+
["bun", new Set(["-e"])],
|
|
74
|
+
]);
|
|
55
75
|
// Per-interpreter flags that consume the next argument as a value (not a filename).
|
|
56
76
|
// Mapped by interpreter name since flags differ across interpreters
|
|
57
77
|
// (e.g. -I is standalone in Python but takes a value in Ruby).
|
|
@@ -353,18 +373,23 @@ function extractSegments(node: TSNode): CommandSegment[] {
|
|
|
353
373
|
|
|
354
374
|
/**
|
|
355
375
|
* Returns true when the interpreter args indicate stdin-exec mode - i.e. the
|
|
356
|
-
* interpreter will read code from stdin
|
|
357
|
-
* rather than from a file. Concretely:
|
|
376
|
+
* interpreter will read code from stdin rather than from a file. Concretely:
|
|
358
377
|
* - Any STDIN_EXEC_FLAGS present → stdin-exec
|
|
378
|
+
* - Interpreter-specific inline code flag (-c/-e) → NOT stdin-exec
|
|
359
379
|
* - No positional (non-flag) arguments at all → stdin-exec (bare `python`)
|
|
360
380
|
* - Otherwise the first positional arg is a filename → NOT stdin-exec
|
|
361
381
|
*/
|
|
362
382
|
function isStdinExecMode(interpreter: string, args: string[]): boolean {
|
|
363
383
|
const valueFlags =
|
|
364
384
|
INTERPRETER_VALUE_FLAGS.get(interpreter) ?? new Set<string>();
|
|
385
|
+
const inlineCodeFlags =
|
|
386
|
+
INTERPRETER_INLINE_CODE_FLAGS.get(interpreter) ?? new Set<string>();
|
|
365
387
|
for (let i = 0; i < args.length; i++) {
|
|
366
388
|
const arg = args[i];
|
|
367
389
|
if (STDIN_EXEC_FLAGS.has(arg)) return true;
|
|
390
|
+
// Interpreter-specific inline code flags (e.g. python -c, node -e) mean
|
|
391
|
+
// the code is provided as an argument, not read from stdin.
|
|
392
|
+
if (inlineCodeFlags.has(arg)) return false;
|
|
368
393
|
// First non-flag argument is a filename/module → file mode
|
|
369
394
|
if (!arg.startsWith("-")) return false;
|
|
370
395
|
// Flags like -W, -X consume the next token as their value - skip it
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { getGatewayInternalBaseUrl } from "../../config/env.js";
|
|
9
9
|
import { getDataDir, getWorkspaceDir } from "../../util/platform.js";
|
|
10
10
|
|
|
11
|
-
const SAFE_ENV_VARS = [
|
|
11
|
+
export const SAFE_ENV_VARS = [
|
|
12
12
|
"PATH",
|
|
13
13
|
"HOME",
|
|
14
14
|
"TERM",
|
|
@@ -37,6 +37,21 @@ const SAFE_ENV_VARS = [
|
|
|
37
37
|
"IS_CONTAINERIZED",
|
|
38
38
|
"IS_PLATFORM",
|
|
39
39
|
"CES_SERVICE_TOKEN",
|
|
40
|
+
"VELLUM_PROFILER_RUN_ID",
|
|
41
|
+
"VELLUM_PROFILER_MODE",
|
|
42
|
+
"VELLUM_PROFILER_MAX_BYTES",
|
|
43
|
+
"VELLUM_PROFILER_MAX_RUNS",
|
|
44
|
+
"VELLUM_PROFILER_MIN_FREE_MB",
|
|
45
|
+
] as const;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Keys that buildSanitizedEnv always injects into the returned env,
|
|
49
|
+
* independent of what is present in process.env.
|
|
50
|
+
*/
|
|
51
|
+
export const ALWAYS_INJECTED_ENV_VARS = [
|
|
52
|
+
"INTERNAL_GATEWAY_BASE_URL",
|
|
53
|
+
"VELLUM_DATA_DIR",
|
|
54
|
+
"VELLUM_WORKSPACE_DIR",
|
|
40
55
|
] as const;
|
|
41
56
|
|
|
42
57
|
export function buildSanitizedEnv(): Record<string, string> {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
|
|
3
|
-
import { getConfig } from "../../config/loader.js";
|
|
4
|
-
import type { SandboxConfig } from "../../config/schema.js";
|
|
5
3
|
import { isLinux, isMacOS } from "../../util/platform.js";
|
|
4
|
+
import type { SandboxConfig } from "./sandbox.js";
|
|
6
5
|
|
|
7
6
|
export interface SandboxCheckResult {
|
|
8
7
|
label: string;
|
|
@@ -69,8 +68,9 @@ function getActiveBackendReason(sandboxConfig: SandboxConfig): string {
|
|
|
69
68
|
* and reports current configuration.
|
|
70
69
|
*/
|
|
71
70
|
export function runSandboxDiagnostics(): SandboxDiagnostics {
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
// Sandbox is disabled — the assistant runs exclusively in Docker or
|
|
72
|
+
// platform-managed environments.
|
|
73
|
+
const sandboxConfig: SandboxConfig = { enabled: false };
|
|
74
74
|
|
|
75
75
|
const checks: SandboxCheckResult[] = [];
|
|
76
76
|
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { SandboxConfig } from "../../config/schema.js";
|
|
2
1
|
import { NativeBackend } from "./backends/native.js";
|
|
3
2
|
import type { SandboxResult, WrapOptions } from "./backends/types.js";
|
|
4
3
|
|
|
4
|
+
export interface SandboxConfig {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
5
8
|
export type {
|
|
6
9
|
SandboxBackend,
|
|
7
10
|
SandboxResult,
|
|
@@ -261,11 +261,9 @@ class ShellTool implements Tool {
|
|
|
261
261
|
"Executing shell command",
|
|
262
262
|
);
|
|
263
263
|
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
? { ...config.sandbox, enabled: context.sandboxOverride }
|
|
268
|
-
: config.sandbox;
|
|
264
|
+
// The assistant runs exclusively in Docker or platform-managed
|
|
265
|
+
// environments where the container provides isolation.
|
|
266
|
+
const sandboxConfig = { enabled: false } as const;
|
|
269
267
|
|
|
270
268
|
// Acquire proxy session if proxied mode is requested.
|
|
271
269
|
// `getOrStartSession` serializes per-conversation so concurrent proxied
|
|
@@ -16,6 +16,7 @@ import { manageSecureCommandTool } from "./credential-execution/manage-secure-co
|
|
|
16
16
|
import { runAuthenticatedCommandTool } from "./credential-execution/run-authenticated-command.js";
|
|
17
17
|
import { credentialStoreTool } from "./credentials/vault.js";
|
|
18
18
|
import { fileEditTool } from "./filesystem/edit.js";
|
|
19
|
+
import { fileListTool } from "./filesystem/list.js";
|
|
19
20
|
import { fileReadTool } from "./filesystem/read.js";
|
|
20
21
|
import { fileWriteTool } from "./filesystem/write.js";
|
|
21
22
|
import { recallTool, rememberTool } from "./memory/register.js";
|
|
@@ -23,6 +24,7 @@ import { webFetchTool } from "./network/web-fetch.js";
|
|
|
23
24
|
import { webSearchTool } from "./network/web-search.js";
|
|
24
25
|
import { skillExecuteTool } from "./skills/execute.js";
|
|
25
26
|
import { skillLoadTool } from "./skills/load.js";
|
|
27
|
+
import { notifyParentTool } from "./subagent/notify-parent.js";
|
|
26
28
|
import { requestSystemPermissionTool } from "./system/request-permission.js";
|
|
27
29
|
import { shellTool } from "./terminal/shell.js";
|
|
28
30
|
import type { Tool } from "./types.js";
|
|
@@ -56,11 +58,13 @@ export const eagerModuleToolNames: string[] = [
|
|
|
56
58
|
"file_read",
|
|
57
59
|
"file_write",
|
|
58
60
|
"file_edit",
|
|
61
|
+
"file_list",
|
|
59
62
|
"web_search",
|
|
60
63
|
"web_fetch",
|
|
61
64
|
"skill_execute",
|
|
62
65
|
"skill_load",
|
|
63
66
|
"request_system_permission",
|
|
67
|
+
"notify_parent",
|
|
64
68
|
];
|
|
65
69
|
|
|
66
70
|
// ── Explicit tool instances ─────────────────────────────────────────
|
|
@@ -76,6 +80,7 @@ export const explicitTools: Tool[] = [
|
|
|
76
80
|
fileReadTool,
|
|
77
81
|
fileWriteTool,
|
|
78
82
|
fileEditTool,
|
|
83
|
+
fileListTool,
|
|
79
84
|
webFetchTool,
|
|
80
85
|
webSearchTool,
|
|
81
86
|
skillExecuteTool,
|
|
@@ -85,6 +90,7 @@ export const explicitTools: Tool[] = [
|
|
|
85
90
|
rememberTool,
|
|
86
91
|
recallTool,
|
|
87
92
|
credentialStoreTool,
|
|
93
|
+
notifyParentTool,
|
|
88
94
|
];
|
|
89
95
|
|
|
90
96
|
// ── CES tools (feature-flag gated) ──────────────────────────────────
|
package/src/tools/types.ts
CHANGED
|
@@ -34,7 +34,6 @@ export interface ToolPermissionPromptEvent extends ToolLifecycleEventBase {
|
|
|
34
34
|
allowlistOptions: AllowlistOption[];
|
|
35
35
|
scopeOptions: ScopeOption[];
|
|
36
36
|
diff?: DiffInfo;
|
|
37
|
-
sandboxed?: boolean;
|
|
38
37
|
persistentDecisionsAllowed?: boolean;
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -110,8 +109,6 @@ export interface ToolContext {
|
|
|
110
109
|
onOutput?: (chunk: string) => void;
|
|
111
110
|
/** Abort signal for cooperative cancellation. Tools should check this periodically. */
|
|
112
111
|
signal?: AbortSignal;
|
|
113
|
-
/** Per-conversation sandbox override. When set, takes precedence over the global config. */
|
|
114
|
-
sandboxOverride?: boolean;
|
|
115
112
|
/** Optional callback for tool lifecycle events (start/prompt/deny/execute/error/secret_detected). */
|
|
116
113
|
onToolLifecycleEvent?: ToolLifecycleEventHandler;
|
|
117
114
|
/** Optional resolver for proxy tools - delegates execution to an external client. */
|
|
@@ -181,6 +178,8 @@ export interface ToolContext {
|
|
|
181
178
|
hostBashProxy?: import("../daemon/host-bash-proxy.js").HostBashProxy;
|
|
182
179
|
/** Optional proxy for delegating host_file_read/write/edit execution to a connected client (managed/cloud-hosted mode). */
|
|
183
180
|
hostFileProxy?: import("../daemon/host-file-proxy.js").HostFileProxy;
|
|
181
|
+
/** True when the assistant is running as a platform-managed remote instance. Used to auto-approve sandboxed bash tools. */
|
|
182
|
+
isPlatformHosted?: boolean;
|
|
184
183
|
/** CES RPC client for credential execution operations. When present, the executor can bridge CES approval flows. */
|
|
185
184
|
cesClient?: CesClient;
|
|
186
185
|
}
|
package/src/util/logger.ts
CHANGED
|
@@ -36,7 +36,7 @@ export type LogFileConfig = {
|
|
|
36
36
|
|
|
37
37
|
const LOG_FILE_PREFIX = "assistant-";
|
|
38
38
|
const LOG_FILE_SUFFIX = ".log";
|
|
39
|
-
const LOG_FILE_PATTERN = /^assistant-(\d{4}-\d{2}-\d{2})\.log$/;
|
|
39
|
+
export const LOG_FILE_PATTERN = /^assistant-(\d{4}-\d{2}-\d{2})\.log$/;
|
|
40
40
|
|
|
41
41
|
function formatDate(date: Date): string {
|
|
42
42
|
const y = date.getUTCFullYear();
|