chatpanel 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chatpanel/__init__.py +135 -0
- chatpanel/_api_generated.py +414 -0
- chatpanel/_runtime.py +361 -0
- chatpanel/_types_generated.py +389 -0
- chatpanel/errors.py +81 -0
- chatpanel/py.typed +0 -0
- chatpanel-0.1.0.dist-info/METADATA +71 -0
- chatpanel-0.1.0.dist-info/RECORD +11 -0
- chatpanel-0.1.0.dist-info/WHEEL +5 -0
- chatpanel-0.1.0.dist-info/licenses/LICENSE +202 -0
- chatpanel-0.1.0.dist-info/top_level.txt +1 -0
chatpanel/__init__.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""chatpanel — a typed client for the local ChatPanel gateway.
|
|
2
|
+
|
|
3
|
+
from chatpanel import ChatPanel
|
|
4
|
+
cp = ChatPanel.from_environment() # reads ~/.chatpanel/gateway-token
|
|
5
|
+
hits = cp.history.smart_search({"question": "what did we decide about the launch?"})
|
|
6
|
+
for text in cp.chat.text({"model": "claude", "messages": [{"role": "user", "content": "hi"}]}):
|
|
7
|
+
print(text, end="", flush=True)
|
|
8
|
+
|
|
9
|
+
The namespaces (``history``, ``memory``, ``chat``, …) are GENERATED from the contract; this
|
|
10
|
+
module adds the few things that need judgement: construction, discovery, pairing, and a text
|
|
11
|
+
iterator over the chat stream.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import Any, Dict, Iterator, Optional
|
|
17
|
+
|
|
18
|
+
from . import _types_generated as types
|
|
19
|
+
from ._api_generated import OPERATIONS, Api
|
|
20
|
+
from ._runtime import (
|
|
21
|
+
DEFAULT_BASE_URL,
|
|
22
|
+
TOKEN_ENV,
|
|
23
|
+
TOKEN_PATH_ENV,
|
|
24
|
+
URL_ENV,
|
|
25
|
+
Operation,
|
|
26
|
+
Runtime,
|
|
27
|
+
SseFrame,
|
|
28
|
+
TokenSource,
|
|
29
|
+
compare_versions,
|
|
30
|
+
discover_base_url,
|
|
31
|
+
discover_token,
|
|
32
|
+
normalise_base_url,
|
|
33
|
+
parse_frame,
|
|
34
|
+
)
|
|
35
|
+
from .errors import (
|
|
36
|
+
ChatPanelError,
|
|
37
|
+
ForbiddenError,
|
|
38
|
+
GatewayTooOldError,
|
|
39
|
+
GatewayUnreachableError,
|
|
40
|
+
InvalidRequestError,
|
|
41
|
+
NotFoundError,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
"ChatPanel", "Runtime", "Operation", "OPERATIONS", "SseFrame", "types",
|
|
46
|
+
"ChatPanelError", "ForbiddenError", "GatewayTooOldError", "GatewayUnreachableError", "InvalidRequestError", "NotFoundError",
|
|
47
|
+
"compare_versions", "normalise_base_url", "parse_frame", "delta_text",
|
|
48
|
+
"discover_base_url", "discover_token", "DEFAULT_BASE_URL", "TOKEN_ENV", "TOKEN_PATH_ENV", "URL_ENV",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
__version__ = "0.1.0"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def delta_text(frame: SseFrame[Any]) -> str:
|
|
55
|
+
"""The text of one streamed chunk, or '' when the frame carried none (usage, a tool call)."""
|
|
56
|
+
d = frame.data
|
|
57
|
+
if not isinstance(d, dict):
|
|
58
|
+
return ""
|
|
59
|
+
choices = d.get("choices") or []
|
|
60
|
+
delta = choices[0].get("delta") if choices and isinstance(choices[0], dict) else None
|
|
61
|
+
content = delta.get("content") if isinstance(delta, dict) else None
|
|
62
|
+
return content if isinstance(content, str) else ""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class _Chat:
|
|
66
|
+
"""The generated chat namespace plus ``text()``."""
|
|
67
|
+
|
|
68
|
+
def __init__(self, inner: Any) -> None:
|
|
69
|
+
self._inner = inner
|
|
70
|
+
|
|
71
|
+
def __getattr__(self, name: str) -> Any:
|
|
72
|
+
return getattr(self._inner, name)
|
|
73
|
+
|
|
74
|
+
def text(self, body: Dict[str, Any], *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[str]:
|
|
75
|
+
"""Stream just the text of a reply. Tool calls and usage frames are skipped; use ``completions_stream`` for those."""
|
|
76
|
+
for frame in self._inner.completions_stream(body, headers=headers, timeout=timeout):
|
|
77
|
+
t = delta_text(frame)
|
|
78
|
+
if t:
|
|
79
|
+
yield t
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class ChatPanel:
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
base_url: Optional[str] = None,
|
|
86
|
+
token: TokenSource = None,
|
|
87
|
+
*,
|
|
88
|
+
allow_remote: bool = False,
|
|
89
|
+
timeout: float = 20.0,
|
|
90
|
+
retries: int = 2,
|
|
91
|
+
version_gate: bool = True,
|
|
92
|
+
user_agent: str = "",
|
|
93
|
+
opener: Any = None,
|
|
94
|
+
) -> None:
|
|
95
|
+
self.runtime = Runtime(base_url, token, allow_remote=allow_remote, timeout=timeout, retries=retries, version_gate=version_gate, user_agent=user_agent, opener=opener)
|
|
96
|
+
api = Api(self.runtime)
|
|
97
|
+
self.gateway = api.gateway
|
|
98
|
+
self.models = api.models
|
|
99
|
+
self.chat = _Chat(api.chat)
|
|
100
|
+
self.redaction = api.redaction
|
|
101
|
+
self.history = api.history
|
|
102
|
+
self.memory = api.memory
|
|
103
|
+
self.prefs = api.prefs
|
|
104
|
+
self.teams = api.teams
|
|
105
|
+
self.projects = api.projects
|
|
106
|
+
self.agents = api.agents
|
|
107
|
+
self.engines = api.engines
|
|
108
|
+
self.skills = api.skills
|
|
109
|
+
|
|
110
|
+
def __repr__(self) -> str:
|
|
111
|
+
return f"ChatPanel({self.runtime.base_url})"
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def from_environment(cls, **kwargs: Any) -> "ChatPanel":
|
|
115
|
+
"""A client for the gateway on this machine, authenticated as the current user: the URL from
|
|
116
|
+
``CHATPANEL_GATEWAY_URL`` and the token from ``CHATPANEL_GATEWAY_TOKEN`` or the token file."""
|
|
117
|
+
kwargs.setdefault("base_url", discover_base_url())
|
|
118
|
+
return cls(token=discover_token() or None, **kwargs)
|
|
119
|
+
|
|
120
|
+
def health(self) -> "types.Health":
|
|
121
|
+
return self.gateway.health()
|
|
122
|
+
|
|
123
|
+
def whoami(self) -> "types.WhoAmI":
|
|
124
|
+
return self.gateway.whoami()
|
|
125
|
+
|
|
126
|
+
def pair(self, code: str) -> "types.Paired":
|
|
127
|
+
"""Exchange a one-time code for the token and start using it. The token is RETURNED so the
|
|
128
|
+
application can persist it — in the platform keychain or a 0600 file, never in a log."""
|
|
129
|
+
paired = self.gateway.pair({"code": str(code).strip()})
|
|
130
|
+
self.runtime.set_token(paired["token"])
|
|
131
|
+
return paired
|
|
132
|
+
|
|
133
|
+
def request(self, operation_id: str, **kwargs: Any) -> Any:
|
|
134
|
+
"""Any operation by id — for a route added to the contract before this package learnt a method for it."""
|
|
135
|
+
return self.runtime.request(OPERATIONS[operation_id], **kwargs)
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# GENERATED FROM openapi/chatpanel-gateway.yaml BY tools/gen-core.mjs — DO NOT EDIT. Edit the spec, run `npm run gen:core`.
|
|
2
|
+
from typing import Any, Dict, Iterator, Optional
|
|
3
|
+
|
|
4
|
+
from . import _types_generated as T
|
|
5
|
+
from ._runtime import Operation, Runtime, SseFrame
|
|
6
|
+
|
|
7
|
+
OPERATIONS: Dict[str, Operation] = {
|
|
8
|
+
"gateway.health": Operation(id="gateway.health", method="GET", path="/health", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
9
|
+
"gateway.whoami": Operation(id="gateway.whoami", method="POST", path="/whoami", auth="open", since="0.9.0", stream=None, path_params=(), query_params=()),
|
|
10
|
+
"gateway.pairCode": Operation(id="gateway.pairCode", method="POST", path="/pair/code", auth="token", since="0.9.0", stream=None, path_params=(), query_params=()),
|
|
11
|
+
"gateway.pair": Operation(id="gateway.pair", method="POST", path="/pair", auth="open", since="0.9.0", stream=None, path_params=(), query_params=()),
|
|
12
|
+
"gateway.audit": Operation(id="gateway.audit", method="GET", path="/audit", auth="token", since=None, stream=None, path_params=(), query_params=()),
|
|
13
|
+
"models.list": Operation(id="models.list", method="GET", path="/v1/models", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
14
|
+
"chat.completions": Operation(id="chat.completions", method="POST", path="/v1/chat/completions", auth="open", since=None, stream="sse-when-stream", path_params=(), query_params=()),
|
|
15
|
+
"redaction.preview": Operation(id="redaction.preview", method="POST", path="/redact", auth="open", since="0.6.62", stream=None, path_params=(), query_params=()),
|
|
16
|
+
"history.search": Operation(id="history.search", method="POST", path="/v1/history/search", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
17
|
+
"history.smartSearch": Operation(id="history.smartSearch", method="POST", path="/v1/history/smart-search", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
18
|
+
"history.related": Operation(id="history.related", method="GET", path="/v1/history/related", auth="open", since=None, stream=None, path_params=(), query_params=("id", "limit",)),
|
|
19
|
+
"history.status": Operation(id="history.status", method="GET", path="/v1/history/status", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
20
|
+
"history.list": Operation(id="history.list", method="GET", path="/v1/history/list", auth="open", since=None, stream=None, path_params=(), query_params=("limit", "offset", "type",)),
|
|
21
|
+
"history.get": Operation(id="history.get", method="GET", path="/v1/history/get", auth="open", since=None, stream=None, path_params=(), query_params=("id", "maxChars", "offset",)),
|
|
22
|
+
"history.records": Operation(id="history.records", method="GET", path="/v1/history/records", auth="open", since="0.10.0", stream=None, path_params=(), query_params=("since", "cursor", "limit", "kind",)),
|
|
23
|
+
"history.putRecords": Operation(id="history.putRecords", method="PUT", path="/v1/history/records", auth="token", since="0.10.0", stream=None, path_params=(), query_params=()),
|
|
24
|
+
"history.stream": Operation(id="history.stream", method="GET", path="/v1/history/stream", auth="open", since="0.11.0", stream="sse", path_params=(), query_params=()),
|
|
25
|
+
"history.ingest": Operation(id="history.ingest", method="POST", path="/v1/history/ingest", auth="token", since=None, stream=None, path_params=(), query_params=()),
|
|
26
|
+
"memory.list": Operation(id="memory.list", method="GET", path="/v1/memory/list", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
27
|
+
"memory.recall": Operation(id="memory.recall", method="POST", path="/v1/memory/recall", auth="open", since=None, stream=None, path_params=(), query_params=()),
|
|
28
|
+
"memory.remember": Operation(id="memory.remember", method="POST", path="/v1/memory/remember", auth="token", since=None, stream=None, path_params=(), query_params=()),
|
|
29
|
+
"memory.forget": Operation(id="memory.forget", method="POST", path="/v1/memory/forget", auth="token", since=None, stream=None, path_params=(), query_params=()),
|
|
30
|
+
"memory.sync": Operation(id="memory.sync", method="POST", path="/v1/memory/sync", auth="token", since=None, stream=None, path_params=(), query_params=()),
|
|
31
|
+
"prefs.get": Operation(id="prefs.get", method="GET", path="/v1/prefs", auth="open", since="0.6.77", stream=None, path_params=(), query_params=("section", "stamps",)),
|
|
32
|
+
"prefs.put": Operation(id="prefs.put", method="POST", path="/v1/prefs", auth="open", since="0.6.77", stream=None, path_params=(), query_params=()),
|
|
33
|
+
"prefs.delete": Operation(id="prefs.delete", method="DELETE", path="/v1/prefs", auth="open", since="0.6.77", stream=None, path_params=(), query_params=("section",)),
|
|
34
|
+
"prefs.events": Operation(id="prefs.events", method="GET", path="/v1/prefs/events", auth="open", since="0.6.77", stream="sse", path_params=(), query_params=()),
|
|
35
|
+
"teams.listRuns": Operation(id="teams.listRuns", method="GET", path="/v1/teams/runs", auth="open", since="0.6.78", stream=None, path_params=(), query_params=("limit", "team",)),
|
|
36
|
+
"teams.createRun": Operation(id="teams.createRun", method="POST", path="/v1/teams/runs", auth="open", since="0.6.78", stream=None, path_params=(), query_params=()),
|
|
37
|
+
"teams.getRun": Operation(id="teams.getRun", method="GET", path="/v1/teams/runs/{runId}", auth="open", since="0.6.78", stream=None, path_params=("runId",), query_params=("events",)),
|
|
38
|
+
"teams.deleteRun": Operation(id="teams.deleteRun", method="DELETE", path="/v1/teams/runs/{runId}", auth="open", since="0.6.110", stream=None, path_params=("runId",), query_params=()),
|
|
39
|
+
"teams.runEvents": Operation(id="teams.runEvents", method="GET", path="/v1/teams/runs/{runId}/events", auth="open", since="0.6.78", stream="sse", path_params=("runId",), query_params=("after",)),
|
|
40
|
+
"teams.appendRunEvents": Operation(id="teams.appendRunEvents", method="POST", path="/v1/teams/runs/{runId}/events", auth="open", since="0.6.78", stream=None, path_params=("runId",), query_params=()),
|
|
41
|
+
"teams.stopRun": Operation(id="teams.stopRun", method="POST", path="/v1/teams/runs/{runId}/stop", auth="open", since="0.6.78", stream=None, path_params=("runId",), query_params=()),
|
|
42
|
+
"teams.answer": Operation(id="teams.answer", method="POST", path="/v1/teams/runs/{runId}/answer", auth="open", since="0.6.81", stream=None, path_params=("runId",), query_params=()),
|
|
43
|
+
"teams.decide": Operation(id="teams.decide", method="POST", path="/v1/teams/runs/{runId}/decide", auth="open", since="0.6.81", stream=None, path_params=("runId",), query_params=()),
|
|
44
|
+
"teams.post": Operation(id="teams.post", method="POST", path="/v1/teams/runs/{runId}/post", auth="open", since="0.6.81", stream=None, path_params=("runId",), query_params=()),
|
|
45
|
+
"teams.removeThread": Operation(id="teams.removeThread", method="DELETE", path="/v1/teams/runs/{runId}/threads/{threadId}", auth="open", since="0.6.106", stream=None, path_params=("runId", "threadId",), query_params=()),
|
|
46
|
+
"teams.handoff": Operation(id="teams.handoff", method="POST", path="/v1/teams/runs/{runId}/handoff", auth="open", since="0.6.85", stream=None, path_params=("runId",), query_params=()),
|
|
47
|
+
"teams.checkpoint": Operation(id="teams.checkpoint", method="GET", path="/v1/teams/runs/{runId}/checkpoint", auth="open", since="0.6.85", stream=None, path_params=("runId",), query_params=()),
|
|
48
|
+
"teams.claim": Operation(id="teams.claim", method="POST", path="/v1/teams/runs/{runId}/claim", auth="open", since="0.6.85", stream=None, path_params=("runId",), query_params=()),
|
|
49
|
+
"projects.list": Operation(id="projects.list", method="GET", path="/v1/projects", auth="open", since="0.6.90", stream=None, path_params=(), query_params=("limit", "status",)),
|
|
50
|
+
"projects.create": Operation(id="projects.create", method="POST", path="/v1/projects", auth="open", since="0.6.90", stream=None, path_params=(), query_params=()),
|
|
51
|
+
"projects.jobBoard": Operation(id="projects.jobBoard", method="GET", path="/v1/projects/jobs", auth="open", since="0.6.90", stream=None, path_params=(), query_params=()),
|
|
52
|
+
"projects.get": Operation(id="projects.get", method="GET", path="/v1/projects/{projectId}", auth="open", since="0.6.90", stream=None, path_params=("projectId",), query_params=("events",)),
|
|
53
|
+
"projects.delete": Operation(id="projects.delete", method="DELETE", path="/v1/projects/{projectId}", auth="open", since="0.6.90", stream=None, path_params=("projectId",), query_params=()),
|
|
54
|
+
"projects.events": Operation(id="projects.events", method="GET", path="/v1/projects/{projectId}/events", auth="open", since="0.6.90", stream="sse", path_params=("projectId",), query_params=("after",)),
|
|
55
|
+
"projects.appendEvents": Operation(id="projects.appendEvents", method="POST", path="/v1/projects/{projectId}/events", auth="open", since="0.6.90", stream=None, path_params=("projectId",), query_params=()),
|
|
56
|
+
"projects.postJob": Operation(id="projects.postJob", method="POST", path="/v1/projects/{projectId}/jobs", auth="open", since="0.6.90", stream=None, path_params=("projectId",), query_params=()),
|
|
57
|
+
"projects.patchJob": Operation(id="projects.patchJob", method="POST", path="/v1/projects/{projectId}/jobs/{jobId}", auth="open", since="0.6.90", stream=None, path_params=("projectId", "jobId",), query_params=()),
|
|
58
|
+
"projects.applications": Operation(id="projects.applications", method="GET", path="/v1/projects/{projectId}/jobs/{jobId}/applications", auth="open", since="0.6.90", stream=None, path_params=("projectId", "jobId",), query_params=("reach", "chatModel",)),
|
|
59
|
+
"projects.recruit": Operation(id="projects.recruit", method="POST", path="/v1/projects/{projectId}/jobs/{jobId}/recruit", auth="open", since="0.6.90", stream=None, path_params=("projectId", "jobId",), query_params=()),
|
|
60
|
+
"agents.scorecards": Operation(id="agents.scorecards", method="GET", path="/v1/agents/scorecards", auth="open", since="0.6.87", stream=None, path_params=(), query_params=()),
|
|
61
|
+
"agents.scorecard": Operation(id="agents.scorecard", method="GET", path="/v1/agents/{agentId}/scorecard", auth="open", since="0.6.87", stream=None, path_params=("agentId",), query_params=()),
|
|
62
|
+
"agents.rate": Operation(id="agents.rate", method="POST", path="/v1/agents/{agentId}/scorecard", auth="open", since="0.6.87", stream=None, path_params=("agentId",), query_params=()),
|
|
63
|
+
"engines.list": Operation(id="engines.list", method="GET", path="/v1/engines", auth="open", since="0.6.89", stream=None, path_params=(), query_params=("minCalls",)),
|
|
64
|
+
"engines.card": Operation(id="engines.card", method="GET", path="/v1/engines/{engineKey}/card", auth="open", since="0.6.89", stream=None, path_params=("engineKey",), query_params=("entries", "minCalls",)),
|
|
65
|
+
"engines.appendEntry": Operation(id="engines.appendEntry", method="POST", path="/v1/engines/{engineKey}/entries", auth="open", since="0.6.89", stream=None, path_params=("engineKey",), query_params=()),
|
|
66
|
+
"skills.list": Operation(id="skills.list", method="GET", path="/skills", auth="open", since="0.6.64", stream=None, path_params=(), query_params=("workdir",)),
|
|
67
|
+
"skills.get": Operation(id="skills.get", method="GET", path="/skills/{skillId}", auth="open", since="0.6.67", stream=None, path_params=("skillId",), query_params=("workdir",)),
|
|
68
|
+
}
|
|
69
|
+
"""Every operation in the contract, keyed by operationId — the route table the runtime executes."""
|
|
70
|
+
|
|
71
|
+
class GatewayApi:
|
|
72
|
+
"""Liveness, identity and pairing."""
|
|
73
|
+
|
|
74
|
+
def __init__(self, rt: Runtime) -> None:
|
|
75
|
+
self._rt = rt
|
|
76
|
+
|
|
77
|
+
def health(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.Health":
|
|
78
|
+
"""Liveness, version and capabilities. Additive fields only. `version` is what every version gate reads."""
|
|
79
|
+
return self._rt.request(OPERATIONS["gateway.health"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
80
|
+
|
|
81
|
+
def whoami(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.WhoAmI":
|
|
82
|
+
"""What the gateway makes of this caller. — Gateway 0.9.0+."""
|
|
83
|
+
return self._rt.request(OPERATIONS["gateway.whoami"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
84
|
+
|
|
85
|
+
def pair_code(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.PairingCode":
|
|
86
|
+
"""Mint a one-time pairing code (5 minutes, one use, 5 attempts). Only a caller that already holds the token may mint one — pairing widens nothing. — Requires the gateway token. Gateway 0.9.0+."""
|
|
87
|
+
return self._rt.request(OPERATIONS["gateway.pairCode"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
88
|
+
|
|
89
|
+
def pair(self, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.Paired":
|
|
90
|
+
"""Exchange a pairing code for the gateway token. — Gateway 0.9.0+."""
|
|
91
|
+
return self._rt.request(OPERATIONS["gateway.pair"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
92
|
+
|
|
93
|
+
def audit(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.Audit":
|
|
94
|
+
"""The egress audit — which hosts this gateway has contacted and which its config allows. The checkable claim behind "nothing leaves the machine". Admin-gated because it names the user's model endpoints. — Requires the gateway token."""
|
|
95
|
+
return self._rt.request(OPERATIONS["gateway.audit"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ModelsApi:
|
|
99
|
+
"""What the gateway can route to."""
|
|
100
|
+
|
|
101
|
+
def __init__(self, rt: Runtime) -> None:
|
|
102
|
+
self._rt = rt
|
|
103
|
+
|
|
104
|
+
def list(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.ModelList":
|
|
105
|
+
"""Every model the gateway can route to. Describes the routing table, not the disk: a bridge agent is listed whether or not the CLI is installed. From 0.6.64 each agent carries `available`; from 0.6.66 a cloud model carries `configured: false` when a turn is known to fail for something the user can fix."""
|
|
106
|
+
return self._rt.request(OPERATIONS["models.list"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ChatApi:
|
|
110
|
+
"""The OpenAI-compatible chat endpoint, redacted and routed by the gateway."""
|
|
111
|
+
|
|
112
|
+
def __init__(self, rt: Runtime) -> None:
|
|
113
|
+
self._rt = rt
|
|
114
|
+
|
|
115
|
+
def completions(self, body: "T.ChatCompletionRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.ChatCompletion":
|
|
116
|
+
"""One chat turn through the gateway (OpenAI-compatible). Redacted on the way out, restored on the way back, routed by `model`. With `stream: true` the response is `text/event-stream` of OpenAI chunk objects ending in `data: [DONE]`. Send `tools` so a redacted turn can still act: the gateway relays a tool call back with real arguments and redacts the result. `X-ChatPanel-Redaction: off` is honoured only from a token-bearing caller (0.6.69+) and is recorded in the trace. **Two lanes.** An API destination (a cloud or local model endpoint) is a proxy hop and is open to any local caller. An AGENT destination (`codex`, `claude`, `opencode`, … — `provider_type: agent` in `GET /v1/models`) spawns a process on this machine, so the caller must hold the gateway token (0.9.0+): without it the gateway answers **401** `{ type: 'auth', code: 'agent_lane_token_required' }`. The SDKs surface that as `ForbiddenError` with `status` 401."""
|
|
117
|
+
return self._rt.request(OPERATIONS["chat.completions"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
118
|
+
|
|
119
|
+
def completions_stream(self, body: "T.ChatCompletionRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[SseFrame["T.ChatCompletionChunk"]]:
|
|
120
|
+
"""The same call with `stream: true` — one frame per chunk until `[DONE]`."""
|
|
121
|
+
return self._rt.stream(OPERATIONS["chat.completions"], path={}, query=query, headers=headers, body={**dict(body), "stream": True}, timeout=timeout)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class RedactionApi:
|
|
125
|
+
"""Preview what the model would receive."""
|
|
126
|
+
|
|
127
|
+
def __init__(self, rt: Runtime) -> None:
|
|
128
|
+
self._rt = rt
|
|
129
|
+
|
|
130
|
+
def preview(self, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.RedactionPreview":
|
|
131
|
+
"""What the model would receive if this text were sent now. Runs the same redaction path as a real turn. The reply carries placeholder types, never the real values. — Gateway 0.6.62+."""
|
|
132
|
+
return self._rt.request(OPERATIONS["redaction.preview"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class HistoryApi:
|
|
136
|
+
"""The user's searchable history — chats, notes, meetings, briefs."""
|
|
137
|
+
|
|
138
|
+
def __init__(self, rt: Runtime) -> None:
|
|
139
|
+
self._rt = rt
|
|
140
|
+
|
|
141
|
+
def search(self, body: "T.SearchRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.SearchResponse":
|
|
142
|
+
"""One keyword query over the warm index."""
|
|
143
|
+
return self._rt.request(OPERATIONS["history.search"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
144
|
+
|
|
145
|
+
def smart_search(self, body: "T.SmartSearchRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.SmartSearchResponse":
|
|
146
|
+
"""Several phrasings at once, rank-fused; briefs lead."""
|
|
147
|
+
return self._rt.request(OPERATIONS["history.smartSearch"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
148
|
+
|
|
149
|
+
def related(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
150
|
+
"""The records most connected to one record."""
|
|
151
|
+
return self._rt.request(OPERATIONS["history.related"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
152
|
+
|
|
153
|
+
def status(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.HistoryStatus":
|
|
154
|
+
"""Size and freshness of the warm index (and the lossless tier from 0.10.0)."""
|
|
155
|
+
return self._rt.request(OPERATIONS["history.status"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
156
|
+
|
|
157
|
+
def list(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.HistoryPage":
|
|
158
|
+
"""A page of the warm index — metadata only, no bodies."""
|
|
159
|
+
return self._rt.request(OPERATIONS["history.list"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
160
|
+
|
|
161
|
+
def get(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
162
|
+
"""One full warm record, optionally paged by characters."""
|
|
163
|
+
return self._rt.request(OPERATIONS["history.get"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
164
|
+
|
|
165
|
+
def records(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.RecordsPage":
|
|
166
|
+
"""WHOLE records changed after a stamp, oldest first, paged by cursor, tombstones included. The lossless tier. A gateway without the SQLite store answers 501. — Gateway 0.10.0+."""
|
|
167
|
+
return self._rt.request(OPERATIONS["history.records"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
168
|
+
|
|
169
|
+
def put_records(self, body: "T.PutRecordsRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.PutRecordsResponse":
|
|
170
|
+
"""Push whole records; the gateway derives the searchable text itself. — Requires the gateway token. Gateway 0.10.0+."""
|
|
171
|
+
return self._rt.request(OPERATIONS["history.putRecords"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
172
|
+
|
|
173
|
+
def stream(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[SseFrame["T.HistoryStreamEvent"]]:
|
|
174
|
+
"""Live record changes — `hello` once, then a `records` event per change. — Gateway 0.11.0+."""
|
|
175
|
+
return self._rt.stream(OPERATIONS["history.stream"], path={}, query=None, headers=headers, timeout=timeout)
|
|
176
|
+
|
|
177
|
+
def ingest(self, body: "T.IngestRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
178
|
+
"""Push flattened (lossy) records into the warm index. — Requires the gateway token."""
|
|
179
|
+
return self._rt.request(OPERATIONS["history.ingest"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class MemoryApi:
|
|
183
|
+
"""Durable facts about the user, carried into every turn on every client."""
|
|
184
|
+
|
|
185
|
+
def __init__(self, rt: Runtime) -> None:
|
|
186
|
+
self._rt = rt
|
|
187
|
+
|
|
188
|
+
def list(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.MemoryList":
|
|
189
|
+
"""Every memory."""
|
|
190
|
+
return self._rt.request(OPERATIONS["memory.list"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
191
|
+
|
|
192
|
+
def recall(self, body: "T.RecallRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.RecallResponse":
|
|
193
|
+
"""The memories relevant to a text, and a prompt block that carries them."""
|
|
194
|
+
return self._rt.request(OPERATIONS["memory.recall"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
195
|
+
|
|
196
|
+
def remember(self, body: "T.RememberRequest", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.RememberResponse":
|
|
197
|
+
"""Save a durable fact. Never anonymous — `source` is recorded. — Requires the gateway token."""
|
|
198
|
+
return self._rt.request(OPERATIONS["memory.remember"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
199
|
+
|
|
200
|
+
def forget(self, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
201
|
+
"""Forget memories matching an id or words. — Requires the gateway token."""
|
|
202
|
+
return self._rt.request(OPERATIONS["memory.forget"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
203
|
+
|
|
204
|
+
def sync(self, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.MemorySyncResponse":
|
|
205
|
+
"""Two-way merge in one round trip — push what you have, receive the full set. — Requires the gateway token."""
|
|
206
|
+
return self._rt.request(OPERATIONS["memory.sync"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class PrefsApi:
|
|
210
|
+
"""The settings every client shares."""
|
|
211
|
+
|
|
212
|
+
def __init__(self, rt: Runtime) -> None:
|
|
213
|
+
self._rt = rt
|
|
214
|
+
|
|
215
|
+
def get(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.Prefs":
|
|
216
|
+
"""The shared sections, or only their stamps. — Gateway 0.6.77+."""
|
|
217
|
+
return self._rt.request(OPERATIONS["prefs.get"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
218
|
+
|
|
219
|
+
def put(self, body: "T.PrefsWrite", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.PrefsWriteResult":
|
|
220
|
+
"""Write sections; per-section last-writer-wins by stamp. — Gateway 0.6.77+."""
|
|
221
|
+
return self._rt.request(OPERATIONS["prefs.put"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
222
|
+
|
|
223
|
+
def delete(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
224
|
+
"""Remove one section. — Gateway 0.6.77+."""
|
|
225
|
+
return self._rt.request(OPERATIONS["prefs.delete"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
226
|
+
|
|
227
|
+
def events(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[SseFrame["T.PrefsEvent"]]:
|
|
228
|
+
"""Live — which sections another client wrote. — Gateway 0.6.77+."""
|
|
229
|
+
return self._rt.stream(OPERATIONS["prefs.events"], path={}, query=None, headers=headers, timeout=timeout)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class TeamsApi:
|
|
233
|
+
"""Team runs — the board every client can read."""
|
|
234
|
+
|
|
235
|
+
def __init__(self, rt: Runtime) -> None:
|
|
236
|
+
self._rt = rt
|
|
237
|
+
|
|
238
|
+
def list_runs(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
239
|
+
"""The board — recent runs, newest first. — Gateway 0.6.78+."""
|
|
240
|
+
return self._rt.request(OPERATIONS["teams.listRuns"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
241
|
+
|
|
242
|
+
def create_run(self, body: "T.TeamRunCreate", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
243
|
+
"""Open a run record. — Gateway 0.6.78+."""
|
|
244
|
+
return self._rt.request(OPERATIONS["teams.createRun"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
245
|
+
|
|
246
|
+
def get_run(self, run_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
247
|
+
"""One run, optionally with its events. — Gateway 0.6.78+."""
|
|
248
|
+
return self._rt.request(OPERATIONS["teams.getRun"], path={"runId": run_id}, query=query, headers=headers, body=None, timeout=timeout)
|
|
249
|
+
|
|
250
|
+
def delete_run(self, run_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
251
|
+
"""Remove a run; a live one is stopped first. — Gateway 0.6.110+."""
|
|
252
|
+
return self._rt.request(OPERATIONS["teams.deleteRun"], path={"runId": run_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
253
|
+
|
|
254
|
+
def run_events(self, run_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[SseFrame["T.RunEvent"]]:
|
|
255
|
+
"""Tail a run — the record first, replay from `after`, then live. — Gateway 0.6.78+."""
|
|
256
|
+
return self._rt.stream(OPERATIONS["teams.runEvents"], path={"runId": run_id}, query=query, headers=headers, timeout=timeout)
|
|
257
|
+
|
|
258
|
+
def append_run_events(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
259
|
+
"""The running client appends events. — Gateway 0.6.78+."""
|
|
260
|
+
return self._rt.request(OPERATIONS["teams.appendRunEvents"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
261
|
+
|
|
262
|
+
def stop_run(self, run_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
263
|
+
"""Ask the running client to stop. — Gateway 0.6.78+."""
|
|
264
|
+
return self._rt.request(OPERATIONS["teams.stopRun"], path={"runId": run_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
265
|
+
|
|
266
|
+
def answer(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
267
|
+
"""A person answers an ask on the board. — Gateway 0.6.81+."""
|
|
268
|
+
return self._rt.request(OPERATIONS["teams.answer"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
269
|
+
|
|
270
|
+
def decide(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
271
|
+
"""Approve or reject a post. — Gateway 0.6.81+."""
|
|
272
|
+
return self._rt.request(OPERATIONS["teams.decide"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
273
|
+
|
|
274
|
+
def post(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
275
|
+
"""Post a note to a thread. — Gateway 0.6.81+."""
|
|
276
|
+
return self._rt.request(OPERATIONS["teams.post"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
277
|
+
|
|
278
|
+
def remove_thread(self, run_id: str, thread_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
279
|
+
"""A person removes a thread from the board. — Gateway 0.6.106+."""
|
|
280
|
+
return self._rt.request(OPERATIONS["teams.removeThread"], path={"runId": run_id, "threadId": thread_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
281
|
+
|
|
282
|
+
def handoff(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
283
|
+
"""Continue a task on another model. — Gateway 0.6.85+."""
|
|
284
|
+
return self._rt.request(OPERATIONS["teams.handoff"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
285
|
+
|
|
286
|
+
def checkpoint(self, run_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
287
|
+
"""What a client needs to resume a run whose client went away. — Gateway 0.6.85+."""
|
|
288
|
+
return self._rt.request(OPERATIONS["teams.checkpoint"], path={"runId": run_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
289
|
+
|
|
290
|
+
def claim(self, run_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
291
|
+
"""A client takes a stopped or stale run over. — Gateway 0.6.85+."""
|
|
292
|
+
return self._rt.request(OPERATIONS["teams.claim"], path={"runId": run_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class ProjectsApi:
|
|
296
|
+
"""The project record — the page a goal starts on and everything done for it."""
|
|
297
|
+
|
|
298
|
+
def __init__(self, rt: Runtime) -> None:
|
|
299
|
+
self._rt = rt
|
|
300
|
+
|
|
301
|
+
def list(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
302
|
+
"""Projects, newest activity first, jobs counted. — Gateway 0.6.90+."""
|
|
303
|
+
return self._rt.request(OPERATIONS["projects.list"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
304
|
+
|
|
305
|
+
def create(self, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
306
|
+
"""Open a record (idempotent) or update the page. — Gateway 0.6.90+."""
|
|
307
|
+
return self._rt.request(OPERATIONS["projects.create"], path={}, query=query, headers=headers, body=body, timeout=timeout)
|
|
308
|
+
|
|
309
|
+
def job_board(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
310
|
+
"""Every open posting across projects. — Gateway 0.6.90+."""
|
|
311
|
+
return self._rt.request(OPERATIONS["projects.jobBoard"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
312
|
+
|
|
313
|
+
def get(self, project_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
314
|
+
"""The record — jobs, runs, spend, decisions, report. — Gateway 0.6.90+."""
|
|
315
|
+
return self._rt.request(OPERATIONS["projects.get"], path={"projectId": project_id}, query=query, headers=headers, body=None, timeout=timeout)
|
|
316
|
+
|
|
317
|
+
def delete(self, project_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
318
|
+
"""Remove a project record. — Gateway 0.6.90+."""
|
|
319
|
+
return self._rt.request(OPERATIONS["projects.delete"], path={"projectId": project_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
320
|
+
|
|
321
|
+
def events(self, project_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Iterator[SseFrame["T.RunEvent"]]:
|
|
322
|
+
"""Tail a project — hello, replay, then live. — Gateway 0.6.90+."""
|
|
323
|
+
return self._rt.stream(OPERATIONS["projects.events"], path={"projectId": project_id}, query=query, headers=headers, timeout=timeout)
|
|
324
|
+
|
|
325
|
+
def append_events(self, project_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
326
|
+
"""The executive loop appends (status, run.linked, run.spent, decision, report). — Gateway 0.6.90+."""
|
|
327
|
+
return self._rt.request(OPERATIONS["projects.appendEvents"], path={"projectId": project_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
328
|
+
|
|
329
|
+
def post_job(self, project_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
330
|
+
"""Post a job. — Gateway 0.6.90+."""
|
|
331
|
+
return self._rt.request(OPERATIONS["projects.postJob"], path={"projectId": project_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
332
|
+
|
|
333
|
+
def patch_job(self, project_id: str, job_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
334
|
+
"""Move a job along its state machine. — Gateway 0.6.90+."""
|
|
335
|
+
return self._rt.request(OPERATIONS["projects.patchJob"], path={"projectId": project_id, "jobId": job_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
336
|
+
|
|
337
|
+
def applications(self, project_id: str, job_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
338
|
+
"""The pool applies at once; `prompt` is the evaluator's, for a structured call. — Gateway 0.6.90+."""
|
|
339
|
+
return self._rt.request(OPERATIONS["projects.applications"], path={"projectId": project_id, "jobId": job_id}, query=query, headers=headers, body=None, timeout=timeout)
|
|
340
|
+
|
|
341
|
+
def recruit(self, project_id: str, job_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
342
|
+
"""One pass — fit recomputed, the evaluation read through the schema, the pick landed as events. — Gateway 0.6.90+."""
|
|
343
|
+
return self._rt.request(OPERATIONS["projects.recruit"], path={"projectId": project_id, "jobId": job_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
class AgentsApi:
|
|
347
|
+
"""Attested per-agent scorecards."""
|
|
348
|
+
|
|
349
|
+
def __init__(self, rt: Runtime) -> None:
|
|
350
|
+
self._rt = rt
|
|
351
|
+
|
|
352
|
+
def scorecards(self, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
353
|
+
"""Every agent's scorecard. — Gateway 0.6.87+."""
|
|
354
|
+
return self._rt.request(OPERATIONS["agents.scorecards"], path={}, query=None, headers=headers, body=None, timeout=timeout)
|
|
355
|
+
|
|
356
|
+
def scorecard(self, agent_id: str, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
357
|
+
"""One agent's attested scorecard. — Gateway 0.6.87+."""
|
|
358
|
+
return self._rt.request(OPERATIONS["agents.scorecard"], path={"agentId": agent_id}, query=None, headers=headers, body=None, timeout=timeout)
|
|
359
|
+
|
|
360
|
+
def rate(self, agent_id: str, body: Dict[str, Any], query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
361
|
+
"""A person rates the agent's work on a run, task or job. — Gateway 0.6.87+."""
|
|
362
|
+
return self._rt.request(OPERATIONS["agents.rate"], path={"agentId": agent_id}, query=query, headers=headers, body=body, timeout=timeout)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class EnginesApi:
|
|
366
|
+
"""The model ledger — every engine's card."""
|
|
367
|
+
|
|
368
|
+
def __init__(self, rt: Runtime) -> None:
|
|
369
|
+
self._rt = rt
|
|
370
|
+
|
|
371
|
+
def list(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
372
|
+
"""Every engine's card. — Gateway 0.6.89+."""
|
|
373
|
+
return self._rt.request(OPERATIONS["engines.list"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
374
|
+
|
|
375
|
+
def card(self, engine_key: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
376
|
+
"""One engine's card, optionally with entries. — Gateway 0.6.89+."""
|
|
377
|
+
return self._rt.request(OPERATIONS["engines.card"], path={"engineKey": engine_key}, query=query, headers=headers, body=None, timeout=timeout)
|
|
378
|
+
|
|
379
|
+
def append_entry(self, engine_key: str, body: "T.AnyObject", query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> "T.AnyObject":
|
|
380
|
+
"""Append a ledger entry for an engine. — Gateway 0.6.89+."""
|
|
381
|
+
return self._rt.request(OPERATIONS["engines.appendEntry"], path={"engineKey": engine_key}, query=query, headers=headers, body=body, timeout=timeout)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class SkillsApi:
|
|
385
|
+
"""The skills on this machine (served through the bridge)."""
|
|
386
|
+
|
|
387
|
+
def __init__(self, rt: Runtime) -> None:
|
|
388
|
+
self._rt = rt
|
|
389
|
+
|
|
390
|
+
def list(self, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
391
|
+
"""The skills on this machine — with a prompt character count, not the prompt. — Gateway 0.6.64+."""
|
|
392
|
+
return self._rt.request(OPERATIONS["skills.list"], path={}, query=query, headers=headers, body=None, timeout=timeout)
|
|
393
|
+
|
|
394
|
+
def get(self, skill_id: str, query: Optional[Dict[str, Any]] = None, *, headers: Optional[Dict[str, str]] = None, timeout: Optional[float] = None) -> Dict[str, Any]:
|
|
395
|
+
"""One skill, with its prompt. — Gateway 0.6.67+."""
|
|
396
|
+
return self._rt.request(OPERATIONS["skills.get"], path={"skillId": skill_id}, query=query, headers=headers, body=None, timeout=timeout)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class Api:
|
|
400
|
+
"""The namespaces a client exposes, built on one runtime."""
|
|
401
|
+
|
|
402
|
+
def __init__(self, rt: Runtime) -> None:
|
|
403
|
+
self.gateway = GatewayApi(rt)
|
|
404
|
+
self.models = ModelsApi(rt)
|
|
405
|
+
self.chat = ChatApi(rt)
|
|
406
|
+
self.redaction = RedactionApi(rt)
|
|
407
|
+
self.history = HistoryApi(rt)
|
|
408
|
+
self.memory = MemoryApi(rt)
|
|
409
|
+
self.prefs = PrefsApi(rt)
|
|
410
|
+
self.teams = TeamsApi(rt)
|
|
411
|
+
self.projects = ProjectsApi(rt)
|
|
412
|
+
self.agents = AgentsApi(rt)
|
|
413
|
+
self.engines = EnginesApi(rt)
|
|
414
|
+
self.skills = SkillsApi(rt)
|