@@ -11,7 +11,7 @@ let result = session.send("Refactor auth to use JWT").await?;
1111[ ![ Crates.io] ( https://img.shields.io/crates/v/a3s-code-core.svg )] ( https://crates.io/crates/a3s-code-core )
1212[ ![ Documentation] ( https://docs.rs/a3s-code-core/badge.svg )] ( https://docs.rs/a3s-code-core )
1313[ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-yellow.svg )] ( ./LICENSE )
14- [ ![ Tests] ( https://img.shields.io/badge/tests-1458 %20passing-brightgreen.svg )] ( ./core/tests )
14+ [ ![ Tests] ( https://img.shields.io/badge/tests-1500 %20passing-brightgreen.svg )] ( ./core/tests )
1515
1616---
1717
@@ -255,6 +255,38 @@ Interactive session commands dispatched before the LLM. Custom commands via the
255255| ` /cron-list ` | List all scheduled recurring prompts |
256256| ` /cron-cancel <id> ` | Cancel a scheduled task by ID |
257257
258+ ### Programmatic Scheduler API (SDK)
259+
260+ ``` typescript
261+ // TypeScript
262+ const commands = session .listCommands (); // CommandInfo[]
263+
264+ const taskId = session .scheduleTask (' check deployment status' , 30 ); // every 30s
265+ const tasks = session .listScheduledTasks (); // ScheduledTaskInfo[]
266+ const ok = session .cancelScheduledTask (taskId ); // boolean
267+
268+ // Also via slash commands:
269+ await session .send (' /loop 5m summarize recent commits' );
270+ await session .send (' /cron-list' );
271+ await session .send (` /cron-cancel ${taskId } ` );
272+ ```
273+
274+ ``` python
275+ # Python
276+ commands = session.list_commands() # list[dict] — name, description, usage
277+ session.register_command(" status" , " Show session status" ,
278+ lambda args , ctx : f " Model: { ctx[' model' ]} , History: { ctx[' history_len' ]} msgs " )
279+
280+ task_id = session.schedule_task(" check deployment status" , 30 ) # every 30s
281+ tasks = session.list_scheduled_tasks() # list[dict] — id, prompt, interval_secs, fire_count, next_fire_in_secs
282+ ok = session.cancel_scheduled_task(task_id) # True
283+
284+ # Also via slash commands:
285+ session.send(" /loop 5m summarize recent commits" )
286+ session.send(" /cron-list" )
287+ session.send(f " /cron-cancel { task_id} " )
288+ ```
289+
258290``` rust
259291use a3s_code_core :: commands :: {SlashCommand , CommandContext , CommandOutput };
260292
@@ -947,7 +979,8 @@ SessionOptions::new().with_security_provider(Arc::new(MyProvider))
947979
948980```
949981Agent (config-driven)
950- ├── CommandRegistry (slash commands: /help, /cost, /model, /clear, ...)
982+ ├── CommandRegistry (slash commands: /help, /model, /loop, /cron-list, /cron-cancel, ...)
983+ │ └── CronScheduler (session-scoped recurring prompts, lazy-start background ticker)
951984 └── AgentSession (workspace-bound)
952985 ├── AgentLoop (core execution engine)
953986 │ ├── ToolExecutor (13 built-in tools, batch parallel execution)
@@ -1082,6 +1115,10 @@ let id = session.session_id();
10821115// Slash commands
10831116session . register_command (Arc :: new (MyCommand ));
10841117let registry = session . command_registry ();
1118+ for (name , desc , usage ) in registry . list_full () { ... }
1119+
1120+ // Scheduled tasks (programmatic)
1121+ // (Use /loop, /cron-list, /cron-cancel slash commands from send() — or via SDK:)
10851122
10861123// Skills (dynamic load by name — must be a built-in or loaded from skill_dirs)
10871124session . load_skill (" delegate-task" );
@@ -1220,9 +1257,24 @@ result = session.tool("git_worktree", {"command": "list"})
12201257session.remember_success(" task" , [" tool" ], " result" )
12211258items = session.recall_similar(" auth" , 5 )
12221259
1260+ # Slash commands
1261+ commands = session.list_commands() # list[dict] — name, description, usage
1262+ session.register_command(" status" , " Show session status" ,
1263+ lambda args , ctx : f " Model: { ctx[' model' ]} , History: { ctx[' history_len' ]} msgs " )
1264+ result = session.send(" /status" )
1265+
12231266# Hooks
12241267session.register_hook(" audit" , " pre_tool_use" , handler_fn)
12251268
1269+ # Scheduled tasks (programmatic)
1270+ task_id = session.schedule_task(" check deployment status" , 30 ) # every 30s
1271+ tasks = session.list_scheduled_tasks() # list[dict] — id, prompt, interval_secs, fire_count, next_fire_in_secs
1272+ ok = session.cancel_scheduled_task(task_id) # True
1273+ # Also via slash commands:
1274+ session.send(" /loop 5m summarize recent commits" )
1275+ session.send(" /cron-list" )
1276+ session.send(f " /cron-cancel { task_id} " )
1277+
12261278# MCP management
12271279count = session.add_mcp_server(" filesystem" , command = " npx" , args = [" -y" , " @modelcontextprotocol/server-filesystem" , " /tmp" ])
12281280status = session.mcp_status() # {name: {connected, tool_count, error}}
@@ -1313,6 +1365,18 @@ const items = await session.recallSimilar('auth', 5);
13131365// Hooks
13141366session .registerHook (' audit' , ' pre_tool_use' , handlerFn );
13151367
1368+ // Slash commands
1369+ const commands = session .listCommands (); // CommandInfo[]
1370+
1371+ // Scheduled tasks (programmatic)
1372+ const taskId = session .scheduleTask (' check deployment status' , 30 ); // every 30s
1373+ const tasks = session .listScheduledTasks (); // ScheduledTaskInfo[]
1374+ const ok = session .cancelScheduledTask (taskId ); // boolean
1375+ // Also via slash commands:
1376+ await session .send (' /loop 5m summarize recent commits' );
1377+ await session .send (' /cron-list' );
1378+ await session .send (` /cron-cancel ${taskId } ` );
1379+
13161380// MCP management
13171381const count = await session .addMcpServer (' filesystem' , ' stdio' , ' npx' , [' -y' , ' @modelcontextprotocol/server-filesystem' , ' /tmp' ]);
13181382const status = await session .mcpStatus (); // McpServerStatusEntry[]
@@ -1384,6 +1448,8 @@ cargo run --example 02_streaming
13841448| Node.js | ` sdk/node/examples/test_run_team_kimi.ts ` | Orchestrator.runTeam() with AgentSlot array (Lead/Worker/Reviewer) |
13851449| Node.js | ` sdk/node/examples/test_run_team_tool.ts ` | ` run_team ` built-in tool via session.tool() + LLM-driven |
13861450| Node.js | ` sdk/node/examples/test_run_team_tool_kimi.ts ` | ` run_team ` tool smoke test with external LLM |
1451+ | Python | ` sdk/python/examples/test_loop_commands.py ` | Slash commands: /loop, /cron-list, /cron-cancel, list_commands, register_command, schedule_task |
1452+ | Node.js | ` sdk/node/examples/test_loop_commands.ts ` | Slash commands: /loop, /cron-list, /cron-cancel, listCommands, scheduleTask |
13871453
13881454### Integration & Feature Tests
13891455
@@ -1412,7 +1478,7 @@ cargo test # All tests
14121478cargo test --lib # Unit tests only
14131479```
14141480
1415- ** Test Coverage:** 1458 tests, 100% pass rate
1481+ ** Test Coverage:** 1500 tests, 100% pass rate
14161482
14171483---
14181484
0 commit comments