A3S Code Python bootstrap package that fetches platform-native binaries from GitHub Releases
Project description
A3S Code — Python SDK
Native Python bindings for the A3S Code AI coding agent, built with PyO3.
Installation
pip install a3s-code
Quick Start
from a3s_code import Agent
agent = Agent.create("agent.hcl")
session = agent.session("/my-project")
result = session.send("What files handle authentication?")
print(result.text)
Slash Commands
Every session includes built-in slash commands dispatched before the LLM:
# List all available commands
commands = session.list_commands()
for cmd in commands:
print(f"/{cmd['name']:15s} {cmd['description']}")
# Built-in commands
result = session.send("/help") # List all commands
result = session.send("/model") # Show current model
result = session.send("/cost") # Token usage and cost
result = session.send("/history") # Conversation stats
result = session.send("/cron-list") # List scheduled tasks
Custom Commands
def my_handler(args: str, ctx: dict) -> str:
return f"Model: {ctx['model']}, History: {ctx['history_len']} msgs, args: {args!r}"
session.register_command("status", "Show session info", my_handler)
result = session.send("/status hello")
Scheduled Tasks
Schedule recurring prompts that fire after each send() call:
# Via /loop slash command
r = session.send("/loop 30s check deployment status")
print(r.text) # Scheduled [a1b2c3d4]: "check deployment status" — fires every 30s
# Programmatic API
task_id = session.schedule_task("summarize recent commits", 300) # every 5 min
# List active tasks
for t in session.list_scheduled_tasks():
print(f"[{t['id']}] every {t['interval_secs']}s — \"{t['prompt']}\"")
# Cancel
session.cancel_scheduled_task(task_id)
session.send(f"/cron-cancel {task_id}")
Interval syntax: 30s, 5m, 2h, 1d. Leading or trailing with every clause.
Full API
from a3s_code import (
Agent,
SessionOptions,
DefaultSecurityProvider,
FileMemoryStore,
FileSessionStore,
)
agent = Agent.create("agent.hcl")
session = agent.session("/my-project",
model="openai/gpt-4o",
builtin_skills=True,
planning=True,
)
# Send / Stream
result = session.send("Explain the auth module")
for event in session.stream("Refactor auth"):
if event.event_type == "text_delta":
print(event.text, end="", flush=True)
# Direct tools (bypass LLM)
session.read_file("src/main.py")
session.bash("pytest")
session.glob("**/*.py")
session.grep("TODO")
# Rich document parsing metadata
tool = session.tool("agentic_parse", {"path": "docs/scanned.pdf"})
print(tool.metadata) # parsed dict
query_tool = session.tool(
"agentic_parse",
{"path": "docs/scanned.pdf", "query": "overview"},
)
for block in query_tool.agentic_parse_llm_blocks_info:
location = block.location.display if block.location else None
print(block.index, block.kind, block.label, location)
search = session.tool("agentic_search", {"query": "invoice total", "mode": "fast"})
for result in search.agentic_search_results_info:
for match in result.matches:
print(match.line_number, match.locator, match.content)
# Slash commands & scheduling
session.list_commands()
session.register_command("ping", "Pong!", lambda args, ctx: "pong")
task_id = session.schedule_task("daily report", 86400)
session.list_scheduled_tasks()
session.cancel_scheduled_task(task_id)
# Memory
session.remember_success("task", ["tool"], "result")
session.recall_similar("auth", 5)
# Hooks
session.register_hook("audit", "pre_tool_use", handler_fn)
# MCP
session.add_mcp_server("github", command="npx", args=["-y", "@modelcontextprotocol/server-github"])
session.mcp_status()
session.tool_names()
session.remove_mcp_server("github")
# Persistence
opts = SessionOptions()
opts.session_store = FileSessionStore('./sessions')
opts.session_id = 'my-session'
opts.auto_save = True
session2 = agent.session(".", opts)
resumed = agent.resume_session('my-session', opts)
Agentic Search Match Locators
agentic_search_results_info now exposes typed match and sampled-line entries
so you can inspect page / section locators without parsing raw metadata.
search = session.tool("agentic_search", {"query": "overview", "mode": "fast"})
for result in search.agentic_search_results_info:
for match in result.matches:
print(match.line_number, match.locator, match.content)
if match.context_before:
print("before:", match.context_before[-1])
deep = session.tool("agentic_search", {"query": "overview", "mode": "deep"})
for result in deep.agentic_search_results_info:
for sampled in result.sampled_lines:
print(sampled.line_number, sampled.locator, sampled.distance, sampled.weight)
Agentic Parse LLM Blocks
When agentic_parse runs with a query, the SDK also exposes which structured
document blocks were actually selected for the LLM input.
tool = session.tool(
"agentic_parse",
{"path": "docs/scanned.pdf", "query": "overview"},
)
for block in tool.agentic_parse_llm_blocks_info:
location = block.location.display if block.location else None
print(block.index, block.kind, block.label, location)
Sub-Agent Events
Orchestrator.create(agent=agent) creates real LLM-backed sub-agents. Use
handle.events() to observe sub-agent progress, tool calls, and streamed text.
from a3s_code import Agent, Orchestrator, SubAgentConfig
agent = Agent.create("agent.hcl")
orch = Orchestrator.create(agent=agent)
handle = orch.spawn_subagent(SubAgentConfig(
agent_type="general",
prompt="Use bash to print hello, then explain it.",
permissive=True,
max_steps=5,
))
events = handle.events()
while True:
event = events.recv(timeout_ms=1000)
if event is None:
continue
event_type = event["event_type"]
if event_type == "sub_agent_internal_event" and event.get("type") == "text_delta":
print(event.get("text", ""), end="", flush=True)
elif event_type == "tool_execution_started":
print("tool args:", event["args"])
elif event_type == "tool_execution_completed":
print("tool duration_ms:", event["duration_ms"])
elif event_type == "sub_agent_completed":
break
Important details:
- Event names use
sub_agent_*, notsubagent_*. sub_agent_internal_eventpayloads are flattened. For example, a text delta is:{"event_type": "sub_agent_internal_event", "type": "text_delta", "text": "..."}rather than nesting underevent.tool_execution_started.argscontains the accumulated tool input.tool_execution_completed.duration_msis guaranteed to be at least1for real tool calls.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file a3s_code-1.9.1.tar.gz.
File metadata
- Download URL: a3s_code-1.9.1.tar.gz
- Upload date:
- Size: 5.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e2c976c1bb3f74a0872db9b728927936e87353a46d78ce1f4c9e67a276116a7
|
|
| MD5 |
fedbb7ff468fe92401f95a3f298b8a6c
|
|
| BLAKE2b-256 |
579209c946f166b29bb927d5d0d0e079939f23ec79655f6653f7e47a6e8823af
|
File details
Details for the file a3s_code-1.9.1-py3-none-any.whl.
File metadata
- Download URL: a3s_code-1.9.1-py3-none-any.whl
- Upload date:
- Size: 5.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b30a6417885d45e7ede8a5487a21b16c98775c0709b82dea440eda23fe71c4d
|
|
| MD5 |
e59d494b41d51b610d108c8e60706ab0
|
|
| BLAKE2b-256 |
0b8434d6a9e479705b316ae3c3e9310a336fbb5c245420382d7f2fe2815cd0c7
|