Expand description
Model inventory, opaque selectors, and reasoning settings. Backend-advertised model, personality, and reasoning selectors.
Selectors preserve their exact strings. Construction validates shape, not
availability; use crate::AgentBackend::list_models for the selected
backend’s inventory. ModelInfo reports optional backend metadata without
turning it into a cross-provider capability promise.
§Supplied selector restrictions
| Backend | Reasoning | Personality |
|---|---|---|
| Codex | Exact effort advertised for the selected model | Rejected: the selected native protocol retired personality selection |
| OpenCode | Portable override is Unsupported | Portable override is Unsupported |
| Custom | minimal, low, medium, high, maximum, mapped to Provider’s portable reasoning enum | Unsupported |
Custom’s selected Provider Model still validates whether it can honor the
mapped effort. Arbitrary native efforts such as xhigh are not a Custom
escape hatch. An omitted override stays omitted at the Agent request boundary;
effective values also depend on conversation/workspace defaults. Availability
of a model name or a syntactically valid selector is not execution evidence.
Caller implementations may support their own advertised selectors.
§Exact Codex selection
This example requires the supported Codex executable on PATH, native
authentication and access to the exact model. Building starts a subprocess;
listing and prompting use the real native service, so this compiles without
running as a doctest. No caller Provider is constructed for a native Agent.
#![recursion_limit = "256"] // Nested concrete async futures need this on Linux.
use std::{num::NonZeroUsize, time::Duration};
use agents_kit::{AgentBackend, AgentBuilder, AgentStorage, ConversationBackend, WorkspaceBackend};
use agents_kit::config::{AgentConfig, CodexConfig};
use agents_kit::conversation::NewConversation;
use agents_kit::model::{ModelSelector, ReasoningEffort};
use agents_kit::prompt::PromptRequest;
use agents_kit::workspace::{NewWorkspace, WorkspaceContext, WorkspaceDefaults,
WorkspaceExecutionPolicy, WorkspaceNetworkAccess, WorkspaceRoot,
WorkspaceRootAccess, WorkspaceSandboxMode};
use storage_kit::{StateStore,
state::config::{LanceStateStoreConfig, StateStoreConfig}};
let store = StateStore::connect(StateStoreConfig::Lance(LanceStateStoreConfig::memory())).await?;
let config = AgentConfig::new(CodexConfig::spawn(Duration::from_secs(15),
Duration::from_secs(90))?.into(), Duration::from_secs(60), NonZeroUsize::MIN)?;
let agent = AgentBuilder::create(config, AgentStorage::new(store)).build().await?;
let outcome = async {
let selected = ModelSelector::new("gpt-6-luna")?;
let effort = ReasoningEffort::medium();
let inventory = agent.list_models().await?;
let model = inventory.iter().find(|item| item.selector() == &selected)
.ok_or_else(|| agents_kit::KitError::unsupported("required exact model is unavailable"))?;
if !model.reasoning_efforts().contains(&effort) {
return Err(agents_kit::KitError::unsupported("required effort is unavailable").into());
}
let cwd = std::env::current_dir()?;
let context = WorkspaceContext::new(cwd.clone(),
vec![WorkspaceRoot::new(cwd, WorkspaceRootAccess::ReadOnly)?],
WorkspaceExecutionPolicy::new(WorkspaceSandboxMode::ReadOnly, WorkspaceNetworkAccess::Disabled))?;
let workspace = agent.new_workspace(NewWorkspace::new("review", context, WorkspaceDefaults::empty())?).await?;
let work = async {
let request = PromptRequest::new("Describe the current task without changing files.")?
.with_model(selected).with_reasoning_effort(effort)
.with_timeout(Duration::from_secs(90))?;
let conversation = workspace.new_conversation(NewConversation::new(None, None, vec![])?).await?;
let response = conversation.prompt(request).await;
let close = conversation.close().await;
let response = match (response, close) {
(Ok(response), Ok(())) => Ok(response),
(Err(primary), Err(cleanup)) => Err(primary.with_supplementary(cleanup)),
(Err(error), _) | (_, Err(error)) => Err(error),
}?;
assert!(!response.output().trim().is_empty()); // progress, not a prescribed wording grade
Ok::<(), agents_kit::KitError>(())
}.await;
let close = workspace.close().await; // also runs if conversation creation failed
match (work, close) {
(Err(primary), Err(cleanup)) => Err(primary.with_supplementary(cleanup)),
(Err(error), _) | (_, Err(error)) => Err(error),
(Ok(()), Ok(())) => Ok(()),
}
}.await;
let shutdown = agent.shutdown().await;
match (outcome, shutdown) {
(Err(primary), Err(cleanup)) => Err(primary.with_supplementary(cleanup)),
(Err(error), _) | (_, Err(error)) => Err(error),
(Ok(()), Ok(())) => Ok(()),
}?;Structs§
- Model
Info - Describes one selectable model returned by agent inventory.
- Model
Selector - Selects one backend model by its canonical opaque value.
- Personality
Selector - Selects one backend-advertised personality by its canonical opaque value.
- Reasoning
Effort - Describes an open-ended backend reasoning-effort value.