codex-chatgpt-control 0.1.0a1__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.
- codex_chatgpt_control/__init__.py +101 -0
- codex_chatgpt_control/agent.py +45 -0
- codex_chatgpt_control/async_client.py +369 -0
- codex_chatgpt_control/backend.py +338 -0
- codex_chatgpt_control/client.py +152 -0
- codex_chatgpt_control/commands.py +52 -0
- codex_chatgpt_control/models.py +240 -0
- codex_chatgpt_control/primitives.py +93 -0
- codex_chatgpt_control/py.typed +1 -0
- codex_chatgpt_control/reports.py +33 -0
- codex_chatgpt_control/responses.py +235 -0
- codex_chatgpt_control/runner.py +59 -0
- codex_chatgpt_control/thread_entrypoint.py +433 -0
- codex_chatgpt_control/transport.py +42 -0
- codex_chatgpt_control/workflows.py +52 -0
- codex_chatgpt_control-0.1.0a1.dist-info/METADATA +151 -0
- codex_chatgpt_control-0.1.0a1.dist-info/RECORD +21 -0
- codex_chatgpt_control-0.1.0a1.dist-info/WHEEL +5 -0
- codex_chatgpt_control-0.1.0a1.dist-info/entry_points.txt +2 -0
- codex_chatgpt_control-0.1.0a1.dist-info/licenses/LICENSE +21 -0
- codex_chatgpt_control-0.1.0a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from .async_client import (
|
|
2
|
+
AsyncChatGPT,
|
|
3
|
+
AsyncChatGPTRunner,
|
|
4
|
+
AsyncCommandClient,
|
|
5
|
+
AsyncPrimitiveGroup,
|
|
6
|
+
AsyncReportsClient,
|
|
7
|
+
AsyncResponsesClient,
|
|
8
|
+
AsyncRunResultStreaming,
|
|
9
|
+
AsyncWorkflowClient,
|
|
10
|
+
)
|
|
11
|
+
from .agent import Agent, AgentConfig
|
|
12
|
+
from .backend import (
|
|
13
|
+
BACKEND_EVENT_SCHEMA_VERSION,
|
|
14
|
+
BACKEND_REQUEST_SCHEMA_VERSION,
|
|
15
|
+
BACKEND_RESPONSE_SCHEMA_VERSION,
|
|
16
|
+
BackendClient,
|
|
17
|
+
BackendProtocolError,
|
|
18
|
+
BackendRequest,
|
|
19
|
+
BackendTransportError,
|
|
20
|
+
StdioBackendTransport,
|
|
21
|
+
)
|
|
22
|
+
from .client import ChatGPT, ChatGPTAgent, ChatGPTRunner
|
|
23
|
+
from .commands import CommandClient
|
|
24
|
+
from .models import (
|
|
25
|
+
BackendCapabilities,
|
|
26
|
+
BackendEvent,
|
|
27
|
+
BackendResponse,
|
|
28
|
+
ChatGPTAgentModel,
|
|
29
|
+
ChatGPTResponse,
|
|
30
|
+
ChatGPTRunInput,
|
|
31
|
+
ChatGPTRunResult,
|
|
32
|
+
ChatGPTRunState,
|
|
33
|
+
ChatGPTStreamEvent,
|
|
34
|
+
CommandDescriptor,
|
|
35
|
+
CommandResult,
|
|
36
|
+
DoctorReport,
|
|
37
|
+
RunReportData,
|
|
38
|
+
SequencePlan,
|
|
39
|
+
)
|
|
40
|
+
from .transport import NodeSidecarError, NodeSidecarTransport
|
|
41
|
+
from .runner import RunResult, RunResultStreaming, RunState, Runner
|
|
42
|
+
from .responses import ResponsesClient, ResponsesValidationResult
|
|
43
|
+
from .primitives import FilesClient, MessagesClient, ModesClient, ResponseClient, SessionClient, ThreadsClient, ToolsClient
|
|
44
|
+
from .reports import ReportsClient
|
|
45
|
+
from .workflows import WorkflowClient
|
|
46
|
+
|
|
47
|
+
__all__ = [
|
|
48
|
+
"Agent",
|
|
49
|
+
"AgentConfig",
|
|
50
|
+
"AsyncChatGPT",
|
|
51
|
+
"AsyncChatGPTRunner",
|
|
52
|
+
"AsyncCommandClient",
|
|
53
|
+
"AsyncPrimitiveGroup",
|
|
54
|
+
"AsyncReportsClient",
|
|
55
|
+
"AsyncResponsesClient",
|
|
56
|
+
"AsyncRunResultStreaming",
|
|
57
|
+
"AsyncWorkflowClient",
|
|
58
|
+
"BACKEND_EVENT_SCHEMA_VERSION",
|
|
59
|
+
"BACKEND_REQUEST_SCHEMA_VERSION",
|
|
60
|
+
"BACKEND_RESPONSE_SCHEMA_VERSION",
|
|
61
|
+
"BackendClient",
|
|
62
|
+
"BackendProtocolError",
|
|
63
|
+
"BackendRequest",
|
|
64
|
+
"BackendTransportError",
|
|
65
|
+
"BackendCapabilities",
|
|
66
|
+
"BackendEvent",
|
|
67
|
+
"BackendResponse",
|
|
68
|
+
"ChatGPT",
|
|
69
|
+
"ChatGPTAgentModel",
|
|
70
|
+
"ChatGPTAgent",
|
|
71
|
+
"ChatGPTRunner",
|
|
72
|
+
"ChatGPTRunInput",
|
|
73
|
+
"ChatGPTResponse",
|
|
74
|
+
"ChatGPTRunResult",
|
|
75
|
+
"ChatGPTRunState",
|
|
76
|
+
"ChatGPTStreamEvent",
|
|
77
|
+
"CommandClient",
|
|
78
|
+
"CommandDescriptor",
|
|
79
|
+
"CommandResult",
|
|
80
|
+
"DoctorReport",
|
|
81
|
+
"FilesClient",
|
|
82
|
+
"MessagesClient",
|
|
83
|
+
"ModesClient",
|
|
84
|
+
"NodeSidecarError",
|
|
85
|
+
"NodeSidecarTransport",
|
|
86
|
+
"ReportsClient",
|
|
87
|
+
"ResponseClient",
|
|
88
|
+
"RunReportData",
|
|
89
|
+
"RunResult",
|
|
90
|
+
"RunResultStreaming",
|
|
91
|
+
"RunState",
|
|
92
|
+
"Runner",
|
|
93
|
+
"ResponsesClient",
|
|
94
|
+
"ResponsesValidationResult",
|
|
95
|
+
"SessionClient",
|
|
96
|
+
"SequencePlan",
|
|
97
|
+
"StdioBackendTransport",
|
|
98
|
+
"ThreadsClient",
|
|
99
|
+
"ToolsClient",
|
|
100
|
+
"WorkflowClient",
|
|
101
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
InstructionsMode = Literal["visible_prefix", "visible_setup_message", "metadata_only"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True)
|
|
11
|
+
class Agent:
|
|
12
|
+
name: str
|
|
13
|
+
instructions: str | None = None
|
|
14
|
+
instructions_mode: InstructionsMode = "visible_prefix"
|
|
15
|
+
defaults: dict[str, Any] = field(default_factory=dict)
|
|
16
|
+
tools: list[dict[str, Any]] = field(default_factory=list)
|
|
17
|
+
guardrails: list[dict[str, Any]] = field(default_factory=list)
|
|
18
|
+
output: dict[str, Any] | None = None
|
|
19
|
+
metadata: dict[str, Any] | None = None
|
|
20
|
+
|
|
21
|
+
def __post_init__(self) -> None:
|
|
22
|
+
normalized = self.name.strip()
|
|
23
|
+
if not normalized:
|
|
24
|
+
raise ValueError("Agent name must not be empty.")
|
|
25
|
+
object.__setattr__(self, "name", normalized)
|
|
26
|
+
|
|
27
|
+
def to_wire(self) -> dict[str, Any]:
|
|
28
|
+
payload: dict[str, Any] = {
|
|
29
|
+
"kind": "chatgpt_browser_agent",
|
|
30
|
+
"name": self.name,
|
|
31
|
+
"instructionsMode": self.instructions_mode,
|
|
32
|
+
"defaults": self.defaults,
|
|
33
|
+
"tools": self.tools,
|
|
34
|
+
"guardrails": self.guardrails,
|
|
35
|
+
}
|
|
36
|
+
if self.instructions is not None:
|
|
37
|
+
payload["instructions"] = self.instructions
|
|
38
|
+
if self.output is not None:
|
|
39
|
+
payload["output"] = self.output
|
|
40
|
+
if self.metadata is not None:
|
|
41
|
+
payload["metadata"] = self.metadata
|
|
42
|
+
return payload
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
AgentConfig = Agent
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from collections.abc import Iterator
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from typing import Any, Protocol
|
|
8
|
+
|
|
9
|
+
from .agent import Agent
|
|
10
|
+
from .commands import wire_kwargs
|
|
11
|
+
from .models import BackendEvent, ChatGPTResponse, ChatGPTRunResult, CommandDescriptor, CommandResult, SequencePlan
|
|
12
|
+
from .responses import (
|
|
13
|
+
normalize_create_args,
|
|
14
|
+
response_from_run_result,
|
|
15
|
+
responses_create_args_to_run_input,
|
|
16
|
+
unsupported_response,
|
|
17
|
+
validate_responses_create_args,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AsyncBackendProtocol(Protocol):
|
|
22
|
+
def request(self, command: str, payload: dict[str, Any] | None = None) -> Any:
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AsyncRunTransport(Protocol):
|
|
27
|
+
async def run(self, payload: dict[str, Any]) -> dict[str, Any]:
|
|
28
|
+
"""Legacy async sidecar run shape kept as a compatibility fallback."""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def maybe_await(value: Any) -> Any:
|
|
33
|
+
if inspect.isawaitable(value):
|
|
34
|
+
return await value
|
|
35
|
+
return value
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
async def async_request_backend(backend: Any, command: str, payload: dict[str, Any] | None = None) -> Any:
|
|
39
|
+
request = getattr(backend, "request", None)
|
|
40
|
+
if not callable(request):
|
|
41
|
+
raise RuntimeError(f"This ChatGPT backend does not support {command}.")
|
|
42
|
+
return await maybe_await(request(command, payload or {}))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def command_result_from_wire(value: Any, command: str) -> CommandResult:
|
|
46
|
+
if not isinstance(value, dict):
|
|
47
|
+
raise RuntimeError(f"{command} backend result must be a CommandResult object.")
|
|
48
|
+
return CommandResult.from_wire(value)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class AsyncChatGPTRunner:
|
|
52
|
+
def __init__(self, backend: Any) -> None:
|
|
53
|
+
self._backend = backend
|
|
54
|
+
|
|
55
|
+
async def run(self, agent: Agent, input: Any) -> ChatGPTRunResult:
|
|
56
|
+
runner_run = getattr(self._backend, "runner_run", None)
|
|
57
|
+
if callable(runner_run):
|
|
58
|
+
result = await maybe_await(runner_run(agent.to_wire(), input))
|
|
59
|
+
if not isinstance(result, dict):
|
|
60
|
+
raise RuntimeError("runner.run backend result must be a JSON object.")
|
|
61
|
+
return ChatGPTRunResult.from_wire(result)
|
|
62
|
+
|
|
63
|
+
request = getattr(self._backend, "request", None)
|
|
64
|
+
if callable(request):
|
|
65
|
+
result = await async_request_backend(self._backend, "runner.run", {"agent": agent.to_wire(), "input": input})
|
|
66
|
+
if not isinstance(result, dict):
|
|
67
|
+
raise RuntimeError("runner.run backend result must be a JSON object.")
|
|
68
|
+
return ChatGPTRunResult.from_wire(result)
|
|
69
|
+
|
|
70
|
+
legacy_run = getattr(self._backend, "run", None)
|
|
71
|
+
if not callable(legacy_run):
|
|
72
|
+
raise RuntimeError("This ChatGPT backend does not support runner.run.")
|
|
73
|
+
payload = {
|
|
74
|
+
"schemaVersion": "chatgpt.browser_control.run.v1",
|
|
75
|
+
"agent": agent.to_wire(),
|
|
76
|
+
"input": input,
|
|
77
|
+
}
|
|
78
|
+
return ChatGPTRunResult.from_wire(await maybe_await(legacy_run(payload)))
|
|
79
|
+
|
|
80
|
+
async def plan(self, agent: Agent, input: Any) -> SequencePlan:
|
|
81
|
+
runner_plan = getattr(self._backend, "runner_plan", None)
|
|
82
|
+
if callable(runner_plan):
|
|
83
|
+
result = await maybe_await(runner_plan(agent.to_wire(), input))
|
|
84
|
+
else:
|
|
85
|
+
result = await async_request_backend(self._backend, "runner.plan", {"agent": agent.to_wire(), "input": input})
|
|
86
|
+
if not isinstance(result, dict):
|
|
87
|
+
raise RuntimeError("runner.plan backend result must be a JSON object.")
|
|
88
|
+
return SequencePlan.from_wire(result)
|
|
89
|
+
|
|
90
|
+
def run_streamed(self, agent: Agent, input: Any) -> "AsyncRunResultStreaming":
|
|
91
|
+
runner_stream = getattr(self._backend, "runner_stream", None)
|
|
92
|
+
if callable(runner_stream):
|
|
93
|
+
events = runner_stream(agent.to_wire(), input)
|
|
94
|
+
else:
|
|
95
|
+
stream = getattr(self._backend, "stream", None)
|
|
96
|
+
if not callable(stream):
|
|
97
|
+
raise RuntimeError("This ChatGPT backend does not support runner.stream.")
|
|
98
|
+
events = stream("runner.stream", {"agent": agent.to_wire(), "input": input})
|
|
99
|
+
return AsyncRunResultStreaming(events)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class AsyncRunResultStreaming:
|
|
104
|
+
_events: Any
|
|
105
|
+
final_result: ChatGPTRunResult | None = None
|
|
106
|
+
_iterator: Iterator[Any] | None = None
|
|
107
|
+
|
|
108
|
+
def __aiter__(self) -> "AsyncRunResultStreaming":
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
async def __anext__(self) -> BackendEvent:
|
|
112
|
+
if hasattr(self._events, "__anext__"):
|
|
113
|
+
raw = await self._events.__anext__()
|
|
114
|
+
else:
|
|
115
|
+
if self._iterator is None:
|
|
116
|
+
self._iterator = iter(self._events)
|
|
117
|
+
try:
|
|
118
|
+
raw = next(self._iterator)
|
|
119
|
+
except StopIteration as exc:
|
|
120
|
+
raise StopAsyncIteration from exc
|
|
121
|
+
event = BackendEvent.from_wire(raw)
|
|
122
|
+
if event.type == "completed" and isinstance(event.result, ChatGPTRunResult):
|
|
123
|
+
self.final_result = event.result
|
|
124
|
+
return event
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class AsyncResponsesClient:
|
|
128
|
+
def __init__(self, backend: Any) -> None:
|
|
129
|
+
self._backend = backend
|
|
130
|
+
|
|
131
|
+
async def create(self, args: dict[str, Any] | None = None, **kwargs: Any) -> ChatGPTResponse:
|
|
132
|
+
payload = normalize_create_args({**(args or {}), **kwargs})
|
|
133
|
+
validation = validate_responses_create_args(payload)
|
|
134
|
+
now = datetime.now(timezone.utc)
|
|
135
|
+
if not validation.ok:
|
|
136
|
+
return unsupported_response(validation.unsupported, now)
|
|
137
|
+
|
|
138
|
+
request = getattr(self._backend, "request", None)
|
|
139
|
+
if callable(request):
|
|
140
|
+
result = await async_request_backend(self._backend, "responses.create", payload)
|
|
141
|
+
if not isinstance(result, dict):
|
|
142
|
+
raise RuntimeError("responses.create backend result must be a JSON object.")
|
|
143
|
+
return ChatGPTResponse.from_wire(result)
|
|
144
|
+
|
|
145
|
+
responses_create = getattr(self._backend, "responses_create", None)
|
|
146
|
+
if callable(responses_create):
|
|
147
|
+
result = await maybe_await(responses_create(payload))
|
|
148
|
+
if not isinstance(result, dict):
|
|
149
|
+
raise RuntimeError("responses.create backend result must be a JSON object.")
|
|
150
|
+
return ChatGPTResponse.from_wire(result)
|
|
151
|
+
|
|
152
|
+
legacy_run = getattr(self._backend, "run", None)
|
|
153
|
+
if not callable(legacy_run):
|
|
154
|
+
raise RuntimeError("This ChatGPT backend does not support responses.create.")
|
|
155
|
+
agent = Agent(
|
|
156
|
+
name="responses-adapter",
|
|
157
|
+
instructions=payload.get("instructions") if isinstance(payload.get("instructions"), str) else None,
|
|
158
|
+
instructions_mode=payload.get("instructionsMode", "visible_prefix"), # type: ignore[arg-type]
|
|
159
|
+
)
|
|
160
|
+
result = await maybe_await(legacy_run({
|
|
161
|
+
"schemaVersion": "chatgpt.browser_control.run.v1",
|
|
162
|
+
"agent": agent.to_wire(),
|
|
163
|
+
"input": responses_create_args_to_run_input(payload),
|
|
164
|
+
}))
|
|
165
|
+
return response_from_run_result(ChatGPTRunResult.from_wire(result), now)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class AsyncWorkflowClient:
|
|
169
|
+
def __init__(self, backend: Any) -> None:
|
|
170
|
+
self._backend = backend
|
|
171
|
+
|
|
172
|
+
async def ask(self, **kwargs: Any) -> CommandResult:
|
|
173
|
+
return command_result_from_wire(await async_request_backend(self._backend, "ask", wire_kwargs(**kwargs)), "ask")
|
|
174
|
+
|
|
175
|
+
async def ask_in_thread(self, **kwargs: Any) -> CommandResult:
|
|
176
|
+
return command_result_from_wire(await async_request_backend(self._backend, "askInThread", wire_kwargs(**kwargs)), "askInThread")
|
|
177
|
+
|
|
178
|
+
async def ask_with_files(self, **kwargs: Any) -> CommandResult:
|
|
179
|
+
return command_result_from_wire(await async_request_backend(self._backend, "askWithFiles", wire_kwargs(**kwargs)), "askWithFiles")
|
|
180
|
+
|
|
181
|
+
async def ask_and_download(self, **kwargs: Any) -> CommandResult:
|
|
182
|
+
return command_result_from_wire(await async_request_backend(self._backend, "askAndDownload", wire_kwargs(**kwargs)), "askAndDownload")
|
|
183
|
+
|
|
184
|
+
async def run_messages(self, **kwargs: Any) -> CommandResult:
|
|
185
|
+
return command_result_from_wire(await async_request_backend(self._backend, "runMessages", wire_kwargs(**kwargs)), "runMessages")
|
|
186
|
+
|
|
187
|
+
async def open_thread(self, thread: dict[str, Any]) -> CommandResult:
|
|
188
|
+
return command_result_from_wire(await async_request_backend(self._backend, "openThread", thread), "openThread")
|
|
189
|
+
|
|
190
|
+
async def read_latest(self, **kwargs: Any) -> CommandResult:
|
|
191
|
+
return command_result_from_wire(await async_request_backend(self._backend, "readLatest", wire_kwargs(**kwargs)), "readLatest")
|
|
192
|
+
|
|
193
|
+
async def copy_latest(self, **kwargs: Any) -> CommandResult:
|
|
194
|
+
return command_result_from_wire(await async_request_backend(self._backend, "copyLatest", wire_kwargs(**kwargs)), "copyLatest")
|
|
195
|
+
|
|
196
|
+
async def download_latest(self, **kwargs: Any) -> CommandResult:
|
|
197
|
+
return command_result_from_wire(await async_request_backend(self._backend, "downloadLatest", wire_kwargs(**kwargs)), "downloadLatest")
|
|
198
|
+
|
|
199
|
+
async def run_plan(self, plan: dict[str, Any]) -> CommandResult:
|
|
200
|
+
return command_result_from_wire(await async_request_backend(self._backend, "runPlan", plan), "runPlan")
|
|
201
|
+
|
|
202
|
+
async def doctor(self, **kwargs: Any) -> CommandResult:
|
|
203
|
+
return command_result_from_wire(await async_request_backend(self._backend, "doctor", wire_kwargs(**kwargs)), "doctor")
|
|
204
|
+
|
|
205
|
+
async def create_report(self, result: dict[str, Any], **kwargs: Any) -> CommandResult:
|
|
206
|
+
payload: dict[str, Any] = {"result": result}
|
|
207
|
+
args = wire_kwargs(**kwargs)
|
|
208
|
+
if args:
|
|
209
|
+
payload["args"] = args
|
|
210
|
+
return command_result_from_wire(await async_request_backend(self._backend, "createReport", payload), "createReport")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class AsyncCommandClient:
|
|
214
|
+
def __init__(self, backend: Any) -> None:
|
|
215
|
+
self._backend = backend
|
|
216
|
+
|
|
217
|
+
async def commands(self, *, layer: str | None = None) -> list[CommandDescriptor]:
|
|
218
|
+
payload: dict[str, Any] = {}
|
|
219
|
+
if layer is not None:
|
|
220
|
+
payload["filter"] = {"layer": layer}
|
|
221
|
+
result = await async_request_backend(self._backend, "commands", payload)
|
|
222
|
+
if not isinstance(result, list):
|
|
223
|
+
raise RuntimeError("commands backend result must be a list.")
|
|
224
|
+
return [CommandDescriptor.from_wire(item) for item in result]
|
|
225
|
+
|
|
226
|
+
async def describe(self, name: str) -> CommandDescriptor:
|
|
227
|
+
result = await async_request_backend(self._backend, "describe", {"name": name})
|
|
228
|
+
if not isinstance(result, dict):
|
|
229
|
+
raise RuntimeError("describe backend result must be a command descriptor.")
|
|
230
|
+
return CommandDescriptor.from_wire(result)
|
|
231
|
+
|
|
232
|
+
async def help(self, topic: str | None = None) -> str:
|
|
233
|
+
payload = {} if topic is None else {"topic": topic}
|
|
234
|
+
result = await async_request_backend(self._backend, "help", payload)
|
|
235
|
+
if not isinstance(result, str):
|
|
236
|
+
raise RuntimeError("help backend result must be a string.")
|
|
237
|
+
return result
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class AsyncReportsClient:
|
|
241
|
+
def __init__(self, backend: Any) -> None:
|
|
242
|
+
self._backend = backend
|
|
243
|
+
|
|
244
|
+
async def create(self, result: dict[str, Any], **kwargs: Any) -> CommandResult:
|
|
245
|
+
return await async_report_command(self._backend, "reports.create", {"result": result}, **kwargs)
|
|
246
|
+
|
|
247
|
+
async def redact(self, value: Any, **kwargs: Any) -> CommandResult:
|
|
248
|
+
return await async_report_command(self._backend, "reports.redact", {"value": value}, **kwargs)
|
|
249
|
+
|
|
250
|
+
async def summarize(self, result: dict[str, Any], **kwargs: Any) -> CommandResult:
|
|
251
|
+
return await async_report_command(self._backend, "reports.summarize", {"result": result}, **kwargs)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
async def async_report_command(backend: Any, command: str, payload: dict[str, Any], **kwargs: Any) -> CommandResult:
|
|
255
|
+
args = wire_kwargs(**kwargs)
|
|
256
|
+
if args:
|
|
257
|
+
payload["args"] = args
|
|
258
|
+
return command_result_from_wire(await async_request_backend(backend, command, payload), command)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class AsyncPrimitiveGroup:
|
|
262
|
+
def __init__(self, backend: Any, commands: dict[str, str]) -> None:
|
|
263
|
+
self._backend = backend
|
|
264
|
+
self._commands = commands
|
|
265
|
+
|
|
266
|
+
def __getattr__(self, name: str):
|
|
267
|
+
command = self._commands.get(name)
|
|
268
|
+
if command is None:
|
|
269
|
+
raise AttributeError(name)
|
|
270
|
+
|
|
271
|
+
async def call(**kwargs: Any) -> CommandResult:
|
|
272
|
+
return command_result_from_wire(await async_request_backend(self._backend, command, wire_kwargs(**kwargs)), command)
|
|
273
|
+
|
|
274
|
+
return call
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class AsyncChatGPT:
|
|
278
|
+
def __init__(self, transport: Any) -> None:
|
|
279
|
+
self._backend = transport
|
|
280
|
+
self.responses = AsyncResponsesClient(transport)
|
|
281
|
+
self.runner = AsyncChatGPTRunner(transport)
|
|
282
|
+
self._workflows = AsyncWorkflowClient(transport)
|
|
283
|
+
self._commands = AsyncCommandClient(transport)
|
|
284
|
+
self.session = AsyncPrimitiveGroup(transport, {"bootstrap": "session.bootstrap"})
|
|
285
|
+
self.threads = AsyncPrimitiveGroup(transport, {"new": "threads.new", "search": "threads.search", "open": "threads.open"})
|
|
286
|
+
self.messages = AsyncPrimitiveGroup(transport, {
|
|
287
|
+
"compose": "messages.compose",
|
|
288
|
+
"submit": "messages.submit",
|
|
289
|
+
"ask": "messages.ask",
|
|
290
|
+
"wait": "messages.wait",
|
|
291
|
+
"read_latest": "messages.readLatest",
|
|
292
|
+
"wait_and_read": "messages.waitAndRead",
|
|
293
|
+
})
|
|
294
|
+
self.files = AsyncPrimitiveGroup(transport, {"attach": "files.attach", "download_latest": "files.downloadLatest"})
|
|
295
|
+
self.modes = AsyncPrimitiveGroup(transport, {"set": "modes.set"})
|
|
296
|
+
self.tools = AsyncPrimitiveGroup(transport, {"select": "tools.select"})
|
|
297
|
+
self.response = AsyncPrimitiveGroup(transport, {"copy": "response.copy"})
|
|
298
|
+
self.reports = AsyncReportsClient(transport)
|
|
299
|
+
|
|
300
|
+
async def run(self, agent: Agent, input: Any) -> ChatGPTRunResult:
|
|
301
|
+
return await self.runner.run(agent, input)
|
|
302
|
+
|
|
303
|
+
async def ask(self, **kwargs: Any) -> CommandResult:
|
|
304
|
+
return await self._workflows.ask(**kwargs)
|
|
305
|
+
|
|
306
|
+
async def ask_in_thread(self, **kwargs: Any) -> CommandResult:
|
|
307
|
+
return await self._workflows.ask_in_thread(**kwargs)
|
|
308
|
+
|
|
309
|
+
async def ask_with_files(self, **kwargs: Any) -> CommandResult:
|
|
310
|
+
return await self._workflows.ask_with_files(**kwargs)
|
|
311
|
+
|
|
312
|
+
async def ask_and_download(self, **kwargs: Any) -> CommandResult:
|
|
313
|
+
return await self._workflows.ask_and_download(**kwargs)
|
|
314
|
+
|
|
315
|
+
async def run_messages(self, **kwargs: Any) -> CommandResult:
|
|
316
|
+
return await self._workflows.run_messages(**kwargs)
|
|
317
|
+
|
|
318
|
+
async def open_thread(self, thread: dict[str, Any]) -> CommandResult:
|
|
319
|
+
return await self._workflows.open_thread(thread)
|
|
320
|
+
|
|
321
|
+
async def read_latest(self, **kwargs: Any) -> CommandResult:
|
|
322
|
+
return await self._workflows.read_latest(**kwargs)
|
|
323
|
+
|
|
324
|
+
async def copy_latest(self, **kwargs: Any) -> CommandResult:
|
|
325
|
+
return await self._workflows.copy_latest(**kwargs)
|
|
326
|
+
|
|
327
|
+
async def download_latest(self, **kwargs: Any) -> CommandResult:
|
|
328
|
+
return await self._workflows.download_latest(**kwargs)
|
|
329
|
+
|
|
330
|
+
async def run_plan(self, plan: dict[str, Any]) -> CommandResult:
|
|
331
|
+
return await self._workflows.run_plan(plan)
|
|
332
|
+
|
|
333
|
+
async def doctor(self, **kwargs: Any) -> CommandResult:
|
|
334
|
+
return await self._workflows.doctor(**kwargs)
|
|
335
|
+
|
|
336
|
+
async def create_report(self, result: dict[str, Any], **kwargs: Any) -> CommandResult:
|
|
337
|
+
return await self._workflows.create_report(result, **kwargs)
|
|
338
|
+
|
|
339
|
+
async def commands(self, *, layer: str | None = None) -> list[CommandDescriptor]:
|
|
340
|
+
return await self._commands.commands(layer=layer)
|
|
341
|
+
|
|
342
|
+
async def describe(self, name: str) -> CommandDescriptor:
|
|
343
|
+
return await self._commands.describe(name)
|
|
344
|
+
|
|
345
|
+
async def help(self, topic: str | None = None) -> str:
|
|
346
|
+
return await self._commands.help(topic)
|
|
347
|
+
|
|
348
|
+
def agent(
|
|
349
|
+
self,
|
|
350
|
+
*,
|
|
351
|
+
name: str,
|
|
352
|
+
instructions: str | None = None,
|
|
353
|
+
instructions_mode: str = "visible_prefix",
|
|
354
|
+
defaults: dict[str, Any] | None = None,
|
|
355
|
+
tools: list[dict[str, Any]] | None = None,
|
|
356
|
+
guardrails: list[dict[str, Any]] | None = None,
|
|
357
|
+
output: dict[str, Any] | None = None,
|
|
358
|
+
metadata: dict[str, Any] | None = None,
|
|
359
|
+
) -> Agent:
|
|
360
|
+
return Agent(
|
|
361
|
+
name=name,
|
|
362
|
+
instructions=instructions,
|
|
363
|
+
instructions_mode=instructions_mode, # type: ignore[arg-type]
|
|
364
|
+
defaults=defaults or {},
|
|
365
|
+
tools=tools or [],
|
|
366
|
+
guardrails=guardrails or [],
|
|
367
|
+
output=output,
|
|
368
|
+
metadata=metadata,
|
|
369
|
+
)
|