tiny.acp.Client
Defined in client.
A caller owns a client for the life of one agent program, to send it prompts and get replies back.
API (27)
Actions
Public operations.
agentError: A caller uses this call to show what the agent said after a call fails witherror.AgentProtocolError.deinit: A caller callsdeinitonce to end the agent and free what the client owns when done with the client.init: A caller callsinitto start the agent and prepare everything the conversation needs, so later calls only exchange messages.prompt: A caller uses this call for the common case of sending text and getting the reply text back.promptDetailed: A caller uses this call to send text and also learn why the agent stopped and whether the reply was cut short.promptDetailedContent: A caller uses this call to send a prompt that carries files, links or media alongside text.readerStatus: A caller reads the status to learn why reading stopped aftererror.ReaderMessageCapacityExceeded, or to watch how close the agent's lines come to the limit.requestCancel: A caller uses this call to stop the agent and everything it started at once.start: A caller callsstartonce afterinitand before the first prompt to open the conversation.
Fields and members
Public fields and members.
agent_errorallocatorargvchildcwdinfoinitializeio_statemcp_serversmodesnext_idnext_update_sequenceobserverpermission_policyreadersession_idtransfer_limitstransport_epoch
Source
Source: lib/acp/src/client.zig:357
zig
/// A caller owns a client for the life of one agent program, to send it prompts and get replies/// back. The instance holds one agent process, the pipes to it, the reader for its output, and the/// state of one session. The order of use is `init`, `start`, any number of prompt calls, then/// `deinit`. The client writes each message to the agent as one line of JSON and reads the agent's/// messages one line at a time. Each call writes one request and then reads the agent's messages/// until the matching response arrives. While it waits, the call hands updates to the observer,/// answers permission requests, answers any other request from the agent with a "method not found"/// error, and drops other notifications. A line of invalid JSON, any other message, or the end of/// the agent's output before the response fails the call with `error.AgentProtocolError`. The/// fields hold the client's working state, and the package tests read `initialize`, `modes` and/// `child` directly.pub const Client = struct { /// The allocator for everything the client owns: the argument list, the directory copy, the /// reader's buffer, parsed messages, reply text and the session id. allocator: std.mem.Allocator, /// The argument list the agent started with: the command, then its arguments. The client owns /// the list, and the strings in it are borrowed from `Options`. argv: []const []const u8, /// The client's own copy of `Options.cwd`, or null. The method `start` reads it for /// `session/new`, and `deinit` frees it. cwd: ?[]u8, /// The name, title and version from `Options.client`, sent by `start`. info: ClientInfo, /// The MCP servers from `Options.mcp_servers`, sent by `start`. mcp_servers: []const McpServer, /// The permission lists from `Options.permission_policy`. permission_policy: PermissionPolicy, /// The callbacks from `Options.observer`, or null. observer: ?Observer, /// The traffic caps from `Options.transfer_limits`. transfer_limits: TransferLimits, /// The caller's number for this client from `Options.transport_epoch`, stamped on every update. transport_epoch: u64, /// The number the next update gets. The value starts at 1 and rises by one for each update, and /// nothing resets it. next_update_sequence: u64 = 1, /// The Zig standard library's thread-based I/O (`std.Io.Threaded`) the client created for the /// agent's process and pipes. The state carries the environment the agent started with. The /// method `deinit` frees it. io_state: sys.thread.ThreadedIo, /// The agent process, with the pipes to its standard input and output. The agent runs in a /// process group of its own, and its standard error is discarded. child: sys.process.Child, /// The line reader over the agent's standard output, which holds the reader's buffer. reader: LineReader, /// The id the next request gets. The value starts at 0 and rises by one per request, so /// `initialize` gets 0, `session/new` gets 1, and the first prompt gets 2. next_id: i64 = 0, /// The agent's id for the current session, taken from the `session/new` answer. The field is /// null before `start`, and every prompt call fails with `error.AgentProtocolError` while it is /// null. The client owns it. session_id: ?[]u8 = null, /// The agent's answer to `initialize`, set by `start`. The field holds the empty defaults /// before `start`. Callers read the protocol version, capability flags and authentication /// methods from it. initialize: protocol.Initialize = .{}, /// The session's modes from the `session/new` answer, set by `start`. The field is empty when /// the agent reports no modes. modes: protocol.Modes = .{}, /// The client's own copy of the message in the latest JSON-RPC error answer from the agent, or /// null. Each later error answer replaces it, and a later success leaves it in place. Callers /// read it through `agentError`. agent_error: ?[]u8 = null, /// A caller calls `init` to start the agent and prepare everything the conversation needs, so /// later calls only exchange messages. The function checks the limits, allocates the reader's /// buffer, copies the argument list and the working directory, then starts the agent. The /// function returns `error.InvalidLimits` before it allocates anything when a traffic cap or /// the transport epoch is zero. The call allocates the reader's buffer, the line limit plus one /// byte, before the agent starts, so a limit too large to add one to fails with /// `error.CapacityOverflow` and no process starts. The agent starts in a new process group of /// its own, with pipes on standard input and output and standard error discarded. The call /// returns allocation errors, errors from starting the process, and /// `error.AgentTransportFailed` when the process has no output pipe. On an error after the /// agent starts, the function signals the agent's process group to terminate and then to die, /// and waits for the agent to exit. The call sends the agent no message: the conversation /// begins with `start`. The caller owns the result and ends it with `deinit`. pub fn init(allocator: std.mem.Allocator, options: Options) !Client { if (!options.transfer_limits.valid() or options.transport_epoch == 0) { return error.InvalidLimits; } var reader_storage = try reader.Storage.init(allocator, options.reader_limits); errdefer reader_storage.deinit(allocator); const argv = try allocator.alloc([]const u8, options.args.len + 1); errdefer allocator.free(argv); argv[0] = options.command; @memcpy(argv[1..], options.args); const cwd = if (options.cwd) |value| try allocator.dupe(u8, value) else null; errdefer if (cwd) |value| allocator.free(value); var io_state = sys.thread.initThreadedIo(allocator, .{ .environ = options.environ orelse sys.env.current() }); errdefer io_state.deinit(); const io = io_state.io(); var child = try sys.process.spawn(io, .{ .argv = argv, .stdin = .pipe, .stdout = .pipe, .stderr = .ignore, .cwd = if (cwd) |value| .{ .path = value } else .inherit, .pgid = 0, }); errdefer stopChildAndReap(&child, io); const stdout = child.stdout orelse return error.AgentTransportFailed; reader_storage.activate(); return .{ .allocator = allocator, .argv = argv, .cwd = cwd, .info = options.client, .mcp_servers = options.mcp_servers, .permission_policy = options.permission_policy, .observer = options.observer, .transfer_limits = options.transfer_limits, .transport_epoch = options.transport_epoch, .io_state = io_state, .child = child, .reader = LineReader.init(io, stdout, reader_storage), }; } /// A caller calls `deinit` once to end the agent and free what the client owns when done with /// the client. The function frees the reader's buffer, the stored `initialize` answer, the /// modes, the error message, the session id and the directory copy. The client signals the /// agent's whole process group to terminate and then to die, and waits for the agent to exit. /// The client sends the agent no message first, `session/cancel` included. The call frees the /// I/O instance and the argument list. pub fn deinit(self: *Client) void { self.reader.deinit(self.allocator); self.initialize.deinit(self.allocator); self.modes.deinit(self.allocator); if (self.agent_error) |value| self.allocator.free(value); if (self.session_id) |value| self.allocator.free(value); if (self.cwd) |value| self.allocator.free(value); stopChildAndReap(&self.child, self.io_state.io()); self.io_state.deinit(); self.allocator.free(self.argv); } /// A caller reads the status to learn why reading stopped after /// `error.ReaderMessageCapacityExceeded`, or to watch how close the agent's lines come to the /// limit. The call returns a snapshot of the reader's limit, buffer size, bytes waiting, /// longest line seen, rejected lines, and whether reading has stopped. The package test reads /// it after an overlong line. pub fn readerStatus(self: *const Client) reader.Status { return self.reader.storage.status(); } /// A caller uses this call to stop the agent and everything it started at once. The client /// signals the agent's whole process group to terminate and then to die, so tools the agent /// started stop too. The call falls back to signalling the agent alone when signalling the /// group fails. The function sends no `session/cancel` message: the client sends that message /// only when a reply reaches a limit. The function returns without waiting for the agent to /// exit, and `deinit` waits for it later. The call returns at once when the process has already /// been reaped. A later call that reads from the agent finds its output closed and fails with /// `error.AgentProtocolError`. pub fn requestCancel(self: *Client) void { stopChild(&self.child, self.io_state.io()); } /// A caller calls `start` once after `init` and before the first prompt to open the /// conversation. The call sends `initialize` with protocol version 1, an empty set of client /// capabilities and the client's name, title and version, then waits for the answer. The /// function fails with `error.AgentProtocolError` when the agent answers with an error, a /// malformed result, or a protocol version other than 1. The client keeps the message of an /// error answer for `agentError`. The call stores the answer in the `initialize` field. The /// function then sends `session/new` with the working directory and the MCP servers, and stores /// the session id and the modes from the answer. Updates and permission requests that arrive /// meanwhile go through the observer as they do during a prompt. Calling it again runs both /// steps again and replaces the stored answer, session id and modes. The call can also fail /// with `error.RequestCapacityExceeded`, `error.ReaderMessageCapacityExceeded` and the errors /// listed at `promptDetailedContent` for messages that arrive meanwhile. pub fn start(self: *Client) !void { const initialize_id = self.nextRequestId(); try self.writeInitialize(initialize_id); var initialize_capture = PromptCapture{}; defer initialize_capture.deinit(self.allocator); var initialized = try self.readResponse(initialize_id, &initialize_capture); defer initialized.deinit(); _ = try self.responseResult(initialized.value); var initialize = try protocol.Initialize.fromResponse(self.allocator, initialized.value); errdefer initialize.deinit(self.allocator); if (initialize.protocol_version != 1) return error.AgentProtocolError; self.initialize.deinit(self.allocator); self.initialize = initialize; const session_id_request = self.nextRequestId(); if (self.cwd) |cwd| { try self.writeSessionNew(session_id_request, cwd); } else { const cwd = try sys.fs.cwdAlloc(self.allocator); defer self.allocator.free(cwd); try self.writeSessionNew(session_id_request, cwd); } var session_capture = PromptCapture{}; defer session_capture.deinit(self.allocator); var session = try self.readResponse(session_id_request, &session_capture); defer session.deinit(); _ = try self.responseResult(session.value); var modes = try protocol.Modes.fromResponse(self.allocator, session.value) orelse protocol.Modes{}; errdefer modes.deinit(self.allocator); if (self.session_id) |value| { self.allocator.free(value); self.session_id = null; } self.session_id = try self.extractSessionId(session.value); self.modes.deinit(self.allocator); self.modes = modes; } /// A caller uses this call for the common case of sending text and getting the reply text back. /// The call sends the text as one prompt and returns the reply: the text of the agent's message /// chunks, joined in arrival order. The caller owns the returned bytes and frees them with the /// client's allocator. The call drops the stop reason and any overflow record, which /// `promptDetailed` returns. The function fails as `promptDetailedContent` does. pub fn prompt(self: *Client, text: []const u8) ![]u8 { var result = try self.promptDetailed(text); const response = result.response; result.response = &.{}; result.deinit(self.allocator); return response; } /// A caller uses this call to send text and also learn why the agent stopped and whether the /// reply was cut short. The call sends the text as one text block and returns the reply, the /// stop reason and any overflow record. The caller frees the result with `PromptResult.deinit` /// and the client's allocator. The function fails as `promptDetailedContent` does. pub fn promptDetailed(self: *Client, text: []const u8) !protocol.PromptResult { const content = [_]protocol.PromptContent{.{ .text = text }}; return try self.promptDetailedContent(content[0..]); } /// A caller uses this call to send a prompt that carries files, links or media alongside text. /// The call sends one `session/prompt` request for the current session with the given blocks in /// order. The function fails with `error.AgentProtocolError` before `start` has set a session. /// The call reads until the prompt's response: each update goes to the observer, and agent /// message chunks join the reply within the reply limits. When one more chunk would pass a /// reply limit, the reply keeps what came before it, the result records the overflow, and the /// client sends one `session/cancel` and keeps waiting for the agent's final response. The call /// returns the reply, the agent's stop reason and the overflow record, and the caller frees the /// result with `PromptResult.deinit`. The function fails with `error.RequestCapacityExceeded` /// when the request is too large to send, and nothing is sent. The call fails with /// `error.UpdateCapacityExceeded` or `error.UpdateCountCapacityExceeded` for an update past a /// limit, `error.ReaderMessageCapacityExceeded` for a line past the line limit, /// `error.MissingDurableObserver` when a callback it needs is missing, and any error an /// observer callback returns. The call fails with `error.AgentProtocolError` for an error /// answer, a malformed message, or a response without a `stopReason`. The call reads the blocks /// and their strings only during the call. pub fn promptDetailedContent(self: *Client, content: []const protocol.PromptContent) !protocol.PromptResult { const session_id = self.session_id orelse return error.AgentProtocolError; const prompt_id = self.nextRequestId(); try self.writePrompt(prompt_id, session_id, content); var capture = PromptCapture{}; defer capture.deinit(self.allocator); var response = try self.readResponse(prompt_id, &capture); defer response.deinit(); const response_text = try capture.chunks.toOwnedSlice(self.allocator); errdefer self.allocator.free(response_text); const stop_reason = try self.extractPromptStop(response.value); errdefer self.allocator.free(stop_reason); return .{ .response = response_text, .stop_reason = stop_reason, .overflow = capture.overflow, }; } fn nextRequestId(self: *Client) i64 { const id = self.next_id; self.next_id += 1; return id; } /// A caller uses this call to show what the agent said after a call fails with /// `error.AgentProtocolError`. The call returns the message of the latest JSON-RPC error answer /// from the agent, or null when there has been none. The message stays until a later error /// answer replaces it, so a later success leaves it in place. When copying a new message fails /// for lack of memory, the client keeps the older message. The slice belongs to the client and /// stays valid until the next error answer or `deinit`. pub fn agentError(self: *const Client) ?[]const u8 { return self.agent_error; } fn recordAgentError(self: *Client, error_value: std.json.Value) void { const object = json.getObject(error_value) orelse return; const message = json.objectString(object, "message") orelse return; const owned = self.allocator.dupe(u8, message) catch return; if (self.agent_error) |previous| self.allocator.free(previous); self.agent_error = owned; } fn responseResult(self: *Client, value: std.json.Value) !std.json.ObjectMap { const object = json.getObject(value) orelse return error.AgentProtocolError; if (object.get("error")) |error_value| { self.recordAgentError(error_value); return error.AgentProtocolError; } const result = object.get("result") orelse return error.AgentProtocolError; return json.getObject(result) orelse return error.AgentProtocolError; } fn extractSessionId(self: *Client, value: std.json.Value) ![]u8 { const result = try self.responseResult(value); const session_id = json.objectString(result, "sessionId") orelse return error.AgentProtocolError; return try self.allocator.dupe(u8, session_id); } fn extractPromptStop(self: *Client, value: std.json.Value) ![]u8 { const result = try self.responseResult(value); const reason = json.objectString(result, "stopReason") orelse return error.AgentProtocolError; return try self.allocator.dupe(u8, reason); } fn writeInitialize(self: *Client, id: i64) !void { var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("id", id); try root.field("method", "initialize"); const params = try root.object("params"); try params.field("protocolVersion", 1); try params.field("clientCapabilities", .{}); const client_info = try params.object("clientInfo"); try client_info.field("name", self.info.name); try client_info.field("title", self.info.title); try client_info.field("version", self.info.version); try client_info.end(); try params.end(); try root.endLine(); try self.send(out.written()); } fn writeSessionNew(self: *Client, id: i64, cwd: []const u8) !void { var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("id", id); try root.field("method", "session/new"); const params = try root.object("params"); try params.field("cwd", cwd); try writeMcpServers(try params.array("mcpServers"), self.mcp_servers); try params.end(); try root.endLine(); try self.send(out.written()); } fn writePrompt( self: *Client, id: i64, session_id: []const u8, content: []const protocol.PromptContent, ) !void { var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("id", id); try root.field("method", "session/prompt"); const params = try root.object("params"); try params.field("sessionId", session_id); try writePromptContent(try params.array("prompt"), content); try params.end(); try root.endLine(); try self.send(out.written()); } fn writePromptContent(array: pretty_json.Array, content: []const protocol.PromptContent) !void { for (content) |item| try writePromptContentItem(array, item); try array.end(); } fn writePromptContentItem(array: pretty_json.Array, item: protocol.PromptContent) !void { switch (item) { .text => |text| { const object = try array.object(); try object.field("type", "text"); try object.field("text", text); try object.end(); }, .image => |media| try writePromptMedia(array, "image", media), .audio => |media| try writePromptMedia(array, "audio", media), .resource_text => |resource| try writePromptTextResource(array, resource), .resource_blob => |resource| try writePromptBlobResource(array, resource), .resource_link => |link| try writePromptResourceLink(array, link), } } fn writePromptMedia( array: pretty_json.Array, content_type: []const u8, media: protocol.PromptMedia, ) !void { const object = try array.object(); try object.field("type", content_type); try object.field("mimeType", media.mime_type); try object.field("data", media.data); try writeOptionalStringField(object, "uri", media.uri); try object.end(); } fn writePromptTextResource( array: pretty_json.Array, resource: protocol.PromptTextResource, ) !void { const object = try array.object(); try object.field("type", "resource"); const value = try object.object("resource"); try value.field("uri", resource.uri); try value.field("text", resource.text); try writeOptionalStringField(value, "mimeType", resource.mime_type); try value.end(); try object.end(); } fn writePromptBlobResource( array: pretty_json.Array, resource: protocol.PromptBlobResource, ) !void { const object = try array.object(); try object.field("type", "resource"); const value = try object.object("resource"); try value.field("uri", resource.uri); try value.field("blob", resource.blob); try writeOptionalStringField(value, "mimeType", resource.mime_type); try value.end(); try object.end(); } fn writePromptResourceLink(array: pretty_json.Array, link: protocol.PromptResourceLink) !void { const object = try array.object(); try object.field("type", "resource_link"); try object.field("uri", link.uri); try object.field("name", link.name); try writeOptionalStringField(object, "mimeType", link.mime_type); try writeOptionalStringField(object, "title", link.title); try writeOptionalStringField(object, "description", link.description); if (link.size) |size| try object.field("size", size); try object.end(); } fn writeOptionalStringField( object: pretty_json.Object, name: []const u8, value: []const u8, ) !void { if (value.len == 0) return; try object.field(name, value); } fn writeErrorResponse(self: *Client, id_value: std.json.Value) !void { var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("id", id_value); const error_value = try root.object("error"); try error_value.field("code", -32601); try error_value.field("message", "method not found"); try error_value.end(); try root.endLine(); try self.send(out.written()); } fn writePermissionResponse( self: *Client, id_value: std.json.Value, selection: PermissionSelection, ) !void { var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("id", id_value); const result = try root.object("result"); const outcome = try result.object("outcome"); try outcome.field("outcome", selection.outcome); try writeOptionalStringField(outcome, "optionId", selection.option_id); try outcome.end(); try result.end(); try root.endLine(); try self.send(out.written()); } fn writeCancel(self: *Client) !void { const session_id = self.session_id orelse return error.AgentProtocolError; var out: std.Io.Writer.Allocating = .init(self.allocator); defer out.deinit(); var stream = pretty_json.Writer.init(&out.writer, .minified); const root = try stream.object(); try root.field("jsonrpc", "2.0"); try root.field("method", "session/cancel"); const params = try root.object("params"); try params.field("sessionId", session_id); try params.end(); try root.endLine(); try self.send(out.written()); } fn send(self: *Client, bytes: []const u8) !void { if (bytes.len > self.transfer_limits.request_bytes) { return error.RequestCapacityExceeded; } const stdin = self.child.stdin orelse return error.AgentTransportFailed; try fileWriteAll(self.io_state.io(), stdin, bytes); } fn selectPermission(self: *Client, object: std.json.ObjectMap) !OwnedSelection { if (self.observer) |observer| { if (observer.permissionFn != null) { var preview = try protocol.PermissionRequest.fromClientRequest( self.allocator, object, "", "pending", "", "", ); defer preview.deinit(self.allocator); if (observer.permission(preview)) |reply| { var owned = OwnedSelection{ .allocator = self.allocator, .selection = .{ .outcome = "cancelled" } }; errdefer owned.deinit(); owned.outcome = try self.allocator.dupe(u8, reply.outcome); owned.option_id = try self.allocator.dupe(u8, reply.option_id); owned.option_kind = try self.allocator.dupe(u8, reply.option_kind); owned.selection = .{ .outcome = owned.outcome.?, .option_id = owned.option_id.?, .option_kind = owned.option_kind.?, }; return owned; } } } return .{ .allocator = self.allocator, .selection = permissionSelection(object, self.permission_policy) }; } fn readResponse(self: *Client, id: i64, capture: *PromptCapture) !std.json.Parsed(std.json.Value) { while (try self.reader.nextLine()) |line| { const trimmed = std.mem.trim(u8, line, " \t\r\n"); if (trimmed.len == 0) continue; var parsed = std.json.parseFromSlice(std.json.Value, self.allocator, trimmed, .{}) catch return error.AgentProtocolError; if (isResponseFor(parsed.value, id)) return parsed; if (try self.handleIncoming(parsed.value, trimmed, capture)) { parsed.deinit(); continue; } parsed.deinit(); return error.AgentProtocolError; } return error.AgentProtocolError; } fn handleIncoming( self: *Client, value: std.json.Value, envelope: []const u8, capture: *PromptCapture, ) !bool { const object = json.getObject(value) orelse return false; if (json.objectString(object, "method")) |method| { if (std.mem.eql(u8, method, "session/update")) { const update_sequence = self.next_update_sequence; if (update_sequence > self.transfer_limits.update_count) { return error.UpdateCountCapacityExceeded; } if (envelope.len > self.transfer_limits.update_bytes) { return error.UpdateCapacityExceeded; } self.next_update_sequence = std.math.add( u64, update_sequence, 1, ) catch return error.UpdateCountCapacityExceeded; var update = (try protocol.Update.fromSessionNotification( self.allocator, object, self.transport_epoch, update_sequence, envelope, )) orelse return error.AgentProtocolError; defer update.deinit(self.allocator); const observer = self.observer orelse return error.MissingDurableObserver; try observer.update(update); if (try capture.appendResponse( self.allocator, update, self.transfer_limits, )) try self.writeCancel(); return true; } if (std.mem.eql(u8, method, "session/request_permission")) { const id_value = object.get("id") orelse return false; var selection = try self.selectPermission(object); defer selection.deinit(); var request = try protocol.PermissionRequest.fromClientRequest( self.allocator, object, envelope, selection.selection.outcome, selection.selection.option_id, selection.selection.option_kind, ); defer request.deinit(self.allocator); const observer = self.observer orelse return error.MissingDurableObserver; try observer.commitPermission(request); try self.writePermissionResponse(id_value, selection.reply()); return true; } if (object.get("id")) |id_value| { try self.writeErrorResponse(id_value); return true; } return true; } return false; }};Source: lib/acp/src/root.zig:66
zig
pub const Client = client.Client;Complete caller list for Client.deinit
11 direct callers.
lib.acp.src.client.test_client_allows_granted_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1414in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_allows_granted_MCP_tool_titles_without_a_kind[function] — test source atlib/acp/src/client.zig:1452in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_cancellation_kills_process_group[function] — test source atlib/acp/src/client.zig:1646in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_collects_ACP_agent_message_chunks[function] — test source atlib/acp/src/client.zig:1197in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_commits_admitted_response_segments_and_settles_overflow[function] — test source atlib/acp/src/client.zig:1607in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_frames_every_official_ACP_v1_session_update_variant_exactly_once[function] — test source atlib/acp/src/client.zig:1315in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_initialize_capabilities[function] — test source atlib/acp/src/client.zig:1232in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_session_updates[function] — test source atlib/acp/src/client.zig:1261in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_refuses_an_oversized_request_before_forwarding[function] — test source atlib/acp/src/client.zig:1579in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_and_records_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1371in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_oversized_ACP_output_before_parsing[function] — test source atlib/acp/src/client.zig:1523in nearest public ownertiny.acp.client
Complete caller list for Client.init
12 direct callers.
lib.acp.src.client.test_client_admits_reader_capacity_before_spawning_the_agent[function] — test source atlib/acp/src/client.zig:1499in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_allows_granted_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1414in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_allows_granted_MCP_tool_titles_without_a_kind[function] — test source atlib/acp/src/client.zig:1452in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_cancellation_kills_process_group[function] — test source atlib/acp/src/client.zig:1646in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_collects_ACP_agent_message_chunks[function] — test source atlib/acp/src/client.zig:1197in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_commits_admitted_response_segments_and_settles_overflow[function] — test source atlib/acp/src/client.zig:1607in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_frames_every_official_ACP_v1_session_update_variant_exactly_once[function] — test source atlib/acp/src/client.zig:1315in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_initialize_capabilities[function] — test source atlib/acp/src/client.zig:1232in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_session_updates[function] — test source atlib/acp/src/client.zig:1261in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_refuses_an_oversized_request_before_forwarding[function] — test source atlib/acp/src/client.zig:1579in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_and_records_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1371in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_oversized_ACP_output_before_parsing[function] — test source atlib/acp/src/client.zig:1523in nearest public ownertiny.acp.client
Complete caller list for Client.promptDetailed
7 direct callers.
tiny.acp.Client.prompt[method] atlib/acp/src/client.zig:559lib.acp.src.client.test_client_allows_granted_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1414in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_allows_granted_MCP_tool_titles_without_a_kind[function] — test source atlib/acp/src/client.zig:1452in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_commits_admitted_response_segments_and_settles_overflow[function] — test source atlib/acp/src/client.zig:1607in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_frames_every_official_ACP_v1_session_update_variant_exactly_once[function] — test source atlib/acp/src/client.zig:1315in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_session_updates[function] — test source atlib/acp/src/client.zig:1261in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_and_records_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1371in nearest public ownertiny.acp.client
Complete caller list for Client.start
10 direct callers.
lib.acp.src.client.test_client_allows_granted_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1414in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_allows_granted_MCP_tool_titles_without_a_kind[function] — test source atlib/acp/src/client.zig:1452in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_collects_ACP_agent_message_chunks[function] — test source atlib/acp/src/client.zig:1197in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_commits_admitted_response_segments_and_settles_overflow[function] — test source atlib/acp/src/client.zig:1607in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_frames_every_official_ACP_v1_session_update_variant_exactly_once[function] — test source atlib/acp/src/client.zig:1315in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_initialize_capabilities[function] — test source atlib/acp/src/client.zig:1232in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_preserves_ACP_session_updates[function] — test source atlib/acp/src/client.zig:1261in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_refuses_an_oversized_request_before_forwarding[function] — test source atlib/acp/src/client.zig:1579in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_and_records_ACP_permission_callbacks[function] — test source atlib/acp/src/client.zig:1371in nearest public ownertiny.acp.clientlib.acp.src.client.test_client_rejects_oversized_ACP_output_before_parsing[function] — test source atlib/acp/src/client.zig:1523in nearest public ownertiny.acp.client
Complete call list for Client.start
10 direct calls.
lib.acp.src.client.Client.extractSessionId[method] — private source atlib/acp/src/client.zig:645in nearest public ownertiny.acp.clientlib.acp.src.client.Client.nextRequestId[method] — private source atlib/acp/src/client.zig:611in nearest public ownertiny.acp.clientlib.acp.src.client.Client.readResponse[method] — private source atlib/acp/src/client.zig:887in nearest public ownertiny.acp.clientlib.acp.src.client.Client.responseResult[method] — private source atlib/acp/src/client.zig:635in nearest public ownertiny.acp.clientlib.acp.src.client.Client.writeInitialize[method] — private source atlib/acp/src/client.zig:657in nearest public ownertiny.acp.clientlib.acp.src.client.Client.writeSessionNew[method] — private source atlib/acp/src/client.zig:678in nearest public ownertiny.acp.clienttiny.acp.Initialize.deinit[method] atlib/acp/src/protocol.zig:72tiny.acp.Initialize.fromResponse[function] atlib/acp/src/protocol.zig:86tiny.acp.Modes.deinit[method] atlib/acp/src/protocol.zig:135tiny.acp.Modes.fromResponse[function] atlib/acp/src/protocol.zig:148
Audit
| Definitions | 10 |
|---|---|
| Public names | 20 |
| Members | 18 |
| Version | 26.7.0 |
| Revision | daab053ee433 |