codex-python 1.131.1__tar.gz → 1.140.0__tar.gz
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_python-1.131.1 → codex_python-1.140.0}/PKG-INFO +1 -1
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/__init__.py +1 -1
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_async_client.py +3 -1
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_async_services.py +74 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_async_threads.py +16 -5
- codex_python-1.140.0/codex/app_server/_payloads.py +102 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_sync_client.py +2 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_sync_services.py +83 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_sync_threads.py +24 -5
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/options.py +66 -15
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/options.py +52 -4
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/protocol/types.py +1505 -725
- {codex_python-1.131.1 → codex_python-1.140.0}/crates/codex_native/Cargo.lock +9 -9
- {codex_python-1.131.1 → codex_python-1.140.0}/crates/codex_native/Cargo.toml +1 -1
- codex_python-1.131.1/codex/app_server/_payloads.py +0 -59
- {codex_python-1.131.1 → codex_python-1.140.0}/LICENSE +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/README.md +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/_binary.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/_config_types.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/_file_utils.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/_runtime.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/_turn_options.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/__init__.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_protocol_helpers.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_session.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_sync_support.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/_types.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/errors.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/models.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/app_server/transports.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/codex.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/dynamic_tools.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/errors.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/output_schema.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/output_schema_file.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/protocol/__init__.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/py.typed +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/thread.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/codex/vendor/.gitkeep +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/crates/codex_native/codex/__init__.py +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/crates/codex_native/src/lib.rs +0 -0
- {codex_python-1.131.1 → codex_python-1.140.0}/pyproject.toml +0 -0
|
@@ -14,6 +14,7 @@ from codex.app_server._async_services import (
|
|
|
14
14
|
AsyncConfigClient,
|
|
15
15
|
AsyncExternalAgentConfigClient,
|
|
16
16
|
AsyncFeedbackClient,
|
|
17
|
+
AsyncFsClient,
|
|
17
18
|
AsyncMcpServersClient,
|
|
18
19
|
AsyncModelsClient,
|
|
19
20
|
AsyncSkillsClient,
|
|
@@ -151,7 +152,8 @@ class AsyncAppServerClient:
|
|
|
151
152
|
self.events = AsyncEventsClient(self._session)
|
|
152
153
|
self.models = AsyncModelsClient(self.rpc)
|
|
153
154
|
self.apps = AsyncAppsClient(self.rpc)
|
|
154
|
-
self.
|
|
155
|
+
self.fs = AsyncFsClient(self.rpc)
|
|
156
|
+
self.skills = AsyncSkillsClient(self.rpc, self.fs)
|
|
155
157
|
self.account = AsyncAccountClient(self.rpc)
|
|
156
158
|
self.config = AsyncConfigClient(self.rpc)
|
|
157
159
|
self.mcp_servers = AsyncMcpServersClient(self.rpc)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import base64
|
|
3
4
|
from collections.abc import Mapping, Sequence
|
|
4
5
|
from typing import Any, Protocol, TypeVar
|
|
5
6
|
|
|
6
7
|
from pydantic import BaseModel
|
|
7
8
|
|
|
9
|
+
from codex.app_server._payloads import skill_input
|
|
8
10
|
from codex.app_server.models import (
|
|
9
11
|
AccountCancelLoginResult,
|
|
10
12
|
AccountRateLimitsResult,
|
|
@@ -49,6 +51,16 @@ class _AsyncServiceClient:
|
|
|
49
51
|
self._rpc = rpc
|
|
50
52
|
|
|
51
53
|
|
|
54
|
+
def _skill_markdown_path(directory: str) -> str:
|
|
55
|
+
if directory == "":
|
|
56
|
+
raise ValueError("Skill directory cannot be empty.")
|
|
57
|
+
if directory.endswith("/") or directory.endswith("\\"):
|
|
58
|
+
return f"{directory}SKILL.md"
|
|
59
|
+
if "\\" in directory and "/" not in directory:
|
|
60
|
+
return f"{directory}\\SKILL.md"
|
|
61
|
+
return f"{directory}/SKILL.md"
|
|
62
|
+
|
|
63
|
+
|
|
52
64
|
class AsyncModelsClient(_AsyncServiceClient):
|
|
53
65
|
async def list(
|
|
54
66
|
self,
|
|
@@ -107,7 +119,50 @@ class AsyncAppsClient(_AsyncServiceClient):
|
|
|
107
119
|
return await self._rpc.request_typed("app/list", params, AppListResult)
|
|
108
120
|
|
|
109
121
|
|
|
122
|
+
class AsyncFsClient(_AsyncServiceClient):
|
|
123
|
+
async def create_directory(
|
|
124
|
+
self,
|
|
125
|
+
*,
|
|
126
|
+
path: str,
|
|
127
|
+
recursive: bool | None = True,
|
|
128
|
+
) -> protocol.FsCreateDirectoryResponse:
|
|
129
|
+
params = protocol.FsCreateDirectoryParams(
|
|
130
|
+
path=protocol.AbsolutePathBuf(path),
|
|
131
|
+
recursive=recursive,
|
|
132
|
+
)
|
|
133
|
+
return await self._rpc.request_typed(
|
|
134
|
+
"fs/createDirectory",
|
|
135
|
+
params,
|
|
136
|
+
protocol.FsCreateDirectoryResponse,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
async def write_file(
|
|
140
|
+
self,
|
|
141
|
+
*,
|
|
142
|
+
path: str,
|
|
143
|
+
data: str | bytes,
|
|
144
|
+
encoding: str = "utf-8",
|
|
145
|
+
) -> protocol.FsWriteFileResponse:
|
|
146
|
+
raw_data = data.encode(encoding) if isinstance(data, str) else data
|
|
147
|
+
params = protocol.FsWriteFileParams(
|
|
148
|
+
path=protocol.AbsolutePathBuf(path),
|
|
149
|
+
dataBase64=base64.b64encode(raw_data).decode("ascii"),
|
|
150
|
+
)
|
|
151
|
+
return await self._rpc.request_typed(
|
|
152
|
+
"fs/writeFile",
|
|
153
|
+
params,
|
|
154
|
+
protocol.FsWriteFileResponse,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
110
158
|
class AsyncSkillsClient(_AsyncServiceClient):
|
|
159
|
+
def __init__(self, rpc: _TypedRpcClient, fs: AsyncFsClient) -> None:
|
|
160
|
+
super().__init__(rpc)
|
|
161
|
+
self._fs = fs
|
|
162
|
+
|
|
163
|
+
def input(self, *, name: str, path: str) -> protocol.SkillUserInput:
|
|
164
|
+
return skill_input(name=name, path=path)
|
|
165
|
+
|
|
111
166
|
async def list(
|
|
112
167
|
self,
|
|
113
168
|
*,
|
|
@@ -133,6 +188,9 @@ class AsyncSkillsClient(_AsyncServiceClient):
|
|
|
133
188
|
)
|
|
134
189
|
return await self._rpc.request_typed("skills/list", params, SkillsListResult)
|
|
135
190
|
|
|
191
|
+
async def reload(self, *, cwds: Sequence[str] | None = None) -> Sequence[SkillsListEntry]:
|
|
192
|
+
return await self.list(cwds=cwds, force_reload=True)
|
|
193
|
+
|
|
136
194
|
async def write_config(self, *, path: str, enabled: bool) -> SkillsConfigWriteResult:
|
|
137
195
|
params = protocol.SkillsConfigWriteParams(
|
|
138
196
|
path=protocol.AbsolutePathBuf(path),
|
|
@@ -140,6 +198,20 @@ class AsyncSkillsClient(_AsyncServiceClient):
|
|
|
140
198
|
)
|
|
141
199
|
return await self._rpc.request_typed("skills/config/write", params, SkillsConfigWriteResult)
|
|
142
200
|
|
|
201
|
+
async def write_skill(
|
|
202
|
+
self,
|
|
203
|
+
*,
|
|
204
|
+
name: str,
|
|
205
|
+
directory: str,
|
|
206
|
+
instructions: str | bytes,
|
|
207
|
+
reload_cwds: Sequence[str] | None = None,
|
|
208
|
+
) -> protocol.SkillUserInput:
|
|
209
|
+
skill_path = _skill_markdown_path(directory)
|
|
210
|
+
await self._fs.create_directory(path=directory, recursive=True)
|
|
211
|
+
await self._fs.write_file(path=skill_path, data=instructions)
|
|
212
|
+
await self.reload(cwds=reload_cwds)
|
|
213
|
+
return self.input(name=name, path=skill_path)
|
|
214
|
+
|
|
143
215
|
|
|
144
216
|
class AsyncAccountClient(_AsyncServiceClient):
|
|
145
217
|
async def read(self, *, refresh_token: bool | None = None) -> AccountReadResult:
|
|
@@ -324,6 +396,7 @@ class AsyncCommandClient(_AsyncServiceClient):
|
|
|
324
396
|
disable_timeout: bool | None = None,
|
|
325
397
|
env: Mapping[str, object | None] | None = None,
|
|
326
398
|
output_bytes_cap: int | None = None,
|
|
399
|
+
permission_profile: str | None = None,
|
|
327
400
|
process_id: str | None = None,
|
|
328
401
|
sandbox_policy: protocol.SandboxPolicy | None = None,
|
|
329
402
|
size: protocol.CommandExecTerminalSize | None = None,
|
|
@@ -339,6 +412,7 @@ class AsyncCommandClient(_AsyncServiceClient):
|
|
|
339
412
|
disableTimeout=disable_timeout,
|
|
340
413
|
env=dict(env) if env is not None else None,
|
|
341
414
|
outputBytesCap=output_bytes_cap,
|
|
415
|
+
permissionProfile=permission_profile,
|
|
342
416
|
processId=process_id,
|
|
343
417
|
sandboxPolicy=sandbox_policy,
|
|
344
418
|
size=size,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
|
-
from collections.abc import Callable, Collection, Mapping
|
|
6
|
+
from collections.abc import Callable, Collection, Mapping, Sequence
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from typing import Protocol, TypeVar, cast
|
|
9
9
|
|
|
@@ -41,6 +41,7 @@ _TURN_STREAM_NOTIFICATION_METHODS = {
|
|
|
41
41
|
"turn/started",
|
|
42
42
|
"turn/completed",
|
|
43
43
|
"turn/diff/updated",
|
|
44
|
+
"turn/moderationMetadata",
|
|
44
45
|
"turn/plan/updated",
|
|
45
46
|
"hook/started",
|
|
46
47
|
"hook/completed",
|
|
@@ -257,12 +258,13 @@ class AsyncTurnStream:
|
|
|
257
258
|
input: TurnInput,
|
|
258
259
|
*,
|
|
259
260
|
responsesapi_client_metadata: Mapping[str, object] | None = None,
|
|
261
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
260
262
|
) -> TurnIdResult:
|
|
261
263
|
"""Append additional user input to the in-flight turn."""
|
|
262
264
|
payload: dict[str, object] = {
|
|
263
265
|
"threadId": self.thread_id,
|
|
264
266
|
"expectedTurnId": self.turn_id,
|
|
265
|
-
"input": normalize_turn_input(input),
|
|
267
|
+
"input": normalize_turn_input(input, skills=skills),
|
|
266
268
|
}
|
|
267
269
|
if responsesapi_client_metadata is not None:
|
|
268
270
|
payload["responsesapiClientMetadata"] = dict(responsesapi_client_metadata)
|
|
@@ -416,11 +418,13 @@ class AsyncAppServerThread:
|
|
|
416
418
|
self,
|
|
417
419
|
input: TurnInput,
|
|
418
420
|
options: AppServerTurnOptions | None = None,
|
|
421
|
+
*,
|
|
422
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
419
423
|
) -> AsyncTurnStream:
|
|
420
424
|
"""Start a turn and return the protocol-native notification stream."""
|
|
421
425
|
payload = (options or AppServerTurnOptions()).to_params(
|
|
422
426
|
thread_id=self.id,
|
|
423
|
-
input=normalize_turn_input(input),
|
|
427
|
+
input=normalize_turn_input(input, skills=skills),
|
|
424
428
|
)
|
|
425
429
|
return await AsyncTurnStream.start(self, payload)
|
|
426
430
|
|
|
@@ -428,8 +432,10 @@ class AsyncAppServerThread:
|
|
|
428
432
|
self,
|
|
429
433
|
input: TurnInput,
|
|
430
434
|
options: AppServerTurnOptions | None = None,
|
|
435
|
+
*,
|
|
436
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
431
437
|
) -> str:
|
|
432
|
-
stream = await self.run(input, options)
|
|
438
|
+
stream = await self.run(input, options, skills=skills)
|
|
433
439
|
await stream.wait()
|
|
434
440
|
stream.raise_for_terminal_status()
|
|
435
441
|
return stream.final_text
|
|
@@ -438,8 +444,10 @@ class AsyncAppServerThread:
|
|
|
438
444
|
self,
|
|
439
445
|
input: TurnInput,
|
|
440
446
|
options: AppServerTurnOptions | None = None,
|
|
447
|
+
*,
|
|
448
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
441
449
|
) -> object:
|
|
442
|
-
stream = await self.run(input, options)
|
|
450
|
+
stream = await self.run(input, options, skills=skills)
|
|
443
451
|
await stream.wait()
|
|
444
452
|
stream.raise_for_terminal_status()
|
|
445
453
|
return stream.final_json()
|
|
@@ -449,6 +457,8 @@ class AsyncAppServerThread:
|
|
|
449
457
|
input: TurnInput,
|
|
450
458
|
model_type: type[_ModelT],
|
|
451
459
|
options: AppServerTurnOptions | None = None,
|
|
460
|
+
*,
|
|
461
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
452
462
|
) -> _ModelT:
|
|
453
463
|
"""Run a turn and validate the final assistant text with `model_type`."""
|
|
454
464
|
stream = await self.run(
|
|
@@ -458,6 +468,7 @@ class AsyncAppServerThread:
|
|
|
458
468
|
model_type,
|
|
459
469
|
owner="AppServerThread.run_model()",
|
|
460
470
|
),
|
|
471
|
+
skills=skills,
|
|
461
472
|
)
|
|
462
473
|
await stream.wait()
|
|
463
474
|
stream.raise_for_terminal_status()
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping, Sequence
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from codex.app_server._types import JsonObject
|
|
9
|
+
from codex.protocol import types as protocol
|
|
10
|
+
|
|
11
|
+
InputItem = (
|
|
12
|
+
str
|
|
13
|
+
| Mapping[str, Any]
|
|
14
|
+
| protocol.UserInput
|
|
15
|
+
| protocol.TextUserInput
|
|
16
|
+
| protocol.ImageUserInput
|
|
17
|
+
| protocol.LocalImageUserInput
|
|
18
|
+
| protocol.SkillUserInput
|
|
19
|
+
| protocol.MentionUserInput
|
|
20
|
+
)
|
|
21
|
+
TurnInput = InputItem | Sequence[InputItem]
|
|
22
|
+
|
|
23
|
+
type ParamsModel = BaseModel
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def serialize_value(value: object) -> object:
|
|
27
|
+
if isinstance(value, BaseModel):
|
|
28
|
+
return value.model_dump(
|
|
29
|
+
mode="json",
|
|
30
|
+
by_alias=True,
|
|
31
|
+
exclude_none=True,
|
|
32
|
+
exclude_unset=True,
|
|
33
|
+
)
|
|
34
|
+
if isinstance(value, type) and issubclass(value, BaseModel):
|
|
35
|
+
return value.model_json_schema()
|
|
36
|
+
if isinstance(value, list):
|
|
37
|
+
return [serialize_value(item) for item in value]
|
|
38
|
+
if isinstance(value, tuple):
|
|
39
|
+
return [serialize_value(item) for item in value]
|
|
40
|
+
if isinstance(value, Mapping):
|
|
41
|
+
return {key: serialize_value(item) for key, item in value.items()}
|
|
42
|
+
return value
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def normalize_input_item(item: InputItem) -> JsonObject:
|
|
46
|
+
if isinstance(item, str):
|
|
47
|
+
return {"type": "text", "text": item}
|
|
48
|
+
serialized = serialize_value(item)
|
|
49
|
+
if not isinstance(serialized, dict):
|
|
50
|
+
raise TypeError(f"Input item must serialize to an object, got {type(serialized).__name__}")
|
|
51
|
+
return cast(JsonObject, serialized)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def skill_input(*, name: str, path: str) -> protocol.SkillUserInput:
|
|
55
|
+
if name == "":
|
|
56
|
+
raise ValueError("Skill name cannot be empty.")
|
|
57
|
+
if name.startswith("$"):
|
|
58
|
+
raise ValueError("Skill name should not include the '$' activation marker.")
|
|
59
|
+
if any(character.isspace() for character in name):
|
|
60
|
+
raise ValueError("Skill name cannot contain whitespace.")
|
|
61
|
+
if "/" in name or "\\" in name:
|
|
62
|
+
raise ValueError("Skill name cannot contain path separators.")
|
|
63
|
+
if path == "":
|
|
64
|
+
raise ValueError("Skill path cannot be empty.")
|
|
65
|
+
return protocol.SkillUserInput(
|
|
66
|
+
type=protocol.SkillUserInputType("skill"),
|
|
67
|
+
name=name,
|
|
68
|
+
path=path,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _add_skill_markers(
|
|
73
|
+
items: list[JsonObject],
|
|
74
|
+
skills: Sequence[protocol.SkillUserInput],
|
|
75
|
+
) -> list[JsonObject]:
|
|
76
|
+
if not skills:
|
|
77
|
+
return items
|
|
78
|
+
markers = " ".join(f"${skill.name}" for skill in skills)
|
|
79
|
+
for item in items:
|
|
80
|
+
if item.get("type") != "text":
|
|
81
|
+
continue
|
|
82
|
+
text = item.get("text")
|
|
83
|
+
if isinstance(text, str):
|
|
84
|
+
item["text"] = f"{markers}\n\n{text}"
|
|
85
|
+
return items
|
|
86
|
+
return [{"type": "text", "text": markers}, *items]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def normalize_turn_input(
|
|
90
|
+
value: TurnInput,
|
|
91
|
+
*,
|
|
92
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
93
|
+
) -> list[JsonObject]:
|
|
94
|
+
if isinstance(value, str):
|
|
95
|
+
items = [{"type": "text", "text": value}]
|
|
96
|
+
elif isinstance(value, Sequence):
|
|
97
|
+
items = [normalize_input_item(item) for item in value]
|
|
98
|
+
else:
|
|
99
|
+
items = [normalize_input_item(value)]
|
|
100
|
+
if skills is None:
|
|
101
|
+
return items
|
|
102
|
+
return _add_skill_markers(items, skills) + [normalize_input_item(skill) for skill in skills]
|
|
@@ -21,6 +21,7 @@ from codex.app_server._sync_services import (
|
|
|
21
21
|
_ConfigClient,
|
|
22
22
|
_ExternalAgentConfigClient,
|
|
23
23
|
_FeedbackClient,
|
|
24
|
+
_FsClient,
|
|
24
25
|
_McpServersClient,
|
|
25
26
|
_ModelsClient,
|
|
26
27
|
_SkillsClient,
|
|
@@ -240,6 +241,7 @@ class AppServerClient(_SyncRunner):
|
|
|
240
241
|
self.mcp_servers = _McpServersClient(async_client.mcp_servers, self._run)
|
|
241
242
|
self.feedback = _FeedbackClient(async_client.feedback, self._run)
|
|
242
243
|
self.command = _CommandClient(async_client.command, self._run)
|
|
244
|
+
self.fs = _FsClient(async_client.fs, self._run)
|
|
243
245
|
self.external_agent_config = _ExternalAgentConfigClient(
|
|
244
246
|
async_client.external_agent_config,
|
|
245
247
|
self._run,
|
|
@@ -71,6 +71,8 @@ class _AsyncAppsClientLike(Protocol):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class _AsyncSkillsClientLike(Protocol):
|
|
74
|
+
def input(self, *, name: str, path: str) -> protocol.SkillUserInput: ...
|
|
75
|
+
|
|
74
76
|
async def list(
|
|
75
77
|
self,
|
|
76
78
|
*,
|
|
@@ -85,8 +87,36 @@ class _AsyncSkillsClientLike(Protocol):
|
|
|
85
87
|
force_reload: bool | None = None,
|
|
86
88
|
) -> SkillsListResult: ...
|
|
87
89
|
|
|
90
|
+
async def reload(self, *, cwds: Sequence[str] | None = None) -> Sequence[SkillsListEntry]: ...
|
|
91
|
+
|
|
88
92
|
async def write_config(self, *, path: str, enabled: bool) -> SkillsConfigWriteResult: ...
|
|
89
93
|
|
|
94
|
+
async def write_skill(
|
|
95
|
+
self,
|
|
96
|
+
*,
|
|
97
|
+
name: str,
|
|
98
|
+
directory: str,
|
|
99
|
+
instructions: str | bytes,
|
|
100
|
+
reload_cwds: Sequence[str] | None = None,
|
|
101
|
+
) -> protocol.SkillUserInput: ...
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class _AsyncFsClientLike(Protocol):
|
|
105
|
+
async def create_directory(
|
|
106
|
+
self,
|
|
107
|
+
*,
|
|
108
|
+
path: str,
|
|
109
|
+
recursive: bool | None = True,
|
|
110
|
+
) -> protocol.FsCreateDirectoryResponse: ...
|
|
111
|
+
|
|
112
|
+
async def write_file(
|
|
113
|
+
self,
|
|
114
|
+
*,
|
|
115
|
+
path: str,
|
|
116
|
+
data: str | bytes,
|
|
117
|
+
encoding: str = "utf-8",
|
|
118
|
+
) -> protocol.FsWriteFileResponse: ...
|
|
119
|
+
|
|
90
120
|
|
|
91
121
|
class _AsyncAccountClientLike(Protocol):
|
|
92
122
|
async def read(self, *, refresh_token: bool | None = None) -> AccountReadResult: ...
|
|
@@ -187,6 +217,7 @@ class _AsyncCommandClientLike(Protocol):
|
|
|
187
217
|
disable_timeout: bool | None = None,
|
|
188
218
|
env: Mapping[str, object | None] | None = None,
|
|
189
219
|
output_bytes_cap: int | None = None,
|
|
220
|
+
permission_profile: str | None = None,
|
|
190
221
|
process_id: str | None = None,
|
|
191
222
|
sandbox_policy: protocol.SandboxPolicy | None = None,
|
|
192
223
|
size: protocol.CommandExecTerminalSize | None = None,
|
|
@@ -331,6 +362,9 @@ class _SkillsClient(_SyncRunner):
|
|
|
331
362
|
super().__init__(runner)
|
|
332
363
|
self._async_client = async_client
|
|
333
364
|
|
|
365
|
+
def input(self, *, name: str, path: str) -> protocol.SkillUserInput:
|
|
366
|
+
return self._async_client.input(name=name, path=path)
|
|
367
|
+
|
|
334
368
|
def list(
|
|
335
369
|
self,
|
|
336
370
|
*,
|
|
@@ -357,9 +391,56 @@ class _SkillsClient(_SyncRunner):
|
|
|
357
391
|
)
|
|
358
392
|
)
|
|
359
393
|
|
|
394
|
+
def reload(self, *, cwds: Sequence[str] | None = None) -> Sequence[SkillsListEntry]:
|
|
395
|
+
return self._run(self._async_client.reload(cwds=cwds))
|
|
396
|
+
|
|
360
397
|
def write_config(self, *, path: str, enabled: bool) -> SkillsConfigWriteResult:
|
|
361
398
|
return self._run(self._async_client.write_config(path=path, enabled=enabled))
|
|
362
399
|
|
|
400
|
+
def write_skill(
|
|
401
|
+
self,
|
|
402
|
+
*,
|
|
403
|
+
name: str,
|
|
404
|
+
directory: str,
|
|
405
|
+
instructions: str | bytes,
|
|
406
|
+
reload_cwds: Sequence[str] | None = None,
|
|
407
|
+
) -> protocol.SkillUserInput:
|
|
408
|
+
return self._run(
|
|
409
|
+
self._async_client.write_skill(
|
|
410
|
+
name=name,
|
|
411
|
+
directory=directory,
|
|
412
|
+
instructions=instructions,
|
|
413
|
+
reload_cwds=reload_cwds,
|
|
414
|
+
)
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
class _FsClient(_SyncRunner):
|
|
419
|
+
def __init__(
|
|
420
|
+
self,
|
|
421
|
+
async_client: _AsyncFsClientLike,
|
|
422
|
+
runner: Callable[[Coroutine[Any, Any, Any]], Any],
|
|
423
|
+
) -> None:
|
|
424
|
+
super().__init__(runner)
|
|
425
|
+
self._async_client = async_client
|
|
426
|
+
|
|
427
|
+
def create_directory(
|
|
428
|
+
self,
|
|
429
|
+
*,
|
|
430
|
+
path: str,
|
|
431
|
+
recursive: bool | None = True,
|
|
432
|
+
) -> protocol.FsCreateDirectoryResponse:
|
|
433
|
+
return self._run(self._async_client.create_directory(path=path, recursive=recursive))
|
|
434
|
+
|
|
435
|
+
def write_file(
|
|
436
|
+
self,
|
|
437
|
+
*,
|
|
438
|
+
path: str,
|
|
439
|
+
data: str | bytes,
|
|
440
|
+
encoding: str = "utf-8",
|
|
441
|
+
) -> protocol.FsWriteFileResponse:
|
|
442
|
+
return self._run(self._async_client.write_file(path=path, data=data, encoding=encoding))
|
|
443
|
+
|
|
363
444
|
|
|
364
445
|
class _AccountClient(_SyncRunner):
|
|
365
446
|
def __init__(
|
|
@@ -554,6 +635,7 @@ class _CommandClient(_SyncRunner):
|
|
|
554
635
|
disable_timeout: bool | None = None,
|
|
555
636
|
env: Mapping[str, object | None] | None = None,
|
|
556
637
|
output_bytes_cap: int | None = None,
|
|
638
|
+
permission_profile: str | None = None,
|
|
557
639
|
process_id: str | None = None,
|
|
558
640
|
sandbox_policy: protocol.SandboxPolicy | None = None,
|
|
559
641
|
size: protocol.CommandExecTerminalSize | None = None,
|
|
@@ -570,6 +652,7 @@ class _CommandClient(_SyncRunner):
|
|
|
570
652
|
disable_timeout=disable_timeout,
|
|
571
653
|
env=env,
|
|
572
654
|
output_bytes_cap=output_bytes_cap,
|
|
655
|
+
permission_profile=permission_profile,
|
|
573
656
|
process_id=process_id,
|
|
574
657
|
sandbox_policy=sandbox_policy,
|
|
575
658
|
size=size,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import Callable, Collection, Coroutine, Mapping
|
|
5
|
+
from collections.abc import Callable, Collection, Coroutine, Mapping, Sequence
|
|
6
6
|
from typing import Any, Protocol, TypeVar
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel
|
|
@@ -54,6 +54,7 @@ class _AsyncTurnStreamLike(Protocol):
|
|
|
54
54
|
input: TurnInput,
|
|
55
55
|
*,
|
|
56
56
|
responsesapi_client_metadata: Mapping[str, object] | None = None,
|
|
57
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
57
58
|
) -> TurnIdResult: ...
|
|
58
59
|
|
|
59
60
|
async def interrupt(self) -> EmptyResult: ...
|
|
@@ -74,18 +75,24 @@ class _AsyncThreadLike(Protocol):
|
|
|
74
75
|
self,
|
|
75
76
|
input: TurnInput,
|
|
76
77
|
options: AppServerTurnOptions | None = None,
|
|
78
|
+
*,
|
|
79
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
77
80
|
) -> _AsyncTurnStreamLike: ...
|
|
78
81
|
|
|
79
82
|
async def run_text(
|
|
80
83
|
self,
|
|
81
84
|
input: TurnInput,
|
|
82
85
|
options: AppServerTurnOptions | None = None,
|
|
86
|
+
*,
|
|
87
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
83
88
|
) -> str: ...
|
|
84
89
|
|
|
85
90
|
async def run_json(
|
|
86
91
|
self,
|
|
87
92
|
input: TurnInput,
|
|
88
93
|
options: AppServerTurnOptions | None = None,
|
|
94
|
+
*,
|
|
95
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
89
96
|
) -> object: ...
|
|
90
97
|
|
|
91
98
|
async def run_model(
|
|
@@ -93,6 +100,8 @@ class _AsyncThreadLike(Protocol):
|
|
|
93
100
|
input: TurnInput,
|
|
94
101
|
model_type: type[_ModelT],
|
|
95
102
|
options: AppServerTurnOptions | None = None,
|
|
103
|
+
*,
|
|
104
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
96
105
|
) -> _ModelT: ...
|
|
97
106
|
|
|
98
107
|
async def review(
|
|
@@ -245,11 +254,13 @@ class TurnStream(_SyncRunner):
|
|
|
245
254
|
input: TurnInput,
|
|
246
255
|
*,
|
|
247
256
|
responsesapi_client_metadata: Mapping[str, object] | None = None,
|
|
257
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
248
258
|
) -> TurnIdResult:
|
|
249
259
|
return self._run(
|
|
250
260
|
self._async_stream.steer(
|
|
251
261
|
input,
|
|
252
262
|
responsesapi_client_metadata=responsesapi_client_metadata,
|
|
263
|
+
skills=skills,
|
|
253
264
|
)
|
|
254
265
|
)
|
|
255
266
|
|
|
@@ -286,9 +297,11 @@ class AppServerThread(_SyncRunner):
|
|
|
286
297
|
self,
|
|
287
298
|
input: TurnInput,
|
|
288
299
|
options: AppServerTurnOptions | None = None,
|
|
300
|
+
*,
|
|
301
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
289
302
|
) -> TurnStream:
|
|
290
303
|
return TurnStream(
|
|
291
|
-
self._run(self._async_thread.run(input, options)),
|
|
304
|
+
self._run(self._async_thread.run(input, options, skills=skills)),
|
|
292
305
|
self._run,
|
|
293
306
|
)
|
|
294
307
|
|
|
@@ -296,23 +309,29 @@ class AppServerThread(_SyncRunner):
|
|
|
296
309
|
self,
|
|
297
310
|
input: TurnInput,
|
|
298
311
|
options: AppServerTurnOptions | None = None,
|
|
312
|
+
*,
|
|
313
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
299
314
|
) -> str:
|
|
300
|
-
return self._run(self._async_thread.run_text(input, options))
|
|
315
|
+
return self._run(self._async_thread.run_text(input, options, skills=skills))
|
|
301
316
|
|
|
302
317
|
def run_json(
|
|
303
318
|
self,
|
|
304
319
|
input: TurnInput,
|
|
305
320
|
options: AppServerTurnOptions | None = None,
|
|
321
|
+
*,
|
|
322
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
306
323
|
) -> object:
|
|
307
|
-
return self._run(self._async_thread.run_json(input, options))
|
|
324
|
+
return self._run(self._async_thread.run_json(input, options, skills=skills))
|
|
308
325
|
|
|
309
326
|
def run_model(
|
|
310
327
|
self,
|
|
311
328
|
input: TurnInput,
|
|
312
329
|
model_type: type[_ModelT],
|
|
313
330
|
options: AppServerTurnOptions | None = None,
|
|
331
|
+
*,
|
|
332
|
+
skills: Sequence[protocol.SkillUserInput] | None = None,
|
|
314
333
|
) -> _ModelT:
|
|
315
|
-
return self._run(self._async_thread.run_model(input, model_type, options))
|
|
334
|
+
return self._run(self._async_thread.run_model(input, model_type, options, skills=skills))
|
|
316
335
|
|
|
317
336
|
def review(
|
|
318
337
|
self,
|