Watch
0
0
Fork
You've already forked hyperhive
0

Set resource caps and inference when creating an agent

POST /api/agents takes optional limits and inference objects, checked by
the same rules as the two PUT routes before anything is queued and stored
ahead of the job graph. The create form gets collapsed sections for both,
reusing the fields of the detail-panel editors.
This commit is contained in:
iris 2026-10-15 11:32:48 +02:00 • committed by mara
commit e36a15de91
8 changed files with 389 additions and 100 deletions

View file

@ -51,7 +51,7 @@ pub struct Caps {
impl Caps {
/// The value to store, or why it is refused.
fn into_stored(self) -> Result<AgentCaps, String> {
pub(crate) fn into_stored(self) -> Result<AgentCaps, String> {
Ok(AgentCaps {
cpu_quota: self.cpu_quota.as_deref().map(cpu_quota).transpose()?,
memory_max: self.memory_max.as_deref().map(memory_max).transpose()?,
@ -253,18 +253,28 @@ pub(crate) async fn put_agent_limits(
&format!("no hive's wanted state declares an agent {agent:?} that is not destroyed"),
));
}
let store = open_or_create(&client).await?;
store(&client, &agent, &value).await?;
Ok(Json(value.into()))
}
/// Replace `agent`'s stored caps with `value`.
pub(crate) async fn store(
client: &async_nats::Client,
agent: &str,
value: &AgentCaps,
) -> Result<(), ProblemDetails> {
let store = open_or_create(client).await?;
for _ in 0..MAX_ATTEMPTS {
let (current, revision, undecodable) = read_or_default::<AgentCaps>(&store, &agent)
let (current, revision, undecodable) = read_or_default::<AgentCaps>(&store, agent)
.await
.map_err(|e| queue_problem(&e))?;
if (current == value && !undecodable)
|| write(&store, &agent, &value, revision)
if (current == *value && !undecodable)
|| write(&store, agent, value, revision)
.await
.map_err(|e| queue_problem(&e))?
{
tracing::info!(%agent, ?value, "set agent limits");
return Ok(Json(value.into()));
return Ok(());
}
}
Err(queue_problem(&anyhow::anyhow!(