From 71286689f461fdc8e0ee04d7294c7e561a0f3968 Mon Sep 17 00:00:00 2001 From: "Dina Berry (She/her)" Date: Sat, 9 May 2026 07:46:12 -0700 Subject: [PATCH] fix: inject current date into spawned agent prompts to prevent hallucination Spawned agents had no awareness of the current date, causing them to hallucinate dates (often defaulting to training data cutoff dates). Changes: - Add current ISO timestamp to spawned agent initial prompts (fan-out.ts) - Replace hardcoded 2025-07-01 dates in scribe-charter templates with dynamic placeholders - Add test coverage for date injection in fan-out Closes #232 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .changeset/fix-date-hallucination.md | 5 +++++ .../squad-cli/templates/scribe-charter.md | 8 +++---- packages/squad-sdk/src/coordinator/fan-out.ts | 5 +++++ .../squad-sdk/templates/scribe-charter.md | 8 +++---- templates/scribe-charter.md | 8 +++---- test/fan-out.test.ts | 21 +++++++++++++++++++ 6 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 .changeset/fix-date-hallucination.md diff --git a/.changeset/fix-date-hallucination.md b/.changeset/fix-date-hallucination.md new file mode 100644 index 000000000..5350787cf --- /dev/null +++ b/.changeset/fix-date-hallucination.md @@ -0,0 +1,5 @@ +--- +'@bradygaster/squad-sdk': patch +--- + +Fix date hallucination in spawned agents by injecting current ISO timestamp into prompts. Replace hardcoded 2025 dates in scribe-charter templates with dynamic placeholders. \ No newline at end of file diff --git a/packages/squad-cli/templates/scribe-charter.md b/packages/squad-cli/templates/scribe-charter.md index a2031d072..0ddb2dc88 100644 --- a/packages/squad-cli/templates/scribe-charter.md +++ b/packages/squad-cli/templates/scribe-charter.md @@ -211,11 +211,11 @@ After every substantial work session: │ ├── river-jwt-auth.md │ └── kai-component-lib.md ├── orchestration-log/ # Per-spawn log entries -│ ├── 2025-07-01T10-00-river.md -│ └── 2025-07-01T10-00-kai.md +│ ├── {timestamp}-river.md +│ └── {timestamp}-kai.md ├── log/ # Session history — searchable record -│ ├── 2025-07-01-setup.md -│ └── 2025-07-02-api.md +│ ├── {date}-setup.md +│ └── {date}-api.md └── agents/ ├── kai/history.md # Kai's personal knowledge ├── river/history.md # River's personal knowledge diff --git a/packages/squad-sdk/src/coordinator/fan-out.ts b/packages/squad-sdk/src/coordinator/fan-out.ts index 7fd9ab4e2..ff1a4fbef 100644 --- a/packages/squad-sdk/src/coordinator/fan-out.ts +++ b/packages/squad-sdk/src/coordinator/fan-out.ts @@ -12,6 +12,7 @@ import type { AgentCharter } from '../agents/index.js'; import type { EventBus } from '../client/event-bus.js'; import type { SessionPool } from '../client/session-pool.js'; + // --- Spawn Configuration --- export interface AgentSpawnConfig { @@ -185,6 +186,10 @@ async function spawnSingle( function buildInitialPrompt(config: AgentSpawnConfig): string { const parts: string[] = []; + // Inject current date so spawned agents know the real date/time. + // Without this, LLMs hallucinate dates (especially the year). + parts.push(`**Current Date:** ${new Date().toISOString()}`); + if (config.priority && config.priority !== 'normal') { parts.push(`**Priority:** ${config.priority.toUpperCase()}`); } diff --git a/packages/squad-sdk/templates/scribe-charter.md b/packages/squad-sdk/templates/scribe-charter.md index a2031d072..0ddb2dc88 100644 --- a/packages/squad-sdk/templates/scribe-charter.md +++ b/packages/squad-sdk/templates/scribe-charter.md @@ -211,11 +211,11 @@ After every substantial work session: │ ├── river-jwt-auth.md │ └── kai-component-lib.md ├── orchestration-log/ # Per-spawn log entries -│ ├── 2025-07-01T10-00-river.md -│ └── 2025-07-01T10-00-kai.md +│ ├── {timestamp}-river.md +│ └── {timestamp}-kai.md ├── log/ # Session history — searchable record -│ ├── 2025-07-01-setup.md -│ └── 2025-07-02-api.md +│ ├── {date}-setup.md +│ └── {date}-api.md └── agents/ ├── kai/history.md # Kai's personal knowledge ├── river/history.md # River's personal knowledge diff --git a/templates/scribe-charter.md b/templates/scribe-charter.md index a2031d072..0ddb2dc88 100644 --- a/templates/scribe-charter.md +++ b/templates/scribe-charter.md @@ -211,11 +211,11 @@ After every substantial work session: │ ├── river-jwt-auth.md │ └── kai-component-lib.md ├── orchestration-log/ # Per-spawn log entries -│ ├── 2025-07-01T10-00-river.md -│ └── 2025-07-01T10-00-kai.md +│ ├── {timestamp}-river.md +│ └── {timestamp}-kai.md ├── log/ # Session history — searchable record -│ ├── 2025-07-01-setup.md -│ └── 2025-07-02-api.md +│ ├── {date}-setup.md +│ └── {date}-api.md └── agents/ ├── kai/history.md # Kai's personal knowledge ├── river/history.md # River's personal knowledge diff --git a/test/fan-out.test.ts b/test/fan-out.test.ts index cc0fbd054..074a74856 100644 --- a/test/fan-out.test.ts +++ b/test/fan-out.test.ts @@ -120,6 +120,27 @@ describe('spawnParallel', () => { expect(sentPrompt).toContain('Related to PRD-5'); }); + it('should include current date in prompt', async () => { + const configs: AgentSpawnConfig[] = [ + { agentName: 'fenster', task: 'Build feature' }, + ]; + + const results = await spawnParallel(configs, mockDeps); + + expect(results[0].status).toBe('success'); + + const createSessionMock = mockDeps.createSession as any; + const mockSession = await createSessionMock.mock.results[0].value; + const sentPrompt = mockSession.sendMessage.mock.calls[0][0].prompt; + + // Prompt must contain a Current Date with ISO timestamp + expect(sentPrompt).toContain('**Current Date:**'); + const dateMatch = sentPrompt.match(/\*\*Current Date:\*\*\s*(\S+)/); + expect(dateMatch).not.toBeNull(); + const timestamp = dateMatch![1]; + expect(timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/); + }); + it('should handle model overrides', async () => { const configs: AgentSpawnConfig[] = [ {