a3s-code 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {a3s_code-0.1.0 → a3s_code-0.2.0}/PKG-INFO +1 -1
- {a3s_code-0.1.0 → a3s_code-0.2.0}/a3s_code/__init__.py +2 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/a3s_code/client.py +118 -8
- {a3s_code-0.1.0 → a3s_code-0.2.0}/a3s_code/types.py +13 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/pyproject.toml +1 -1
- {a3s_code-0.1.0 → a3s_code-0.2.0}/.git +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/.gitignore +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/LICENSE +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/MANIFEST.in +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/README.md +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/a3s_code/py.typed +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/README.md +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/basic_usage.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/claude_code_skills_example.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/code_review_agent.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/context_management.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/event_streaming.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/external_tasks.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/hitl_confirmation.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/lsp_example.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/memory_events_example.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/memory_example.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/permission_policy.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/planning_example.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/provider_config.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/skill_management.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/storage_configuration.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/examples/todo_tracking.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/justfile +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/proto/code_agent.proto +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/pytest.ini +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/tests/conftest.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/tests/test_client.py +0 -0
- {a3s_code-0.1.0 → a3s_code-0.2.0}/tests/test_integration.py +0 -0
|
@@ -28,6 +28,7 @@ from .types import (
|
|
|
28
28
|
MemoryType,
|
|
29
29
|
CronJobStatus,
|
|
30
30
|
CronExecutionStatus,
|
|
31
|
+
StorageType,
|
|
31
32
|
# Types
|
|
32
33
|
AgentInfo,
|
|
33
34
|
ToolCapability,
|
|
@@ -106,6 +107,7 @@ __all__ = [
|
|
|
106
107
|
"MemoryType",
|
|
107
108
|
"CronJobStatus",
|
|
108
109
|
"CronExecutionStatus",
|
|
110
|
+
"StorageType",
|
|
109
111
|
# Types
|
|
110
112
|
"AgentInfo",
|
|
111
113
|
"ToolCapability",
|
|
@@ -8,7 +8,7 @@ import grpc
|
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Optional, List, Dict, Iterator, Any
|
|
11
|
+
from typing import Optional, List, Dict, Iterator, Any, Union
|
|
12
12
|
|
|
13
13
|
from .types import (
|
|
14
14
|
ProviderInfo,
|
|
@@ -17,6 +17,8 @@ from .types import (
|
|
|
17
17
|
ModelLimitInfo,
|
|
18
18
|
ModelModalitiesInfo,
|
|
19
19
|
SessionConfig,
|
|
20
|
+
LLMConfig,
|
|
21
|
+
StorageType,
|
|
20
22
|
Message,
|
|
21
23
|
Todo,
|
|
22
24
|
ConfirmationPolicy,
|
|
@@ -290,8 +292,91 @@ class A3sClient:
|
|
|
290
292
|
config: Optional[SessionConfig] = None,
|
|
291
293
|
session_id: Optional[str] = None,
|
|
292
294
|
initial_context: Optional[List[Message]] = None,
|
|
295
|
+
*,
|
|
296
|
+
name: str = "",
|
|
297
|
+
workspace: str = "",
|
|
298
|
+
llm: Optional[Union[LLMConfig, Dict[str, Any]]] = None,
|
|
299
|
+
system_prompt: Optional[str] = None,
|
|
300
|
+
max_context_length: Optional[int] = None,
|
|
301
|
+
auto_compact: Optional[bool] = None,
|
|
302
|
+
storage_type: Optional[StorageType] = None,
|
|
293
303
|
) -> Dict[str, Any]:
|
|
294
|
-
"""Create a new session.
|
|
304
|
+
"""Create a new session.
|
|
305
|
+
|
|
306
|
+
Accepts either a SessionConfig object or keyword arguments to build one.
|
|
307
|
+
If both are provided, keyword arguments override the config fields.
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
config: Optional SessionConfig object.
|
|
311
|
+
session_id: Optional session ID (server generates one if omitted).
|
|
312
|
+
initial_context: Optional list of messages to seed the session.
|
|
313
|
+
name: Session name.
|
|
314
|
+
workspace: Working directory for tool sandboxing. Each session gets
|
|
315
|
+
its own workspace-scoped ToolContext. If empty, falls back to
|
|
316
|
+
the server-level default workspace.
|
|
317
|
+
llm: LLM configuration (LLMConfig object or plain dict with keys:
|
|
318
|
+
provider, model, api_key, base_url, temperature, max_tokens).
|
|
319
|
+
system_prompt: Custom system prompt for the session.
|
|
320
|
+
max_context_length: Maximum context window length.
|
|
321
|
+
auto_compact: Enable automatic context compaction.
|
|
322
|
+
storage_type: Storage backend (StorageType.MEMORY or StorageType.FILE).
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
Dict with session_id and session.
|
|
326
|
+
"""
|
|
327
|
+
# Build config from kwargs when no config object is provided
|
|
328
|
+
has_kwargs = any(v for v in [name, workspace, llm, system_prompt,
|
|
329
|
+
max_context_length, auto_compact, storage_type])
|
|
330
|
+
if config is None and has_kwargs:
|
|
331
|
+
llm_config = None
|
|
332
|
+
if llm is not None:
|
|
333
|
+
if isinstance(llm, dict):
|
|
334
|
+
llm_config = LLMConfig(
|
|
335
|
+
provider=llm.get("provider", ""),
|
|
336
|
+
model=llm.get("model", ""),
|
|
337
|
+
api_key=llm.get("api_key"),
|
|
338
|
+
base_url=llm.get("base_url"),
|
|
339
|
+
temperature=llm.get("temperature"),
|
|
340
|
+
max_tokens=llm.get("max_tokens"),
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
llm_config = llm
|
|
344
|
+
config = SessionConfig(
|
|
345
|
+
name=name,
|
|
346
|
+
workspace=workspace,
|
|
347
|
+
llm=llm_config,
|
|
348
|
+
system_prompt=system_prompt,
|
|
349
|
+
max_context_length=max_context_length,
|
|
350
|
+
auto_compact=auto_compact,
|
|
351
|
+
storage_type=storage_type,
|
|
352
|
+
)
|
|
353
|
+
elif config is not None and has_kwargs:
|
|
354
|
+
# kwargs override config fields
|
|
355
|
+
if name:
|
|
356
|
+
config.name = name
|
|
357
|
+
if workspace:
|
|
358
|
+
config.workspace = workspace
|
|
359
|
+
if llm is not None:
|
|
360
|
+
if isinstance(llm, dict):
|
|
361
|
+
config.llm = LLMConfig(
|
|
362
|
+
provider=llm.get("provider", ""),
|
|
363
|
+
model=llm.get("model", ""),
|
|
364
|
+
api_key=llm.get("api_key"),
|
|
365
|
+
base_url=llm.get("base_url"),
|
|
366
|
+
temperature=llm.get("temperature"),
|
|
367
|
+
max_tokens=llm.get("max_tokens"),
|
|
368
|
+
)
|
|
369
|
+
else:
|
|
370
|
+
config.llm = llm
|
|
371
|
+
if system_prompt is not None:
|
|
372
|
+
config.system_prompt = system_prompt
|
|
373
|
+
if max_context_length is not None:
|
|
374
|
+
config.max_context_length = max_context_length
|
|
375
|
+
if auto_compact is not None:
|
|
376
|
+
config.auto_compact = auto_compact
|
|
377
|
+
if storage_type is not None:
|
|
378
|
+
config.storage_type = storage_type
|
|
379
|
+
|
|
295
380
|
request = {
|
|
296
381
|
"session_id": session_id,
|
|
297
382
|
"config": self._session_config_to_proto(config) if config else None,
|
|
@@ -1741,18 +1826,43 @@ class A3sClient:
|
|
|
1741
1826
|
"workspace": config.workspace,
|
|
1742
1827
|
}
|
|
1743
1828
|
if config.llm:
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1829
|
+
if isinstance(config.llm, dict):
|
|
1830
|
+
llm_proto = {
|
|
1831
|
+
"provider": config.llm.get("provider", ""),
|
|
1832
|
+
"model": config.llm.get("model", ""),
|
|
1833
|
+
"api_key": config.llm.get("api_key", ""),
|
|
1834
|
+
"base_url": config.llm.get("base_url", ""),
|
|
1835
|
+
}
|
|
1836
|
+
if config.llm.get("temperature") is not None:
|
|
1837
|
+
llm_proto["temperature"] = config.llm["temperature"]
|
|
1838
|
+
if config.llm.get("max_tokens") is not None:
|
|
1839
|
+
llm_proto["max_tokens"] = config.llm["max_tokens"]
|
|
1840
|
+
else:
|
|
1841
|
+
llm_proto = {
|
|
1842
|
+
"provider": config.llm.provider,
|
|
1843
|
+
"model": config.llm.model,
|
|
1844
|
+
"api_key": config.llm.api_key or "",
|
|
1845
|
+
"base_url": config.llm.base_url or "",
|
|
1846
|
+
}
|
|
1847
|
+
if config.llm.temperature is not None:
|
|
1848
|
+
llm_proto["temperature"] = config.llm.temperature
|
|
1849
|
+
if config.llm.max_tokens is not None:
|
|
1850
|
+
llm_proto["max_tokens"] = config.llm.max_tokens
|
|
1851
|
+
result["llm"] = llm_proto
|
|
1750
1852
|
if config.system_prompt:
|
|
1751
1853
|
result["system_prompt"] = config.system_prompt
|
|
1752
1854
|
if config.max_context_length:
|
|
1753
1855
|
result["max_context_length"] = config.max_context_length
|
|
1754
1856
|
if config.auto_compact is not None:
|
|
1755
1857
|
result["auto_compact"] = config.auto_compact
|
|
1858
|
+
if config.storage_type is not None:
|
|
1859
|
+
# Map enum value to proto int; use .value to normalize aliases
|
|
1860
|
+
storage_value_map = {
|
|
1861
|
+
"STORAGE_TYPE_UNSPECIFIED": 0,
|
|
1862
|
+
"STORAGE_TYPE_MEMORY": 1,
|
|
1863
|
+
"STORAGE_TYPE_FILE": 2,
|
|
1864
|
+
}
|
|
1865
|
+
result["storage_type"] = storage_value_map.get(config.storage_type.value, 0)
|
|
1756
1866
|
return result
|
|
1757
1867
|
|
|
1758
1868
|
def _message_to_proto(self, msg: Message) -> Dict[str, Any]:
|
|
@@ -155,6 +155,18 @@ class ResourceLimits:
|
|
|
155
155
|
# ============================================================================
|
|
156
156
|
|
|
157
157
|
|
|
158
|
+
class StorageType(Enum):
|
|
159
|
+
"""Storage backend type for session persistence."""
|
|
160
|
+
UNSPECIFIED = "STORAGE_TYPE_UNSPECIFIED"
|
|
161
|
+
MEMORY = "STORAGE_TYPE_MEMORY"
|
|
162
|
+
FILE = "STORAGE_TYPE_FILE"
|
|
163
|
+
|
|
164
|
+
# Aliases for proto-style naming (used by examples and TS SDK parity)
|
|
165
|
+
STORAGE_TYPE_UNSPECIFIED = "STORAGE_TYPE_UNSPECIFIED"
|
|
166
|
+
STORAGE_TYPE_MEMORY = "STORAGE_TYPE_MEMORY"
|
|
167
|
+
STORAGE_TYPE_FILE = "STORAGE_TYPE_FILE"
|
|
168
|
+
|
|
169
|
+
|
|
158
170
|
@dataclass
|
|
159
171
|
class LLMConfig:
|
|
160
172
|
provider: str = ""
|
|
@@ -173,6 +185,7 @@ class SessionConfig:
|
|
|
173
185
|
system_prompt: Optional[str] = None
|
|
174
186
|
max_context_length: Optional[int] = None
|
|
175
187
|
auto_compact: Optional[bool] = None
|
|
188
|
+
storage_type: Optional[StorageType] = None
|
|
176
189
|
|
|
177
190
|
|
|
178
191
|
@dataclass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|