@vellumai/assistant 0.4.45 → 0.4.48
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 +6 -6
- package/docs/architecture/memory.md +1 -1
- package/docs/architecture/scheduling.md +2 -3
- package/docs/architecture/security.md +5 -5
- package/docs/trusted-contact-access.md +5 -6
- package/package.json +4 -1
- package/src/__tests__/avatar-e2e.test.ts +18 -219
- package/src/__tests__/avatar-generator.test.ts +5 -57
- package/src/__tests__/browser-fill-credential.test.ts +5 -2
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
- package/src/__tests__/channel-readiness-routes.test.ts +20 -19
- package/src/__tests__/cli.test.ts +23 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
- package/src/__tests__/credential-broker-server-use.test.ts +22 -21
- package/src/__tests__/credential-broker.test.ts +2 -1
- package/src/__tests__/credential-metadata-store.test.ts +240 -18
- package/src/__tests__/credential-resolve.test.ts +5 -4
- package/src/__tests__/credential-security-e2e.test.ts +8 -8
- package/src/__tests__/credential-security-invariants.test.ts +104 -7
- package/src/__tests__/credential-vault-unit.test.ts +22 -20
- package/src/__tests__/credential-vault.test.ts +284 -12
- package/src/__tests__/credentials-cli.test.ts +11 -6
- package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
- package/src/__tests__/gemini-image-service.test.ts +75 -45
- package/src/__tests__/gemini-provider.test.ts +9 -6
- package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
- package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
- package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +35 -0
- package/src/__tests__/integration-status.test.ts +53 -21
- package/src/__tests__/managed-proxy-context.test.ts +5 -3
- package/src/__tests__/media-generate-image.test.ts +63 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
- package/src/__tests__/messaging-send-tool.test.ts +4 -6
- package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/schema-transforms.test.ts +226 -0
- package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
- package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +5 -3
- package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +0 -9
- package/src/__tests__/slack-channel-config.test.ts +9 -8
- package/src/__tests__/slack-share-routes.test.ts +11 -6
- package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
- package/src/__tests__/twilio-config.test.ts +2 -1
- package/src/__tests__/twilio-provider.test.ts +4 -2
- package/src/__tests__/twilio-routes.test.ts +5 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
- package/src/approvals/AGENTS.md +1 -1
- package/src/calls/call-domain.ts +7 -4
- package/src/calls/twilio-config.ts +2 -1
- package/src/calls/twilio-provider.ts +2 -1
- package/src/calls/twilio-rest.ts +2 -2
- package/src/cli/commands/browser-relay.ts +40 -15
- package/src/cli/commands/credentials.ts +9 -8
- package/src/cli/commands/oauth.ts +1 -1
- package/src/cli.ts +3 -2
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
- package/src/config/bundled-skills/gmail/SKILL.md +4 -4
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
- package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +70 -29
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
- package/src/config/bundled-skills/messaging/SKILL.md +6 -6
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
- package/src/config/bundled-skills/messaging/tools/shared.ts +11 -11
- package/src/config/bundled-skills/notifications/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +5 -5
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
- package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
- package/src/config/loader.ts +6 -0
- package/src/daemon/computer-use-session.ts +7 -1
- package/src/daemon/guardian-action-generators.ts +4 -5
- package/src/daemon/handlers/config-slack-channel.ts +37 -20
- package/src/daemon/handlers/config-telegram.ts +33 -20
- package/src/daemon/lifecycle.ts +9 -1
- package/src/daemon/message-types/integrations.ts +1 -0
- package/src/daemon/ride-shotgun-handler.ts +3 -1
- package/src/daemon/session-messaging.ts +3 -1
- package/src/daemon/session-tool-setup.ts +18 -2
- package/src/daemon/session.ts +1 -1
- package/src/email/providers/index.ts +2 -1
- package/src/instrument.ts +15 -1
- package/src/media/app-icon-generator.ts +30 -4
- package/src/media/avatar-router.ts +28 -62
- package/src/media/gemini-image-service.ts +28 -2
- package/src/memory/canonical-guardian-store.ts +1 -1
- package/src/memory/guardian-action-store.ts +1 -1
- package/src/memory/schema/guardian.ts +1 -1
- package/src/messaging/provider.ts +16 -10
- package/src/messaging/providers/gmail/adapter.ts +40 -23
- package/src/messaging/providers/gmail/client.ts +203 -122
- package/src/messaging/providers/gmail/people-client.ts +26 -18
- package/src/messaging/providers/slack/adapter.ts +29 -19
- package/src/messaging/providers/slack/client.ts +265 -78
- package/src/messaging/providers/telegram-bot/adapter.ts +5 -4
- package/src/messaging/providers/whatsapp/adapter.ts +6 -3
- package/src/messaging/registry.ts +2 -1
- package/src/oauth/byo-connection.test.ts +436 -0
- package/src/oauth/byo-connection.ts +112 -0
- package/src/oauth/connect-orchestrator.ts +27 -0
- package/src/oauth/connection-resolver.ts +34 -0
- package/src/oauth/connection.ts +38 -0
- package/src/oauth/platform-connection.test.ts +163 -0
- package/src/oauth/platform-connection.ts +110 -0
- package/src/oauth/provider-base-urls.ts +21 -0
- package/src/oauth/provider-profiles.ts +1 -1
- package/src/oauth/token-persistence.ts +20 -20
- package/src/permissions/checker.ts +6 -1
- package/src/prompts/system-prompt.ts +52 -15
- package/src/prompts/templates/BOOTSTRAP.md +1 -1
- package/src/providers/gemini/client.ts +15 -6
- package/src/providers/managed-proxy/constants.ts +2 -2
- package/src/providers/managed-proxy/context.ts +5 -1
- package/src/providers/ratelimit.ts +17 -0
- package/src/providers/registry.ts +2 -2
- package/src/runtime/AGENTS.md +18 -1
- package/src/runtime/auth/route-policy.ts +1 -0
- package/src/runtime/channel-invite-transports/telegram.ts +2 -1
- package/src/runtime/channel-readiness-service.ts +168 -195
- package/src/runtime/channel-readiness-types.ts +4 -0
- package/src/runtime/guardian-action-conversation-turn.ts +1 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -2
- package/src/runtime/guardian-action-message-composer.ts +3 -23
- package/src/runtime/http-server.ts +9 -4
- package/src/runtime/http-types.ts +0 -1
- package/src/runtime/middleware/rate-limiter.ts +74 -20
- package/src/runtime/middleware/twilio-validation.ts +1 -3
- package/src/runtime/routes/channel-readiness-routes.ts +2 -0
- package/src/runtime/routes/diagnostics-routes.ts +11 -9
- package/src/runtime/routes/guardian-approval-interception.ts +20 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +71 -25
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +12 -5
- package/src/runtime/routes/integrations/slack/share.ts +3 -2
- package/src/runtime/routes/integrations/twilio.ts +6 -5
- package/src/runtime/routes/secret-routes.ts +3 -2
- package/src/runtime/routes/settings-routes.ts +75 -17
- package/src/runtime/telegram-streaming-delivery.test.ts +132 -0
- package/src/runtime/telegram-streaming-delivery.ts +11 -1
- package/src/schedule/integration-status.ts +5 -4
- package/src/security/credential-key.ts +170 -0
- package/src/security/token-manager.ts +36 -7
- package/src/tools/apps/definitions.ts +0 -5
- package/src/tools/assets/materialize.ts +0 -5
- package/src/tools/assets/search.ts +0 -5
- package/src/tools/browser/headless-browser.ts +1 -67
- package/src/tools/claude-code/claude-code.ts +0 -5
- package/src/tools/computer-use/request-computer-control.ts +0 -5
- package/src/tools/credentials/broker.ts +6 -4
- package/src/tools/credentials/metadata-store.ts +72 -20
- package/src/tools/credentials/resolve.ts +2 -1
- package/src/tools/credentials/vault.ts +77 -16
- package/src/tools/filesystem/edit.ts +1 -6
- package/src/tools/filesystem/read.ts +0 -5
- package/src/tools/filesystem/write.ts +1 -6
- package/src/tools/host-filesystem/edit.ts +1 -6
- package/src/tools/host-filesystem/read.ts +1 -6
- package/src/tools/host-filesystem/write.ts +1 -6
- package/src/tools/mcp/mcp-tool-factory.ts +18 -1
- package/src/tools/memory/definitions.ts +0 -5
- package/src/tools/network/web-fetch.ts +0 -5
- package/src/tools/network/web-search.ts +0 -5
- package/src/tools/schema-transforms.ts +99 -0
- package/src/tools/skills/load.ts +0 -5
- package/src/tools/swarm/delegate.ts +0 -5
- package/src/tools/system/avatar-generator.ts +3 -44
- package/src/tools/ui-surface/definitions.ts +0 -15
- package/src/tools/watch/screen-watch.ts +0 -5
- package/src/version.ts +10 -0
- package/src/watcher/providers/github.ts +51 -52
- package/src/watcher/providers/gmail.ts +88 -80
- package/src/watcher/providers/google-calendar.ts +93 -86
- package/src/watcher/providers/linear.ts +87 -93
- package/src/__tests__/avatar-router.test.ts +0 -149
- package/src/__tests__/managed-avatar-client.test.ts +0 -337
- package/src/config/bundled-skills/doordash/SKILL.md +0 -170
- package/src/config/bundled-skills/doordash/__tests__/doordash-client.test.ts +0 -205
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +0 -74
- package/src/config/bundled-skills/doordash/doordash-cli.ts +0 -1081
- package/src/config/bundled-skills/doordash/doordash-entry.ts +0 -22
- package/src/config/bundled-skills/doordash/lib/cart-queries.ts +0 -787
- package/src/config/bundled-skills/doordash/lib/client.ts +0 -1069
- package/src/config/bundled-skills/doordash/lib/order-queries.ts +0 -85
- package/src/config/bundled-skills/doordash/lib/queries.ts +0 -28
- package/src/config/bundled-skills/doordash/lib/query-extractor.ts +0 -94
- package/src/config/bundled-skills/doordash/lib/search-queries.ts +0 -203
- package/src/config/bundled-skills/doordash/lib/session.ts +0 -96
- package/src/config/bundled-skills/doordash/lib/shared/errors.ts +0 -61
- package/src/config/bundled-skills/doordash/lib/shared/network-recorder.ts +0 -380
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +0 -55
- package/src/config/bundled-skills/doordash/lib/shared/recording-store.ts +0 -43
- package/src/config/bundled-skills/doordash/lib/shared/recording-types.ts +0 -49
- package/src/config/bundled-skills/doordash/lib/shared/truncate.ts +0 -6
- package/src/config/bundled-skills/doordash/lib/store-queries.ts +0 -246
- package/src/config/bundled-skills/doordash/lib/types.ts +0 -367
- package/src/media/avatar-types.ts +0 -53
- package/src/media/managed-avatar-client.ts +0 -225
|
@@ -44,11 +44,6 @@ class BrowserNavigateTool implements Tool {
|
|
|
44
44
|
description:
|
|
45
45
|
"If true, allows navigation to localhost/private-network hosts. Disabled by default for SSRF safety.",
|
|
46
46
|
},
|
|
47
|
-
reason: {
|
|
48
|
-
type: "string",
|
|
49
|
-
description:
|
|
50
|
-
"Brief non-technical explanation of what you are navigating to and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
51
|
-
},
|
|
52
47
|
},
|
|
53
48
|
required: ["url"],
|
|
54
49
|
},
|
|
@@ -80,13 +75,7 @@ class BrowserSnapshotTool implements Tool {
|
|
|
80
75
|
description: this.description,
|
|
81
76
|
input_schema: {
|
|
82
77
|
type: "object",
|
|
83
|
-
properties: {
|
|
84
|
-
reason: {
|
|
85
|
-
type: "string",
|
|
86
|
-
description:
|
|
87
|
-
"Brief non-technical explanation of what you are inspecting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
88
|
-
},
|
|
89
|
-
},
|
|
78
|
+
properties: {},
|
|
90
79
|
},
|
|
91
80
|
};
|
|
92
81
|
}
|
|
@@ -122,11 +111,6 @@ class BrowserScreenshotTool implements Tool {
|
|
|
122
111
|
description:
|
|
123
112
|
"Capture the full scrollable page instead of just the viewport.",
|
|
124
113
|
},
|
|
125
|
-
reason: {
|
|
126
|
-
type: "string",
|
|
127
|
-
description:
|
|
128
|
-
"Brief non-technical explanation of what you are capturing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
129
|
-
},
|
|
130
114
|
},
|
|
131
115
|
},
|
|
132
116
|
};
|
|
@@ -163,11 +147,6 @@ class BrowserCloseTool implements Tool {
|
|
|
163
147
|
description:
|
|
164
148
|
"If true, close all browser pages and the browser context. Default: false (close only the current session page).",
|
|
165
149
|
},
|
|
166
|
-
reason: {
|
|
167
|
-
type: "string",
|
|
168
|
-
description:
|
|
169
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
170
|
-
},
|
|
171
150
|
},
|
|
172
151
|
},
|
|
173
152
|
};
|
|
@@ -214,11 +193,6 @@ class BrowserClickTool implements Tool {
|
|
|
214
193
|
description:
|
|
215
194
|
"Max time in ms to wait for the element to be clickable (default: 10000).",
|
|
216
195
|
},
|
|
217
|
-
reason: {
|
|
218
|
-
type: "string",
|
|
219
|
-
description:
|
|
220
|
-
"Brief non-technical explanation of what you are clicking and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
221
|
-
},
|
|
222
196
|
},
|
|
223
197
|
},
|
|
224
198
|
};
|
|
@@ -273,11 +247,6 @@ class BrowserTypeTool implements Tool {
|
|
|
273
247
|
type: "boolean",
|
|
274
248
|
description: "If true, press Enter after typing the text.",
|
|
275
249
|
},
|
|
276
|
-
reason: {
|
|
277
|
-
type: "string",
|
|
278
|
-
description:
|
|
279
|
-
"Brief non-technical explanation of what you are typing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
280
|
-
},
|
|
281
250
|
},
|
|
282
251
|
required: ["text"],
|
|
283
252
|
},
|
|
@@ -323,11 +292,6 @@ class BrowserPressKeyTool implements Tool {
|
|
|
323
292
|
type: "string",
|
|
324
293
|
description: "Optional CSS selector to target.",
|
|
325
294
|
},
|
|
326
|
-
reason: {
|
|
327
|
-
type: "string",
|
|
328
|
-
description:
|
|
329
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
330
|
-
},
|
|
331
295
|
},
|
|
332
296
|
required: ["key"],
|
|
333
297
|
},
|
|
@@ -378,11 +342,6 @@ class BrowserScrollTool implements Tool {
|
|
|
378
342
|
type: "string",
|
|
379
343
|
description: "Optional CSS selector of element to scroll within.",
|
|
380
344
|
},
|
|
381
|
-
reason: {
|
|
382
|
-
type: "string",
|
|
383
|
-
description:
|
|
384
|
-
"Brief non-technical explanation of what you are scrolling to see and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
385
|
-
},
|
|
386
345
|
},
|
|
387
346
|
required: ["direction"],
|
|
388
347
|
},
|
|
@@ -437,11 +396,6 @@ class BrowserSelectOptionTool implements Tool {
|
|
|
437
396
|
type: "number",
|
|
438
397
|
description: "The zero-based index of the <option> to select.",
|
|
439
398
|
},
|
|
440
|
-
reason: {
|
|
441
|
-
type: "string",
|
|
442
|
-
description:
|
|
443
|
-
"Brief non-technical explanation of what you are selecting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
444
|
-
},
|
|
445
399
|
},
|
|
446
400
|
},
|
|
447
401
|
};
|
|
@@ -483,11 +437,6 @@ class BrowserHoverTool implements Tool {
|
|
|
483
437
|
description:
|
|
484
438
|
"A CSS selector to target. Used as fallback when element_id is not available.",
|
|
485
439
|
},
|
|
486
|
-
reason: {
|
|
487
|
-
type: "string",
|
|
488
|
-
description:
|
|
489
|
-
"Brief non-technical explanation of what you are hovering over and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
490
|
-
},
|
|
491
440
|
},
|
|
492
441
|
},
|
|
493
442
|
};
|
|
@@ -537,11 +486,6 @@ class BrowserWaitForTool implements Tool {
|
|
|
537
486
|
description:
|
|
538
487
|
"Maximum wait time in milliseconds (default and max: 30000).",
|
|
539
488
|
},
|
|
540
|
-
reason: {
|
|
541
|
-
type: "string",
|
|
542
|
-
description:
|
|
543
|
-
"Brief non-technical explanation of what you are waiting for and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
544
|
-
},
|
|
545
489
|
},
|
|
546
490
|
},
|
|
547
491
|
};
|
|
@@ -578,11 +522,6 @@ class BrowserExtractTool implements Tool {
|
|
|
578
522
|
description:
|
|
579
523
|
"If true, include a list of links found on the page (up to 200).",
|
|
580
524
|
},
|
|
581
|
-
reason: {
|
|
582
|
-
type: "string",
|
|
583
|
-
description:
|
|
584
|
-
"Brief non-technical explanation of what you are extracting and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
585
|
-
},
|
|
586
525
|
},
|
|
587
526
|
},
|
|
588
527
|
};
|
|
@@ -634,11 +573,6 @@ class BrowserFillCredentialTool implements Tool {
|
|
|
634
573
|
type: "boolean",
|
|
635
574
|
description: "Press Enter after filling",
|
|
636
575
|
},
|
|
637
|
-
reason: {
|
|
638
|
-
type: "string",
|
|
639
|
-
description:
|
|
640
|
-
"Brief non-technical explanation of what you are filling in and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
641
|
-
},
|
|
642
576
|
},
|
|
643
577
|
required: ["service", "field"],
|
|
644
578
|
},
|
|
@@ -123,11 +123,6 @@ export const claudeCodeTool: Tool = {
|
|
|
123
123
|
description:
|
|
124
124
|
"Worker profile that scopes tool access. Defaults to general (backward compatible).",
|
|
125
125
|
},
|
|
126
|
-
reason: {
|
|
127
|
-
type: "string",
|
|
128
|
-
description:
|
|
129
|
-
"Brief non-technical explanation of what you are delegating and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
130
|
-
},
|
|
131
126
|
},
|
|
132
127
|
},
|
|
133
128
|
};
|
|
@@ -42,11 +42,6 @@ export const requestComputerControlTool: Tool = {
|
|
|
42
42
|
description:
|
|
43
43
|
"Concise description of what computer use should accomplish",
|
|
44
44
|
},
|
|
45
|
-
reason: {
|
|
46
|
-
type: "string",
|
|
47
|
-
description:
|
|
48
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
49
|
-
},
|
|
50
45
|
},
|
|
51
46
|
required: ["task"],
|
|
52
47
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
+
import { credentialKey, migrateKeys } from "../../security/credential-key.js";
|
|
3
4
|
import { getSecureKey } from "../../security/secure-keys.js";
|
|
4
5
|
import { getLogger } from "../../util/logger.js";
|
|
5
6
|
import type {
|
|
@@ -46,7 +47,7 @@ export class CredentialBroker {
|
|
|
46
47
|
* browserFill or consume call for this service/field pair, then discarded.
|
|
47
48
|
*/
|
|
48
49
|
injectTransient(service: string, field: string, value: string): void {
|
|
49
|
-
const key =
|
|
50
|
+
const key = credentialKey(service, field);
|
|
50
51
|
this.transientValues.set(key, { value });
|
|
51
52
|
log.info(
|
|
52
53
|
{ service, field },
|
|
@@ -59,6 +60,7 @@ export class CredentialBroker {
|
|
|
59
60
|
* Returns a single-use token on success, or a denial reason on failure.
|
|
60
61
|
*/
|
|
61
62
|
authorize(request: AuthorizeRequest): AuthorizeResult {
|
|
63
|
+
migrateKeys();
|
|
62
64
|
const metadata = getCredentialMetadata(request.service, request.field);
|
|
63
65
|
if (!metadata) {
|
|
64
66
|
return {
|
|
@@ -123,7 +125,7 @@ export class CredentialBroker {
|
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
token.consumed = true;
|
|
126
|
-
const storageKey =
|
|
128
|
+
const storageKey = credentialKey(token.service, token.field);
|
|
127
129
|
// Check for transient value first (one-time send) — consume and return the value
|
|
128
130
|
// directly since transient values are never persisted to secure storage.
|
|
129
131
|
const transient = this.transientValues.get(storageKey);
|
|
@@ -211,7 +213,7 @@ export class CredentialBroker {
|
|
|
211
213
|
}
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
const storageKey =
|
|
216
|
+
const storageKey = credentialKey(request.service, request.field);
|
|
215
217
|
// Check transient values first (one-time send), then fall back to keychain.
|
|
216
218
|
// Deletion is deferred until after a successful fill so the value survives
|
|
217
219
|
// transient failures (e.g. stale element, page navigation, Playwright timeout).
|
|
@@ -299,7 +301,7 @@ export class CredentialBroker {
|
|
|
299
301
|
};
|
|
300
302
|
}
|
|
301
303
|
|
|
302
|
-
const storageKey =
|
|
304
|
+
const storageKey = credentialKey(request.service, request.field);
|
|
303
305
|
const transient = this.transientValues.get(storageKey);
|
|
304
306
|
const value = transient?.value ?? getSecureKey(storageKey);
|
|
305
307
|
if (!value) {
|
|
@@ -27,20 +27,20 @@ export interface CredentialMetadata {
|
|
|
27
27
|
oauth2TokenUrl?: string;
|
|
28
28
|
/** OAuth2 client ID — paired with oauth2TokenUrl for refresh. */
|
|
29
29
|
oauth2ClientId?: string;
|
|
30
|
-
/** OAuth2 client secret — for providers that require it (e.g. Slack). Stored in metadata for autonomous refresh. */
|
|
31
|
-
oauth2ClientSecret?: string;
|
|
32
30
|
/** How the client authenticates at the token endpoint (client_secret_basic or client_secret_post). */
|
|
33
31
|
oauth2TokenEndpointAuthMethod?: string;
|
|
34
32
|
/** Human-friendly name for this credential (e.g. "fal-primary"). */
|
|
35
33
|
alias?: string;
|
|
36
34
|
/** Templates describing how to inject this credential into proxied requests. */
|
|
37
35
|
injectionTemplates?: CredentialInjectionTemplate[];
|
|
36
|
+
/** Whether a refresh token exists in the secure store for this service. */
|
|
37
|
+
hasRefreshToken?: boolean;
|
|
38
38
|
createdAt: number;
|
|
39
39
|
updatedAt: number;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/** Current on-disk schema version. */
|
|
43
|
-
const CURRENT_VERSION =
|
|
43
|
+
const CURRENT_VERSION = 4;
|
|
44
44
|
|
|
45
45
|
interface MetadataFile {
|
|
46
46
|
version: typeof CURRENT_VERSION;
|
|
@@ -120,10 +120,6 @@ function migrateRecordV1toV2(
|
|
|
120
120
|
typeof record.oauth2ClientId === "string"
|
|
121
121
|
? record.oauth2ClientId
|
|
122
122
|
: undefined,
|
|
123
|
-
oauth2ClientSecret:
|
|
124
|
-
typeof record.oauth2ClientSecret === "string"
|
|
125
|
-
? record.oauth2ClientSecret
|
|
126
|
-
: undefined,
|
|
127
123
|
oauth2TokenEndpointAuthMethod:
|
|
128
124
|
typeof record.oauth2TokenEndpointAuthMethod === "string"
|
|
129
125
|
? record.oauth2TokenEndpointAuthMethod
|
|
@@ -132,11 +128,52 @@ function migrateRecordV1toV2(
|
|
|
132
128
|
injectionTemplates: Array.isArray(record.injectionTemplates)
|
|
133
129
|
? (record.injectionTemplates as CredentialInjectionTemplate[])
|
|
134
130
|
: undefined,
|
|
131
|
+
hasRefreshToken:
|
|
132
|
+
typeof record.hasRefreshToken === "boolean"
|
|
133
|
+
? record.hasRefreshToken
|
|
134
|
+
: undefined,
|
|
135
135
|
createdAt: record.createdAt as number,
|
|
136
136
|
updatedAt: record.updatedAt as number,
|
|
137
137
|
};
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Migrate a v2 record to v3 by stripping the oauth2ClientSecret field.
|
|
142
|
+
* Client secrets are now read exclusively from the secure key store.
|
|
143
|
+
*/
|
|
144
|
+
function migrateRecordV2toV3(record: CredentialMetadata): CredentialMetadata {
|
|
145
|
+
const { oauth2ClientSecret: _removed, ...rest } =
|
|
146
|
+
record as CredentialMetadata & { oauth2ClientSecret?: string };
|
|
147
|
+
return rest;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Migrate v3 credentials to v4:
|
|
152
|
+
* - Delete ghost `refresh_token` metadata records
|
|
153
|
+
* - Set `hasRefreshToken: true` on corresponding `access_token` records
|
|
154
|
+
*/
|
|
155
|
+
function migrateV3toV4(
|
|
156
|
+
credentials: CredentialMetadata[],
|
|
157
|
+
): CredentialMetadata[] {
|
|
158
|
+
// Collect services that had refresh_token ghost records
|
|
159
|
+
const servicesWithRefresh = new Set<string>();
|
|
160
|
+
for (const c of credentials) {
|
|
161
|
+
if (c.field === "refresh_token") {
|
|
162
|
+
servicesWithRefresh.add(c.service);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Remove all refresh_token records and set hasRefreshToken on access_token records
|
|
167
|
+
const filtered = credentials.filter((c) => c.field !== "refresh_token");
|
|
168
|
+
for (const c of filtered) {
|
|
169
|
+
if (c.field === "access_token" && servicesWithRefresh.has(c.service)) {
|
|
170
|
+
c.hasRefreshToken = true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return filtered;
|
|
175
|
+
}
|
|
176
|
+
|
|
140
177
|
function loadFile(): LoadResult {
|
|
141
178
|
const raw = readTextFileSync(getMetadataPath());
|
|
142
179
|
if (raw == null) {
|
|
@@ -148,7 +185,12 @@ function loadFile(): LoadResult {
|
|
|
148
185
|
return { version: CURRENT_VERSION, credentials: [] };
|
|
149
186
|
}
|
|
150
187
|
const fileVersion = typeof data.version === "number" ? data.version : 1;
|
|
151
|
-
if (
|
|
188
|
+
if (
|
|
189
|
+
fileVersion !== 1 &&
|
|
190
|
+
fileVersion !== 2 &&
|
|
191
|
+
fileVersion !== 3 &&
|
|
192
|
+
fileVersion !== 4
|
|
193
|
+
) {
|
|
152
194
|
// Unrecognized version (future, fractional, negative, zero) — refuse to touch it
|
|
153
195
|
return { unknownVersion: true };
|
|
154
196
|
}
|
|
@@ -159,8 +201,24 @@ function loadFile(): LoadResult {
|
|
|
159
201
|
const validRecords = rawCredentials.filter(isValidCredentialRecord);
|
|
160
202
|
|
|
161
203
|
if (fileVersion < CURRENT_VERSION) {
|
|
162
|
-
//
|
|
163
|
-
|
|
204
|
+
// Apply migrations in sequence: v1→v2→v3→v4
|
|
205
|
+
let credentials: CredentialMetadata[];
|
|
206
|
+
if (fileVersion === 1) {
|
|
207
|
+
credentials = migrateV3toV4(
|
|
208
|
+
validRecords.map(migrateRecordV1toV2).map(migrateRecordV2toV3),
|
|
209
|
+
);
|
|
210
|
+
} else if (fileVersion === 2) {
|
|
211
|
+
credentials = migrateV3toV4(
|
|
212
|
+
(validRecords as unknown as CredentialMetadata[]).map(
|
|
213
|
+
migrateRecordV2toV3,
|
|
214
|
+
),
|
|
215
|
+
);
|
|
216
|
+
} else {
|
|
217
|
+
// fileVersion === 3
|
|
218
|
+
credentials = migrateV3toV4(
|
|
219
|
+
validRecords as unknown as CredentialMetadata[],
|
|
220
|
+
);
|
|
221
|
+
}
|
|
164
222
|
const migrated: MetadataFile = { version: CURRENT_VERSION, credentials };
|
|
165
223
|
try {
|
|
166
224
|
saveFile(migrated);
|
|
@@ -219,13 +277,12 @@ export function upsertCredentialMetadata(
|
|
|
219
277
|
grantedScopes?: string[];
|
|
220
278
|
oauth2TokenUrl?: string;
|
|
221
279
|
oauth2ClientId?: string;
|
|
222
|
-
/** Pass `null` to explicitly clear a previously-set client secret. */
|
|
223
|
-
oauth2ClientSecret?: string | null;
|
|
224
280
|
oauth2TokenEndpointAuthMethod?: string;
|
|
225
281
|
/** Pass `null` to explicitly clear a previously-set alias. */
|
|
226
282
|
alias?: string | null;
|
|
227
283
|
/** Pass `null` to explicitly clear injection templates. */
|
|
228
284
|
injectionTemplates?: CredentialInjectionTemplate[] | null;
|
|
285
|
+
hasRefreshToken?: boolean;
|
|
229
286
|
},
|
|
230
287
|
): CredentialMetadata {
|
|
231
288
|
const result = loadFile();
|
|
@@ -261,13 +318,6 @@ export function upsertCredentialMetadata(
|
|
|
261
318
|
existing.oauth2TokenUrl = policy.oauth2TokenUrl;
|
|
262
319
|
if (policy?.oauth2ClientId !== undefined)
|
|
263
320
|
existing.oauth2ClientId = policy.oauth2ClientId;
|
|
264
|
-
if (policy?.oauth2ClientSecret !== undefined) {
|
|
265
|
-
if (policy.oauth2ClientSecret == null) {
|
|
266
|
-
delete existing.oauth2ClientSecret;
|
|
267
|
-
} else {
|
|
268
|
-
existing.oauth2ClientSecret = policy.oauth2ClientSecret;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
321
|
if (policy?.oauth2TokenEndpointAuthMethod !== undefined)
|
|
272
322
|
existing.oauth2TokenEndpointAuthMethod =
|
|
273
323
|
policy.oauth2TokenEndpointAuthMethod;
|
|
@@ -285,6 +335,8 @@ export function upsertCredentialMetadata(
|
|
|
285
335
|
existing.injectionTemplates = policy.injectionTemplates;
|
|
286
336
|
}
|
|
287
337
|
}
|
|
338
|
+
if (policy?.hasRefreshToken !== undefined)
|
|
339
|
+
existing.hasRefreshToken = policy.hasRefreshToken;
|
|
288
340
|
existing.updatedAt = now;
|
|
289
341
|
saveFile(data);
|
|
290
342
|
return existing;
|
|
@@ -301,10 +353,10 @@ export function upsertCredentialMetadata(
|
|
|
301
353
|
grantedScopes: policy?.grantedScopes,
|
|
302
354
|
oauth2TokenUrl: policy?.oauth2TokenUrl,
|
|
303
355
|
oauth2ClientId: policy?.oauth2ClientId,
|
|
304
|
-
oauth2ClientSecret: policy?.oauth2ClientSecret ?? undefined,
|
|
305
356
|
oauth2TokenEndpointAuthMethod: policy?.oauth2TokenEndpointAuthMethod,
|
|
306
357
|
alias: policy?.alias ?? undefined,
|
|
307
358
|
injectionTemplates: policy?.injectionTemplates ?? undefined,
|
|
359
|
+
hasRefreshToken: policy?.hasRefreshToken,
|
|
308
360
|
createdAt: now,
|
|
309
361
|
updatedAt: now,
|
|
310
362
|
};
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* secure key naming convention.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
9
10
|
import { matchHostPattern } from "./host-pattern-match.js";
|
|
10
11
|
import {
|
|
11
12
|
type CredentialMetadata,
|
|
@@ -33,7 +34,7 @@ function toResolved(metadata: CredentialMetadata): ResolvedCredential {
|
|
|
33
34
|
credentialId: metadata.credentialId,
|
|
34
35
|
service: metadata.service,
|
|
35
36
|
field: metadata.field,
|
|
36
|
-
storageKey:
|
|
37
|
+
storageKey: credentialKey(metadata.service, metadata.field),
|
|
37
38
|
alias: metadata.alias,
|
|
38
39
|
injectionTemplates: metadata.injectionTemplates ?? [],
|
|
39
40
|
metadata,
|
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
} from "../../oauth/provider-profiles.js";
|
|
8
8
|
import { RiskLevel } from "../../permissions/types.js";
|
|
9
9
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
10
|
+
import { buildAssistantEvent } from "../../runtime/assistant-event.js";
|
|
11
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
12
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../runtime/assistant-scope.js";
|
|
13
|
+
import { credentialKey, migrateKeys } from "../../security/credential-key.js";
|
|
10
14
|
import type { TokenEndpointAuthMethod } from "../../security/oauth2.js";
|
|
11
15
|
import {
|
|
12
16
|
deleteSecureKeyAsync,
|
|
@@ -33,10 +37,10 @@ import { toPolicyFromInput, validatePolicyInput } from "./policy-validate.js";
|
|
|
33
37
|
const log = getLogger("credential-vault");
|
|
34
38
|
|
|
35
39
|
/**
|
|
36
|
-
* Look up a stored OAuth
|
|
37
|
-
* Checks both the canonical and alias service names.
|
|
40
|
+
* Look up a stored OAuth secret (e.g. client_secret) for a service from the
|
|
41
|
+
* secure store. Checks both the canonical and alias service names.
|
|
38
42
|
*/
|
|
39
|
-
function
|
|
43
|
+
function findStoredOAuthSecret(
|
|
40
44
|
service: string,
|
|
41
45
|
field: string,
|
|
42
46
|
): string | undefined {
|
|
@@ -47,7 +51,30 @@ function findStoredOAuthField(
|
|
|
47
51
|
if (alias === service) servicesToCheck.push(canonical);
|
|
48
52
|
}
|
|
49
53
|
for (const svc of servicesToCheck) {
|
|
50
|
-
const value = getSecureKey(
|
|
54
|
+
const value = getSecureKey(credentialKey(svc, field));
|
|
55
|
+
if (value) return value;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Look up the stored OAuth client_id for a service from credential metadata.
|
|
62
|
+
* Checks both the canonical and alias service names.
|
|
63
|
+
*/
|
|
64
|
+
function findStoredOAuthClientId(service: string): string | undefined {
|
|
65
|
+
const servicesToCheck = [service];
|
|
66
|
+
for (const [alias, canonical] of Object.entries(SERVICE_ALIASES)) {
|
|
67
|
+
if (canonical === service) servicesToCheck.push(alias);
|
|
68
|
+
if (alias === service) servicesToCheck.push(canonical);
|
|
69
|
+
}
|
|
70
|
+
// Check metadata first (written by oauth2_connect after successful auth)
|
|
71
|
+
for (const svc of servicesToCheck) {
|
|
72
|
+
const meta = getCredentialMetadata(svc, "access_token");
|
|
73
|
+
if (meta?.oauth2ClientId) return meta.oauth2ClientId;
|
|
74
|
+
}
|
|
75
|
+
// Fall back to secure key store (written by credential_store prompt action)
|
|
76
|
+
for (const svc of servicesToCheck) {
|
|
77
|
+
const value = getSecureKey(credentialKey(svc, "client_id"));
|
|
51
78
|
if (value) return value;
|
|
52
79
|
}
|
|
53
80
|
return undefined;
|
|
@@ -206,11 +233,6 @@ class CredentialStoreTool implements Tool {
|
|
|
206
233
|
description:
|
|
207
234
|
"Templates describing how to inject this credential into proxied requests (for store and prompt actions)",
|
|
208
235
|
},
|
|
209
|
-
reason: {
|
|
210
|
-
type: "string",
|
|
211
|
-
description:
|
|
212
|
-
"Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
213
|
-
},
|
|
214
236
|
},
|
|
215
237
|
required: ["action"],
|
|
216
238
|
},
|
|
@@ -221,6 +243,7 @@ class CredentialStoreTool implements Tool {
|
|
|
221
243
|
input: Record<string, unknown>,
|
|
222
244
|
context: ToolContext,
|
|
223
245
|
): Promise<ToolExecutionResult> {
|
|
246
|
+
migrateKeys();
|
|
224
247
|
const action = input.action as string;
|
|
225
248
|
|
|
226
249
|
switch (action) {
|
|
@@ -359,7 +382,7 @@ class CredentialStoreTool implements Tool {
|
|
|
359
382
|
};
|
|
360
383
|
}
|
|
361
384
|
|
|
362
|
-
const key =
|
|
385
|
+
const key = credentialKey(service, field);
|
|
363
386
|
const ok = await setSecureKeyAsync(key, value);
|
|
364
387
|
if (!ok) {
|
|
365
388
|
return {
|
|
@@ -422,7 +445,7 @@ class CredentialStoreTool implements Tool {
|
|
|
422
445
|
const entries = allMetadata
|
|
423
446
|
.filter((m) => {
|
|
424
447
|
if (secureKeySet)
|
|
425
|
-
return secureKeySet.has(
|
|
448
|
+
return secureKeySet.has(credentialKey(m.service, m.field));
|
|
426
449
|
return true;
|
|
427
450
|
})
|
|
428
451
|
.map((m) => {
|
|
@@ -472,7 +495,7 @@ class CredentialStoreTool implements Tool {
|
|
|
472
495
|
};
|
|
473
496
|
}
|
|
474
497
|
|
|
475
|
-
const key =
|
|
498
|
+
const key = credentialKey(service, field);
|
|
476
499
|
const result = await deleteSecureKeyAsync(key);
|
|
477
500
|
if (result === "error") {
|
|
478
501
|
return {
|
|
@@ -712,7 +735,7 @@ class CredentialStoreTool implements Tool {
|
|
|
712
735
|
}
|
|
713
736
|
|
|
714
737
|
// Default: persist to keychain
|
|
715
|
-
const key =
|
|
738
|
+
const key = credentialKey(service, field);
|
|
716
739
|
const ok = await setSecureKeyAsync(key, result.value);
|
|
717
740
|
if (!ok) {
|
|
718
741
|
return {
|
|
@@ -757,13 +780,13 @@ class CredentialStoreTool implements Tool {
|
|
|
757
780
|
// Fill missing params from provider profile
|
|
758
781
|
const profile = getProviderProfile(service);
|
|
759
782
|
|
|
760
|
-
// Look up client_id
|
|
783
|
+
// Look up client_id from metadata and client_secret from secure store
|
|
761
784
|
const clientId =
|
|
762
785
|
(input.client_id as string | undefined) ??
|
|
763
|
-
|
|
786
|
+
findStoredOAuthClientId(service);
|
|
764
787
|
const clientSecret =
|
|
765
788
|
(input.client_secret as string | undefined) ??
|
|
766
|
-
|
|
789
|
+
findStoredOAuthSecret(service, "client_secret");
|
|
767
790
|
|
|
768
791
|
// Early guardrails that stay in vault.ts (credential resolution is vault-specific)
|
|
769
792
|
const inputScopes = input.scopes as string[] | undefined;
|
|
@@ -867,6 +890,44 @@ class CredentialStoreTool implements Tool {
|
|
|
867
890
|
userinfoUrl:
|
|
868
891
|
(input.userinfo_url as string | undefined) ?? profile?.userinfoUrl,
|
|
869
892
|
tokenEndpointAuthMethod,
|
|
893
|
+
onDeferredComplete: (deferredResult) => {
|
|
894
|
+
// Emit oauth_connect_result to all connected SSE clients so the
|
|
895
|
+
// UI can update immediately when the deferred browser flow completes.
|
|
896
|
+
assistantEventHub
|
|
897
|
+
.publish(
|
|
898
|
+
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
899
|
+
type: "oauth_connect_result",
|
|
900
|
+
success: deferredResult.success,
|
|
901
|
+
service: deferredResult.service,
|
|
902
|
+
accountInfo: deferredResult.accountInfo,
|
|
903
|
+
error: deferredResult.error,
|
|
904
|
+
}),
|
|
905
|
+
)
|
|
906
|
+
.catch((err) => {
|
|
907
|
+
log.warn(
|
|
908
|
+
{ err, service: deferredResult.service },
|
|
909
|
+
"Failed to publish oauth_connect_result event",
|
|
910
|
+
);
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
if (deferredResult.success) {
|
|
914
|
+
log.info(
|
|
915
|
+
{
|
|
916
|
+
service: deferredResult.service,
|
|
917
|
+
accountInfo: deferredResult.accountInfo,
|
|
918
|
+
},
|
|
919
|
+
"Deferred OAuth connect completed successfully",
|
|
920
|
+
);
|
|
921
|
+
} else {
|
|
922
|
+
log.warn(
|
|
923
|
+
{
|
|
924
|
+
service: deferredResult.service,
|
|
925
|
+
err: deferredResult.error,
|
|
926
|
+
},
|
|
927
|
+
"Deferred OAuth connect failed",
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
},
|
|
870
931
|
});
|
|
871
932
|
|
|
872
933
|
if (!result.success) {
|
|
@@ -38,13 +38,8 @@ class FileEditTool implements Tool {
|
|
|
38
38
|
description:
|
|
39
39
|
"Replace all occurrences of old_string instead of requiring a unique match (default: false)",
|
|
40
40
|
},
|
|
41
|
-
reason: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description:
|
|
44
|
-
"Brief non-technical explanation of why this file is being edited, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
45
|
-
},
|
|
46
41
|
},
|
|
47
|
-
required: ["path", "old_string", "new_string"
|
|
42
|
+
required: ["path", "old_string", "new_string"],
|
|
48
43
|
},
|
|
49
44
|
};
|
|
50
45
|
}
|
|
@@ -38,11 +38,6 @@ class FileReadTool implements Tool {
|
|
|
38
38
|
type: "number",
|
|
39
39
|
description: "Maximum number of lines to read",
|
|
40
40
|
},
|
|
41
|
-
reason: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description:
|
|
44
|
-
"Brief non-technical explanation of what you are reading and why, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
45
|
-
},
|
|
46
41
|
},
|
|
47
42
|
required: ["path"],
|
|
48
43
|
},
|
|
@@ -28,13 +28,8 @@ class FileWriteTool implements Tool {
|
|
|
28
28
|
type: "string",
|
|
29
29
|
description: "The content to write to the file",
|
|
30
30
|
},
|
|
31
|
-
reason: {
|
|
32
|
-
type: "string",
|
|
33
|
-
description:
|
|
34
|
-
"Brief non-technical explanation of why this file is being written, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
35
|
-
},
|
|
36
31
|
},
|
|
37
|
-
required: ["path", "content"
|
|
32
|
+
required: ["path", "content"],
|
|
38
33
|
},
|
|
39
34
|
};
|
|
40
35
|
}
|
|
@@ -35,13 +35,8 @@ class HostFileEditTool implements Tool {
|
|
|
35
35
|
description:
|
|
36
36
|
"Replace all occurrences instead of requiring a unique match (default: false)",
|
|
37
37
|
},
|
|
38
|
-
reason: {
|
|
39
|
-
type: "string",
|
|
40
|
-
description:
|
|
41
|
-
"Brief non-technical explanation of why this file is being edited, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
42
|
-
},
|
|
43
38
|
},
|
|
44
|
-
required: ["path", "old_string", "new_string"
|
|
39
|
+
required: ["path", "old_string", "new_string"],
|
|
45
40
|
},
|
|
46
41
|
};
|
|
47
42
|
}
|
|
@@ -29,13 +29,8 @@ class HostFileReadTool implements Tool {
|
|
|
29
29
|
type: "number",
|
|
30
30
|
description: "Maximum number of lines to read",
|
|
31
31
|
},
|
|
32
|
-
reason: {
|
|
33
|
-
type: "string",
|
|
34
|
-
description:
|
|
35
|
-
"Brief non-technical explanation of why this file is being read, shown to the user as a status update. Use simple language a non-technical person would understand.",
|
|
36
|
-
},
|
|
37
32
|
},
|
|
38
|
-
required: ["path"
|
|
33
|
+
required: ["path"],
|
|
39
34
|
},
|
|
40
35
|
};
|
|
41
36
|
}
|