acontext 0.0.14__py3-none-any.whl → 0.0.16__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.
- acontext/agent/__init__.py +10 -0
- acontext/agent/skill.py +148 -0
- acontext/async_client.py +4 -0
- acontext/client.py +4 -0
- acontext/resources/__init__.py +8 -0
- acontext/resources/async_disks.py +11 -3
- acontext/resources/async_sessions.py +36 -16
- acontext/resources/async_skills.py +150 -0
- acontext/resources/async_spaces.py +12 -2
- acontext/resources/async_users.py +20 -0
- acontext/resources/disks.py +11 -3
- acontext/resources/sessions.py +17 -0
- acontext/resources/skills.py +146 -0
- acontext/resources/spaces.py +12 -2
- acontext/resources/users.py +20 -0
- acontext/types/__init__.py +14 -1
- acontext/types/common.py +11 -0
- acontext/types/disk.py +3 -7
- acontext/types/session.py +31 -15
- acontext/types/skill.py +69 -0
- acontext/types/space.py +1 -0
- {acontext-0.0.14.dist-info → acontext-0.0.16.dist-info}/METADATA +1 -1
- acontext-0.0.16.dist-info/RECORD +40 -0
- {acontext-0.0.14.dist-info → acontext-0.0.16.dist-info}/WHEEL +1 -1
- acontext-0.0.14.dist-info/RECORD +0 -33
acontext/agent/__init__.py
CHANGED
acontext/agent/skill.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Skill tools for agent operations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
from .base import BaseContext, BaseTool, BaseToolPool
|
|
8
|
+
from ..client import AcontextClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class SkillContext(BaseContext):
|
|
13
|
+
client: AcontextClient
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GetSkillTool(BaseTool):
|
|
17
|
+
"""Tool for getting a skill by name."""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def name(self) -> str:
|
|
21
|
+
return "get_skill"
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def description(self) -> str:
|
|
25
|
+
return (
|
|
26
|
+
"Get a skill by its name. Return the skill information including the relative paths of the files and their mime type categories"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def arguments(self) -> dict:
|
|
31
|
+
return {
|
|
32
|
+
"name": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "The name of the skill (unique within project).",
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def required_arguments(self) -> list[str]:
|
|
40
|
+
return ["name"]
|
|
41
|
+
|
|
42
|
+
def execute(self, ctx: SkillContext, llm_arguments: dict) -> str:
|
|
43
|
+
"""Get a skill by name."""
|
|
44
|
+
name = llm_arguments.get("name")
|
|
45
|
+
|
|
46
|
+
if not name:
|
|
47
|
+
raise ValueError("name is required")
|
|
48
|
+
|
|
49
|
+
skill = ctx.client.skills.get_by_name(name)
|
|
50
|
+
|
|
51
|
+
file_count = len(skill.file_index)
|
|
52
|
+
|
|
53
|
+
# Format all files with path and MIME type
|
|
54
|
+
if skill.file_index:
|
|
55
|
+
file_list = "\n".join(
|
|
56
|
+
[f" - {file_info.path} ({file_info.mime})" for file_info in skill.file_index]
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
file_list = " [NO FILES]"
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
f"Skill: {skill.name} (ID: {skill.id})\n"
|
|
63
|
+
f"Description: {skill.description}\n"
|
|
64
|
+
f"Files: {file_count} file(s)\n"
|
|
65
|
+
f"{file_list}\n"
|
|
66
|
+
f"Created: {skill.created_at}\n"
|
|
67
|
+
f"Updated: {skill.updated_at}"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class GetSkillFileTool(BaseTool):
|
|
72
|
+
"""Tool for getting a file from a skill."""
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def name(self) -> str:
|
|
76
|
+
return "get_skill_file"
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def description(self) -> str:
|
|
80
|
+
return (
|
|
81
|
+
"Get a file from a skill by name. The file_path should be a relative path within the skill (e.g., 'scripts/extract_text.json'). "
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def arguments(self) -> dict:
|
|
86
|
+
return {
|
|
87
|
+
"skill_name": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "The name of the skill.",
|
|
90
|
+
},
|
|
91
|
+
"file_path": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"description": "Relative path to the file within the skill (e.g., 'scripts/extract_text.json').",
|
|
94
|
+
},
|
|
95
|
+
"expire": {
|
|
96
|
+
"type": "integer",
|
|
97
|
+
"description": "URL expiration time in seconds (only used for non-parseable files). Defaults to 900 (15 minutes).",
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def required_arguments(self) -> list[str]:
|
|
103
|
+
return ["skill_name", "file_path"]
|
|
104
|
+
|
|
105
|
+
def execute(self, ctx: SkillContext, llm_arguments: dict) -> str:
|
|
106
|
+
"""Get a skill file."""
|
|
107
|
+
skill_name = llm_arguments.get("skill_name")
|
|
108
|
+
file_path = llm_arguments.get("file_path")
|
|
109
|
+
expire = llm_arguments.get("expire")
|
|
110
|
+
|
|
111
|
+
if not file_path:
|
|
112
|
+
raise ValueError("file_path is required")
|
|
113
|
+
if not skill_name:
|
|
114
|
+
raise ValueError("skill_name is required")
|
|
115
|
+
|
|
116
|
+
result = ctx.client.skills.get_file_by_name(
|
|
117
|
+
skill_name=skill_name,
|
|
118
|
+
file_path=file_path,
|
|
119
|
+
expire=expire,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
output_parts = [f"File '{result.path}' (MIME: {result.mime}) from skill '{skill_name}':"]
|
|
123
|
+
|
|
124
|
+
if result.content:
|
|
125
|
+
output_parts.append(f"\nContent (type: {result.content.type}):")
|
|
126
|
+
output_parts.append(result.content.raw)
|
|
127
|
+
|
|
128
|
+
if result.url:
|
|
129
|
+
expire_seconds = expire if expire is not None else 900
|
|
130
|
+
output_parts.append(f"\nDownload URL (expires in {expire_seconds} seconds):")
|
|
131
|
+
output_parts.append(result.url)
|
|
132
|
+
|
|
133
|
+
if not result.content and not result.url:
|
|
134
|
+
return f"File '{result.path}' retrieved but no content or URL returned."
|
|
135
|
+
|
|
136
|
+
return "\n".join(output_parts)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class SkillToolPool(BaseToolPool):
|
|
140
|
+
"""Tool pool for skill operations on Acontext skills."""
|
|
141
|
+
|
|
142
|
+
def format_context(self, client: AcontextClient) -> SkillContext:
|
|
143
|
+
return SkillContext(client=client)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
SKILL_TOOLS = SkillToolPool()
|
|
147
|
+
SKILL_TOOLS.add_tool(GetSkillTool())
|
|
148
|
+
SKILL_TOOLS.add_tool(GetSkillFileTool())
|
acontext/async_client.py
CHANGED
|
@@ -17,6 +17,8 @@ from .resources.async_blocks import AsyncBlocksAPI as AsyncBlocksAPI
|
|
|
17
17
|
from .resources.async_sessions import AsyncSessionsAPI as AsyncSessionsAPI
|
|
18
18
|
from .resources.async_spaces import AsyncSpacesAPI as AsyncSpacesAPI
|
|
19
19
|
from .resources.async_tools import AsyncToolsAPI as AsyncToolsAPI
|
|
20
|
+
from .resources.async_skills import AsyncSkillsAPI as AsyncSkillsAPI
|
|
21
|
+
from .resources.async_users import AsyncUsersAPI as AsyncUsersAPI
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class AcontextAsyncClient:
|
|
@@ -109,6 +111,8 @@ class AcontextAsyncClient:
|
|
|
109
111
|
self.artifacts = self.disks.artifacts
|
|
110
112
|
self.blocks = AsyncBlocksAPI(self)
|
|
111
113
|
self.tools = AsyncToolsAPI(self)
|
|
114
|
+
self.skills = AsyncSkillsAPI(self)
|
|
115
|
+
self.users = AsyncUsersAPI(self)
|
|
112
116
|
|
|
113
117
|
@property
|
|
114
118
|
def base_url(self) -> str:
|
acontext/client.py
CHANGED
|
@@ -17,6 +17,8 @@ from .resources.blocks import BlocksAPI as BlocksAPI
|
|
|
17
17
|
from .resources.sessions import SessionsAPI as SessionsAPI
|
|
18
18
|
from .resources.spaces import SpacesAPI as SpacesAPI
|
|
19
19
|
from .resources.tools import ToolsAPI as ToolsAPI
|
|
20
|
+
from .resources.skills import SkillsAPI as SkillsAPI
|
|
21
|
+
from .resources.users import UsersAPI as UsersAPI
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class AcontextClient:
|
|
@@ -109,6 +111,8 @@ class AcontextClient:
|
|
|
109
111
|
self.artifacts = self.disks.artifacts
|
|
110
112
|
self.blocks = BlocksAPI(self)
|
|
111
113
|
self.tools = ToolsAPI(self)
|
|
114
|
+
self.skills = SkillsAPI(self)
|
|
115
|
+
self.users = UsersAPI(self)
|
|
112
116
|
|
|
113
117
|
@property
|
|
114
118
|
def base_url(self) -> str:
|
acontext/resources/__init__.py
CHANGED
|
@@ -5,11 +5,15 @@ from .async_disks import AsyncDisksAPI, AsyncDiskArtifactsAPI
|
|
|
5
5
|
from .async_sessions import AsyncSessionsAPI
|
|
6
6
|
from .async_spaces import AsyncSpacesAPI
|
|
7
7
|
from .async_tools import AsyncToolsAPI
|
|
8
|
+
from .async_skills import AsyncSkillsAPI
|
|
9
|
+
from .async_users import AsyncUsersAPI
|
|
8
10
|
from .blocks import BlocksAPI
|
|
9
11
|
from .disks import DisksAPI, DiskArtifactsAPI
|
|
10
12
|
from .sessions import SessionsAPI
|
|
11
13
|
from .spaces import SpacesAPI
|
|
12
14
|
from .tools import ToolsAPI
|
|
15
|
+
from .skills import SkillsAPI
|
|
16
|
+
from .users import UsersAPI
|
|
13
17
|
|
|
14
18
|
__all__ = [
|
|
15
19
|
"DisksAPI",
|
|
@@ -18,10 +22,14 @@ __all__ = [
|
|
|
18
22
|
"SessionsAPI",
|
|
19
23
|
"SpacesAPI",
|
|
20
24
|
"ToolsAPI",
|
|
25
|
+
"SkillsAPI",
|
|
26
|
+
"UsersAPI",
|
|
21
27
|
"AsyncDisksAPI",
|
|
22
28
|
"AsyncDiskArtifactsAPI",
|
|
23
29
|
"AsyncBlocksAPI",
|
|
24
30
|
"AsyncSessionsAPI",
|
|
25
31
|
"AsyncSpacesAPI",
|
|
26
32
|
"AsyncToolsAPI",
|
|
33
|
+
"AsyncSkillsAPI",
|
|
34
|
+
"AsyncUsersAPI",
|
|
27
35
|
]
|
|
@@ -27,6 +27,7 @@ class AsyncDisksAPI:
|
|
|
27
27
|
async def list(
|
|
28
28
|
self,
|
|
29
29
|
*,
|
|
30
|
+
user: str | None = None,
|
|
30
31
|
limit: int | None = None,
|
|
31
32
|
cursor: str | None = None,
|
|
32
33
|
time_desc: bool | None = None,
|
|
@@ -34,6 +35,7 @@ class AsyncDisksAPI:
|
|
|
34
35
|
"""List all disks in the project.
|
|
35
36
|
|
|
36
37
|
Args:
|
|
38
|
+
user: Filter by user identifier. Defaults to None.
|
|
37
39
|
limit: Maximum number of disks to return. Defaults to None.
|
|
38
40
|
cursor: Cursor for pagination. Defaults to None.
|
|
39
41
|
time_desc: Order by created_at descending if True, ascending if False. Defaults to None.
|
|
@@ -41,17 +43,23 @@ class AsyncDisksAPI:
|
|
|
41
43
|
Returns:
|
|
42
44
|
ListDisksOutput containing the list of disks and pagination information.
|
|
43
45
|
"""
|
|
44
|
-
params = build_params(limit=limit, cursor=cursor, time_desc=time_desc)
|
|
46
|
+
params = build_params(user=user, limit=limit, cursor=cursor, time_desc=time_desc)
|
|
45
47
|
data = await self._requester.request("GET", "/disk", params=params or None)
|
|
46
48
|
return ListDisksOutput.model_validate(data)
|
|
47
49
|
|
|
48
|
-
async def create(self) -> Disk:
|
|
50
|
+
async def create(self, *, user: str | None = None) -> Disk:
|
|
49
51
|
"""Create a new disk.
|
|
50
52
|
|
|
53
|
+
Args:
|
|
54
|
+
user: Optional user identifier string. Defaults to None.
|
|
55
|
+
|
|
51
56
|
Returns:
|
|
52
57
|
The created Disk object.
|
|
53
58
|
"""
|
|
54
|
-
|
|
59
|
+
payload: dict[str, Any] = {}
|
|
60
|
+
if user is not None:
|
|
61
|
+
payload["user"] = user
|
|
62
|
+
data = await self._requester.request("POST", "/disk", json_data=payload or None)
|
|
55
63
|
return Disk.model_validate(data)
|
|
56
64
|
|
|
57
65
|
async def delete(self, disk_id: str) -> None:
|
|
@@ -37,6 +37,7 @@ class AsyncSessionsAPI:
|
|
|
37
37
|
async def list(
|
|
38
38
|
self,
|
|
39
39
|
*,
|
|
40
|
+
user: str | None = None,
|
|
40
41
|
space_id: str | None = None,
|
|
41
42
|
not_connected: bool | None = None,
|
|
42
43
|
limit: int | None = None,
|
|
@@ -46,6 +47,7 @@ class AsyncSessionsAPI:
|
|
|
46
47
|
"""List all sessions in the project.
|
|
47
48
|
|
|
48
49
|
Args:
|
|
50
|
+
user: Filter by user identifier. Defaults to None.
|
|
49
51
|
space_id: Filter sessions by space ID. Defaults to None.
|
|
50
52
|
not_connected: Filter sessions that are not connected to a space. Defaults to None.
|
|
51
53
|
limit: Maximum number of sessions to return. Defaults to None.
|
|
@@ -56,6 +58,8 @@ class AsyncSessionsAPI:
|
|
|
56
58
|
ListSessionsOutput containing the list of sessions and pagination information.
|
|
57
59
|
"""
|
|
58
60
|
params: dict[str, Any] = {}
|
|
61
|
+
if user:
|
|
62
|
+
params["user"] = user
|
|
59
63
|
if space_id:
|
|
60
64
|
params["space_id"] = space_id
|
|
61
65
|
params.update(
|
|
@@ -72,12 +76,14 @@ class AsyncSessionsAPI:
|
|
|
72
76
|
async def create(
|
|
73
77
|
self,
|
|
74
78
|
*,
|
|
79
|
+
user: str | None = None,
|
|
75
80
|
space_id: str | None = None,
|
|
76
81
|
configs: Mapping[str, Any] | None = None,
|
|
77
82
|
) -> Session:
|
|
78
83
|
"""Create a new session.
|
|
79
84
|
|
|
80
85
|
Args:
|
|
86
|
+
user: Optional user identifier string. Defaults to None.
|
|
81
87
|
space_id: Optional space ID to associate with the session. Defaults to None.
|
|
82
88
|
configs: Optional session configuration dictionary. Defaults to None.
|
|
83
89
|
|
|
@@ -85,6 +91,8 @@ class AsyncSessionsAPI:
|
|
|
85
91
|
The created Session object.
|
|
86
92
|
"""
|
|
87
93
|
payload: dict[str, Any] = {}
|
|
94
|
+
if user:
|
|
95
|
+
payload["user"] = user
|
|
88
96
|
if space_id:
|
|
89
97
|
payload["space_id"] = space_id
|
|
90
98
|
if configs is not None:
|
|
@@ -267,6 +275,7 @@ class AsyncSessionsAPI:
|
|
|
267
275
|
format: Literal["acontext", "openai", "anthropic", "gemini"] = "openai",
|
|
268
276
|
time_desc: bool | None = None,
|
|
269
277
|
edit_strategies: Optional[List[EditStrategy]] = None,
|
|
278
|
+
pin_editing_strategies_at_message: str | None = None,
|
|
270
279
|
) -> GetMessagesOutput:
|
|
271
280
|
"""Get messages for a session.
|
|
272
281
|
|
|
@@ -283,6 +292,12 @@ class AsyncSessionsAPI:
|
|
|
283
292
|
- Remove tool results: [{"type": "remove_tool_result", "params": {"keep_recent_n_tool_results": 3}}]
|
|
284
293
|
- Token limit: [{"type": "token_limit", "params": {"limit_tokens": 20000}}]
|
|
285
294
|
Defaults to None.
|
|
295
|
+
pin_editing_strategies_at_message: Message ID to pin editing strategies at.
|
|
296
|
+
When provided, strategies are only applied to messages up to and including
|
|
297
|
+
this message ID, keeping subsequent messages unchanged. This helps maintain
|
|
298
|
+
prompt cache stability by preserving a stable prefix. The response includes
|
|
299
|
+
edit_at_message_id indicating where strategies were applied. Pass this value
|
|
300
|
+
in subsequent requests to maintain cache hits. Defaults to None.
|
|
286
301
|
|
|
287
302
|
Returns:
|
|
288
303
|
GetMessagesOutput containing the list of messages and pagination information.
|
|
@@ -300,6 +315,10 @@ class AsyncSessionsAPI:
|
|
|
300
315
|
)
|
|
301
316
|
if edit_strategies is not None:
|
|
302
317
|
params["edit_strategies"] = json.dumps(edit_strategies)
|
|
318
|
+
if pin_editing_strategies_at_message is not None:
|
|
319
|
+
params["pin_editing_strategies_at_message"] = (
|
|
320
|
+
pin_editing_strategies_at_message
|
|
321
|
+
)
|
|
303
322
|
data = await self._requester.request(
|
|
304
323
|
"GET", f"/session/{session_id}/messages", params=params or None
|
|
305
324
|
)
|
|
@@ -348,20 +367,21 @@ class AsyncSessionsAPI:
|
|
|
348
367
|
)
|
|
349
368
|
return TokenCounts.model_validate(data)
|
|
350
369
|
|
|
370
|
+
|
|
351
371
|
async def messages_observing_status(self, session_id: str) -> MessageObservingStatus:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
372
|
+
"""Get message observing status counts for a session.
|
|
373
|
+
|
|
374
|
+
Returns the count of messages by their observing status:
|
|
375
|
+
observed, in_process, and pending.
|
|
376
|
+
|
|
377
|
+
Args:
|
|
378
|
+
session_id: The UUID of the session.
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
MessageObservingStatus object containing observed, in_process,
|
|
382
|
+
pending counts and updated_at timestamp.
|
|
383
|
+
"""
|
|
384
|
+
data = await self._requester.request(
|
|
385
|
+
"GET", f"/session/{session_id}/observing_status"
|
|
386
|
+
)
|
|
387
|
+
return MessageObservingStatus.model_validate(data)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Skills endpoints (async).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from typing import Any, BinaryIO, cast
|
|
8
|
+
|
|
9
|
+
from .._utils import build_params
|
|
10
|
+
from ..client_types import AsyncRequesterProtocol
|
|
11
|
+
from ..types.skill import (
|
|
12
|
+
GetSkillFileResp,
|
|
13
|
+
ListSkillsOutput,
|
|
14
|
+
Skill,
|
|
15
|
+
SkillCatalogItem,
|
|
16
|
+
_ListSkillsResponse,
|
|
17
|
+
)
|
|
18
|
+
from ..uploads import FileUpload, normalize_file_upload
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AsyncSkillsAPI:
|
|
22
|
+
def __init__(self, requester: AsyncRequesterProtocol) -> None:
|
|
23
|
+
self._requester = requester
|
|
24
|
+
|
|
25
|
+
async def create(
|
|
26
|
+
self,
|
|
27
|
+
*,
|
|
28
|
+
file: FileUpload
|
|
29
|
+
| tuple[str, BinaryIO | bytes]
|
|
30
|
+
| tuple[str, BinaryIO | bytes, str],
|
|
31
|
+
user: str | None = None,
|
|
32
|
+
meta: Mapping[str, Any] | None = None,
|
|
33
|
+
) -> Skill:
|
|
34
|
+
"""Create a new skill by uploading a ZIP file.
|
|
35
|
+
|
|
36
|
+
The ZIP file must contain a SKILL.md file (case-insensitive) with YAML format
|
|
37
|
+
containing 'name' and 'description' fields.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
file: The ZIP file to upload (FileUpload object or tuple format).
|
|
41
|
+
user: Optional user identifier string. Defaults to None.
|
|
42
|
+
meta: Custom metadata as JSON-serializable dict, defaults to None.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Skill containing the created skill information.
|
|
46
|
+
"""
|
|
47
|
+
upload = normalize_file_upload(file)
|
|
48
|
+
files = {"file": upload.as_httpx()}
|
|
49
|
+
form: dict[str, Any] = {}
|
|
50
|
+
if user is not None:
|
|
51
|
+
form["user"] = user
|
|
52
|
+
if meta is not None:
|
|
53
|
+
form["meta"] = json.dumps(cast(Mapping[str, Any], meta))
|
|
54
|
+
data = await self._requester.request(
|
|
55
|
+
"POST",
|
|
56
|
+
"/agent_skills",
|
|
57
|
+
data=form or None,
|
|
58
|
+
files=files,
|
|
59
|
+
)
|
|
60
|
+
return Skill.model_validate(data)
|
|
61
|
+
|
|
62
|
+
async def list_catalog(
|
|
63
|
+
self,
|
|
64
|
+
*,
|
|
65
|
+
user: str | None = None,
|
|
66
|
+
limit: int | None = None,
|
|
67
|
+
cursor: str | None = None,
|
|
68
|
+
time_desc: bool | None = None,
|
|
69
|
+
) -> ListSkillsOutput:
|
|
70
|
+
"""Get a catalog of skills (names and descriptions only) with pagination.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
user: Filter by user identifier. Defaults to None.
|
|
74
|
+
limit: Maximum number of skills per page (defaults to 100, max 200).
|
|
75
|
+
cursor: Cursor for pagination to fetch the next page (optional).
|
|
76
|
+
time_desc: Order by created_at descending if True, ascending if False (defaults to False).
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
ListSkillsOutput containing skills with name and description for the current page,
|
|
80
|
+
along with pagination information (next_cursor and has_more).
|
|
81
|
+
"""
|
|
82
|
+
effective_limit = limit if limit is not None else 100
|
|
83
|
+
params = build_params(user=user, limit=effective_limit, cursor=cursor, time_desc=time_desc)
|
|
84
|
+
data = await self._requester.request(
|
|
85
|
+
"GET", "/agent_skills", params=params or None
|
|
86
|
+
)
|
|
87
|
+
api_response = _ListSkillsResponse.model_validate(data)
|
|
88
|
+
|
|
89
|
+
# Convert to catalog format (name and description only)
|
|
90
|
+
return ListSkillsOutput(
|
|
91
|
+
items=[
|
|
92
|
+
SkillCatalogItem(name=skill.name, description=skill.description)
|
|
93
|
+
for skill in api_response.items
|
|
94
|
+
],
|
|
95
|
+
next_cursor=api_response.next_cursor,
|
|
96
|
+
has_more=api_response.has_more,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
async def get_by_name(self, name: str) -> Skill:
|
|
100
|
+
"""Get a skill by its name.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
name: The name of the skill (unique within project).
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Skill containing the skill information.
|
|
107
|
+
"""
|
|
108
|
+
params = {"name": name}
|
|
109
|
+
data = await self._requester.request(
|
|
110
|
+
"GET", "/agent_skills/by_name", params=params
|
|
111
|
+
)
|
|
112
|
+
return Skill.model_validate(data)
|
|
113
|
+
|
|
114
|
+
async def delete(self, skill_id: str) -> None:
|
|
115
|
+
"""Delete a skill by its ID.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
skill_id: The UUID of the skill to delete.
|
|
119
|
+
"""
|
|
120
|
+
await self._requester.request("DELETE", f"/agent_skills/{skill_id}")
|
|
121
|
+
|
|
122
|
+
async def get_file_by_name(
|
|
123
|
+
self,
|
|
124
|
+
*,
|
|
125
|
+
skill_name: str,
|
|
126
|
+
file_path: str,
|
|
127
|
+
expire: int | None = None,
|
|
128
|
+
) -> GetSkillFileResp:
|
|
129
|
+
"""Get a file from a skill by name.
|
|
130
|
+
|
|
131
|
+
The backend automatically returns content for parseable text files, or a presigned URL
|
|
132
|
+
for non-parseable files (binary, images, etc.).
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
skill_name: The name of the skill.
|
|
136
|
+
file_path: Relative path to the file within the skill (e.g., 'scripts/extract_text.json').
|
|
137
|
+
expire: URL expiration time in seconds. Defaults to 900 (15 minutes).
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
GetSkillFileResp containing the file path, MIME type, and either content or URL.
|
|
141
|
+
"""
|
|
142
|
+
endpoint = f"/agent_skills/by_name/{skill_name}/file"
|
|
143
|
+
|
|
144
|
+
params = {"file_path": file_path}
|
|
145
|
+
if expire is not None:
|
|
146
|
+
params["expire"] = expire
|
|
147
|
+
|
|
148
|
+
data = await self._requester.request("GET", endpoint, params=params)
|
|
149
|
+
return GetSkillFileResp.model_validate(data)
|
|
150
|
+
|
|
@@ -23,6 +23,7 @@ class AsyncSpacesAPI:
|
|
|
23
23
|
async def list(
|
|
24
24
|
self,
|
|
25
25
|
*,
|
|
26
|
+
user: str | None = None,
|
|
26
27
|
limit: int | None = None,
|
|
27
28
|
cursor: str | None = None,
|
|
28
29
|
time_desc: bool | None = None,
|
|
@@ -30,6 +31,7 @@ class AsyncSpacesAPI:
|
|
|
30
31
|
"""List all spaces in the project.
|
|
31
32
|
|
|
32
33
|
Args:
|
|
34
|
+
user: Filter by user identifier. Defaults to None.
|
|
33
35
|
limit: Maximum number of spaces to return. Defaults to None.
|
|
34
36
|
cursor: Cursor for pagination. Defaults to None.
|
|
35
37
|
time_desc: Order by created_at descending if True, ascending if False. Defaults to None.
|
|
@@ -37,20 +39,28 @@ class AsyncSpacesAPI:
|
|
|
37
39
|
Returns:
|
|
38
40
|
ListSpacesOutput containing the list of spaces and pagination information.
|
|
39
41
|
"""
|
|
40
|
-
params = build_params(limit=limit, cursor=cursor, time_desc=time_desc)
|
|
42
|
+
params = build_params(user=user, limit=limit, cursor=cursor, time_desc=time_desc)
|
|
41
43
|
data = await self._requester.request("GET", "/space", params=params or None)
|
|
42
44
|
return ListSpacesOutput.model_validate(data)
|
|
43
45
|
|
|
44
|
-
async def create(
|
|
46
|
+
async def create(
|
|
47
|
+
self,
|
|
48
|
+
*,
|
|
49
|
+
user: str | None = None,
|
|
50
|
+
configs: Mapping[str, Any] | None = None,
|
|
51
|
+
) -> Space:
|
|
45
52
|
"""Create a new space.
|
|
46
53
|
|
|
47
54
|
Args:
|
|
55
|
+
user: Optional user identifier string. Defaults to None.
|
|
48
56
|
configs: Optional space configuration dictionary. Defaults to None.
|
|
49
57
|
|
|
50
58
|
Returns:
|
|
51
59
|
The created Space object.
|
|
52
60
|
"""
|
|
53
61
|
payload: dict[str, Any] = {}
|
|
62
|
+
if user is not None:
|
|
63
|
+
payload["user"] = user
|
|
54
64
|
if configs is not None:
|
|
55
65
|
payload["configs"] = configs
|
|
56
66
|
data = await self._requester.request("POST", "/space", json_data=payload)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
User management endpoints (async).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from urllib.parse import quote
|
|
6
|
+
|
|
7
|
+
from ..client_types import AsyncRequesterProtocol
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AsyncUsersAPI:
|
|
11
|
+
def __init__(self, requester: AsyncRequesterProtocol) -> None:
|
|
12
|
+
self._requester = requester
|
|
13
|
+
|
|
14
|
+
async def delete(self, identifier: str) -> None:
|
|
15
|
+
"""Delete a user and cascade delete all associated resources (Space, Session, Disk, Skill).
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
identifier: The user identifier string.
|
|
19
|
+
"""
|
|
20
|
+
await self._requester.request("DELETE", f"/user/{quote(identifier, safe='')}")
|
acontext/resources/disks.py
CHANGED
|
@@ -27,6 +27,7 @@ class DisksAPI:
|
|
|
27
27
|
def list(
|
|
28
28
|
self,
|
|
29
29
|
*,
|
|
30
|
+
user: str | None = None,
|
|
30
31
|
limit: int | None = None,
|
|
31
32
|
cursor: str | None = None,
|
|
32
33
|
time_desc: bool | None = None,
|
|
@@ -34,6 +35,7 @@ class DisksAPI:
|
|
|
34
35
|
"""List all disks in the project.
|
|
35
36
|
|
|
36
37
|
Args:
|
|
38
|
+
user: Filter by user identifier. Defaults to None.
|
|
37
39
|
limit: Maximum number of disks to return. Defaults to None.
|
|
38
40
|
cursor: Cursor for pagination. Defaults to None.
|
|
39
41
|
time_desc: Order by created_at descending if True, ascending if False. Defaults to None.
|
|
@@ -41,17 +43,23 @@ class DisksAPI:
|
|
|
41
43
|
Returns:
|
|
42
44
|
ListDisksOutput containing the list of disks and pagination information.
|
|
43
45
|
"""
|
|
44
|
-
params = build_params(limit=limit, cursor=cursor, time_desc=time_desc)
|
|
46
|
+
params = build_params(user=user, limit=limit, cursor=cursor, time_desc=time_desc)
|
|
45
47
|
data = self._requester.request("GET", "/disk", params=params or None)
|
|
46
48
|
return ListDisksOutput.model_validate(data)
|
|
47
49
|
|
|
48
|
-
def create(self) -> Disk:
|
|
50
|
+
def create(self, *, user: str | None = None) -> Disk:
|
|
49
51
|
"""Create a new disk.
|
|
50
52
|
|
|
53
|
+
Args:
|
|
54
|
+
user: Optional user identifier string. Defaults to None.
|
|
55
|
+
|
|
51
56
|
Returns:
|
|
52
57
|
The created Disk object.
|
|
53
58
|
"""
|
|
54
|
-
|
|
59
|
+
payload: dict[str, Any] = {}
|
|
60
|
+
if user is not None:
|
|
61
|
+
payload["user"] = user
|
|
62
|
+
data = self._requester.request("POST", "/disk", json_data=payload or None)
|
|
55
63
|
return Disk.model_validate(data)
|
|
56
64
|
|
|
57
65
|
def delete(self, disk_id: str) -> None:
|
acontext/resources/sessions.py
CHANGED
|
@@ -37,6 +37,7 @@ class SessionsAPI:
|
|
|
37
37
|
def list(
|
|
38
38
|
self,
|
|
39
39
|
*,
|
|
40
|
+
user: str | None = None,
|
|
40
41
|
space_id: str | None = None,
|
|
41
42
|
not_connected: bool | None = None,
|
|
42
43
|
limit: int | None = None,
|
|
@@ -46,6 +47,7 @@ class SessionsAPI:
|
|
|
46
47
|
"""List all sessions in the project.
|
|
47
48
|
|
|
48
49
|
Args:
|
|
50
|
+
user: Filter by user identifier. Defaults to None.
|
|
49
51
|
space_id: Filter sessions by space ID. Defaults to None.
|
|
50
52
|
not_connected: Filter sessions that are not connected to a space. Defaults to None.
|
|
51
53
|
limit: Maximum number of sessions to return. Defaults to None.
|
|
@@ -56,6 +58,8 @@ class SessionsAPI:
|
|
|
56
58
|
ListSessionsOutput containing the list of sessions and pagination information.
|
|
57
59
|
"""
|
|
58
60
|
params: dict[str, Any] = {}
|
|
61
|
+
if user:
|
|
62
|
+
params["user"] = user
|
|
59
63
|
if space_id:
|
|
60
64
|
params["space_id"] = space_id
|
|
61
65
|
params.update(
|
|
@@ -72,6 +76,7 @@ class SessionsAPI:
|
|
|
72
76
|
def create(
|
|
73
77
|
self,
|
|
74
78
|
*,
|
|
79
|
+
user: str | None = None,
|
|
75
80
|
space_id: str | None = None,
|
|
76
81
|
disable_task_tracking: bool | None = None,
|
|
77
82
|
configs: Mapping[str, Any] | None = None,
|
|
@@ -79,6 +84,7 @@ class SessionsAPI:
|
|
|
79
84
|
"""Create a new session.
|
|
80
85
|
|
|
81
86
|
Args:
|
|
87
|
+
user: Optional user identifier string. Defaults to None.
|
|
82
88
|
space_id: Optional space ID to associate with the session. Defaults to None.
|
|
83
89
|
disable_task_tracking: Whether to disable task tracking for this session. Defaults to None (server default: False).
|
|
84
90
|
configs: Optional session configuration dictionary. Defaults to None.
|
|
@@ -87,6 +93,8 @@ class SessionsAPI:
|
|
|
87
93
|
The created Session object.
|
|
88
94
|
"""
|
|
89
95
|
payload: dict[str, Any] = {}
|
|
96
|
+
if user:
|
|
97
|
+
payload["user"] = user
|
|
90
98
|
if space_id:
|
|
91
99
|
payload["space_id"] = space_id
|
|
92
100
|
if disable_task_tracking is not None:
|
|
@@ -271,6 +279,7 @@ class SessionsAPI:
|
|
|
271
279
|
format: Literal["acontext", "openai", "anthropic", "gemini"] = "openai",
|
|
272
280
|
time_desc: bool | None = None,
|
|
273
281
|
edit_strategies: Optional[List[EditStrategy]] = None,
|
|
282
|
+
pin_editing_strategies_at_message: str | None = None,
|
|
274
283
|
) -> GetMessagesOutput:
|
|
275
284
|
"""Get messages for a session.
|
|
276
285
|
|
|
@@ -287,6 +296,12 @@ class SessionsAPI:
|
|
|
287
296
|
- Remove tool results: [{"type": "remove_tool_result", "params": {"keep_recent_n_tool_results": 3}}]
|
|
288
297
|
- Token limit: [{"type": "token_limit", "params": {"limit_tokens": 20000}}]
|
|
289
298
|
Defaults to None.
|
|
299
|
+
pin_editing_strategies_at_message: Message ID to pin editing strategies at.
|
|
300
|
+
When provided, strategies are only applied to messages up to and including
|
|
301
|
+
this message ID, keeping subsequent messages unchanged. This helps maintain
|
|
302
|
+
prompt cache stability by preserving a stable prefix. The response includes
|
|
303
|
+
edit_at_message_id indicating where strategies were applied. Pass this value
|
|
304
|
+
in subsequent requests to maintain cache hits. Defaults to None.
|
|
290
305
|
|
|
291
306
|
Returns:
|
|
292
307
|
GetMessagesOutput containing the list of messages and pagination information.
|
|
@@ -304,6 +319,8 @@ class SessionsAPI:
|
|
|
304
319
|
)
|
|
305
320
|
if edit_strategies is not None:
|
|
306
321
|
params["edit_strategies"] = json.dumps(edit_strategies)
|
|
322
|
+
if pin_editing_strategies_at_message is not None:
|
|
323
|
+
params["pin_editing_strategies_at_message"] = pin_editing_strategies_at_message
|
|
307
324
|
data = self._requester.request(
|
|
308
325
|
"GET", f"/session/{session_id}/messages", params=params or None
|
|
309
326
|
)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Skills endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from typing import Any, BinaryIO, cast
|
|
8
|
+
|
|
9
|
+
from .._utils import build_params
|
|
10
|
+
from ..client_types import RequesterProtocol
|
|
11
|
+
from ..types.skill import (
|
|
12
|
+
GetSkillFileResp,
|
|
13
|
+
ListSkillsOutput,
|
|
14
|
+
Skill,
|
|
15
|
+
SkillCatalogItem,
|
|
16
|
+
_ListSkillsResponse,
|
|
17
|
+
)
|
|
18
|
+
from ..uploads import FileUpload, normalize_file_upload
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SkillsAPI:
|
|
22
|
+
def __init__(self, requester: RequesterProtocol) -> None:
|
|
23
|
+
self._requester = requester
|
|
24
|
+
|
|
25
|
+
def create(
|
|
26
|
+
self,
|
|
27
|
+
*,
|
|
28
|
+
file: FileUpload
|
|
29
|
+
| tuple[str, BinaryIO | bytes]
|
|
30
|
+
| tuple[str, BinaryIO | bytes, str],
|
|
31
|
+
user: str | None = None,
|
|
32
|
+
meta: Mapping[str, Any] | None = None,
|
|
33
|
+
) -> Skill:
|
|
34
|
+
"""Create a new skill by uploading a ZIP file.
|
|
35
|
+
|
|
36
|
+
The ZIP file must contain a SKILL.md file (case-insensitive) with YAML format
|
|
37
|
+
containing 'name' and 'description' fields.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
file: The ZIP file to upload (FileUpload object or tuple format).
|
|
41
|
+
user: Optional user identifier string. Defaults to None.
|
|
42
|
+
meta: Custom metadata as JSON-serializable dict, defaults to None.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Skill containing the created skill information.
|
|
46
|
+
"""
|
|
47
|
+
upload = normalize_file_upload(file)
|
|
48
|
+
files = {"file": upload.as_httpx()}
|
|
49
|
+
form: dict[str, Any] = {}
|
|
50
|
+
if user is not None:
|
|
51
|
+
form["user"] = user
|
|
52
|
+
if meta is not None:
|
|
53
|
+
form["meta"] = json.dumps(cast(Mapping[str, Any], meta))
|
|
54
|
+
data = self._requester.request(
|
|
55
|
+
"POST",
|
|
56
|
+
"/agent_skills",
|
|
57
|
+
data=form or None,
|
|
58
|
+
files=files,
|
|
59
|
+
)
|
|
60
|
+
return Skill.model_validate(data)
|
|
61
|
+
|
|
62
|
+
def list_catalog(
|
|
63
|
+
self,
|
|
64
|
+
*,
|
|
65
|
+
user: str | None = None,
|
|
66
|
+
limit: int | None = None,
|
|
67
|
+
cursor: str | None = None,
|
|
68
|
+
time_desc: bool | None = None,
|
|
69
|
+
) -> ListSkillsOutput:
|
|
70
|
+
"""Get a catalog of skills (names and descriptions only) with pagination.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
user: Filter by user identifier. Defaults to None.
|
|
74
|
+
limit: Maximum number of skills per page (defaults to 100, max 200).
|
|
75
|
+
cursor: Cursor for pagination to fetch the next page (optional).
|
|
76
|
+
time_desc: Order by created_at descending if True, ascending if False (defaults to False).
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
ListSkillsOutput containing skills with name and description for the current page,
|
|
80
|
+
along with pagination information (next_cursor and has_more).
|
|
81
|
+
"""
|
|
82
|
+
effective_limit = limit if limit is not None else 100
|
|
83
|
+
params = build_params(user=user, limit=effective_limit, cursor=cursor, time_desc=time_desc)
|
|
84
|
+
data = self._requester.request("GET", "/agent_skills", params=params or None)
|
|
85
|
+
api_response = _ListSkillsResponse.model_validate(data)
|
|
86
|
+
|
|
87
|
+
# Convert to catalog format (name and description only)
|
|
88
|
+
return ListSkillsOutput(
|
|
89
|
+
items=[
|
|
90
|
+
SkillCatalogItem(name=skill.name, description=skill.description)
|
|
91
|
+
for skill in api_response.items
|
|
92
|
+
],
|
|
93
|
+
next_cursor=api_response.next_cursor,
|
|
94
|
+
has_more=api_response.has_more,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def get_by_name(self, name: str) -> Skill:
|
|
98
|
+
"""Get a skill by its name.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
name: The name of the skill (unique within project).
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Skill containing the skill information.
|
|
105
|
+
"""
|
|
106
|
+
params = {"name": name}
|
|
107
|
+
data = self._requester.request("GET", "/agent_skills/by_name", params=params)
|
|
108
|
+
return Skill.model_validate(data)
|
|
109
|
+
|
|
110
|
+
def delete(self, skill_id: str) -> None:
|
|
111
|
+
"""Delete a skill by its ID.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
skill_id: The UUID of the skill to delete.
|
|
115
|
+
"""
|
|
116
|
+
self._requester.request("DELETE", f"/agent_skills/{skill_id}")
|
|
117
|
+
|
|
118
|
+
def get_file_by_name(
|
|
119
|
+
self,
|
|
120
|
+
*,
|
|
121
|
+
skill_name: str,
|
|
122
|
+
file_path: str,
|
|
123
|
+
expire: int | None = None,
|
|
124
|
+
) -> GetSkillFileResp:
|
|
125
|
+
"""Get a file from a skill by name.
|
|
126
|
+
|
|
127
|
+
The backend automatically returns content for parseable text files, or a presigned URL
|
|
128
|
+
for non-parseable files (binary, images, etc.).
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
skill_name: The name of the skill.
|
|
132
|
+
file_path: Relative path to the file within the skill (e.g., 'scripts/extract_text.json').
|
|
133
|
+
expire: URL expiration time in seconds. Defaults to 900 (15 minutes).
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
GetSkillFileResp containing the file path, MIME type, and either content or URL.
|
|
137
|
+
"""
|
|
138
|
+
endpoint = f"/agent_skills/by_name/{skill_name}/file"
|
|
139
|
+
|
|
140
|
+
params = {"file_path": file_path}
|
|
141
|
+
if expire is not None:
|
|
142
|
+
params["expire"] = expire
|
|
143
|
+
|
|
144
|
+
data = self._requester.request("GET", endpoint, params=params)
|
|
145
|
+
return GetSkillFileResp.model_validate(data)
|
|
146
|
+
|
acontext/resources/spaces.py
CHANGED
|
@@ -23,6 +23,7 @@ class SpacesAPI:
|
|
|
23
23
|
def list(
|
|
24
24
|
self,
|
|
25
25
|
*,
|
|
26
|
+
user: str | None = None,
|
|
26
27
|
limit: int | None = None,
|
|
27
28
|
cursor: str | None = None,
|
|
28
29
|
time_desc: bool | None = None,
|
|
@@ -30,6 +31,7 @@ class SpacesAPI:
|
|
|
30
31
|
"""List all spaces in the project.
|
|
31
32
|
|
|
32
33
|
Args:
|
|
34
|
+
user: Filter by user identifier. Defaults to None.
|
|
33
35
|
limit: Maximum number of spaces to return. Defaults to None.
|
|
34
36
|
cursor: Cursor for pagination. Defaults to None.
|
|
35
37
|
time_desc: Order by created_at descending if True, ascending if False. Defaults to None.
|
|
@@ -37,20 +39,28 @@ class SpacesAPI:
|
|
|
37
39
|
Returns:
|
|
38
40
|
ListSpacesOutput containing the list of spaces and pagination information.
|
|
39
41
|
"""
|
|
40
|
-
params = build_params(limit=limit, cursor=cursor, time_desc=time_desc)
|
|
42
|
+
params = build_params(user=user, limit=limit, cursor=cursor, time_desc=time_desc)
|
|
41
43
|
data = self._requester.request("GET", "/space", params=params or None)
|
|
42
44
|
return ListSpacesOutput.model_validate(data)
|
|
43
45
|
|
|
44
|
-
def create(
|
|
46
|
+
def create(
|
|
47
|
+
self,
|
|
48
|
+
*,
|
|
49
|
+
user: str | None = None,
|
|
50
|
+
configs: Mapping[str, Any] | None = None,
|
|
51
|
+
) -> Space:
|
|
45
52
|
"""Create a new space.
|
|
46
53
|
|
|
47
54
|
Args:
|
|
55
|
+
user: Optional user identifier string. Defaults to None.
|
|
48
56
|
configs: Optional space configuration dictionary. Defaults to None.
|
|
49
57
|
|
|
50
58
|
Returns:
|
|
51
59
|
The created Space object.
|
|
52
60
|
"""
|
|
53
61
|
payload: dict[str, Any] = {}
|
|
62
|
+
if user is not None:
|
|
63
|
+
payload["user"] = user
|
|
54
64
|
if configs is not None:
|
|
55
65
|
payload["configs"] = configs
|
|
56
66
|
data = self._requester.request("POST", "/space", json_data=payload)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
User management endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from urllib.parse import quote
|
|
6
|
+
|
|
7
|
+
from ..client_types import RequesterProtocol
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class UsersAPI:
|
|
11
|
+
def __init__(self, requester: RequesterProtocol) -> None:
|
|
12
|
+
self._requester = requester
|
|
13
|
+
|
|
14
|
+
def delete(self, identifier: str) -> None:
|
|
15
|
+
"""Delete a user and cascade delete all associated resources (Space, Session, Disk, Skill).
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
identifier: The user identifier string.
|
|
19
|
+
"""
|
|
20
|
+
self._requester.request("DELETE", f"/user/{quote(identifier, safe='')}")
|
acontext/types/__init__.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Type definitions for API responses."""
|
|
2
2
|
|
|
3
|
+
from .common import FileContent
|
|
3
4
|
from .disk import (
|
|
4
5
|
Artifact,
|
|
5
6
|
Disk,
|
|
6
|
-
FileContent,
|
|
7
7
|
GetArtifactResp,
|
|
8
8
|
ListArtifactsResp,
|
|
9
9
|
ListDisksOutput,
|
|
@@ -38,6 +38,13 @@ from .tool import (
|
|
|
38
38
|
ToolReferenceData,
|
|
39
39
|
ToolRenameItem,
|
|
40
40
|
)
|
|
41
|
+
from .skill import (
|
|
42
|
+
FileInfo,
|
|
43
|
+
GetSkillFileResp,
|
|
44
|
+
ListSkillsOutput,
|
|
45
|
+
Skill,
|
|
46
|
+
SkillCatalogItem,
|
|
47
|
+
)
|
|
41
48
|
|
|
42
49
|
__all__ = [
|
|
43
50
|
# Disk types
|
|
@@ -75,4 +82,10 @@ __all__ = [
|
|
|
75
82
|
"InsertBlockResponse",
|
|
76
83
|
"ToolReferenceData",
|
|
77
84
|
"ToolRenameItem",
|
|
85
|
+
# Skill types
|
|
86
|
+
"FileInfo",
|
|
87
|
+
"Skill",
|
|
88
|
+
"SkillCatalogItem",
|
|
89
|
+
"ListSkillsOutput",
|
|
90
|
+
"GetSkillFileResp",
|
|
78
91
|
]
|
acontext/types/common.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Common type definitions shared across modules."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FileContent(BaseModel):
|
|
7
|
+
"""Parsed file content model."""
|
|
8
|
+
|
|
9
|
+
type: str = Field(..., description="File content type: 'text', 'json', 'csv', or 'code'")
|
|
10
|
+
raw: str = Field(..., description="Raw text content of the file")
|
|
11
|
+
|
acontext/types/disk.py
CHANGED
|
@@ -4,12 +4,15 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
|
+
from .common import FileContent
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
class Disk(BaseModel):
|
|
9
11
|
"""Disk model representing a disk resource."""
|
|
10
12
|
|
|
11
13
|
id: str = Field(..., description="Disk UUID")
|
|
12
14
|
project_id: str = Field(..., description="Project UUID")
|
|
15
|
+
user_id: str | None = Field(None, description="User UUID")
|
|
13
16
|
created_at: str = Field(..., description="ISO 8601 formatted creation timestamp")
|
|
14
17
|
updated_at: str = Field(..., description="ISO 8601 formatted update timestamp")
|
|
15
18
|
|
|
@@ -36,13 +39,6 @@ class Artifact(BaseModel):
|
|
|
36
39
|
updated_at: str = Field(..., description="ISO 8601 formatted update timestamp")
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
class FileContent(BaseModel):
|
|
40
|
-
"""Parsed file content model."""
|
|
41
|
-
|
|
42
|
-
type: str = Field(..., description="File content type: 'text', 'json', 'csv', or 'code'")
|
|
43
|
-
raw: str = Field(..., description="Raw text content of the file")
|
|
44
|
-
|
|
45
|
-
|
|
46
42
|
class GetArtifactResp(BaseModel):
|
|
47
43
|
"""Response model for getting an artifact."""
|
|
48
44
|
|
acontext/types/session.py
CHANGED
|
@@ -13,10 +13,13 @@ class RemoveToolResultParams(TypedDict, total=False):
|
|
|
13
13
|
Defaults to 3 if not specified.
|
|
14
14
|
tool_result_placeholder: Custom text to replace old tool results with.
|
|
15
15
|
Defaults to "Done" if not specified.
|
|
16
|
+
keep_tools: List of tool names that should never have their results removed.
|
|
17
|
+
Tool results from these tools are always kept regardless of keep_recent_n_tool_results.
|
|
16
18
|
"""
|
|
17
19
|
|
|
18
20
|
keep_recent_n_tool_results: NotRequired[int]
|
|
19
21
|
tool_result_placeholder: NotRequired[str]
|
|
22
|
+
keep_tools: NotRequired[list[str]]
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
class RemoveToolResultStrategy(TypedDict):
|
|
@@ -36,10 +39,12 @@ class RemoveToolCallParamsParams(TypedDict, total=False):
|
|
|
36
39
|
Attributes:
|
|
37
40
|
keep_recent_n_tool_calls: Number of most recent tool calls to keep with full parameters.
|
|
38
41
|
Defaults to 3 if not specified.
|
|
42
|
+
keep_tools: List of tool names that should never have their parameters removed.
|
|
43
|
+
Tool calls for these tools always keep their full parameters regardless of keep_recent_n_tool_calls.
|
|
39
44
|
"""
|
|
40
45
|
|
|
41
46
|
keep_recent_n_tool_calls: NotRequired[int]
|
|
42
|
-
|
|
47
|
+
keep_tools: NotRequired[list[str]]
|
|
43
48
|
|
|
44
49
|
|
|
45
50
|
class RemoveToolCallParamsStrategy(TypedDict):
|
|
@@ -57,7 +62,6 @@ class RemoveToolCallParamsStrategy(TypedDict):
|
|
|
57
62
|
params: RemoveToolCallParamsParams
|
|
58
63
|
|
|
59
64
|
|
|
60
|
-
|
|
61
65
|
class TokenLimitParams(TypedDict):
|
|
62
66
|
"""Parameters for the token_limit edit strategy.
|
|
63
67
|
|
|
@@ -87,7 +91,9 @@ class TokenLimitStrategy(TypedDict):
|
|
|
87
91
|
|
|
88
92
|
# Union type for all edit strategies
|
|
89
93
|
# When adding new strategies, add them to this Union: EditStrategy = Union[RemoveToolResultStrategy, OtherStrategy, ...]
|
|
90
|
-
EditStrategy = Union[
|
|
94
|
+
EditStrategy = Union[
|
|
95
|
+
RemoveToolResultStrategy, RemoveToolCallParamsStrategy, TokenLimitStrategy
|
|
96
|
+
]
|
|
91
97
|
|
|
92
98
|
|
|
93
99
|
class Asset(BaseModel):
|
|
@@ -137,6 +143,7 @@ class Session(BaseModel):
|
|
|
137
143
|
|
|
138
144
|
id: str = Field(..., description="Session UUID")
|
|
139
145
|
project_id: str = Field(..., description="Project UUID")
|
|
146
|
+
user_id: str | None = Field(None, description="User UUID")
|
|
140
147
|
disable_task_tracking: bool = Field(
|
|
141
148
|
False, description="Whether task tracking is disabled for this session"
|
|
142
149
|
)
|
|
@@ -216,15 +223,29 @@ class GetMessagesOutput(BaseModel):
|
|
|
216
223
|
description="List of messages in the requested format (Message, OpenAI format, or Anthropic format)",
|
|
217
224
|
)
|
|
218
225
|
ids: list[str] = Field(
|
|
219
|
-
|
|
220
|
-
|
|
226
|
+
...,
|
|
227
|
+
description="List of message UUIDs corresponding to each item in the same order",
|
|
221
228
|
)
|
|
222
229
|
next_cursor: str | None = Field(None, description="Cursor for pagination")
|
|
223
230
|
has_more: bool = Field(..., description="Whether there are more items")
|
|
231
|
+
this_time_tokens: int = Field(
|
|
232
|
+
...,
|
|
233
|
+
description="Total token count of the returned messages",
|
|
234
|
+
)
|
|
224
235
|
public_urls: dict[str, PublicURL] | None = Field(
|
|
225
236
|
None,
|
|
226
237
|
description="Map of SHA256 hash to PublicURL (only included when format='acontext')",
|
|
227
238
|
)
|
|
239
|
+
edit_at_message_id: str | None = Field(
|
|
240
|
+
None,
|
|
241
|
+
description=(
|
|
242
|
+
"The message ID where edit strategies were applied up to. "
|
|
243
|
+
"If pin_editing_strategies_at_message was provided, this equals that value. "
|
|
244
|
+
"Otherwise, this is the ID of the last message in the response. "
|
|
245
|
+
"Use this value to maintain prompt cache stability by passing it as "
|
|
246
|
+
"pin_editing_strategies_at_message in subsequent requests."
|
|
247
|
+
),
|
|
248
|
+
)
|
|
228
249
|
|
|
229
250
|
|
|
230
251
|
class GetTasksOutput(BaseModel):
|
|
@@ -254,18 +275,13 @@ class TokenCounts(BaseModel):
|
|
|
254
275
|
description="Total token count for all text and tool-call parts in a session",
|
|
255
276
|
)
|
|
256
277
|
|
|
278
|
+
|
|
257
279
|
class MessageObservingStatus(BaseModel):
|
|
258
280
|
"""Response model for message observing status."""
|
|
259
|
-
|
|
260
|
-
observed: int = Field(
|
|
261
|
-
..., description="Number of messages with observed status"
|
|
262
|
-
)
|
|
281
|
+
|
|
282
|
+
observed: int = Field(..., description="Number of messages with observed status")
|
|
263
283
|
in_process: int = Field(
|
|
264
284
|
..., description="Number of messages with in_process status"
|
|
265
285
|
)
|
|
266
|
-
pending: int = Field(
|
|
267
|
-
|
|
268
|
-
)
|
|
269
|
-
updated_at: str = Field(
|
|
270
|
-
..., description="Timestamp when the status was retrieved"
|
|
271
|
-
)
|
|
286
|
+
pending: int = Field(..., description="Number of messages with pending status")
|
|
287
|
+
updated_at: str = Field(..., description="Timestamp when the status was retrieved")
|
acontext/types/skill.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Type definitions for skill resources."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from .common import FileContent
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FileInfo(BaseModel):
|
|
11
|
+
"""File information in a skill."""
|
|
12
|
+
|
|
13
|
+
path: str = Field(..., description="Relative file path from skill root")
|
|
14
|
+
mime: str = Field(..., description="MIME type of the file")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Skill(BaseModel):
|
|
18
|
+
"""Skill model representing an agent skill resource."""
|
|
19
|
+
|
|
20
|
+
id: str = Field(..., description="Skill UUID")
|
|
21
|
+
user_id: str | None = Field(None, description="User UUID")
|
|
22
|
+
name: str = Field(..., description="Skill name (unique within project)")
|
|
23
|
+
description: str = Field(..., description="Skill description")
|
|
24
|
+
file_index: list[FileInfo] = Field(
|
|
25
|
+
..., description="List of file information (path and MIME type) in the skill"
|
|
26
|
+
)
|
|
27
|
+
meta: dict[str, Any] | None = Field(
|
|
28
|
+
None, description="Custom metadata dictionary"
|
|
29
|
+
)
|
|
30
|
+
created_at: str = Field(..., description="ISO 8601 formatted creation timestamp")
|
|
31
|
+
updated_at: str = Field(..., description="ISO 8601 formatted update timestamp")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SkillCatalogItem(BaseModel):
|
|
35
|
+
"""Catalog item containing only name and description."""
|
|
36
|
+
|
|
37
|
+
name: str = Field(..., description="Skill name (unique within project)")
|
|
38
|
+
description: str = Field(..., description="Skill description")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ListSkillsOutput(BaseModel):
|
|
42
|
+
"""Response model for listing skills (catalog format with name and description only)."""
|
|
43
|
+
|
|
44
|
+
items: list[SkillCatalogItem] = Field(
|
|
45
|
+
..., description="List of skills with name and description"
|
|
46
|
+
)
|
|
47
|
+
next_cursor: str | None = Field(None, description="Cursor for pagination")
|
|
48
|
+
has_more: bool = Field(..., description="Whether there are more items")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class _ListSkillsResponse(BaseModel):
|
|
52
|
+
"""Internal response model for API pagination (full Skill objects).
|
|
53
|
+
|
|
54
|
+
This is used internally to parse the raw API response before converting
|
|
55
|
+
to the catalog format (ListSkillsOutput).
|
|
56
|
+
"""
|
|
57
|
+
items: list[Skill]
|
|
58
|
+
next_cursor: str | None = None
|
|
59
|
+
has_more: bool = False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class GetSkillFileResp(BaseModel):
|
|
63
|
+
"""Response model for getting a skill file."""
|
|
64
|
+
|
|
65
|
+
path: str = Field(..., description="File path")
|
|
66
|
+
mime: str = Field(..., description="MIME type of the file")
|
|
67
|
+
url: str | None = Field(None, description="Presigned URL for downloading the file (present if file is not parseable)")
|
|
68
|
+
content: FileContent | None = Field(None, description="Parsed file content if available (present if file is parseable)")
|
|
69
|
+
|
acontext/types/space.py
CHANGED
|
@@ -10,6 +10,7 @@ class Space(BaseModel):
|
|
|
10
10
|
|
|
11
11
|
id: str = Field(..., description="Space UUID")
|
|
12
12
|
project_id: str = Field(..., description="Project UUID")
|
|
13
|
+
user_id: str | None = Field(None, description="User UUID")
|
|
13
14
|
configs: dict[str, Any] | None = Field(
|
|
14
15
|
None, description="Space configuration dictionary"
|
|
15
16
|
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
acontext/__init__.py,sha256=jAgRawWIjyMd6g3gq7Xm_3vNB31cPj8rMFPO4LGQKdM,1027
|
|
2
|
+
acontext/_constants.py,sha256=Ikuy_Wz3CPmXjKPLXb4Y580-fe54o1hZ2ZB1Bpw3sFE,363
|
|
3
|
+
acontext/_utils.py,sha256=GKQH45arKh0sDu64u-5jwrII_ctnU_oChYlgR5lRkfE,1250
|
|
4
|
+
acontext/agent/__init__.py,sha256=PAUhm1rBYOdKw3lCD-H9d72emkGL4KoxEvVq4GeS9ig,158
|
|
5
|
+
acontext/agent/base.py,sha256=kN2KzV6fOlvmMSi_0yu2QqwVLtHh09TznAy_SDtC8iM,2998
|
|
6
|
+
acontext/agent/disk.py,sha256=d9sOggIs4da7niB9TaE0ab82_7l0O5n08eOcQxcaYRs,12623
|
|
7
|
+
acontext/agent/skill.py,sha256=opsOTQyuedqQMlwDXWMVwCwg0u9cyehfyELDEbat3bE,4451
|
|
8
|
+
acontext/async_client.py,sha256=sqdSNjl3tx8ijoRNYoEwh1Lxdlhfk0zyd-h-xffIJJE,8372
|
|
9
|
+
acontext/client.py,sha256=3xha-zbHYLwI1njlhmoB_BYK5JIJoXFyrCpvIi63b9o,8097
|
|
10
|
+
acontext/client_types.py,sha256=uVBWzLbZyXrqkljG49ojdQL_xX6N3n_HGt4Bs_TEE48,987
|
|
11
|
+
acontext/errors.py,sha256=W9i7_t46q9kbci3XAyZiyQhS154d4R9rSon3na-gjgs,1296
|
|
12
|
+
acontext/messages.py,sha256=oNRZStfhcPFt6DPOfs_-Q7R1Xui6dOMr3wmpmC8pzvE,2310
|
|
13
|
+
acontext/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
acontext/resources/__init__.py,sha256=Oww11t9hmwdNFK2nC8YW9mf4BBSz5YLPAXAWLlZuNTs,935
|
|
15
|
+
acontext/resources/async_blocks.py,sha256=e_iJpgcAdwS2tXQ16MMCnySlddp5JV3BadN_EyqZSF4,5555
|
|
16
|
+
acontext/resources/async_disks.py,sha256=rwcRwQ79ZYbMMWAj5YDDpKQmfAIOl9M3CTYxOZTy_UU,6830
|
|
17
|
+
acontext/resources/async_sessions.py,sha256=Ld9T8l884r3UuUprRz7MwafSI8BaPfLA0pg0dPfNM1A,14363
|
|
18
|
+
acontext/resources/async_skills.py,sha256=mbEzyUH7S2_jkZ5tfl0FzpHJ7Io3x_biw5FirhokzAQ,5062
|
|
19
|
+
acontext/resources/async_spaces.py,sha256=b8DNG2L43B6iSgfmH8M-0cxAp681IjSCjw-4alfjV2A,6712
|
|
20
|
+
acontext/resources/async_tools.py,sha256=RbGaF2kX65Mun-q-Fp5H1J8waWTLIdCOfbdY19jpn1o,1091
|
|
21
|
+
acontext/resources/async_users.py,sha256=wqgWIgT4SOAJ0jFN2dXrZ49Fu9KKzP2uV6oVDwfB_Ak,572
|
|
22
|
+
acontext/resources/blocks.py,sha256=HJdAy5HdyTcHCYCPmqNdvApYKZ6aWs-ORIi_wQt3TUM,5447
|
|
23
|
+
acontext/resources/disks.py,sha256=3D-8veyWr3crDppyTvTs83FhRGWDmYRBNuKBPDh-sSk,6695
|
|
24
|
+
acontext/resources/sessions.py,sha256=qUoLs01tzmYChHy3kozzGQ3ZeAz_JyWGtCIsVL20BO4,14491
|
|
25
|
+
acontext/resources/skills.py,sha256=FPp1YWhH85I9BU0fJJC9FbePIbFhyX6j2FYxjPuBEAc,4935
|
|
26
|
+
acontext/resources/spaces.py,sha256=Ktvkkn3Jj7CZoKMbn6fYuo0zqImoCWj2EnMsnL2q-0A,6571
|
|
27
|
+
acontext/resources/tools.py,sha256=II_185B0HYKSP43hizE6C1zs7kjkkPLKihuEG8s-DRY,1046
|
|
28
|
+
acontext/resources/users.py,sha256=mcoXS-BPiF1Porkpm8ioo1acGPBGZSfHaFfcd1oRWL8,537
|
|
29
|
+
acontext/types/__init__.py,sha256=RFrkHI413x7AOk6X2ztu_WcuqNm09xvEzGmE352tDE4,1696
|
|
30
|
+
acontext/types/block.py,sha256=CzKByunk642rWXNNnh8cx67UzKLKDAxODmC_whwjP90,1078
|
|
31
|
+
acontext/types/common.py,sha256=5kLwzszlIofz8qZ9-Wj_zcBBiF22mAWgH9uWPkcgWCE,327
|
|
32
|
+
acontext/types/disk.py,sha256=nMjyXLUre4Xuu_YfBbzzdRQDRxB8qX1Zx9LsNqGCi9E,2223
|
|
33
|
+
acontext/types/session.py,sha256=WIaTiiAw8OujeSnk18Vy_Fn_AffW60pfs-unlPXYuT8,11076
|
|
34
|
+
acontext/types/skill.py,sha256=qBDNysW9ptKX6RcMiZd4PfwWwvcYCzj_dC-6RbXqyx4,2531
|
|
35
|
+
acontext/types/space.py,sha256=9BkGBYGeQDVwYTmPLoIjMY-IUdQzjrt8I7CXca2_5Vc,2600
|
|
36
|
+
acontext/types/tool.py,sha256=-mVn-vgk2SENK0Ubt-ZgWFZxKa-ddABqcAgXQ69YY-E,805
|
|
37
|
+
acontext/uploads.py,sha256=6twnqQOY_eerNuEjeSKsE_3S0IfJUiczXtAy4aXqDl8,1379
|
|
38
|
+
acontext-0.0.16.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
|
|
39
|
+
acontext-0.0.16.dist-info/METADATA,sha256=ZBbXvjNXaFKVUN02XUief26BXVQVMHt0-EkcHwV2eU8,859
|
|
40
|
+
acontext-0.0.16.dist-info/RECORD,,
|
acontext-0.0.14.dist-info/RECORD
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
acontext/__init__.py,sha256=jAgRawWIjyMd6g3gq7Xm_3vNB31cPj8rMFPO4LGQKdM,1027
|
|
2
|
-
acontext/_constants.py,sha256=Ikuy_Wz3CPmXjKPLXb4Y580-fe54o1hZ2ZB1Bpw3sFE,363
|
|
3
|
-
acontext/_utils.py,sha256=GKQH45arKh0sDu64u-5jwrII_ctnU_oChYlgR5lRkfE,1250
|
|
4
|
-
acontext/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
acontext/agent/base.py,sha256=kN2KzV6fOlvmMSi_0yu2QqwVLtHh09TznAy_SDtC8iM,2998
|
|
6
|
-
acontext/agent/disk.py,sha256=d9sOggIs4da7niB9TaE0ab82_7l0O5n08eOcQxcaYRs,12623
|
|
7
|
-
acontext/async_client.py,sha256=mfyR-WVy_LEOXjrkTcXLNaPDC5euaZ9zFI_5e1gapGs,8153
|
|
8
|
-
acontext/client.py,sha256=jFr5-Q8obdcZBamUNtY3fCklpOJiNiIKLzEApTmbnTg,7920
|
|
9
|
-
acontext/client_types.py,sha256=uVBWzLbZyXrqkljG49ojdQL_xX6N3n_HGt4Bs_TEE48,987
|
|
10
|
-
acontext/errors.py,sha256=W9i7_t46q9kbci3XAyZiyQhS154d4R9rSon3na-gjgs,1296
|
|
11
|
-
acontext/messages.py,sha256=oNRZStfhcPFt6DPOfs_-Q7R1Xui6dOMr3wmpmC8pzvE,2310
|
|
12
|
-
acontext/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
acontext/resources/__init__.py,sha256=KSVQ3YJ-wuU6OWGWJ47gDGbjjetP102aEsVSR8JUb_4,721
|
|
14
|
-
acontext/resources/async_blocks.py,sha256=e_iJpgcAdwS2tXQ16MMCnySlddp5JV3BadN_EyqZSF4,5555
|
|
15
|
-
acontext/resources/async_disks.py,sha256=2JjLpUkz5YZEkLt_jCts_khTG_b7lvf4cUMfoaJcnI8,6471
|
|
16
|
-
acontext/resources/async_sessions.py,sha256=660qEvz9aG_Nn3XiKKj9AbWizMstHhUsQN2m3W8ZGJ4,13357
|
|
17
|
-
acontext/resources/async_spaces.py,sha256=5lIZjI8GmgoMBcftAMD2vDj2FmbLZ6pi1-yNCWKv4cM,6408
|
|
18
|
-
acontext/resources/async_tools.py,sha256=RbGaF2kX65Mun-q-Fp5H1J8waWTLIdCOfbdY19jpn1o,1091
|
|
19
|
-
acontext/resources/blocks.py,sha256=HJdAy5HdyTcHCYCPmqNdvApYKZ6aWs-ORIi_wQt3TUM,5447
|
|
20
|
-
acontext/resources/disks.py,sha256=BjVhVXoujHWhg6L0TG9GmW9HLTTldJYEPxCbuppRkc4,6336
|
|
21
|
-
acontext/resources/sessions.py,sha256=9qfEMVmiJGmhAqKYQ89yYa14SDZ-dyol1-rPXU3wSI0,13441
|
|
22
|
-
acontext/resources/spaces.py,sha256=LJP9krygZGdktMDtYGudCpk7yBxe_4v34QLk3SdejwQ,6267
|
|
23
|
-
acontext/resources/tools.py,sha256=II_185B0HYKSP43hizE6C1zs7kjkkPLKihuEG8s-DRY,1046
|
|
24
|
-
acontext/types/__init__.py,sha256=QWNLmdSnLE2b5XRXxnI2OKnHVdKQPJH0nJvvOYwhB1o,1448
|
|
25
|
-
acontext/types/block.py,sha256=CzKByunk642rWXNNnh8cx67UzKLKDAxODmC_whwjP90,1078
|
|
26
|
-
acontext/types/disk.py,sha256=g9u3rgCh05rK-gay19NUi-WyzI5Vt1GQwcyKv-5TSC4,2361
|
|
27
|
-
acontext/types/session.py,sha256=H_n4vZJ02ZO5flqGZ8R5AYVSScxScf2r7UgsN5LRIa0,9965
|
|
28
|
-
acontext/types/space.py,sha256=uxbPrOHYpsntPHqhMCLQ2KovM7BngHC5Q2j7qexVrN8,2537
|
|
29
|
-
acontext/types/tool.py,sha256=-mVn-vgk2SENK0Ubt-ZgWFZxKa-ddABqcAgXQ69YY-E,805
|
|
30
|
-
acontext/uploads.py,sha256=6twnqQOY_eerNuEjeSKsE_3S0IfJUiczXtAy4aXqDl8,1379
|
|
31
|
-
acontext-0.0.14.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
|
|
32
|
-
acontext-0.0.14.dist-info/METADATA,sha256=sm1g1hhGbW15feWubCtcNkjgK5Ja1S_-xr1lIbXvmjU,859
|
|
33
|
-
acontext-0.0.14.dist-info/RECORD,,
|