Synced from monorepo

Synced from monorepo

Changes:
- Workspace server: report `/ready` as failed with dwell on hub connect failure
- Refresh OIDC token for the Grok agent in the shell
- ACP terminal output recorder
- Cross-platform provider auth commands in the shell
- Default `/resume` to Grok sessions with a hint for hidden external sessions
- Resume sessions by title with `--resume`
- Limit app-builder archive size
- Data-driven tag labels for slash commands
- Doctor fixes for tmux
- Custom provider gateways and subprocess environment policy in the shell
- `/tutorial` — opt-in onboarding tour of Grok Build
- Soft and required CLI version checks in the shell
- Privacy banner env overrides survive live settings updates
- Add remote flag to override the image-edit model
- Return profile fields from auth info even when the access token is expired
- Add edit control on queued prompt rows
- Keep fail-closed policy when clearing orphans with no team
- Setting to disable the Ctrl+Space/F8 voice shortcut
- Pass `--raw` to pw-record so Linux dictation works on older PipeWire
- Validate git URLs when adding marketplace entries
- Stop shipping stale tool-doc parameter and tool names
- Re-point dashboard attach after `/fork` only when the parent was attached
- Surface Grok Computer media-generation results as file-path chunks
- Clear web background-task tray on kill and keep the task description
- Show privacy upsell banner in agent view until acted on
- Add tools-server client callback surface
- Protect persistent global hook sources

Source-Revision: 95d84f443eddcbed6cbfd6eed22e2eafe6b3939d
This commit is contained in:
grokkybara[bot] 2026-07-23 17:12:33 +00:00
commit 69f0ba880a
286 changed files with 22939 additions and 9624 deletions

View file

@ -29,6 +29,22 @@ fn main() {
".xai.grok.tools.v1.ToolConfigEntry.description_override",
"#[serde(default)]",
)
.field_attribute(
".xai.grok.tools.v1.FinalizeToolServerConfigRequest.client_callback_addr",
"#[serde(default)]",
)
.field_attribute(
".xai.grok.tools.v1.FinalizeToolServerConfigRequest.session_id",
"#[serde(default)]",
)
.field_attribute(
".xai.grok.tools.v1.FinalizeToolServerConfigRequest.client_callback_secret",
"#[serde(default)]",
)
.field_attribute(
".xai.grok.tools.v1.FinalizeToolServerConfigResponse.callback_status",
"#[serde(default)]",
)
.compile_protos(&["proto/grok-tools.proto"], &["proto/"])
.unwrap();
}

View file

