Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions ORCHESTRATOR_INTEGRATION.md
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],
});
}
});

// ...
}
```
Comment on lines +29 to +202
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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 uses ExecutionTrackerService plus ExecutionPhase values like starting, completing, and error, and actionHistory in ExecutionStatus. Please update the snippets and field lists to match src/services/executionTracker.service.ts and src/types/execution.ts so integrators aren’t misled.

🤖 Prompt for AI Agents
In `@ORCHESTRATOR_INTEGRATION.md` around lines 29 - 202, Replace the old
CoderService examples with the actual ExecutionTrackerService API: in the
codeExecutionStatusProvider sample and agent snippets, get the service via
runtime.getService<ExecutionTrackerService>('executionTracker') and call the
real methods (e.g., getExecutionStatus / updateExecutionStatus) rather than
coderService.getExecutionStatus/updateStatus; switch phase/string values to the
real ExecutionPhase enums (including starting, completing, error) instead of
'idle'|'planning'|'reading'|'writing'|'verifying'; replace nullable/legacy
fields with the actual ExecutionStatus shape from src/types/execution.ts
(include actionHistory instead of recentActions, adjust timing/identifier fields
to match the type), and update NativeCoderAgent.execute and
ClaudeCodeAgent.execute examples to call
ExecutionTrackerService.updateExecutionStatus with the new phase values and
actionHistory updates when parsing CLI output.


## 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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix table pipe spacing to satisfy markdownlint MD060.

The separator row is missing spaces around pipes.

🧹 Table separator formatting
-|---------------|-------------|
+| ------------- | ----------- |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| 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..." |
| 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..." |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 239-239: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 239-239: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 239-239: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 239-239: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)

🤖 Prompt for AI Agents
In `@ORCHESTRATOR_INTEGRATION.md` around lines 238 - 243, The Markdown table
separator row in ORCHESTRATOR_INTEGRATION.md is missing spaces around the pipe
characters which violates markdownlint MD060; update the separator row between
the header and body so each pipe has a single space before and after it (i.e.,
change "|---------------|-------------|" to use " | " spacing consistent with
the header and rows), ensuring the separator aligns with the header columns for
the table shown under the "Without Status | With Status" heading.


## 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?
Loading