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.
@@ -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 send_message(
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
- """Send a message to a session.
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)
@@ -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 send_message(
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
- """Send a message to a session.
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=oFVcU0rBGD5Mhue7HdKxRQermmSHSlI05eNRgPV-8J4,12541
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=mETp0dtGBi9e20L5f_KbCzw-6oP0pjtUmx-9Vlb8vYA,12634
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=HU8i8zxHGfGkHS9YRlh4JDst3aWZLfqSIUVq-HX4GYg,8444
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.9.dist-info/WHEEL,sha256=xDCZ-UyfvkGuEHPeI7BcJzYKIZzdqN8A8o1M5Om8IyA,79
32
- acontext-0.0.9.dist-info/METADATA,sha256=O1dmjGIvaW5EisSVf5E9huYMe2jo_SmrYUUhy6JVv_Q,14395
33
- acontext-0.0.9.dist-info/RECORD,,
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,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.17
2
+ Generator: uv 0.9.18
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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.