@vellumai/assistant 0.3.3 → 0.3.4
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/README.md +8 -16
- package/package.json +1 -1
- package/src/__tests__/call-orchestrator.test.ts +321 -0
- package/src/__tests__/channel-approval-routes.test.ts +382 -124
- package/src/__tests__/channel-approvals.test.ts +51 -2
- package/src/__tests__/channel-delivery-store.test.ts +30 -4
- package/src/__tests__/channel-guardian.test.ts +187 -0
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/daemon-lifecycle.test.ts +635 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +19 -13
- package/src/__tests__/handlers-twilio-config.test.ts +73 -0
- package/src/__tests__/secret-scanner.test.ts +223 -0
- package/src/__tests__/shell-parser-property.test.ts +357 -2
- package/src/__tests__/system-prompt.test.ts +25 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +34 -1
- package/src/__tests__/user-reference.test.ts +68 -0
- package/src/calls/call-orchestrator.ts +63 -11
- package/src/cli/map.ts +6 -0
- package/src/commands/__tests__/cc-command-registry.test.ts +67 -0
- package/src/commands/cc-command-registry.ts +14 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +10 -3
- package/src/config/bundled-skills/messaging/SKILL.md +4 -0
- package/src/config/defaults.ts +1 -1
- package/src/config/schema.ts +3 -3
- package/src/config/skills.ts +5 -32
- package/src/config/system-prompt.ts +16 -0
- package/src/config/user-reference.ts +29 -0
- package/src/config/vellum-skills/catalog.json +52 -0
- package/src/config/vellum-skills/telegram-setup/SKILL.md +6 -1
- package/src/config/vellum-skills/twilio-setup/SKILL.md +38 -0
- package/src/daemon/auth-manager.ts +103 -0
- package/src/daemon/computer-use-session.ts +8 -1
- package/src/daemon/config-watcher.ts +253 -0
- package/src/daemon/handlers/config.ts +36 -13
- package/src/daemon/handlers/skills.ts +6 -7
- package/src/daemon/ipc-contract.ts +6 -0
- package/src/daemon/ipc-handler.ts +87 -0
- package/src/daemon/lifecycle.ts +16 -4
- package/src/daemon/ride-shotgun-handler.ts +11 -1
- package/src/daemon/server.ts +105 -502
- package/src/daemon/session-agent-loop.ts +5 -14
- package/src/daemon/session-runtime-assembly.ts +60 -44
- package/src/daemon/session.ts +8 -1
- package/src/memory/db-connection.ts +28 -0
- package/src/memory/db-init.ts +1019 -0
- package/src/memory/db.ts +2 -2007
- package/src/memory/embedding-backend.ts +79 -11
- package/src/memory/indexer.ts +2 -0
- package/src/memory/job-utils.ts +64 -4
- package/src/memory/jobs-worker.ts +7 -1
- package/src/memory/recall-cache.ts +107 -0
- package/src/memory/retriever.ts +30 -1
- package/src/memory/schema-migration.ts +984 -0
- package/src/memory/schema.ts +1 -0
- package/src/memory/search/types.ts +2 -0
- package/src/permissions/prompter.ts +14 -3
- package/src/permissions/trust-store.ts +7 -0
- package/src/runtime/channel-approvals.ts +17 -3
- package/src/runtime/gateway-client.ts +2 -1
- package/src/runtime/http-server.ts +15 -4
- package/src/runtime/routes/channel-routes.ts +172 -84
- package/src/runtime/routes/run-routes.ts +7 -1
- package/src/runtime/run-orchestrator.ts +8 -1
- package/src/security/secret-scanner.ts +218 -0
- package/src/skills/frontmatter.ts +63 -0
- package/src/skills/slash-commands.ts +23 -0
- package/src/skills/vellum-catalog-remote.ts +107 -0
- package/src/tools/browser/auto-navigate.ts +132 -24
- package/src/tools/browser/browser-manager.ts +67 -61
- package/src/tools/claude-code/claude-code.ts +55 -3
- package/src/tools/executor.ts +10 -2
- package/src/tools/skills/vellum-catalog.ts +61 -156
- package/src/tools/terminal/parser.ts +21 -5
- package/src/util/platform.ts +8 -1
- package/src/util/retry.ts +4 -4
|
@@ -298,6 +298,53 @@ describe('handleChannelDecision', () => {
|
|
|
298
298
|
expect(orchestrator.submitDecision).toHaveBeenCalledWith(run.id, 'deny');
|
|
299
299
|
});
|
|
300
300
|
|
|
301
|
+
test('uses decision.runId to target the matching pending run', () => {
|
|
302
|
+
ensureConversation('conv-1');
|
|
303
|
+
const olderRun = createRun('conv-1');
|
|
304
|
+
setRunConfirmation(olderRun.id, {
|
|
305
|
+
...sampleConfirmation,
|
|
306
|
+
toolName: 'shell',
|
|
307
|
+
toolUseId: 'req-older',
|
|
308
|
+
});
|
|
309
|
+
const newerRun = createRun('conv-1');
|
|
310
|
+
setRunConfirmation(newerRun.id, {
|
|
311
|
+
...sampleConfirmation,
|
|
312
|
+
toolName: 'browser',
|
|
313
|
+
toolUseId: 'req-newer',
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const orchestrator = makeMockOrchestrator();
|
|
317
|
+
const decision: ApprovalDecisionResult = {
|
|
318
|
+
action: 'approve_once',
|
|
319
|
+
source: 'telegram_button',
|
|
320
|
+
runId: newerRun.id,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const result = handleChannelDecision('conv-1', decision, orchestrator);
|
|
324
|
+
expect(result.applied).toBe(true);
|
|
325
|
+
expect(result.runId).toBe(newerRun.id);
|
|
326
|
+
expect(orchestrator.submitDecision).toHaveBeenCalledWith(newerRun.id, 'allow');
|
|
327
|
+
expect(orchestrator.submitDecision).not.toHaveBeenCalledWith(olderRun.id, 'allow');
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test('returns applied: false when decision.runId does not match a pending run', () => {
|
|
331
|
+
ensureConversation('conv-1');
|
|
332
|
+
const run = createRun('conv-1');
|
|
333
|
+
setRunConfirmation(run.id, sampleConfirmation);
|
|
334
|
+
|
|
335
|
+
const orchestrator = makeMockOrchestrator();
|
|
336
|
+
const decision: ApprovalDecisionResult = {
|
|
337
|
+
action: 'approve_once',
|
|
338
|
+
source: 'telegram_button',
|
|
339
|
+
runId: 'run-missing',
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const result = handleChannelDecision('conv-1', decision, orchestrator);
|
|
343
|
+
expect(result.applied).toBe(false);
|
|
344
|
+
expect(result.runId).toBeUndefined();
|
|
345
|
+
expect(orchestrator.submitDecision).not.toHaveBeenCalled();
|
|
346
|
+
});
|
|
347
|
+
|
|
301
348
|
test('approve_always adds a trust rule and submits "allow"', () => {
|
|
302
349
|
ensureConversation('conv-1');
|
|
303
350
|
const run = createRun('conv-1');
|
|
@@ -319,14 +366,16 @@ describe('handleChannelDecision', () => {
|
|
|
319
366
|
expect(result.applied).toBe(true);
|
|
320
367
|
expect(result.runId).toBe(run.id);
|
|
321
368
|
|
|
322
|
-
// Trust rule added with first allowlist and scope option
|
|
369
|
+
// Trust rule added with first allowlist and scope option.
|
|
370
|
+
// executionTarget is undefined for core tools like 'shell' — only
|
|
371
|
+
// skill-origin tools persist it (see channel-approvals.ts).
|
|
323
372
|
expect(addRuleSpy).toHaveBeenCalledWith(
|
|
324
373
|
'shell',
|
|
325
374
|
'rm -rf *',
|
|
326
375
|
'/tmp/project',
|
|
327
376
|
'allow',
|
|
328
377
|
100,
|
|
329
|
-
{ executionTarget:
|
|
378
|
+
{ executionTarget: undefined },
|
|
330
379
|
);
|
|
331
380
|
|
|
332
381
|
// The run is still approved with a simple "allow"
|
|
@@ -24,7 +24,7 @@ mock.module('../util/logger.js', () => ({
|
|
|
24
24
|
}));
|
|
25
25
|
|
|
26
26
|
import { initializeDb, getDb, resetDb } from '../memory/db.js';
|
|
27
|
-
import { channelInboundEvents, conversations, messages } from '../memory/schema.js';
|
|
27
|
+
import { channelInboundEvents, conversations, externalConversationBindings, messages } from '../memory/schema.js';
|
|
28
28
|
import {
|
|
29
29
|
recordInbound,
|
|
30
30
|
linkMessage,
|
|
@@ -470,7 +470,7 @@ describe('channel-delivery-store', () => {
|
|
|
470
470
|
|
|
471
471
|
// ── handleDeleteConversation assistantId parameter ───────────────
|
|
472
472
|
|
|
473
|
-
test('handleDeleteConversation
|
|
473
|
+
test('handleDeleteConversation with non-self assistant deletes only scoped key', async () => {
|
|
474
474
|
// Set up a scoped conversation key like the one created by recordInbound
|
|
475
475
|
// with a specific assistantId.
|
|
476
476
|
const convId = 'conv-delete-test';
|
|
@@ -488,6 +488,13 @@ describe('channel-delivery-store', () => {
|
|
|
488
488
|
}).run();
|
|
489
489
|
setConversationKey(scopedKey, convId);
|
|
490
490
|
setConversationKey(legacyKey, convId);
|
|
491
|
+
db.insert(externalConversationBindings).values({
|
|
492
|
+
conversationId: convId,
|
|
493
|
+
sourceChannel: 'telegram',
|
|
494
|
+
externalChatId: 'chat-del',
|
|
495
|
+
createdAt: now,
|
|
496
|
+
updatedAt: now,
|
|
497
|
+
}).run();
|
|
491
498
|
|
|
492
499
|
// Verify both keys exist
|
|
493
500
|
expect(getConversationByKey(scopedKey)).not.toBeNull();
|
|
@@ -510,9 +517,15 @@ describe('channel-delivery-store', () => {
|
|
|
510
517
|
const json = await res.json() as { ok: boolean };
|
|
511
518
|
expect(json.ok).toBe(true);
|
|
512
519
|
|
|
513
|
-
//
|
|
520
|
+
// Non-self delete should only remove the scoped key and preserve legacy.
|
|
514
521
|
expect(getConversationByKey(scopedKey)).toBeNull();
|
|
515
|
-
expect(getConversationByKey(legacyKey)).toBeNull();
|
|
522
|
+
expect(getConversationByKey(legacyKey)).not.toBeNull();
|
|
523
|
+
// Non-self delete should not mutate assistant-agnostic external bindings.
|
|
524
|
+
const remainingBinding = db.select()
|
|
525
|
+
.from(externalConversationBindings)
|
|
526
|
+
.where(eq(externalConversationBindings.conversationId, convId))
|
|
527
|
+
.get();
|
|
528
|
+
expect(remainingBinding).not.toBeNull();
|
|
516
529
|
});
|
|
517
530
|
|
|
518
531
|
test('handleDeleteConversation defaults to "self" when no assistantId provided', async () => {
|
|
@@ -530,6 +543,13 @@ describe('channel-delivery-store', () => {
|
|
|
530
543
|
}).run();
|
|
531
544
|
setConversationKey(scopedKey, convId);
|
|
532
545
|
setConversationKey(legacyKey, convId);
|
|
546
|
+
db.insert(externalConversationBindings).values({
|
|
547
|
+
conversationId: convId,
|
|
548
|
+
sourceChannel: 'telegram',
|
|
549
|
+
externalChatId: 'chat-def',
|
|
550
|
+
createdAt: now,
|
|
551
|
+
updatedAt: now,
|
|
552
|
+
}).run();
|
|
533
553
|
|
|
534
554
|
const req = new Request('http://localhost/channels/conversation', {
|
|
535
555
|
method: 'DELETE',
|
|
@@ -546,5 +566,11 @@ describe('channel-delivery-store', () => {
|
|
|
546
566
|
|
|
547
567
|
expect(getConversationByKey(scopedKey)).toBeNull();
|
|
548
568
|
expect(getConversationByKey(legacyKey)).toBeNull();
|
|
569
|
+
// Self delete should keep external bindings in sync for the canonical route.
|
|
570
|
+
const remainingBinding = db.select()
|
|
571
|
+
.from(externalConversationBindings)
|
|
572
|
+
.where(eq(externalConversationBindings.conversationId, convId))
|
|
573
|
+
.get();
|
|
574
|
+
expect(remainingBinding).toBeUndefined();
|
|
549
575
|
});
|
|
550
576
|
});
|
|
@@ -52,6 +52,10 @@ import {
|
|
|
52
52
|
isGuardian,
|
|
53
53
|
revokeBinding as serviceRevokeBinding,
|
|
54
54
|
} from '../runtime/channel-guardian-service.js';
|
|
55
|
+
import { handleGuardianVerification } from '../daemon/handlers/config.js';
|
|
56
|
+
import type { GuardianVerificationRequest, GuardianVerificationResponse } from '../daemon/ipc-contract.js';
|
|
57
|
+
import type { HandlerContext } from '../daemon/handlers/shared.js';
|
|
58
|
+
import type * as net from 'node:net';
|
|
55
59
|
|
|
56
60
|
initializeDb();
|
|
57
61
|
|
|
@@ -1186,3 +1190,186 @@ describe('assistant-scoped approval request lookups', () => {
|
|
|
1186
1190
|
expect(foundB!.toolName).toBe('browser');
|
|
1187
1191
|
});
|
|
1188
1192
|
});
|
|
1193
|
+
|
|
1194
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1195
|
+
// 10. IPC handler — channel-aware guardian status response
|
|
1196
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Creates a minimal mock HandlerContext that captures the response sent via ctx.send().
|
|
1200
|
+
*/
|
|
1201
|
+
function createMockCtx(): { ctx: HandlerContext; lastResponse: () => GuardianVerificationResponse | null } {
|
|
1202
|
+
let captured: GuardianVerificationResponse | null = null;
|
|
1203
|
+
const ctx = {
|
|
1204
|
+
sessions: new Map(),
|
|
1205
|
+
socketToSession: new Map(),
|
|
1206
|
+
cuSessions: new Map(),
|
|
1207
|
+
socketToCuSession: new Map(),
|
|
1208
|
+
cuObservationParseSequence: new Map(),
|
|
1209
|
+
socketSandboxOverride: new Map(),
|
|
1210
|
+
sharedRequestTimestamps: [],
|
|
1211
|
+
debounceTimers: { schedule: () => {}, cancel: () => {} } as unknown as HandlerContext['debounceTimers'],
|
|
1212
|
+
suppressConfigReload: false,
|
|
1213
|
+
setSuppressConfigReload: () => {},
|
|
1214
|
+
updateConfigFingerprint: () => {},
|
|
1215
|
+
send: (_socket: net.Socket, msg: unknown) => { captured = msg as GuardianVerificationResponse; },
|
|
1216
|
+
broadcast: () => {},
|
|
1217
|
+
clearAllSessions: () => 0,
|
|
1218
|
+
getOrCreateSession: () => Promise.resolve({} as never),
|
|
1219
|
+
touchSession: () => {},
|
|
1220
|
+
} as unknown as HandlerContext;
|
|
1221
|
+
return { ctx, lastResponse: () => captured };
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const mockSocket = {} as net.Socket;
|
|
1225
|
+
|
|
1226
|
+
describe('IPC handler channel-aware guardian status', () => {
|
|
1227
|
+
beforeEach(() => {
|
|
1228
|
+
resetTables();
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
test('status action for telegram returns channel and assistantId fields', () => {
|
|
1232
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1233
|
+
const msg: GuardianVerificationRequest = {
|
|
1234
|
+
type: 'guardian_verification',
|
|
1235
|
+
action: 'status',
|
|
1236
|
+
channel: 'telegram',
|
|
1237
|
+
assistantId: 'self',
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1241
|
+
|
|
1242
|
+
const resp = lastResponse();
|
|
1243
|
+
expect(resp).not.toBeNull();
|
|
1244
|
+
expect(resp!.success).toBe(true);
|
|
1245
|
+
expect(resp!.channel).toBe('telegram');
|
|
1246
|
+
expect(resp!.assistantId).toBe('self');
|
|
1247
|
+
expect(resp!.bound).toBe(false);
|
|
1248
|
+
expect(resp!.guardianDeliveryChatId).toBeUndefined();
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
test('status action for sms returns channel: sms and assistantId: self', () => {
|
|
1252
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1253
|
+
const msg: GuardianVerificationRequest = {
|
|
1254
|
+
type: 'guardian_verification',
|
|
1255
|
+
action: 'status',
|
|
1256
|
+
channel: 'sms',
|
|
1257
|
+
assistantId: 'self',
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1261
|
+
|
|
1262
|
+
const resp = lastResponse();
|
|
1263
|
+
expect(resp).not.toBeNull();
|
|
1264
|
+
expect(resp!.success).toBe(true);
|
|
1265
|
+
expect(resp!.channel).toBe('sms');
|
|
1266
|
+
expect(resp!.assistantId).toBe('self');
|
|
1267
|
+
expect(resp!.bound).toBe(false);
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
test('status action returns guardianDeliveryChatId when bound', () => {
|
|
1271
|
+
createBinding({
|
|
1272
|
+
assistantId: 'self',
|
|
1273
|
+
channel: 'telegram',
|
|
1274
|
+
guardianExternalUserId: 'user-42',
|
|
1275
|
+
guardianDeliveryChatId: 'chat-42',
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1279
|
+
const msg: GuardianVerificationRequest = {
|
|
1280
|
+
type: 'guardian_verification',
|
|
1281
|
+
action: 'status',
|
|
1282
|
+
channel: 'telegram',
|
|
1283
|
+
assistantId: 'self',
|
|
1284
|
+
};
|
|
1285
|
+
|
|
1286
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1287
|
+
|
|
1288
|
+
const resp = lastResponse();
|
|
1289
|
+
expect(resp).not.toBeNull();
|
|
1290
|
+
expect(resp!.success).toBe(true);
|
|
1291
|
+
expect(resp!.bound).toBe(true);
|
|
1292
|
+
expect(resp!.guardianExternalUserId).toBe('user-42');
|
|
1293
|
+
expect(resp!.guardianDeliveryChatId).toBe('chat-42');
|
|
1294
|
+
expect(resp!.channel).toBe('telegram');
|
|
1295
|
+
expect(resp!.assistantId).toBe('self');
|
|
1296
|
+
});
|
|
1297
|
+
|
|
1298
|
+
test('status action defaults channel to telegram when omitted (backward compat)', () => {
|
|
1299
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1300
|
+
const msg: GuardianVerificationRequest = {
|
|
1301
|
+
type: 'guardian_verification',
|
|
1302
|
+
action: 'status',
|
|
1303
|
+
// channel omitted — should default to 'telegram'
|
|
1304
|
+
};
|
|
1305
|
+
|
|
1306
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1307
|
+
|
|
1308
|
+
const resp = lastResponse();
|
|
1309
|
+
expect(resp).not.toBeNull();
|
|
1310
|
+
expect(resp!.channel).toBe('telegram');
|
|
1311
|
+
expect(resp!.assistantId).toBe('self');
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
test('status action defaults assistantId to self when omitted (backward compat)', () => {
|
|
1315
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1316
|
+
const msg: GuardianVerificationRequest = {
|
|
1317
|
+
type: 'guardian_verification',
|
|
1318
|
+
action: 'status',
|
|
1319
|
+
channel: 'sms',
|
|
1320
|
+
// assistantId omitted — should default to 'self'
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1323
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1324
|
+
|
|
1325
|
+
const resp = lastResponse();
|
|
1326
|
+
expect(resp).not.toBeNull();
|
|
1327
|
+
expect(resp!.assistantId).toBe('self');
|
|
1328
|
+
expect(resp!.channel).toBe('sms');
|
|
1329
|
+
});
|
|
1330
|
+
|
|
1331
|
+
test('status action with custom assistantId returns correct value', () => {
|
|
1332
|
+
createBinding({
|
|
1333
|
+
assistantId: 'asst-custom',
|
|
1334
|
+
channel: 'telegram',
|
|
1335
|
+
guardianExternalUserId: 'user-77',
|
|
1336
|
+
guardianDeliveryChatId: 'chat-77',
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1340
|
+
const msg: GuardianVerificationRequest = {
|
|
1341
|
+
type: 'guardian_verification',
|
|
1342
|
+
action: 'status',
|
|
1343
|
+
channel: 'telegram',
|
|
1344
|
+
assistantId: 'asst-custom',
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1348
|
+
|
|
1349
|
+
const resp = lastResponse();
|
|
1350
|
+
expect(resp).not.toBeNull();
|
|
1351
|
+
expect(resp!.success).toBe(true);
|
|
1352
|
+
expect(resp!.bound).toBe(true);
|
|
1353
|
+
expect(resp!.assistantId).toBe('asst-custom');
|
|
1354
|
+
expect(resp!.channel).toBe('telegram');
|
|
1355
|
+
expect(resp!.guardianExternalUserId).toBe('user-77');
|
|
1356
|
+
expect(resp!.guardianDeliveryChatId).toBe('chat-77');
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
test('status action for unbound sms does not return guardianDeliveryChatId', () => {
|
|
1360
|
+
const { ctx, lastResponse } = createMockCtx();
|
|
1361
|
+
const msg: GuardianVerificationRequest = {
|
|
1362
|
+
type: 'guardian_verification',
|
|
1363
|
+
action: 'status',
|
|
1364
|
+
channel: 'sms',
|
|
1365
|
+
};
|
|
1366
|
+
|
|
1367
|
+
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1368
|
+
|
|
1369
|
+
const resp = lastResponse();
|
|
1370
|
+
expect(resp).not.toBeNull();
|
|
1371
|
+
expect(resp!.bound).toBe(false);
|
|
1372
|
+
expect(resp!.guardianDeliveryChatId).toBeUndefined();
|
|
1373
|
+
expect(resp!.guardianExternalUserId).toBeUndefined();
|
|
1374
|
+
});
|
|
1375
|
+
});
|
|
@@ -681,7 +681,7 @@ describe('AssistantConfigSchema', () => {
|
|
|
681
681
|
userConsultTimeoutSeconds: 120,
|
|
682
682
|
disclosure: {
|
|
683
683
|
enabled: true,
|
|
684
|
-
text: 'At the very beginning of the call,
|
|
684
|
+
text: 'At the very beginning of the call, introduce yourself as an assistant calling on behalf of the user.',
|
|
685
685
|
},
|
|
686
686
|
safety: {
|
|
687
687
|
denyCategories: [],
|