ctfy.sdk.admin_resources.llm_calls
client.admin.llm_calls — every model request the gateway relayed.
1"""``client.admin.llm_calls`` — every model request the gateway relayed.""" 2 3from __future__ import annotations 4 5from typing import Any 6 7from ctfy.core.enums import PrincipalOrAny 8from ctfy.sdk._helpers import _raise_for_status 9from ctfy.sdk.base import BaseHttpClient 10from ctfy.server.models import LlmCallBody, LlmCallPage 11 12 13class AdminLlmCallsResource: 14 """The operator's whole transcript feed. 15 16 ⚠️ **The only surface on which a ``principal == "instance"`` row can 17 be read at all**, and admin-gated rather than organiser-gated for 18 that reason: an ``AGENTBENCH`` container's conversation carries the 19 challenge's minted answer, its system prompt and the hidden state of 20 a prompt-injection task — facts about a benchmark that outlives any 21 one competition. 22 23 ⚠️ **``indexing`` rides the envelope.** An empty list means *either* 24 that nothing has been relayed *or* that this deployment runs no 25 gateway, and those call for opposite actions. Same shape as 26 ``gateway_configured`` on the budget page. 27 """ 28 29 def __init__(self, http: BaseHttpClient) -> None: 30 self._http = http 31 32 def list( 33 self, 34 *, 35 principal: PrincipalOrAny = "", 36 competition_id: str = "", 37 team_id: str = "", 38 challenge_id: str = "", 39 instance_id: str = "", 40 model: str = "", 41 status: int = 0, 42 since_ts: float = 0.0, 43 offset: int = 0, 44 limit: int = 50, 45 ) -> LlmCallPage: 46 """Relayed calls, newest first. 47 48 ``principal`` is the first control: ``instance`` (a challenge 49 container), ``agent`` (somebody's own eval-run agent) or 50 ``platform`` (the report grader, the AWD attacker). 51 ⚠️ ``total`` is counted with the **same** filters as the page, or 52 the paginator offers a page three of two. 53 Wraps ``GET /admin/llm-calls``.""" 54 params: dict[str, Any] = { 55 "principal": principal, 56 "competition_id": competition_id, 57 "team_id": team_id, 58 "challenge_id": challenge_id, 59 "instance_id": instance_id, 60 "model": model, 61 "status": status, 62 "since_ts": since_ts, 63 "offset": offset, 64 "limit": limit, 65 } 66 resp = self._http.request("GET", "/admin/llm-calls", params=params) 67 _raise_for_status(resp) 68 return LlmCallPage.model_validate(resp.json()) 69 70 def read(self, call_id: str) -> LlmCallBody: 71 """The archived conversation for one call. 72 73 ⚠️ ``available=False`` is an ordinary answer rather than an 74 error: retention reclaims the object and leaves the row, so "the 75 call happened and its body is gone" is a state the page must be 76 able to render — a 404 would read as "no such call". 77 Wraps ``GET /admin/llm-calls/{call_id}``.""" 78 resp = self._http.request("GET", f"/admin/llm-calls/{call_id}") 79 _raise_for_status(resp) 80 return LlmCallBody.model_validate(resp.json())
14class AdminLlmCallsResource: 15 """The operator's whole transcript feed. 16 17 ⚠️ **The only surface on which a ``principal == "instance"`` row can 18 be read at all**, and admin-gated rather than organiser-gated for 19 that reason: an ``AGENTBENCH`` container's conversation carries the 20 challenge's minted answer, its system prompt and the hidden state of 21 a prompt-injection task — facts about a benchmark that outlives any 22 one competition. 23 24 ⚠️ **``indexing`` rides the envelope.** An empty list means *either* 25 that nothing has been relayed *or* that this deployment runs no 26 gateway, and those call for opposite actions. Same shape as 27 ``gateway_configured`` on the budget page. 28 """ 29 30 def __init__(self, http: BaseHttpClient) -> None: 31 self._http = http 32 33 def list( 34 self, 35 *, 36 principal: PrincipalOrAny = "", 37 competition_id: str = "", 38 team_id: str = "", 39 challenge_id: str = "", 40 instance_id: str = "", 41 model: str = "", 42 status: int = 0, 43 since_ts: float = 0.0, 44 offset: int = 0, 45 limit: int = 50, 46 ) -> LlmCallPage: 47 """Relayed calls, newest first. 48 49 ``principal`` is the first control: ``instance`` (a challenge 50 container), ``agent`` (somebody's own eval-run agent) or 51 ``platform`` (the report grader, the AWD attacker). 52 ⚠️ ``total`` is counted with the **same** filters as the page, or 53 the paginator offers a page three of two. 54 Wraps ``GET /admin/llm-calls``.""" 55 params: dict[str, Any] = { 56 "principal": principal, 57 "competition_id": competition_id, 58 "team_id": team_id, 59 "challenge_id": challenge_id, 60 "instance_id": instance_id, 61 "model": model, 62 "status": status, 63 "since_ts": since_ts, 64 "offset": offset, 65 "limit": limit, 66 } 67 resp = self._http.request("GET", "/admin/llm-calls", params=params) 68 _raise_for_status(resp) 69 return LlmCallPage.model_validate(resp.json()) 70 71 def read(self, call_id: str) -> LlmCallBody: 72 """The archived conversation for one call. 73 74 ⚠️ ``available=False`` is an ordinary answer rather than an 75 error: retention reclaims the object and leaves the row, so "the 76 call happened and its body is gone" is a state the page must be 77 able to render — a 404 would read as "no such call". 78 Wraps ``GET /admin/llm-calls/{call_id}``.""" 79 resp = self._http.request("GET", f"/admin/llm-calls/{call_id}") 80 _raise_for_status(resp) 81 return LlmCallBody.model_validate(resp.json())
The operator's whole transcript feed.
⚠️ The only surface on which a principal == "instance" row can
be read at all, and admin-gated rather than organiser-gated for
that reason: an AGENTBENCH container's conversation carries the
challenge's minted answer, its system prompt and the hidden state of
a prompt-injection task — facts about a benchmark that outlives any
one competition.
⚠️ indexing rides the envelope. An empty list means either
that nothing has been relayed or that this deployment runs no
gateway, and those call for opposite actions. Same shape as
gateway_configured on the budget page.
33 def list( 34 self, 35 *, 36 principal: PrincipalOrAny = "", 37 competition_id: str = "", 38 team_id: str = "", 39 challenge_id: str = "", 40 instance_id: str = "", 41 model: str = "", 42 status: int = 0, 43 since_ts: float = 0.0, 44 offset: int = 0, 45 limit: int = 50, 46 ) -> LlmCallPage: 47 """Relayed calls, newest first. 48 49 ``principal`` is the first control: ``instance`` (a challenge 50 container), ``agent`` (somebody's own eval-run agent) or 51 ``platform`` (the report grader, the AWD attacker). 52 ⚠️ ``total`` is counted with the **same** filters as the page, or 53 the paginator offers a page three of two. 54 Wraps ``GET /admin/llm-calls``.""" 55 params: dict[str, Any] = { 56 "principal": principal, 57 "competition_id": competition_id, 58 "team_id": team_id, 59 "challenge_id": challenge_id, 60 "instance_id": instance_id, 61 "model": model, 62 "status": status, 63 "since_ts": since_ts, 64 "offset": offset, 65 "limit": limit, 66 } 67 resp = self._http.request("GET", "/admin/llm-calls", params=params) 68 _raise_for_status(resp) 69 return LlmCallPage.model_validate(resp.json())
Relayed calls, newest first.
principal is the first control: instance (a challenge
container), agent (somebody's own eval-run agent) or
platform (the report grader, the AWD attacker).
⚠️ total is counted with the same filters as the page, or
the paginator offers a page three of two.
Wraps GET /admin/llm-calls.
71 def read(self, call_id: str) -> LlmCallBody: 72 """The archived conversation for one call. 73 74 ⚠️ ``available=False`` is an ordinary answer rather than an 75 error: retention reclaims the object and leaves the row, so "the 76 call happened and its body is gone" is a state the page must be 77 able to render — a 404 would read as "no such call". 78 Wraps ``GET /admin/llm-calls/{call_id}``.""" 79 resp = self._http.request("GET", f"/admin/llm-calls/{call_id}") 80 _raise_for_status(resp) 81 return LlmCallBody.model_validate(resp.json())
The archived conversation for one call.
⚠️ available=False is an ordinary answer rather than an
error: retention reclaims the object and leaves the row, so "the
call happened and its body is gone" is a state the page must be
able to render — a 404 would read as "no such call".
Wraps GET /admin/llm-calls/{call_id}.