diff --git a/AGENT-TASK-HANDOFF.md b/AGENT-TASK-HANDOFF.md new file mode 100644 index 0000000..701bc69 --- /dev/null +++ b/AGENT-TASK-HANDOFF.md @@ -0,0 +1,238 @@ +# Task Handoff: executor.ts + pi-runtime.ts Split + +## Context + +Du arbeitest im Repo `/home/cynar/Projects/evOo-local`. + +Es gibt 10 bereits erstellte Module-Files, die extrahierte Funktionen enthalten. Der Original-File enthält aber noch **Duplikate** derselben Funktionen. Ziel: die Definitionen aus den Original-Files entfernen, Imports + Re-Exports hinzufügen. + +## Module Files (bereits vorhanden, NICHT löschen) + +### executor-*.ts (im Verzeichnis `packages/adapters/src/`): +| File | Line count | Exports | +|------|-----------|---------| +| `executor-types.ts` | 50 | `ExecutorDeps` (interface) | +| `executor-attachments.ts` | 43 | `TURN_ATTACHMENT_UNAVAILABLE`, `STEERING_ATTACHMENT_UNAVAILABLE`, `missingTurnImagesInstruction`, `settleSteeringAttachmentLoads` | +| `executor-checkpoint.ts` | 23 | `createRunWorkspaceCheckpoint` | +| `executor-shell-guard.ts` | 177 | `isProtectedComputerLifecycleCommand` | +| `executor-effects.ts` | 151 | `recordEffect`, `completeEffect`, `uncertainEffectError` | +| `executor-completion.ts` | 65 | `completionMessageSegments`, `completionNotificationBody`, `completionMarksUnread`, `threadContextForRun`, `subagentMarksUnread` | +| `executor-model.ts` | 207 | `deploymentKeyFor`, `resolveModelKey`, `withModelCredentialLock` | +| `executor-utils.ts` | 63 | `selectRunConnections`, `loadCurrentTurnImages` | +| `executor-tools.ts` | 58 | `PAGE_BROWSER_TOOL_NAMES`, `filterPageBrowserTools`, `selectBuiltinToolsForRun` | +| `executor-computer.ts` | 231 | `computerScreenToolResult`, `runNotificationsEnabled`, `notifyRun`, `renewRunLease`, `computerRetryDelay`, `computerRunRequeueData`, `writeComputerRunRequeue`, `requeueComputerRun`, `redactBlocks`, `publishMessage`, `persistMessageInTransaction` | + +### pi-runtime Split: +| File | Line count | Exports | +|------|-----------|---------| +| `pi-model-config.ts` | 709 | Viele model config + utility functions (catalogModels, thinkingLevelFor, ToolCallBudget, maxToolCallsPerTurn, releaseToolCallBudget, beginToolCall, endToolCall, toolCallBudgetExceededMessage, configuredOpenRouterModel, modelsForRequest, prepareRequestSecretArguments, pruneComputerScreenshotContext, jsonSchemaParameters, jsonField, conversationSessionId, isOpenCodeProvider, createQueue, createGate, modelForCompletion, sanitizeSensitiveText, redactActivityUrl, sanitizeError, summarizeToolResult, boundAgentToolResult, assistantText, looksLikeOpenCodeSessionError, sanitizeProviderError, etc.) | +| `pi-runtime.ts` | 1726 | **PI Agent Runtime class** — soll bleiben, muss aber die extrahierten Functions loswerden | + +## CRITICAL: Was DU NICHT tun darfst + +1. **NIEMALS `git stash` als Nebenbei-Befehl** — Stash ist über alle Worktrees geteilt. +2. **NIEMALS den Original-File (executor.ts / pi-runtime.ts) durch einen SubAgent schreiben lassen.** Der SubAgent wird den File während der Arbeit überschreiben. +3. **NIEMALS `sed` mit Shell-Metazeichen durch SSH.** +4. **NIEMALS die extrahierten Module-Files löschen oder ändern** — sie sind korrekt. + +## Task 1: executor.ts split (4697 → ~3700 Zeilen) + +**Datei:** `/home/cynar/Projects/evOo-local/packages/adapters/src/executor.ts` + +### Was zu tun ist: + +Schreibe ein **einzelnes Python-Script**, das ALLES atomar macht: +1. Liest executor.ts +2. Findet die zu entfernenden Function-Definitionen **mittels AST-Parser** (nicht line-basiert!) +3. Entfernt die Definitionen +4. Fügt Imports + Re-Exports am Ende des import-Blocks ein +5. Entfernt alte Re-Exports am Ende der Datei +6. Schreibt den File +7. Prüft `npx tsc --noEmit -p packages/adapters/tsconfig.json` +8. Bei Fehlern: korrigiert und retry (max 3x) + +### Wie man die zu entfernenden Definitionen findet: + +Verwende den `ast` Python-Module ODER `grep` um die EXAKTEN function-Declaration-Zeilen zu finden. Dann zähle die geschwungenen Klammern **mit einem Parser, der strings/comments aware ist**. + +**WICHTIG:** Verwende `tree-sitter` oder `ast` Python-Modul wenn möglich. Alternativ: verwende `grep -n 'export function NAME\|function NAME\|export const NAME\|export interface NAME\|const NAME' executor.ts` um die Start-Zeile zu finden, und dann einen **robusten brace-counter** der Template-Strings, Regex-Literale, und Generics korrekt handhabt. + +### Zu entfernende Functions (alle existieren schon in den executor-*.ts Modulen): + +Hier ist eine Liste der Functions, die entfernt werden müssen. Für jede muss der **exakte** start/end-Block im executor.ts gefunden und entfernt werden. + +**Wichtig:** Die brace-counting muss korrekt sein bei: +- Generics: `` — die `{ }` sind Type-Parameter, keine Code-Blöcke +- Template-Strings: `` `template ${expr}` `` — kein `{ }` +- Regex: `/regex/` — kein `{ }` +- Arrow Functions: `() => { body }` — der Body hat `{ }` + +### Schritt-für-Schritt: + +#### Step 1: Finde alle zu entfernenden Export-Namen +```bash +# In packages/adapters/src/: +for f in executor-*.ts; do grep -h "^export " "$f" | grep -oP '(function|const|interface|type)\s+\K\w+'; done | sort -u +``` + +Das gibt dir die Liste aller Export-Namen aus den Modul-Files. + +#### Step 2: Finde diese Namen im executor.ts +```bash +# Für jeden Namen: +grep -n "^export.*NAME\b\|^function NAME\b\|^const NAME\b\|^interface NAME\b" executor.ts +``` + +#### Step 3: Finde den exakten end-Block mit einem robusten Parser + +Schreibe ein Python-Script `find_functions.py`: +```python +import re, sys + +file_path = sys.argv[1] +target_name = sys.argv[2] + +with open(file_path) as f: + content = f.read() + lines = content.split('\n') + +# Find declaration line +for i, line in enumerate(lines): + if re.search(rf'\b{re.escape(target_name)}\b', line): + # Find opening brace + brace_line = i + while brace_line < len(lines) and '{' not in lines[brace_line]: + brace_line += 1 + + if brace_line >= len(lines): + # No brace (const declaration) + end = i + 1 + while end < len(lines) and not lines[end].strip().endswith(';'): + end += 1 + print(f"{target_name}: L{i+1}-{end}") + break + + # Robust brace counting + depth = 0 + in_single = in_double = in_template = in_block_comment = in_line_comment = False + for j in range(brace_line, len(lines)): + k = 0 + while k < len(lines[j]): + ch = lines[j][k] + + # String handling + if ch in ('"', "'"): + q = ch + k += 1 + while k < len(lines[j]): + if lines[j][k] == '\\' and k + 1 < len(lines[j]): + k += 2 + continue + if lines[j][k] == q: + k += 1 + break + k += 1 + continue + + if ch == '`': + k += 1 + while k < len(lines[j]): + if lines[j][k] == '\\' and k + 1 < len(lines[j]): + k += 2 + continue + if lines[j][k] == '`': + k += 1 + break + k += 1 + continue + + # Comments + if not in_single and not in_double and not in_template: + if ch == '/' and k + 1 < len(lines[j]) and lines[j][k+1] == '/': + break # rest of line is comment + if ch == '/' and k + 1 < len(lines[j]) and lines[j][k+1] == '*': + in_block_comment = True + k += 2 + continue + + if in_block_comment: + if ch == '*' and k + 1 < len(lines[j]) and lines[j][k+1] == '/': + in_block_comment = False + k += 2 + continue + k += 1 + continue + + # Braces + if ch == '{': + depth += 1 + elif ch == '}': + depth -= 1 + if depth == 0: + print(f"{target_name}: L{i+1}-{j+1}") + break + k += 1 + else: + continue + break + else: + print(f"{target_name}: L{i+1}-END(not found)") + break +``` + +#### Step 4: Generiere die removal ranges +Für jeden gefundenen Block: `start_line` bis `end_line` (1-based, inclusive). + +#### Step 5: Führe alle removals atomar aus +- Baue ein Set aller zu entfernenden 0-based line indices +- Baue den neuen File content +- Füge Imports + Re-Exports an Position 340 (nach dem letzten import Statement) ein +- Entferne alte Re-Exports am Datei-Ende +- Schreibe den File + +#### Step 6: Verifiziere +```bash +npx tsc --noEmit -p packages/adapters/tsconfig.json 2>&1 | grep "executor.ts" +``` +Wenn keine errors: SUCCESS. +Wenn errors: lies die errors, korrigiere, retry max 3x. + +## Task 2: pi-runtime.ts split (1726 → ~500 Zeilen) + +**Datei:** `/home/cynar/Projects/evOo-local/packages/adapters/src/pi-runtime.ts` +**Modul:** `pi-model-config.ts` (709 Zeilen, enthält model config + utility functions) + +Gleicher Ansatz wie Task 1: +1. Finde alle Export-Namen in `pi-model-config.ts` +2. Finde diese im `pi-runtime.ts` +3. Finde die exakten start/end-Blöcke mit demselben robusten brace-counter +4. Entferne die Blöcke atomar +5. Füge Imports + Re-Exports ein +6. Entferne alte Re-Exports +7. Verifiziere mit `npx tsc --noEmit -p packages/adapters/tsconfig.json` + +## Wichtige Hinweise + +- Der `packages/adapters/src/index.ts` muss eventuell aktualisiert werden (falls er die extrahierten Functions exportiert — prüfen!) +- `verbatimModuleSyntax` ist enabled → alle imports müssen `.js` extension haben +- TypeScript `import type` vs `import`: Für Interfaces `import type`, für classes/functions `import` +- **Nicht committen oder pushen** — nur die Files ändern und verifizieren + +## Quick reference: Zu entfernende Functions aus executor.ts + +Diese Functions existieren in den executor-*.ts Modulen und MÜSSEN aus executor.ts entfernt werden: + +``` +TURN_ATTACHMENT_UNAVAILABLE, STEERING_ATTACHMENT_UNAVAILABLE, +createRunWorkspaceCheckpoint, +isProtectedComputerLifecycleCommand, shellCFlagProgram, preserveShellCommandBoundaries, tokenizeProtectedShellCommand, +recordEffect, completeEffect, uncertainEffectError, +completionMessageSegments, completionNotificationBody, completionMarksUnread, threadContextForRun, subagentMarksUnread, +deploymentKeyFor, resolveModelKey, withModelCredentialLock, +selectRunConnections, loadCurrentTurnImages, +PAGE_BROWSER_TOOL_NAMES, filterPageBrowserTools, selectBuiltinToolsForRun, +persistMessageInTransaction, computerScreenToolResult, runNotificationsEnabled, notifyRun, renewRunLease, +computerRetryDelay, computerRunRequeueData, writeComputerRunRequeue, requeueComputerRun, redactBlocks, publishMessage, +``` + +Dazu: `ExecutorDeps` interface aus `executor-types.ts`.