@vellumai/assistant 0.4.48 → 0.4.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +2 -2
- package/README.md +2 -23
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +156 -0
- package/src/__tests__/approval-cascade.test.ts +810 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +15 -6
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +9 -29
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-metadata-store.test.ts +64 -73
- package/src/__tests__/credential-security-invariants.test.ts +13 -7
- package/src/__tests__/credential-vault-unit.test.ts +280 -49
- package/src/__tests__/credential-vault.test.ts +138 -16
- package/src/__tests__/credentials-cli.test.ts +71 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-cu-proxy.test.ts +629 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +32 -51
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +11 -43
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +373 -14
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +756 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/send-endpoint-busy.test.ts +21 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-uninstall.test.ts +1 -1
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/slack-channel-config.test.ts +67 -3
- package/src/__tests__/slack-share-routes.test.ts +17 -19
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +1 -22
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -16
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +235 -0
- package/src/agent/loop.ts +76 -130
- package/src/calls/call-domain.ts +1 -6
- package/src/calls/relay-server.ts +9 -13
- package/src/calls/twilio-config.ts +2 -7
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +18 -12
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +101 -15
- package/src/cli/commands/oauth/apps.ts +255 -0
- package/src/cli/commands/oauth/connections.ts +299 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +242 -0
- package/src/cli/commands/skills.ts +4 -338
- package/src/cli/program.ts +1 -5
- package/src/cli/reference.ts +1 -3
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +21 -16
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -4
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/loader.ts +0 -6
- package/src/config/schema.ts +3 -1
- package/src/config/skills.ts +21 -2
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +49 -10
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +49 -46
- package/src/daemon/handlers/config-telegram.ts +32 -16
- package/src/daemon/handlers/sessions.ts +10 -24
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/host-cu-proxy.ts +401 -0
- package/src/daemon/lifecycle.ts +36 -68
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +2 -119
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/server.ts +14 -21
- package/src/daemon/session-agent-loop-handlers.ts +2 -0
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +40 -28
- package/src/daemon/session-tool-setup.ts +2 -9
- package/src/daemon/session.ts +138 -15
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/logfire.ts +16 -5
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/migrations/149-oauth-tables.ts +60 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/oauth.ts +65 -0
- package/src/messaging/provider.ts +4 -4
- package/src/messaging/providers/gmail/client.ts +82 -2
- package/src/messaging/providers/gmail/people-client.ts +10 -10
- package/src/messaging/providers/telegram-bot/adapter.ts +17 -17
- package/src/messaging/providers/whatsapp/adapter.ts +11 -8
- package/src/messaging/registry.ts +2 -32
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +126 -25
- package/src/oauth/byo-connection.ts +22 -6
- package/src/oauth/connect-orchestrator.ts +113 -57
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +35 -11
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +496 -0
- package/src/oauth/platform-connection.test.ts +29 -0
- package/src/oauth/platform-connection.ts +6 -5
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +161 -0
- package/src/oauth/token-persistence.ts +74 -78
- package/src/permissions/checker.ts +3 -3
- package/src/permissions/defaults.ts +0 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +13 -0
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +28 -40
- package/src/providers/anthropic/client.ts +133 -24
- package/src/providers/retry.ts +1 -27
- package/src/runtime/auth/route-policy.ts +0 -3
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/http-server.ts +8 -6
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/conversation-routes.ts +73 -19
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -7
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/settings-routes.ts +55 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/schedule/integration-status.ts +10 -9
- package/src/security/credential-key.ts +0 -156
- package/src/security/keychain-broker-client.ts +5 -6
- package/src/security/oauth2.ts +1 -1
- package/src/security/token-manager.ts +119 -46
- package/src/skills/catalog-install.ts +358 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/computer-use/definitions.ts +46 -11
- package/src/tools/computer-use/registry.ts +4 -5
- package/src/tools/credentials/broker.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +17 -121
- package/src/tools/credentials/vault.ts +94 -167
- package/src/tools/registry.ts +2 -7
- package/src/tools/skills/load.ts +62 -3
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/watcher/providers/google-calendar.ts +2 -1
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
- package/src/daemon/computer-use-session.ts +0 -1026
- package/src/daemon/ride-shotgun-handler.ts +0 -569
- package/src/oauth/provider-base-urls.ts +0 -21
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -729
- package/src/runtime/telegram-streaming-delivery.ts +0 -393
- package/src/tools/computer-use/request-computer-control.ts +0 -56
|
@@ -1,348 +1,14 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
import {
|
|
4
|
-
cpSync,
|
|
5
|
-
existsSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
renameSync,
|
|
9
|
-
rmSync,
|
|
10
|
-
writeFileSync,
|
|
11
|
-
} from "node:fs";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { dirname, join } from "node:path";
|
|
14
|
-
import { gunzipSync } from "node:zlib";
|
|
15
|
-
|
|
16
1
|
import type { Command } from "commander";
|
|
17
2
|
|
|
3
|
+
import type { CatalogSkill } from "../../skills/catalog-install.js";
|
|
18
4
|
import {
|
|
19
|
-
getWorkspaceConfigPath,
|
|
20
|
-
getWorkspaceSkillsDir,
|
|
21
|
-
readPlatformToken,
|
|
22
|
-
} from "../../util/platform.js";
|
|
23
|
-
import { log } from "../logger.js";
|
|
24
|
-
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Path helpers
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
function getSkillsIndexPath(): string {
|
|
30
|
-
return join(getWorkspaceSkillsDir(), "SKILLS.md");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Resolve the repo-level skills/ directory when running in dev mode.
|
|
35
|
-
* Returns the path if VELLUM_DEV is set and the directory exists, or undefined.
|
|
36
|
-
*/
|
|
37
|
-
function getRepoSkillsDir(): string | undefined {
|
|
38
|
-
if (!process.env.VELLUM_DEV) return undefined;
|
|
39
|
-
|
|
40
|
-
// assistant/src/cli/commands/skills.ts -> ../../../../skills/
|
|
41
|
-
const candidate = join(import.meta.dir, "..", "..", "..", "..", "skills");
|
|
42
|
-
if (existsSync(join(candidate, "catalog.json"))) {
|
|
43
|
-
return candidate;
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Read skills from the repo-local catalog.json.
|
|
50
|
-
*/
|
|
51
|
-
function readLocalCatalog(repoSkillsDir: string): CatalogSkill[] {
|
|
52
|
-
try {
|
|
53
|
-
const raw = readFileSync(join(repoSkillsDir, "catalog.json"), "utf-8");
|
|
54
|
-
const manifest = JSON.parse(raw) as CatalogManifest;
|
|
55
|
-
if (!Array.isArray(manifest.skills)) return [];
|
|
56
|
-
return manifest.skills;
|
|
57
|
-
} catch {
|
|
58
|
-
return [];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// Platform API client
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
function getConfigPlatformUrl(): string | undefined {
|
|
67
|
-
try {
|
|
68
|
-
const configPath = getWorkspaceConfigPath();
|
|
69
|
-
if (!existsSync(configPath)) return undefined;
|
|
70
|
-
const raw = JSON.parse(readFileSync(configPath, "utf-8")) as Record<
|
|
71
|
-
string,
|
|
72
|
-
unknown
|
|
73
|
-
>;
|
|
74
|
-
const platform = raw.platform as Record<string, unknown> | undefined;
|
|
75
|
-
const baseUrl = platform?.baseUrl;
|
|
76
|
-
if (typeof baseUrl === "string" && baseUrl.trim()) return baseUrl.trim();
|
|
77
|
-
} catch {
|
|
78
|
-
// ignore
|
|
79
|
-
}
|
|
80
|
-
return undefined;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function getPlatformUrl(): string {
|
|
84
|
-
return (
|
|
85
|
-
process.env.VELLUM_ASSISTANT_PLATFORM_URL ??
|
|
86
|
-
getConfigPlatformUrl() ??
|
|
87
|
-
"https://platform.vellum.ai"
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function buildHeaders(): Record<string, string> {
|
|
92
|
-
const headers: Record<string, string> = {};
|
|
93
|
-
const token = readPlatformToken();
|
|
94
|
-
if (token) {
|
|
95
|
-
headers["X-Session-Token"] = token;
|
|
96
|
-
}
|
|
97
|
-
return headers;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ---------------------------------------------------------------------------
|
|
101
|
-
// Types
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
|
|
104
|
-
interface CatalogSkill {
|
|
105
|
-
id: string;
|
|
106
|
-
name: string;
|
|
107
|
-
description: string;
|
|
108
|
-
emoji?: string;
|
|
109
|
-
includes?: string[];
|
|
110
|
-
version?: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
interface CatalogManifest {
|
|
114
|
-
version: number;
|
|
115
|
-
skills: CatalogSkill[];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
// Catalog operations
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
|
|
122
|
-
async function fetchCatalog(): Promise<CatalogSkill[]> {
|
|
123
|
-
const url = `${getPlatformUrl()}/v1/skills/`;
|
|
124
|
-
const response = await fetch(url, {
|
|
125
|
-
headers: buildHeaders(),
|
|
126
|
-
signal: AbortSignal.timeout(10000),
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
if (!response.ok) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`Platform API error ${response.status}: ${response.statusText}`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const manifest = (await response.json()) as CatalogManifest;
|
|
136
|
-
if (!Array.isArray(manifest.skills)) {
|
|
137
|
-
throw new Error("Platform catalog has invalid skills array");
|
|
138
|
-
}
|
|
139
|
-
return manifest.skills;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Extract all files from a tar archive (uncompressed) into a directory.
|
|
144
|
-
* Returns true if a SKILL.md was found in the archive.
|
|
145
|
-
*/
|
|
146
|
-
function extractTarToDir(tarBuffer: Buffer, destDir: string): boolean {
|
|
147
|
-
let foundSkillMd = false;
|
|
148
|
-
let offset = 0;
|
|
149
|
-
while (offset + 512 <= tarBuffer.length) {
|
|
150
|
-
const header = tarBuffer.subarray(offset, offset + 512);
|
|
151
|
-
|
|
152
|
-
// End-of-archive (two consecutive zero blocks)
|
|
153
|
-
if (header.every((b) => b === 0)) break;
|
|
154
|
-
|
|
155
|
-
// Filename (bytes 0-99, null-terminated)
|
|
156
|
-
const nameEnd = header.indexOf(0, 0);
|
|
157
|
-
const name = header
|
|
158
|
-
.subarray(0, Math.min(nameEnd >= 0 ? nameEnd : 100, 100))
|
|
159
|
-
.toString("utf-8");
|
|
160
|
-
|
|
161
|
-
// File type (byte 156): '5' = directory, '0' or '\0' = regular file
|
|
162
|
-
const typeFlag = header[156];
|
|
163
|
-
|
|
164
|
-
// File size (bytes 124-135, octal)
|
|
165
|
-
const sizeStr = header.subarray(124, 136).toString("utf-8").trim();
|
|
166
|
-
const size = parseInt(sizeStr, 8) || 0;
|
|
167
|
-
|
|
168
|
-
offset += 512; // past header
|
|
169
|
-
|
|
170
|
-
// Skip directories and empty names
|
|
171
|
-
if (name && typeFlag !== 53 /* '5' */) {
|
|
172
|
-
// Prevent path traversal
|
|
173
|
-
const normalizedName = name.replace(/^\.\//, "");
|
|
174
|
-
if (!normalizedName.startsWith("..") && !normalizedName.includes("/..")) {
|
|
175
|
-
const destPath = join(destDir, normalizedName);
|
|
176
|
-
mkdirSync(dirname(destPath), { recursive: true });
|
|
177
|
-
writeFileSync(destPath, tarBuffer.subarray(offset, offset + size));
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
normalizedName === "SKILL.md" ||
|
|
181
|
-
normalizedName.endsWith("/SKILL.md")
|
|
182
|
-
) {
|
|
183
|
-
foundSkillMd = true;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Skip to next header (data padded to 512 bytes)
|
|
189
|
-
offset += Math.ceil(size / 512) * 512;
|
|
190
|
-
}
|
|
191
|
-
return foundSkillMd;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async function fetchAndExtractSkill(
|
|
195
|
-
skillId: string,
|
|
196
|
-
destDir: string,
|
|
197
|
-
): Promise<void> {
|
|
198
|
-
const url = `${getPlatformUrl()}/v1/skills/${encodeURIComponent(skillId)}/`;
|
|
199
|
-
const response = await fetch(url, {
|
|
200
|
-
headers: buildHeaders(),
|
|
201
|
-
signal: AbortSignal.timeout(15000),
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
if (!response.ok) {
|
|
205
|
-
throw new Error(
|
|
206
|
-
`Failed to fetch skill "${skillId}": HTTP ${response.status}`,
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const gzipBuffer = Buffer.from(await response.arrayBuffer());
|
|
211
|
-
const tarBuffer = gunzipSync(gzipBuffer);
|
|
212
|
-
const foundSkillMd = extractTarToDir(tarBuffer, destDir);
|
|
213
|
-
|
|
214
|
-
if (!foundSkillMd) {
|
|
215
|
-
throw new Error(`SKILL.md not found in archive for "${skillId}"`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ---------------------------------------------------------------------------
|
|
220
|
-
// Managed skill installation
|
|
221
|
-
// ---------------------------------------------------------------------------
|
|
222
|
-
|
|
223
|
-
function atomicWriteFile(filePath: string, content: string): void {
|
|
224
|
-
const dir = dirname(filePath);
|
|
225
|
-
mkdirSync(dir, { recursive: true });
|
|
226
|
-
const tmpPath = join(dir, `.tmp-${randomUUID()}`);
|
|
227
|
-
writeFileSync(tmpPath, content, "utf-8");
|
|
228
|
-
renameSync(tmpPath, filePath);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function upsertSkillsIndex(id: string): void {
|
|
232
|
-
const indexPath = getSkillsIndexPath();
|
|
233
|
-
let lines: string[] = [];
|
|
234
|
-
if (existsSync(indexPath)) {
|
|
235
|
-
lines = readFileSync(indexPath, "utf-8").split("\n");
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const escaped = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
239
|
-
const pattern = new RegExp(`^[-*]\\s+(?:\`)?${escaped}(?:\`)?\\s*$`);
|
|
240
|
-
if (lines.some((line) => pattern.test(line))) return;
|
|
241
|
-
|
|
242
|
-
const nonEmpty = lines.filter((l) => l.trim());
|
|
243
|
-
nonEmpty.push(`- ${id}`);
|
|
244
|
-
const content = nonEmpty.join("\n");
|
|
245
|
-
atomicWriteFile(indexPath, content.endsWith("\n") ? content : content + "\n");
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function removeSkillsIndexEntry(id: string): void {
|
|
249
|
-
const indexPath = getSkillsIndexPath();
|
|
250
|
-
if (!existsSync(indexPath)) return;
|
|
251
|
-
|
|
252
|
-
const lines = readFileSync(indexPath, "utf-8").split("\n");
|
|
253
|
-
const escaped = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
254
|
-
const pattern = new RegExp(`^[-*]\\s+(?:\`)?${escaped}(?:\`)?\\s*$`);
|
|
255
|
-
const filtered = lines.filter((line) => !pattern.test(line));
|
|
256
|
-
|
|
257
|
-
// If nothing changed, skip the write
|
|
258
|
-
if (filtered.length === lines.length) return;
|
|
259
|
-
|
|
260
|
-
const content = filtered.join("\n");
|
|
261
|
-
atomicWriteFile(indexPath, content.endsWith("\n") ? content : content + "\n");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function uninstallSkillLocally(skillId: string): void {
|
|
265
|
-
const skillDir = join(getWorkspaceSkillsDir(), skillId);
|
|
266
|
-
|
|
267
|
-
if (!existsSync(skillDir)) {
|
|
268
|
-
throw new Error(`Skill "${skillId}" is not installed.`);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
rmSync(skillDir, { recursive: true, force: true });
|
|
272
|
-
removeSkillsIndexEntry(skillId);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async function installSkillLocally(
|
|
276
|
-
skillId: string,
|
|
277
|
-
catalogEntry: CatalogSkill,
|
|
278
|
-
overwrite: boolean,
|
|
279
|
-
): Promise<void> {
|
|
280
|
-
const skillDir = join(getWorkspaceSkillsDir(), skillId);
|
|
281
|
-
const skillFilePath = join(skillDir, "SKILL.md");
|
|
282
|
-
|
|
283
|
-
if (existsSync(skillFilePath) && !overwrite) {
|
|
284
|
-
throw new Error(
|
|
285
|
-
`Skill "${skillId}" is already installed. Use --overwrite to replace it.`,
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
mkdirSync(skillDir, { recursive: true });
|
|
290
|
-
|
|
291
|
-
// In dev mode, install from the local repo skills directory if available
|
|
292
|
-
const repoSkillsDir = getRepoSkillsDir();
|
|
293
|
-
const repoSkillSource = repoSkillsDir
|
|
294
|
-
? join(repoSkillsDir, skillId)
|
|
295
|
-
: undefined;
|
|
296
|
-
|
|
297
|
-
if (repoSkillSource && existsSync(join(repoSkillSource, "SKILL.md"))) {
|
|
298
|
-
cpSync(repoSkillSource, skillDir, { recursive: true });
|
|
299
|
-
} else {
|
|
300
|
-
await fetchAndExtractSkill(skillId, skillDir);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Write version metadata
|
|
304
|
-
if (catalogEntry.version) {
|
|
305
|
-
const meta = {
|
|
306
|
-
version: catalogEntry.version,
|
|
307
|
-
installedAt: new Date().toISOString(),
|
|
308
|
-
};
|
|
309
|
-
atomicWriteFile(
|
|
310
|
-
join(skillDir, "version.json"),
|
|
311
|
-
JSON.stringify(meta, null, 2) + "\n",
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Install npm dependencies if the skill has a package.json
|
|
316
|
-
if (existsSync(join(skillDir, "package.json"))) {
|
|
317
|
-
const bunPath = `${homedir()}/.bun/bin`;
|
|
318
|
-
execSync("bun install", {
|
|
319
|
-
cwd: skillDir,
|
|
320
|
-
stdio: "inherit",
|
|
321
|
-
env: { ...process.env, PATH: `${bunPath}:${process.env.PATH}` },
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Register in SKILLS.md only after all steps succeed
|
|
326
|
-
upsertSkillsIndex(skillId);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// ---------------------------------------------------------------------------
|
|
330
|
-
// Exported types and functions for testing
|
|
331
|
-
// ---------------------------------------------------------------------------
|
|
332
|
-
|
|
333
|
-
export type { CatalogManifest, CatalogSkill };
|
|
334
|
-
|
|
335
|
-
export {
|
|
336
|
-
extractTarToDir,
|
|
337
|
-
fetchAndExtractSkill,
|
|
338
5
|
fetchCatalog,
|
|
339
|
-
|
|
6
|
+
getRepoSkillsDir,
|
|
340
7
|
installSkillLocally,
|
|
341
8
|
readLocalCatalog,
|
|
342
|
-
removeSkillsIndexEntry,
|
|
343
9
|
uninstallSkillLocally,
|
|
344
|
-
|
|
345
|
-
};
|
|
10
|
+
} from "../../skills/catalog-install.js";
|
|
11
|
+
import { log } from "../logger.js";
|
|
346
12
|
|
|
347
13
|
// ---------------------------------------------------------------------------
|
|
348
14
|
// Command registration
|
package/src/cli/program.ts
CHANGED
|
@@ -12,15 +12,13 @@ import { registerConfigCommand } from "./commands/config.js";
|
|
|
12
12
|
import { registerContactsCommand } from "./commands/contacts.js";
|
|
13
13
|
import { registerCredentialsCommand } from "./commands/credentials.js";
|
|
14
14
|
import { registerDefaultAction } from "./commands/default-action.js";
|
|
15
|
-
import { registerDevCommand } from "./commands/dev.js";
|
|
16
15
|
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
17
16
|
import { registerEmailCommand } from "./commands/email.js";
|
|
18
17
|
import { registerKeysCommand } from "./commands/keys.js";
|
|
19
|
-
import { registerMapCommand } from "./commands/map.js";
|
|
20
18
|
import { registerMcpCommand } from "./commands/mcp.js";
|
|
21
19
|
import { registerMemoryCommand } from "./commands/memory.js";
|
|
22
20
|
import { registerNotificationsCommand } from "./commands/notifications.js";
|
|
23
|
-
import { registerOAuthCommand } from "./commands/oauth.js";
|
|
21
|
+
import { registerOAuthCommand } from "./commands/oauth/index.js";
|
|
24
22
|
import { registerPlatformCommand } from "./commands/platform.js";
|
|
25
23
|
import { registerSequenceCommand } from "./commands/sequence.js";
|
|
26
24
|
import { registerSessionsCommand } from "./commands/sessions.js";
|
|
@@ -36,7 +34,6 @@ export function buildCliProgram(): Command {
|
|
|
36
34
|
program.name("assistant").description("Local AI assistant").version(version);
|
|
37
35
|
|
|
38
36
|
registerDefaultAction(program);
|
|
39
|
-
registerDevCommand(program);
|
|
40
37
|
registerSessionsCommand(program);
|
|
41
38
|
registerConfigCommand(program);
|
|
42
39
|
registerKeysCommand(program);
|
|
@@ -58,7 +55,6 @@ export function buildCliProgram(): Command {
|
|
|
58
55
|
registerSkillsCommand(program);
|
|
59
56
|
registerBrowserRelayCommand(program);
|
|
60
57
|
|
|
61
|
-
registerMapCommand(program);
|
|
62
58
|
registerSequenceCommand(program);
|
|
63
59
|
|
|
64
60
|
return program;
|
package/src/cli/reference.ts
CHANGED
|
@@ -10,7 +10,6 @@ Options:
|
|
|
10
10
|
-h, --help display help for command
|
|
11
11
|
|
|
12
12
|
Commands:
|
|
13
|
-
dev [options] Run the assistant in dev mode
|
|
14
13
|
sessions Manage sessions
|
|
15
14
|
config Manage configuration
|
|
16
15
|
keys Manage API keys in secure storage
|
|
@@ -28,9 +27,8 @@ Commands:
|
|
|
28
27
|
completions <shell> Generate shell completion script (e.g. assistant completions bash >> ~/.bashrc)
|
|
29
28
|
notifications [options] Send and inspect notifications through the unified notification router
|
|
30
29
|
platform [options] Manage platform integration for containerized deployments
|
|
31
|
-
oauth [options] Manage OAuth
|
|
30
|
+
oauth [options] Manage OAuth providers, apps, connections, and tokens
|
|
32
31
|
skills Browse and install skills from the Vellum catalog
|
|
33
32
|
browser Browser automation, extension relay, and Chrome CDP management
|
|
34
|
-
map [options] <domain> Auto-navigate a domain and produce a deduplicated API map. Launches Chrome with CDP, starts a Ride Shotgun learn session, then analyzes captured network traffic.
|
|
35
33
|
sequence [options] Manage email sequences
|
|
36
34
|
`;
|
|
@@ -42,10 +42,7 @@ function loadDefaultsRegistry(): FeatureFlagDefaultsRegistry {
|
|
|
42
42
|
if (cachedDefaults) return cachedDefaults;
|
|
43
43
|
|
|
44
44
|
const thisDir = import.meta.dirname ?? __dirname;
|
|
45
|
-
const envPath = process.env.FEATURE_FLAG_DEFAULTS_PATH?.trim();
|
|
46
45
|
const candidates = [
|
|
47
|
-
// Explicit override (primarily for tests / controlled environments)
|
|
48
|
-
...(envPath ? [envPath] : []),
|
|
49
46
|
// Bundled: co-located copy in the same directory as this source file.
|
|
50
47
|
// Works in Docker / packaged builds where the repo-root `meta/` dir
|
|
51
48
|
// is not available.
|
|
@@ -6,7 +6,7 @@ For account and auth workflows, prefer documented `assistant` CLI commands over
|
|
|
6
6
|
any generic account registry:
|
|
7
7
|
|
|
8
8
|
- `assistant credentials ...` for stored secrets and credential metadata
|
|
9
|
-
- `assistant oauth token <
|
|
9
|
+
- `assistant oauth connections token <provider-key>` for OAuth-backed integrations
|
|
10
10
|
- `assistant mcp auth <name>` when an MCP server needs browser login
|
|
11
11
|
- `assistant platform status` for platform-linked deployment/auth context
|
|
12
12
|
|
|
@@ -10,13 +10,10 @@ metadata:
|
|
|
10
10
|
disable-model-invocation: true
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
This skill provides the
|
|
14
|
-
the macOS desktop
|
|
13
|
+
This skill provides the computer_use_* action tools for controlling
|
|
14
|
+
the macOS desktop. CU tools run through the main agent loop via HostCuProxy.
|
|
15
15
|
|
|
16
|
-
The
|
|
17
|
-
registry (not this skill) so text_qa sessions can execute it directly.
|
|
18
|
-
|
|
19
|
-
The skill is internally preactivated for computer-use sessions.
|
|
16
|
+
The skill is internally preactivated for sessions with a connected desktop client.
|
|
20
17
|
|
|
21
18
|
Tools in this skill are proxy tools — execution is forwarded to the connected
|
|
22
19
|
macOS client, never handled locally by the assistant.
|
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"tools": [
|
|
4
|
+
{
|
|
5
|
+
"name": "computer_use_observe",
|
|
6
|
+
"description": "Capture the current screen state. Returns the accessibility tree with [ID] element references and optionally a screenshot.\n\nThe accessibility tree shows interactive elements like [3] AXButton 'Save' or [17] AXTextField 'Search'. Use element_id to target these elements in subsequent actions — this is much more reliable than pixel coordinates.\n\nCall this before your first computer use action, or to check screen state without acting.",
|
|
7
|
+
"category": "computer-use",
|
|
8
|
+
"risk": "low",
|
|
9
|
+
"input_schema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"reason": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Brief non-technical explanation of why this tool is being called"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["reason"]
|
|
18
|
+
},
|
|
19
|
+
"executor": "tools/computer-use-observe.ts",
|
|
20
|
+
"execution_target": "host"
|
|
21
|
+
},
|
|
4
22
|
{
|
|
5
23
|
"name": "computer_use_click",
|
|
6
|
-
"description": "Click
|
|
24
|
+
"description": "Click an element on screen. Prefer element_id (from the accessibility tree) over x/y coordinates.",
|
|
7
25
|
"category": "computer-use",
|
|
8
26
|
"risk": "low",
|
|
9
27
|
"input_schema": {
|
|
@@ -42,7 +60,7 @@
|
|
|
42
60
|
},
|
|
43
61
|
{
|
|
44
62
|
"name": "computer_use_type_text",
|
|
45
|
-
"description": "Type text at the current cursor position.
|
|
63
|
+
"description": "Type text at the current cursor position. First click a text field (by element_id) to focus it, then call this tool. If a field shows 'FOCUSED', skip the click.",
|
|
46
64
|
"category": "computer-use",
|
|
47
65
|
"risk": "low",
|
|
48
66
|
"input_schema": {
|
|
@@ -235,7 +253,7 @@
|
|
|
235
253
|
},
|
|
236
254
|
{
|
|
237
255
|
"name": "computer_use_run_applescript",
|
|
238
|
-
"description": "
|
|
256
|
+
"description": "Run an AppleScript command. Prefer this over click/type when possible \u2014 it doesn't move the cursor or interrupt the user. Never use 'do shell script' inside AppleScript (blocked for security).",
|
|
239
257
|
"category": "computer-use",
|
|
240
258
|
"risk": "low",
|
|
241
259
|
"input_schema": {
|
|
@@ -261,7 +279,7 @@
|
|
|
261
279
|
},
|
|
262
280
|
{
|
|
263
281
|
"name": "computer_use_done",
|
|
264
|
-
"description": "
|
|
282
|
+
"description": "Signal that the computer use task is complete. Provide a summary of what was accomplished. This ends the computer use session.",
|
|
265
283
|
"category": "computer-use",
|
|
266
284
|
"risk": "low",
|
|
267
285
|
"input_schema": {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { OAuthConnection } from "../../../oauth/connection.js";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const GOOGLE_CALENDAR_BASE_URL = "https://www.googleapis.com/calendar/v3";
|
|
3
4
|
import type {
|
|
4
5
|
CalendarEvent,
|
|
5
6
|
CalendarEventsListResponse,
|
|
@@ -23,6 +24,7 @@ async function request<T>(
|
|
|
23
24
|
connection: OAuthConnection,
|
|
24
25
|
path: string,
|
|
25
26
|
options?: RequestInit,
|
|
27
|
+
query?: Record<string, string | string[]>,
|
|
26
28
|
): Promise<T> {
|
|
27
29
|
const method = (options?.method ?? "GET").toUpperCase();
|
|
28
30
|
|
|
@@ -65,6 +67,7 @@ async function request<T>(
|
|
|
65
67
|
const resp = await connection.request({
|
|
66
68
|
method,
|
|
67
69
|
path,
|
|
70
|
+
query,
|
|
68
71
|
baseUrl: GOOGLE_CALENDAR_BASE_URL,
|
|
69
72
|
headers: {
|
|
70
73
|
"Content-Type": "application/json",
|
|
@@ -106,29 +109,31 @@ export async function listEvents(
|
|
|
106
109
|
syncToken?: string;
|
|
107
110
|
},
|
|
108
111
|
): Promise<CalendarEventsListResponse> {
|
|
109
|
-
const
|
|
112
|
+
const query: Record<string, string> = {};
|
|
110
113
|
|
|
111
|
-
if (options?.timeMin)
|
|
112
|
-
if (options?.timeMax)
|
|
113
|
-
|
|
114
|
-
if (options?.query)
|
|
114
|
+
if (options?.timeMin) query.timeMin = options.timeMin;
|
|
115
|
+
if (options?.timeMax) query.timeMax = options.timeMax;
|
|
116
|
+
query.maxResults = String(options?.maxResults ?? 25);
|
|
117
|
+
if (options?.query) query.q = options.query;
|
|
115
118
|
|
|
116
119
|
// Default to expanding recurring events into instances
|
|
117
120
|
const singleEvents = options?.singleEvents ?? true;
|
|
118
|
-
|
|
121
|
+
query.singleEvents = String(singleEvents);
|
|
119
122
|
|
|
120
123
|
if (singleEvents && options?.orderBy) {
|
|
121
|
-
|
|
124
|
+
query.orderBy = options.orderBy;
|
|
122
125
|
} else if (singleEvents) {
|
|
123
|
-
|
|
126
|
+
query.orderBy = "startTime";
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
if (options?.pageToken)
|
|
127
|
-
if (options?.syncToken)
|
|
129
|
+
if (options?.pageToken) query.pageToken = options.pageToken;
|
|
130
|
+
if (options?.syncToken) query.syncToken = options.syncToken;
|
|
128
131
|
|
|
129
132
|
return request<CalendarEventsListResponse>(
|
|
130
133
|
connection,
|
|
131
|
-
`/calendars/${encodeURIComponent(calendarId)}/events
|
|
134
|
+
`/calendars/${encodeURIComponent(calendarId)}/events`,
|
|
135
|
+
undefined,
|
|
136
|
+
query,
|
|
132
137
|
);
|
|
133
138
|
}
|
|
134
139
|
|
|
@@ -160,14 +165,14 @@ export async function createEvent(
|
|
|
160
165
|
calendarId = "primary",
|
|
161
166
|
sendUpdates: "all" | "externalOnly" | "none" = "all",
|
|
162
167
|
): Promise<CalendarEvent> {
|
|
163
|
-
const params = new URLSearchParams({ sendUpdates });
|
|
164
168
|
return request<CalendarEvent>(
|
|
165
169
|
connection,
|
|
166
|
-
`/calendars/${encodeURIComponent(calendarId)}/events
|
|
170
|
+
`/calendars/${encodeURIComponent(calendarId)}/events`,
|
|
167
171
|
{
|
|
168
172
|
method: "POST",
|
|
169
173
|
body: JSON.stringify(event),
|
|
170
174
|
},
|
|
175
|
+
{ sendUpdates },
|
|
171
176
|
);
|
|
172
177
|
}
|
|
173
178
|
|
|
@@ -186,16 +191,16 @@ export async function patchEvent(
|
|
|
186
191
|
calendarId = "primary",
|
|
187
192
|
sendUpdates: "all" | "externalOnly" | "none" = "all",
|
|
188
193
|
): Promise<CalendarEvent> {
|
|
189
|
-
const params = new URLSearchParams({ sendUpdates });
|
|
190
194
|
return request<CalendarEvent>(
|
|
191
195
|
connection,
|
|
192
196
|
`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(
|
|
193
197
|
eventId,
|
|
194
|
-
)}
|
|
198
|
+
)}`,
|
|
195
199
|
{
|
|
196
200
|
method: "PATCH",
|
|
197
201
|
body: JSON.stringify(updates),
|
|
198
202
|
},
|
|
203
|
+
{ sendUpdates },
|
|
199
204
|
);
|
|
200
205
|
}
|
|
201
206
|
|
|
@@ -6,7 +6,6 @@ import type { MessagingProvider } from "../../../../messaging/provider.js";
|
|
|
6
6
|
import {
|
|
7
7
|
getConnectedProviders,
|
|
8
8
|
getMessagingProvider,
|
|
9
|
-
isPlatformEnabled,
|
|
10
9
|
} from "../../../../messaging/registry.js";
|
|
11
10
|
import type { OAuthConnection } from "../../../../oauth/connection.js";
|
|
12
11
|
import { resolveOAuthConnection } from "../../../../oauth/connection-resolver.js";
|
|
@@ -110,9 +109,7 @@ export function extractEmail(address: string): string {
|
|
|
110
109
|
export function resolveProvider(platformInput?: string): MessagingProvider {
|
|
111
110
|
if (platformInput) return getMessagingProvider(platformInput);
|
|
112
111
|
|
|
113
|
-
const connected = getConnectedProviders()
|
|
114
|
-
isPlatformEnabled(p.id),
|
|
115
|
-
);
|
|
112
|
+
const connected = getConnectedProviders();
|
|
116
113
|
if (connected.length === 1) return connected[0];
|
|
117
114
|
if (connected.length === 0) {
|
|
118
115
|
throw new Error(
|
|
@@ -9,4 +9,4 @@ metadata:
|
|
|
9
9
|
user-invocable: true
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key,
|
|
12
|
+
Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key, conversation timeout), avatar generation, system settings navigation, and in-app settings tab navigation.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "voice_config_update",
|
|
6
|
-
"description": "Update a voice configuration setting (TTS voice ID, PTT activation key,
|
|
6
|
+
"description": "Update a voice configuration setting (TTS voice ID, PTT activation key, conversation timeout). Changes take effect immediately.",
|
|
7
7
|
"category": "system",
|
|
8
8
|
"risk": "low",
|
|
9
9
|
"input_schema": {
|
|
@@ -11,13 +11,7 @@
|
|
|
11
11
|
"properties": {
|
|
12
12
|
"setting": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"enum": [
|
|
15
|
-
"activation_key",
|
|
16
|
-
"wake_word_enabled",
|
|
17
|
-
"wake_word_keyword",
|
|
18
|
-
"wake_word_timeout",
|
|
19
|
-
"tts_voice_id"
|
|
20
|
-
],
|
|
14
|
+
"enum": ["activation_key", "conversation_timeout", "tts_voice_id"],
|
|
21
15
|
"description": "The voice setting to change"
|
|
22
16
|
},
|
|
23
17
|
"value": {
|