| author | |
| committer | |
| log | 3b6af0bd1600f034b0466e1b8ff017fbabeba910 |
| tree | 040d631e5f69a01196f32669eac674e9c17758f3 |
| parent | 563645cf6e104ad930f4c9b209678a77eef07e65 |
| signature | Signed by PGP key B5690EEEBB952194 |
14 files changed, 185 insertions(+), 173 deletions(-)
apps/server/src/orchestration-v2/testkit/fixtures/message_steering/pi_transcript.ndjson-2| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"message_steering","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"message_steering","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
apps/server/src/orchestration-v2/testkit/fixtures/multi_turn/pi_transcript.ndjson-2| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"multi_turn","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"multi_turn","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
apps/server/src/orchestration-v2/testkit/fixtures/pi_compaction/pi_transcript.ndjson-2| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"pi_compaction","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"pi_compaction","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
apps/server/src/orchestration-v2/testkit/fixtures/provider_thread_resume/pi_transcript.ndjson-4| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"provider_thread_resume","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"provider_thread_resume","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
| ... | @@ -61,9 +59,7 @@ | ... | @@ -61,9 +59,7 @@ |
| 61 | {"type":"emit_inbound","label":"response:get_session_stats","frame":{"id":"t3-8","type":"response","command":"get_session_stats","success":true,"data":{"sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","userMessages":1,"assistantMessages":1,"toolCalls":0,"toolResults":0,"totalMessages":3,"tokens":{"input":1792,"output":85,"cacheRead":0,"cacheWrite":0,"total":1877},"cost":0.00008212932000000001,"contextUsage":{"tokens":1877,"contextWindow":1048576,"percent":0.17900466918945312}}}} | 59 | {"type":"emit_inbound","label":"response:get_session_stats","frame":{"id":"t3-8","type":"response","command":"get_session_stats","success":true,"data":{"sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","userMessages":1,"assistantMessages":1,"toolCalls":0,"toolResults":0,"totalMessages":3,"tokens":{"input":1792,"output":85,"cacheRead":0,"cacheWrite":0,"total":1877},"cost":0.00008212932000000001,"contextUsage":{"tokens":1877,"contextWindow":1048576,"percent":0.17900466918945312}}}} |
| 62 | {"type":"expect_outbound","label":"process_start@p2","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 60 | {"type":"expect_outbound","label":"process_start@p2","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 63 | {"type":"expect_outbound","label":"switch_session@p2","frame":{"type":"switch_session","sessionPath":"/pi-sessions/session-1.jsonl","id":"t3-0"}} | 61 | {"type":"expect_outbound","label":"switch_session@p2","frame":{"type":"switch_session","sessionPath":"/pi-sessions/session-1.jsonl","id":"t3-0"}} |
| 64 | {"type":"expect_outbound","label":"get_commands@p2","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 65 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000003","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 62 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000003","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 66 | {"type":"emit_inbound","label":"response:get_commands@p2","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 67 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000004","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 63 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000004","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 68 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000005","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 64 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000005","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 69 | {"type":"emit_inbound","label":"response:switch_session@p2","frame":{"id":"t3-0","type":"response","command":"switch_session","success":true,"data":{"cancelled":false}}} | 65 | {"type":"emit_inbound","label":"response:switch_session@p2","frame":{"id":"t3-0","type":"response","command":"switch_session","success":true,"data":{"cancelled":false}}} |
apps/server/src/orchestration-v2/testkit/fixtures/simple/pi_transcript.ndjson-2| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"simple","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"simple","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
apps/server/src/orchestration-v2/testkit/fixtures/thread_rollback/pi_transcript.ndjson-2| ... | @@ -1,11 +1,9 @@ | ... | @@ -1,11 +1,9 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"thread_rollback","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"thread_rollback","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 8 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
| 11 | {"type":"emit_inbound","label":"response:get_entries","frame":{"id":"t3-3","type":"response","command":"get_entries","success":true,"data":{"entries":[{"type":"model_change","id":"648fe89a","parentId":null,"timestamp":"2026-01-01T00:00:00.000Z","provider":"openrouter","modelId":"deepseek/deepseek-v4-flash"},{"type":"thinking_level_change","id":"00c31b78","parentId":"648fe89a","timestamp":"2026-01-01T00:00:00.000Z","thinkingLevel":"high"}],"leafId":"00c31b78"}}} | 9 | {"type":"emit_inbound","label":"response:get_entries","frame":{"id":"t3-3","type":"response","command":"get_entries","success":true,"data":{"entries":[{"type":"model_change","id":"648fe89a","parentId":null,"timestamp":"2026-01-01T00:00:00.000Z","provider":"openrouter","modelId":"deepseek/deepseek-v4-flash"},{"type":"thinking_level_change","id":"00c31b78","parentId":"648fe89a","timestamp":"2026-01-01T00:00:00.000Z","thinkingLevel":"high"}],"leafId":"00c31b78"}}} |
apps/server/src/orchestration-v2/testkit/fixtures/thread_rollback_after_stop/pi_transcript.ndjson-4| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"thread_rollback_after_stop","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"thread_rollback_after_stop","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
| ... | @@ -151,9 +149,7 @@ | ... | @@ -151,9 +149,7 @@ |
| 151 | {"type":"emit_inbound","label":"response:get_entries","frame":{"id":"t3-10","type":"response","command":"get_entries","success":true,"data":{"entries":[{"type":"message","id":"ee73daae","parentId":"b184b5a8","timestamp":"2026-01-01T00:00:01.971Z","message":{"role":"user","content":[{"type":"text","text":"Run this exact local command: `node -e \"console.log('interrupt fixture tool started'); setTimeout(() => {}, 30000)\"`. Do not answer until it completes, then respond exactly: interrupt fixture should not finish naturally."}],"timestamp":1767225601969}},{"type":"message","id":"c3915df7","parentId":"ee73daae","timestamp":"2026-01-01T00:00:06.406Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"The user wants me to run a command that will wait for 30 seconds, and then after it completes, respond with a specific message. But they also say \"Do not answer until it completes\" - but this command will run for 30 seconds and then naturally finish. However, the response they want is \"interrupt fixture should not finish naturally\" which contradicts the fact that it did finish naturally.\n\nWait, let me re-read. They want me to run the command and not answer until it completes. The command is a node script that logs \"interrupt fixture tool started\" and then waits 30 seconds. If I wait for it to complete, it will finish naturally after 30 seconds. But the response they want is \"interrupt fixture should not finish naturally\" - implying that the fixture should have been interrupted before finishing naturally.\n\nThis is a test scenario. Let me just run it and see what happens. Actually, maybe they want me to just run it and respond accordingly. Let me execute the command.\n\nActually, I think this is part of a test where the system might interrupt/kill the process. Let me just run the command with a sufficient timeout.","thinkingSignature":"<signature>"},{"type":"toolCall","id":"call_8ac3cb4177994abdb9aa1c57","name":"bash","arguments":{"command":"node -e \"console.log('interrupt fixture tool started'); setTimeout(() => {}, 30000)\"","timeout":35}}],"api":"openai-completions","provider":"openrouter","model":"deepseek/deepseek-v4-flash","usage":{"input":77,"output":317,"cacheRead":1792,"cacheWrite":0,"reasoning":284,"totalTokens":2186,"cost":{"input":0.00000322322,"output":0.000026539239999999998,"cacheRead":0.000015002623999999998,"cacheWrite":0,"total":0.000044765084}},"stopReason":"toolUse","timestamp":1767225601972,"responseId":"gen-1790898593-E5hfYfRp6aKBI57pUKss","rawStopReason":"tool_calls","thinkingLevel":"high"}},{"type":"message","id":"641f3d3f","parentId":"c3915df7","timestamp":"2026-01-01T00:00:06.463Z","message":{"role":"toolResult","toolCallId":"call_8ac3cb4177994abdb9aa1c57","toolName":"bash","content":[{"type":"text","text":"interrupt fixture tool started\n\n\nCommand aborted"}],"details":{},"isError":true,"timestamp":1767225606463}},{"type":"message","id":"e3ab1495","parentId":"641f3d3f","timestamp":"2026-01-01T00:00:06.465Z","message":{"role":"assistant","content":[],"api":"openai-completions","provider":"openrouter","model":"deepseek/deepseek-v4-flash","usage":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0,"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0}},"stopReason":"error","errorMessage":"This operation was aborted","timestamp":1767225606465,"thinkingLevel":"high"}}],"leafId":"e3ab1495"}}} | 149 | {"type":"emit_inbound","label":"response:get_entries","frame":{"id":"t3-10","type":"response","command":"get_entries","success":true,"data":{"entries":[{"type":"message","id":"ee73daae","parentId":"b184b5a8","timestamp":"2026-01-01T00:00:01.971Z","message":{"role":"user","content":[{"type":"text","text":"Run this exact local command: `node -e \"console.log('interrupt fixture tool started'); setTimeout(() => {}, 30000)\"`. Do not answer until it completes, then respond exactly: interrupt fixture should not finish naturally."}],"timestamp":1767225601969}},{"type":"message","id":"c3915df7","parentId":"ee73daae","timestamp":"2026-01-01T00:00:06.406Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"The user wants me to run a command that will wait for 30 seconds, and then after it completes, respond with a specific message. But they also say \"Do not answer until it completes\" - but this command will run for 30 seconds and then naturally finish. However, the response they want is \"interrupt fixture should not finish naturally\" which contradicts the fact that it did finish naturally.\n\nWait, let me re-read. They want me to run the command and not answer until it completes. The command is a node script that logs \"interrupt fixture tool started\" and then waits 30 seconds. If I wait for it to complete, it will finish naturally after 30 seconds. But the response they want is \"interrupt fixture should not finish naturally\" - implying that the fixture should have been interrupted before finishing naturally.\n\nThis is a test scenario. Let me just run it and see what happens. Actually, maybe they want me to just run it and respond accordingly. Let me execute the command.\n\nActually, I think this is part of a test where the system might interrupt/kill the process. Let me just run the command with a sufficient timeout.","thinkingSignature":"<signature>"},{"type":"toolCall","id":"call_8ac3cb4177994abdb9aa1c57","name":"bash","arguments":{"command":"node -e \"console.log('interrupt fixture tool started'); setTimeout(() => {}, 30000)\"","timeout":35}}],"api":"openai-completions","provider":"openrouter","model":"deepseek/deepseek-v4-flash","usage":{"input":77,"output":317,"cacheRead":1792,"cacheWrite":0,"reasoning":284,"totalTokens":2186,"cost":{"input":0.00000322322,"output":0.000026539239999999998,"cacheRead":0.000015002623999999998,"cacheWrite":0,"total":0.000044765084}},"stopReason":"toolUse","timestamp":1767225601972,"responseId":"gen-1790898593-E5hfYfRp6aKBI57pUKss","rawStopReason":"tool_calls","thinkingLevel":"high"}},{"type":"message","id":"641f3d3f","parentId":"c3915df7","timestamp":"2026-01-01T00:00:06.463Z","message":{"role":"toolResult","toolCallId":"call_8ac3cb4177994abdb9aa1c57","toolName":"bash","content":[{"type":"text","text":"interrupt fixture tool started\n\n\nCommand aborted"}],"details":{},"isError":true,"timestamp":1767225606463}},{"type":"message","id":"e3ab1495","parentId":"641f3d3f","timestamp":"2026-01-01T00:00:06.465Z","message":{"role":"assistant","content":[],"api":"openai-completions","provider":"openrouter","model":"deepseek/deepseek-v4-flash","usage":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0,"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0}},"stopReason":"error","errorMessage":"This operation was aborted","timestamp":1767225606465,"thinkingLevel":"high"}}],"leafId":"e3ab1495"}}} |
| 152 | {"type":"expect_outbound","label":"process_start@p2","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 150 | {"type":"expect_outbound","label":"process_start@p2","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 153 | {"type":"expect_outbound","label":"switch_session@p2","frame":{"type":"switch_session","sessionPath":"/pi-sessions/session-1.jsonl","id":"t3-0"}} | 151 | {"type":"expect_outbound","label":"switch_session@p2","frame":{"type":"switch_session","sessionPath":"/pi-sessions/session-1.jsonl","id":"t3-0"}} |
| 154 | {"type":"expect_outbound","label":"get_commands@p2","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 155 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000003","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 152 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000003","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 156 | {"type":"emit_inbound","label":"response:get_commands@p2","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 157 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000004","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 153 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000004","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 158 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000005","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 154 | {"type":"emit_inbound","label":"extension_ui_request@p2","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000005","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 159 | {"type":"emit_inbound","label":"response:switch_session@p2","frame":{"id":"t3-0","type":"response","command":"switch_session","success":true,"data":{"cancelled":false}}} | 155 | {"type":"emit_inbound","label":"response:switch_session@p2","frame":{"id":"t3-0","type":"response","command":"switch_session","success":true,"data":{"cancelled":false}}} |
apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/pi_transcript.ndjson-2| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"turn_interrupt_mid_tool","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} | 1 | {"type":"transcript_start","provider":"pi","protocol":"pi.rpc-jsonl","version":"1.0.0","scenario":"turn_interrupt_mid_tool","metadata":{"generatedBy":"live-pi-recorder","piVersion":"1.0.0","model":"openrouter/deepseek/deepseek-v4-flash","launchArgs":"--provider openrouter --model deepseek/deepseek-v4-flash --no-extensions --no-skills --no-prompt-templates --no-context-files --approve"}} |
| 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} | 2 | {"type":"expect_outbound","label":"process_start","frame":{"type":"process_start","args":["--mode","rpc","--provider","openrouter","--model","deepseek/deepseek-v4-flash","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--approve","--extension","<any>"]}} |
| 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} | 3 | {"type":"expect_outbound","label":"get_state","frame":{"type":"get_state","id":"t3-0"}} |
| 4 | {"type":"expect_outbound","label":"get_commands","frame":{"type":"get_commands","id":"t3-1"}} | ||
| 5 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} | 4 | {"type":"emit_inbound","label":"extension_ui_request","frame":{"type":"extension_ui_request","id":"00000000-0000-4000-8000-000000000001","method":"notify","message":"t3-code MCP unavailable: T3_MCP_URL or T3_MCP_BEARER_TOKEN is missing.","notifyType":"warning"}} |
| 6 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} | 5 | {"type":"emit_inbound","label":"response:get_state","frame":{"id":"t3-0","type":"response","command":"get_state","success":true,"data":{"model":{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}},"thinkingLevel":"high","isStreaming":false,"isCompacting":false,"steeringMode":"one-at-a-time","followUpMode":"one-at-a-time","sessionFile":"/pi-sessions/session-1.jsonl","sessionId":"00000000-0000-4000-8000-000000000002","autoCompactionEnabled":true,"messageCount":0,"pendingMessageCount":0}}} |
| 7 | {"type":"emit_inbound","label":"response:get_commands","frame":{"id":"t3-1","type":"response","command":"get_commands","success":true,"data":{"commands":[]}}} | ||
| 8 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} | 6 | {"type":"expect_outbound","label":"get_available_models","frame":{"type":"get_available_models","id":"t3-2"}} |
| 9 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} | 7 | {"type":"emit_inbound","label":"response:get_available_models","frame":{"id":"t3-2","type":"response","command":"get_available_models","success":true,"data":{"models":[{"type":"chat","id":"deepseek/deepseek-v4-flash","name":"DeepSeek: DeepSeek V4 Flash 0423","api":"openai-completions","baseUrl":"https://openrouter.ai/api/v1","provider":"openrouter","reasoning":true,"thinkingLevelMap":{"off":"none","minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh","max":null},"input":["text"],"cost":{"input":0.04186,"output":0.08372,"cacheRead":0.008372,"cacheWrite":0},"contextWindow":1048576,"maxTokens":131072,"compat":{"supportsDeveloperRole":false,"thinkingFormat":"openrouter","supportsStrictMode":true,"sendSessionAffinityHeaders":true,"requiresReasoningContentOnAssistantMessages":true}}]}}} |
| 10 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} | 8 | {"type":"expect_outbound","label":"get_entries","frame":{"type":"get_entries","id":"t3-3"}} |
packages/provider-pi/src/server/adapter.test.ts+2-60| ... | @@ -94,10 +94,6 @@ interface FakePi { | ... | @@ -94,10 +94,6 @@ interface FakePi { |
| 94 | readonly allRequests: () => ReadonlyArray<PiRpcRecord>; | 94 | readonly allRequests: () => ReadonlyArray<PiRpcRecord>; |
| 95 | /** Data returned by the next `get_session_stats` acks, consumed in order. */ | 95 | /** Data returned by the next `get_session_stats` acks, consumed in order. */ |
| 96 | readonly queueStats: (data: unknown) => void; | 96 | readonly queueStats: (data: unknown) => void; |
| 97 | /** Data returned by the next `get_commands` acks, consumed in order. */ | ||
| 98 | readonly queueCommands: (data: unknown) => void; | ||
| 99 | /** Make the next `get_commands` ack fail. */ | ||
| 100 | readonly failNextCommands: () => void; | ||
| 101 | /** Close the fake process stdout stream. */ | 97 | /** Close the fake process stdout stream. */ |
| 102 | readonly closeStdout: Effect.Effect<void>; | 98 | readonly closeStdout: Effect.Effect<void>; |
| 103 | readonly lastSpawn: () => { | 99 | readonly lastSpawn: () => { |
| ... | @@ -137,7 +133,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { | ... | @@ -137,7 +133,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { |
| 137 | const messagesQueue: Array<unknown> = []; | 133 | const messagesQueue: Array<unknown> = []; |
| 138 | const stateQueue: Array<Record<string, unknown>> = []; | 134 | const stateQueue: Array<Record<string, unknown>> = []; |
| 139 | const statsQueue: Array<unknown> = []; | 135 | const statsQueue: Array<unknown> = []; |
| 140 | const commandsQueue: Array<{ readonly success: boolean; readonly data?: unknown }> = []; | ||
| 141 | const allRequests: Array<PiRpcRecord> = []; | 136 | const allRequests: Array<PiRpcRecord> = []; |
| 142 | let deferState = false; | 137 | let deferState = false; |
| 143 | let deferredStateRequest: PiRpcRecord | undefined; | 138 | let deferredStateRequest: PiRpcRecord | undefined; |
| ... | @@ -191,8 +186,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { | ... | @@ -191,8 +186,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { |
| 191 | return { ...base, data: messagesQueue.shift() ?? { messages: [] } }; | 186 | return { ...base, data: messagesQueue.shift() ?? { messages: [] } }; |
| 192 | case "get_session_stats": | 187 | case "get_session_stats": |
| 193 | return { ...base, data: statsQueue.shift() ?? {} }; | 188 | return { ...base, data: statsQueue.shift() ?? {} }; |
| 194 | case "get_commands": | ||
| 195 | return { ...base, ...(commandsQueue.shift() ?? { data: { commands: [] } }) }; | ||
| 196 | case "fork": | 189 | case "fork": |
| 197 | return { ...base, data: { text: "Hello pi", cancelled: false } }; | 190 | return { ...base, data: { text: "Hello pi", cancelled: false } }; |
| 198 | default: | 191 | default: |
| ... | @@ -305,8 +298,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { | ... | @@ -305,8 +298,6 @@ const makeFakePi: Effect.Effect<FakePi> = Effect.gen(function* () { |
| 305 | }, | 298 | }, |
| 306 | queueState: (data) => stateQueue.push(data), | 299 | queueState: (data) => stateQueue.push(data), |
| 307 | queueStats: (data) => statsQueue.push(data), | 300 | queueStats: (data) => statsQueue.push(data), |
| 308 | queueCommands: (data) => commandsQueue.push({ success: true, data }), | ||
| 309 | failNextCommands: () => commandsQueue.push({ success: false }), | ||
| 310 | closeStdout: Queue.end(stdout), | 301 | closeStdout: Queue.end(stdout), |
| 311 | lastSpawn: () => lastSpawn, | 302 | lastSpawn: () => lastSpawn, |
| 312 | } satisfies FakePi; | 303 | } satisfies FakePi; |
| ... | @@ -1697,22 +1688,9 @@ describe("PiAdapterV2", () => { | ... | @@ -1697,22 +1688,9 @@ describe("PiAdapterV2", () => { |
| 1697 | }).pipe(Effect.scoped, Effect.provide(layerTest)), | 1688 | }).pipe(Effect.scoped, Effect.provide(layerTest)), |
| 1698 | ); | 1689 | ); |
| 1699 | 1690 | ||
| 1700 | it.effect("expands a selected $ skill through Pi's native skill command", () => | 1691 | it.effect("preserves selected skill references for the Pi extension to expand", () => |
| 1701 | Effect.gen(function* () { | 1692 | Effect.gen(function* () { |
| 1702 | const fake = yield* makeFakePi; | 1693 | const fake = yield* makeFakePi; |
| 1703 | fake.queueCommands({ | ||
| 1704 | commands: [ | ||
| 1705 | { | ||
| 1706 | name: "skill:repo-review", | ||
| 1707 | description: "Review this repository.", | ||
| 1708 | source: "skill", | ||
| 1709 | sourceInfo: { | ||
| 1710 | path: "/workspace/.agents/skills/repo-review/SKILL.md", | ||
| 1711 | scope: "project", | ||
| 1712 | }, | ||
| 1713 | }, | ||
| 1714 | ], | ||
| 1715 | }); | ||
| 1716 | const { runtime } = yield* openRuntime(fake); | 1694 | const { runtime } = yield* openRuntime(fake); |
| 1717 | const providerThread = yield* runtime.ensureThread({ | 1695 | const providerThread = yield* runtime.ensureThread({ |
| 1718 | threadId: THREAD_ID, | 1696 | threadId: THREAD_ID, |
| ... | @@ -1728,43 +1706,7 @@ describe("PiAdapterV2", () => { | ... | @@ -1728,43 +1706,7 @@ describe("PiAdapterV2", () => { |
| 1728 | "Review this change please $repo-review", | 1706 | "Review this change please $repo-review", |
| 1729 | ); | 1707 | ); |
| 1730 | const prompt = yield* fake.takeRequest("prompt"); | 1708 | const prompt = yield* fake.takeRequest("prompt"); |
| 1731 | assert.equal(prompt["message"], "/skill:repo-review Review this change please"); | 1709 | assert.equal(prompt["message"], "Review this change please $repo-review"); |
| 1732 | }).pipe(Effect.scoped, Effect.provide(layerTest)), | ||
| 1733 | ); | ||
| 1734 | |||
| 1735 | it.effect("expands every selected $ skill through Pi native skill commands", () => | ||
| 1736 | Effect.gen(function* () { | ||
| 1737 | const fake = yield* makeFakePi; | ||
| 1738 | fake.queueCommands({ | ||
| 1739 | commands: [ | ||
| 1740 | { | ||
| 1741 | name: "skill:repo-review", | ||
| 1742 | source: "skill", | ||
| 1743 | sourceInfo: { | ||
| 1744 | path: "/workspace/.agents/skills/repo-review/SKILL.md", | ||
| 1745 | scope: "project", | ||
| 1746 | }, | ||
| 1747 | }, | ||
| 1748 | { | ||
| 1749 | name: "skill:deploy", | ||
| 1750 | source: "skill", | ||
| 1751 | sourceInfo: { | ||
| 1752 | path: "/workspace/.agents/skills/deploy/SKILL.md", | ||
| 1753 | scope: "project", | ||
| 1754 | }, | ||
| 1755 | }, | ||
| 1756 | ], | ||
| 1757 | }); | ||
| 1758 | const { runtime } = yield* openRuntime(fake); | ||
| 1759 | const providerThread = yield* runtime.ensureThread({ | ||
| 1760 | threadId: THREAD_ID, | ||
| 1761 | modelSelection: modelSelection("default"), | ||
| 1762 | runtimePolicy, | ||
| 1763 | }); | ||
| 1764 | |||
| 1765 | yield* startTurn(runtime, providerThread, "default", [], "use $repo-review and $deploy"); | ||
| 1766 | const prompt = yield* fake.takeRequest("prompt"); | ||
| 1767 | assert.equal(prompt["message"], "/skill:repo-review /skill:deploy use and"); | ||
| 1768 | }).pipe(Effect.scoped, Effect.provide(layerTest)), | 1710 | }).pipe(Effect.scoped, Effect.provide(layerTest)), |
| 1769 | ); | 1711 | ); |
| 1770 | 1712 |
packages/provider-pi/src/server/adapter.ts+2-37| ... | @@ -63,12 +63,7 @@ import { ChildProcessSpawner } from "effect/process"; | ... | @@ -63,12 +63,7 @@ import { ChildProcessSpawner } from "effect/process"; |
| 63 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; | 63 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 64 | import { mcpToolPresentation } from "@t3tools/provider-core/server/mcpToolPresentation"; | 64 | import { mcpToolPresentation } from "@t3tools/provider-core/server/mcpToolPresentation"; |
| 65 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; | 65 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; |
| 66 | import { | 66 | import { parsePiCompactCommand, type PiCompactCommand } from "./commands.ts"; |
| 67 | expandPiSkillReference, | ||
| 68 | parsePiCompactCommand, | ||
| 69 | parsePiDiscoveredCommands, | ||
| 70 | type PiCompactCommand, | ||
| 71 | } from "./commands.ts"; | ||
| 72 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; | 67 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; |
| 73 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 68 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 74 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | 69 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| ... | @@ -114,7 +109,6 @@ const STREAM_FLUSH_MS = 50; | ... | @@ -114,7 +109,6 @@ const STREAM_FLUSH_MS = 50; |
| 114 | const PI_REQUEST_TIMEOUT_MS = 15_000; | 109 | const PI_REQUEST_TIMEOUT_MS = 15_000; |
| 115 | // Session lifecycle hooks reload extensions, MCP servers and language servers. | 110 | // Session lifecycle hooks reload extensions, MCP servers and language servers. |
| 116 | const PI_SESSION_TIMEOUT_MS = 60_000; | 111 | const PI_SESSION_TIMEOUT_MS = 60_000; |
| 117 | const PI_SKILL_DISCOVERY_TIMEOUT_MS = 4_000; | ||
| 118 | const PI_UNSOLICITED_ACTIVITY_ERROR = | 112 | const PI_UNSOLICITED_ACTIVITY_ERROR = |
| 119 | "Pi started agent work outside an active T3 turn. The session was stopped to prevent invisible tool execution."; | 113 | "Pi started agent work outside an active T3 turn. The session was stopped to prevent invisible tool execution."; |
| 120 | const SETTLE_PROBE_MAX_ATTEMPTS = 3; | 114 | const SETTLE_PROBE_MAX_ATTEMPTS = 3; |
| ... | @@ -458,15 +452,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( | ... | @@ -458,15 +452,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( |
| 458 | }), | 452 | }), |
| 459 | ), | 453 | ), |
| 460 | ); | 454 | ); |
| 461 | const discoverSkillNames = connection | ||
| 462 | .request({ type: "get_commands" }, PI_SKILL_DISCOVERY_TIMEOUT_MS) | ||
| 463 | .pipe( | ||
| 464 | Effect.map( | ||
| 465 | (data) => new Set(parsePiDiscoveredCommands(data).skills.map((skill) => skill.name)), | ||
| 466 | ), | ||
| 467 | ); | ||
| 468 | let skillNames: Set<string> | null = null; | ||
| 469 | |||
| 470 | const now = yield* DateTime.now; | 455 | const now = yield* DateTime.now; |
| 471 | let sessionEntity: OrchestrationV2ProviderSession = { | 456 | let sessionEntity: OrchestrationV2ProviderSession = { |
| 472 | id: input.providerSessionId, | 457 | id: input.providerSessionId, |
| ... | @@ -2117,16 +2102,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( | ... | @@ -2117,16 +2102,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( |
| 2117 | Effect.forkIn(scope), | 2102 | Effect.forkIn(scope), |
| 2118 | ); | 2103 | ); |
| 2119 | 2104 | ||
| 2120 | // Discovery can invoke extension code and therefore raise a blocking | ||
| 2121 | // UI request. Start it only after the event pump exists, and never hold | ||
| 2122 | // session opening on it; startup requests are persisted at session | ||
| 2123 | // scope and can be answered before a turn begins. | ||
| 2124 | yield* discoverSkillNames.pipe( | ||
| 2125 | Effect.tap((discovered) => Effect.sync(() => (skillNames = discovered))), | ||
| 2126 | Effect.ignore, | ||
| 2127 | Effect.forkIn(scope), | ||
| 2128 | ); | ||
| 2129 | |||
| 2130 | // ── session runtime ─────────────────────────────────── | 2105 | // ── session runtime ─────────────────────────────────── |
| 2131 | 2106 | ||
| 2132 | const registerThread = Effect.fnUntraced(function* ( | 2107 | const registerThread = Effect.fnUntraced(function* ( |
| ... | @@ -2329,15 +2304,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( | ... | @@ -2329,15 +2304,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( |
| 2329 | text: string, | 2304 | text: string, |
| 2330 | attachments: ReadonlyArray<ChatAttachment>, | 2305 | attachments: ReadonlyArray<ChatAttachment>, |
| 2331 | ) { | 2306 | ) { |
| 2332 | // Provider discovery and the live session are separate Pi processes. | ||
| 2333 | // Retry a failed session-local lookup once at first use so a transient | ||
| 2334 | // startup failure cannot leave a visible $ skill inert for this session. | ||
| 2335 | if (skillNames === null && text.includes("$")) { | ||
| 2336 | skillNames = yield* discoverSkillNames.pipe( | ||
| 2337 | Effect.orElseSucceed(() => new Set<string>()), | ||
| 2338 | ); | ||
| 2339 | } | ||
| 2340 | const expandedText = skillNames === null ? text : expandPiSkillReference(text, skillNames); | ||
| 2341 | const images: Array<{ type: "image"; data: string; mimeType: string }> = []; | 2307 | const images: Array<{ type: "image"; data: string; mimeType: string }> = []; |
| 2342 | const extraLines: Array<string> = []; | 2308 | const extraLines: Array<string> = []; |
| 2343 | for (const attachment of attachments) { | 2309 | for (const attachment of attachments) { |
| ... | @@ -2354,8 +2320,7 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( | ... | @@ -2354,8 +2320,7 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( |
| 2354 | extraLines.push(`[Attachment saved at ${path}]`); | 2320 | extraLines.push(`[Attachment saved at ${path}]`); |
| 2355 | } | 2321 | } |
| 2356 | } | 2322 | } |
| 2357 | const message = | 2323 | const message = extraLines.length === 0 ? text : `${text}\n\n${extraLines.join("\n")}`; |
| 2358 | extraLines.length === 0 ? expandedText : `${expandedText}\n\n${extraLines.join("\n")}`; | ||
| 2359 | return { message, images }; | 2324 | return { message, images }; |
| 2360 | }); | 2325 | }); |
| 2361 | 2326 |
packages/provider-pi/src/server/commands.test.ts-17| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | import { expect, it } from "@effect/vitest"; | 1 | import { expect, it } from "@effect/vitest"; |
| 2 | 2 | ||
| 3 | import { | 3 | import { |
| 4 | expandPiSkillReference, | ||
| 5 | parsePiCompactCommand, | 4 | parsePiCompactCommand, |
| 6 | parsePiDiscoveredCommands, | 5 | parsePiDiscoveredCommands, |
| 7 | PI_COMPACT_SLASH_COMMAND, | 6 | PI_COMPACT_SLASH_COMMAND, |
| ... | @@ -109,19 +108,3 @@ it("prepends the builtin compact command without duplicating a discovered one", | ... | @@ -109,19 +108,3 @@ it("prepends the builtin compact command without duplicating a discovered one", |
| 109 | ]), | 108 | ]), |
| 110 | ).toEqual([PI_COMPACT_SLASH_COMMAND, { name: "hello" }]); | 109 | ).toEqual([PI_COMPACT_SLASH_COMMAND, { name: "hello" }]); |
| 111 | }); | 110 | }); |
| 112 | |||
| 113 | it("leaves unrelated dollar-prefixed text unchanged", () => { | ||
| 114 | expect(expandPiSkillReference("Explain $HOME", new Set(["global-review"]))).toBe("Explain $HOME"); | ||
| 115 | }); | ||
| 116 | |||
| 117 | it("hoists every known $ skill and keeps the rest of the prompt", () => { | ||
| 118 | expect(expandPiSkillReference("use $alpha then $beta please", new Set(["alpha", "beta"]))).toBe( | ||
| 119 | "/skill:alpha /skill:beta use then please", | ||
| 120 | ); | ||
| 121 | }); | ||
| 122 | |||
| 123 | it("preserves code indentation and line breaks when expanding a skill", () => { | ||
| 124 | expect(expandPiSkillReference("$review\n```ts\n const x = 1;\n```", new Set(["review"]))).toBe( | ||
| 125 | "/skill:review ```ts\n const x = 1;\n```", | ||
| 126 | ); | ||
| 127 | }); |
packages/provider-pi/src/server/commands.ts-35| ... | @@ -91,41 +91,6 @@ export function parsePiDiscoveredCommands(data: unknown): PiDiscoveredCommands { | ... | @@ -91,41 +91,6 @@ export function parsePiDiscoveredCommands(data: unknown): PiDiscoveredCommands { |
| 91 | return { slashCommands, skills }; | 91 | return { slashCommands, skills }; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /** | ||
| 95 | * Pi expands skills only through leading `/skill:name` commands. T3 stores | ||
| 96 | * skill chips as `$name`, so hoist every known `$skill` to that native | ||
| 97 | * command position while preserving the rest of the user's prompt. | ||
| 98 | */ | ||
| 99 | export function expandPiSkillReference(text: string, skillNames: ReadonlySet<string>): string { | ||
| 100 | const references = /(^|\s)\$([^\s]+)(?=\s|$)/g; | ||
| 101 | const found: Array<{ name: string; start: number; end: number }> = []; | ||
| 102 | for (const match of text.matchAll(references)) { | ||
| 103 | const name = match[2]; | ||
| 104 | if (name === undefined || !skillNames.has(name) || match.index === undefined) continue; | ||
| 105 | const tokenStart = match.index + (match[1]?.length ?? 0); | ||
| 106 | found.push({ name, start: tokenStart, end: tokenStart + name.length + 1 }); | ||
| 107 | } | ||
| 108 | if (found.length === 0) return text; | ||
| 109 | |||
| 110 | const orderedNames: string[] = []; | ||
| 111 | const seen = new Set<string>(); | ||
| 112 | for (const token of found) { | ||
| 113 | if (seen.has(token.name)) continue; | ||
| 114 | seen.add(token.name); | ||
| 115 | orderedNames.push(token.name); | ||
| 116 | } | ||
| 117 | |||
| 118 | let body = text; | ||
| 119 | for (let index = found.length - 1; index >= 0; index -= 1) { | ||
| 120 | const token = found[index]; | ||
| 121 | if (token === undefined) continue; | ||
| 122 | body = `${body.slice(0, token.start)}${body.slice(token.end)}`; | ||
| 123 | } | ||
| 124 | body = body.trim(); | ||
| 125 | const prefix = orderedNames.map((name) => `/skill:${name}`).join(" "); | ||
| 126 | return body.length === 0 ? prefix : `${prefix} ${body}`; | ||
| 127 | } | ||
| 128 | |||
| 129 | function recordField(input: unknown, key: string): unknown { | 94 | function recordField(input: unknown, key: string): unknown { |
| 130 | return Predicate.isObject(input) ? input[key] : undefined; | 95 | return Predicate.isObject(input) ? input[key] : undefined; |
| 131 | } | 96 | } |
packages/provider-pi/src/server/mcpExtensionSource.test.ts+146-3| ... | @@ -1,3 +1,7 @@ | ... | @@ -1,3 +1,7 @@ |
| 1 | // @effect-diagnostics nodeBuiltinImport:off -- Pi extensions run outside Effect; these tests exercise their native filesystem boundary. | ||
| 2 | import * as NodeFSP from "node:fs/promises"; | ||
| 3 | import * as NodePath from "node:path"; | ||
| 4 | import * as NodeOS from "node:os"; | ||
| 1 | import * as NodeModule from "node:module"; | 5 | import * as NodeModule from "node:module"; |
| 2 | import * as NodeVM from "node:vm"; | 6 | import * as NodeVM from "node:vm"; |
| 3 | import { assert, describe, it } from "@effect/vitest"; | 7 | import { assert, describe, it } from "@effect/vitest"; |
| ... | @@ -9,6 +13,40 @@ type RequestHook = ( | ... | @@ -9,6 +13,40 @@ type RequestHook = ( |
| 9 | ctx: { model: { provider: string } }, | 13 | ctx: { model: { provider: string } }, |
| 10 | ) => Record<string, unknown> | undefined; | 14 | ) => Record<string, unknown> | undefined; |
| 11 | 15 | ||
| 16 | interface SkillCommand { | ||
| 17 | readonly name: string; | ||
| 18 | readonly source: string; | ||
| 19 | readonly sourceInfo: { readonly path: string }; | ||
| 20 | } | ||
| 21 | |||
| 22 | type InputHook = ( | ||
| 23 | event: { text: string; images?: ReadonlyArray<unknown> }, | ||
| 24 | ctx: { ui: { notify: (message: string, level: string) => void } }, | ||
| 25 | ) => Promise<{ action: string; text: string; images?: ReadonlyArray<unknown> } | undefined>; | ||
| 26 | |||
| 27 | async function loadHooks(commands: ReadonlyArray<SkillCommand> = []) { | ||
| 28 | const handlers = new Map<string, unknown>(); | ||
| 29 | // Execute the shipped extension with MCP disabled; this path needs no Typebox. | ||
| 30 | const source = NodeModule.stripTypeScriptTypes( | ||
| 31 | PI_T3_MCP_EXTENSION_SOURCE.replace(/^import .*;$/gm, "").replace( | ||
| 32 | "export default async function", | ||
| 33 | "async function", | ||
| 34 | ), | ||
| 35 | ); | ||
| 36 | await NodeVM.runInNewContext(`${source}\nt3McpExtension(pi)`, { | ||
| 37 | process: { env: {} }, | ||
| 38 | NodeFSP, | ||
| 39 | NodePath, | ||
| 40 | // Frontmatter parsing belongs to Pi. These fixtures contain only skill bodies. | ||
| 41 | stripFrontmatter: (content: string) => content, | ||
| 42 | pi: { | ||
| 43 | on: (name: string, handler: unknown) => handlers.set(name, handler), | ||
| 44 | getCommands: () => commands, | ||
| 45 | }, | ||
| 46 | }); | ||
| 47 | return handlers; | ||
| 48 | } | ||
| 49 | |||
| 12 | interface RegisteredTool { | 50 | interface RegisteredTool { |
| 13 | readonly name: string; | 51 | readonly name: string; |
| 14 | readonly description: string; | 52 | readonly description: string; |
| ... | @@ -55,7 +93,7 @@ async function loadMcpBridge( | ... | @@ -55,7 +93,7 @@ async function loadMcpBridge( |
| 55 | { name: "preview_snapshot", description: "Inspect the collaborative browser." }, | 93 | { name: "preview_snapshot", description: "Inspect the collaborative browser." }, |
| 56 | ].map((tool) => ({ ...tool, inputSchema: { type: "object", properties: {} } })); | 94 | ].map((tool) => ({ ...tool, inputSchema: { type: "object", properties: {} } })); |
| 57 | const source = NodeModule.stripTypeScriptTypes( | 95 | const source = NodeModule.stripTypeScriptTypes( |
| 58 | PI_T3_MCP_EXTENSION_SOURCE.replace('import { Type } from "typebox";', "").replace( | 96 | PI_T3_MCP_EXTENSION_SOURCE.replace(/^import .*;$/gm, "").replace( |
| 59 | "export default async function", | 97 | "export default async function", |
| 60 | "async function", | 98 | "async function", |
| 61 | ), | 99 | ), |
| ... | @@ -271,7 +309,7 @@ describe("Pi tool discovery permissions", () => { | ... | @@ -271,7 +309,7 @@ describe("Pi tool discovery permissions", () => { |
| 271 | let toolCall: ToolCallHook | undefined; | 309 | let toolCall: ToolCallHook | undefined; |
| 272 | let searchPath = "builtin:tool-search"; | 310 | let searchPath = "builtin:tool-search"; |
| 273 | const source = NodeModule.stripTypeScriptTypes( | 311 | const source = NodeModule.stripTypeScriptTypes( |
| 274 | PI_T3_MCP_EXTENSION_SOURCE.replace('import { Type } from "typebox";', "").replace( | 312 | PI_T3_MCP_EXTENSION_SOURCE.replace(/^import .*;$/gm, "").replace( |
| 275 | "export default async function", | 313 | "export default async function", |
| 276 | "async function", | 314 | "async function", |
| 277 | ), | 315 | ), |
| ... | @@ -315,7 +353,7 @@ async function loadRequestHook(): Promise<RequestHook> { | ... | @@ -315,7 +353,7 @@ async function loadRequestHook(): Promise<RequestHook> { |
| 315 | const handlers = new Map<string, RequestHook>(); | 353 | const handlers = new Map<string, RequestHook>(); |
| 316 | // Execute the shipped extension with MCP disabled; this path needs no Typebox. | 354 | // Execute the shipped extension with MCP disabled; this path needs no Typebox. |
| 317 | const source = NodeModule.stripTypeScriptTypes( | 355 | const source = NodeModule.stripTypeScriptTypes( |
| 318 | PI_T3_MCP_EXTENSION_SOURCE.replace('import { Type } from "typebox";', "").replace( | 356 | PI_T3_MCP_EXTENSION_SOURCE.replace(/^import .*;$/gm, "").replace( |
| 319 | "export default async function", | 357 | "export default async function", |
| 320 | "async function", | 358 | "async function", |
| 321 | ), | 359 | ), |
| ... | @@ -359,3 +397,108 @@ describe("Pi upstream output-budget workaround", () => { | ... | @@ -359,3 +397,108 @@ describe("Pi upstream output-budget workaround", () => { |
| 359 | ); | 397 | ); |
| 360 | }); | 398 | }); |
| 361 | }); | 399 | }); |
| 400 | |||
| 401 | async function loadInputHook(commands: ReadonlyArray<SkillCommand>) { | ||
| 402 | const handlers = await loadHooks(commands); | ||
| 403 | const hook = handlers.get("input"); | ||
| 404 | assert.isDefined(hook); | ||
| 405 | return hook as InputHook; | ||
| 406 | } | ||
| 407 | |||
| 408 | describe("Pi skill references", () => { | ||
| 409 | it("loads every selected skill once while preserving inline prose, whitespace, and images", async () => { | ||
| 410 | const directory = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "pi-skill-mentions-")); | ||
| 411 | try { | ||
| 412 | const alpha = NodePath.join(directory, "alpha.md"); | ||
| 413 | const beta = NodePath.join(directory, "beta.md"); | ||
| 414 | await NodeFSP.writeFile(alpha, "ALPHA_INSTRUCTIONS"); | ||
| 415 | await NodeFSP.writeFile(beta, "BETA_INSTRUCTIONS"); | ||
| 416 | const hook = await loadInputHook([ | ||
| 417 | { name: "skill:alpha", source: "skill", sourceInfo: { path: alpha } }, | ||
| 418 | { name: "skill:beta", source: "skill", sourceInfo: { path: beta } }, | ||
| 419 | ]); | ||
| 420 | const text = | ||
| 421 | "Please use the $alpha philosophy, then $beta and $alpha\n```ts\n const x = 1;\n```"; | ||
| 422 | const images = [{ type: "image", data: "fixture" }]; | ||
| 423 | const result = await hook({ text, images }, { ui: { notify: assert.fail } }); | ||
| 424 | assert.equal(result?.action, "transform"); | ||
| 425 | assert.isTrue(result?.text.startsWith(text + "\n\n")); | ||
| 426 | assert.equal(result?.text.split("ALPHA_INSTRUCTIONS").length, 2); | ||
| 427 | assert.equal(result?.text.split("BETA_INSTRUCTIONS").length, 2); | ||
| 428 | assert.include(result?.text ?? "", `References are relative to ${directory}.`); | ||
| 429 | assert.strictEqual(result?.images, images); | ||
| 430 | } finally { | ||
| 431 | await NodeFSP.rm(directory, { recursive: true }); | ||
| 432 | } | ||
| 433 | }); | ||
| 434 | |||
| 435 | it("leaves unknown references and native skill commands for Pi", async () => { | ||
| 436 | const hook = await loadInputHook([ | ||
| 437 | { name: "skill:alpha", source: "skill", sourceInfo: { path: "/unused" } }, | ||
| 438 | ]); | ||
| 439 | // Punctuation-adjacent references are plain text in the composer, not selected chips. | ||
| 440 | for (const text of [ | ||
| 441 | "Explain $HOME", | ||
| 442 | "/skill:alpha use $alpha", | ||
| 443 | "Hello", | ||
| 444 | "$missing", | ||
| 445 | "Use $alpha, then continue", | ||
| 446 | "Use ($alpha)", | ||
| 447 | ]) { | ||
| 448 | assert.isUndefined(await hook({ text }, { ui: { notify: assert.fail } })); | ||
| 449 | } | ||
| 450 | }); | ||
| 451 | |||
| 452 | it("loads additional chips without duplicating a leading native skill", async () => { | ||
| 453 | const directory = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "pi-skill-mentions-")); | ||
| 454 | try { | ||
| 455 | const path = NodePath.join(directory, "beta.md"); | ||
| 456 | await NodeFSP.writeFile(path, "BETA_INSTRUCTIONS"); | ||
| 457 | const hook = await loadInputHook([ | ||
| 458 | { name: "skill:alpha", source: "skill", sourceInfo: { path: "/unused" } }, | ||
| 459 | { name: "skill:beta", source: "skill", sourceInfo: { path } }, | ||
| 460 | ]); | ||
| 461 | const text = "/skill:alpha use $alpha and $beta"; | ||
| 462 | const result = await hook({ text }, { ui: { notify: assert.fail } }); | ||
| 463 | assert.isTrue(result?.text.startsWith(text + "\n\n")); | ||
| 464 | assert.notInclude(result?.text ?? "", '<skill name="alpha"'); | ||
| 465 | assert.include(result?.text ?? "", "BETA_INSTRUCTIONS"); | ||
| 466 | } finally { | ||
| 467 | await NodeFSP.rm(directory, { recursive: true }); | ||
| 468 | } | ||
| 469 | }); | ||
| 470 | |||
| 471 | it("reports an unreadable skill without deleting its reference or other selected instructions", async () => { | ||
| 472 | const directory = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "pi-skill-mentions-")); | ||
| 473 | try { | ||
| 474 | const path = NodePath.join(directory, "readable.md"); | ||
| 475 | await NodeFSP.writeFile(path, "READABLE_INSTRUCTIONS"); | ||
| 476 | const hook = await loadInputHook([ | ||
| 477 | { | ||
| 478 | name: "skill:missing", | ||
| 479 | source: "skill", | ||
| 480 | sourceInfo: { path: NodePath.join(directory, "missing.md") }, | ||
| 481 | }, | ||
| 482 | { name: "skill:readable", source: "skill", sourceInfo: { path } }, | ||
| 483 | ]); | ||
| 484 | const notices: string[] = []; | ||
| 485 | const text = "Use $missing and $readable"; | ||
| 486 | const result = await hook( | ||
| 487 | { text }, | ||
| 488 | { | ||
| 489 | ui: { | ||
| 490 | notify: (message) => { | ||
| 491 | notices.push(message); | ||
| 492 | }, | ||
| 493 | }, | ||
| 494 | }, | ||
| 495 | ); | ||
| 496 | assert.isTrue(result?.text.startsWith(text + "\n\n")); | ||
| 497 | assert.include(result?.text ?? "", "READABLE_INSTRUCTIONS"); | ||
| 498 | assert.equal(notices.length, 1); | ||
| 499 | assert.include(notices[0] ?? "", "Could not load skill missing"); | ||
| 500 | } finally { | ||
| 501 | await NodeFSP.rm(directory, { recursive: true }); | ||
| 502 | } | ||
| 503 | }); | ||
| 504 | }); |
packages/provider-pi/src/server/mcpExtensionSource.ts+35-1| ... | @@ -23,7 +23,9 @@ export const T3_PI_RUNTIME_MODE_ENV = "T3_PI_RUNTIME_MODE"; | ... | @@ -23,7 +23,9 @@ export const T3_PI_RUNTIME_MODE_ENV = "T3_PI_RUNTIME_MODE"; |
| 23 | export const PI_FILE_CHANGE_TOOLS = ["edit", "write"] as const; | 23 | export const PI_FILE_CHANGE_TOOLS = ["edit", "write"] as const; |
| 24 | 24 | ||
| 25 | export const PI_T3_MCP_EXTENSION_SOURCE = `\ | 25 | export const PI_T3_MCP_EXTENSION_SOURCE = `\ |
| 26 | import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; | 26 | import { stripFrontmatter, type ExtensionAPI } from "@earendil-works/pi-coding-agent"; |
| 27 | import * as NodeFSP from "node:fs/promises"; | ||
| 28 | import * as NodePath from "node:path"; | ||
| 27 | import { Type } from "typebox"; | 29 | import { Type } from "typebox"; |
| 28 | 30 | ||
| 29 | const URL_ENV = ${JSON.stringify(T3_MCP_URL_ENV)}; | 31 | const URL_ENV = ${JSON.stringify(T3_MCP_URL_ENV)}; |
| ... | @@ -210,6 +212,38 @@ function createMcpClient(endpoint: string, token: string) { | ... | @@ -210,6 +212,38 @@ function createMcpClient(endpoint: string, token: string) { |
| 210 | } | 212 | } |
| 211 | 213 | ||
| 212 | export default async function t3McpExtension(pi: ExtensionAPI) { | 214 | export default async function t3McpExtension(pi: ExtensionAPI) { |
| 215 | // Keep skill chips in the request. Pi expands only one leading /skill: | ||
| 216 | // command, so use its own frontmatter loader for every selected chip here. | ||
| 217 | pi.on("input", async (event, ctx) => { | ||
| 218 | if (!event.text.includes("$")) return; | ||
| 219 | const commands = pi.getCommands().filter((command) => command.source === "skill"); | ||
| 220 | const nativeSkill = /^\\/skill:([^ ]+)(?: |$)/.exec(event.text)?.[1]; | ||
| 221 | const seen = new Set<string>(nativeSkill === undefined ? [] : [nativeSkill]); | ||
| 222 | const blocks: string[] = []; | ||
| 223 | for (const match of event.text.matchAll(/(^|\\s)\\$([^\\s]+)(?=\\s|$)/g)) { | ||
| 224 | const name = match[2]; | ||
| 225 | if (name === undefined || seen.has(name)) continue; | ||
| 226 | const command = commands.find((candidate) => candidate.name === "skill:" + name); | ||
| 227 | if (command === undefined) continue; | ||
| 228 | seen.add(name); | ||
| 229 | const path = command.sourceInfo.path; | ||
| 230 | try { | ||
| 231 | const body = stripFrontmatter(await NodeFSP.readFile(path, "utf8")).trim(); | ||
| 232 | blocks.push( | ||
| 233 | \`<skill name="\${name}" location="\${path}">\\nReferences are relative to \${NodePath.dirname(path)}.\\n\\n\${body}\\n</skill>\`, | ||
| 234 | ); | ||
| 235 | } catch { | ||
| 236 | ctx.ui.notify(\`Could not load skill \${name} from \${path}.\`, "error"); | ||
| 237 | } | ||
| 238 | } | ||
| 239 | if (blocks.length === 0) return; | ||
| 240 | return { | ||
| 241 | action: "transform", | ||
| 242 | text: event.text + "\\n\\n" + blocks.join("\\n\\n"), | ||
| 243 | images: event.images, | ||
| 244 | }; | ||
| 245 | }); | ||
| 246 | |||
| 213 | // Workaround for an upstream Pi context-budgeting bug: pi-ai reuses the | 247 | // Workaround for an upstream Pi context-budgeting bug: pi-ai reuses the |
| 214 | // previous response's usage even when a fork's instructions/tools differ, | 248 | // previous response's usage even when a fork's instructions/tools differ, |
| 215 | // then reserves almost all remaining context for output. OpenRouter can | 249 | // then reserves almost all remaining context for output. OpenRouter can |