acontext 0.0.9__py3-none-any.whl → 0.0.11__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/resources/async_sessions.py +21 -2
- acontext/resources/sessions.py +20 -2
- acontext/types/session.py +49 -1
- acontext-0.0.11.dist-info/METADATA +34 -0
- {acontext-0.0.9.dist-info → acontext-0.0.11.dist-info}/RECORD +6 -6
- {acontext-0.0.9.dist-info → acontext-0.0.11.dist-info}/WHEEL +1 -1
- acontext-0.0.9.dist-info/METADATA +0 -661
|
@@ -15,6 +15,7 @@ from ..types.session import (
|
|
|
15
15
|
LearningStatus,
|
|
16
16
|
ListSessionsOutput,
|
|
17
17
|
Message,
|
|
18
|
+
MessageObservingStatus,
|
|
18
19
|
Session,
|
|
19
20
|
TokenCounts,
|
|
20
21
|
)
|
|
@@ -167,7 +168,7 @@ class AsyncSessionsAPI:
|
|
|
167
168
|
)
|
|
168
169
|
return GetTasksOutput.model_validate(data)
|
|
169
170
|
|
|
170
|
-
async def
|
|
171
|
+
async def store_message(
|
|
171
172
|
self,
|
|
172
173
|
session_id: str,
|
|
173
174
|
*,
|
|
@@ -181,7 +182,7 @@ class AsyncSessionsAPI:
|
|
|
181
182
|
| None
|
|
182
183
|
) = None,
|
|
183
184
|
) -> Message:
|
|
184
|
-
"""
|
|
185
|
+
"""Store a message to a session.
|
|
185
186
|
|
|
186
187
|
Args:
|
|
187
188
|
session_id: The UUID of the session.
|
|
@@ -346,3 +347,21 @@ class AsyncSessionsAPI:
|
|
|
346
347
|
"GET", f"/session/{session_id}/token_counts"
|
|
347
348
|
)
|
|
348
349
|
return TokenCounts.model_validate(data)
|
|
350
|
+
|
|
351
|
+
async def messages_observing_status(self, session_id: str) -> MessageObservingStatus:
|
|
352
|
+
"""Get message observing status counts for a session.
|
|
353
|
+
|
|
354
|
+
Returns the count of messages by their observing status:
|
|
355
|
+
observed, in_process, and pending.
|
|
356
|
+
|
|
357
|
+
Args:
|
|
358
|
+
session_id: The UUID of the session.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
MessageObservingStatus object containing observed, in_process,
|
|
362
|
+
pending counts and updated_at timestamp.
|
|
363
|
+
"""
|
|
364
|
+
data = await self._requester.request(
|
|
365
|
+
"GET", f"/session/{session_id}/observing_status"
|
|
366
|
+
)
|
|
367
|
+
return MessageObservingStatus.model_validate(data)
|
acontext/resources/sessions.py
CHANGED
|
@@ -15,6 +15,7 @@ from ..types.session import (
|
|
|
15
15
|
LearningStatus,
|
|
16
16
|
ListSessionsOutput,
|
|
17
17
|
Message,
|
|
18
|
+
MessageObservingStatus,
|
|
18
19
|
Session,
|
|
19
20
|
TokenCounts,
|
|
20
21
|
)
|
|
@@ -171,7 +172,7 @@ class SessionsAPI:
|
|
|
171
172
|
)
|
|
172
173
|
return GetTasksOutput.model_validate(data)
|
|
173
174
|
|
|
174
|
-
def
|
|
175
|
+
def store_message(
|
|
175
176
|
self,
|
|
176
177
|
session_id: str,
|
|
177
178
|
*,
|
|
@@ -185,7 +186,7 @@ class SessionsAPI:
|
|
|
185
186
|
| None
|
|
186
187
|
) = None,
|
|
187
188
|
) -> Message:
|
|
188
|
-
"""
|
|
189
|
+
"""Store a message to a session.
|
|
189
190
|
|
|
190
191
|
Args:
|
|
191
192
|
session_id: The UUID of the session.
|
|
@@ -348,3 +349,20 @@ class SessionsAPI:
|
|
|
348
349
|
"""
|
|
349
350
|
data = self._requester.request("GET", f"/session/{session_id}/token_counts")
|
|
350
351
|
return TokenCounts.model_validate(data)
|
|
352
|
+
def messages_observing_status(self, session_id: str) -> MessageObservingStatus:
|
|
353
|
+
"""Get message observing status counts for a session.
|
|
354
|
+
|
|
355
|
+
Returns the count of messages by their observing status:
|
|
356
|
+
observed, in_process, and pending.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
session_id: The UUID of the session.
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
MessageObservingStatus object containing observed, in_process,
|
|
363
|
+
pending counts and updated_at timestamp.
|
|
364
|
+
"""
|
|
365
|
+
data = self._requester.request(
|
|
366
|
+
"GET", f"/session/{session_id}/observing_status"
|
|
367
|
+
)
|
|
368
|
+
return MessageObservingStatus.model_validate(data)
|
acontext/types/session.py
CHANGED
|
@@ -30,6 +30,34 @@ class RemoveToolResultStrategy(TypedDict):
|
|
|
30
30
|
params: RemoveToolResultParams
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
class RemoveToolCallParamsParams(TypedDict, total=False):
|
|
34
|
+
"""Parameters for the remove_tool_call_params edit strategy.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
keep_recent_n_tool_calls: Number of most recent tool calls to keep with full parameters.
|
|
38
|
+
Defaults to 3 if not specified.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
keep_recent_n_tool_calls: NotRequired[int]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class RemoveToolCallParamsStrategy(TypedDict):
|
|
46
|
+
"""Edit strategy to remove parameters from old tool-call parts.
|
|
47
|
+
|
|
48
|
+
Keeps the most recent N tool calls with full parameters, replacing older
|
|
49
|
+
tool call arguments with empty JSON "{}". The tool call ID and name remain
|
|
50
|
+
intact so tool-results can still reference them.
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
{"type": "remove_tool_call_params", "params": {"keep_recent_n_tool_calls": 5}}
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
type: Literal["remove_tool_call_params"]
|
|
57
|
+
params: RemoveToolCallParamsParams
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
33
61
|
class TokenLimitParams(TypedDict):
|
|
34
62
|
"""Parameters for the token_limit edit strategy.
|
|
35
63
|
|
|
@@ -59,7 +87,7 @@ class TokenLimitStrategy(TypedDict):
|
|
|
59
87
|
|
|
60
88
|
# Union type for all edit strategies
|
|
61
89
|
# When adding new strategies, add them to this Union: EditStrategy = Union[RemoveToolResultStrategy, OtherStrategy, ...]
|
|
62
|
-
EditStrategy = Union[RemoveToolResultStrategy, TokenLimitStrategy]
|
|
90
|
+
EditStrategy = Union[RemoveToolResultStrategy, RemoveToolCallParamsStrategy, TokenLimitStrategy]
|
|
63
91
|
|
|
64
92
|
|
|
65
93
|
class Asset(BaseModel):
|
|
@@ -187,6 +215,10 @@ class GetMessagesOutput(BaseModel):
|
|
|
187
215
|
...,
|
|
188
216
|
description="List of messages in the requested format (Message, OpenAI format, or Anthropic format)",
|
|
189
217
|
)
|
|
218
|
+
ids: list[str] = Field(
|
|
219
|
+
...,
|
|
220
|
+
description="List of message UUIDs corresponding to each item in the same order",
|
|
221
|
+
)
|
|
190
222
|
next_cursor: str | None = Field(None, description="Cursor for pagination")
|
|
191
223
|
has_more: bool = Field(..., description="Whether there are more items")
|
|
192
224
|
public_urls: dict[str, PublicURL] | None = Field(
|
|
@@ -221,3 +253,19 @@ class TokenCounts(BaseModel):
|
|
|
221
253
|
...,
|
|
222
254
|
description="Total token count for all text and tool-call parts in a session",
|
|
223
255
|
)
|
|
256
|
+
|
|
257
|
+
class MessageObservingStatus(BaseModel):
|
|
258
|
+
"""Response model for message observing status."""
|
|
259
|
+
|
|
260
|
+
observed: int = Field(
|
|
261
|
+
..., description="Number of messages with observed status"
|
|
262
|
+
)
|
|
263
|
+
in_process: int = Field(
|
|
264
|
+
..., description="Number of messages with in_process status"
|
|
265
|
+
)
|
|
266
|
+
pending: int = Field(
|
|
267
|
+
..., description="Number of messages with pending status"
|
|
268
|
+
)
|
|
269
|
+
updated_at: str = Field(
|
|
270
|
+
..., description="Timestamp when the status was retrieved"
|
|
271
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: acontext
|
|
3
|
+
Version: 0.0.11
|
|
4
|
+
Summary: Python SDK for the Acontext API
|
|
5
|
+
Keywords: acontext,sdk,client,api
|
|
6
|
+
Requires-Dist: httpx>=0.28.1
|
|
7
|
+
Requires-Dist: openai>=2.6.1
|
|
8
|
+
Requires-Dist: anthropic>=0.72.0
|
|
9
|
+
Requires-Dist: pydantic>=2.12.3
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Project-URL: Homepage, https://github.com/memodb-io/Acontext
|
|
12
|
+
Project-URL: Issues, https://github.com/memodb-io/Acontext/issues
|
|
13
|
+
Project-URL: Repository, https://github.com/memodb-io/Acontext
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
## acontext client for python
|
|
17
|
+
|
|
18
|
+
Python SDK for interacting with the Acontext REST API.
|
|
19
|
+
|
|
20
|
+
### Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install acontext
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> Requires Python 3.10 or newer.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# 🔍 Document
|
|
33
|
+
|
|
34
|
+
To understand more about this SDK, please view [our docs](https://docs.acontext.io/) and [api references](https://docs.acontext.io/api-reference/introduction)
|
|
@@ -13,21 +13,21 @@ acontext/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
13
13
|
acontext/resources/__init__.py,sha256=KSVQ3YJ-wuU6OWGWJ47gDGbjjetP102aEsVSR8JUb_4,721
|
|
14
14
|
acontext/resources/async_blocks.py,sha256=e_iJpgcAdwS2tXQ16MMCnySlddp5JV3BadN_EyqZSF4,5555
|
|
15
15
|
acontext/resources/async_disks.py,sha256=2JjLpUkz5YZEkLt_jCts_khTG_b7lvf4cUMfoaJcnI8,6471
|
|
16
|
-
acontext/resources/async_sessions.py,sha256=
|
|
16
|
+
acontext/resources/async_sessions.py,sha256=UBqVr7M0BrRifB79u7xWe0CfM66YTeSebiKHpvZZhBI,13252
|
|
17
17
|
acontext/resources/async_spaces.py,sha256=5lIZjI8GmgoMBcftAMD2vDj2FmbLZ6pi1-yNCWKv4cM,6408
|
|
18
18
|
acontext/resources/async_tools.py,sha256=RbGaF2kX65Mun-q-Fp5H1J8waWTLIdCOfbdY19jpn1o,1091
|
|
19
19
|
acontext/resources/blocks.py,sha256=HJdAy5HdyTcHCYCPmqNdvApYKZ6aWs-ORIi_wQt3TUM,5447
|
|
20
20
|
acontext/resources/disks.py,sha256=BjVhVXoujHWhg6L0TG9GmW9HLTTldJYEPxCbuppRkc4,6336
|
|
21
|
-
acontext/resources/sessions.py,sha256=
|
|
21
|
+
acontext/resources/sessions.py,sha256=7wdCM1rlozv3F05o9a5T9T-EEOp-y1eiVZHVfRYbQUo,13336
|
|
22
22
|
acontext/resources/spaces.py,sha256=LJP9krygZGdktMDtYGudCpk7yBxe_4v34QLk3SdejwQ,6267
|
|
23
23
|
acontext/resources/tools.py,sha256=II_185B0HYKSP43hizE6C1zs7kjkkPLKihuEG8s-DRY,1046
|
|
24
24
|
acontext/types/__init__.py,sha256=QWNLmdSnLE2b5XRXxnI2OKnHVdKQPJH0nJvvOYwhB1o,1448
|
|
25
25
|
acontext/types/block.py,sha256=CzKByunk642rWXNNnh8cx67UzKLKDAxODmC_whwjP90,1078
|
|
26
26
|
acontext/types/disk.py,sha256=g9u3rgCh05rK-gay19NUi-WyzI5Vt1GQwcyKv-5TSC4,2361
|
|
27
|
-
acontext/types/session.py,sha256=
|
|
27
|
+
acontext/types/session.py,sha256=H_n4vZJ02ZO5flqGZ8R5AYVSScxScf2r7UgsN5LRIa0,9965
|
|
28
28
|
acontext/types/space.py,sha256=uxbPrOHYpsntPHqhMCLQ2KovM7BngHC5Q2j7qexVrN8,2537
|
|
29
29
|
acontext/types/tool.py,sha256=-mVn-vgk2SENK0Ubt-ZgWFZxKa-ddABqcAgXQ69YY-E,805
|
|
30
30
|
acontext/uploads.py,sha256=6twnqQOY_eerNuEjeSKsE_3S0IfJUiczXtAy4aXqDl8,1379
|
|
31
|
-
acontext-0.0.
|
|
32
|
-
acontext-0.0.
|
|
33
|
-
acontext-0.0.
|
|
31
|
+
acontext-0.0.11.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
|
|
32
|
+
acontext-0.0.11.dist-info/METADATA,sha256=rlg5ytr7FzRwgofIKYaZkUFUxbYXoiW2EwOBKXIe1hs,859
|
|
33
|
+
acontext-0.0.11.dist-info/RECORD,,
|
|
@@ -1,661 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: acontext
|
|
3
|
-
Version: 0.0.9
|
|
4
|
-
Summary: Python SDK for the Acontext API
|
|
5
|
-
Keywords: acontext,sdk,client,api
|
|
6
|
-
Requires-Dist: httpx>=0.28.1
|
|
7
|
-
Requires-Dist: openai>=2.6.1
|
|
8
|
-
Requires-Dist: anthropic>=0.72.0
|
|
9
|
-
Requires-Dist: pydantic>=2.12.3
|
|
10
|
-
Requires-Python: >=3.10
|
|
11
|
-
Project-URL: Homepage, https://github.com/memodb-io/Acontext
|
|
12
|
-
Project-URL: Issues, https://github.com/memodb-io/Acontext/issues
|
|
13
|
-
Project-URL: Repository, https://github.com/memodb-io/Acontext
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
|
-
## acontext client for python
|
|
17
|
-
|
|
18
|
-
Python SDK for interacting with the Acontext REST API.
|
|
19
|
-
|
|
20
|
-
### Installation
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
pip install acontext
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
> Requires Python 3.10 or newer.
|
|
27
|
-
|
|
28
|
-
### Quickstart
|
|
29
|
-
|
|
30
|
-
```python
|
|
31
|
-
from acontext import AcontextClient
|
|
32
|
-
|
|
33
|
-
with AcontextClient(api_key="sk_project_token") as client:
|
|
34
|
-
# Create a space
|
|
35
|
-
space = client.spaces.create()
|
|
36
|
-
|
|
37
|
-
# Create a session
|
|
38
|
-
session = client.sessions.create(space_id=space.id)
|
|
39
|
-
|
|
40
|
-
# Send a message
|
|
41
|
-
from acontext.messages import build_acontext_message
|
|
42
|
-
message = build_acontext_message(role="user", parts=["Hello!"])
|
|
43
|
-
client.sessions.send_message(session.id, blob=message, format="acontext")
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
See the sections below for detailed examples of all available APIs.
|
|
47
|
-
|
|
48
|
-
### Async Client
|
|
49
|
-
|
|
50
|
-
The SDK provides full async support via `AsyncAcontextClient`. All API methods are available in async form:
|
|
51
|
-
|
|
52
|
-
```python
|
|
53
|
-
import asyncio
|
|
54
|
-
from acontext import AsyncAcontextClient
|
|
55
|
-
|
|
56
|
-
async def main():
|
|
57
|
-
async with AsyncAcontextClient(api_key="sk_project_token") as client:
|
|
58
|
-
# Create a space
|
|
59
|
-
space = await client.spaces.create()
|
|
60
|
-
|
|
61
|
-
# Create a session
|
|
62
|
-
session = await client.sessions.create(space_id=space.id)
|
|
63
|
-
|
|
64
|
-
# Send a message
|
|
65
|
-
from acontext.messages import build_acontext_message
|
|
66
|
-
message = build_acontext_message(role="user", parts=["Hello async!"])
|
|
67
|
-
await client.sessions.send_message(session.id, blob=message, format="acontext")
|
|
68
|
-
|
|
69
|
-
# Perform concurrent operations
|
|
70
|
-
spaces_task = client.spaces.list(limit=10)
|
|
71
|
-
sessions_task = client.sessions.list(limit=10)
|
|
72
|
-
spaces, sessions = await asyncio.gather(spaces_task, sessions_task)
|
|
73
|
-
|
|
74
|
-
asyncio.run(main())
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Health Check
|
|
78
|
-
|
|
79
|
-
#### Ping the server
|
|
80
|
-
|
|
81
|
-
Test connectivity to the Acontext API server:
|
|
82
|
-
|
|
83
|
-
```python
|
|
84
|
-
# Synchronous client
|
|
85
|
-
pong = client.ping()
|
|
86
|
-
print(f"Server responded: {pong}") # Output: Server responded: pong
|
|
87
|
-
|
|
88
|
-
# Async client
|
|
89
|
-
pong = await client.ping()
|
|
90
|
-
print(f"Server responded: {pong}") # Output: Server responded: pong
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
This is useful for:
|
|
94
|
-
- Verifying API connectivity before performing operations
|
|
95
|
-
- Health checks in monitoring systems
|
|
96
|
-
- Debugging connection issues
|
|
97
|
-
|
|
98
|
-
### Spaces API
|
|
99
|
-
|
|
100
|
-
#### List spaces
|
|
101
|
-
|
|
102
|
-
```python
|
|
103
|
-
spaces = client.spaces.list(limit=10, time_desc=True)
|
|
104
|
-
for space in spaces.items:
|
|
105
|
-
print(f"{space.id}: {space.configs}")
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
#### Create space
|
|
109
|
-
|
|
110
|
-
```python
|
|
111
|
-
space = client.spaces.create(configs={"name": "My Space"})
|
|
112
|
-
print(f"Created space: {space.id}")
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
#### Delete space
|
|
116
|
-
|
|
117
|
-
```python
|
|
118
|
-
client.spaces.delete(space_id="space-uuid")
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
#### Update space configs
|
|
122
|
-
|
|
123
|
-
```python
|
|
124
|
-
client.spaces.update_configs(
|
|
125
|
-
space_id="space-uuid",
|
|
126
|
-
configs={"name": "Updated Name", "description": "New description"}
|
|
127
|
-
)
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
#### Get space configs
|
|
131
|
-
|
|
132
|
-
```python
|
|
133
|
-
space = client.spaces.get_configs(space_id="space-uuid")
|
|
134
|
-
print(space.configs)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Sessions API
|
|
138
|
-
|
|
139
|
-
#### List sessions
|
|
140
|
-
|
|
141
|
-
```python
|
|
142
|
-
sessions = client.sessions.list(
|
|
143
|
-
space_id="space-uuid",
|
|
144
|
-
limit=20,
|
|
145
|
-
time_desc=True
|
|
146
|
-
)
|
|
147
|
-
for session in sessions.items:
|
|
148
|
-
print(f"{session.id}: {session.space_id}")
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### Create session
|
|
152
|
-
|
|
153
|
-
```python
|
|
154
|
-
session = client.sessions.create(
|
|
155
|
-
space_id="space-uuid",
|
|
156
|
-
configs={"mode": "chat"}
|
|
157
|
-
)
|
|
158
|
-
print(f"Created session: {session.id}")
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
#### Delete session
|
|
162
|
-
|
|
163
|
-
```python
|
|
164
|
-
client.sessions.delete(session_id="session-uuid")
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
#### Update session configs
|
|
168
|
-
|
|
169
|
-
```python
|
|
170
|
-
client.sessions.update_configs(
|
|
171
|
-
session_id="session-uuid",
|
|
172
|
-
configs={"mode": "updated-mode"}
|
|
173
|
-
)
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### Get session configs
|
|
177
|
-
|
|
178
|
-
```python
|
|
179
|
-
session = client.sessions.get_configs(session_id="session-uuid")
|
|
180
|
-
print(session.configs)
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
#### Connect session to space
|
|
184
|
-
|
|
185
|
-
```python
|
|
186
|
-
client.sessions.connect_to_space(
|
|
187
|
-
session_id="session-uuid",
|
|
188
|
-
space_id="space-uuid"
|
|
189
|
-
)
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
#### Get tasks
|
|
193
|
-
|
|
194
|
-
```python
|
|
195
|
-
tasks = client.sessions.get_tasks(
|
|
196
|
-
session_id="session-uuid",
|
|
197
|
-
limit=10,
|
|
198
|
-
time_desc=True
|
|
199
|
-
)
|
|
200
|
-
for task in tasks.items:
|
|
201
|
-
print(f"{task.id}: {task.status}")
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
#### Get messages
|
|
205
|
-
|
|
206
|
-
```python
|
|
207
|
-
messages = client.sessions.get_messages(
|
|
208
|
-
session_id="session-uuid",
|
|
209
|
-
limit=50,
|
|
210
|
-
format="acontext",
|
|
211
|
-
time_desc=True
|
|
212
|
-
)
|
|
213
|
-
for message in messages.items:
|
|
214
|
-
print(f"{message.role}: {message.parts}")
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### Send message (Acontext format)
|
|
218
|
-
|
|
219
|
-
```python
|
|
220
|
-
from acontext.messages import build_acontext_message
|
|
221
|
-
|
|
222
|
-
# Simple text message
|
|
223
|
-
message = build_acontext_message(role="user", parts=["Hello!"])
|
|
224
|
-
client.sessions.send_message(
|
|
225
|
-
session_id="session-uuid",
|
|
226
|
-
blob=message,
|
|
227
|
-
format="acontext"
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
# Message with file upload
|
|
231
|
-
from acontext import FileUpload
|
|
232
|
-
|
|
233
|
-
file_message = build_acontext_message(
|
|
234
|
-
role="user",
|
|
235
|
-
parts=[{"type": "file", "file_field": "document"}]
|
|
236
|
-
)
|
|
237
|
-
client.sessions.send_message(
|
|
238
|
-
session_id="session-uuid",
|
|
239
|
-
blob=file_message,
|
|
240
|
-
format="acontext",
|
|
241
|
-
file_field="document",
|
|
242
|
-
file=FileUpload(
|
|
243
|
-
filename="doc.pdf",
|
|
244
|
-
content=b"file content",
|
|
245
|
-
content_type="application/pdf"
|
|
246
|
-
)
|
|
247
|
-
)
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
#### Send message (OpenAI format)
|
|
251
|
-
|
|
252
|
-
```python
|
|
253
|
-
openai_message = {
|
|
254
|
-
"role": "user",
|
|
255
|
-
"content": "Hello from OpenAI format!"
|
|
256
|
-
}
|
|
257
|
-
client.sessions.send_message(
|
|
258
|
-
session_id="session-uuid",
|
|
259
|
-
blob=openai_message,
|
|
260
|
-
format="openai"
|
|
261
|
-
)
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
#### Send message (Anthropic format)
|
|
265
|
-
|
|
266
|
-
```python
|
|
267
|
-
anthropic_message = {
|
|
268
|
-
"role": "user",
|
|
269
|
-
"content": "Hello from Anthropic format!"
|
|
270
|
-
}
|
|
271
|
-
client.sessions.send_message(
|
|
272
|
-
session_id="session-uuid",
|
|
273
|
-
blob=anthropic_message,
|
|
274
|
-
format="anthropic"
|
|
275
|
-
)
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
#### Flush session buffer
|
|
279
|
-
|
|
280
|
-
```python
|
|
281
|
-
result = client.sessions.flush(session_id="session-uuid")
|
|
282
|
-
print(result) # {"status": 0, "errmsg": ""}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
### Tools API
|
|
286
|
-
|
|
287
|
-
#### Get tool names
|
|
288
|
-
|
|
289
|
-
```python
|
|
290
|
-
tools = client.tools.get_tool_name()
|
|
291
|
-
for tool in tools:
|
|
292
|
-
print(f"{tool.name} (used in {tool.sop_count} SOPs)")
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
#### Rename tool names
|
|
296
|
-
|
|
297
|
-
```python
|
|
298
|
-
result = client.tools.rename_tool_name(
|
|
299
|
-
rename=[
|
|
300
|
-
{"old_name": "calculate", "new_name": "calculate_math"},
|
|
301
|
-
{"old_name": "search", "new_name": "search_web"},
|
|
302
|
-
]
|
|
303
|
-
)
|
|
304
|
-
print(result.status) # 0 for success
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Agent Tools
|
|
308
|
-
|
|
309
|
-
The SDK provides agent tools that allow LLMs (OpenAI, Anthropic) to interact with Acontext disks through function calling. These tools can be converted to OpenAI or Anthropic tool schemas and executed when the LLM calls them.
|
|
310
|
-
|
|
311
|
-
#### Pre-configured Disk Tools
|
|
312
|
-
|
|
313
|
-
The SDK includes a pre-configured `DISK_TOOLS` pool with four disk operation tools:
|
|
314
|
-
|
|
315
|
-
- **`write_file`**: Write text content to a file
|
|
316
|
-
- **`read_file`**: Read a text file with optional line offset and limit
|
|
317
|
-
- **`replace_string`**: Replace strings in a file
|
|
318
|
-
- **`list_artifacts`**: List files and directories in a path
|
|
319
|
-
|
|
320
|
-
#### Getting Tool Schemas for LLM APIs
|
|
321
|
-
|
|
322
|
-
Convert tools to the appropriate format for your LLM provider:
|
|
323
|
-
|
|
324
|
-
```python
|
|
325
|
-
from acontext import AcontextClient
|
|
326
|
-
from acontext.agent.disk import DISK_TOOLS
|
|
327
|
-
|
|
328
|
-
client = AcontextClient(api_key="sk-ac-your-root-api-bearer-token")
|
|
329
|
-
|
|
330
|
-
# Get OpenAI-compatible tool schemas
|
|
331
|
-
openai_tools = DISK_TOOLS.to_openai_tool_schema()
|
|
332
|
-
|
|
333
|
-
# Get Anthropic-compatible tool schemas
|
|
334
|
-
anthropic_tools = DISK_TOOLS.to_anthropic_tool_schema()
|
|
335
|
-
|
|
336
|
-
# Use with OpenAI API
|
|
337
|
-
import openai
|
|
338
|
-
openai_client = openai.OpenAI(api_key="your-openai-key")
|
|
339
|
-
completion = openai_client.chat.completions.create(
|
|
340
|
-
model="gpt-4",
|
|
341
|
-
messages=[{"role": "user", "content": 'Write a file called hello.txt with "Hello, World!"'}],
|
|
342
|
-
tools=openai_tools,
|
|
343
|
-
)
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Executing Tools
|
|
347
|
-
|
|
348
|
-
When an LLM calls a tool, execute it using the tool pool:
|
|
349
|
-
|
|
350
|
-
```python
|
|
351
|
-
from acontext import AcontextClient
|
|
352
|
-
from acontext.agent.disk import DISK_TOOLS
|
|
353
|
-
|
|
354
|
-
client = AcontextClient(api_key="sk-ac-your-root-api-bearer-token")
|
|
355
|
-
|
|
356
|
-
# Create a disk for the tools to operate on
|
|
357
|
-
disk = client.disks.create()
|
|
358
|
-
|
|
359
|
-
# Create a context for the tools
|
|
360
|
-
ctx = DISK_TOOLS.format_context(client, disk.id)
|
|
361
|
-
|
|
362
|
-
# Execute a tool (e.g., after LLM returns a tool call)
|
|
363
|
-
result = DISK_TOOLS.execute_tool(
|
|
364
|
-
ctx,
|
|
365
|
-
"write_file",
|
|
366
|
-
{"filename": "hello.txt", "file_path": "/notes/", "content": "Hello, World!"}
|
|
367
|
-
)
|
|
368
|
-
print(result) # File 'hello.txt' written successfully to '/notes/hello.txt'
|
|
369
|
-
|
|
370
|
-
# Read the file
|
|
371
|
-
read_result = DISK_TOOLS.execute_tool(
|
|
372
|
-
ctx,
|
|
373
|
-
"read_file",
|
|
374
|
-
{"filename": "hello.txt", "file_path": "/notes/"}
|
|
375
|
-
)
|
|
376
|
-
print(read_result)
|
|
377
|
-
|
|
378
|
-
# List files in a directory
|
|
379
|
-
list_result = DISK_TOOLS.execute_tool(
|
|
380
|
-
ctx,
|
|
381
|
-
"list_artifacts",
|
|
382
|
-
{"file_path": "/notes/"}
|
|
383
|
-
)
|
|
384
|
-
print(list_result)
|
|
385
|
-
|
|
386
|
-
# Replace a string in a file
|
|
387
|
-
replace_result = DISK_TOOLS.execute_tool(
|
|
388
|
-
ctx,
|
|
389
|
-
"replace_string",
|
|
390
|
-
{
|
|
391
|
-
"filename": "hello.txt",
|
|
392
|
-
"file_path": "/notes/",
|
|
393
|
-
"old_string": "Hello",
|
|
394
|
-
"new_string": "Hi",
|
|
395
|
-
}
|
|
396
|
-
)
|
|
397
|
-
print(replace_result)
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
#### Creating Custom Tools
|
|
401
|
-
|
|
402
|
-
You can create custom tools by extending `BaseTool`:
|
|
403
|
-
|
|
404
|
-
```python
|
|
405
|
-
from acontext.agent.base import BaseTool, BaseToolPool, BaseContext
|
|
406
|
-
from typing import Dict, Any
|
|
407
|
-
|
|
408
|
-
class MyCustomTool(BaseTool):
|
|
409
|
-
@property
|
|
410
|
-
def name(self) -> str:
|
|
411
|
-
return "my_custom_tool"
|
|
412
|
-
|
|
413
|
-
@property
|
|
414
|
-
def description(self) -> str:
|
|
415
|
-
return "A custom tool that does something"
|
|
416
|
-
|
|
417
|
-
@property
|
|
418
|
-
def arguments(self) -> dict:
|
|
419
|
-
return {
|
|
420
|
-
"param1": {
|
|
421
|
-
"type": "string",
|
|
422
|
-
"description": "First parameter",
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
@property
|
|
427
|
-
def required_arguments(self) -> list[str]:
|
|
428
|
-
return ["param1"]
|
|
429
|
-
|
|
430
|
-
def execute(self, ctx: BaseContext, llm_arguments: dict) -> str:
|
|
431
|
-
param1 = llm_arguments.get("param1")
|
|
432
|
-
# Your custom logic here
|
|
433
|
-
return f"Result: {param1}"
|
|
434
|
-
|
|
435
|
-
# Create a custom tool pool
|
|
436
|
-
class MyToolPool(BaseToolPool):
|
|
437
|
-
def format_context(self, *args, **kwargs) -> BaseContext:
|
|
438
|
-
# Create and return your context
|
|
439
|
-
return BaseContext()
|
|
440
|
-
|
|
441
|
-
my_pool = MyToolPool()
|
|
442
|
-
my_pool.add_tool(MyCustomTool())
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### Blocks API
|
|
446
|
-
|
|
447
|
-
#### List blocks
|
|
448
|
-
|
|
449
|
-
```python
|
|
450
|
-
blocks = client.blocks.list(
|
|
451
|
-
space_id="space-uuid",
|
|
452
|
-
parent_id="parent-uuid",
|
|
453
|
-
block_type="page"
|
|
454
|
-
)
|
|
455
|
-
for block in blocks:
|
|
456
|
-
print(f"{block.id}: {block.title}")
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
#### Create block
|
|
460
|
-
|
|
461
|
-
```python
|
|
462
|
-
# Create a page
|
|
463
|
-
page = client.blocks.create(
|
|
464
|
-
space_id="space-uuid",
|
|
465
|
-
block_type="page",
|
|
466
|
-
title="My Page"
|
|
467
|
-
)
|
|
468
|
-
|
|
469
|
-
# Create a text block under the page
|
|
470
|
-
text_block = client.blocks.create(
|
|
471
|
-
space_id="space-uuid",
|
|
472
|
-
parent_id=page["id"],
|
|
473
|
-
block_type="text",
|
|
474
|
-
title="Content",
|
|
475
|
-
props={"text": "Block content here"}
|
|
476
|
-
)
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
#### Delete block
|
|
480
|
-
|
|
481
|
-
```python
|
|
482
|
-
client.blocks.delete(space_id="space-uuid", block_id="block-uuid")
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
#### Get block properties
|
|
486
|
-
|
|
487
|
-
```python
|
|
488
|
-
block = client.blocks.get_properties(
|
|
489
|
-
space_id="space-uuid",
|
|
490
|
-
block_id="block-uuid"
|
|
491
|
-
)
|
|
492
|
-
print(f"{block.title}: {block.props}")
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
#### Update block properties
|
|
496
|
-
|
|
497
|
-
```python
|
|
498
|
-
client.blocks.update_properties(
|
|
499
|
-
space_id="space-uuid",
|
|
500
|
-
block_id="block-uuid",
|
|
501
|
-
title="Updated Title",
|
|
502
|
-
props={"text": "Updated content"}
|
|
503
|
-
)
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
#### Move block
|
|
507
|
-
|
|
508
|
-
```python
|
|
509
|
-
# Move to a different parent
|
|
510
|
-
client.blocks.move(
|
|
511
|
-
space_id="space-uuid",
|
|
512
|
-
block_id="block-uuid",
|
|
513
|
-
parent_id="new-parent-uuid"
|
|
514
|
-
)
|
|
515
|
-
|
|
516
|
-
# Update sort order
|
|
517
|
-
client.blocks.move(
|
|
518
|
-
space_id="space-uuid",
|
|
519
|
-
block_id="block-uuid",
|
|
520
|
-
sort=0
|
|
521
|
-
)
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
#### Update block sort
|
|
525
|
-
|
|
526
|
-
```python
|
|
527
|
-
client.blocks.update_sort(
|
|
528
|
-
space_id="space-uuid",
|
|
529
|
-
block_id="block-uuid",
|
|
530
|
-
sort=5
|
|
531
|
-
)
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
### Disks API
|
|
535
|
-
|
|
536
|
-
#### List disks
|
|
537
|
-
|
|
538
|
-
```python
|
|
539
|
-
disks = client.disks.list(limit=10, time_desc=True)
|
|
540
|
-
for disk in disks.items:
|
|
541
|
-
print(f"Disk: {disk.id}")
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
#### Create disk
|
|
545
|
-
|
|
546
|
-
```python
|
|
547
|
-
disk = client.disks.create()
|
|
548
|
-
print(f"Created disk: {disk.id}")
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
#### Delete disk
|
|
552
|
-
|
|
553
|
-
```python
|
|
554
|
-
client.disks.delete(disk_id="disk-uuid")
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
### DiskArtifacts API
|
|
558
|
-
|
|
559
|
-
#### Upsert artifact
|
|
560
|
-
|
|
561
|
-
```python
|
|
562
|
-
from acontext import FileUpload
|
|
563
|
-
|
|
564
|
-
artifact = client.disks.artifacts.upsert(
|
|
565
|
-
disk_id="disk-uuid",
|
|
566
|
-
file=FileUpload(
|
|
567
|
-
filename="notes.md",
|
|
568
|
-
content=b"# Notes\nContent here",
|
|
569
|
-
content_type="text/markdown"
|
|
570
|
-
),
|
|
571
|
-
file_path="/documents/",
|
|
572
|
-
meta={"source": "api", "version": "1.0"}
|
|
573
|
-
)
|
|
574
|
-
print(f"Uploaded: {artifact.filename}")
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
#### Get artifact
|
|
578
|
-
|
|
579
|
-
```python
|
|
580
|
-
artifact = client.disks.artifacts.get(
|
|
581
|
-
disk_id="disk-uuid",
|
|
582
|
-
file_path="/documents/",
|
|
583
|
-
filename="notes.md",
|
|
584
|
-
with_public_url=True,
|
|
585
|
-
with_content=True
|
|
586
|
-
)
|
|
587
|
-
print(f"Content: {artifact.content}")
|
|
588
|
-
print(f"URL: {artifact.public_url}")
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
#### Update artifact metadata
|
|
592
|
-
|
|
593
|
-
```python
|
|
594
|
-
artifact = client.disks.artifacts.update(
|
|
595
|
-
disk_id="disk-uuid",
|
|
596
|
-
file_path="/documents/",
|
|
597
|
-
filename="notes.md",
|
|
598
|
-
meta={"source": "api", "version": "2.0", "updated": True}
|
|
599
|
-
)
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
#### Delete artifact
|
|
603
|
-
|
|
604
|
-
```python
|
|
605
|
-
client.disks.artifacts.delete(
|
|
606
|
-
disk_id="disk-uuid",
|
|
607
|
-
file_path="/documents/",
|
|
608
|
-
filename="notes.md"
|
|
609
|
-
)
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
#### List artifacts
|
|
613
|
-
|
|
614
|
-
```python
|
|
615
|
-
artifacts = client.disks.artifacts.list(
|
|
616
|
-
disk_id="disk-uuid",
|
|
617
|
-
path="/documents/"
|
|
618
|
-
)
|
|
619
|
-
for artifact in artifacts.items:
|
|
620
|
-
print(f"{artifact.filename} ({artifact.size_b} bytes)")
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
### Semantic search within spaces
|
|
624
|
-
|
|
625
|
-
The SDK provides a powerful semantic search API for finding content within your spaces:
|
|
626
|
-
|
|
627
|
-
#### 1. Experience Search (Advanced AI-powered search)
|
|
628
|
-
|
|
629
|
-
The most sophisticated search that can operate in two modes: **fast** (quick semantic search) or **agentic** (AI-powered iterative refinement).
|
|
630
|
-
|
|
631
|
-
```python
|
|
632
|
-
from acontext import AcontextClient
|
|
633
|
-
|
|
634
|
-
client = AcontextClient(api_key="sk_project_token")
|
|
635
|
-
|
|
636
|
-
# Fast mode - quick semantic search
|
|
637
|
-
result = client.spaces.experience_search(
|
|
638
|
-
space_id="space-uuid",
|
|
639
|
-
query="How to implement authentication?",
|
|
640
|
-
limit=10,
|
|
641
|
-
mode="fast",
|
|
642
|
-
)
|
|
643
|
-
|
|
644
|
-
# Agentic mode - AI-powered iterative search
|
|
645
|
-
result = client.spaces.experience_search(
|
|
646
|
-
space_id="space-uuid",
|
|
647
|
-
query="What are the best practices for API security?",
|
|
648
|
-
limit=10,
|
|
649
|
-
mode="agentic",
|
|
650
|
-
max_iterations=20,
|
|
651
|
-
)
|
|
652
|
-
|
|
653
|
-
# Access results
|
|
654
|
-
for block in result.cited_blocks:
|
|
655
|
-
print(f"{block.title} (distance: {block.distance})")
|
|
656
|
-
|
|
657
|
-
if result.final_answer:
|
|
658
|
-
print(f"AI Answer: {result.final_answer}")
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
See `examples/search_usage.py` for more detailed examples including async usage.
|