跳到內容
Crystal CodeDocs
繁繁體中文

Crystal consumption

本頁內容尚未翻譯。

The interactive turn uses IStreamingChatClient and ToolExecutor. When the selected model declares imageInput and its adapter supports it, the session uses IStreamingMultimodalChatClient and a host executor that preserves the same approval policy. The session owns those clients and may replace them on /model. It does not use Crystal.Agents.Agent for the live UI: that Agent completes model turns without token streaming.

The live session does not yet use Crystal.Harness.AgentHarness. Parent/child Agent composition is deferred product work; when that topology is implemented, the host consumes AgentHarness for named invocation ancestry and shared budgets while retaining ownership of prompts, tools, approval, persistence, and the terminal projection.

Approval is a ToolInvocationPolicy supplied to ToolExecutor. Rejection returns Harness-authored ToolOutput. Tool exceptions become model-visible only through a Harness ToolExceptionMapper.

CrystalCode.Engine owns image attachment, MIME signature validation, session persistence, transcript markers, and projection onto Crystal’s typed multimodal contracts. A front end owns only how it presents and edits the markers in its composer. [Image #N] is presentation and persistence metadata; providers receive typed ImageContent, never a marker in place of its bytes. Pasted markers are atomic composer spans with a distinct color: cursor movement and deletion cannot leave a partial attached marker. User-entered text with the same spelling remains plain text. On submission, only attached spans receive an invisible provenance prefix; only prefixed markers in transcript items produce model images. The prefix is removed for display and text-only model requests. Session JSON records whether markers have this prefix. Older sessions without that flag tag references to their saved images on load, preserving their prior semantics. Deleted unsent images are discarded immediately while idle and at submission during an active turn. Workspace and clipboard images are checked against the 20 MiB limit and validated by MIME signature before they enter the session; the media store validates again before writing. Saved image bytes live in owner-only, content-addressed files under ~/.crystal/media/<sha256>. Session JSON stores the hash and MIME type, not Base64 bytes. The media file is written before the session references it, and both writes use a temporary file followed by an atomic replacement. Sessions persist only images referenced by the archive or the model context. A missing, truncated, or modified media file is skipped on resume while the text and other attachments remain available; the operator receives a note, and its reference is retained on later saves so restoring the file can repair the session. Inline data is a supported session representation; local saves move its image bytes to the media store. JSON session export retains marker provenance and inlines available image bytes in data so its contents do not depend on Home media files. If a referenced media file is unavailable, its metadata remains in the export but bytes cannot be included. The store does not automatically delete unreferenced media files. Inline image bytes and absolute image URIs are supported. Images returned by an in-process plugin, a dotnet operator tool’s native IMultimodalTool path, or an exec tool with "output": "content" are assigned the same markers and become input on the following model round. A text-only turn rejects exec image results instead of dropping them. Clipboard paste reserves its image number before waiting for the OS reader. Tool images reserve numbers through the same session lock, which also protects image lookup and mutation. A failed paste leaves a gap rather than reusing its number. Input batches dispatch keys in order, so Ctrl+V finishes attaching before a following Enter submits the prompt. Dotnet multimodal tools are omitted from active catalogs when the selected model or provider does not support image input. Declared audioInput or videoInput does not keep them. describe_image is a text tool on Plan and Work when config.json imageModel names a provider and model whose catalog entry has imageInput. It sends that file to a side multimodal client with the image-description prompt and returns the reply as text. The side request has no tools, is not written into the session transcript, and uses imageModel.thinkingEffort through the same gear mapping as the host. view_image is registered only for an image-capable turn. It returns the file as ImageContent so the current model sees it on the next round. Both follow the read path fence. A missing image-model credential fails the tool call and does not block session start.

The Responses, OpenAI-compatible Chat Completions, DeepSeek Chat Completions, Anthropic Messages, Gemini GenerateContent, and Ollama Chat adapters accept text and image input and emit only text, reasoning, and tool-call events. The native Gemini adapter sends tool-result images as inlineData parts on functionResponse. That is the Gemini 3 multimodal function-response field; an older model may reject the request. The native Ollama adapter sends them on the tool message images array. Transcripts keep markers either way. Chat Completions and Anthropic images are restricted to user and tool messages, matching their wire contracts. Clipboard image input is read through Windows PowerShell on Windows, the macOS system osascript command on macOS, and wl-paste or xclip on Linux; it does not capture the screen. Windows reads clipboard PNG bytes before falling back to bitmap conversion, and passes Base64 text from PowerShell to the host. macOS tries PNG, JPEG, and GIF clipboard representations in that order. Linux checks advertised clipboard types and tries PNG, JPEG, GIF, and WebP in that order. Reader output and temporary files are bounded by the image size limit. A missing reader, an empty image clipboard, unsupported image bytes, an oversized image, and a reader failure have separate operator errors. Reader commands are optional at runtime, and their absence does not prevent the application from starting. A model must opt in with imageInput: true; unsupported combinations are rejected before sending a request. audioInput and videoInput are stored declarations. They are published on plugin model facts and on PluginClientRequest, and they do not change adapter capabilities, tool registration, attachment, persistence, or the outbound request. Selected service tiers and speeds are also published on both contracts; a custom protocol factory must apply a non-null slot or reject it when the client is created. Built-in adapters still accept only text and image input. Accepting audio or video, and non-text model output, remain TODO. MCP media transport is TODO.

CrystalCode does not capture screenshots, control browsers, phones, virtual machines, interpret coordinates, or define frame/device protocols. External plugins own those behaviors and may return ordinary typed images through the generic tool boundary.