From a7ac7ee3d4a145d5fcf905e1bf2b02b74de66fbb Mon Sep 17 00:00:00 2001 From: Hefeng Zhou Date: Mon, 6 Jul 2026 17:51:44 +0800 Subject: [PATCH] docs(python): clarify skill invocation from SDK --- examples/test_skill_tool.py | 11 +++++------ sdk/python/README.md | 24 +++++++++++++++++++++--- sdk/python/docs/QUICK_REFERENCE.md | 25 ++++++++++++++++++++++++- sdk/python/src/session.rs | 2 +- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/examples/test_skill_tool.py b/examples/test_skill_tool.py index 485ecb61..020366fe 100644 --- a/examples/test_skill_tool.py +++ b/examples/test_skill_tool.py @@ -9,7 +9,6 @@ 4. Verifying permission isolation works """ -import asyncio import os import sys import tempfile @@ -21,7 +20,7 @@ from a3s_code import Agent -async def main(): +def main(): print("=" * 80) print("Skill Tool Test with Kimi Model") print("=" * 80) @@ -90,7 +89,7 @@ async def main(): try: print("\nšŸ’¬ Prompt: Use the file-reader skill to read test.txt") - result = await session.send( + result = session.send( "Use the file-reader skill to read test.txt and tell me what it contains" ) print(f"\nāœ… Response:\n{result.text}") @@ -107,7 +106,7 @@ async def main(): try: print("\nšŸ’¬ Prompt: Use the file-reader skill to search for 'test' in all files") - result = await session.send( + result = session.send( "Use the file-reader skill to search for the word 'test' in all files" ) print(f"\nāœ… Response:\n{result.text}") @@ -124,7 +123,7 @@ async def main(): try: print("\nšŸ’¬ Prompt: Use the file-reader skill to write a summary to output.txt") - result = await session.send( + result = session.send( "Use the file-reader skill to write a summary of test.txt to output.txt" ) print(f"\nāœ… Response:\n{result.text}") @@ -146,4 +145,4 @@ async def main(): print("=" * 80) if __name__ == "__main__": - asyncio.run(main()) + main() diff --git a/sdk/python/README.md b/sdk/python/README.md index e849a437..fe0ce8e3 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -24,12 +24,12 @@ Air-gapped or hermetic install? Grab the wheel matching your interpreter directly: ```bash +VERSION=5.3.5 # replace with the release version you are installing +PYTAG=cp312-cp312-manylinux_2_28_x86_64 pip install \ - 'https://github.com/A3S-Lab/Code/releases/download/v/a3s_code--cp312-cp312-manylinux_2_28_x86_64.whl' + "https://github.com/A3S-Lab/Code/releases/download/v${VERSION}/a3s_code-${VERSION}-${PYTAG}.whl" ``` -Replace `` with the release to install, for example `5.3.5`. - ## Quick Start ```python @@ -280,6 +280,24 @@ session.tool("dynamic_workflow", { }) session.unregister_dynamic_tool("dynamic_workflow") +# Folder-style skills +workspace = "/my-project" +skill_dir = f"{workspace}/skills" +session = agent.session(workspace, skill_dirs=[skill_dir]) +matches = session.tool("search_skills", {"query": "review database schema", "limit": 5}) +print(matches.output) + +skill_result = session.tool("Skill", { + "skill_name": "db-review", + "prompt": "Review the migrations and summarize correctness risks.", +}) +print(skill_result.output) + +# Or configure skill directories through SessionOptions. +opts = SessionOptions() +opts.skill_dirs = [skill_dir] +session = agent.session(workspace, opts) + # S3-compatible workspace — point the same direct tools at object storage. # `bash`, `git`, `grep`, `glob` are automatically hidden because object # storage cannot service them. Works with AWS S3, MinIO, RustFS, R2, B2. diff --git a/sdk/python/docs/QUICK_REFERENCE.md b/sdk/python/docs/QUICK_REFERENCE.md index 6929550a..7149b81c 100644 --- a/sdk/python/docs/QUICK_REFERENCE.md +++ b/sdk/python/docs/QUICK_REFERENCE.md @@ -1,4 +1,4 @@ -# A3S Code Python SDK 2.3 Quick Reference +# A3S Code Python SDK Quick Reference This page is the short, current reference for the Python SDK. @@ -74,6 +74,29 @@ session.unregister_dynamic_tool("dynamic_workflow") Direct tools bypass the LLM and are useful for deterministic checks, diagnostics, and tests. +## Skills + +```python +session = agent.session(".", skill_dirs=["./skills"]) + +matches = session.tool("search_skills", { + "query": "review database schema", + "limit": 5, +}) +print(matches.output) + +result = session.tool("Skill", { + "skill_name": "db-review", + "prompt": "Review the migrations and summarize correctness risks.", +}) +print(result.output) +``` + +`search_skills` is a deterministic direct tool. `Skill` loads the selected +folder-style skill and then runs the configured model with that skill's +temporary allowed-tools grant, so the session still needs a working provider +configuration. + ## Evidence ```python diff --git a/sdk/python/src/session.rs b/sdk/python/src/session.rs index 7015bb30..a18d0ed1 100644 --- a/sdk/python/src/session.rs +++ b/sdk/python/src/session.rs @@ -846,7 +846,7 @@ impl PySession { /// return f"pong! session={ctx['session_id']}" /// /// session.register_command("ping", "Pong!", ping_handler) - /// result = await session.send("/ping hello") + /// result = session.send("/ping hello") #[pyo3(signature = (name, description, handler))] fn register_command( &self,