Pi için yapılandırma, özelleştirme, platform kurulumu ve API referansları.

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/id ve 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\n giriş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:

  1. Bash çıktısı LLM bağlamına hemen değil, sonraki komut isteminde dahil edilir
  2. 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ı (/name ile ç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 numarada pi.registerCommand() aracılığıyla kaydedildi
    • "prompt": Bilgi istemi şablonu .md dosyasından yüklendi
    • "skill": Bir beceri dizininden yüklendi (adın önüne skill: 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 bir extension_ui_request yayınlayın ve istemci, id ile eşleşen stdin'de bir extension_ui_response geri gönderene kadar bloke edin.
  • Ateşle ve unut yöntemleri (notify, setStatus, setWidget, setTitle, set_editor_text): stdout üzerinde extension_ui_request yayı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() undefined değerini döndürür
  • setWorkingMessage(), setWorkingIndicator(), setFooter(), setHeader(), setEditorComponent(), setToolsExpanded() operasyon dışıdır
  • getEditorText() "" değerini döndürür
  • getToolsExpanded() false değerini döndürür
  • pasteToEditor() setEditorText()'ye yetki verir (yapıştırma/daraltma işlemi yoktur)
  • getAllThemes() [] değerini döndürür
  • getTheme() undefined değerini döndürür
  • setTheme() { 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ı:

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");
});