use polyc_llm::ToolSpec;
use serde_json::json;
pub const DELETE_PROVISIONAL_PERSONA: &str = "delete_provisional_persona";
pub const LIST_PROVISIONAL_PERSONAS: &str = "list_provisional_personas";
pub const ALL: &[&str] = &[DELETE_PROVISIONAL_PERSONA, LIST_PROVISIONAL_PERSONAS];
pub const ARG_TARGET_USER_ID: &str = "target_user_id";
pub const ARG_PAGE_TOKEN: &str = "page_token";
#[must_use]
pub fn all_specs() -> Vec<ToolSpec> {
vec![
delete_provisional_persona_spec(),
list_provisional_personas_spec(),
]
}
#[must_use]
pub fn delete_provisional_persona_spec() -> ToolSpec {
ToolSpec::new(
DELETE_PROVISIONAL_PERSONA,
"For an admin only: permanently remove a STILL-PROVISIONAL persona — one that was \
auto-created by a first message but never went through a link ceremony or was ever \
granted anything. Use it to clean up stray test/demo identities, for example \"delete \
the U_TESTER persona\" or \"remove that leftover demo account\". Pass the target's \
user id EXACTLY as it appears in the mention markup in the message (the id inside \
`<@...>`), never a typed-out name. This refuses outright if the target is not \
currently provisional (already linked, merged, or an admin/operator) — that persona \
must go through revoke instead, since removing a real linked persona is a different, \
higher-stakes action. If the person asking isn't an admin, it returns a refusal \
rather than removing anyone.",
json!({
"type": "object",
"properties": {
ARG_TARGET_USER_ID: {
"type": "string",
"description": "The target's provider-native user id, taken \
verbatim from the mention markup (`<@U...>`) in the \
message — not a display name or handle."
}
},
"required": [ARG_TARGET_USER_ID],
"additionalProperties": false
}),
)
.titled("Delete a still-provisional persona (admin)")
}
#[must_use]
pub fn list_provisional_personas_spec() -> ToolSpec {
ToolSpec::new(
LIST_PROVISIONAL_PERSONAS,
"For an admin only: list personas that are still PROVISIONAL — auto-created by a \
first message but never linked or granted anything, the usual shape of a stray \
test/demo identity. Use it when an admin asks what provisional or unlinked test \
personas exist, e.g. \"what test personas are lying around\" or \"show me the \
provisional ones\". Takes no argument on a first call; if the result says there are \
more, call again passing the returned continuation token to see the rest. If the \
person asking isn't an admin, it returns a refusal instead of a list.",
json!({
"type": "object",
"properties": {
ARG_PAGE_TOKEN: {
"type": "string",
"description": "Continuation token from a prior call's result, to \
fetch the next page. Omit on the first call."
}
},
"additionalProperties": false
}),
)
.titled("List still-provisional personas (admin)")
.read_only()
}