RPC Modu
RPC modu, kodlama aracısının stdin/stdout üzerinden JSON protokolü aracılığıyla başsız çalışmasını sağlar. Bu, aracıyı diğer uygulamalara, IDE'lere veya özel kullanıcı arayüzlerine gömmek için kullanışlıdır.
Node.js/TypeScript kullanıcıları için not: Bir Node.js uygulaması oluşturuyorsanız, bir alt süreç oluşturmak yerine doğrudan @earendil-works/pi-coding-agent'den AgentSession kullanmayı düşünün. API için src/core/agent-session.ts'ye bakın. Alt süreç tabanlı bir TypeScript istemcisi için bkz. src/modes/rpc/rpc-client.ts.
RPC Modu Başlatılıyor
pi --mode rpc [options]Ortak seçenekler:
--provider <name>: LLM sağlayıcısını ayarlayın (antropik, openai, google vb.)--model <pattern>: Model deseni veya kimliği (provider/idve isteğe bağlı:<thinking>'yi destekler)--name <name>/-n <name>: Başlangıçta oturumun görünen adını ayarlayın--no-session: Oturum kalıcılığını devre dışı bırak--session-dir <path>: Özel oturum depolama dizini
Protokole Genel Bakış
- Komutlar: stdin'ye gönderilen JSON nesneler, her satıra bir tane
- Yanıtlar: JSON komut başarısını/başarısızlığını gösteren
type: "response"içeren nesneler - Olaylar: Aracı etkinlikleri stdout'ye JSON satır olarak aktarılır
Tüm komutlar istek/yanıt korelasyonu için isteğe bağlı bir id alanını destekler. Sağlanırsa ilgili yanıt aynı id'yi içerecektir. bash_execution_update olayları aynı zamanda kaynak bash komutunun id'sini de içerir.
Çerçeveleme
RPC modu, tek kayıt sınırlayıcı olarak LF (\n) ile katı JSONL anlambilimini kullanır.
Bu müşteriler için önemlidir:
- Kayıtları yalnızca
\n'de bölme - Sondaki
\röğesini çıkararak isteğe bağlı\r\ngirişini kabul edin - Unicode ayırıcılara yeni satır muamelesi yapan genel satır okuyucuları kullanmayın
Özellikle, readline Düğümü RPC modu için protokolle uyumlu değildir çünkü aynı zamanda JSON dizeleri içinde geçerli olan U+2028 ve U+2029 üzerinde de bölünür.
Komutlar
İsteme
çabuk
Temsilciye bir kullanıcı istemi gönderin. Komut yanıtı, istem kabul edildikten, kuyruğa alındıktan veya işlendikten sonra gönderilir. Etkinlikler kabul edildikten sonra eşzamansız olarak yayınlanmaya devam eder.
{"id": "req-1", "type": "prompt", "message": "Hello, world!"}Resimlerle:
{"type": "prompt", "message": "What's in this image?", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}Akış sırasında: Aracı zaten akış gerçekleştiriyorsa, mesajı sıraya koymak için streamingBehavior belirtmelisiniz:
{"type": "prompt", "message": "New instruction", "streamingBehavior": "steer"}"steer": Aracı çalışırken mesajı sıraya alın. Mevcut asistan sırasının takım çağrılarını yürütmeyi bitirmesinden sonra, bir sonraki LLM çağrısından önce teslim edilir."followUp": Temsilcinin işi bitene kadar bekleyin. Mesaj yalnızca aracı durduğunda iletilir.
Aracı akış halindeyse ve streamingBehavior belirtilmemişse komut bir hata döndürür.
Uzantı komutları: Mesaj bir uzantı komutuysa (ör. /mycommand), akış sırasında bile hemen yürütülür. Uzantı komutları kendi LLM etkileşimlerini pi.sendMessage() aracılığıyla yönetir.
Giriş genişletme: Beceri komutları (/skill:name) ve prompt templates (/template) göndermeden/kuyruğa almadan önce genişletilir.
Cevap:
{"id": "req-1", "type": "response", "command": "prompt", "success": true}success: true istemin hemen kabul edildiği, kuyruğa alındığı veya işlendiği anlamına gelir. success: false istemin kabul edilmeden önce reddedildiği anlamına gelir. Kabulden sonraki hatalar, aynı istek kimliği için ikinci bir response olarak değil, normal olay ve mesaj akışı aracılığıyla raporlanır.
images alanı isteğe bağlıdır. Her resim ImageContent biçimini kullanır: {"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}.
yönlendirmek
Temsilci çalışırken bir yönlendirme mesajını kuyruğa alın. Mevcut asistan sırasının takım çağrılarını yürütmeyi bitirmesinden sonra, bir sonraki LLM çağrısından önce teslim edilir. Beceri komutları ve prompt templates genişletildi. Uzantı komutlarına izin verilmez (bunun yerine prompt kullanın).
{"type": "steer", "message": "Stop and do this instead"}Resimlerle:
{"type": "steer", "message": "Look at this instead", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}images alanı isteğe bağlıdır. Her görsel ImageContent formatını kullanır (prompt ile aynı).
Cevap:
{"type": "response", "command": "steer", "success": true}Yönlendirme mesajlarının nasıl işlendiğini kontrol etmek için set_steering_mode'ye bakın.
takip etmek
Temsilci işini bitirdikten sonra işlenecek bir takip mesajını sıraya koyun. Yalnızca temsilcinin artık araç çağrısı veya yönlendirme mesajı kalmadığında teslim edilir. Beceri komutları ve prompt templates genişletildi. Uzantı komutlarına izin verilmez (bunun yerine prompt kullanın).
{"type": "follow_up", "message": "After you're done, also do this"}Resimlerle:
{"type": "follow_up", "message": "Also check this image", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}images alanı isteğe bağlıdır. Her görsel ImageContent formatını kullanır (prompt ile aynı).
Cevap:
{"type": "response", "command": "follow_up", "success": true}Takip mesajlarının nasıl işlendiğini kontrol etmek için set_follow_up_mode'ye bakın.
iptal etmek
Geçerli aracı işlemini iptal edin.
{"type": "abort"}Cevap:
{"type": "response", "command": "abort", "success": true}yeni_session
Yeni bir oturum başlatın. session_before_switch eklenti olay işleyicisi tarafından iptal edilebilir.
{"type": "new_session"}İsteğe bağlı ebeveyn oturumu takibiyle:
{"type": "new_session", "parentSession": "/path/to/parent-session.jsonl"}Cevap:
{"type": "response", "command": "new_session", "success": true, "data": {"cancelled": false}}Bir uzatma iptal edilirse:
{"type": "response", "command": "new_session", "success": true, "data": {"cancelled": true}}Durum
get_state
Geçerli oturum durumunu alın.
{"type": "get_state"}Cevap:
{
"type": "response",
"command": "get_state",
"success": true,
"data": {
"model": {...},
"thinkingLevel": "medium",
"isStreaming": false,
"isCompacting": false,
"steeringMode": "all",
"followUpMode": "one-at-a-time",
"sessionFile": "/path/to/session.jsonl",
"sessionId": "abc123",
"sessionName": "my-feature-work",
"autoCompactionEnabled": true,
"messageCount": 5,
"pendingMessageCount": 0
}
}model alanı tam bir Model nesnesi veya null'dir. sessionName alanı, set_session_name aracılığıyla ayarlanan görünen addır veya ayarlanmadıysa atlanır.
get_messages
Konuşmadaki tüm mesajları alın.
{"type": "get_messages"}Cevap:
{
"type": "response",
"command": "get_messages",
"success": true,
"data": {"messages": [...]}
}Mesajlar AgentMessage nesnelerdir (bkz. Message Types).
Modeli
set_model
Belirli bir modele geçin.
{"type": "set_model", "provider": "anthropic", "modelId": "claude-sonnet-4-20250514"}Yanıt tam Model nesnesini içeriyor:
{
"type": "response",
"command": "set_model",
"success": true,
"data": {...}
}döngü_modeli
Bir sonraki mevcut modele geçin. Yalnızca bir model mevcutsa null verisini döndürür.
{"type": "cycle_model"}Cevap:
{
"type": "response",
"command": "cycle_model",
"success": true,
"data": {
"model": {...},
"thinkingLevel": "medium",
"isScoped": false
}
}model alanı tam bir Model nesnesidir.
get_available_models
Yapılandırılmış tüm modelleri listeleyin.
{"type": "get_available_models"}Yanıt, tam Model nesnelerden oluşan bir dizi içerir:
{
"type": "response",
"command": "get_available_models",
"success": true,
"data": {
"models": [...]
}
}Düşünme
set_thinking_level
Onu destekleyen modeller için akıl yürütme/düşünme düzeyini ayarlayın.
{"type": "set_thinking_level", "level": "high"}Seviyeler: "off", "minimal", "low", "medium", "high", "xhigh", "max"
"xhigh" ve "max" yalnızca seçilen model tarafından desteklendiğinde gösterilir. GPT-5.6 dahil bazı modeller her ikisini de gösterir.
Cevap:
{"type": "response", "command": "set_thinking_level", "success": true}cycle_thinking_level
Mevcut düşünme seviyeleri arasında geçiş yapın. Model düşünmeyi desteklemiyorsa null veriyi döndürür.
{"type": "cycle_thinking_level"}Cevap:
{
"type": "response",
"command": "cycle_thinking_level",
"success": true,
"data": {"level": "high"}
}get_available_thinking_levels
Mevcut modelin desteklediği düşünme düzeylerini listeleyiniz. Akıl yürütme desteği olmayan bir model için ["off"] değerini döndürür.
{"type": "get_available_thinking_levels"}Cevap:
{
"type": "response",
"command": "get_available_thinking_levels",
"success": true,
"data": {
"levels": ["off", "minimal", "low", "medium", "high"]
}
}Kuyruk Modları
set_steering_mode
Yönlendirme mesajlarının (steer'den itibaren) nasıl iletildiğini kontrol edin.
{"type": "set_steering_mode", "mode": "one-at-a-time"}Modlar:
"all": Mevcut asistan dönüşü araç çağrılarını yürütmeyi tamamladıktan sonra tüm direksiyon mesajlarını iletin"one-at-a-time": Tamamlanan asistan turu başına bir direksiyon mesajı gönderin (varsayılan)
Cevap:
{"type": "response", "command": "set_steering_mode", "success": true}set_follow_up_mode
Takip mesajlarının (follow_up'den itibaren) nasıl teslim edildiğini kontrol edin.
{"type": "set_follow_up_mode", "mode": "one-at-a-time"}Modlar:
"all": Temsilci işini bitirdiğinde tüm takip mesajlarını ilet"one-at-a-time": Temsilci tamamlandığında bir takip mesajı gönderin (varsayılan)
Cevap:
{"type": "response", "command": "set_follow_up_mode", "success": true}Sıkıştırma
kompakt
Belirteç kullanımını azaltmak için konuşma içeriğini manuel olarak sıkıştırın.
{"type": "compact"}Özel talimatlarla:
{"type": "compact", "customInstructions": "Focus on code changes"}Cevap:
{
"type": "response",
"command": "compact",
"success": true,
"data": {
"summary": "Summary of conversation...",
"firstKeptEntryId": "abc123",
"tokensBefore": 150000,
"estimatedTokensAfter": 32000,
"usage": {
"input": 32000,
"output": 1200,
"cacheRead": 0,
"cacheWrite": 0,
"totalTokens": 33200,
"cost": {"input": 0.01, "output": 0.02, "cacheRead": 0, "cacheWrite": 0, "total": 0.03}
},
"details": {}
}
}estimatedTokensAfter, sağlayıcının tam belirteç sayısı değil, sıkıştırmanın hemen ardından yeniden oluşturulan mesaj bağlamı üzerinden yapılan buluşsal bir tahmindir. usage LLM çağrısını veya özeti oluşturan çağrıları bildirir ve özel sıkıştırma işleyicileri tarafından göz ardı edilebilir.
set_auto_compaction
Bağlam dolmaya yaklaştığında otomatik sıkıştırmayı etkinleştirin veya devre dışı bırakın.
{"type": "set_auto_compaction", "enabled": true}Cevap:
{"type": "response", "command": "set_auto_compaction", "success": true}Yeniden dene
set_auto_retry
Geçici hatalarda (aşırı yük, hız sınırı, 5xx) otomatik yeniden denemeyi etkinleştirin veya devre dışı bırakın.
{"type": "set_auto_retry", "enabled": true}Cevap:
{"type": "response", "command": "set_auto_retry", "success": true}iptal_yeniden dene
Devam eden bir yeniden denemeyi iptal edin (gecikmeyi iptal edin ve yeniden denemeyi durdurun).
{"type": "abort_retry"}Cevap:
{"type": "response", "command": "abort_retry", "success": true}Bash
bash
Bir kabuk komutunu yürütün ve çıktıyı konuşma bağlamına ekleyin. Komut çalışırken akışların çıktısını bash_execution_update olaylar olarak alın; yanıt nihai sonucu içerir.
{"id": "req-1", "type": "bash", "command": "ls -la"}Akışlı bash_execution_update olaylarını bu komutla ilişkilendirmek için bir id ekleyin.
Cevap:
{
"id": "req-1",
"type": "response",
"command": "bash",
"success": true,
"data": {
"output": "total 48\ndrwxr-xr-x ...",
"exitCode": 0,
"cancelled": false,
"truncated": false
}
}Çıktı kesilmişse fullOutputPath şunları içerir:
{
"type": "response",
"command": "bash",
"success": true,
"data": {
"output": "truncated output...",
"exitCode": 0,
"cancelled": false,
"truncated": true,
"fullOutputPath": "/tmp/pi-bash-abc123.log"
}
}bash sonuçları LLM'ye nasıl ulaşır:
bash komutu hemen yürütülür ve BashResult değerini döndürür. Dahili olarak, aracının mesaj durumunda bir BashExecutionMessage oluşturulur ve saklanır.
Bir sonraki prompt komutu gönderildiğinde, tüm mesajlar (BashExecutionMessage dahil) LLM'ye gönderilmeden önce dönüştürülür. BashExecutionMessage şu formatla UserMessage'ye dönüştürülür:
Ran `ls -la`
```
toplam 48
drwxr-xr-x...
```Bu şu anlama gelir:
- Bash çıktısı LLM bağlamına hemen değil, sonraki komut isteminde dahil edilir
- Bir istemden önce birden fazla bash komutu yürütülebilir; tüm çıktılar dahil edilecek
iptal_bash
Çalışan bir bash komutunu iptal edin.
{"type": "abort_bash"}Cevap:
{"type": "response", "command": "abort_bash", "success": true}Oturum
get_session_stats
Belirteç kullanımını, maliyet istatistiklerini ve mevcut bağlam penceresi kullanımını alın.
{"type": "get_session_stats"}Cevap:
{
"type": "response",
"command": "get_session_stats",
"success": true,
"data": {
"sessionFile": "/path/to/session.jsonl",
"sessionId": "abc123",
"userMessages": 5,
"assistantMessages": 5,
"toolCalls": 12,
"toolResults": 12,
"totalMessages": 22,
"tokens": {
"input": 50000,
"output": 10000,
"cacheRead": 40000,
"cacheWrite": 5000,
"total": 105000
},
"cost": 0.45,
"contextUsage": {
"tokens": 60000,
"contextWindow": 200000,
"percent": 30
}
}
}tokens ve cost tüm oturum boyunca asistan mesajlarını, araçlar tarafından bildirilen kullanımı ve sıkıştırma/dal özeti oluşturmayı içerir. contextUsage sıkıştırma ve alt bilgi ekranı için kullanılan gerçek geçerli bağlam penceresi tahminini içerir.
Hiçbir model veya bağlam penceresi mevcut olmadığında contextUsage atlanır. contextUsage.tokens ve contextUsage.percent, yeni bir sıkıştırma sonrası asistanının yanıtı geçerli kullanım verileri sağlayana kadar sıkıştırmadan hemen sonra null'dir.
ihracat_html
Oturumu bir HTML dosyasına aktarın.
{"type": "export_html"}Özel yol ile:
{"type": "export_html", "outputPath": "/tmp/session.html"}Cevap:
{
"type": "response",
"command": "export_html",
"success": true,
"data": {"path": "/tmp/session.html"}
}switch_session
Farklı bir oturum dosyası yükleyin. session_before_switch eklenti olay işleyicisi tarafından iptal edilebilir.
{"type": "switch_session", "sessionPath": "/path/to/session.jsonl"}Cevap:
{"type": "response", "command": "switch_session", "success": true, "data": {"cancelled": false}}Bir uzantının geçişi iptal etmesi durumunda:
{"type": "response", "command": "switch_session", "success": true, "data": {"cancelled": true}}çatal
Aktif daldaki önceki kullanıcı mesajından yeni bir çatal oluşturun. session_before_fork eklenti olay işleyicisi tarafından iptal edilebilir. Çatallanan mesajın metnini döndürür.
{"type": "fork", "entryId": "abc123"}Cevap:
{
"type": "response",
"command": "fork",
"success": true,
"data": {"text": "The original prompt text...", "cancelled": false}
}Bir uzantı çatalı iptal ederse:
{
"type": "response",
"command": "fork",
"success": true,
"data": {"text": "The original prompt text...", "cancelled": true}
}klon
Geçerli aktif dalı geçerli konumdaki yeni bir oturuma kopyalayın. session_before_fork eklenti olay işleyicisi tarafından iptal edilebilir.
{"type": "clone"}Cevap:
{
"type": "response",
"command": "clone",
"success": true,
"data": {"cancelled": false}
}Bir uzantı klonu iptal ederse:
{
"type": "response",
"command": "clone",
"success": true,
"data": {"cancelled": true}
}get_fork_messages
Çatallama için kullanıcı mesajlarının kullanılabilir olmasını sağlayın.
{"type": "get_fork_messages"}Cevap:
{
"type": "response",
"command": "get_fork_messages",
"success": true,
"data": {
"messages": [
{"entryId": "abc123", "text": "First prompt..."},
{"entryId": "def456", "text": "Second prompt..."}
]
}
}get_entries
Tüm oturum girişlerini ekleme sırasına göre alın (oturum başlığı hariç). Oturum, sabit kimliklere sahip yalnızca eklemeli bir giriş ağacıdır, dolayısıyla giriş kimliği dayanıklı bir imleç olarak çalışır: istemci yeniden başlatmalarında bile yalnızca ondan sonraki girişleri almak için gördüğünüz son giriş kimliğini since olarak iletin. get_messages'den farklı olarak bu, ön sıkıştırma geçmişini ve terk edilmiş dalları içerir.
{"type": "get_entries"}Bir imleçle:
{"type": "get_entries", "since": "abc123"}Cevap:
{
"type": "response",
"command": "get_entries",
"success": true,
"data": {
"entries": [
{"type": "message", "id": "def456", "parentId": "abc123", "timestamp": "...", "message": {"role": "user", "...": "..."}}
],
"leafId": "def456"
}
}leafId geçerli yaprak girişinin kimliğidir (boş bir oturum için null), böylece müşteri tek bir gidiş-dönüş yolculuğunda aktif dalın taşınıp taşınmadığını anlayabilir. since herhangi bir giriş kimliğiyle eşleşmiyorsa yanıt success: false olur.
get_tree
Oturumu bir giriş ağacı olarak alın. Her düğüm {entry, children, label?, labelTimestamp?}'dir. İyi biçimlendirilmiş bir oturumun tek bir kökü vardır; yetim girdiler (kırık ana zincir) de kök olarak görünür.
{"type": "get_tree"}Cevap:
{
"type": "response",
"command": "get_tree",
"success": true,
"data": {
"tree": [
{
"entry": {"type": "message", "id": "abc123", "parentId": null, "...": "..."},
"children": [
{"entry": {"type": "message", "id": "def456", "parentId": "abc123", "...": "..."}, "children": []}
]
}
],
"leafId": "def456"
}
}get_last_assistant_text
Son asistan mesajının metin içeriğini alın.
{"type": "get_last_assistant_text"}Cevap:
{
"type": "response",
"command": "get_last_assistant_text",
"success": true,
"data": {"text": "The assistant's response..."}
}Asistan mesajı yoksa {"text": null} değerini döndürür.
set_session_name
Geçerli oturum için bir görünen ad belirleyin. Ad, oturum listelerinde görünür ve oturumların tanımlanmasına yardımcı olur.
{"type": "set_session_name", "name": "my-feature-work"}Cevap:
{
"type": "response",
"command": "set_session_name",
"success": true
}Geçerli oturum adına sessionName alanında get_state aracılığıyla ulaşılabilir. RPC modunu başlatırken başlangıç adını ayarlamak için pi --mode rpc işlemine --name <name> veya -n <name>'yi geçin.
Komutlar
get_commands
Kullanılabilir komutları alın (uzantı komutları, prompt templates ve beceriler). Bunlar, / öneki eklenerek prompt komutu aracılığıyla çağrılabilir.
{"type": "get_commands"}Cevap:
{
"type": "response",
"command": "get_commands",
"success": true,
"data": {
"commands": [
{"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.pi/agent/extensions/session.ts"},
{"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.pi/agent/prompts/fix-tests.md"},
{"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.pi/agent/skills/brave-search/SKILL.md"}
]
}
}Her komutta şunlar bulunur:
name: Komut adı (/nameile çağırın)description: İnsanların okuyabileceği açıklama (uzantı komutları için isteğe bağlı)source: Ne tür bir komut:"extension": Bir dahili numaradapi.registerCommand()aracılığıyla kaydedildi"prompt": Bilgi istemi şablonu.mddosyasından yüklendi"skill": Bir beceri dizininden yüklendi (adın önüneskill:eklenir)
location: Nereden yüklendiği (isteğe bağlı, uzantılar için mevcut değil):"user": Kullanıcı düzeyi (~/.pi/agent/)"project": Proje düzeyinde (./.pi/agent/)"path": CLI veya ayarlar aracılığıyla açık yol
path: Komut kaynağına giden mutlak dosya yolu (isteğe bağlı)
Not: Yerleşik TUI komutları (/settings, /hotkeys vb.) dahil değildir. Yalnızca etkileşimli modda işlenirler ve prompt aracılığıyla gönderilirse yürütülmezler.
Olaylar
Aracı işlemi sırasında olaylar stdout'ye JSON satırlar halinde aktarılır. Etkinlikler genellikle id alanı içermez; bash_execution_update, sağlandığı sırada kaynak bash komutunun id'sini içerir.
Etkinlik Türleri
| Etkinlik | Tanım |
|---|---|
agent_start |
Aracı işlemeye başlıyor |
agent_end |
Bir düşük seviyeli aracı çalıştırması tamamlanır (ardından yeniden deneme, sıkıştırma veya sıraya alınmış devamlar gelebilir) |
agent_settled |
Aracı çalıştırması tamamen çözüldü; otomatik yeniden deneme, sıkıştırma yeniden denemesi veya sıraya alınmış devam durumu kalmaz |
turn_start |
Yeni dönüş başlıyor |
turn_end |
Dönüş tamamlanır (asistan mesajını ve araç sonuçlarını içerir) |
message_start |
Mesaj başlıyor |
message_update |
Akış güncellemesi (metin/düşünme/araç çağrısı deltaları) |
message_end |
Mesaj tamamlandı |
bash_execution_update |
Doğrudan RPC bash komut çıktı öbeği |
tool_execution_start |
Araç yürütülmeye başlar |
tool_execution_update |
Araç yürütme ilerlemesi (akış çıktısı) |
tool_execution_end |
Araç tamamlanır |
queue_update |
Bekleyen yönlendirme/takip kuyruğu değiştirildi |
compaction_start |
Sıkıştırma başlıyor |
compaction_end |
Sıkıştırma tamamlandı |
auto_retry_start |
Otomatik yeniden deneme başlar (geçici hatadan sonra) |
auto_retry_end |
Otomatik yeniden deneme tamamlandı (başarılı veya nihai başarısızlık) |
summarization_retry_scheduled |
Geçici sıkıştırma veya dal özeti özetleme hatası nedeniyle planlanmış yeniden deneme |
summarization_retry_attempt_start |
Yeniden denenen özetleme isteği başlıyor |
summarization_retry_finished |
Özetleme yeniden deneme döngüsü tamamlanır |
extension_error |
Uzantı bir hata verdi |
ajan_başlangıç
Aracı bir istemi işlemeye başladığında yayılır.
{"type": "agent_start"}ajan_end
Bir düşük seviyeli aracı çalıştırması tamamlandığında yayılır. Bu çalıştırma sırasında oluşturulan tüm mesajları içerir. willRetry doğruysa otomatik yeniden deneme yapılır.
{
"type": "agent_end",
"messages": [...],
"willRetry": false
}ajan_settled
Tam oturum düzeyinde çalıştırma tamamlandıktan sonra yayılır. Bu noktada Pi yeniden deneme, sıkıştırma yeniden denemesi veya sıraya alınmış takip mesajları yoluyla otomatik olarak devam etmeyecektir.
{"type": "agent_settled"}dönüş_başlangıç / dönüş_son
Bir dönüş, bir asistan yanıtının yanı sıra bunun sonucunda ortaya çıkan araç çağrıları ve sonuçlarından oluşur.
{"type": "turn_start"}{
"type": "turn_end",
"message": {...},
"toolResults": [...]
}message_start / message_end
Bir mesaj başladığında ve tamamlandığında yayılır. message alanı bir AgentMessage içerir.
{"type": "message_start", "message": {...}}
{"type": "message_end", "message": {...}}message_update (Akış)
Asistan mesajlarının akışı sırasında yayılır. Kümülatif mesaj anlık görüntüsü olmayan bir delta olayı içerir.
{
"type": "message_update",
"assistantMessageEvent": {
"type": "text_delta",
"contentIndex": 0,
"delta": "Hello "
}
}assistantMessageEvent alanı şu delta türlerinden birini içerir:
| Tip | Tanım |
|---|---|
text_start |
Metin içeriği bloğu başlatıldı |
text_delta |
Metin içeriği yığını |
text_end |
Metin içeriği bloğu sona erdi |
thinking_start |
Düşünme bloğu başladı |
thinking_delta |
İçerik yığınını düşünme |
thinking_end |
Düşünme engeli sona erdi |
toolcall_start |
Araç çağrısı başlatıldı |
toolcall_delta |
Araç çağrısı argümanları öbeği |
toolcall_end |
Araç çağrısı sona erdi (tam toolCall nesnesini içerir) |
Bir metin yanıtının akışının örneği:
{"type":"message_update","assistantMessageEvent":{"type":"text_start","contentIndex":0}}
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world"}}
{"type":"message_update","assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world"}}message_update önceki kümülatif message alanını kasıtlı olarak atlar ve
assistantMessageEvent.partial. Canlı kısmi mesaja ihtiyaç duyan istemcilerin bunu birleştirmesi gerekir
message_start'den ve contentIndex'yi kullanan sonraki olaylardan. Tedavi message_end.message
yetkili olarak. Araç çağrıları için arabellek toolcall_delta.delta; toolcall_end.toolCall
tamamlanan aramayı içerir.
bash_execution_update
Doğrudan bash komutundan her çıktı öbeği için bir kez yayılır. id komutun id ile eşleşerek istemcilerin çıktıyı doğru komutla ilişkilendirmesine olanak tanır.
Son bash yanıtının output'si kesilmiş olsa bile, komut çalışırken olaylar tüm çıktıyı yayınlar.
{
"type": "bash_execution_update",
"id": "req-1",
"delta": "total 48\n"
}tool_execution_start / tool_execution_update / tool_execution_end
Bir araç başladığında, ilerleme akışı yapıldığında ve yürütmeyi tamamladığında yayılır.
{
"type": "tool_execution_start",
"toolCallId": "call_abc123",
"toolName": "bash",
"args": {"command": "ls -la"}
}Yürütme sırasında, tool_execution_update olayları kısmi sonuçların akışını sağlar (örneğin, bash geldiğinde çıktı):
{
"type": "tool_execution_update",
"toolCallId": "call_abc123",
"toolName": "bash",
"args": {"command": "ls -la"},
"partialResult": {
"content": [{"type": "text", "text": "partial output so far..."}],
"details": {"truncation": null, "fullOutputPath": null}
}
}Tamamlandığında:
{
"type": "tool_execution_end",
"toolCallId": "call_abc123",
"toolName": "bash",
"result": {
"content": [{"type": "text", "text": "total 48\n..."}],
"details": {...}
},
"isError": false
}Olayları ilişkilendirmek için toolCallId tuşunu kullanın. tool_execution_update'deki partialResult, o ana kadar biriken çıktıyı içerir (yalnızca deltayı değil), istemcilerin her güncellemede ekranlarını kolayca değiştirmelerine olanak tanır.
kuyruk_update
Bekleyen yönlendirme veya takip kuyruğu değiştiğinde yayılır.
{
"type": "queue_update",
"steering": ["Focus on error handling"],
"followUp": ["After that, summarize the result"]
}sıkıştırma_başlangıç / sıkıştırma_son
İster manuel ister otomatik olsun, sıkıştırma çalıştırıldığında yayılır.
{"type": "compaction_start", "reason": "threshold"}reason alanı "manual", "threshold" veya "overflow"'dir.
{
"type": "compaction_end",
"reason": "threshold",
"result": {
"summary": "Summary of conversation...",
"firstKeptEntryId": "abc123",
"tokensBefore": 150000,
"estimatedTokensAfter": 32000,
"usage": {
"input": 32000,
"output": 1200,
"cacheRead": 0,
"cacheWrite": 0,
"totalTokens": 33200,
"cost": {"input": 0.01, "output": 0.02, "cacheRead": 0, "cacheWrite": 0, "total": 0.03}
},
"details": {}
},
"aborted": false,
"willRetry": false
}reason, "overflow" ise ve sıkıştırma başarılı olursa, willRetry, true olur ve aracı, istemi otomatik olarak yeniden deneyecektir.
Sıkıştırma iptal edildiyse, result, null ve aborted, true olur.
Sıkıştırma başarısız olursa (örneğin, API kota aşıldı), result null'dir, aborted false'dir ve errorMessage hata açıklamasını içerir.
auto_retry_start / auto_retry_end
Geçici bir hatanın (aşırı yük, hız limiti, 5xx) ardından otomatik yeniden deneme tetiklendiğinde ortaya çıkar.
{
"type": "auto_retry_start",
"attempt": 1,
"maxAttempts": 3,
"delayMs": 2000,
"errorMessage": "529 {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"}}"
}{
"type": "auto_retry_end",
"success": true,
"attempt": 2
}Nihai başarısızlık durumunda (maksimum yeniden deneme sayısı aşıldı):
{
"type": "auto_retry_end",
"success": false,
"attempt": 3,
"finalError": "529 overloaded_error: Overloaded"
}summarization_retry_scheduled / summarization_retry_attempt_start / summarization_retry_finished
Sıkıştırma veya dal özeti özetleme, geçici bir sağlayıcı hatasından sonra yeniden denendiğinde ortaya çıkar. Bu olaylar, otomatik asistan dönüşü yeniden denemeleriyle aynı yeniden deneme ayarlarını kullanır.
{
"type": "summarization_retry_scheduled",
"attempt": 1,
"maxAttempts": 3,
"delayMs": 2000,
"errorMessage": "terminated"
}{
"type": "summarization_retry_attempt_start",
"source": "compaction",
"reason": "threshold"
}Dal özetleri için source, "branchSummary"'dir ve reason yoktur.
{
"type": "summarization_retry_finished"
}extension_error
Bir uzantı hata verdiğinde ortaya çıkar.
{
"type": "extension_error",
"extensionPath": "/path/to/extension.ts",
"event": "tool_call",
"error": "Error message..."
}Uzantı Kullanıcı Arayüzü Protokolü
Extensions, ctx.ui.select(), ctx.ui.confirm() vb. aracılığıyla kullanıcı etkileşimi talep edebilir. RPC modunda bunlar, temel komut/olay akışının üstünde bir istek/yanıt alt protokolüne dönüştürülür.
Uzantı kullanıcı arayüzü yöntemlerinin iki kategorisi vardır:
- İletişim yöntemleri (
select,confirm,input,editor): stdout'de birextension_ui_requestyayınlayın ve istemci,idile eşleşen stdin'de birextension_ui_responsegeri gönderene kadar bloke edin. - Ateşle ve unut yöntemleri (
notify,setStatus,setWidget,setTitle,set_editor_text): stdout üzerindeextension_ui_requestyayınlayın ancak yanıt beklemeyin. İstemci bilgileri görüntüleyebilir veya görmezden gelebilir.
Bir diyalog yöntemi bir timeout alanı içeriyorsa, aracı tarafı, zaman aşımı sona erdiğinde varsayılan bir değerle otomatik olarak çözümleyecektir. İstemcinin zaman aşımlarını izlemesine gerek yoktur.
Bazı ExtensionUIContext yöntemleri, doğrudan TUI erişimi gerektirdiğinden RPC modunda desteklenmez veya kalitesi düşürülmez:
custom()undefineddeğerini döndürürsetWorkingMessage(),setWorkingIndicator(),setFooter(),setHeader(),setEditorComponent(),setToolsExpanded()operasyon dışıdırgetEditorText()""değerini döndürürgetToolsExpanded()falsedeğerini döndürürpasteToEditor()setEditorText()'ye yetki verir (yapıştırma/daraltma işlemi yoktur)getAllThemes()[]değerini döndürürgetTheme()undefineddeğerini döndürürsetTheme(){ success: false, error: "..." }değerini döndürür
Not: RPC modunda ctx.mode "rpc" ve ctx.hasUI true'dir çünkü diyalog ve ateşle ve unut yöntemleri, uzantı kullanıcı arayüzü alt protokolü aracılığıyla işlevseldir. Gerçek bir terminal gerektiren custom() gibi TUI'ye özgü özellikleri korumak için ctx.mode === "tui" kullanın.
Uzantı Kullanıcı Arayüzü İstekleri (stdout)
Tüm isteklerin type: "extension_ui_request", benzersiz bir id ve method alanı vardır.
seçme
Kullanıcıdan listeden seçim yapmasını isteyin. timeout alanına sahip iletişim yöntemleri milisaniye cinsinden zaman aşımını içerir; müşteri zamanında yanıt vermezse temsilci undefined ile otomatik olarak çözer.
{
"type": "extension_ui_request",
"id": "uuid-1",
"method": "select",
"title": "Allow dangerous command?",
"options": ["Allow", "Block"],
"timeout": 10000
}Beklenen yanıt: extension_ui_response ile value (seçilen seçenek dizisi) veya cancelled: true.
onaylamak
Kullanıcıdan evet/hayır onayı isteyin.
{
"type": "extension_ui_request",
"id": "uuid-2",
"method": "confirm",
"title": "Clear session?",
"message": "All messages will be lost.",
"timeout": 5000
}Beklenen yanıt: extension_ui_response ile confirmed: true/false veya cancelled: true.
giriş
Kullanıcıdan serbest biçimli metin isteyin.
{
"type": "extension_ui_request",
"id": "uuid-3",
"method": "input",
"title": "Enter a value",
"placeholder": "type something..."
}Beklenen yanıt: extension_ui_response ile value (girilen metin) veya cancelled: true.
editör
İsteğe bağlı önceden doldurulmuş içeriğe sahip çok satırlı bir metin düzenleyiciyi açın.
{
"type": "extension_ui_request",
"id": "uuid-4",
"method": "editor",
"title": "Edit some text",
"prefill": "Line 1\nLine 2\nLine 3"
}Beklenen yanıt: extension_ui_response ile value (düzenlenen metin) veya cancelled: true.
bildirmek
Bir bildirim görüntüleyin. Ateşle ve unut, herhangi bir yanıt beklenmiyor.
{
"type": "extension_ui_request",
"id": "uuid-5",
"method": "notify",
"message": "Command blocked by user",
"notifyType": "warning"
}notifyType alanı "info", "warning" veya "error"'dir. Atlanırsa varsayılan olarak "info" olur.
setDurum
Alt bilgi/durum çubuğunda bir durum girişi ayarlayın veya temizleyin. Ateşle ve unut.
{
"type": "extension_ui_request",
"id": "uuid-6",
"method": "setStatus",
"statusKey": "my-ext",
"statusText": "Turn 3 running..."
}Söz konusu tuşun durum girişini temizlemek için statusText: undefined gönderin (veya atlayın).
setWidget'ı
Düzenleyicinin üstünde veya altında görüntülenen bir widget'ı (metin satırları bloğu) ayarlayın veya temizleyin. Ateşle ve unut.
{
"type": "extension_ui_request",
"id": "uuid-7",
"method": "setWidget",
"widgetKey": "my-ext",
"widgetLines": ["--- My Widget ---", "Line 1", "Line 2"],
"widgetPlacement": "aboveEditor"
}Widget'ı temizlemek için widgetLines: undefined gönderin (veya atlayın). widgetPlacement alanı "aboveEditor" (varsayılan) veya "belowEditor"'dir. RPC modunda yalnızca dize dizileri desteklenir; bileşen fabrikaları göz ardı edilir.
setTitle
Terminal penceresi/sekme başlığını ayarlayın. Ateşle ve unut.
{
"type": "extension_ui_request",
"id": "uuid-8",
"method": "setTitle",
"title": "pi - my project"
}set_editor_text
Giriş düzenleyicisinde metni ayarlayın. Ateşle ve unut.
{
"type": "extension_ui_request",
"id": "uuid-9",
"method": "set_editor_text",
"text": "prefilled text for the user"
}Uzantı Kullanıcı Arayüzü Yanıtları (stdin)
Yanıtlar yalnızca iletişim yöntemleri için gönderilir (select, confirm, input, editor). id istekle eşleşmelidir.
Değer yanıtı (seç, gir, düzenle)
{"type": "extension_ui_response", "id": "uuid-1", "value": "Allow"}Onay yanıtı (onayla)
{"type": "extension_ui_response", "id": "uuid-2", "confirmed": true}İptal yanıtı (herhangi bir iletişim kutusu)
Herhangi bir diyalog yöntemini reddedin. Uzantı undefined (seçim/giriş/düzenleyici için) veya false (onay için) alır.
{"type": "extension_ui_response", "id": "uuid-3", "cancelled": true}Hata İşleme
Başarısız olan komutlar success: false ile bir yanıt döndürür:
{
"type": "response",
"command": "set_model",
"success": false,
"error": "Model not found: invalid/model"
}Ayrıştırma hataları:
{
"type": "response",
"command": "parse",
"success": false,
"error": "Failed to parse command: Unexpected token..."
}Türler
Kaynak dosyaları:
packages/ai/src/types.ts-Model,UserMessage,AssistantMessage,ToolResultMessagepackages/agent/src/types.ts-AgentMessage,AgentEventsrc/core/messages.ts-BashExecutionMessagesrc/modes/json-event.ts-JsonAgentSessionEventsrc/modes/rpc/rpc-types.ts- RPC komut/yanıt türleri, uzantı kullanıcı arayüzü istek/yanıt türleri
Modeli
{
"id": "claude-sonnet-4-20250514",
"name": "Claude Sonnet 4",
"api": "anthropic-messages",
"provider": "anthropic",
"baseUrl": "https://api.anthropic.com",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 200000,
"maxTokens": 16384,
"cost": {
"input": 3.0,
"output": 15.0,
"cacheRead": 0.3,
"cacheWrite": 3.75
}
}Kullanıcı Mesajı
{
"role": "user",
"content": "Hello!",
"timestamp": 1733234567890,
"attachments": []
}content alanı bir dize veya TextContent/ImageContent bloklardan oluşan bir dizi olabilir.
AsistanMesajı
{
"role": "assistant",
"content": [
{"type": "text", "text": "Hello! How can I help?"},
{"type": "thinking", "thinking": "User is greeting me..."},
{"type": "toolCall", "id": "call_123", "name": "bash", "arguments": {"command": "ls"}}
],
"api": "anthropic-messages",
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"usage": {
"input": 100,
"output": 50,
"cacheRead": 0,
"cacheWrite": 0,
"cost": {"input": 0.0003, "output": 0.00075, "cacheRead": 0, "cacheWrite": 0, "total": 0.00105}
},
"stopReason": "stop",
"timestamp": 1733234567890
}Durdurma nedenleri: "stop", "length", "toolUse", "error", "aborted"
AraçSonucuMesajı
{
"role": "toolResult",
"toolCallId": "call_123",
"toolName": "bash",
"content": [{"type": "text", "text": "total 48\ndrwxr-xr-x ..."}],
"usage": {
"input": 100,
"output": 50,
"cacheRead": 0,
"cacheWrite": 0,
"totalTokens": 150,
"cost": {"input": 0.0003, "output": 0.00075, "cacheRead": 0, "cacheWrite": 0, "total": 0.00105}
},
"isError": false,
"timestamp": 1733234567890
}usage isteğe bağlıdır ve araç tarafından gerçekleştirilen iç içe geçmiş LLM çalışmasını raporlar. Mevcut olduğunda oturum belirtecine ve maliyet toplamlarına katkıda bulunur.
BashYürütmeMesajı
bash RPC komutuyla oluşturulmuştur (LLM araç çağrıları tarafından değil):
{
"role": "bashExecution",
"command": "ls -la",
"output": "total 48\ndrwxr-xr-x ...",
"exitCode": 0,
"cancelled": false,
"truncated": false,
"fullOutputPath": null,
"timestamp": 1733234567890
}EK
{
"id": "img1",
"type": "image",
"fileName": "photo.jpg",
"mimeType": "image/jpeg",
"size": 102400,
"content": "base64-encoded-data...",
"extractedText": null,
"preview": null
}Örnek: Temel İstemci (Python)
import subprocess
import json
proc = subprocess.Popen(
["pi", "--mode", "rpc", "--no-session"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
def send(cmd):
proc.stdin.write(json.dumps(cmd) + "\n")
proc.stdin.flush()
def read_events():
for line in proc.stdout:
yield json.loads(line)
# Send prompt
send({"type": "prompt", "message": "Hello!"})
# Process events
for event in read_events():
if event.get("type") == "message_update":
delta = event.get("assistantMessageEvent", {})
if delta.get("type") == "text_delta":
print(delta["delta"], end="", flush=True)
if event.get("type") == "agent_end":
print()
breakÖrnek: Etkileşimli İstemci (Node.js)
Tam bir etkileşimli örnek için test/rpc-example.ts'ye veya yazılan bir istemci uygulaması için src/modes/rpc/rpc-client.ts'ye bakın.
Uzantı kullanıcı arayüzü protokolünü işlemeye ilişkin tam bir örnek için, examples/extensions/rpc-demo.ts uzantısıyla eşleşen examples/rpc-extension-ui.ts'ye bakın.
const { spawn } = require("child_process");
const { StringDecoder } = require("string_decoder");
const agent = spawn("pi", ["--mode", "rpc", "--no-session"]);
function attachJsonlReader(stream, onLine) {
const decoder = new StringDecoder("utf8");
let buffer = "";
stream.on("data", (chunk) => {
buffer += typeof chunk === "string" ? chunk : decoder.write(chunk);
while (true) {
const newlineIndex = buffer.indexOf("\n");
if (newlineIndex === -1) break;
let line = buffer.slice(0, newlineIndex);
buffer = buffer.slice(newlineIndex + 1);
if (line.endsWith("\r")) line = line.slice(0, -1);
onLine(line);
}
});
stream.on("end", () => {
buffer += decoder.end();
if (buffer.length > 0) {
onLine(buffer.endsWith("\r") ? buffer.slice(0, -1) : buffer);
}
});
}
attachJsonlReader(agent.stdout, (line) => {
const event = JSON.parse(line);
if (event.type === "message_update") {
const { assistantMessageEvent } = event;
if (assistantMessageEvent.type === "text_delta") {
process.stdout.write(assistantMessageEvent.delta);
}
}
});
// Send prompt
agent.stdin.write(JSON.stringify({ type: "prompt", message: "Hello" }) + "\n");
// Abort on Ctrl+C
process.on("SIGINT", () => {
agent.stdin.write(JSON.stringify({ type: "abort" }) + "\n");
});