@vellumai/assistant 0.4.11 → 0.4.13
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 +401 -385
- package/package.json +1 -1
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +75 -61
- package/src/__tests__/registry.test.ts +235 -187
- package/src/__tests__/secure-keys.test.ts +27 -0
- package/src/__tests__/session-agent-loop.test.ts +521 -256
- package/src/__tests__/session-surfaces-task-progress.test.ts +1 -0
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/skills.test.ts +334 -276
- package/src/__tests__/slack-skill.test.ts +124 -0
- package/src/__tests__/starter-task-flow.test.ts +7 -17
- package/src/agent/loop.ts +10 -3
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +449 -0
- package/src/config/bundled-skills/doordash/SKILL.md +171 -0
- package/src/config/bundled-skills/doordash/__tests__/doordash-client.test.ts +203 -0
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +164 -0
- package/src/config/bundled-skills/doordash/doordash-cli.ts +1193 -0
- package/src/config/bundled-skills/doordash/doordash-entry.ts +22 -0
- package/src/config/bundled-skills/doordash/lib/cart-queries.ts +787 -0
- package/src/config/bundled-skills/doordash/lib/client.ts +1071 -0
- package/src/config/bundled-skills/doordash/lib/order-queries.ts +85 -0
- package/src/config/bundled-skills/doordash/lib/queries.ts +28 -0
- package/src/config/bundled-skills/doordash/lib/query-extractor.ts +94 -0
- package/src/config/bundled-skills/doordash/lib/search-queries.ts +203 -0
- package/src/config/bundled-skills/doordash/lib/session.ts +93 -0
- package/src/config/bundled-skills/doordash/lib/shared/errors.ts +61 -0
- package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +32 -0
- package/src/config/bundled-skills/doordash/lib/shared/network-recorder.ts +380 -0
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +35 -0
- package/src/config/bundled-skills/doordash/lib/shared/recording-store.ts +43 -0
- package/src/config/bundled-skills/doordash/lib/shared/recording-types.ts +49 -0
- package/src/config/bundled-skills/doordash/lib/shared/truncate.ts +6 -0
- package/src/config/bundled-skills/doordash/lib/store-queries.ts +246 -0
- package/src/config/bundled-skills/doordash/lib/types.ts +367 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +4 -5
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +41 -41
- package/src/config/bundled-skills/messaging/SKILL.md +59 -42
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -92
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +5 -1
- package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +11 -2
- package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +8 -1
- package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +12 -4
- package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +5 -1
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +5 -1
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +5 -2
- package/src/config/bundled-skills/notion/SKILL.md +240 -0
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +127 -0
- package/src/config/bundled-skills/oauth-setup/SKILL.md +144 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +76 -45
- package/src/config/bundled-skills/skills-catalog/SKILL.md +32 -29
- package/src/config/bundled-skills/slack/SKILL.md +49 -0
- package/src/config/bundled-skills/slack/TOOLS.json +167 -0
- package/src/config/bundled-skills/slack/tools/shared.ts +23 -0
- package/src/config/bundled-skills/{messaging → slack}/tools/slack-add-reaction.ts +2 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +33 -0
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +75 -0
- package/src/config/bundled-skills/{messaging → slack}/tools/slack-delete-message.ts +2 -5
- package/src/config/bundled-skills/{messaging → slack}/tools/slack-leave-channel.ts +2 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +193 -0
- package/src/config/{vellum-skills → bundled-skills}/sms-setup/SKILL.md +29 -22
- package/src/config/{vellum-skills → bundled-skills}/telegram-setup/SKILL.md +17 -14
- package/src/config/{vellum-skills → bundled-skills}/twilio-setup/SKILL.md +20 -5
- package/src/config/bundled-tool-registry.ts +292 -267
- package/src/config/schema.ts +1 -1
- package/src/daemon/handlers/skills.ts +334 -234
- package/src/daemon/ipc-contract/messages.ts +2 -0
- package/src/daemon/ipc-contract/surfaces.ts +2 -0
- package/src/daemon/lifecycle.ts +358 -221
- package/src/daemon/response-tier.ts +2 -0
- package/src/daemon/server.ts +453 -193
- package/src/daemon/session-agent-loop-handlers.ts +43 -2
- package/src/daemon/session-agent-loop.ts +3 -0
- package/src/daemon/session-lifecycle.ts +3 -0
- package/src/daemon/session-process.ts +1 -0
- package/src/daemon/session-surfaces.ts +22 -20
- package/src/daemon/session-tool-setup.ts +1 -0
- package/src/daemon/session.ts +5 -2
- package/src/messaging/outreach-classifier.ts +12 -5
- package/src/messaging/provider-types.ts +5 -0
- package/src/messaging/provider.ts +1 -1
- package/src/messaging/providers/gmail/adapter.ts +11 -5
- package/src/messaging/providers/gmail/client.ts +2 -0
- package/src/messaging/providers/slack/adapter.ts +1 -0
- package/src/messaging/providers/slack/client.ts +8 -0
- package/src/messaging/providers/slack/types.ts +5 -0
- package/src/runtime/http-errors.ts +33 -20
- package/src/runtime/http-server.ts +706 -291
- package/src/runtime/http-types.ts +26 -16
- package/src/runtime/routes/secret-routes.ts +57 -2
- package/src/runtime/routes/surface-action-routes.ts +66 -0
- package/src/runtime/routes/trust-rules-routes.ts +140 -0
- package/src/security/keychain-to-encrypted-migration.ts +59 -0
- package/src/security/secure-keys.ts +17 -0
- package/src/skills/frontmatter.ts +9 -7
- package/src/tools/apps/executors.ts +2 -1
- package/src/tools/tool-manifest.ts +44 -42
- package/src/tools/types.ts +9 -0
- package/src/__tests__/skill-mirror-parity.test.ts +0 -176
- package/src/config/vellum-skills/catalog.json +0 -63
- package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +0 -295
- package/src/skills/vellum-catalog-remote.ts +0 -166
- package/src/tools/skills/vellum-catalog.ts +0 -168
- /package/src/config/{vellum-skills → bundled-skills}/chatgpt-import/SKILL.md +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/chatgpt-import/TOOLS.json +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/deploy-fullstack-vercel/SKILL.md +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/document-writer/SKILL.md +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/guardian-verify-setup/SKILL.md +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/slack-oauth-setup/SKILL.md +0 -0
- /package/src/config/{vellum-skills → bundled-skills}/trusted-contacts/SKILL.md +0 -0
package/package.json
CHANGED
|
@@ -5,113 +5,128 @@
|
|
|
5
5
|
* so the user does not have to manually ask whether verification succeeded.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { readFileSync } from
|
|
9
|
-
import { resolve } from
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
10
|
|
|
11
|
-
import { describe, expect, test } from
|
|
11
|
+
import { describe, expect, test } from "bun:test";
|
|
12
12
|
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
// Locate the skill SKILL.md
|
|
15
15
|
// ---------------------------------------------------------------------------
|
|
16
16
|
|
|
17
|
-
const ASSISTANT_DIR = resolve(import.meta.dirname ?? __dirname,
|
|
17
|
+
const ASSISTANT_DIR = resolve(import.meta.dirname ?? __dirname, "..", "..");
|
|
18
18
|
const SKILL_PATH = resolve(
|
|
19
19
|
ASSISTANT_DIR,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
"src",
|
|
21
|
+
"config",
|
|
22
|
+
"bundled-skills",
|
|
23
|
+
"guardian-verify-setup",
|
|
24
|
+
"SKILL.md",
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
const skillContent = readFileSync(SKILL_PATH,
|
|
27
|
+
const skillContent = readFileSync(SKILL_PATH, "utf-8");
|
|
28
28
|
|
|
29
29
|
// ---------------------------------------------------------------------------
|
|
30
30
|
// Tests
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
32
|
|
|
33
|
-
describe(
|
|
34
|
-
test(
|
|
33
|
+
describe("guardian-verify-setup skill — voice auto-followup", () => {
|
|
34
|
+
test("voice path in Step 3 references the auto-check polling loop", () => {
|
|
35
35
|
// The voice success instruction in Step 3 must direct the assistant to
|
|
36
36
|
// begin the polling loop rather than waiting for the user to report back.
|
|
37
37
|
expect(skillContent).toContain(
|
|
38
|
-
|
|
38
|
+
"immediately begin the voice auto-check polling loop",
|
|
39
39
|
);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
test(
|
|
42
|
+
test("voice path in Step 4 (resend) references the auto-check polling loop", () => {
|
|
43
43
|
// After a voice resend, the same auto-check behavior must kick in.
|
|
44
|
-
const resendSection =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
44
|
+
const resendSection =
|
|
45
|
+
skillContent.split("## Step 4")[1]?.split("## Step 5")[0] ?? "";
|
|
46
|
+
expect(resendSection).toContain("voice auto-check polling loop");
|
|
48
47
|
});
|
|
49
48
|
|
|
50
|
-
test(
|
|
51
|
-
expect(skillContent).toContain(
|
|
49
|
+
test("contains a Voice Auto-Check Polling section", () => {
|
|
50
|
+
expect(skillContent).toContain("## Voice Auto-Check Polling");
|
|
52
51
|
});
|
|
53
52
|
|
|
54
|
-
test(
|
|
53
|
+
test("polling section specifies the correct status endpoint for voice", () => {
|
|
55
54
|
const pollingSection =
|
|
56
|
-
skillContent
|
|
55
|
+
skillContent
|
|
56
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
57
|
+
?.split("## Step 6")[0] ?? "";
|
|
57
58
|
expect(pollingSection).toContain(
|
|
58
|
-
|
|
59
|
+
"/v1/integrations/guardian/status?channel=voice",
|
|
59
60
|
);
|
|
60
61
|
});
|
|
61
62
|
|
|
62
|
-
test(
|
|
63
|
+
test("polling section includes ~15 second interval", () => {
|
|
63
64
|
const pollingSection =
|
|
64
|
-
skillContent
|
|
65
|
-
|
|
65
|
+
skillContent
|
|
66
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
67
|
+
?.split("## Step 6")[0] ?? "";
|
|
68
|
+
expect(pollingSection).toContain("~15 seconds");
|
|
66
69
|
});
|
|
67
70
|
|
|
68
|
-
test(
|
|
71
|
+
test("polling section includes 2-minute timeout", () => {
|
|
69
72
|
const pollingSection =
|
|
70
|
-
skillContent
|
|
71
|
-
|
|
73
|
+
skillContent
|
|
74
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
75
|
+
?.split("## Step 6")[0] ?? "";
|
|
76
|
+
expect(pollingSection).toContain("2 minutes");
|
|
72
77
|
});
|
|
73
78
|
|
|
74
|
-
test(
|
|
79
|
+
test("polling section checks for bound: true", () => {
|
|
75
80
|
const pollingSection =
|
|
76
|
-
skillContent
|
|
77
|
-
|
|
81
|
+
skillContent
|
|
82
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
83
|
+
?.split("## Step 6")[0] ?? "";
|
|
84
|
+
expect(pollingSection).toContain("bound: true");
|
|
78
85
|
});
|
|
79
86
|
|
|
80
|
-
test(
|
|
87
|
+
test("polling section includes proactive success confirmation", () => {
|
|
81
88
|
const pollingSection =
|
|
82
|
-
skillContent
|
|
83
|
-
|
|
89
|
+
skillContent
|
|
90
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
91
|
+
?.split("## Step 6")[0] ?? "";
|
|
92
|
+
expect(pollingSection).toContain("proactive success message");
|
|
84
93
|
});
|
|
85
94
|
|
|
86
|
-
test(
|
|
95
|
+
test("polling section includes timeout fallback with resend/restart offer", () => {
|
|
87
96
|
const pollingSection =
|
|
88
|
-
skillContent
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
skillContent
|
|
98
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
99
|
+
?.split("## Step 6")[0] ?? "";
|
|
100
|
+
expect(pollingSection).toContain("timeout");
|
|
101
|
+
expect(pollingSection).toContain("resend");
|
|
91
102
|
});
|
|
92
103
|
|
|
93
|
-
test(
|
|
104
|
+
test("polling section includes rebind guard against false-success from pre-existing binding", () => {
|
|
94
105
|
const pollingSection =
|
|
95
|
-
skillContent
|
|
106
|
+
skillContent
|
|
107
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
108
|
+
?.split("## Step 6")[0] ?? "";
|
|
96
109
|
// Must mention rebind guard concept
|
|
97
|
-
expect(pollingSection).toContain(
|
|
110
|
+
expect(pollingSection).toContain("Rebind guard");
|
|
98
111
|
// Must instruct not to trust the first bound: true in a rebind flow
|
|
99
112
|
expect(pollingSection).toContain(
|
|
100
|
-
|
|
113
|
+
"do NOT treat the first `bound: true` poll result as success",
|
|
101
114
|
);
|
|
102
115
|
// Must reference bound_at timestamp comparison as the primary mechanism
|
|
103
|
-
expect(pollingSection).toContain(
|
|
116
|
+
expect(pollingSection).toContain("bound_at");
|
|
104
117
|
// Must have a fallback for when bound_at is unavailable
|
|
105
|
-
expect(pollingSection).toContain(
|
|
118
|
+
expect(pollingSection).toContain("second poll onward");
|
|
106
119
|
// Must clarify non-rebind flows are unaffected
|
|
107
|
-
expect(pollingSection).toContain(
|
|
120
|
+
expect(pollingSection).toContain("Non-rebind flows");
|
|
108
121
|
});
|
|
109
122
|
|
|
110
|
-
test(
|
|
123
|
+
test("polling is voice-only — does not apply to SMS or Telegram", () => {
|
|
111
124
|
const pollingSection =
|
|
112
|
-
skillContent
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
skillContent
|
|
126
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
127
|
+
?.split("## Step 6")[0] ?? "";
|
|
128
|
+
expect(pollingSection).toContain("voice-only");
|
|
129
|
+
expect(pollingSection).toContain("Do NOT poll for SMS or Telegram");
|
|
115
130
|
});
|
|
116
131
|
|
|
117
132
|
test('no instruction requires waiting for user to ask "did it work?"', () => {
|
|
@@ -119,23 +134,22 @@ describe('guardian-verify-setup skill — voice auto-followup', () => {
|
|
|
119
134
|
// confirm that voice verification worked. The auto-check polling loop
|
|
120
135
|
// makes this unnecessary.
|
|
121
136
|
const voiceAutoCheckSection =
|
|
122
|
-
skillContent
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
);
|
|
137
|
+
skillContent
|
|
138
|
+
.split("## Voice Auto-Check Polling")[1]
|
|
139
|
+
?.split("## Step 6")[0] ?? "";
|
|
140
|
+
expect(voiceAutoCheckSection).toContain("Do NOT require the user to ask");
|
|
126
141
|
// The voice bullet in Step 3 should not instruct the assistant to wait
|
|
127
142
|
// for the user to confirm or ask if it worked. Narrow to just the voice
|
|
128
143
|
// bullet line to avoid false positives from Telegram's "wait for the
|
|
129
144
|
// user to confirm they clicked the link" which is unrelated to voice.
|
|
130
|
-
const step3Section =
|
|
131
|
-
.split(
|
|
132
|
-
?.split('## Step 4')[0] ?? '';
|
|
145
|
+
const step3Section =
|
|
146
|
+
skillContent.split("## Step 3")[1]?.split("## Step 4")[0] ?? "";
|
|
133
147
|
const voiceBullet = step3Section
|
|
134
|
-
.split(
|
|
148
|
+
.split("\n")
|
|
135
149
|
.filter((line) => /^\s*-\s+\*\*Voice\*\*/.test(line))
|
|
136
|
-
.join(
|
|
150
|
+
.join("\n");
|
|
137
151
|
expect(voiceBullet).not.toHaveLength(0);
|
|
138
|
-
expect(voiceBullet).not.toContain(
|
|
139
|
-
expect(voiceBullet).not.toContain(
|
|
152
|
+
expect(voiceBullet).not.toContain("wait for the user to confirm");
|
|
153
|
+
expect(voiceBullet).not.toContain("ask the user if it worked");
|
|
140
154
|
});
|
|
141
155
|
});
|