מדריך גרוק CLI בעברית

תיעוד 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. מחזור חיים אופייני של סשן:

  1. אתחול: הלקוח שולח initialize עם יכולות
  2. יצירת סשן: הלקוח שולח session/new עם תיקיית העבודה
  3. שליחת הנחיות: הלקוח שולח session/prompt עם הודעות המשתמש
  4. קבלת עדכונים: הסוכן שולח התראות session/update עם תוכן בזרימה
  5. טיפול בהרשאות: הסוכן עשוי לבקש אישור להרצת כלי (או לאפשר או לדחות לפי מצב ההרשאה)

#ארכיטקטורה

+------------------------------------------+
|           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
Gitx.ai/git/*status, stage, commit, diffs, discard
Git Worktreex.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קטגוריההשפעה
modelmodelמחליף את מודל הסשן (allowed_models, ניתוב שער הצ'אט). הערך חייב להיות מזהה מחרוזת.
reasoning_effortthought_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 רשמיות זמינות לכמה שפות:


#לקוחות תואמים

לקוחסטטוס
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;
  }
}

#משאבים