-
Notifications
You must be signed in to change notification settings - Fork 0
bring in agent backends #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.x
Are you sure you want to change the base?
Changes from all commits
fe47d1b
98dd1ed
6867482
601be82
18f2ba5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,250 @@ | ||||||||||||||||||||||||||
| # plugin-code Orchestrator Integration Guidelines | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Context | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| `plugin-orchestrator` is a new agentic task orchestrator that: | ||||||||||||||||||||||||||
| - Runs background tasks with an agentic loop (plan → execute → evaluate → decide) | ||||||||||||||||||||||||||
| - Calls runtime actions (like CODE) to execute work | ||||||||||||||||||||||||||
| - Tracks progress and detects stalemate (stuck tasks) | ||||||||||||||||||||||||||
| - Provides batched notifications to users | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| When orchestrator calls the CODE action, it currently only knows: | ||||||||||||||||||||||||||
| - ✅ Success or failure | ||||||||||||||||||||||||||
| - ✅ Which files were modified | ||||||||||||||||||||||||||
| - ❌ What's happening during execution | ||||||||||||||||||||||||||
| - ❌ How much progress was made | ||||||||||||||||||||||||||
| - ❌ What the agent is currently doing | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Request: Add Status Provider | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Why | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The orchestrator needs to evaluate progress after each iteration. Currently it can only see binary success/failure. With a status provider, the orchestrator could: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| 1. **Better progress estimation** - Know if agent is 10% or 90% through the task | ||||||||||||||||||||||||||
| 2. **Better stalemate detection** - See if agent is stuck vs. making progress | ||||||||||||||||||||||||||
| 3. **Better user feedback** - Show "reading files..." vs. "writing changes..." | ||||||||||||||||||||||||||
| 4. **Better planning** - Know what the agent tried so it can plan next steps | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Proposed: `CODE_EXECUTION_STATUS` Provider | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```typescript | ||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Provider that exposes current coding execution status. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * WHY: Orchestrator needs visibility into CODE action execution | ||||||||||||||||||||||||||
| * to make better progress estimates and detect stalemate. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| export const codeExecutionStatusProvider: Provider = { | ||||||||||||||||||||||||||
| name: 'CODE_EXECUTION_STATUS', | ||||||||||||||||||||||||||
| description: 'Current status of coding agent execution', | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| get: async (runtime: IAgentRuntime, message: Memory, state?: State) => { | ||||||||||||||||||||||||||
| const coderService = runtime.getService<CoderService>('coder'); | ||||||||||||||||||||||||||
| if (!coderService) { | ||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||
| text: 'Coder service not available', | ||||||||||||||||||||||||||
| values: { available: false }, | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const status = coderService.getExecutionStatus(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||
| text: formatStatus(status), | ||||||||||||||||||||||||||
| values: { | ||||||||||||||||||||||||||
| // Is a coding task currently running? | ||||||||||||||||||||||||||
| isExecuting: status.isExecuting, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Which agent is being used? | ||||||||||||||||||||||||||
| agent: status.agent, // 'claude-code', 'cursor', 'native', etc. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Current phase | ||||||||||||||||||||||||||
| phase: status.phase, // 'idle', 'planning', 'reading', 'writing', 'verifying' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Files being worked on | ||||||||||||||||||||||||||
| currentFile: status.currentFile, | ||||||||||||||||||||||||||
| filesRead: status.filesRead, | ||||||||||||||||||||||||||
| filesWritten: status.filesWritten, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Progress estimate (0-100) | ||||||||||||||||||||||||||
| progress: status.progress, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Time elapsed | ||||||||||||||||||||||||||
| startedAt: status.startedAt, | ||||||||||||||||||||||||||
| elapsedMs: status.elapsedMs, | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Last action taken | ||||||||||||||||||||||||||
| lastAction: status.lastAction, | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| data: status, | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### What CoderService Needs to Track | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```typescript | ||||||||||||||||||||||||||
| interface ExecutionStatus { | ||||||||||||||||||||||||||
| // Execution state | ||||||||||||||||||||||||||
| isExecuting: boolean; | ||||||||||||||||||||||||||
| agent: string | null; | ||||||||||||||||||||||||||
| conversationId: string | null; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Phase tracking | ||||||||||||||||||||||||||
| phase: 'idle' | 'planning' | 'reading' | 'writing' | 'verifying'; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // File tracking | ||||||||||||||||||||||||||
| currentFile: string | null; | ||||||||||||||||||||||||||
| filesRead: string[]; | ||||||||||||||||||||||||||
| filesWritten: string[]; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Progress | ||||||||||||||||||||||||||
| progress: number; // 0-100 estimate | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Timing | ||||||||||||||||||||||||||
| startedAt: number | null; | ||||||||||||||||||||||||||
| elapsedMs: number; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // History (last few actions for context) | ||||||||||||||||||||||||||
| lastAction: string | null; | ||||||||||||||||||||||||||
| recentActions: string[]; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### How Agents Update Status | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Each agent implementation should call status updates: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```typescript | ||||||||||||||||||||||||||
| // In NativeCoderAgent.execute(): | ||||||||||||||||||||||||||
| async execute(params: ExecuteParams, runtime: IAgentRuntime): Promise<AgentResult> { | ||||||||||||||||||||||||||
| const coderService = runtime.getService<CoderService>('coder'); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Start | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| isExecuting: true, | ||||||||||||||||||||||||||
| agent: 'native', | ||||||||||||||||||||||||||
| phase: 'planning', | ||||||||||||||||||||||||||
| progress: 10, | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Reading files | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| phase: 'reading', | ||||||||||||||||||||||||||
| currentFile: 'src/auth.ts', | ||||||||||||||||||||||||||
| progress: 30, | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Writing | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| phase: 'writing', | ||||||||||||||||||||||||||
| currentFile: 'src/auth.ts', | ||||||||||||||||||||||||||
| filesWritten: ['src/auth.ts'], | ||||||||||||||||||||||||||
| progress: 70, | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Done | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| isExecuting: false, | ||||||||||||||||||||||||||
| phase: 'idle', | ||||||||||||||||||||||||||
| progress: 100, | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return result; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### For CLI Agents (claude, cursor, etc.) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| CLI agents can update status based on output parsing: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```typescript | ||||||||||||||||||||||||||
| // In ClaudeCodeAgent.execute(): | ||||||||||||||||||||||||||
| async execute(params: ExecuteParams, runtime: IAgentRuntime): Promise<AgentResult> { | ||||||||||||||||||||||||||
| const coderService = runtime.getService<CoderService>('coder'); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| isExecuting: true, | ||||||||||||||||||||||||||
| agent: 'claude-code', | ||||||||||||||||||||||||||
| phase: 'planning', | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Stream CLI output and parse for status updates | ||||||||||||||||||||||||||
| const process = spawn('claude', [...]); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| process.stdout.on('data', (data) => { | ||||||||||||||||||||||||||
| const output = data.toString(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Parse for file operations | ||||||||||||||||||||||||||
| if (output.includes('Reading')) { | ||||||||||||||||||||||||||
| const file = parseFileName(output); | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| phase: 'reading', | ||||||||||||||||||||||||||
| currentFile: file, | ||||||||||||||||||||||||||
| filesRead: [...status.filesRead, file], | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (output.includes('Writing')) { | ||||||||||||||||||||||||||
| const file = parseFileName(output); | ||||||||||||||||||||||||||
| coderService.updateStatus({ | ||||||||||||||||||||||||||
| phase: 'writing', | ||||||||||||||||||||||||||
| currentFile: file, | ||||||||||||||||||||||||||
| filesWritten: [...status.filesWritten, file], | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // ... | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## How Orchestrator Uses This | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```typescript | ||||||||||||||||||||||||||
| // In orchestrator's runOneIteration(): | ||||||||||||||||||||||||||
| async function runOneIteration(runtime: IAgentRuntime, task: Task) { | ||||||||||||||||||||||||||
| // ... execute CODE action ... | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // After execution, get status for better progress estimation | ||||||||||||||||||||||||||
| const statusProvider = runtime.providers.find(p => p.name === 'CODE_EXECUTION_STATUS'); | ||||||||||||||||||||||||||
| if (statusProvider) { | ||||||||||||||||||||||||||
| const status = await statusProvider.get(runtime, message, state); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Use files written as progress indicator | ||||||||||||||||||||||||||
| if (status.values.filesWritten?.length > 0) { | ||||||||||||||||||||||||||
| // Made tangible progress | ||||||||||||||||||||||||||
| progressBonus = 10; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Use phase for LLM context | ||||||||||||||||||||||||||
| lastAction = status.values.lastAction; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Implementation Priority | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| 1. **High**: Add `ExecutionStatus` tracking to CoderService | ||||||||||||||||||||||||||
| 2. **High**: Add `CODE_EXECUTION_STATUS` provider | ||||||||||||||||||||||||||
| 3. **Medium**: Update NativeCoderAgent to report status | ||||||||||||||||||||||||||
| 4. **Medium**: Update CLI agents to parse output and report status | ||||||||||||||||||||||||||
| 5. **Low**: Add `recentActions` history for LLM context | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Benefits | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| | Without Status | With Status | | ||||||||||||||||||||||||||
| |---------------|-------------| | ||||||||||||||||||||||||||
| | "CODE succeeded" | "CODE succeeded: wrote 3 files in 12s using claude-code" | | ||||||||||||||||||||||||||
| | Progress: guess | Progress: based on files read/written | | ||||||||||||||||||||||||||
| | Stalemate: after 3 failures | Stalemate: detect stuck at "reading" phase | | ||||||||||||||||||||||||||
| | User sees: "Running..." | User sees: "Writing src/auth.ts..." | | ||||||||||||||||||||||||||
|
Comment on lines
+238
to
+243
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix table pipe spacing to satisfy markdownlint MD060. The separator row is missing spaces around pipes. 🧹 Table separator formatting-|---------------|-------------|
+| ------------- | ----------- |📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.20.0)[warning] 239-239: Table column style (MD060, table-column-style) [warning] 239-239: Table column style (MD060, table-column-style) [warning] 239-239: Table column style (MD060, table-column-style) [warning] 239-239: Table column style (MD060, table-column-style) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Questions for Discussion | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| 1. Should status be per-conversation or global? | ||||||||||||||||||||||||||
| 2. How much history to keep in `recentActions`? | ||||||||||||||||||||||||||
| 3. Should progress be auto-calculated or agent-provided? | ||||||||||||||||||||||||||
| 4. Should we emit events in addition to provider? | ||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align the examples with the actual ExecutionTrackerService and ExecutionStatus types.
The doc samples use
CoderService.updateStatus()/coderService.getExecutionStatus()and an older interface shape (nullable fields, missing phases/actionHistory). The implementation now usesExecutionTrackerServiceplusExecutionPhasevalues likestarting,completing, anderror, andactionHistoryinExecutionStatus. Please update the snippets and field lists to matchsrc/services/executionTracker.service.tsandsrc/types/execution.tsso integrators aren’t misled.🤖 Prompt for AI Agents