opencode-swarm-plugin 0.34.0 → 0.36.0
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/.turbo/turbo-test.log +333 -333
- package/CHANGELOG.md +97 -0
- package/bin/swarm.test.ts +70 -0
- package/bin/swarm.ts +139 -14
- package/examples/plugin-wrapper-template.ts +447 -33
- package/package.json +1 -1
- package/src/compaction-hook.test.ts +226 -258
- package/src/compaction-hook.ts +361 -16
- package/src/eval-capture.ts +5 -6
- package/src/index.ts +21 -1
- package/src/learning.integration.test.ts +0 -2
- package/src/schemas/task.ts +0 -1
- package/src/swarm-decompose.ts +1 -15
- package/src/swarm-prompts.ts +1 -8
- package/src/swarm.integration.test.ts +0 -40
package/package.json
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
SWARM_COMPACTION_CONTEXT,
|
|
8
8
|
SWARM_DETECTION_FALLBACK,
|
|
9
9
|
createCompactionHook,
|
|
10
|
+
scanSessionMessages,
|
|
11
|
+
type ScannedSwarmState,
|
|
10
12
|
} from "./compaction-hook";
|
|
11
13
|
|
|
12
14
|
// Track log calls for verification
|
|
@@ -330,257 +332,6 @@ describe("Compaction Hook", () => {
|
|
|
330
332
|
});
|
|
331
333
|
});
|
|
332
334
|
|
|
333
|
-
describe("scanSessionMessages (SDK client integration)", () => {
|
|
334
|
-
/**
|
|
335
|
-
* These tests verify that we can extract swarm state from session messages
|
|
336
|
-
* using the OpenCode SDK client.
|
|
337
|
-
*
|
|
338
|
-
* Key types from @opencode-ai/sdk:
|
|
339
|
-
* - ToolPart: { type: "tool", tool: string, state: ToolState, ... }
|
|
340
|
-
* - ToolStateCompleted: { status: "completed", input: Record<string, unknown>, output: string, ... }
|
|
341
|
-
* - Part: union type including ToolPart
|
|
342
|
-
* - Message: { id, sessionID, role, ... }
|
|
343
|
-
*
|
|
344
|
-
* SDK API:
|
|
345
|
-
* - client.session.messages({ sessionID, limit }) → { info: Message, parts: Part[] }[]
|
|
346
|
-
*/
|
|
347
|
-
|
|
348
|
-
// Mock SDK client factory
|
|
349
|
-
const createMockClient = (messages: Array<{ info: any; parts: any[] }>) => ({
|
|
350
|
-
session: {
|
|
351
|
-
messages: async ({ sessionID, limit }: { sessionID: string; limit?: number }) => ({
|
|
352
|
-
data: messages,
|
|
353
|
-
error: undefined,
|
|
354
|
-
}),
|
|
355
|
-
},
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
it("extracts epic ID from swarm_spawn_subtask tool calls", async () => {
|
|
359
|
-
const mockMessages = [
|
|
360
|
-
{
|
|
361
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
362
|
-
parts: [
|
|
363
|
-
{
|
|
364
|
-
id: "part-1",
|
|
365
|
-
type: "tool",
|
|
366
|
-
tool: "swarm_spawn_subtask",
|
|
367
|
-
state: {
|
|
368
|
-
status: "completed",
|
|
369
|
-
input: {
|
|
370
|
-
epic_id: "bd-epic-auth-123",
|
|
371
|
-
subtask_title: "Implement auth service",
|
|
372
|
-
files: ["src/auth/service.ts"],
|
|
373
|
-
},
|
|
374
|
-
output: JSON.stringify({ success: true, agent_name: "BlueLake" }),
|
|
375
|
-
title: "Spawned subtask",
|
|
376
|
-
metadata: {},
|
|
377
|
-
time: { start: 1000, end: 2000 },
|
|
378
|
-
},
|
|
379
|
-
},
|
|
380
|
-
],
|
|
381
|
-
},
|
|
382
|
-
];
|
|
383
|
-
|
|
384
|
-
const client = createMockClient(mockMessages);
|
|
385
|
-
|
|
386
|
-
// This function doesn't exist yet - TDD Red phase
|
|
387
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
388
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
389
|
-
|
|
390
|
-
expect(result.epicId).toBe("bd-epic-auth-123");
|
|
391
|
-
expect(result.subtasks.size).toBeGreaterThan(0);
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
it("extracts agent name from swarmmail_init tool calls", async () => {
|
|
395
|
-
const mockMessages = [
|
|
396
|
-
{
|
|
397
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
398
|
-
parts: [
|
|
399
|
-
{
|
|
400
|
-
id: "part-1",
|
|
401
|
-
type: "tool",
|
|
402
|
-
tool: "swarmmail_init",
|
|
403
|
-
state: {
|
|
404
|
-
status: "completed",
|
|
405
|
-
input: {
|
|
406
|
-
project_path: "/Users/joel/project",
|
|
407
|
-
task_description: "Working on auth",
|
|
408
|
-
},
|
|
409
|
-
output: JSON.stringify({
|
|
410
|
-
agent_name: "DarkWind",
|
|
411
|
-
project_key: "/Users/joel/project",
|
|
412
|
-
}),
|
|
413
|
-
title: "Initialized swarm mail",
|
|
414
|
-
metadata: {},
|
|
415
|
-
time: { start: 1000, end: 2000 },
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
],
|
|
419
|
-
},
|
|
420
|
-
];
|
|
421
|
-
|
|
422
|
-
const client = createMockClient(mockMessages);
|
|
423
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
424
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
425
|
-
|
|
426
|
-
expect(result.agentName).toBe("DarkWind");
|
|
427
|
-
expect(result.projectPath).toBe("/Users/joel/project");
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
it("extracts epic title from hive_create_epic tool calls", async () => {
|
|
431
|
-
const mockMessages = [
|
|
432
|
-
{
|
|
433
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
434
|
-
parts: [
|
|
435
|
-
{
|
|
436
|
-
id: "part-1",
|
|
437
|
-
type: "tool",
|
|
438
|
-
tool: "hive_create_epic",
|
|
439
|
-
state: {
|
|
440
|
-
status: "completed",
|
|
441
|
-
input: {
|
|
442
|
-
epic_title: "Add OAuth authentication",
|
|
443
|
-
epic_description: "Implement OAuth2 flow",
|
|
444
|
-
subtasks: [
|
|
445
|
-
{ title: "Schema", files: ["src/schema.ts"] },
|
|
446
|
-
{ title: "Service", files: ["src/service.ts"] },
|
|
447
|
-
],
|
|
448
|
-
},
|
|
449
|
-
output: JSON.stringify({
|
|
450
|
-
epic_id: "bd-epic-oauth-456",
|
|
451
|
-
subtask_ids: ["bd-epic-oauth-456.1", "bd-epic-oauth-456.2"],
|
|
452
|
-
}),
|
|
453
|
-
title: "Created epic",
|
|
454
|
-
metadata: {},
|
|
455
|
-
time: { start: 1000, end: 2000 },
|
|
456
|
-
},
|
|
457
|
-
},
|
|
458
|
-
],
|
|
459
|
-
},
|
|
460
|
-
];
|
|
461
|
-
|
|
462
|
-
const client = createMockClient(mockMessages);
|
|
463
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
464
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
465
|
-
|
|
466
|
-
expect(result.epicId).toBe("bd-epic-oauth-456");
|
|
467
|
-
expect(result.epicTitle).toBe("Add OAuth authentication");
|
|
468
|
-
expect(result.subtasks.size).toBe(2);
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
it("tracks last action with timestamp", async () => {
|
|
472
|
-
const mockMessages = [
|
|
473
|
-
{
|
|
474
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
475
|
-
parts: [
|
|
476
|
-
{
|
|
477
|
-
id: "part-1",
|
|
478
|
-
type: "tool",
|
|
479
|
-
tool: "swarm_status",
|
|
480
|
-
state: {
|
|
481
|
-
status: "completed",
|
|
482
|
-
input: { epic_id: "bd-epic-123", project_key: "/path" },
|
|
483
|
-
output: JSON.stringify({ status: "in_progress" }),
|
|
484
|
-
title: "Checked status",
|
|
485
|
-
metadata: {},
|
|
486
|
-
time: { start: 5000, end: 6000 },
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
],
|
|
490
|
-
},
|
|
491
|
-
];
|
|
492
|
-
|
|
493
|
-
const client = createMockClient(mockMessages);
|
|
494
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
495
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
496
|
-
|
|
497
|
-
expect(result.lastAction).toBeDefined();
|
|
498
|
-
expect(result.lastAction?.tool).toBe("swarm_status");
|
|
499
|
-
expect(result.lastAction?.timestamp).toBe(6000);
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
it("ignores non-tool parts", async () => {
|
|
503
|
-
const mockMessages = [
|
|
504
|
-
{
|
|
505
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
506
|
-
parts: [
|
|
507
|
-
{ id: "part-1", type: "text", text: "Hello" },
|
|
508
|
-
{ id: "part-2", type: "reasoning", text: "Thinking..." },
|
|
509
|
-
],
|
|
510
|
-
},
|
|
511
|
-
];
|
|
512
|
-
|
|
513
|
-
const client = createMockClient(mockMessages);
|
|
514
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
515
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
516
|
-
|
|
517
|
-
expect(result.epicId).toBeUndefined();
|
|
518
|
-
expect(result.subtasks.size).toBe(0);
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
it("ignores pending/running tool states", async () => {
|
|
522
|
-
const mockMessages = [
|
|
523
|
-
{
|
|
524
|
-
info: { id: "msg-1", sessionID: "sess-1", role: "assistant" },
|
|
525
|
-
parts: [
|
|
526
|
-
{
|
|
527
|
-
id: "part-1",
|
|
528
|
-
type: "tool",
|
|
529
|
-
tool: "swarm_spawn_subtask",
|
|
530
|
-
state: {
|
|
531
|
-
status: "pending",
|
|
532
|
-
input: { epic_id: "bd-epic-123" },
|
|
533
|
-
raw: "{}",
|
|
534
|
-
},
|
|
535
|
-
},
|
|
536
|
-
{
|
|
537
|
-
id: "part-2",
|
|
538
|
-
type: "tool",
|
|
539
|
-
tool: "swarm_status",
|
|
540
|
-
state: {
|
|
541
|
-
status: "running",
|
|
542
|
-
input: { epic_id: "bd-epic-456" },
|
|
543
|
-
time: { start: 1000 },
|
|
544
|
-
},
|
|
545
|
-
},
|
|
546
|
-
],
|
|
547
|
-
},
|
|
548
|
-
];
|
|
549
|
-
|
|
550
|
-
const client = createMockClient(mockMessages);
|
|
551
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
552
|
-
const result = await scanSessionMessages(client as any, "sess-1");
|
|
553
|
-
|
|
554
|
-
// Should not extract from pending/running states
|
|
555
|
-
expect(result.epicId).toBeUndefined();
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
it("handles SDK client errors gracefully", async () => {
|
|
559
|
-
const errorClient = {
|
|
560
|
-
session: {
|
|
561
|
-
messages: async () => ({
|
|
562
|
-
data: undefined,
|
|
563
|
-
error: { message: "Network error" },
|
|
564
|
-
}),
|
|
565
|
-
},
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
569
|
-
const result = await scanSessionMessages(errorClient as any, "sess-1");
|
|
570
|
-
|
|
571
|
-
// Should return empty state, not throw
|
|
572
|
-
expect(result.subtasks.size).toBe(0);
|
|
573
|
-
expect(result.epicId).toBeUndefined();
|
|
574
|
-
});
|
|
575
|
-
|
|
576
|
-
it("returns empty state when client is undefined", async () => {
|
|
577
|
-
const { scanSessionMessages } = await import("./compaction-hook");
|
|
578
|
-
const result = await scanSessionMessages(undefined as any, "sess-1");
|
|
579
|
-
|
|
580
|
-
expect(result.subtasks.size).toBe(0);
|
|
581
|
-
});
|
|
582
|
-
});
|
|
583
|
-
|
|
584
335
|
describe("Logging instrumentation", () => {
|
|
585
336
|
it("logs compaction start with session_id", async () => {
|
|
586
337
|
const hook = createCompactionHook();
|
|
@@ -714,13 +465,230 @@ describe("Compaction Hook", () => {
|
|
|
714
465
|
await hook(input, output);
|
|
715
466
|
|
|
716
467
|
// If context was injected, should log the size
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
468
|
+
if (output.context.length > 0) {
|
|
469
|
+
const injectionLog = logCalls.find(
|
|
470
|
+
(log) =>
|
|
471
|
+
log.level === "info" && log.message === "injected swarm context",
|
|
472
|
+
);
|
|
473
|
+
expect(injectionLog?.data.context_length).toBeGreaterThan(0);
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
describe("scanSessionMessages", () => {
|
|
479
|
+
it("returns empty state when client is undefined", async () => {
|
|
480
|
+
const state = await scanSessionMessages(undefined, "test-session");
|
|
481
|
+
expect(state.epicId).toBeUndefined();
|
|
482
|
+
expect(state.agentName).toBeUndefined();
|
|
483
|
+
expect(state.subtasks.size).toBe(0);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it("returns empty state when client is null", async () => {
|
|
487
|
+
const state = await scanSessionMessages(null, "test-session");
|
|
488
|
+
expect(state.epicId).toBeUndefined();
|
|
489
|
+
expect(state.subtasks.size).toBe(0);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("extracts epic data from hive_create_epic tool call", async () => {
|
|
493
|
+
const mockClient = {
|
|
494
|
+
session: {
|
|
495
|
+
messages: async () => ({
|
|
496
|
+
data: [
|
|
497
|
+
{
|
|
498
|
+
info: { id: "msg-1", sessionID: "test-session" },
|
|
499
|
+
parts: [
|
|
500
|
+
{
|
|
501
|
+
type: "tool",
|
|
502
|
+
tool: "hive_create_epic",
|
|
503
|
+
state: {
|
|
504
|
+
status: "completed",
|
|
505
|
+
input: { epic_title: "Test Epic" },
|
|
506
|
+
output: JSON.stringify({ epic: { id: "epic-123" } }),
|
|
507
|
+
time: { start: 1000, end: 2000 },
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
],
|
|
511
|
+
},
|
|
512
|
+
],
|
|
513
|
+
}),
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
518
|
+
expect(state.epicId).toBe("epic-123");
|
|
519
|
+
expect(state.epicTitle).toBe("Test Epic");
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
it("extracts agent name from swarmmail_init tool call", async () => {
|
|
523
|
+
const mockClient = {
|
|
524
|
+
session: {
|
|
525
|
+
messages: async () => ({
|
|
526
|
+
data: [
|
|
527
|
+
{
|
|
528
|
+
info: { id: "msg-1", sessionID: "test-session" },
|
|
529
|
+
parts: [
|
|
530
|
+
{
|
|
531
|
+
type: "tool",
|
|
532
|
+
tool: "swarmmail_init",
|
|
533
|
+
state: {
|
|
534
|
+
status: "completed",
|
|
535
|
+
input: {},
|
|
536
|
+
output: JSON.stringify({
|
|
537
|
+
agent_name: "BlueLake",
|
|
538
|
+
project_key: "/test/project",
|
|
539
|
+
}),
|
|
540
|
+
time: { start: 1000, end: 2000 },
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
}),
|
|
547
|
+
},
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
551
|
+
expect(state.agentName).toBe("BlueLake");
|
|
552
|
+
expect(state.projectPath).toBe("/test/project");
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it("tracks subtasks from swarm_spawn_subtask tool calls", async () => {
|
|
556
|
+
const mockClient = {
|
|
557
|
+
session: {
|
|
558
|
+
messages: async () => ({
|
|
559
|
+
data: [
|
|
560
|
+
{
|
|
561
|
+
info: { id: "msg-1", sessionID: "test-session" },
|
|
562
|
+
parts: [
|
|
563
|
+
{
|
|
564
|
+
type: "tool",
|
|
565
|
+
tool: "swarm_spawn_subtask",
|
|
566
|
+
state: {
|
|
567
|
+
status: "completed",
|
|
568
|
+
input: {
|
|
569
|
+
bead_id: "bd-123.1",
|
|
570
|
+
epic_id: "epic-123",
|
|
571
|
+
subtask_title: "Add auth",
|
|
572
|
+
files: ["src/auth.ts"],
|
|
573
|
+
},
|
|
574
|
+
output: JSON.stringify({ worker: "RedMountain" }),
|
|
575
|
+
time: { start: 1000, end: 2000 },
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
],
|
|
579
|
+
},
|
|
580
|
+
],
|
|
581
|
+
}),
|
|
582
|
+
},
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
586
|
+
expect(state.subtasks.size).toBe(1);
|
|
587
|
+
const subtask = state.subtasks.get("bd-123.1");
|
|
588
|
+
expect(subtask?.title).toBe("Add auth");
|
|
589
|
+
expect(subtask?.status).toBe("spawned");
|
|
590
|
+
expect(subtask?.worker).toBe("RedMountain");
|
|
591
|
+
expect(subtask?.files).toEqual(["src/auth.ts"]);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("marks subtasks as completed from swarm_complete tool calls", async () => {
|
|
595
|
+
const mockClient = {
|
|
596
|
+
session: {
|
|
597
|
+
messages: async () => ({
|
|
598
|
+
data: [
|
|
599
|
+
{
|
|
600
|
+
info: { id: "msg-1", sessionID: "test-session" },
|
|
601
|
+
parts: [
|
|
602
|
+
{
|
|
603
|
+
type: "tool",
|
|
604
|
+
tool: "swarm_spawn_subtask",
|
|
605
|
+
state: {
|
|
606
|
+
status: "completed",
|
|
607
|
+
input: {
|
|
608
|
+
bead_id: "bd-123.1",
|
|
609
|
+
subtask_title: "Add auth",
|
|
610
|
+
},
|
|
611
|
+
output: "{}",
|
|
612
|
+
time: { start: 1000, end: 2000 },
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
type: "tool",
|
|
617
|
+
tool: "swarm_complete",
|
|
618
|
+
state: {
|
|
619
|
+
status: "completed",
|
|
620
|
+
input: { bead_id: "bd-123.1" },
|
|
621
|
+
output: "{}",
|
|
622
|
+
time: { start: 3000, end: 4000 },
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
},
|
|
627
|
+
],
|
|
628
|
+
}),
|
|
629
|
+
},
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
633
|
+
const subtask = state.subtasks.get("bd-123.1");
|
|
634
|
+
expect(subtask?.status).toBe("completed");
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it("tracks last action", async () => {
|
|
638
|
+
const mockClient = {
|
|
639
|
+
session: {
|
|
640
|
+
messages: async () => ({
|
|
641
|
+
data: [
|
|
642
|
+
{
|
|
643
|
+
info: { id: "msg-1", sessionID: "test-session" },
|
|
644
|
+
parts: [
|
|
645
|
+
{
|
|
646
|
+
type: "tool",
|
|
647
|
+
tool: "swarm_status",
|
|
648
|
+
state: {
|
|
649
|
+
status: "completed",
|
|
650
|
+
input: { epic_id: "epic-123", project_key: "/test" },
|
|
651
|
+
output: "{}",
|
|
652
|
+
time: { start: 5000, end: 6000 },
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
],
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
}),
|
|
659
|
+
},
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
663
|
+
expect(state.lastAction?.tool).toBe("swarm_status");
|
|
664
|
+
expect(state.lastAction?.timestamp).toBe(6000);
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
it("handles SDK errors gracefully", async () => {
|
|
668
|
+
const mockClient = {
|
|
669
|
+
session: {
|
|
670
|
+
messages: async () => {
|
|
671
|
+
throw new Error("SDK error");
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
// Should not throw, just return empty state
|
|
677
|
+
const state = await scanSessionMessages(mockClient, "test-session");
|
|
678
|
+
expect(state.subtasks.size).toBe(0);
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
it("respects limit parameter", async () => {
|
|
682
|
+
const mockClient = {
|
|
683
|
+
session: {
|
|
684
|
+
messages: async (opts: { query?: { limit?: number } }) => {
|
|
685
|
+
expect(opts.query?.limit).toBe(50);
|
|
686
|
+
return { data: [] };
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
await scanSessionMessages(mockClient, "test-session", 50);
|
|
724
692
|
});
|
|
725
693
|
});
|
|
726
694
|
});
|