From b2e9c37c41843febf64ea24ebc09647ed331ef40 Mon Sep 17 00:00:00 2001 From: CZ Date: Sat, 2 May 2026 14:01:29 +0800 Subject: [PATCH 1/2] Slim developer session prompts --- modules/api/src/developer.ts | 111 ++-------------- modules/api/src/task-continue-prompt.ts | 72 +--------- modules/api/test/developer.test.ts | 124 ++++++++---------- modules/api/test/task-continue-prompt.test.ts | 48 +++---- 4 files changed, 86 insertions(+), 269 deletions(-) diff --git a/modules/api/src/developer.ts b/modules/api/src/developer.ts index 32f3eb7b..2f0e7a8c 100644 --- a/modules/api/src/developer.ts +++ b/modules/api/src/developer.ts @@ -3,18 +3,10 @@ import type { Task } from "@aim-ai/contract"; import { AIM_SESSION_SETTLEMENT_PROTOCOL } from "./aim-session-settlement-protocol.js"; import type { ApiLogger } from "./api-logger.js"; import { cancelableSleep } from "./cancelable-sleep.js"; -import { execGh, execGit } from "./exec-file.js"; +import { execGh } from "./exec-file.js"; import type { OpenCodeSessionManager } from "./opencode-session-manager.js"; import type { OptimizerLaneEventInput } from "./optimizer-lane-events.js"; -import { ensureProjectWorkspace } from "./project-workspace.js"; -import { - type BaselineFacts, - buildTaskSessionPrompt, -} from "./task-continue-prompt.js"; - -type BaselineRepository = { - getLatestBaselineFacts(projectDirectory: string): Promise; -}; +import { buildTaskSessionPrompt } from "./task-continue-prompt.js"; type DeveloperSessionManager = Pick; @@ -49,7 +41,6 @@ type DeveloperTaskRepository = { sessionId: string, ): Promise; getTaskById?(taskId: string): Promise | null | Task; - listRejectedTasksByProject(projectId: string): Promise; listUnfinishedTasks(): Promise; updateTask?( taskId: string, @@ -58,7 +49,6 @@ type DeveloperTaskRepository = { }; type CreateDeveloperOptions = { - baselineRepository?: BaselineRepository; canStartTask?: ( task: Task, ) => @@ -75,9 +65,6 @@ type CreateDeveloperOptions = { const heartbeatMs = 1000; -const git = async (projectDirectory: string, args: string[]) => - (await execGit(projectDirectory, args, { target: projectDirectory })).trim(); - const getPullRequestFollowupOutput = (pullRequestUrl: string) => execGh( [ @@ -172,23 +159,6 @@ const categorizePullRequest = (pullRequest: PullRequestFollowupView) => { return "ready_to_merge"; }; -const defaultBaselineRepository: BaselineRepository = { - async getLatestBaselineFacts(projectDirectory) { - await git(projectDirectory, ["fetch", "origin", "main"]); - - return { - commitSha: await git(projectDirectory, ["rev-parse", "origin/main"]), - fetchedAt: new Date().toISOString(), - summary: await git(projectDirectory, [ - "log", - "-1", - "--format=%s", - "origin/main", - ]), - }; - }, -}; - const defaultPullRequestStatusProvider: PullRequestStatusProvider = { async getTaskPullRequestStatus(task) { if (!task.pull_request_url) { @@ -212,23 +182,9 @@ const defaultPullRequestStatusProvider: PullRequestStatusProvider = { const summarizeError = (error: unknown) => error instanceof Error ? error.message : String(error); -const withExplicitSourceBaselineFreshness = (task: Task): Task => - task.source_baseline_freshness - ? task - : { - ...task, - source_baseline_freshness: { - current_commit: null, - source_commit: null, - status: "unknown", - summary: "not set", - }, - }; - const buildMergedPullRequestSettlementPrompt = ( task: Task, - context: Parameters[1], -) => `${buildTaskSessionPrompt(task, context)} +) => `${buildTaskSessionPrompt(task)} Merged PR settlement objective: - This is settlement-only work for a PR-backed AIM Task whose pull_request_status is merged_but_not_resolved. @@ -240,7 +196,6 @@ Merged PR settlement objective: `; export const createDeveloper = ({ - baselineRepository = defaultBaselineRepository, canStartTask = () => ({ ok: true }), logger, onLaneEvent, @@ -316,57 +271,8 @@ export const createDeveloper = ({ return unmetDependencyIds; }; - const buildSettlementPromptContext = async ( - task: Task, - unfinishedTasks: Task[], - ) => { - const directory = await ensureProjectWorkspace(task); - const [baselineFacts, rejectedTasks] = await Promise.all([ - baselineRepository.getLatestBaselineFacts(directory), - taskRepository.listRejectedTasksByProject(task.project_id), - ]); - const activeTasks = unfinishedTasks - .filter((activeTask) => activeTask.project_id === task.project_id) - .map(withExplicitSourceBaselineFreshness); - - return { - directory, - prompt: buildMergedPullRequestSettlementPrompt(task, { - activeTasks, - baselineFacts, - rejectedTasks, - }), - }; - }; - - const buildContinuationPrompt = async ( - task: Task, - unfinishedTasks: Task[], - ) => { - const directory = await ensureProjectWorkspace(task); - const [baselineFacts, rejectedTasks] = await Promise.all([ - baselineRepository.getLatestBaselineFacts(directory), - taskRepository.listRejectedTasksByProject(task.project_id), - ]); - const activeTasks = unfinishedTasks - .filter((activeTask) => activeTask.project_id === task.project_id) - .map(withExplicitSourceBaselineFreshness); - - return buildTaskSessionPrompt(withExplicitSourceBaselineFreshness(task), { - activeTasks, - baselineFacts, - rejectedTasks, - }); - }; - - const continueMergedPullRequestSettlement = async ( - task: Task, - unfinishedTasks: Task[], - ) => { - const { prompt } = await buildSettlementPromptContext( - task, - unfinishedTasks, - ); + const continueMergedPullRequestSettlement = async (task: Task) => { + const prompt = buildMergedPullRequestSettlementPrompt(task); if (task.session_id) { onLaneEvent?.({ @@ -412,7 +318,6 @@ export const createDeveloper = ({ const continueAssignedPendingSession = async ( task: Task, tasksById: Map, - unfinishedTasks: Task[], ) => { if (!task.session_id) { return; @@ -559,7 +464,7 @@ export const createDeveloper = ({ } await rebindAssignedTaskToNewSession({ - prompt: await buildContinuationPrompt(task, unfinishedTasks), + prompt: buildTaskSessionPrompt(task), successSummary: (sessionId) => `Developer lane rebound assigned pending task ${task.task_id} from session ${task.session_id} to session ${sessionId}.`, title: `AIM Developer: ${task.title}`, @@ -596,7 +501,7 @@ export const createDeveloper = ({ } try { - await continueMergedPullRequestSettlement(task, tasks); + await continueMergedPullRequestSettlement(task); } catch (error) { logger?.error( { @@ -699,7 +604,7 @@ export const createDeveloper = ({ } try { - await continueAssignedPendingSession(task, tasksById, tasks); + await continueAssignedPendingSession(task, tasksById); } catch (error) { logger?.error( { diff --git a/modules/api/src/task-continue-prompt.ts b/modules/api/src/task-continue-prompt.ts index 7a2151b9..3a4b7f73 100644 --- a/modules/api/src/task-continue-prompt.ts +++ b/modules/api/src/task-continue-prompt.ts @@ -1,75 +1,6 @@ import type { Task } from "@aim-ai/contract"; -export type BaselineFacts = { - commitSha: string; - fetchedAt: string; - summary: string; -}; - -export type TaskSessionPromptContext = { - activeTasks: Task[]; - baselineFacts: BaselineFacts; - rejectedTasks: Task[]; -}; - -const formatTaskSummary = (task: Task) => { - const freshness = task.source_baseline_freshness; - - return [ - `- task_id: ${task.task_id}`, - ` title: ${task.title}`, - ` status: ${task.status}`, - ` done: ${task.done}`, - ` session_id: ${task.session_id ?? "not recorded"}`, - ` worktree_path: ${task.worktree_path ?? "not recorded"}`, - ` pull_request_url: ${task.pull_request_url ?? "not recorded"}`, - ` source_baseline_freshness: ${freshness?.status ?? "unknown"}; ${freshness?.summary ?? "not set"}`, - ].join("\n"); -}; - -const formatRejectedTaskSummary = (task: Task) => - [ - formatTaskSummary(task), - ` rejected_feedback: ${task.result || "not recorded"}`, - ].join("\n"); - -const buildContextPromptSection = (context?: TaskSessionPromptContext) => { - if (!context) { - return ""; - } - - const activeTaskLines = context.activeTasks.length - ? context.activeTasks.map(formatTaskSummary).join("\n") - : "- none"; - const rejectedTaskLines = context.rejectedTasks.length - ? context.rejectedTasks.map(formatRejectedTaskSummary).join("\n") - : "- none"; - - return ` - -Current baseline facts: -- origin/main commit: ${context.baselineFacts.commitSha} -- fetched_at: ${context.baselineFacts.fetchedAt} -- latest_commit_summary: ${context.baselineFacts.summary} - -Current Active Task Pool: -${activeTaskLines} - -Rejected Task feedback for this project: -${rejectedTaskLines} - -source_baseline_freshness guardrails: -- Treat stale or unknown source_baseline_freshness as a collision warning, not permission to proceed blindly. -- Before editing, compare the task source baseline against the latest origin/main facts above. -- Avoid duplicating or conflicting with same-project unfinished Tasks in the Active Task Pool. -- Account for rejected Task feedback before continuing implementation. -`; -}; - -export const buildTaskSessionPrompt = ( - task: Task, - context?: TaskSessionPromptContext, -) => ` +export const buildTaskSessionPrompt = (task: Task) => ` You are the AIM developer. FOLLOW the aim-developer-guide SKILL and finish the task assigned to you by AIM Coordinator. @@ -89,7 +20,6 @@ High-cost lifecycle warnings: - If worktree_path is recorded, do not recreate the worktree; continue the existing lifecycle. - If pull_request_url is recorded, do not recreate the PR; continue the existing lifecycle. - If a lifecycle fact is not recorded, verify current task facts before creating anything. -${buildContextPromptSection(context)} Final status reporting is concise: resolved only after the GitHub PR is merged, the worktree is cleaned up, and the local main branch is refreshed to origin/main; rejected only when Task Spec verification fails. diff --git a/modules/api/test/developer.test.ts b/modules/api/test/developer.test.ts index b0e4fbd4..fd4b7a27 100644 --- a/modules/api/test/developer.test.ts +++ b/modules/api/test/developer.test.ts @@ -55,16 +55,6 @@ const createOpenCodeSession = ( ...overrides, }); -const baselineFacts = { - commitSha: "a9979ba9487edf2d822e10ae7b651c98be3d175d", - fetchedAt: "2026-04-28T17:13:03.000Z", - summary: "Refactor optimizer system startup lifecycle (#258)", -}; - -const createBaselineRepository = () => ({ - getLatestBaselineFacts: vi.fn().mockResolvedValue(baselineFacts), -}); - const unknownSourceBaselineFreshness: Task["source_baseline_freshness"] = { current_commit: null, source_commit: null, @@ -122,10 +112,8 @@ describe("developer", () => { .mockResolvedValue([initialTaskWithoutFreshness]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, taskRepository: repository, }); @@ -169,7 +157,6 @@ describe("developer", () => { listUnfinishedTasks: vi.fn().mockResolvedValue([newTask, mergedTask]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const pullRequestStatusProvider = { getTaskPullRequestStatus: vi.fn().mockResolvedValue({ category: "merged_but_not_resolved", @@ -177,7 +164,6 @@ describe("developer", () => { }; const developer = createTestDeveloper({ - baselineRepository, pullRequestStatusProvider, sessionManager, taskRepository: repository, @@ -220,7 +206,6 @@ describe("developer", () => { .mockResolvedValue([failedChecksTask, reviewBlockedTask, newTask]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const pullRequestStatusProvider = { getTaskPullRequestStatus: vi .fn() @@ -229,7 +214,6 @@ describe("developer", () => { }; const developer = createTestDeveloper({ - baselineRepository, pullRequestStatusProvider, sessionManager, taskRepository: repository, @@ -261,7 +245,6 @@ describe("developer", () => { listUnfinishedTasks: vi.fn().mockResolvedValue([mergedTask]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const pullRequestStatusProvider = { getTaskPullRequestStatus: vi.fn().mockResolvedValue({ category: "merged_but_not_resolved", @@ -269,7 +252,6 @@ describe("developer", () => { }; const developer = createTestDeveloper({ - baselineRepository, pullRequestStatusProvider, sessionManager, taskRepository: repository, @@ -306,8 +288,14 @@ describe("developer", () => { const settlementPrompt = sessionManager.createSession.mock.calls.find( ([input]) => input.prompt.includes("Merged PR settlement objective"), )?.[0].prompt; + expect(settlementPrompt?.length).toBeLessThan(2_300); + expect(settlementPrompt).not.toContain("Current baseline facts"); + expect(settlementPrompt).not.toContain("Current Active Task Pool"); + expect(settlementPrompt).not.toContain("Rejected Task feedback"); + expect(settlementPrompt).not.toContain("task_spec"); expect(settlementPrompt).not.toContain("aim_session_resolve"); expect(settlementPrompt).not.toContain("aim_session_reject"); + expect(repository.listRejectedTasksByProject).not.toHaveBeenCalled(); expect(sessionManager.createSession).toHaveBeenCalledWith( expect.objectContaining({ prompt: expect.stringContaining("actionable rejected reason"), @@ -342,11 +330,9 @@ describe("developer", () => { sessionManager.createSession.mockResolvedValue( createSessionHandle("session-rebound"), ); - const baselineRepository = createBaselineRepository(); const onLaneEvent = vi.fn(); const developer = createTestDeveloper({ - baselineRepository, onLaneEvent, sessionManager, taskRepository: repository, @@ -358,15 +344,15 @@ describe("developer", () => { }); }); expect(sessionManager.createSession).toHaveBeenCalledWith({ - prompt: expect.stringContaining("Current baseline facts"), + prompt: buildTaskSessionPrompt(assignedTask), projectId: assignedTask.project_id, title: `AIM Developer: ${assignedTask.title}`, }); const prompt = sessionManager.createSession.mock.calls[0]?.[0].prompt; - expect(prompt).toContain(baselineFacts.commitSha); - expect(prompt).toContain("Current Active Task Pool"); - expect(prompt).toContain("Rejected Task feedback"); - expect(prompt).toContain("source_baseline_freshness guardrails"); + expect(prompt).not.toContain("Current baseline facts"); + expect(prompt).not.toContain("Current Active Task Pool"); + expect(prompt).not.toContain("Rejected Task feedback"); + expect(prompt).not.toContain("source_baseline_freshness guardrails"); expect(onLaneEvent).toHaveBeenCalledWith( expect.objectContaining({ event: "success", @@ -409,10 +395,8 @@ describe("developer", () => { sessionManager.createSession.mockResolvedValue( createSessionHandle("session-rebound"), ); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, sessionRepository, taskRepository: repository, @@ -427,7 +411,7 @@ describe("developer", () => { "session-existing", ); expect(sessionManager.createSession).toHaveBeenCalledWith({ - prompt: expect.stringContaining("Current baseline facts"), + prompt: buildTaskSessionPrompt(assignedTask), projectId: assignedTask.project_id, title: `AIM Developer: ${assignedTask.title}`, }); @@ -436,7 +420,7 @@ describe("developer", () => { await developer[Symbol.asyncDispose](); }); - it("includes same-project active pool and rejected feedback in assigned pending rebind prompts", async () => { + it("keeps assigned pending rebind prompts stable with many active and rejected tasks", async () => { vi.useFakeTimers(); const assignedTask = createTask({ opencode_session: createOpenCodeSession({ @@ -450,7 +434,7 @@ describe("developer", () => { const activeTask = createTask({ session_id: "session-active", source_baseline_freshness: { - current_commit: baselineFacts.commitSha, + current_commit: "a9979ba9487edf2d822e10ae7b651c98be3d175d", source_commit: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", status: "stale", summary: "Task source baseline differs from current origin/main", @@ -488,10 +472,8 @@ describe("developer", () => { sessionManager.createSession.mockResolvedValue( createSessionHandle("session-rebound"), ); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, taskRepository: repository, }); @@ -502,14 +484,16 @@ describe("developer", () => { }); }); const prompt = sessionManager.createSession.mock.calls[0]?.[0].prompt; - expect(prompt).toContain(baselineFacts.commitSha); + expect(prompt.length).toBeLessThan(1_800); expect(prompt).toContain("task-assigned"); - expect(prompt).toContain("task-active"); - expect(prompt).toContain("Active overlapping work"); + expect(prompt).not.toContain("a9979ba9487edf2d822e10ae7b651c98be3d175d"); + expect(prompt).not.toContain("task-active"); + expect(prompt).not.toContain("Active overlapping work"); expect(prompt).not.toContain("task-other-project"); - expect(prompt).toContain("task-rejected"); - expect(prompt).toContain("Rejected because origin/main moved."); - expect(prompt).toContain("source_baseline_freshness guardrails"); + expect(prompt).not.toContain("task-rejected"); + expect(prompt).not.toContain("Rejected because origin/main moved."); + expect(prompt).not.toContain("source_baseline_freshness guardrails"); + expect(repository.listRejectedTasksByProject).not.toHaveBeenCalled(); await developer[Symbol.asyncDispose](); }); @@ -530,11 +514,9 @@ describe("developer", () => { listUnfinishedTasks: vi.fn().mockResolvedValue([assignedTask]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const onLaneEvent = vi.fn(); const developer = createTestDeveloper({ - baselineRepository, onLaneEvent, sessionManager, taskRepository: repository, @@ -1059,10 +1041,8 @@ describe("developer", () => { }; const sessionManager = createSessionManager(); sessionManager.createSession.mockResolvedValue(activeSession); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, taskRepository: repository, }); @@ -1091,10 +1071,8 @@ describe("developer", () => { }; const sessionManager = createSessionManager(); sessionManager.createSession.mockResolvedValue(lostRaceSession); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, taskRepository: repository, }); @@ -1112,38 +1090,42 @@ describe("developer", () => { it("builds a lightweight bootstrap prompt without preloading baseline, active pool, or rejected feedback", async () => { vi.useFakeTimers(); const initialTask = createTask(); - const activeTask = createTask({ - session_id: "session-active", - source_baseline_freshness: { - current_commit: "a9979ba9487edf2d822e10ae7b651c98be3d175d", - source_commit: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - status: "stale", - summary: - "Task source baseline bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb differs from current origin/main a9979ba9487edf2d822e10ae7b651c98be3d175d", - }, - task_id: "task-active", - title: "Active overlapping work", - worktree_path: "/repo/.worktrees/task-active", - }); - const rejectedTask = createTask({ - done: true, - result: "Rejected because origin/main moved.", - status: "rejected", - task_id: "task-rejected", - title: "Rejected stale work", - }); + const activeTasks = Array.from({ length: 60 }, (_, index) => + createTask({ + session_id: `session-active-${index}`, + source_baseline_freshness: { + current_commit: "a9979ba9487edf2d822e10ae7b651c98be3d175d", + source_commit: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + status: "stale", + summary: + "Task source baseline bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb differs from current origin/main a9979ba9487edf2d822e10ae7b651c98be3d175d", + }, + task_id: `task-active-${index}`, + title: `Active overlapping work ${index}`, + worktree_path: `/repo/.worktrees/task-active-${index}`, + }), + ); + const rejectedTasks = Array.from({ length: 60 }, (_, index) => + createTask({ + done: true, + result: `Rejected because origin/main moved ${index}.`, + status: "rejected", + task_id: `task-rejected-${index}`, + title: `Rejected stale work ${index}`, + }), + ); const repository = { assignSessionIfUnassigned: vi .fn() .mockResolvedValue(createTask({ session_id: "session-1" })), - listRejectedTasksByProject: vi.fn().mockResolvedValue([rejectedTask]), - listUnfinishedTasks: vi.fn().mockResolvedValue([initialTask, activeTask]), + listRejectedTasksByProject: vi.fn().mockResolvedValue(rejectedTasks), + listUnfinishedTasks: vi + .fn() + .mockResolvedValue([initialTask, ...activeTasks]), }; const sessionManager = createSessionManager(); - const baselineRepository = createBaselineRepository(); const developer = createTestDeveloper({ - baselineRepository, sessionManager, taskRepository: repository, }); @@ -1155,7 +1137,6 @@ describe("developer", () => { ); }); - expect(baselineRepository.getLatestBaselineFacts).not.toHaveBeenCalled(); expect(repository.listRejectedTasksByProject).not.toHaveBeenCalled(); expect(sessionManager.createSession).toHaveBeenCalledBefore( repository.assignSessionIfUnassigned, @@ -1166,11 +1147,12 @@ describe("developer", () => { expect(prompt).toContain(`project_id: ${initialTask.project_id}`); expect(prompt).toContain(`GET /tasks/${initialTask.task_id}`); expect(prompt).toContain(`GET /tasks/${initialTask.task_id}/spec`); + expect(prompt.length).toBeLessThan(1_800); expect(prompt).not.toContain("Current baseline facts"); expect(prompt).not.toContain("Current Active Task Pool"); expect(prompt).not.toContain("Rejected Task feedback"); - expect(prompt).not.toContain("task-active"); - expect(prompt).not.toContain("task-rejected"); + expect(prompt).not.toContain("task-active-59"); + expect(prompt).not.toContain("task-rejected-59"); await developer[Symbol.asyncDispose](); }); diff --git a/modules/api/test/task-continue-prompt.test.ts b/modules/api/test/task-continue-prompt.test.ts index 52ecda34..4044da05 100644 --- a/modules/api/test/task-continue-prompt.test.ts +++ b/modules/api/test/task-continue-prompt.test.ts @@ -75,30 +75,30 @@ describe("buildTaskSessionPrompt", () => { expect(prompt).toMatch(/continue the existing lifecycle/i); }); - it("serializes provided baseline, active pool, and rejected feedback into the developer prompt", () => { - const prompt = buildTaskSessionPrompt(createTask(), { - activeTasks: [ - createTask({ task_id: "task-active", title: "Active work" }), - ], - baselineFacts: { - commitSha: "a9979ba9487edf2d822e10ae7b651c98be3d175d", - fetchedAt: "2026-04-28T17:13:03.000Z", - summary: "Refactor optimizer system startup lifecycle (#258)", - }, - rejectedTasks: [ - createTask({ task_id: "task-rejected", title: "Rejected work" }), - ], - }); + it("does not serialize task spec or bulky task fields into the bootstrap prompt", () => { + const prompt = buildTaskSessionPrompt( + createTask({ + result: "Rejected because origin/main moved.", + source_metadata: { + generated_tasks: Array.from({ length: 100 }, (_, index) => ({ + task_id: `generated-${index}`, + title: `Generated task ${index}`, + })), + }, + task_spec: + "Implement a large private task spec that must be fetched separately.", + title: "Large task title that should not be preloaded", + }), + ); - expect(prompt).toContain("Current baseline facts"); - expect(prompt).toContain("a9979ba9487edf2d822e10ae7b651c98be3d175d"); - expect(prompt).toContain("Refactor optimizer system startup lifecycle"); - expect(prompt).toContain("Current Active Task Pool"); - expect(prompt).toContain("task-active"); - expect(prompt).toContain("Active work"); - expect(prompt).toContain("Rejected Task feedback"); - expect(prompt).toContain("task-rejected"); - expect(prompt).toContain("Rejected work"); - expect(prompt).toContain("source_baseline_freshness guardrails"); + expect(prompt.length).toBeLessThan(1_800); + expect(prompt).not.toContain("Implement a large private task spec"); + expect(prompt).not.toContain("Large task title"); + expect(prompt).not.toContain("Rejected because origin/main moved"); + expect(prompt).not.toContain("generated-99"); + expect(prompt).not.toContain("Current baseline facts"); + expect(prompt).not.toContain("Current Active Task Pool"); + expect(prompt).not.toContain("Rejected Task feedback"); + expect(prompt).not.toContain("source_baseline_freshness guardrails"); }); }); From 485d78f52df8598646db4f6098754dea0cdf694b Mon Sep 17 00:00:00 2001 From: CZ Date: Sat, 2 May 2026 14:06:46 +0800 Subject: [PATCH 2/2] Add developer prompt changeset --- .changeset/slim-developer-session-prompts.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/slim-developer-session-prompts.md diff --git a/.changeset/slim-developer-session-prompts.md b/.changeset/slim-developer-session-prompts.md new file mode 100644 index 00000000..a370fc20 --- /dev/null +++ b/.changeset/slim-developer-session-prompts.md @@ -0,0 +1,5 @@ +--- +"@aim-ai/api": patch +--- + +Slim AIM Developer session prompts to avoid preloading task pool and baseline context.