# Cursor Response JSON-Struktur - Spezifikation **Stand**: Februar 2026 **Zweck**: Definition der JSON-Antwortstruktur fuer die Chat-API-Komponente, in der Antwortteile als einzelne Dokumente erfasst werden --- ## 1. Design-Prinzip Eine LLM-Antwort besteht typischerweise aus verschiedenen Segmenten: erklaerenden Texten, Code-Referenzen, neuen Code-Bloecken, Tool-Aufrufen, Datei-Aenderungen und Plaenen. Diese Segmente werden als einzelne **Dokumente** in einem Array erfasst, um sie einzeln verarbeiten, rendern und referenzieren zu koennen. --- ## 2. Top-Level Response ```json { "id": "chat_", "conversationId": "conv_", "model": "claude-4.6-opus", "mode": "agent | plan | ask | debug", "created": "2026-02-23T10:30:00Z", "status": "completed | streaming | error", "documents": [ /* Array von Document-Objekten */ ], "usage": { "promptTokens": 2450, "completionTokens": 890, "totalTokens": 3340 }, "metadata": { "duration_ms": 4520, "toolCallCount": 3, "turnCount": 2 } } ``` ### Feld-Beschreibung | Feld | Typ | Beschreibung | |---|---|---| | `id` | string | Eindeutige ID dieser Antwort | | `conversationId` | string | ID der laufenden Konversation (fuer Multi-Turn) | | `model` | string | Verwendetes LLM-Modell | | `mode` | enum | Aktiver Modus: agent, plan, ask, debug | | `created` | ISO 8601 | Zeitstempel der Erstellung | | `status` | enum | Status: completed, streaming, error | | `documents` | array | Geordnetes Array der Antwort-Dokumente | | `usage` | object | Token-Verbrauch | | `metadata` | object | Zusaetzliche Metadaten | --- ## 3. Document Types Jedes Dokument im `documents[]` Array hat folgende Basis-Struktur: ```json { "id": "doc_", "type": "", "sequence": 1, "content": "...", "metadata": { /* typ-spezifische Metadaten */ } } ``` ### 3.1 `text` - Erklaerungstext Freitext-Erklaerungen, Beschreibungen, Instruktionen des AI-Assistenten. ```json { "id": "doc_001", "type": "text", "sequence": 1, "content": "Ich werde eine Authentication-Middleware implementieren, die JWT-Token validiert und den Request-Context mit User-Informationen anreichert.\n\nDafuer sind folgende Schritte noetig:", "metadata": { "format": "markdown" } } ``` --- ### 3.2 `code_reference` - Verweis auf existierenden Code Referenz auf bestehenden Code im Projekt (Cursor's `startLine:endLine:filepath` Format). ```json { "id": "doc_002", "type": "code_reference", "sequence": 2, "content": "def main():\n app = Flask(__name__)\n app.register_blueprint(api_bp)", "metadata": { "filePath": "src/main.py", "startLine": 12, "endLine": 14, "language": "python" } } ``` --- ### 3.3 `code_block` - Neuer/vorgeschlagener Code Code-Block fuer neuen oder vorgeschlagenen Code, der nicht direkt einer Datei zugeordnet ist. ```json { "id": "doc_003", "type": "code_block", "sequence": 3, "content": "from functools import wraps\nfrom flask import request, jsonify\nimport jwt\n\ndef authMiddleware(f):\n @wraps(f)\n def decorated(*args, **kwargs):\n token = request.headers.get('Authorization')\n if not token:\n return jsonify({'error': 'Token fehlt'}), 401\n try:\n data = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])\n request.userId = data['userId']\n except jwt.InvalidTokenError:\n return jsonify({'error': 'Ungueltiger Token'}), 401\n return f(*args, **kwargs)\n return decorated", "metadata": { "language": "python", "purpose": "new_code" } } ``` --- ### 3.4 `file_edit` - Datei-Aenderung Konkrete Aenderung an einer bestehenden oder neuen Datei. ```json { "id": "doc_004", "type": "file_edit", "sequence": 4, "content": "from functools import wraps\nfrom flask import request, jsonify\nimport jwt\n\nSECRET_KEY = 'your-secret-key'\n\ndef authMiddleware(f):\n ...", "metadata": { "filePath": "src/middleware/auth.py", "operation": "create", "language": "python", "diff": null } } ``` **Operationen**: | Operation | Beschreibung | |---|---| | `create` | Neue Datei erstellen | | `edit` | Bestehende Datei aendern | | `delete` | Datei loeschen | | `rename` | Datei umbenennen | Bei `edit` wird zusaetzlich ein Diff mitgeliefert: ```json { "id": "doc_005", "type": "file_edit", "sequence": 5, "content": "app.register_blueprint(api_bp)\napp.register_blueprint(auth_bp)", "metadata": { "filePath": "src/main.py", "operation": "edit", "language": "python", "diff": { "oldString": "app.register_blueprint(api_bp)", "newString": "app.register_blueprint(api_bp)\napp.register_blueprint(auth_bp)", "startLine": 14, "endLine": 14 } } } ``` --- ### 3.5 `tool_call` - Tool-Aufruf und Ergebnis Dokumentiert einen Tool-Aufruf inklusive Argumente und Ergebnis. ```json { "id": "doc_006", "type": "tool_call", "sequence": 6, "content": null, "metadata": { "toolName": "codebase_search", "toolCallId": "call_abc123", "arguments": { "query": "Where is the Flask app initialized?", "target_directories": ["src/"], "explanation": "Find the main app entry point" }, "result": { "status": "success", "data": "Found in src/main.py:12 - app = Flask(__name__)" }, "duration_ms": 320 } } ``` --- ### 3.6 `terminal_command` - Terminal-Ausfuehrung Dokumentiert die Ausfuehrung eines Terminal-Kommandos. ```json { "id": "doc_007", "type": "terminal_command", "sequence": 7, "content": null, "metadata": { "command": "pip install PyJWT flask", "workingDirectory": "/path/to/project", "exitCode": 0, "output": "Successfully installed PyJWT-2.8.0 flask-3.0.0", "duration_ms": 5200, "permissions": ["network"] } } ``` --- ### 3.7 `plan` - Strukturierter Plan Ergebnis des Plan-Modus oder eines `create_plan` Tool-Aufrufs. ```json { "id": "doc_008", "type": "plan", "sequence": 8, "content": "# Authentication Middleware\n\n## Uebersicht\nImplementierung einer JWT-basierten Auth-Middleware...\n\n## Dateien\n- `src/middleware/auth.py` (neu)\n- `src/main.py` (aendern)\n- `requirements.txt` (aendern)", "metadata": { "title": "Auth Middleware Implementation", "overview": "JWT-basierte Authentication-Middleware mit Token-Validierung", "todos": [ { "id": "create-middleware", "content": "Auth-Middleware-Modul erstellen", "status": "pending", "dependencies": [] }, { "id": "register-blueprint", "content": "Blueprint in main.py registrieren", "status": "pending", "dependencies": ["create-middleware"] }, { "id": "update-deps", "content": "PyJWT zu requirements.txt hinzufuegen", "status": "pending", "dependencies": [] }, { "id": "protect-routes", "content": "Schuetzenswerte Routes mit Decorator versehen", "status": "pending", "dependencies": ["create-middleware", "register-blueprint"] } ], "format": "markdown" } } ``` --- ### 3.8 `clarification` - Klaerende Frage Klaerende Rueckfrage des AI-Assistenten an den User (haeufig im Plan Mode). ```json { "id": "doc_009", "type": "clarification", "sequence": 9, "content": "Bevor ich den Plan finalisiere, habe ich folgende Fragen:", "metadata": { "questions": [ { "id": "q1", "text": "Soll die Middleware JWT oder Session-basierte Auth verwenden?", "options": [ { "id": "jwt", "label": "JWT Token-basiert" }, { "id": "session", "label": "Session-basiert mit Cookies" } ] }, { "id": "q2", "text": "Welche Routes sollen geschuetzt werden?", "options": [ { "id": "all", "label": "Alle ausser Login/Register" }, { "id": "selective", "label": "Nur explizit markierte Routes" } ] } ] } } ``` --- ### 3.9 `error` - Fehlermeldung Fehlermeldung bei Tool-Ausfuehrung oder LLM-Fehler. ```json { "id": "doc_010", "type": "error", "sequence": 10, "content": "Die Datei konnte nicht gelesen werden", "metadata": { "errorCode": "FILE_NOT_FOUND", "source": "read_file", "details": "src/middleware/auth.py does not exist" } } ``` --- ### 3.10 `todo_update` - Task-Status-Aenderung Aenderung am Task-Tracking waehrend der Ausfuehrung. ```json { "id": "doc_011", "type": "todo_update", "sequence": 11, "content": null, "metadata": { "todos": [ { "id": "create-middleware", "status": "completed" }, { "id": "register-blueprint", "status": "in_progress" } ] } } ``` --- ## 4. Vollstaendiges Response-Beispiel Ein realistisches Beispiel fuer die Anfrage "Implementiere JWT Authentication": ```json { "id": "chat_7f3a2b1c", "conversationId": "conv_9e8d7c6b", "model": "claude-4.6-opus", "mode": "agent", "created": "2026-02-23T10:30:00Z", "status": "completed", "documents": [ { "id": "doc_001", "type": "text", "sequence": 1, "content": "Ich analysiere zuerst die bestehende Projektstruktur, um die beste Integrationsstrategie zu finden.", "metadata": { "format": "markdown" } }, { "id": "doc_002", "type": "tool_call", "sequence": 2, "content": null, "metadata": { "toolName": "codebase_search", "toolCallId": "call_001", "arguments": { "query": "Where is the Flask app initialized?", "target_directories": ["src/"] }, "result": { "status": "success", "data": "src/main.py:12" }, "duration_ms": 280 } }, { "id": "doc_003", "type": "tool_call", "sequence": 3, "content": null, "metadata": { "toolName": "read_file", "toolCallId": "call_002", "arguments": { "target_file": "src/main.py" }, "result": { "status": "success", "data": "import os\nfrom flask import Flask\n\ndef main():\n app = Flask(__name__)\n app.register_blueprint(api_bp)\n return app" }, "duration_ms": 45 } }, { "id": "doc_004", "type": "code_reference", "sequence": 4, "content": "def main():\n app = Flask(__name__)\n app.register_blueprint(api_bp)\n return app", "metadata": { "filePath": "src/main.py", "startLine": 5, "endLine": 8, "language": "python" } }, { "id": "doc_005", "type": "text", "sequence": 5, "content": "Ich erstelle jetzt die Auth-Middleware und integriere sie in die App.", "metadata": { "format": "markdown" } }, { "id": "doc_006", "type": "file_edit", "sequence": 6, "content": "from functools import wraps\nfrom flask import request, jsonify\nimport jwt\nimport os\n\nSECRET_KEY = os.environ.get('JWT_SECRET', 'dev-secret')\n\ndef authMiddleware(f):\n @wraps(f)\n def decorated(*args, **kwargs):\n token = request.headers.get('Authorization', '').replace('Bearer ', '')\n if not token:\n return jsonify({'error': 'Token required'}), 401\n try:\n data = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])\n request.userId = data['userId']\n except jwt.InvalidTokenError:\n return jsonify({'error': 'Invalid token'}), 401\n return f(*args, **kwargs)\n return decorated", "metadata": { "filePath": "src/middleware/auth.py", "operation": "create", "language": "python" } }, { "id": "doc_007", "type": "file_edit", "sequence": 7, "content": "from middleware.auth import authMiddleware\n\napp.register_blueprint(api_bp)\napp.register_blueprint(auth_bp)", "metadata": { "filePath": "src/main.py", "operation": "edit", "language": "python", "diff": { "oldString": "app.register_blueprint(api_bp)", "newString": "from middleware.auth import authMiddleware\n\napp.register_blueprint(api_bp)\napp.register_blueprint(auth_bp)", "startLine": 6, "endLine": 6 } } }, { "id": "doc_008", "type": "terminal_command", "sequence": 8, "content": null, "metadata": { "command": "pip install PyJWT", "exitCode": 0, "output": "Successfully installed PyJWT-2.8.0", "duration_ms": 3200, "permissions": ["network"] } }, { "id": "doc_009", "type": "text", "sequence": 9, "content": "Die JWT Authentication-Middleware ist implementiert. Du kannst jetzt Routes schuetzen mit dem `@authMiddleware` Decorator:\n\n```python\n@app.route('/api/protected')\n@authMiddleware\ndef protectedRoute():\n return jsonify({'userId': request.userId})\n```", "metadata": { "format": "markdown" } } ], "usage": { "promptTokens": 3200, "completionTokens": 1450, "totalTokens": 4650 }, "metadata": { "duration_ms": 8750, "toolCallCount": 2, "turnCount": 3 } } ``` --- ## 5. Streaming-Format Im Streaming-Modus wird jedes Dokument als Serie von Server-Sent Events uebertragen: ### 5.1 Event Types | Event Type | Beschreibung | |---|---| | `document_start` | Neues Dokument beginnt, enthaelt id und type | | `content_delta` | Text-Chunk fuer ein laufendes Dokument | | `tool_call_start` | Tool-Aufruf beginnt | | `tool_call_arguments` | Argumente des Tool-Aufrufs | | `tool_result` | Ergebnis des Tool-Aufrufs | | `document_end` | Dokument abgeschlossen | | `done` | Gesamte Antwort abgeschlossen, enthaelt usage | ### 5.2 Event-Sequenz fuer ein Text-Dokument ``` event: document_start data: {"id":"doc_001","type":"text","sequence":1} event: content_delta data: {"documentId":"doc_001","delta":"Ich analysiere "} event: content_delta data: {"documentId":"doc_001","delta":"zuerst die bestehende "} event: content_delta data: {"documentId":"doc_001","delta":"Projektstruktur..."} event: document_end data: {"documentId":"doc_001","finalContent":"Ich analysiere zuerst die bestehende Projektstruktur..."} ``` ### 5.3 Event-Sequenz fuer einen Tool-Call ``` event: document_start data: {"id":"doc_002","type":"tool_call","sequence":2} event: tool_call_start data: {"documentId":"doc_002","toolName":"read_file","toolCallId":"call_001"} event: tool_call_arguments data: {"documentId":"doc_002","arguments":{"target_file":"src/main.py"}} event: tool_result data: {"documentId":"doc_002","result":{"status":"success","data":"import os\n..."}} event: document_end data: {"documentId":"doc_002"} ``` --- ## 6. TypeScript Interface-Definitionen ```typescript interface ChatResponse { id: string; conversationId: string; model: string; mode: "agent" | "plan" | "ask" | "debug"; created: string; status: "completed" | "streaming" | "error"; documents: Document[]; usage: UsageInfo; metadata: ResponseMetadata; } type DocumentType = | "text" | "code_reference" | "code_block" | "file_edit" | "tool_call" | "terminal_command" | "plan" | "clarification" | "error" | "todo_update"; interface Document { id: string; type: DocumentType; sequence: number; content: string | null; metadata: Record; } interface TextMetadata { format: "markdown" | "plain"; } interface CodeReferenceMetadata { filePath: string; startLine: number; endLine: number; language: string; } interface CodeBlockMetadata { language: string; purpose: "new_code" | "example" | "suggestion"; } interface FileEditMetadata { filePath: string; operation: "create" | "edit" | "delete" | "rename"; language: string; diff?: { oldString: string; newString: string; startLine: number; endLine: number; }; } interface ToolCallMetadata { toolName: string; toolCallId: string; arguments: Record; result: { status: "success" | "error"; data: unknown; }; duration_ms: number; } interface TerminalCommandMetadata { command: string; workingDirectory?: string; exitCode: number; output: string; duration_ms: number; permissions: string[]; } interface PlanMetadata { title: string; overview: string; todos: PlanTodo[]; format: "markdown"; } interface PlanTodo { id: string; content: string; status: "pending" | "in_progress" | "completed" | "cancelled"; dependencies: string[]; } interface ClarificationMetadata { questions: ClarificationQuestion[]; } interface ClarificationQuestion { id: string; text: string; options: { id: string; label: string }[]; } interface ErrorMetadata { errorCode: string; source: string; details: string; } interface TodoUpdateMetadata { todos: { id: string; status: string }[]; } interface UsageInfo { promptTokens: number; completionTokens: number; totalTokens: number; } interface ResponseMetadata { duration_ms: number; toolCallCount: number; turnCount: number; } // Streaming Events type StreamEventType = | "document_start" | "content_delta" | "tool_call_start" | "tool_call_arguments" | "tool_result" | "document_end" | "done"; interface StreamEvent { type: StreamEventType; documentId?: string; data: unknown; } ``` --- ## 7. Mapping: Cursor LLM Response → Document Types Wie Cursor's roher LLM-Stream in Dokument-Typen umgewandelt wird: ``` LLM Output Stream ↓ Parser State Machine │ ├─> Erkennt freien Text → type: "text" │ Akkumuliert bis naechster Segment-Beginn │ ├─> Erkennt ``` mit startLine:endLine:filepath → type: "code_reference" │ Extrahiert: filePath, startLine, endLine, content │ ├─> Erkennt ``` mit Language-Tag → type: "code_block" │ Extrahiert: language, content │ ├─> Erkennt Tool Call im Response │ ├─> tool_name == "edit_file" → type: "file_edit" │ ├─> tool_name == "run_terminal_cmd" → type: "terminal_command" │ ├─> tool_name == "create_plan" → type: "plan" │ ├─> tool_name == "todo_write" → type: "todo_update" │ └─> alle anderen → type: "tool_call" │ └─> Erkennt Fehler → type: "error" ``` --- ## Referenzen - Cursor Architektur: `doc_cursor_ai_agent_architecture.md` - API Integration Konzept: `doc_cursor_chat_api_integration_concept.md` - OpenAI Chat Completions Streaming: https://platform.openai.com/docs/api-reference/chat/streaming - Server-Sent Events Spec: https://html.spec.whatwg.org/multipage/server-sent-events.html