תיעוד 39
מצב סוכן (ACP) ושילוב עם IDE
מצב סוכן מריץ את Grok כשרת ארוך טווח שלקוחות מדברים איתו דרך ACP (JSON-RPC). משתמשים בו מתוך סביבות פיתוח (IDE), ערכות SDK, סביבות הערכה (eval harnesses) ויישומים מותאמים אישית. עבור הנחיה חד פעמית שמדפיסה ויוצאת, השתמשו ב-grok -p (מצב headless).
#אוטומציה וערכות SDK
עבור סקריפטים, CI, הערכות (evals) ושרתי סוכן, התחילו עם always-approve כדי שכלים ירוצו בלי בקשות הרשאה אינטראקטיביות. כללי deny ו-hooks עדיין חלים.
# stdio (local process / many SDKs)
grok agent --always-approve stdio
# WebSocket server
grok agent --always-approve serve --bind 127.0.0.1:2419 --secret <token>אפשר גם להגדיר always-approve לכל סשן ב-session/new:
{
"cwd": "/path/to/project",
"mcpServers": [],
"_meta": { "yoloMode": true }
}משתמשי TUI אינטראקטיבי בדרך כלל משאירים את מצב ask כברירת מחדל (או משתמשים ב-auto). ראו הרשאות ובטיחות.
#מה זה ACP?
Agent Client Protocol (ACP) מגדיר איך לקוחות מדברים עם סוכני קוד דרך JSON-RPC. עם Grok הוא מכסה:
- סשנים (יצירה, טעינה, חידוש)
- הנחיות ותשובות בזרימה
- עדכוני קריאות כלים
- זרמי חשיבה (reasoning) / thought
- בקשות הרשאה כשהסשן אינו במצב always-approve
#תעבורת stdio
stdio הוא נתיב השילוב המקומי הנפוץ. הסוכן מדבר JSON-RPC על stdin ועל stdout:
grok agent --always-approve stdioלקוחות אופייניים: הרחבות IDE (Zed, Neovim, Emacs), כלים מותאמים אישית, וערכות SDK של ACP.
#אפשרויות
אפשרויות הסוכן חלות על כל תעבורה (stdio, serve, headless, leader). הן באות אחרי agent ולפני שם המצב. דגלים ייחודיים למצב באים אחרי המצב (לדוגמה serve --bind).
grok agent --always-approve --model grok-4.6 stdio
grok agent --always-approve serve --bind 127.0.0.1:2419 --secret <token>| דגל | תיאור |
|---|---|
-m, --model <MODEL> | מזהה מודל (לדוגמה grok-4.6). |
--always-approve | הרצה בלי בקשות הרשאה אינטראקטיביות לכלים. כינוי: --yolo. |
--reauth | אימות לפני שהסוכן מתחיל. |
--agent-profile <PATH> | טעינת פרופיל סוכן מקובץ. במסלול ה-daemon הקובץ לא נטען, והסשנים מדלגים על [agent] ועל GROK_AGENT, ולכן הם מריצים את סוכן ברירת המחדל אלא אם הלקוח מציין אחד. |
--leader / --no-leader | התחברות לתהליך leader משותף, או כפיית סוכן מקומי. כשמבקשים פרופיל sandbox שאינו off, מצב leader נדחה כדי שהכלים יישארו בתוך התהליך (ראו מצב Sandbox). |
#מצב שרת
grok agent --always-approve serve --bind 127.0.0.1:2419 --secret <token>לקוחות מתחברים דרך WebSocket ומאמתים עם האסימון הסודי. אם משמיטים את --secret, הסוכן מדפיס אסימון שנוצר בהפעלה, או מגדירים את GROK_AGENT_SECRET. התהליך שומר מצב בין חיבורים מחדש של לקוחות. ההרשאות תואמות לנקודות כניסה אחרות. ראו הרשאות ובטיחות.
זה שרת שאתם מריצים בעצמכם. ארגזי החול בענן המארח של Grok לא מריצים את grok agent serve.
#ממסר WebSocket
כדי להגיע לסוכן דרך האינטרנט, חברו את הסוכן לממסר והפנו דפדפנים לאותו ממסר:
grok agent --always-approve headless --grok-ws-url wss://your-relay.example.com/ws#יסודות פרוטוקול ACP
התקשורת עוקבת אחרי פורמט JSON-RPC 2.0. מחזור חיים אופייני של סשן:
- אתחול: הלקוח שולח
initializeעם יכולות - יצירת סשן: הלקוח שולח
session/newעם תיקיית העבודה - שליחת הנחיות: הלקוח שולח
session/promptעם הודעות המשתמש - קבלת עדכונים: הסוכן שולח התראות
session/updateעם תוכן בזרימה - טיפול בהרשאות: הסוכן עשוי לבקש אישור להרצת כלי (או לאפשר או לדחות לפי מצב ההרשאה)
#ארכיטקטורה
+------------------------------------------+
| ACP Client |
| (IDE, Editor, Custom Application) |
+-------------------+----------------------+
| JSON-RPC over stdio
+-------------------v----------------------+
| grok agent stdio |
| |
| +---------+ +---------+ +---------+ |
| | Session | | Tools | | MCP | |
| | Manager | | Registry| | Servers | |
| +---------+ +---------+ +---------+ |
+------------------------------------------+#עדכוני זרימה
ACP מזרים אירועים מובנים. כל התראת session/update נושאת שדה sessionUpdate שמזהה את סוג העדכון:
ערך sessionUpdate | תיאור |
|---|---|
agent_message_chunk | נתח מטקסט התשובה של הסוכן. |
agent_thought_chunk | נתח מהחשיבה הפנימית של הסוכן. |
tool_call | הפעלת כלי חדשה (כותרת, סוג, סטטוס, קלט). |
tool_call_update | עדכון סטטוס או תוצאה לקריאת כלי שרצה. |
plan | תוכנית הביצוע של הסוכן. |
כל עדכון מציין את הסוג שלו, כך שלקוח יכול להציג לוחות נפרדים לחשיבה, לקריאות כלים ולטקסט התשובה.
#שיטות הרחבה
מעבר לפרוטוקול ACP הבסיסי, Grok מגדיר שיטות הרחבה תחת הקידומת x.ai/ לפונקציונליות ייחודית ל-SpaceXAI. אלה מכסות:
| קטגוריה | קידומת | דוגמאות |
|---|---|---|
| מערכת קבצים | x.ai/fs/* | list, exists, read_file, write_file |
| Git | x.ai/git/* | status, stage, commit, diffs, discard |
| Git Worktree | x.ai/git/worktree/* | create, remove, apply, list, gc |
| חיפוש | x.ai/search/* | fuzzy/open, fuzzy/change, content |
| מסוף | x.ai/terminal/* | create, kill, output, wait_for_exit |
| ניהול סשן | x.ai/session/* | fork, resolve_local_for_worktree_resume |
| שיחה והיסטוריה | x.ai/* | prompt_history, rewind/*, compact_conversation |
| אימות | x.ai/auth/* | get_url, submit_code |
| משוב וטלמטריה | x.ai/* | feedback, telemetry/* |
הטבלאות כאן מציגות שיטות מייצגות בכל קטגוריה. קבוצת x.ai/* ייחודית ל-SpaceXAI ועשויה להתרחב בין גרסאות, ולכן התייחסו אליה כלא ממצה וגלו את השיטות הזמינות מתשובת initialize של הסוכן.
#התראות (מהסוכן ללקוח)
הסוכן שולח התראות דחיפה ללקוחות לעדכונים בזמן אמת:
| התראה | תיאור |
|---|---|
x.ai/search/fuzzy/status | עדכון תוצאות חיפוש fuzzy |
x.ai/git/worktree/status | התקדמות יצירת worktree |
x.ai/fs_notify | התראת שינוי במערכת הקבצים |
x.ai/fs/index | עדכון אינדקס קבצים מלא |
x.ai/fs/index/delta | עדכון אינדקס קבצים מצטבר |
x.ai/session_notification | עדכונים ייחודיים לסשן (סקירת diff, מצב ניסיון חוזר, auto-compact) |
x.ai/session/update | עדכון סשן (קריאות כלים, תוכן) |
x.ai/fs/index יכול להגיע שוב באמצע הסשן, אחרי שה-watcher מפיל שינויים. התראה עם chunk: 0 מתחילה רשימה חדשה. הלקוח מחליף את הרשימה שלו בנתח הזה ובאלה שאחריו, עד זה שמסומן complete. אין x.ai/fs/index/delta לפני x.ai/fs/index הראשון.
root ב-x.ai/fs/index נותן שם לתיקייה שה-watcher עובר עליה.
נתיבי האינדקס והדלתא יחסיים אליה ומפרידים תיקיות ב-/, גם ב-Windows.
במסלול ה-daemon ה-watcher עובר על תיקיית ה-daemon של הסשן, או על cwd של הסשן כשה-daemon לא מציין אחת.
אחרת הוא עובר על cwd של הסשן.
ה-root יכול להיות שונה לפי מסלול לאותו סשן, לדוגמה /repo במסלול ה-daemon ו-/repo/sub אחרת.
#אפשרויות תצורת סשן
תשובות session/new ו-session/load כוללות רשימת configOptions עם טיפוסים (ACP סטנדרטי, לא הרחבת x.ai/). משנים אפשרות חיה עם session/set_config_option.
configId | קטגוריה | השפעה |
|---|---|---|
model | model | מחליף את מודל הסשן (allowed_models, ניתוב שער הצ'אט). הערך חייב להיות מזהה מחרוזת. |
reasoning_effort | thought_level | מחיל מאמץ על המודל הנוכחי בלי להחליף את המודל (בלי שכתוב הנחיה, בלי שער allowed_models). הערך חייב להיות מזהה מחרוזת (minimal, low, medium, high, xhigh). מושמט עם אזהרה כשהמודל לא מפרסם supportsReasoningEffort. |
{
"sessionId": "…",
"configId": "reasoning_effort",
"value": { "value": "high" }
}התשובה היא רשימת האפשרויות המלאה והמעודכנת. התראת סשן config_option_update משקפת אותה לכל לקוח רשום. במצב leader ה-proxy מצותת ל-configId: model כדי ש-default_model של כל לקוח יישאר מסונכרן. ערכים בוליאניים נדחים. חשיפת אפשרויות בוליאניות עדיין לא ממומשת.
#אפשרויות _meta של סשן
שדות אופציונליים ב-session/new:
| שדה | תיאור |
|---|---|
rules | כללים נוספים שמצורפים להנחיית המערכת. |
systemPromptOverride | הנחיית מערכת חלופית. |
agentProfile | שם פרופיל סוכן או אובייקט JSON. במסלול ה-daemon, שם של סוכן משתמש או סוכן מצורף מריץ את ההנחיה וה-hooks של אותו סוכן, אבל עדיין לא את mcpServers: או model: שלו. ילד Task רץ בלי ה-hooks של אותו סוכן, שלא כמו ב-shell. daemon שלא מדווח grok_session_main_agent.v1 עשוי להריץ את סוכן ברירת המחדל במקום. שם מובנה ואובייקט מריצים את סוכן ברירת המחדל. כך גם שם שקובץ סוכן של פרויקט חולק, אלא אם התיקייה מהימנה והקובץ הזה לא עובר parse. שם שיש רק לפרויקט, או אובייקט שלא עובר parse, נופלים אל [agent] ו-GROK_AGENT. |
yoloMode | כש-true, always-approve לסשן הזה. |
autoMode | כש-true, מצב הרשאה auto לסשן הזה. מתבטל כש-always-approve כבר פעיל. |
{
"cwd": "/path/to/project",
"mcpServers": [],
"_meta": { "yoloMode": true }
}#ערכות SDK של ACP
ספריות SDK רשמיות זמינות לכמה שפות:
| שפה | חבילה |
|---|---|
| TypeScript | @agentclientprotocol/sdk |
| Rust | agent-client-protocol |
| Python | agent-client-protocol-python |
| Go | acp-go-sdk |
| Kotlin | acp |
#לקוחות תואמים
| לקוח | סטטוס |
|---|---|
| Zed | נתמך |
| Neovim (CodeCompanion, avante.nvim) | נתמך |
| Emacs | נתמך |
| marimo notebook | נתמך |
| JetBrains | בקרוב |
#דוגמת שילוב: לקוח ACP ב-TypeScript
import { spawn, ChildProcess } from "child_process";
import * as readline from "readline";
class GrokACPChat {
private proc!: ChildProcess;
private sessionId!: string;
private rl!: readline.Interface;
constructor(private cwd = ".") {}
async init() {
this.proc = spawn("grok", ["agent", "--always-approve", "stdio"]);
this.rl = readline.createInterface({ input: this.proc.stdout! });
await this.request("initialize", {
protocolVersion: 1,
clientCapabilities: {
fs: { readTextFile: true, writeTextFile: true },
terminal: true,
},
});
const { sessionId } = await this.request("session/new", {
cwd: this.cwd,
mcpServers: [],
_meta: { yoloMode: true },
});
this.sessionId = sessionId;
return this;
}
private async request(method: string, params: any): Promise<any> {
return new Promise((resolve) => {
const msg = JSON.stringify({ jsonrpc: "2.0", id: 1, method, params });
this.proc.stdin!.write(msg + "\n");
this.rl.once("line", (line) => {
resolve(JSON.parse(line).result || {});
});
});
}
async *streamPrompt(text: string) {
const msg = JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "session/prompt",
params: {
sessionId: this.sessionId,
prompt: [{ type: "text", text }],
},
});
this.proc.stdin!.write(msg + "\n");
for await (const line of this.rl) {
const data = JSON.parse(line);
if (data.method === "session/update") {
const update = data.params.update;
yield update; // { sessionUpdate, content, title, ... }
} else if (data.result) {
break; // Final response
}
}
}
}
// Usage
const client = await new GrokACPChat(".").init();
for await (const update of client.streamPrompt("List the files in this project")) {
switch (update.sessionUpdate) {
case "agent_message_chunk":
process.stdout.write(update.content?.text || "");
break;
case "agent_thought_chunk":
console.log(`\n[Thinking: ${update.content?.text}]`);
break;
case "tool_call":
console.log(`\n[Tool: ${update.title}]`);
break;
}
}