Skip to main content

Crate canact

Crate canact 

Source
Expand description

Probe an LLM and return host policy (max_tools, edit format, XML, JSON).

Structs§

CacheEntry
A cached probe result together with the time it was stored.
CapabilityProfile
Complete capability profile for a model.
HostPolicyMeta
Session knobs for CapabilityProfile::host_policy_envelope_with.
ProbeCache
File-based probe cache keyed by model|provider|effort|suite|cost|vision|ctx.
ProbeResult
Individual probe result.

Enums§

CapabilityLevel
Capability level for a probe dimension.
EditFormatRecommendation
Recommended edit format based on probe results.
ProbeError
Errors that can occur during probing or cache I/O.

Constants§

ANTHROPIC_BASE_URL
Anthropic OpenAI-compatible listener (--provider claude / anthropic).
CACHE_TTL_SECS
How long a cached entry remains valid (30 days in seconds).
CORE_DIMENSION_NAMES
Default human table only. Includes xml_tool_calling, omits tool_selection. Not a ToolRequirements zip.
DEFAULT_PROBE_EFFORT
Default effort label when probes leave reasoning_effort unset.
DEFAULT_SKIP_EXPENSIVE
Default cost knob: paid/full suite (skip_expensive = false).
DEFAULT_VISION
Default vision knob: vision probe not requested.
DIMENSION_NAMES
All probed dimension names, in the order they appear on the struct.
LMSTUDIO_BASE_URL
LM Studio’s OpenAI-compatible listener.
OLLAMA_BASE_URL
Ollama’s OpenAI-compatible listener.
PROBE_SUITE_VERSION
Bump when probe identity/scoring changes enough to invalidate old entries. v2: #1336 rename, #1337 multi-turn probe, #1339 system adherence redesign. v3: transient stream/tool probe errors are not 30-day Weak/Medium. v4: context-faithfulness timeout synonyms (#3317). v5: generic edit_file on tool_selection is not 30-day Weak/max_tools=10 (#3315). v6: forceful tool-call prompts (Goose #6281) and stricter arg schema. v7: persisted effective_context_tokens ladder. v8: token_efficiency prefers live ProbeResponse usage when present. v9: cheap ladder is not a finished size; vision refusal beats “text”; synthesized error Medium does not open can_use_tools. v10: empty instruction-following is Weak; vision color-only refusal is Weak; SSE late tool name still emits ToolCallStart. v11: synthesized error Medium does not open host policy (vision, XML fallback, edit format, meets); o-series chat uses max_completion_tokens and omits temperature. v12: empty token_efficiency is Weak; SSE tool_calls indexes each emit ToolCallStart. v13: chat parse accepts legacy function/function_call; complex two-name imprecise args are Medium; ladder heartbeat accepts 2,840. v14: SSE function_call deltas emit starts; empty max_tokens compliance is Weak; parallel numeric paths are Medium. v15: JSON fence language tags; streaming Strong requires read_file; system-adherence details are UTF-8 safe. v16: one_shot_tool_plan and tool_selection Strong require non-empty string args on preferred tools. v17: whitespace-only args are not Strong; tool_selection scores the best same-name call; one_shot order uses first precise call; tool_calling/xml/streaming reject empty path. v18: remaining tool probes reject empty/whitespace string args; tool_selection doc_set Strong requires a present non-null value. v19: multi_turn_task_sequencing Strong requires nonempty string args; token_efficiency empty text is Weak even when usage is 1-10. v20: tool_selection Strong requires all three preferred tools precise; empty/whitespace doc_set value is not precise; json_output Strong requires nonempty word and reversed. v21: streaming_tool_calls Strong requires a string path on the read_file start that produced the args (no other-tool merge); search_replace / unified_diff Strong require the edit bodies (not whole-response contains) to hold greet/Hello and welcome/Welcome. v22: json_output Strong requires word=hello, length=5, reversed=olleh (prompt example is not Strong); stream ignores leftover function_call when tool_calls is present; vision “no text” is Weak. v23: vision Strong requires a standalone bl token (not black); tool-arg strings reject ZWSP-only values; unprobed default dimensions do not open host policy. v24: XML format-card echo and tag mention do not open canUseTools; SEARCH/REPLACE Strong requires fn greet / fn welcome; unified_diff Medium requires hunk or file headers (not a markdown +/- list); vision Medium surface words are tokens (not whitespace / context). v25: vision “no letters” / “no characters” is Weak; a closed XML block that only mentions <name>read_file</name> without <arguments> does not open canUseTools. v26: closed XML Medium requires arguments that open {; vision “don’t see letters” is Weak; SEARCH/REPLACE Strong requires fn greet( / fn welcome(. v27: vision question echo, unified-diff format-card echo, and XML JSON Schema paste do not open host policy. v28: unified_diff headers and hunks must start a line (prose --- / +++ / @@ is Weak). v29: vision “text-only” / “black box” is Weak; XML {"path":"value"} is format-card echo. v30: vision “no visible” is Weak; an unclosed <tool_call> does not open tools from a read_file name before the tag. v31: json_output does not peel an array wrapper to reach a valid object (array-wrapped JSON must not skip repair). v32: tool_calling empty or whitespace function.name is Weak (does not open can_use_tools). v33: SEARCH/REPLACE Strong ignores // comment tokens (fn greet( / Hello in comments is not a rename). v34: xml_tool_calling empty or whitespace <name> is Weak (does not open can_use_tools). v35: unified_diff Strong requires fn greet / fn welcome in code +/- lines; comment-only +/- is Weak (not UnifiedDiff). v36: SEARCH/REPLACE and unified_diff ignore /* */ comment tokens the same way as // comments. v37: tool names that are only ZWSP/format marks are Weak (same as empty names for can_use_tools). v38: vision “text model” / “processes text” is Weak (does not set supportsVision). v39: vision “text-based” / “work with text” / “isn’t any text” is Weak. v40: unified_diff format-card body (removed line / added line) is Weak even when the path is greet.rs. v41: vision “no visible letters” / “doesn’t contain letters” is Weak (does not set supportsVision). v42: unified_diff title-case format-card body (Removed line / Added line) is Weak. v43: vision “white space” / “white-box” / “text-processing” is Weak (does not set supportsVision). v44: SEARCH/REPLACE and unified_diff ignore # comment tokens the same way as // (# fn greet is not a rename). Rust attributes (#[derive]) are not comments. v45: XML {"param":"value"} plus extra keys, or {'param':'value'}, is format-card echo (does not set canUseTools). v46: vision “no visible characters” / “no discernible text” / “white-space” is Weak (does not set supportsVision). v47: XML array-wrapped [{"param":"value"}] and unclosed param/value cards are format-card echo (do not set canUseTools). v48: vision “no discernible characters” / “aren’t any characters” is Weak (does not set supportsVision). v49: unified_diff format-card body (remove line / add line) is Weak. v50: XML multi-element [{"param":"value"},{"param":"value"}] is format-card echo (does not set canUseTools). v51: unified_diff hyphenated or double-space format-card body (removed-line / added-line, removed line / added line) is Weak. v52: XML nested {"payload":{"param":"value"}}, JSON-string wrap "{\"param\":\"value\"}", and {"param":["value"]} are format-card echo (do not set canUseTools). v53: XML card keys and value compare case-insensitively (Param/Value / path":"Value" is echo, not canUseTools). v54: unified_diff underscore format-card body (removed_line / added_line) is Weak. v55: XML {"path":["value"]} and padded "value " are format-card echo (do not set canUseTools). v56: unparseable {'path':'value'} is format-card echo (does not set canUseTools). v57: XML card value ignores ZWSP/format marks ("value\\u200b" is echo, not canUseTools). v58: unparseable {'path':'Value'} is format-card echo (does not set canUseTools). v59: XML card keys ignore ZWSP/format marks ("path\\u200b" is echo, not canUseTools). v60: XML card value (fullwidth) is echo (does not set canUseTools). v61: unparseable {p\\u200bath:'value'} is format-card echo (does not set canUseTools). v62: unified-diff card removed\\u{200B}line is echo (does not set UnifiedDiff). v63: vision no\\u{200B} text is a refusal (does not set supportsVision). v64: vision don\\u{200B}'t / can\\u{200B}'t is a refusal (does not set supportsVision). v65: cheap skip is not a measured Medium (envelope status + completed_level); persist probed_context_floor; CLI envelope cacheable/skipExpensive. v66: adapter strips / thinking parts so CoT is not graded. v67: Length + no tool call is truncated (uncacheable), not 30-day Weak. v68: recommendedContextTokens = min(advertised, measured); advertised in cache key. v69: Length + incomplete tool/XML is truncated, not 30-day Medium. v70: stream Length is truncated (uncacheable), not 30-day Weak/Medium. v71: Length on JSON / edit / vision / instruction / context ladder is truncated, not a 30-day host-policy card. v72: instruction_following Strong requires the asked capital. v73: blank-path parallel reads no longer outrank valid paths; Length on code/faithfulness/memory/system is uncacheable; SSE buffers bytes so split UTF-8 is not corrupted. v74: vision Strong requires no refusal; code_syntax ignores docstring ...; empty Length on max_tokens is Transient. v75: memory refusals are Weak; code_syntax uses the merge fence; JSON length 5.0; XML/unified-diff pick a real edit over a card; fenced Paris; ladder 2.84s; Length-empty token_efficiency Transient. v76: tool_calling Strong if any call is read_file + path (not only first). v77: json_output scores the best object, not only the first fence. v78: SEARCH/REPLACE parses without —––; unified-diff Strong requires Hello/Welcome in the +/- body. v79: stream string indexes, numeric tool ids, array content, finish_reason on delta, capped error bodies. v80: JSON length “5”; port 9,847; old_text aliases; XML path child. v81: STATUS: ok space-fold; code_syntax ignores comment return and requires def merge_sorted. v82: nested edit path alias; XML file_path JSON alias. v83: vision cannot-read BL; memory cannot-share; numeric chat tool id; incremental success-body cap. v84: vision unable/can-not-read; memory unable-to-recall; docstring return; merge_sorted fence; native file_path; stream JSON Transient; loopback provider URL. v85: stream strips think/reasoning; ZWSP stream names; file_path alias on streaming/parallel/sequencing; search_replace ORs split edits; XML bare path is 0.4; advertised probe isolation; export provider aliases; overlay prefixes slash models; looks_cheap uses host hint; code_syntax strips quotes; nested_arguments pick-best; memory ZWSP refusals. v86: code_syntax unfenced prose; memory can-not/reveal/forgotten; vision no-readable / not-able-to-read; second != milliseconds; 0.0.0.0 is ollama; export strips provider prefix; knob aliases. v87: code_syntax fenced name-only; extract prefers def merge_sorted(; colon-in-prose name-drops are not a signature; multi_turn requires read<edit<run turns; MCP stdio NDJSON. v88: code_syntax sentence-with-paren is not a def; English paren contents, same-line prose after colon, and English return phrases (same-line or indented) stay Weak; extract falls back when no fence is a real def; path-once SEARCH/REPLACE; array-then-object JSON pick-best; memory not-able/can-not- repeat/I forgot; vision identify/make-BL-out/can-not; msec unit; file_path on sequencing edit, one-shot, and selection tasks. v89: typed merge_sorted signatures and defaults; extract picks complete fence over stub; return must be in merge_sorted body; lecture-line return is Weak; JSON nested objects and object before fenced array; memory provide/tell/should-not refusals; vision cannot-recognize. v90: wrapped typed merge_sorted, trailing commas, and args are real defs; ellipsis assignment is not Strong; lecture fn greet( is not SearchReplace; TOOL_NAME plus a real path is Medium; vision don’t/do not/recognise and curly apostrophes; memory not-able/not-allowed/won’t/should-not on provide/tell/repeat (including won’t tell); recognize-the-font hedge stays Strong. v91: hash comments in wrapped typed defs; start-of-line lecture signatures; array-wrapped hello after an example object; vision could-not / did-not-see / make-out plus letters Medium; this/that font hedges; memory hyphenless code and more refusals; minutes are not the planted ms fact; XML file_path=value echo. v92: these/those font hedges; past-tense recognize/identify; memory didn’t-recall / I’d-forgotten; hyphenless warehouse and proto; hours and 1750 minutes are not the planted ms fact; trailing- comma or commented array wrap stays Weak. v93: leftover lecture verbs after -> Type; letters plus cannot-read is Medium; identify-the-font and a/any typeface stay Strong; cannot-quite-read and not-readable are not Strong; memory say/give/wouldn’t/permitted/retrieve/no-longer; 1750/2840 seconds are not the planted ms fact. v94: JSON string-wrapped hello stays Weak; loopback :11434 shares the ollama cache family; MCP isError only on actual tool failures. v95: xai/grok/api.x.ai share the xai cache family; api.x.ai requires a key; 400 incorrect-key is Auth. v96: claude/anthropic/api.anthropic.com share the anthropic family; Anthropic OAuth headers; ANTHROPIC_ keys.
REQUIREMENT_DIMENSION_NAMES
First 9 of DIMENSION_NAMES. Zips 1:1 with Bline ToolRequirements::as_slice(). Do not zip CORE_DIMENSION_NAMES against that slice.
TOOL_PROBE_NAMES
Probe names scored Weak when the provider reports “does not support tools”. Shared by resolve_probe and stale-cache migration.
VLLM_BASE_URL
Common vLLM OpenAI-compatible listener.
XAI_BASE_URL
xAI OpenAI-compatible listener (--provider xai / grok).

Functions§

classify
Classify a normalized score (0.0..=1.0) into a capability level.
cloud_endpoint_requires_key
Cloud hosts that must not be called without an API key.
default_compat_base_url
Base URL when --base-url is omitted.
is_anthropic_cloud_host
True when extra Anthropic headers are required (OAuth + version).
is_anthropic_provider_label
--provider claude / anthropic / api.anthropic.com.
is_ollama_compat_base
True when {base} is an Ollama OpenAI-compat listener (*:11434).
is_xai_provider_label
--provider xai / grok / api.x.ai (not a loopback host).
local_provider_base_url
Local-provider default when the user omitted --base-url.
looks_cheap
missing_model_message
--model is required because GET /models did not return exactly one id.
provider_from_base_url
True when the host or model looks local/free so the cheap suite is enough. Host label used as provider when the user omitted --provider. Loopback URLs keep host:port so different listeners do not share a cache row.