@ -171,6 +171,29 @@ service GrokToolsService {
}
}
// ============================================================================
// CLIENT CALLBACK SERVICE
// ============================================================================
/// GrokToolsCallbackService is implemented by the client/host process and
/// dialed by grok-tools-server during finalize when callback fields are set.
///
/// The contract is deliberately minimal the server owns all subagent
/// knowledge (type registry, prompts, toolset resolution, and lifecycle state
/// in the shared coordinator actor); the host only does genuinely host-side work:
///
/// - `SpawnSubagent`: execute one resolved child request to completion.
/// The RPC spans the whole request; cancellation is the call's cancellation.
/// - `SendNotification`: fire-and-forget push of serde-tagged notification
/// JSON (e.g. `SubagentCompleted`) into the host's conversation stream.
service GrokToolsCallbackService {
/// Rust sends one tool notification to the host process.
rpc SendNotification(ToolNotificationMsg) returns (NotificationAck);
/// Execute one resolved child request and return its final result.
rpc SpawnSubagent(SpawnSubagentRequest) returns (SubagentResultMsg);
}
// ============================================================================
// TOOL SERVER CONFIG MESSAGES (finalize-time configuration)
// ============================================================================
@ -207,6 +230,23 @@ message FinalizeToolServerConfigRequest {
/// Behavior preset name (e.g. "current", "legacy-0.4.10").
/// Applied to all version-managed tools. Defaults to "current" when empty.
optional string behavior_preset = 5;
/// Optional host callback address. When set, grok-tools-server dials this
/// client-hosted gRPC endpoint during finalize and injects callback-backed
/// resource views for notifications and subagents. The server accepts bare
/// "host:port" addresses and assumes "http://".
optional string client_callback_addr = 6;
/// Logical session identifier used for callback correlation and resource
/// scoping (SessionIdResource / OwnerSessionId). If omitted while a callback
/// address is present, the server uses its generated process session id.
optional string session_id = 7;
/// Per-session bearer secret required by the client-hosted callback service.
/// Only used when client_callback_addr is set.
optional string client_callback_secret = 8;
reserved 9;
}
/// Per-tool configuration entry.
@ -281,6 +321,13 @@ message VersionWarning {
string message = 4;
}
/// Status of the optional callback connection established during finalize.
message CallbackStatus {
bool connected = 1;
repeated string active_surfaces = 2;
optional string message = 3;
}
/// Response from finalizing the tool server configuration.
message FinalizeToolServerConfigResponse {
bool success = 1;
@ -293,6 +340,78 @@ message FinalizeToolServerConfigResponse {
/// Deprecation/lifecycle warnings for resolved versions.
/// Empty when all versions are Active.
repeated VersionWarning version_warnings = 4;
/// Optional status for the finalize-time callback dial.
optional CallbackStatus callback_status = 5;
}
// ============================================================================
// CALLBACK MESSAGES
// ============================================================================
message ToolNotificationMsg {
string session_id = 1;
/// serde(tag = "type") JSON for xai_grok_tools::notification::ToolNotification.
string notification_json = 2;
/// Monotonically increasing sequence number for observability.
uint64 sequence = 3;
}
message NotificationAck {}
/// Execute one resolved child request.
///
/// The server resolves everything from its own registry and finalized
/// toolset before dialing: `system_prompt` is the complete production
/// subagent base template + definition body rendered with the child's actual
/// (possibly randomized) tool names, and `tool_names` is selected from the
/// canonical production AgentDefinition. The host executes the request with
/// the supplied tool names and working directory.
///
/// Lifecycle (backgrounding, foreground budget, query/cancel, completion
/// surfacing) is owned by the server-side coordinator actor; the host keeps
/// no lifecycle state. Cancellation = the gRPC call's cancellation.
message SpawnSubagentRequest {
string id = 1;
string prompt = 2;
string description = 3;
string subagent_type = 4;
string parent_session_id = 5;
optional string parent_prompt_id = 6;
/// Resume a previously completed child: the server validates source identity
/// and workspace; the host replays non-system turns, installs the freshly
/// rendered `system_prompt`, and appends `prompt`.
optional string resume_from = 7;
optional string cwd = 8;
reserved 9, 10, 11, 12, 13;
/// Complete rendered production system prompt for the child.
optional string system_prompt = 14;
/// Client-facing names of the tools the child may use.
repeated string tool_names = 15;
/// Optional user message prepended before the task prompt.
optional string initial_user_message = 16;
}
message SubagentResultMsg {
bool success = 1;
string output = 2;
optional string error = 3;
bool cancelled = 4;
/// Deprecated: identity is stamped by the server.
string subagent_id = 5;
/// Deprecated: identity is stamped by the server.
string child_session_id = 6;
uint32 tool_calls = 7;
uint32 turns = 8;
uint64 duration_ms = 9;
/// Legacy total/context usage fallback.
uint64 tokens_used = 10;
/// Deprecated: workspace is stamped by the server.
optional string worktree_path = 11;
/// Deprecated: delivery state is owned by the server.
bool backgrounded = 12;
optional uint64 output_tokens_used = 13;
optional uint64 total_tokens_used = 14;
}
// ============================================================================
@ -641,6 +760,13 @@ message ToolInfo {
/// Populated by ListTools pre-finalization from the fully-qualified
/// registry key (e.g. "GrokBuild:grep" namespace="GrokBuild").
string namespace = 19;
// 20-21 were `allowed_capability_modes` / `tool_kind`, exposed so remote
// clients could filter child subagent toolsets themselves. The server now
// resolves child toolsets from its own registry and sends the result in
// SpawnSubagentRequest, so nothing consumes them. No released pin ever
// read them.
reserved 20, 21;
}
/// Describes an output format supported by a tool

View file

@ -21,6 +21,7 @@ pub use pb::{
AgentToolExecConfig,
AgentToolRetryConfig,
// Request/response types
CallbackStatus,
ClearToolOverrideRequest,
ClearToolOverrideResponse,
DisableToolRequest,
@ -75,10 +76,12 @@ pub use pb::{
SetToolOverrideResponse,
SetTruncationConfigRequest,
SetTruncationConfigResponse,
SpawnSubagentRequest,
// Streaming types
StreamDataChunk,
StreamDataKind,
StreamFinalResult,
SubagentResultMsg,
// Capability/metadata types
ToolCapabilities,
ToolCategory,
@ -86,6 +89,7 @@ pub use pb::{
ToolConfigEntry,
ToolError,
ToolInfo,
ToolNotificationMsg,
ToolSource,
ToolStreamChunk,
ToolSuccess,

View file

@ -21,6 +21,19 @@ fn full_entry() -> ToolConfigEntry {
}
}
fn finalize_request_minimal() -> xai_grok_tools_api::FinalizeToolServerConfigRequest {
xai_grok_tools_api::FinalizeToolServerConfigRequest {
tools: vec![],
truncation: None,
system_reminders_enabled: false,
initial_tool_state_json: None,
behavior_preset: None,
client_callback_addr: None,
session_id: None,
client_callback_secret: None,
}
}
#[test]
fn tool_config_entry_serializes_to_pinned_json_shape() {
let value = serde_json::to_value(full_entry()).expect("serialize");
@ -100,3 +113,38 @@ fn explicit_null_map_is_rejected() {
"null params_name_overrides must be rejected (omit the key or send {{}})"
);
}
#[test]
fn finalize_request_callback_fields_are_optional_and_snake_case() {
let mut req = finalize_request_minimal();
req.client_callback_addr = Some("http://127.0.0.1:50051".to_owned());
req.session_id = Some("session-123".to_owned());
req.client_callback_secret = Some("secret-123".to_owned());
let value = serde_json::to_value(&req).expect("serialize");
assert_eq!(
value.get("client_callback_addr"),
Some(&serde_json::json!("http://127.0.0.1:50051"))
);
assert_eq!(
value.get("session_id"),
Some(&serde_json::json!("session-123"))
);
assert_eq!(
value.get("client_callback_secret"),
Some(&serde_json::json!("secret-123"))
);
}
#[test]
fn finalize_request_callback_fields_default_when_absent() {
let back: xai_grok_tools_api::FinalizeToolServerConfigRequest =
serde_json::from_value(serde_json::json!({
"tools": [],
"system_reminders_enabled": false,
}))
.expect("deserialize sparse finalize request");
assert_eq!(back.client_callback_addr, None);
assert_eq!(back.session_id, None);
assert_eq!(back.client_callback_secret, None);
}