Files
Genarrative/server-rs/crates/agent-runtime-core/src/profile.rs
T
AIGameCreator App d4075c3423
Project CI / Frontend tests (push) Failing after 3m43s
Project CI / Native shell tests (push) Failing after 3m36s
Project CI / Repository checks (push) Failing after 4m36s
Project CI / Backend tests (push) Successful in 8m36s
抽取通用多智能体运行时与可扩展Provider
新增纯 Rust agent-runtime-core,提供运行时契约、能力注册、Agent 目录、Profile、完成策略与零重放恢复
抽取中立 LLM Provider 协议与可扩展 Registry,并适配 OpenAI Responses、OpenAI Chat 和 Anthropic
将 AGC interaction、Provider 控制、Runner 生命周期、steering 与 tool-plan handoff 接入统一运行时边界
补充非游戏消费者、Provider 网络闭环、Runtime 恢复及 GUI Runner owner 测试
同步 Cargo/npm 门禁、Runtime 技术方案和项目共享记忆
2026-07-30 16:15:51 +08:00

135 lines
4.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use std::collections::{BTreeMap, BTreeSet};
use serde_json::{Map, Value};
use crate::capability::CapabilityRegistry;
use crate::catalog::collect_unique_capability_ids;
use crate::contract::{ContractError, ContractErrorKind, validate_identifier, validate_metadata};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RunProfileDefinition {
id: String,
capability_ids: Vec<String>,
completion_policy_id: String,
metadata: Value,
}
impl RunProfileDefinition {
pub fn try_new(
id: impl Into<String>,
capability_ids: impl IntoIterator<Item = impl Into<String>>,
completion_policy_id: impl Into<String>,
) -> Result<Self, ContractError> {
let id = id.into();
let completion_policy_id = completion_policy_id.into();
validate_identifier(&id, "run profile id")?;
validate_identifier(&completion_policy_id, "completion policy id")?;
let capability_ids = collect_unique_capability_ids(capability_ids, "run profile")?;
Ok(Self {
id,
capability_ids,
completion_policy_id,
metadata: Value::Object(Map::new()),
})
}
pub fn with_metadata(mut self, metadata: Value) -> Result<Self, ContractError> {
validate_metadata(&metadata, "run profile metadata")?;
self.metadata = metadata;
Ok(self)
}
pub fn id(&self) -> &str {
&self.id
}
pub fn capability_ids(&self) -> &[String] {
&self.capability_ids
}
pub fn completion_policy_id(&self) -> &str {
&self.completion_policy_id
}
pub fn metadata(&self) -> &Value {
&self.metadata
}
}
#[derive(Clone, Debug)]
pub struct RunProfileCatalog {
profiles: Vec<RunProfileDefinition>,
by_id: BTreeMap<String, usize>,
}
impl RunProfileCatalog {
pub fn try_new(
profiles: impl IntoIterator<Item = RunProfileDefinition>,
) -> Result<Self, ContractError> {
let profiles = profiles.into_iter().collect::<Vec<_>>();
let mut by_id = BTreeMap::new();
for (index, profile) in profiles.iter().enumerate() {
if by_id.insert(profile.id.clone(), index).is_some() {
return Err(ContractError::new(
ContractErrorKind::DuplicateId,
format!("run profile id 重复:{}", profile.id),
));
}
}
Ok(Self { profiles, by_id })
}
pub fn get(&self, id: &str) -> Option<&RunProfileDefinition> {
self.by_id
.get(id)
.and_then(|index| self.profiles.get(*index))
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = &RunProfileDefinition> {
self.profiles.iter()
}
pub fn validate_capabilities<D>(
&self,
capabilities: &CapabilityRegistry<D>,
) -> Result<(), ContractError> {
for profile in &self.profiles {
for capability_id in &profile.capability_ids {
if capabilities.get(capability_id).is_none() {
return Err(ContractError::new(
ContractErrorKind::UnknownCapability,
format!(
"run profile {} 引用了未知 capability{capability_id}",
profile.id
),
));
}
}
}
Ok(())
}
pub fn validate_completion_policy_ids<'a>(
&self,
policy_ids: impl IntoIterator<Item = &'a str>,
) -> Result<(), ContractError> {
let mut known_policy_ids = BTreeSet::new();
for policy_id in policy_ids {
validate_identifier(policy_id, "completion policy id")?;
known_policy_ids.insert(policy_id);
}
for profile in &self.profiles {
if !known_policy_ids.contains(profile.completion_policy_id.as_str()) {
return Err(ContractError::new(
ContractErrorKind::UnknownCompletionPolicy,
format!(
"run profile {} 引用了未知 completion policy{}",
profile.id, profile.completion_policy_id
),
));
}
}
Ok(())
}
}