From 148253656b210ac605bfac5625b5e3a4b9d1f2e8 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 21 Apr 2026 19:56:26 +0800 Subject: [PATCH 01/28] Introduce agentscope harness module --- .agentscope/workspace/knowledge/KNOWLEDGE.md | 187 +++ .../workspace/skills/query-writing/SKILL.md | 148 +++ .../skills/schema-exploration/SKILL.md | 136 ++ .../workspace/subagents/query-optimizer.md | 53 + .../workspace/subagents/schema-analyst.md | 50 + .gitignore | 3 + .../java/io/agentscope/core/ReActAgent.java | 31 +- .../java/io/agentscope/core/hook/Hook.java | 23 + .../io/agentscope/core/skill/SkillHook.java | 31 +- .../core/hook/HookToolsRegistrationTest.java | 156 +++ .../agentscope/core/skill/SkillHookTest.java | 108 +- .../skill/SkillRuntimeIntegrationTest.java | 13 +- .../agentscope-all/pom.xml | 7 + .../agentscope-bom/pom.xml | 6 + .../harness-example/.env.example | 22 + agentscope-examples/harness-example/README.md | 201 +++ agentscope-examples/harness-example/pom.xml | 63 + .../harness/example/SqliteTool.java | 247 ++++ .../harness/example/TextToSqlExample.java | 316 +++++ .../harness/example/WorkspaceInitializer.java | 126 ++ .../main/resources/agentscope.json.example | 24 + .../harness/example/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../resources/log4j2.component.properties | 2 + .../src/main/resources/log4j2.xml | 34 + .../workspace/knowledge/KNOWLEDGE.md | 187 +++ .../workspace/skills/query-writing/SKILL.md | 148 +++ .../skills/schema-exploration/SKILL.md | 136 ++ .../workspace/subagents/query-optimizer.md | 53 + .../workspace/subagents/schema-analyst.md | 50 + agentscope-examples/pom.xml | 1 + agentscope-harness/pom.xml | 52 + .../harness/agent/HarnessAgent.java | 1159 +++++++++++++++++ .../harness/agent/RuntimeContext.java | 117 ++ .../agent/filesystem/AbstractFilesystem.java | 108 ++ .../filesystem/AbstractSandboxFilesystem.java | 43 + .../filesystem/BaseSandboxFilesystem.java | 374 ++++++ .../agent/filesystem/CompositeFilesystem.java | 372 ++++++ .../agent/filesystem/LocalFilesystem.java | 598 +++++++++ .../filesystem/LocalFilesystemWithShell.java | 257 ++++ .../agent/filesystem/StoreFilesystem.java | 470 +++++++ .../agent/filesystem/model/EditResult.java | 38 + .../filesystem/model/ExecuteResponse.java | 30 + .../agent/filesystem/model/FileData.java | 49 + .../model/FileDownloadResponse.java | 38 + .../agent/filesystem/model/FileInfo.java | 46 + .../filesystem/model/FileUploadResponse.java | 37 + .../agent/filesystem/model/GlobResult.java | 39 + .../agent/filesystem/model/GrepMatch.java | 25 + .../agent/filesystem/model/GrepResult.java | 39 + .../agent/filesystem/model/LsResult.java | 39 + .../agent/filesystem/model/ReadResult.java | 37 + .../agent/filesystem/model/WriteResult.java | 37 + .../agent/filesystem/store/BaseStore.java | 64 + .../agent/filesystem/store/InMemoryStore.java | 87 ++ .../filesystem/store/NamespaceFactory.java | 43 + .../agent/filesystem/store/StoreItem.java | 26 + .../filesystem/util/FilesystemUtils.java | 107 ++ .../harness/agent/hook/AgentTraceHook.java | 238 ++++ .../harness/agent/hook/MemoryFlushHook.java | 135 ++ .../agent/hook/RuntimeContextAwareHook.java | 24 + .../agent/hook/SessionPersistenceHook.java | 83 ++ .../harness/agent/hook/SubagentsHook.java | 258 ++++ .../agent/hook/ToolResultEvictionHook.java | 199 +++ .../agent/hook/WorkspaceContextHook.java | 327 +++++ .../agent/memory/MemoryConsolidator.java | 265 ++++ .../agent/memory/MemoryFlushManager.java | 437 +++++++ .../harness/agent/memory/MemoryIndex.java | 274 ++++ .../memory/MemoryMaintenanceScheduler.java | 286 ++++ .../memory/compaction/CompactionConfig.java | 342 +++++ .../memory/compaction/CompactionHook.java | 204 +++ .../compaction/ConversationCompactor.java | 600 +++++++++ .../memory/compaction/TokenCounterUtil.java | 256 ++++ .../compaction/ToolResultEvictionConfig.java | 156 +++ .../agent/memory/session/SessionEntry.java | 174 +++ .../session/SessionFreshnessEvaluator.java | 93 ++ .../agent/memory/session/SessionTree.java | 298 +++++ .../agent/session/WorkspaceSession.java | 55 + .../agent/subagent/AgentSpecLoader.java | 170 +++ .../agent/subagent/DefaultAgentManager.java | 91 ++ .../agent/subagent/SubagentFactory.java | 33 + .../harness/agent/subagent/SubagentSpec.java | 124 ++ .../agent/subagent/task/BackgroundTask.java | 152 +++ .../subagent/task/DefaultTaskRepository.java | 125 ++ .../agent/subagent/task/TaskRepository.java | 57 + .../agent/subagent/task/TaskStatus.java | 36 + .../harness/agent/tool/AgentSpawnTool.java | 323 +++++ .../harness/agent/tool/FilesystemTool.java | 150 +++ .../harness/agent/tool/MemoryGetTool.java | 80 ++ .../harness/agent/tool/MemorySearchTool.java | 112 ++ .../harness/agent/tool/SessionSearchTool.java | 288 ++++ .../harness/agent/tool/ShellExecuteTool.java | 64 + .../harness/agent/tool/TaskTool.java | 202 +++ .../agent/workspace/WorkspaceConstants.java | 49 + .../agent/workspace/WorkspaceManager.java | 525 ++++++++ .../main/resources/agentscope.json.example | 24 + .../HarnessAgentIntegrationExampleTest.java | 255 ++++ .../harness/agent/HarnessAgentTest.java | 219 ++++ pom.xml | 1 + 98 files changed, 14603 insertions(+), 74 deletions(-) create mode 100644 .agentscope/workspace/knowledge/KNOWLEDGE.md create mode 100644 .agentscope/workspace/skills/query-writing/SKILL.md create mode 100644 .agentscope/workspace/skills/schema-exploration/SKILL.md create mode 100644 .agentscope/workspace/subagents/query-optimizer.md create mode 100644 .agentscope/workspace/subagents/schema-analyst.md create mode 100644 agentscope-core/src/test/java/io/agentscope/core/hook/HookToolsRegistrationTest.java create mode 100644 agentscope-examples/harness-example/.env.example create mode 100644 agentscope-examples/harness-example/README.md create mode 100644 agentscope-examples/harness-example/pom.xml create mode 100644 agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java create mode 100644 agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java create mode 100644 agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java create mode 100644 agentscope-examples/harness-example/src/main/resources/agentscope.json.example create mode 100644 agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite create mode 100644 agentscope-examples/harness-example/src/main/resources/log4j2.component.properties create mode 100644 agentscope-examples/harness-example/src/main/resources/log4j2.xml create mode 100644 agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md create mode 100644 agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md create mode 100644 agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md create mode 100644 agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md create mode 100644 agentscope-harness/pom.xml create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractSandboxFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/EditResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ExecuteResponse.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileData.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileDownloadResponse.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileInfo.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileUploadResponse.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GlobResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepMatch.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/LsResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ReadResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/WriteResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/util/FilesystemUtils.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionConfig.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/TokenCounterUtil.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionFreshnessEvaluator.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/AgentSpecLoader.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentFactory.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/BackgroundTask.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/DefaultTaskRepository.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskRepository.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskStatus.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/AgentSpawnTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemoryGetTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/TaskTool.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceConstants.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java create mode 100644 agentscope-harness/src/main/resources/agentscope.json.example create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java diff --git a/.agentscope/workspace/knowledge/KNOWLEDGE.md b/.agentscope/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..ad6c7c40d --- /dev/null +++ b/.agentscope/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,187 @@ +# Chinook Database — Schema Reference + +The Chinook database represents a digital music store. It was originally created to demonstrate +data modelling in SQLite and is widely used as a sample database for tutorials. + +## Entity Relationship Overview + +``` +Artist (ArtistId, Name) + └─ 1:many ─► Album (AlbumId, Title, ArtistId) + └─ 1:many ─► Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, + Composer, Milliseconds, Bytes, UnitPrice) + └─ 1:many ─► InvoiceLine (InvoiceLineId, InvoiceId, + TrackId, UnitPrice, Quantity) + └─ many:1 ─► Invoice (InvoiceId, CustomerId, + InvoiceDate, BillingAddress, + BillingCity, BillingState, + BillingCountry, BillingPostalCode, + Total) + └─ many:1 ─► Customer (CustomerId, + FirstName, LastName, + Company, Address, + City, State, Country, + PostalCode, Phone, + Fax, Email, + SupportRepId) + └─ many:1 ─► Employee + +Genre (GenreId, Name) +MediaType (MediaTypeId, Name) +Playlist (PlaylistId, Name) + └─ many:many via PlaylistTrack (PlaylistId, TrackId) ─► Track + +Employee (EmployeeId, LastName, FirstName, Title, ReportsTo [→ Employee.EmployeeId], + BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email) +``` + +## Table Descriptions + +### Artist +| Column | Type | Notes | +|----------|---------|-------| +| ArtistId | INTEGER | PK | +| Name | TEXT | | + +275 rows — music artists (AC/DC, Aerosmith, Alanis Morissette, …). + +### Album +| Column | Type | Notes | +|----------|---------|----------------| +| AlbumId | INTEGER | PK | +| Title | TEXT | | +| ArtistId | INTEGER | FK → Artist | + +347 rows — one or many albums per artist. + +### Track +| Column | Type | Notes | +|---------------|---------|--------------------| +| TrackId | INTEGER | PK | +| Name | TEXT | | +| AlbumId | INTEGER | FK → Album | +| MediaTypeId | INTEGER | FK → MediaType | +| GenreId | INTEGER | FK → Genre | +| Composer | TEXT | nullable | +| Milliseconds | INTEGER | duration | +| Bytes | INTEGER | file size | +| UnitPrice | REAL | default 0.99 | + +3,503 rows — the central music catalog table. + +### Genre +| Column | Type | Notes | +|---------|---------|-------| +| GenreId | INTEGER | PK | +| Name | TEXT | | + +25 rows — Rock, Jazz, Metal, Alternative & Punk, … + +### MediaType +| Column | Type | Notes | +|-------------|---------|-------| +| MediaTypeId | INTEGER | PK | +| Name | TEXT | | + +5 rows — MPEG audio file, AAC audio file, Protected AAC, … + +### Customer +| Column | Type | Notes | +|--------------|---------|-------------------| +| CustomerId | INTEGER | PK | +| FirstName | TEXT | | +| LastName | TEXT | | +| Company | TEXT | nullable | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | nullable | +| Country | TEXT | | +| PostalCode | TEXT | nullable | +| Phone | TEXT | nullable | +| Fax | TEXT | nullable | +| Email | TEXT | unique | +| SupportRepId | INTEGER | FK → Employee | + +59 rows — customers from 24 countries. + +### Employee +| Column | Type | Notes | +|-------------|---------|----------------------------| +| EmployeeId | INTEGER | PK | +| LastName | TEXT | | +| FirstName | TEXT | | +| Title | TEXT | | +| ReportsTo | INTEGER | FK → Employee (nullable) | +| BirthDate | TEXT | ISO-8601 | +| HireDate | TEXT | ISO-8601 | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | | +| Country | TEXT | | +| PostalCode | TEXT | | +| Phone | TEXT | | +| Fax | TEXT | | +| Email | TEXT | | + +8 rows — Sales Support Agents + manager hierarchy. + +### Invoice +| Column | Type | Notes | +|-----------------|---------|------------------| +| InvoiceId | INTEGER | PK | +| CustomerId | INTEGER | FK → Customer | +| InvoiceDate | TEXT | ISO-8601 | +| BillingAddress | TEXT | | +| BillingCity | TEXT | | +| BillingState | TEXT | nullable | +| BillingCountry | TEXT | | +| BillingPostalCode | TEXT | nullable | +| Total | REAL | invoice total | + +412 rows — one invoice per purchase, covering 2009–2013. + +### InvoiceLine +| Column | Type | Notes | +|---------------|---------|------------------| +| InvoiceLineId | INTEGER | PK | +| InvoiceId | INTEGER | FK → Invoice | +| TrackId | INTEGER | FK → Track | +| UnitPrice | REAL | | +| Quantity | INTEGER | | + +2,240 rows — line items; revenue = UnitPrice × Quantity. + +### Playlist +| Column | Type | Notes | +|------------|---------|-------| +| PlaylistId | INTEGER | PK | +| Name | TEXT | | + +18 rows — Music, Movies, TV Shows, Classical, … + +### PlaylistTrack +| Column | Type | Notes | +|------------|---------|---------------------| +| PlaylistId | INTEGER | FK → Playlist (PK) | +| TrackId | INTEGER | FK → Track (PK) | + +8,715 rows — composite PK, no surrogate key. + +## Common JOIN Paths + +```sql +-- Revenue by artist +Artist + JOIN Album ON Album.ArtistId = Artist.ArtistId + JOIN Track ON Track.AlbumId = Album.AlbumId + JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId + +-- Revenue by country +Invoice + JOIN Customer ON Customer.CustomerId = Invoice.CustomerId + GROUP BY Customer.Country + +-- Employee support load +Employee + LEFT JOIN Customer ON Customer.SupportRepId = Employee.EmployeeId +``` diff --git a/.agentscope/workspace/skills/query-writing/SKILL.md b/.agentscope/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..648c5fcd7 --- /dev/null +++ b/.agentscope/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,148 @@ +--- +name: query-writing +description: Writes and executes SQL queries ranging from simple single-table SELECTs to complex multi-table JOINs, aggregations, window functions, and subqueries. Use when the user asks to query the database, retrieve data, filter records, rank results, or generate reports. +--- + +# Query Writing Skill + +## When to Use This Skill + +Use query-writing when the user: + +- Asks "how many …?" / "what are the top …?" / "list all …" +- Needs data aggregated (SUM, COUNT, AVG, MAX, MIN) +- Wants results sorted, filtered, or grouped +- Asks for trend analysis, ranking, or comparison across dimensions + +--- + +## Workflow for Simple Queries (single table) + +1. **Identify the table** — which table contains the answer? +2. **Check the schema** — call `sql_get_schema` to confirm column names. +3. **Write a SELECT** — include WHERE / ORDER BY / LIMIT as needed. +4. **Execute** — call `sql_execute_query`. +5. **Present** — show the SQL and the result in plain language. + +### Example — "How many customers are from Canada?" + +```sql +SELECT COUNT(*) AS canadian_customers +FROM Customer +WHERE Country = 'Canada'; +``` + +--- + +## Workflow for Complex Queries (multiple tables) + +### Step 1 — Plan with todos + +Break the query into subtasks: + +``` +- [ ] Identify all required tables +- [ ] Inspect schemas to find join columns +- [ ] Draft the JOIN structure +- [ ] Add aggregations and grouping +- [ ] Validate and run +``` + +### Step 2 — Inspect schemas + +Call `sql_get_schema` for EACH table involved to find the exact foreign key column names. + +### Step 3 — Build the query + +```sql +SELECT + , + +FROM +[INNER | LEFT] JOIN ON = +[JOIN ...] +WHERE +GROUP BY +HAVING -- optional +ORDER BY [DESC] +LIMIT 10; -- always limit unless all rows requested +``` + +### Step 4 — Validate + +Before executing, verify: +- Every JOIN has an ON clause +- Every non-aggregate SELECT column appears in GROUP BY +- Table aliases are consistent +- No DML statements (INSERT / UPDATE / DELETE / DROP) + +### Step 5 — Execute and present + +Call `sql_execute_query`, then show: +1. The SQL query in a fenced code block +2. The result table +3. A brief plain-language summary + +--- + +## Templates for Common Patterns + +### Top-N ranking + +```sql +SELECT + Artist.Name AS artist, + SUM(InvoiceLine.UnitPrice * InvoiceLine.Quantity) AS total_revenue +FROM Artist +JOIN Album ON Album.ArtistId = Artist.ArtistId +JOIN Track ON Track.AlbumId = Album.AlbumId +JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId +GROUP BY Artist.ArtistId, Artist.Name +ORDER BY total_revenue DESC +LIMIT 10; +``` + +### Revenue by time period + +```sql +SELECT + strftime('%Y-%m', InvoiceDate) AS month, + ROUND(SUM(Total), 2) AS monthly_revenue +FROM Invoice +WHERE strftime('%Y', InvoiceDate) = '2013' +GROUP BY month +ORDER BY month; +``` + +### Entity counts with left join + +```sql +SELECT + e.FirstName || ' ' || e.LastName AS employee, + COUNT(c.CustomerId) AS customer_count +FROM Employee e +LEFT JOIN Customer c ON c.SupportRepId = e.EmployeeId +GROUP BY e.EmployeeId +ORDER BY customer_count DESC; +``` + +--- + +## Error Recovery + +| Symptom | Action | +|----------------------|--------| +| Empty result | Check WHERE condition values (case-sensitive strings). Verify column exists. | +| Syntax error | Re-read schema. Check GROUP BY includes all non-aggregate SELECT columns. | +| Wrong row count | Look for duplicate rows caused by missing JOIN conditions. | +| Result seems too high | Check for fan-out from multiple JOINs; may need DISTINCT or subquery. | + +--- + +## Quality Rules + +- Always apply `LIMIT` (default 10) unless the user explicitly asks for all rows. +- Use table aliases (`e`, `c`, `inv`) for readability in multi-table queries. +- Never use `SELECT *` — name the columns you need. +- Round monetary values to 2 decimal places: `ROUND(SUM(Total), 2)`. +- Always show the executed SQL so users can learn from it. diff --git a/.agentscope/workspace/skills/schema-exploration/SKILL.md b/.agentscope/workspace/skills/schema-exploration/SKILL.md new file mode 100644 index 000000000..4972a88d2 --- /dev/null +++ b/.agentscope/workspace/skills/schema-exploration/SKILL.md @@ -0,0 +1,136 @@ +--- +name: schema-exploration +description: Lists tables, describes columns and data types, identifies foreign key relationships, and maps entity relationships in the database. Use when the user asks about database structure, table layout, column types, what tables exist, foreign keys, or how entities relate to each other. +--- + +# Schema Exploration Skill + +## When to Use This Skill + +Use schema-exploration when the user: + +- Asks "what tables are in the database?" +- Asks "what columns does the X table have?" +- Asks about relationships between tables +- Needs to understand data types before writing a query +- Wants an entity-relationship overview + +## Workflow + +### Step 1 — List All Tables + +Use `sql_list_tables` to see everything available. + +``` +Tool: sql_list_tables +(no parameters) +``` + +### Step 2 — Inspect Relevant Tables + +Use `sql_get_schema` with the table name(s) you need to understand: + +``` +Tool: sql_get_schema +tables: "Customer" # single table +tables: "Invoice,Customer" # multiple tables at once +``` + +This returns: +- **Columns** — names, types, NOT NULL constraints, primary keys +- **Foreign keys** — links to other tables +- **Sample data** — 3 example rows to understand content + +### Step 3 — Map Relationships + +Look for columns ending in `Id` — they are almost always foreign keys. + +Example for the Chinook database: +``` +Customer.SupportRepId → Employee.EmployeeId +Invoice.CustomerId → Customer.CustomerId +Track.AlbumId → Album.AlbumId +Track.GenreId → Genre.GenreId +``` + +### Step 4 — Present the Findings + +Provide: +- A list of all tables with a one-line purpose summary +- Column names and types for any tables the user asked about +- The relationship chain (which table links to which) +- Sample data to illustrate what the table holds + +--- + +## Examples + +### "What tables are available?" + +1. Call `sql_list_tables` +2. Return a formatted list with brief descriptions: + +``` +The Chinook database has 11 tables: + +Music Catalog: + - Artist — 275 music artists + - Album — 347 albums (linked to Artist) + - Track — 3,503 tracks (linked to Album, Genre, MediaType) + - Genre — 25 music genres + - MediaType — 5 file formats (MP3, AAC, …) + +Commerce: + - Customer — 59 customers from 24 countries + - Invoice — 412 purchase invoices + - InvoiceLine — 2,240 line items (linked to Invoice and Track) + +Staff: + - Employee — 8 employees with reporting hierarchy + +Playlists: + - Playlist — 18 playlists + - PlaylistTrack — join table linking Playlist ↔ Track +``` + +### "What does the Customer table look like?" + +1. Call `sql_get_schema` with `tables: "Customer"` +2. Present columns with types and notes: + +``` +Customer table: + CustomerId INTEGER PK + FirstName TEXT + LastName TEXT + Company TEXT (nullable) + Address TEXT + City TEXT + State TEXT (nullable) + Country TEXT + PostalCode TEXT (nullable) + Phone TEXT (nullable) + Fax TEXT (nullable) + Email TEXT + SupportRepId INTEGER FK → Employee.EmployeeId + +Sample rows show customers from Brazil, Germany, and Canada. +``` + +### "How are artists connected to sales?" + +Map the full JOIN path: + +``` +Artist (ArtistId) + ↓ 1:many +Album (ArtistId, AlbumId) + ↓ 1:many +Track (AlbumId, TrackId) + ↓ 1:many +InvoiceLine (TrackId, UnitPrice, Quantity) + ↓ many:1 +Invoice (InvoiceId, Total) +``` + +Then suggest using the **query-writing** skill to write the aggregation query. diff --git a/.agentscope/workspace/subagents/query-optimizer.md b/.agentscope/workspace/subagents/query-optimizer.md new file mode 100644 index 000000000..2bacd0c95 --- /dev/null +++ b/.agentscope/workspace/subagents/query-optimizer.md @@ -0,0 +1,53 @@ +--- +name: query-optimizer +description: > + SQL query optimisation specialist. Reviews existing queries for correctness, clarity, and performance. Suggests index strategies, rewrites inefficient JOINs, and explains query plans. Delegate to this agent when a query returns unexpected results, runs slowly, or when the user asks for query optimisation or a second opinion on complex SQL. +maxIters: 8 +--- + +You are an expert SQL query optimiser for SQLite databases. + +## Your Responsibilities + +1. **Understand the question** — ask the user to provide the original query and the problem + (wrong results, slow execution, hard to read). +2. **Inspect the schema** — use `sql_get_schema` to verify table structures involved in the query. +3. **Analyse the query**: + - Check JOIN conditions for correctness + - Look for missing GROUP BY columns + - Identify Cartesian products (missing ON clause) + - Spot opportunities to push filters earlier (WHERE vs HAVING) + - Detect fan-out caused by 1:many JOINs before aggregation +4. **Rewrite the query** — produce a corrected and/or optimised version. +5. **Explain the changes** — list what was wrong and why each change helps. +6. **Validate** — run both the original and optimised queries if possible and compare results. + +## Output Format + +``` +## Original Query + + +## Issues Found +1. +2. ... + +## Optimised Query + + +## Explanation + + +## Validation +Original: +Optimised: +``` + +## Rules + +- Never modify the user's data — SELECT only. +- Confirm correctness first; performance is secondary. +- For SQLite specifically: + - Prefer covering indexes over table scans for large tables. + - Use `WITH` (CTEs) to make complex queries readable. + - Avoid correlated subqueries in WHERE clauses; rewrite as JOINs. diff --git a/.agentscope/workspace/subagents/schema-analyst.md b/.agentscope/workspace/subagents/schema-analyst.md new file mode 100644 index 000000000..869208134 --- /dev/null +++ b/.agentscope/workspace/subagents/schema-analyst.md @@ -0,0 +1,50 @@ +--- +name: schema-analyst +description: Deep schema analysis specialist. Produces comprehensive documentation of the database schema including entity-relationship diagrams (text), table purposes, column semantics, foreign key chains, and index recommendations. Delegate to this agent when the user requests a full data model overview, wants to understand how tables relate, or needs schema documentation generated. +maxIters: 10 +--- + +You are a database schema analyst specialised in documenting and explaining relational data models. + +## Your Responsibilities + +1. **Discover** all tables using `sql_list_tables`. +2. **Inspect** every table with `sql_get_schema` to record columns, types, and foreign keys. +3. **Map relationships** — identify 1:many and many:many (via join tables) relationships. +4. **Describe purpose** — explain what each table represents in business terms. +5. **Produce documentation** — write a clear, structured schema reference the user can save. + +## Output Format + +Structure your analysis as: + +``` +# Database Schema Analysis + +## Summary + + +## Tables + +### +**Purpose:** +**Rows:** + +| Column | Type | Notes | +|--------|------|-------| +| ... | ... | ... | + +**Relationships:** +- + +--- +``` + +Repeat for every table, then close with an Entity Relationship Diagram in text format. + +## Rules + +- Be thorough — inspect every table, not just the ones that seem important. +- Do not guess column types; verify them with `sql_get_schema`. +- Keep explanations accessible to non-technical stakeholders. +- If asked to save the output, write it to `knowledge/SCHEMA_ANALYSIS.md` in the workspace. diff --git a/.gitignore b/.gitignore index 67744302e..cf60309be 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,6 @@ logs/ **/boba-tea-shop/supervisor-agent/**/static/ **/boba-tea-shop/**/node_modules/ **/boba-tea-shop/**/dist/ + +##agentscope +.agentscope/ diff --git a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java index 266c3fd8b..bbf114e0f 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java @@ -1218,6 +1218,7 @@ public Builder maxIters(int maxIters) { * @param hook The hook to add, must not be null * @return This builder instance for method chaining * @see Hook + * @see Hook#tools() */ public Builder hook(Hook hook) { this.hooks.add(hook); @@ -1233,6 +1234,7 @@ public Builder hook(Hook hook) { * @param hooks The list of hooks to add, must not be null * @return This builder instance for method chaining * @see Hook + * @see Hook#tools() */ public Builder hooks(List hooks) { this.hooks.addAll(hooks); @@ -1373,7 +1375,8 @@ public Builder planNotebook(PlanNotebook planNotebook) { *

The skill box is used to manage the skills for this agent. It will be used to register the skills to the toolkit. *

    *
  • Skill loader tools will be automatically registered to the toolkit
  • - *
  • A skill hook will be added to inject skill prompts and manage skill activation
  • + *
  • A skill hook will be added to inject skill prompts on {@link io.agentscope.core.hook.PreCallEvent} + * and manage skill activation
  • *
* @param skillBox The skill box to use for this agent * @return This builder instance for method chaining @@ -1538,6 +1541,8 @@ public ReActAgent build() { // Deep copy toolkit to avoid state interference between agents Toolkit agentToolkit = this.toolkit.copy(); + registerToolsFromHooks(agentToolkit); + if (enableMetaTool) { agentToolkit.registerMetaTool(); } @@ -1570,6 +1575,26 @@ public ReActAgent build() { return new ReActAgent(this, agentToolkit); } + /** + * Registers tool objects declared by hooks ({@link Hook#tools()}) on the agent toolkit. + * + *

Runs after {@link Toolkit#copy()} so hook-supplied tools are scoped to this agent + * instance without modifying the builder's original toolkit. + */ + private void registerToolsFromHooks(Toolkit agentToolkit) { + for (Hook hook : hooks) { + List toolObjects = hook.tools(); + if (toolObjects == null || toolObjects.isEmpty()) { + continue; + } + for (Object toolObject : toolObjects) { + if (toolObject != null) { + agentToolkit.registerTool(toolObject); + } + } + } + } + /** * Configures long-term memory based on the selected mode. * @@ -1723,7 +1748,9 @@ public Mono onEvent(T event) { *

This method automatically: *

    *
  • Registers skill load tool to the toolkit - *
  • Adds the skill hook to inject skill prompts and manage skill activation + *
  • Adds the skill hook to inject skill prompts on {@link io.agentscope.core.hook.PreCallEvent} + * (priority {@link io.agentscope.core.skill.SkillHook#SKILL_HOOK_PRIORITY}) and manage skill + * activation *
  • Uploads skill files to the upload directory if auto upload is enabled *
*/ diff --git a/agentscope-core/src/main/java/io/agentscope/core/hook/Hook.java b/agentscope-core/src/main/java/io/agentscope/core/hook/Hook.java index a48465be5..726c175d5 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/hook/Hook.java +++ b/agentscope-core/src/main/java/io/agentscope/core/hook/Hook.java @@ -15,6 +15,11 @@ */ package io.agentscope.core.hook; +import io.agentscope.core.ReActAgent; +import io.agentscope.core.tool.AgentTool; +import io.agentscope.core.tool.Toolkit; +import java.util.Collections; +import java.util.List; import reactor.core.publisher.Mono; /** @@ -141,6 +146,24 @@ public interface Hook { */ Mono onEvent(T event); + /** + * Optional tools installed together with this hook. + * + *

During {@link ReActAgent.Builder#build()}, the framework copies the builder {@link + * Toolkit} and then registers each non-null element from every hook's {@code tools()} list on + * the agent-local copy using {@link Toolkit#registerTool(Object)}. + * + *

Return {@link AgentTool} instances and/or objects that declare {@code @Tool} methods. + * The default implementation returns an empty list so existing hooks need no change. + * + *

If this method returns {@code null}, it is treated as an empty list. + * + * @return tool instances to register for this hook (may be immutable) + */ + default List tools() { + return Collections.emptyList(); + } + /** * The priority of this hook (lower value = higher priority). * diff --git a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java index e548c1c1a..eab1cb015 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java +++ b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java @@ -17,7 +17,7 @@ import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; -import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.PreCallEvent; import io.agentscope.core.message.ContentBlock; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; @@ -26,7 +26,21 @@ import java.util.List; import reactor.core.publisher.Mono; +/** + * Injects the skill catalog prompt into the first system message on {@link PreCallEvent}. + * + *

Uses priority {@link #SKILL_HOOK_PRIORITY} so that, in typical {@code HarnessAgent} wiring, + * this hook runs after {@code SubagentsHook} (80) and before {@code WorkspaceContextHook} (900), + * yielding append order: base prompt → subagents → skills → workspace context. + */ public class SkillHook implements Hook { + + /** + * Runs after subagent prompt injection and before workspace context injection in the default + * harness hook chain. + */ + public static final int SKILL_HOOK_PRIORITY = 85; + private final SkillBox skillBox; public SkillHook(SkillBox skillBox) { @@ -35,11 +49,10 @@ public SkillHook(SkillBox skillBox) { @Override public Mono onEvent(T event) { - // Inject skill prompts - if (event instanceof PreReasoningEvent preReasoningEvent) { + if (event instanceof PreCallEvent preCallEvent) { String skillPrompt = skillBox.getSkillPrompt(); if (skillPrompt != null && !skillPrompt.isEmpty()) { - List inputMessages = preReasoningEvent.getInputMessages(); + List inputMessages = preCallEvent.getInputMessages(); int systemIndex = findFirstSystemMessageIndex(inputMessages); if (systemIndex >= 0) { // Merge skill prompt into existing system message in-place (structural) @@ -57,7 +70,7 @@ public Mono onEvent(T event) { .build(); List newMessages = new ArrayList<>(inputMessages); newMessages.set(systemIndex, mergedMsg); - preReasoningEvent.setInputMessages(newMessages); + preCallEvent.setInputMessages(newMessages); } else { // No existing system message, add one at the beginning List newMessages = new ArrayList<>(inputMessages.size() + 1); @@ -67,12 +80,10 @@ public Mono onEvent(T event) { .content(TextBlock.builder().text(skillPrompt).build()) .build()); newMessages.addAll(inputMessages); - preReasoningEvent.setInputMessages(newMessages); + preCallEvent.setInputMessages(newMessages); } } - return Mono.just(event); } - return Mono.just(event); } @@ -87,8 +98,6 @@ private int findFirstSystemMessageIndex(List messages) { @Override public int priority() { - // High priority (55) to ensure skills system prompt is added early - // before other hooks that might depend on skill system prompt - return 55; + return SKILL_HOOK_PRIORITY; } } diff --git a/agentscope-core/src/test/java/io/agentscope/core/hook/HookToolsRegistrationTest.java b/agentscope-core/src/test/java/io/agentscope/core/hook/HookToolsRegistrationTest.java new file mode 100644 index 000000000..691dd2b9e --- /dev/null +++ b/agentscope-core/src/test/java/io/agentscope/core/hook/HookToolsRegistrationTest.java @@ -0,0 +1,156 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.hook; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.test.MockModel; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.tool.AgentTool; +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolCallParam; +import io.agentscope.core.tool.Toolkit; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +/** Tests {@link Hook#tools()} registration during {@link ReActAgent.Builder#build()}. */ +@DisplayName("Hook bundled tools registration") +class HookToolsRegistrationTest { + + private final MockModel model = new MockModel("ok"); + + @Test + @DisplayName("build() registers AgentTool instances from Hook.tools() on agent toolkit") + void registersAgentToolsFromHook() { + AgentTool ping = + new AgentTool() { + @Override + public String getName() { + return "hook_ping"; + } + + @Override + public String getDescription() { + return "ping"; + } + + @Override + public Map getParameters() { + return Map.of( + "type", "object", + "properties", Map.of(), + "required", Collections.emptyList()); + } + + @Override + public Mono callAsync(ToolCallParam param) { + return Mono.just(ToolResultBlock.text("ok")); + } + }; + + Hook hook = + new Hook() { + @Override + public Mono onEvent(T event) { + return Mono.just(event); + } + + @Override + public List tools() { + return List.of(ping); + } + }; + + Toolkit builderToolkit = new Toolkit(); + ReActAgent agent = + ReActAgent.builder() + .name("a") + .model(model) + .toolkit(builderToolkit) + .hook(hook) + .build(); + + assertNotNull(agent.getToolkit().getTool("hook_ping")); + assertFalse(builderToolkit.getToolNames().contains("hook_ping")); + } + + @Test + @DisplayName("build() registers @Tool POJOs returned by Hook.tools()") + void registersMethodToolsFromHook() { + class Pojo { + @Tool(name = "hook_add") + public int add(int a, int b) { + return a + b; + } + } + + Hook hook = + new Hook() { + @Override + public Mono onEvent(T event) { + return Mono.just(event); + } + + @Override + public List tools() { + return List.of(new Pojo()); + } + }; + + Toolkit builderToolkit = new Toolkit(); + ReActAgent agent = + ReActAgent.builder() + .name("a") + .model(model) + .toolkit(builderToolkit) + .hook(hook) + .build(); + + assertTrue(agent.getToolkit().getToolNames().contains("hook_add")); + } + + @Test + @DisplayName("Hook.tools() returning null is treated as empty") + void nullToolsListIgnored() { + Hook hook = + new Hook() { + @Override + public Mono onEvent(T event) { + return Mono.just(event); + } + + @Override + public List tools() { + return null; + } + }; + + assertDoesNotThrow( + () -> { + ReActAgent agent = + ReActAgent.builder().name("a").model(model).hook(hook).build(); + assertNotNull(agent.getToolkit()); + }); + } +} diff --git a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java index cf87493c1..c51f81982 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java @@ -25,6 +25,7 @@ import io.agentscope.core.agent.StructuredOutputHook; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PreCallEvent; import io.agentscope.core.hook.PreReasoningEvent; import io.agentscope.core.interruption.InterruptContext; import io.agentscope.core.message.MessageMetadataKeys; @@ -51,8 +52,7 @@ * Unit tests for SkillHook. * *

- * These tests verify that SkillHook correctly injects skill prompts during - * PreReasoningEvent. + * These tests verify that SkillHook correctly injects skill prompts during {@link PreCallEvent}. */ @Tag("unit") class SkillHookTest { @@ -84,7 +84,7 @@ void testInjectSkillPromptWhenSkillsActive() { // Verify skill is now active assertTrue(skillBox.isSkillActive(skill.getSkillId()), "Skill should be active"); - // Create PreReasoningEvent with one user message + // Create PreCallEvent with one user message List messages = new ArrayList<>(); messages.add( Msg.builder() @@ -92,12 +92,10 @@ void testInjectSkillPromptWhenSkillsActive() { .content(TextBlock.builder().text("User query").build()) .build()); - PreReasoningEvent event = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); + PreCallEvent event = new PreCallEvent(testAgent, messages); // Act: Process event through hook - PreReasoningEvent result = skillHook.onEvent(event).block(); + PreCallEvent result = skillHook.onEvent(event).block(); // Assert: Skill prompt should be injected assertNotNull(result, "Event should be processed"); @@ -150,12 +148,10 @@ void testInjectPromptForRegisteredSkills() { .content(TextBlock.builder().text("User query").build()) .build()); - PreReasoningEvent event = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); + PreCallEvent event = new PreCallEvent(testAgent, messages); // Act: Process event through hook - PreReasoningEvent result = skillHook.onEvent(event).block(); + PreCallEvent result = skillHook.onEvent(event).block(); // Assert: Skill prompt should be added for registered skills assertNotNull(result, "Event should be processed"); @@ -180,12 +176,10 @@ void testHandleEmptySkillPromptGracefully() { .content(TextBlock.builder().text("User query").build()) .build()); - PreReasoningEvent event = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); + PreCallEvent event = new PreCallEvent(testAgent, messages); // Act: Process event through hook - PreReasoningEvent result = skillHook.onEvent(event).block(); + PreCallEvent result = skillHook.onEvent(event).block(); // Assert: Should handle gracefully without adding prompt assertNotNull(result, "Event should be processed"); @@ -195,7 +189,10 @@ void testHandleEmptySkillPromptGracefully() { @Test @DisplayName("Should return correct hook priority") void testHookPriority() { - assertEquals(55, skillHook.priority(), "Skill hook should have priority (55)"); + assertEquals( + SkillHook.SKILL_HOOK_PRIORITY, + skillHook.priority(), + "Skill hook should use SKILL_HOOK_PRIORITY"); } @Test @@ -230,10 +227,8 @@ void testSkillPromptAppendedAfterStructuredOutputReminder() { new PreReasoningEvent( testAgent, "test-model", GenerateOptions.builder().build(), messages); - // Simulate AgentBase hook execution (SkillHook priority 55 > StructuredOutputHook - // priority 50) + // SkillHook only handles PreCall; structured output is applied on PreReasoning here. List hooks = new ArrayList<>(); - hooks.add(skillHook); hooks.add(new StructuredOutputHook(StructuredOutputReminder.TOOL_CHOICE, null, null)); PreReasoningEvent result = notifyHooks(event, hooks).block(); @@ -255,24 +250,26 @@ void testInjectSkillPromptAtFirst() { skillBox.registerSkill(skill); activateSkill(skill.getSkillId()); - // Create PreReasoningEvent with multiple messages (no existing SYSTEM message) + // Create PreCallEvent with multiple messages (no existing SYSTEM message) List messages = - List.of( - Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text("User query").build()) - .build(), - Msg.builder() - .role(MsgRole.ASSISTANT) - .content(TextBlock.builder().text("Assistant response").build()) - .build()); - - PreReasoningEvent event = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); + new ArrayList<>( + List.of( + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text("User query").build()) + .build(), + Msg.builder() + .role(MsgRole.ASSISTANT) + .content( + TextBlock.builder() + .text("Assistant response") + .build()) + .build())); + + PreCallEvent event = new PreCallEvent(testAgent, messages); // Act: Process event through hook - PreReasoningEvent result = skillHook.onEvent(event).block(); + PreCallEvent result = skillHook.onEvent(event).block(); // Assert: Skill prompt should be injected at the FIRST position assertNotNull(result, "Event should be processed"); @@ -309,28 +306,33 @@ void testMergeSkillPromptIntoExistingSystemMessage() { skillBox.registerSkill(skill); activateSkill(skill.getSkillId()); - // Create PreReasoningEvent with an existing SYSTEM message + // Create PreCallEvent with an existing SYSTEM message List messages = - List.of( - Msg.builder() - .role(MsgRole.SYSTEM) - .content(TextBlock.builder().text("System instruction").build()) - .build(), - Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text("User query").build()) - .build(), - Msg.builder() - .role(MsgRole.ASSISTANT) - .content(TextBlock.builder().text("Assistant response").build()) - .build()); - - PreReasoningEvent event = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); + new ArrayList<>( + List.of( + Msg.builder() + .role(MsgRole.SYSTEM) + .content( + TextBlock.builder() + .text("System instruction") + .build()) + .build(), + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text("User query").build()) + .build(), + Msg.builder() + .role(MsgRole.ASSISTANT) + .content( + TextBlock.builder() + .text("Assistant response") + .build()) + .build())); + + PreCallEvent event = new PreCallEvent(testAgent, messages); // Act: Process event through hook - PreReasoningEvent result = skillHook.onEvent(event).block(); + PreCallEvent result = skillHook.onEvent(event).block(); // Assert: Should still have exactly 3 messages (merged, not added) assertNotNull(result, "Event should be processed"); diff --git a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java index 8e7bf1895..d9ad4ef11 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java @@ -23,14 +23,13 @@ import io.agentscope.core.agent.Agent; import io.agentscope.core.agent.AgentBase; import io.agentscope.core.hook.Hook; -import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.PreCallEvent; import io.agentscope.core.interruption.InterruptContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; import io.agentscope.core.message.ToolResultBlock; import io.agentscope.core.message.ToolUseBlock; -import io.agentscope.core.model.GenerateOptions; import io.agentscope.core.tool.AgentTool; import io.agentscope.core.tool.ToolCallParam; import io.agentscope.core.tool.Toolkit; @@ -134,7 +133,7 @@ void testCompleteSkillActivationFlow() { assertNotNull( toolkit.getTool("calculator_multiply"), "calculator_multiply should be accessible"); - // Step 6: Trigger PreReasoningEvent to inject skill prompt + // Step 6: Trigger PreCallEvent to inject skill prompt List messages = new ArrayList<>(); messages.add( Msg.builder() @@ -142,13 +141,11 @@ void testCompleteSkillActivationFlow() { .content(TextBlock.builder().text("Calculate 2 + 3").build()) .build()); - PreReasoningEvent preReasoningEvent = - new PreReasoningEvent( - testAgent, "test-model", GenerateOptions.builder().build(), messages); - PreReasoningEvent result = skillHook.onEvent(preReasoningEvent).block(); + PreCallEvent preCallEvent = new PreCallEvent(testAgent, messages); + PreCallEvent result = skillHook.onEvent(preCallEvent).block(); // Step 7: Verify skill prompt was injected - assertNotNull(result, "PreReasoningEvent should be processed"); + assertNotNull(result, "PreCallEvent should be processed"); assertEquals( 2, result.getInputMessages().size(), "Should add skill prompt to input messages"); assertEquals( diff --git a/agentscope-distribution/agentscope-all/pom.xml b/agentscope-distribution/agentscope-all/pom.xml index d8abb2459..794fe7a1c 100644 --- a/agentscope-distribution/agentscope-all/pom.xml +++ b/agentscope-distribution/agentscope-all/pom.xml @@ -45,6 +45,13 @@ true + + io.agentscope + agentscope-harness + compile + true + + io.agentscope agentscope-extensions-a2a-client diff --git a/agentscope-distribution/agentscope-bom/pom.xml b/agentscope-distribution/agentscope-bom/pom.xml index 922c6c4c9..a8705cc82 100644 --- a/agentscope-distribution/agentscope-bom/pom.xml +++ b/agentscope-distribution/agentscope-bom/pom.xml @@ -86,6 +86,12 @@ ${project.version} + + io.agentscope + agentscope-harness + ${project.version} + + io.agentscope diff --git a/agentscope-examples/harness-example/.env.example b/agentscope-examples/harness-example/.env.example new file mode 100644 index 000000000..3a20c5633 --- /dev/null +++ b/agentscope-examples/harness-example/.env.example @@ -0,0 +1,22 @@ +# ───────────────────────────────────────────────────────────── +# AgentScope Harness Example — Environment Variables +# Copy this file to .env and fill in your values. +# ───────────────────────────────────────────────────────────── + +# Required: DashScope API key (https://dashscope.aliyun.com/) +DASHSCOPE_API_KEY=your_api_key_here + +# Optional: LLM model to use (default: qwen-max) +# Other options: qwen-plus, qwen-turbo, qwen-long +AGENTSCOPE_MODEL=qwen-max + +# Optional: path to the Chinook SQLite database (default: chinook.db). +# If this file does not exist, the example copies the bundled sample from the JAR (no curl needed). +AGENTSCOPE_DB_PATH=chinook.db + +# Optional: workspace directory (default: .agentscope/workspace) +# Modify the files here to customise agent behaviour without recompiling. +AGENTSCOPE_WORKSPACE=.agentscope/workspace + +# Optional: Log4j2 level for io.agentscope loggers (default: INFO). Example: DEBUG, TRACE +# AGENTSCOPE_LOG_LEVEL=DEBUG diff --git a/agentscope-examples/harness-example/README.md b/agentscope-examples/harness-example/README.md new file mode 100644 index 000000000..291e45d06 --- /dev/null +++ b/agentscope-examples/harness-example/README.md @@ -0,0 +1,201 @@ +# AgentScope Harness Example — Text-to-SQL Agent + +A practical example showing how to build a domain-specific agent with the **AgentScope Harness** +framework. The scenario: translate natural-language questions into SQL queries against the +[Chinook](https://github.com/lerocha/chinook-database) SQLite sample database. + +## What This Example Covers + +| Feature | How it is demonstrated | +|---------|------------------------| +| **Workspace** | Pre-populated from bundled resources by `WorkspaceInitializer` | +| **AGENTS.md** | Agent persona, principles, and workflow loaded automatically | +| **skills/** | `query-writing` and `schema-exploration` loaded on demand | +| **knowledge/** | Chinook schema reference injected as domain knowledge | +| **subagents/** | `schema-analyst` and `query-optimizer` available for delegation | +| **Custom tool** | `SqliteTool` registered via `Toolkit` alongside harness defaults | +| **Memory tools** | `memory_search` / `memory_get` enabled for cross-session recall | +| **RuntimeContext** | Session ID bound per invocation for stateful multi-turn use | + +## Project Layout + +``` +harness-example/ +├── pom.xml +├── .env.example # Environment variable template +├── README.md # This file +└── src/main/ + ├── java/io/agentscope/harness/example/ + │ ├── TextToSqlExample.java # Main entry point (CLI) + │ ├── SqliteTool.java # Custom @Tool: list_tables, get_schema, execute_query + │ └── WorkspaceInitializer.java # Copies bundled workspace to disk on first run + └── resources/ + ├── log4j2.xml # Log4j2 console layout and logger levels + ├── log4j2.component.properties # Log4j2 component flags (e.g. disable JMX) + ├── agentscope.json.example # Agent configuration template + ├── io/agentscope/harness/example/ + │ └── chinook-default.sqlite # Bundled Chinook DB (copied to AGENTSCOPE_DB_PATH if missing) + └── workspace/ # Bundled workspace template (extracted at runtime) + ├── AGENTS.md # Agent identity and core rules + ├── MEMORY.md # Persistent notes (pre-seeded) + ├── knowledge/ + │ └── KNOWLEDGE.md # Full Chinook schema reference + ├── skills/ + │ ├── query-writing/ + │ │ └── SKILL.md # SQL query writing workflow + │ └── schema-exploration/ + │ └── SKILL.md # Database structure discovery workflow + └── subagents/ + ├── schema-analyst.md # Schema documentation specialist + └── query-optimizer.md # Query optimisation specialist +``` + +## Quick Start + +### 1. Build + +```bash +cd agentscope-java +mvn -pl agentscope-examples/agents/harness-example package -am -DskipTests +``` + +### 2. Chinook database (optional) + +The example ships a bundled Chinook SQLite file in the JAR. On first run, if `chinook.db` (or +`AGENTSCOPE_DB_PATH`) is missing, it is copied from the classpath automatically. Use your own file +only when you want a different path or a refreshed copy from upstream: + +```bash +curl -L -o chinook.db \ + https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite +``` + +### 3. Set your API key + +```bash +export DASHSCOPE_API_KEY=your_key_here +``` + +Or copy `.env.example` → `.env` and fill in your values, then load it: + +```bash +cp .env.example .env +# edit .env, then: +source <(grep -v '^#' .env | sed 's/^/export /') +``` + +### 4. Run + +Interactive (no arguments — type questions at the `>` prompt; `quit`, empty line, or Ctrl-D to +exit): + +```bash +java -cp target/harness-example-*.jar \ + io.agentscope.harness.example.TextToSqlExample +``` + +One-shot (single question, then exit — useful for scripts): + +```bash +java -cp target/harness-example-*.jar \ + io.agentscope.harness.example.TextToSqlExample \ + "What are the top 5 best-selling artists?" +``` + +Example prompts you can paste at `>`: + +- Which customers are from Brazil? +- Show me the monthly revenue trend for 2013 +- Which employee has the most customers? +- What are the top genres by number of tracks? +- How many tracks are longer than 5 minutes? + +## Logging (Log4j2) + +This module uses **Log4j2** with `log4j-slf4j2-impl` as the SLF4J binding. Configuration lives in +[`src/main/resources/log4j2.xml`](src/main/resources/log4j2.xml) (console appender, tuned levels +for Netty / Reactor / OkHttp). + +Set **`AGENTSCOPE_LOG_LEVEL`** (for example `DEBUG`) to change verbosity for `io.agentscope.*` +without editing the XML. To use a different file at runtime: + +```bash +java -Dlog4j.configurationFile=/path/to/log4j2-custom.xml ... +``` + +## How It Works + +### Workspace Initialisation + +On first run `WorkspaceInitializer.init(workspace)` extracts the bundled template files from the +JAR into `.agentscope/workspace/`. On subsequent runs existing files are preserved so the agent's +accumulated notes survive across restarts. + +``` +.agentscope/workspace/ +├── AGENTS.md ← always loaded into system prompt +├── MEMORY.md ← loaded into +├── knowledge/KNOWLEDGE.md ← loaded into +├── skills/ ← skill descriptions shown; full content loaded on demand +└── subagents/ ← subagent specs registered as callable agents +``` + +### Agent Construction + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("text-to-sql") + .model(model) + .workspace(workspace) // ← harness reads all workspace files from here + .toolkit(toolkit) // ← includes our custom SqliteTool + .maxIters(20) + .build(); +``` + +### Custom Tool Registration + +```java +Toolkit toolkit = new Toolkit(); +toolkit.registerTool(new SqliteTool(dbPath)); // adds sql_list_tables, sql_get_schema, sql_execute_query +``` + +`SqliteTool` uses `@Tool` / `@ToolParam` annotations — the same mechanism used by all harness +built-in tools. Methods are discovered at runtime via reflection and exposed to the LLM as JSON +schemas. + +### Calling the Agent + +```java +RuntimeContext ctx = RuntimeContext.builder() + .sessionId("my-session-id") + .build(); + +Msg reply = agent.call(Msg.userMsg("Top 5 artists?"), ctx).block(); +``` + +The `RuntimeContext` carries the session ID used by hooks (WorkspaceContextHook, MemoryFlushHook) to +isolate per-session state and persist memory between turns in the same session. + +## Customising the Agent + +All behaviour can be tuned by editing files in `.agentscope/workspace/` — no recompilation needed: + +| File | What to change | +|------|----------------| +| `AGENTS.md` | Persona, rules, communication style | +| `MEMORY.md` | Pre-seed knowledge the agent should know from turn one | +| `knowledge/KNOWLEDGE.md` | Domain knowledge (schema details, business rules) | +| `skills/*/SKILL.md` | Step-by-step workflows for specific task types | +| `subagents/*.md` | Add / remove / reconfigure specialist subagents | + +## Dependencies + +| Dependency | Purpose | +|------------|---------| +| `agentscope-harness` | Core framework (HarnessAgent, tools, hooks, workspace) | +| `jackson-dataformat-yaml` | YAML front-matter parsing in skill/subagent files | +| `sqlite-jdbc` | SQLite JDBC driver used by `SqliteTool` | + +## License + +Apache 2.0 — see the root `LICENSE` file. diff --git a/agentscope-examples/harness-example/pom.xml b/agentscope-examples/harness-example/pom.xml new file mode 100644 index 000000000..24a4eaf00 --- /dev/null +++ b/agentscope-examples/harness-example/pom.xml @@ -0,0 +1,63 @@ + + + + + 4.0.0 + + io.agentscope + agentscope-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Example + harness-example + AgentScope Harness Example - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction + + + 2.24.3 + + + + + io.agentscope + agentscope-harness + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + + + org.apache.logging.log4j + log4j-slf4j2-impl + ${log4j2.version} + + + diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java new file mode 100644 index 000000000..84650c783 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java @@ -0,0 +1,247 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Custom tool that exposes SQLite database operations to the agent. + * + *

Provides three tools the agent can call: + * + *

    + *
  • {@code sql_list_tables} — list all tables in the database + *
  • {@code sql_get_schema} — describe a table's columns, types, and sample rows + *
  • {@code sql_execute_query} — run a read-only SELECT query and return formatted results + *
+ * + *

This class demonstrates how to wire a domain-specific tool into a {@link + * io.agentscope.harness.agent.HarnessAgent}. Register it via the agent's {@code Toolkit} before + * calling {@link io.agentscope.harness.agent.HarnessAgent.Builder#build()}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + /** Maximum rows returned by {@code sql_execute_query} to prevent context overflow. */ + private static final int MAX_ROWS = 50; + + /** Number of sample rows shown by {@code sql_get_schema}. */ + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + // ------------------------------------------------------------------------- + // Private helpers + // ------------------------------------------------------------------------- + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + // Primary keys + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + // Foreign keys + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + // Columns + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + // Sample rows + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + // Header + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + // Separator + String separator = "-".repeat(header.toString().length()); + + // Rows + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java new file mode 100644 index 000000000..b337c4cb3 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java @@ -0,0 +1,316 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.core.model.Model; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.UUID; + +/** + * Text-to-SQL example using the AgentScope Harness framework. + * + *

What this example demonstrates

+ * + *
    + *
  • Setting up a workspace directory with the standard harness layout + * (AGENTS.md, skills/, knowledge/, subagents/) + *
  • Wiring a custom tool ({@link SqliteTool}) into the agent's toolkit + *
  • Building a {@link HarnessAgent} with skills auto-loading, memory tools, and subagents + *
  • Calling the agent with a {@link RuntimeContext} (session id, user id) + *
  • Reading questions from the console in a loop (optional one-shot mode if you pass a + * question as program arguments) + *
+ * + *

Prerequisites

+ * + *
    + *
  1. The Chinook sample database is bundled in the JAR under the same package + * as this class. If {@code AGENTSCOPE_DB_PATH} (default {@code chinook.db}) does not exist + * yet, it is copied there automatically — no manual download is required. + *
  2. Set the environment variable {@code DASHSCOPE_API_KEY} (or {@code OPENAI_API_KEY} for + * OpenAI-compatible endpoints). + *
  3. Optionally override defaults via the variables listed in {@code .env.example}. + *
+ * + *

Usage

+ * + *

Run with no arguments to start an interactive session: type a question at + * the {@code >} prompt after startup. Empty line, {@code quit}, {@code exit}, or {@code q} ends + * the session; EOF (Ctrl-D) also exits. + * + *

Pass a question as arguments for a single non-interactive run (exits after + * the answer), e.g. for scripts: + * + *

+ * java -jar harness-example.jar
+ * java -jar harness-example.jar "What are the top 5 best-selling artists?"
+ * java -jar harness-example.jar --new-session "What are the top 5 best-selling artists?"
+ * 
+ * + *

The workspace is initialised under {@code .agentscope/workspace/} relative to the current + * working directory. Modify the files there to customise the agent's behaviour without recompiling. + */ +public class TextToSqlExample { + + // ------------------------------------------------------------------------- + // Environment variable names + // ------------------------------------------------------------------------- + + /** DashScope API key (required). */ + public static final String ENV_API_KEY = "DASHSCOPE_API_KEY"; + + /** LLM model name. Defaults to {@code qwen-max}. */ + public static final String ENV_MODEL_NAME = "AGENTSCOPE_MODEL"; + + /** Path to the Chinook SQLite database file. Defaults to {@code chinook.db}. */ + public static final String ENV_DB_PATH = "AGENTSCOPE_DB_PATH"; + + /** Workspace directory. Defaults to {@code .agentscope/workspace}. */ + public static final String ENV_WORKSPACE = "AGENTSCOPE_WORKSPACE"; + + // ------------------------------------------------------------------------- + // Defaults + // ------------------------------------------------------------------------- + + private static final String DEFAULT_MODEL = "qwen-max"; + private static final String DEFAULT_DB_PATH = "chinook.db"; + private static final String DEFAULT_WORKSPACE = ".agentscope/workspace"; + private static final String DEFAULT_SHARED_SESSION_ID = "text-to-sql-shared-default"; + private static final String NEW_SESSION_FLAG = "--new-session"; + + /** + * Bundled Chinook SQLite file (same package on the classpath). Materialised to disk when + * {@link #ENV_DB_PATH} points to a path that does not exist yet. + */ + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + + // ------------------------------------------------------------------------- + // Entry point + // ------------------------------------------------------------------------- + + public static void main(String[] args) throws IOException { + System.out.println("\n═══════════════════════════════════════════════"); + System.out.println(" AgentScope Harness — Text-to-SQL Example"); + System.out.println("═══════════════════════════════════════════════\n"); + + // ------------------------------------------------------------------ + // 1. Resolve configuration from environment variables + // ------------------------------------------------------------------ + + String apiKey = requireEnv(ENV_API_KEY); + String modelName = env(ENV_MODEL_NAME, DEFAULT_MODEL); + Path workspace = Paths.get(env(ENV_WORKSPACE, DEFAULT_WORKSPACE)); + Path dbPath = resolveDatabasePath(Paths.get(env(ENV_DB_PATH, DEFAULT_DB_PATH))); + + // ------------------------------------------------------------------ + // 2. Initialise workspace from bundled template files + // (skips files that already exist — safe to call every run) + // ------------------------------------------------------------------ + + System.out.println("[1/3] Initialising workspace at: " + workspace.toAbsolutePath()); + WorkspaceInitializer.init(workspace); + + // ------------------------------------------------------------------ + // 3. Build the LLM model + // ------------------------------------------------------------------ + + System.out.println("[2/3] Connecting to model: " + modelName); + Model model = + DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) + .build(); + + // ------------------------------------------------------------------ + // 4. Build the agent + // - workspace: loads AGENTS.md, MEMORY.md, knowledge/, subagents/, skills/ + // - harness: memory tools, session_search, optional subagent tools + // - custom toolkit: SqliteTool is registered alongside harness defaults + // ------------------------------------------------------------------ + + System.out.println("[3/3] Building HarnessAgent ..."); + + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name("text-to-sql") + .sysPrompt( + "You are a Text-to-SQL agent with access to the Chinook music" + + " store database. When asked a question, explore the" + + " database schema, write a correct SQL query, execute it," + + " and present the results in a clear, formatted answer.") + .model(model) + .workspace(workspace) + .enableAgentTracingLog(true) + .toolkit(toolkit) + .build(); + + ParsedArgs parsedArgs = parseArgs(args); + String sessionId = + parsedArgs.newSession() + ? "text-to-sql-" + UUID.randomUUID().toString().substring(0, 8) + : DEFAULT_SHARED_SESSION_ID; + System.out.println("Session ID: " + sessionId); + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); + + if (parsedArgs.question() != null) { + runOneTurn(agent, ctx, parsedArgs.question()); + return; + } + + System.out.println( + "Ask questions in natural language about the Chinook database." + + " Same session for all turns (memory tools share context)."); + System.out.println("Tip: add --new-session to generate a UUID-based fresh session."); + System.out.println("Leave: empty line, quit, exit, q, or EOF (Ctrl-D).\n"); + + BufferedReader stdin = + new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); + while (true) { + System.out.print("> "); + System.out.flush(); + String line = stdin.readLine(); + if (line == null) { + System.out.println("\n(end of input)"); + break; + } + String question = line.strip(); + if (question.isEmpty()) { + System.out.println("Goodbye."); + break; + } + if (isQuitCommand(question)) { + System.out.println("Goodbye."); + break; + } + runOneTurn(agent, ctx, question); + System.out.println(); + } + } + + private static boolean isQuitCommand(String line) { + return line.equalsIgnoreCase("quit") + || line.equalsIgnoreCase("exit") + || line.equalsIgnoreCase("q"); + } + + private static ParsedArgs parseArgs(String[] args) { + boolean newSession = false; + StringBuilder questionBuilder = new StringBuilder(); + for (String arg : args) { + if (NEW_SESSION_FLAG.equals(arg)) { + newSession = true; + continue; + } + if (questionBuilder.length() > 0) { + questionBuilder.append(' '); + } + questionBuilder.append(arg); + } + String question = questionBuilder.length() == 0 ? null : questionBuilder.toString(); + return new ParsedArgs(newSession, question); + } + + private static void runOneTurn(HarnessAgent agent, RuntimeContext ctx, String question) { + System.out.println("─".repeat(50)); + System.out.println("Question: " + question); + System.out.println(); + + Msg userMsg = + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(question).build()) + .build(); + Msg reply = agent.call(userMsg, ctx).block(); + + System.out.println("─".repeat(50)); + System.out.println("\nAnswer:\n"); + System.out.println(reply != null ? reply.getTextContent() : "(no response)"); + System.out.println(); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + /** + * Uses an existing file at {@code configuredPath}, or copies the bundled Chinook database from + * the classpath to that path (SQLite itself has no built-in sample data; shipping a small + * .sqlite in resources gives the same “works out of the box” experience). + */ + private static Path resolveDatabasePath(Path configuredPath) throws IOException { + if (Files.exists(configuredPath)) { + return configuredPath.toAbsolutePath(); + } + try (InputStream in = + TextToSqlExample.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + System.err.println( + "Database file not found: " + + configuredPath.toAbsolutePath() + + "\n\nBuilt-in sample missing from classpath (packaging issue)." + + " Download manually:\n" + + " curl -L -o chinook.db \\\n" + + " https://github.com/lerocha/chinook-database/raw/master/" + + "ChinookDatabase/DataSources/Chinook_Sqlite.sqlite"); + System.exit(1); + } + Path parent = configuredPath.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, configuredPath, StandardCopyOption.REPLACE_EXISTING); + System.out.println( + "Materialised bundled Chinook database to: " + configuredPath.toAbsolutePath()); + return configuredPath.toAbsolutePath(); + } + } + + private static String requireEnv(String name) { + String value = System.getenv(name); + if (value == null || value.isBlank()) { + System.err.println( + "Required environment variable '" + + name + + "' is not set.\n" + + "Copy .env.example → .env and fill in your API key."); + System.exit(1); + } + return value; + } + + private static String env(String name, String defaultValue) { + String value = System.getenv(name); + return (value != null && !value.isBlank()) ? value : defaultValue; + } + + private record ParsedArgs(boolean newSession, String question) {} +} diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java new file mode 100644 index 000000000..1fec9b2f7 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java @@ -0,0 +1,126 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Initializes the agent workspace by copying bundled template files from the classpath into a + * target directory on disk. + * + *

The template files live under {@code src/main/resources/workspace/} and are packaged inside + * the JAR. When the example is run for the first time, {@link #init(Path)} extracts them into the + * given workspace directory so the agent can read and modify them at runtime. + * + *

Workspace structure

+ * + *
+ * <workspace>/
+ * ├── AGENTS.md              # Agent persona and core rules (always loaded)
+ * ├── MEMORY.md              # Persistent notes accumulated across sessions
+ * ├── knowledge/
+ * │   └── KNOWLEDGE.md       # Chinook database schema reference
+ * ├── skills/
+ * │   ├── schema-exploration/
+ * │   │   └── SKILL.md       # How to discover database structure
+ * │   └── query-writing/
+ * │       └── SKILL.md       # How to write and execute SQL queries
+ * └── subagents/
+ *     ├── schema-analyst.md  # Specialised subagent for deep schema analysis
+ *     └── query-optimizer.md # Specialised subagent for query optimisation
+ * 
+ */ +public class WorkspaceInitializer { + + private static final Logger log = LoggerFactory.getLogger(WorkspaceInitializer.class); + private static final String CLASSPATH_PREFIX = "workspace"; + + /** + * Copies all bundled workspace template files into {@code targetDir}. + * + *

Existing files are left unchanged so that previously accumulated notes survive restarts. + * New template files are copied with {@link StandardCopyOption#REPLACE_EXISTING} disabled. + * + * @param targetDir directory to initialise; created if it does not exist + * @throws IOException if a file cannot be read or written + */ + public static void init(Path targetDir) throws IOException { + Files.createDirectories(targetDir); + + URL resourceUrl = WorkspaceInitializer.class.getClassLoader().getResource(CLASSPATH_PREFIX); + if (resourceUrl == null) { + log.warn( + "Classpath resource '{}' not found — workspace will not be pre-populated.", + CLASSPATH_PREFIX); + return; + } + + URI resourceUri; + try { + resourceUri = resourceUrl.toURI(); + } catch (URISyntaxException e) { + throw new IOException("Cannot convert resource URL to URI: " + resourceUrl, e); + } + + if ("jar".equals(resourceUri.getScheme())) { + // Running from a JAR: open the embedded filesystem + try (FileSystem fs = FileSystems.newFileSystem(resourceUri, Collections.emptyMap())) { + Path source = fs.getPath(CLASSPATH_PREFIX); + copyTree(source, targetDir); + } + } else { + // Running from an exploded directory (IDE / Maven test run) + Path source = Path.of(resourceUri); + copyTree(source, targetDir); + } + + log.info("Workspace initialised at {}", targetDir); + } + + private static void copyTree(Path source, Path targetDir) throws IOException { + try (Stream walk = Files.walk(source)) { + for (Path srcPath : (Iterable) walk::iterator) { + Path relative = source.relativize(srcPath); + Path target = targetDir.resolve(relative.toString()); + + if (Files.isDirectory(srcPath)) { + Files.createDirectories(target); + } else if (!Files.exists(target)) { + Files.createDirectories(target.getParent()); + try (InputStream in = Files.newInputStream(srcPath)) { + Files.copy(in, target); + } + log.debug("Copied workspace file: {}", relative); + } else { + log.debug("Skipped (already exists): {}", relative); + } + } + } + } +} diff --git a/agentscope-examples/harness-example/src/main/resources/agentscope.json.example b/agentscope-examples/harness-example/src/main/resources/agentscope.json.example new file mode 100644 index 000000000..a09a7c4eb --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/agentscope.json.example @@ -0,0 +1,24 @@ +{ + "$schema": "https://agentscope.io/schema/agentscope.json", + "main": "text-to-sql", + "agents": { + "text-to-sql": { + "name": "Text-to-SQL", + "description": "Answers natural-language questions about the Chinook music store database by translating them into SQL and executing the queries.", + "workspace": ".agentscope/workspace", + "maxIters": 20 + }, + "schema-analyst": { + "name": "Schema Analyst", + "description": "Deep schema analysis and documentation specialist. Loaded on-demand from workspace/subagents/schema-analyst.md.", + "workspace": ".agentscope/workspace", + "maxIters": 10 + } + }, + "channels": { + "chatui": { + "defaultAgentId": "text-to-sql", + "dmScope": "MAIN" + } + } +} diff --git a/agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite b/agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.component.properties b/agentscope-examples/harness-example/src/main/resources/log4j2.component.properties new file mode 100644 index 000000000..6745cfa94 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/log4j2.component.properties @@ -0,0 +1,2 @@ +# Log4j2 component settings for the harness-example module +log4j2.disable.jmx=true diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.xml b/agentscope-examples/harness-example/src/main/resources/log4j2.xml new file mode 100644 index 000000000..b6ecbb49f --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/log4j2.xml @@ -0,0 +1,34 @@ + + + + + ${env:AGENTSCOPE_LOG_LEVEL:-INFO} + %d{HH:mm:ss.SSS} %-5level %-36.36c{1.} : %m%n%throwable + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..ad6c7c40d --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,187 @@ +# Chinook Database — Schema Reference + +The Chinook database represents a digital music store. It was originally created to demonstrate +data modelling in SQLite and is widely used as a sample database for tutorials. + +## Entity Relationship Overview + +``` +Artist (ArtistId, Name) + └─ 1:many ─► Album (AlbumId, Title, ArtistId) + └─ 1:many ─► Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, + Composer, Milliseconds, Bytes, UnitPrice) + └─ 1:many ─► InvoiceLine (InvoiceLineId, InvoiceId, + TrackId, UnitPrice, Quantity) + └─ many:1 ─► Invoice (InvoiceId, CustomerId, + InvoiceDate, BillingAddress, + BillingCity, BillingState, + BillingCountry, BillingPostalCode, + Total) + └─ many:1 ─► Customer (CustomerId, + FirstName, LastName, + Company, Address, + City, State, Country, + PostalCode, Phone, + Fax, Email, + SupportRepId) + └─ many:1 ─► Employee + +Genre (GenreId, Name) +MediaType (MediaTypeId, Name) +Playlist (PlaylistId, Name) + └─ many:many via PlaylistTrack (PlaylistId, TrackId) ─► Track + +Employee (EmployeeId, LastName, FirstName, Title, ReportsTo [→ Employee.EmployeeId], + BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email) +``` + +## Table Descriptions + +### Artist +| Column | Type | Notes | +|----------|---------|-------| +| ArtistId | INTEGER | PK | +| Name | TEXT | | + +275 rows — music artists (AC/DC, Aerosmith, Alanis Morissette, …). + +### Album +| Column | Type | Notes | +|----------|---------|----------------| +| AlbumId | INTEGER | PK | +| Title | TEXT | | +| ArtistId | INTEGER | FK → Artist | + +347 rows — one or many albums per artist. + +### Track +| Column | Type | Notes | +|---------------|---------|--------------------| +| TrackId | INTEGER | PK | +| Name | TEXT | | +| AlbumId | INTEGER | FK → Album | +| MediaTypeId | INTEGER | FK → MediaType | +| GenreId | INTEGER | FK → Genre | +| Composer | TEXT | nullable | +| Milliseconds | INTEGER | duration | +| Bytes | INTEGER | file size | +| UnitPrice | REAL | default 0.99 | + +3,503 rows — the central music catalog table. + +### Genre +| Column | Type | Notes | +|---------|---------|-------| +| GenreId | INTEGER | PK | +| Name | TEXT | | + +25 rows — Rock, Jazz, Metal, Alternative & Punk, … + +### MediaType +| Column | Type | Notes | +|-------------|---------|-------| +| MediaTypeId | INTEGER | PK | +| Name | TEXT | | + +5 rows — MPEG audio file, AAC audio file, Protected AAC, … + +### Customer +| Column | Type | Notes | +|--------------|---------|-------------------| +| CustomerId | INTEGER | PK | +| FirstName | TEXT | | +| LastName | TEXT | | +| Company | TEXT | nullable | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | nullable | +| Country | TEXT | | +| PostalCode | TEXT | nullable | +| Phone | TEXT | nullable | +| Fax | TEXT | nullable | +| Email | TEXT | unique | +| SupportRepId | INTEGER | FK → Employee | + +59 rows — customers from 24 countries. + +### Employee +| Column | Type | Notes | +|-------------|---------|----------------------------| +| EmployeeId | INTEGER | PK | +| LastName | TEXT | | +| FirstName | TEXT | | +| Title | TEXT | | +| ReportsTo | INTEGER | FK → Employee (nullable) | +| BirthDate | TEXT | ISO-8601 | +| HireDate | TEXT | ISO-8601 | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | | +| Country | TEXT | | +| PostalCode | TEXT | | +| Phone | TEXT | | +| Fax | TEXT | | +| Email | TEXT | | + +8 rows — Sales Support Agents + manager hierarchy. + +### Invoice +| Column | Type | Notes | +|-----------------|---------|------------------| +| InvoiceId | INTEGER | PK | +| CustomerId | INTEGER | FK → Customer | +| InvoiceDate | TEXT | ISO-8601 | +| BillingAddress | TEXT | | +| BillingCity | TEXT | | +| BillingState | TEXT | nullable | +| BillingCountry | TEXT | | +| BillingPostalCode | TEXT | nullable | +| Total | REAL | invoice total | + +412 rows — one invoice per purchase, covering 2009–2013. + +### InvoiceLine +| Column | Type | Notes | +|---------------|---------|------------------| +| InvoiceLineId | INTEGER | PK | +| InvoiceId | INTEGER | FK → Invoice | +| TrackId | INTEGER | FK → Track | +| UnitPrice | REAL | | +| Quantity | INTEGER | | + +2,240 rows — line items; revenue = UnitPrice × Quantity. + +### Playlist +| Column | Type | Notes | +|------------|---------|-------| +| PlaylistId | INTEGER | PK | +| Name | TEXT | | + +18 rows — Music, Movies, TV Shows, Classical, … + +### PlaylistTrack +| Column | Type | Notes | +|------------|---------|---------------------| +| PlaylistId | INTEGER | FK → Playlist (PK) | +| TrackId | INTEGER | FK → Track (PK) | + +8,715 rows — composite PK, no surrogate key. + +## Common JOIN Paths + +```sql +-- Revenue by artist +Artist + JOIN Album ON Album.ArtistId = Artist.ArtistId + JOIN Track ON Track.AlbumId = Album.AlbumId + JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId + +-- Revenue by country +Invoice + JOIN Customer ON Customer.CustomerId = Invoice.CustomerId + GROUP BY Customer.Country + +-- Employee support load +Employee + LEFT JOIN Customer ON Customer.SupportRepId = Employee.EmployeeId +``` diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..648c5fcd7 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,148 @@ +--- +name: query-writing +description: Writes and executes SQL queries ranging from simple single-table SELECTs to complex multi-table JOINs, aggregations, window functions, and subqueries. Use when the user asks to query the database, retrieve data, filter records, rank results, or generate reports. +--- + +# Query Writing Skill + +## When to Use This Skill + +Use query-writing when the user: + +- Asks "how many …?" / "what are the top …?" / "list all …" +- Needs data aggregated (SUM, COUNT, AVG, MAX, MIN) +- Wants results sorted, filtered, or grouped +- Asks for trend analysis, ranking, or comparison across dimensions + +--- + +## Workflow for Simple Queries (single table) + +1. **Identify the table** — which table contains the answer? +2. **Check the schema** — call `sql_get_schema` to confirm column names. +3. **Write a SELECT** — include WHERE / ORDER BY / LIMIT as needed. +4. **Execute** — call `sql_execute_query`. +5. **Present** — show the SQL and the result in plain language. + +### Example — "How many customers are from Canada?" + +```sql +SELECT COUNT(*) AS canadian_customers +FROM Customer +WHERE Country = 'Canada'; +``` + +--- + +## Workflow for Complex Queries (multiple tables) + +### Step 1 — Plan with todos + +Break the query into subtasks: + +``` +- [ ] Identify all required tables +- [ ] Inspect schemas to find join columns +- [ ] Draft the JOIN structure +- [ ] Add aggregations and grouping +- [ ] Validate and run +``` + +### Step 2 — Inspect schemas + +Call `sql_get_schema` for EACH table involved to find the exact foreign key column names. + +### Step 3 — Build the query + +```sql +SELECT + , + +FROM +[INNER | LEFT] JOIN ON = +[JOIN ...] +WHERE +GROUP BY +HAVING -- optional +ORDER BY [DESC] +LIMIT 10; -- always limit unless all rows requested +``` + +### Step 4 — Validate + +Before executing, verify: +- Every JOIN has an ON clause +- Every non-aggregate SELECT column appears in GROUP BY +- Table aliases are consistent +- No DML statements (INSERT / UPDATE / DELETE / DROP) + +### Step 5 — Execute and present + +Call `sql_execute_query`, then show: +1. The SQL query in a fenced code block +2. The result table +3. A brief plain-language summary + +--- + +## Templates for Common Patterns + +### Top-N ranking + +```sql +SELECT + Artist.Name AS artist, + SUM(InvoiceLine.UnitPrice * InvoiceLine.Quantity) AS total_revenue +FROM Artist +JOIN Album ON Album.ArtistId = Artist.ArtistId +JOIN Track ON Track.AlbumId = Album.AlbumId +JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId +GROUP BY Artist.ArtistId, Artist.Name +ORDER BY total_revenue DESC +LIMIT 10; +``` + +### Revenue by time period + +```sql +SELECT + strftime('%Y-%m', InvoiceDate) AS month, + ROUND(SUM(Total), 2) AS monthly_revenue +FROM Invoice +WHERE strftime('%Y', InvoiceDate) = '2013' +GROUP BY month +ORDER BY month; +``` + +### Entity counts with left join + +```sql +SELECT + e.FirstName || ' ' || e.LastName AS employee, + COUNT(c.CustomerId) AS customer_count +FROM Employee e +LEFT JOIN Customer c ON c.SupportRepId = e.EmployeeId +GROUP BY e.EmployeeId +ORDER BY customer_count DESC; +``` + +--- + +## Error Recovery + +| Symptom | Action | +|----------------------|--------| +| Empty result | Check WHERE condition values (case-sensitive strings). Verify column exists. | +| Syntax error | Re-read schema. Check GROUP BY includes all non-aggregate SELECT columns. | +| Wrong row count | Look for duplicate rows caused by missing JOIN conditions. | +| Result seems too high | Check for fan-out from multiple JOINs; may need DISTINCT or subquery. | + +--- + +## Quality Rules + +- Always apply `LIMIT` (default 10) unless the user explicitly asks for all rows. +- Use table aliases (`e`, `c`, `inv`) for readability in multi-table queries. +- Never use `SELECT *` — name the columns you need. +- Round monetary values to 2 decimal places: `ROUND(SUM(Total), 2)`. +- Always show the executed SQL so users can learn from it. diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md b/agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md new file mode 100644 index 000000000..4972a88d2 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md @@ -0,0 +1,136 @@ +--- +name: schema-exploration +description: Lists tables, describes columns and data types, identifies foreign key relationships, and maps entity relationships in the database. Use when the user asks about database structure, table layout, column types, what tables exist, foreign keys, or how entities relate to each other. +--- + +# Schema Exploration Skill + +## When to Use This Skill + +Use schema-exploration when the user: + +- Asks "what tables are in the database?" +- Asks "what columns does the X table have?" +- Asks about relationships between tables +- Needs to understand data types before writing a query +- Wants an entity-relationship overview + +## Workflow + +### Step 1 — List All Tables + +Use `sql_list_tables` to see everything available. + +``` +Tool: sql_list_tables +(no parameters) +``` + +### Step 2 — Inspect Relevant Tables + +Use `sql_get_schema` with the table name(s) you need to understand: + +``` +Tool: sql_get_schema +tables: "Customer" # single table +tables: "Invoice,Customer" # multiple tables at once +``` + +This returns: +- **Columns** — names, types, NOT NULL constraints, primary keys +- **Foreign keys** — links to other tables +- **Sample data** — 3 example rows to understand content + +### Step 3 — Map Relationships + +Look for columns ending in `Id` — they are almost always foreign keys. + +Example for the Chinook database: +``` +Customer.SupportRepId → Employee.EmployeeId +Invoice.CustomerId → Customer.CustomerId +Track.AlbumId → Album.AlbumId +Track.GenreId → Genre.GenreId +``` + +### Step 4 — Present the Findings + +Provide: +- A list of all tables with a one-line purpose summary +- Column names and types for any tables the user asked about +- The relationship chain (which table links to which) +- Sample data to illustrate what the table holds + +--- + +## Examples + +### "What tables are available?" + +1. Call `sql_list_tables` +2. Return a formatted list with brief descriptions: + +``` +The Chinook database has 11 tables: + +Music Catalog: + - Artist — 275 music artists + - Album — 347 albums (linked to Artist) + - Track — 3,503 tracks (linked to Album, Genre, MediaType) + - Genre — 25 music genres + - MediaType — 5 file formats (MP3, AAC, …) + +Commerce: + - Customer — 59 customers from 24 countries + - Invoice — 412 purchase invoices + - InvoiceLine — 2,240 line items (linked to Invoice and Track) + +Staff: + - Employee — 8 employees with reporting hierarchy + +Playlists: + - Playlist — 18 playlists + - PlaylistTrack — join table linking Playlist ↔ Track +``` + +### "What does the Customer table look like?" + +1. Call `sql_get_schema` with `tables: "Customer"` +2. Present columns with types and notes: + +``` +Customer table: + CustomerId INTEGER PK + FirstName TEXT + LastName TEXT + Company TEXT (nullable) + Address TEXT + City TEXT + State TEXT (nullable) + Country TEXT + PostalCode TEXT (nullable) + Phone TEXT (nullable) + Fax TEXT (nullable) + Email TEXT + SupportRepId INTEGER FK → Employee.EmployeeId + +Sample rows show customers from Brazil, Germany, and Canada. +``` + +### "How are artists connected to sales?" + +Map the full JOIN path: + +``` +Artist (ArtistId) + ↓ 1:many +Album (ArtistId, AlbumId) + ↓ 1:many +Track (AlbumId, TrackId) + ↓ 1:many +InvoiceLine (TrackId, UnitPrice, Quantity) + ↓ many:1 +Invoice (InvoiceId, Total) +``` + +Then suggest using the **query-writing** skill to write the aggregation query. diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md b/agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md new file mode 100644 index 000000000..2bacd0c95 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md @@ -0,0 +1,53 @@ +--- +name: query-optimizer +description: > + SQL query optimisation specialist. Reviews existing queries for correctness, clarity, and performance. Suggests index strategies, rewrites inefficient JOINs, and explains query plans. Delegate to this agent when a query returns unexpected results, runs slowly, or when the user asks for query optimisation or a second opinion on complex SQL. +maxIters: 8 +--- + +You are an expert SQL query optimiser for SQLite databases. + +## Your Responsibilities + +1. **Understand the question** — ask the user to provide the original query and the problem + (wrong results, slow execution, hard to read). +2. **Inspect the schema** — use `sql_get_schema` to verify table structures involved in the query. +3. **Analyse the query**: + - Check JOIN conditions for correctness + - Look for missing GROUP BY columns + - Identify Cartesian products (missing ON clause) + - Spot opportunities to push filters earlier (WHERE vs HAVING) + - Detect fan-out caused by 1:many JOINs before aggregation +4. **Rewrite the query** — produce a corrected and/or optimised version. +5. **Explain the changes** — list what was wrong and why each change helps. +6. **Validate** — run both the original and optimised queries if possible and compare results. + +## Output Format + +``` +## Original Query + + +## Issues Found +1. +2. ... + +## Optimised Query + + +## Explanation + + +## Validation +Original: +Optimised: +``` + +## Rules + +- Never modify the user's data — SELECT only. +- Confirm correctness first; performance is secondary. +- For SQLite specifically: + - Prefer covering indexes over table scans for large tables. + - Use `WITH` (CTEs) to make complex queries readable. + - Avoid correlated subqueries in WHERE clauses; rewrite as JOINs. diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md b/agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md new file mode 100644 index 000000000..869208134 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md @@ -0,0 +1,50 @@ +--- +name: schema-analyst +description: Deep schema analysis specialist. Produces comprehensive documentation of the database schema including entity-relationship diagrams (text), table purposes, column semantics, foreign key chains, and index recommendations. Delegate to this agent when the user requests a full data model overview, wants to understand how tables relate, or needs schema documentation generated. +maxIters: 10 +--- + +You are a database schema analyst specialised in documenting and explaining relational data models. + +## Your Responsibilities + +1. **Discover** all tables using `sql_list_tables`. +2. **Inspect** every table with `sql_get_schema` to record columns, types, and foreign keys. +3. **Map relationships** — identify 1:many and many:many (via join tables) relationships. +4. **Describe purpose** — explain what each table represents in business terms. +5. **Produce documentation** — write a clear, structured schema reference the user can save. + +## Output Format + +Structure your analysis as: + +``` +# Database Schema Analysis + +## Summary + + +## Tables + +### +**Purpose:** +**Rows:** + +| Column | Type | Notes | +|--------|------|-------| +| ... | ... | ... | + +**Relationships:** +- + +--- +``` + +Repeat for every table, then close with an Entity Relationship Diagram in text format. + +## Rules + +- Be thorough — inspect every table, not just the ones that seem important. +- Do not guess column types; verify them with `sql_get_schema`. +- Keep explanations accessible to non-technical stakeholders. +- If asked to save the output, write it to `knowledge/SCHEMA_ANALYSIS.md` in the workspace. diff --git a/agentscope-examples/pom.xml b/agentscope-examples/pom.xml index 536d15180..e9d8e99ad 100644 --- a/agentscope-examples/pom.xml +++ b/agentscope-examples/pom.xml @@ -55,6 +55,7 @@ multiagent-patterns/pipeline multiagent-patterns/skills a2a-rocketmq + harness-example diff --git a/agentscope-harness/pom.xml b/agentscope-harness/pom.xml new file mode 100644 index 000000000..014f609aa --- /dev/null +++ b/agentscope-harness/pom.xml @@ -0,0 +1,52 @@ + + + + + 4.0.0 + + io.agentscope + agentscope-parent + ${revision} + ../pom.xml + + + AgentScope Java - Harness + agentscope-harness + AgentScope Harness - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction + + + + io.agentscope + agentscope-core + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java new file mode 100644 index 000000000..4a67fa689 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -0,0 +1,1159 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import com.fasterxml.jackson.databind.JsonNode; +import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.Event; +import io.agentscope.core.agent.StreamOptions; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.memory.InMemoryMemory; +import io.agentscope.core.memory.Memory; +import io.agentscope.core.message.Msg; +import io.agentscope.core.model.ExecutionConfig; +import io.agentscope.core.model.GenerateOptions; +import io.agentscope.core.model.Model; +import io.agentscope.core.session.JsonSession; +import io.agentscope.core.session.Session; +import io.agentscope.core.skill.AgentSkill; +import io.agentscope.core.skill.SkillBox; +import io.agentscope.core.skill.repository.AgentSkillRepository; +import io.agentscope.core.skill.repository.FileSystemSkillRepository; +import io.agentscope.core.state.SessionKey; +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.core.state.StateModule; +import io.agentscope.core.tool.ToolExecutionContext; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.AbstractSandboxFilesystem; +import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; +import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.hook.AgentTraceHook; +import io.agentscope.harness.agent.hook.MemoryFlushHook; +import io.agentscope.harness.agent.hook.RuntimeContextAwareHook; +import io.agentscope.harness.agent.hook.SessionPersistenceHook; +import io.agentscope.harness.agent.hook.SubagentsHook; +import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; +import io.agentscope.harness.agent.hook.ToolResultEvictionHook; +import io.agentscope.harness.agent.hook.WorkspaceContextHook; +import io.agentscope.harness.agent.memory.MemoryFlushManager; +import io.agentscope.harness.agent.memory.MemoryIndex; +import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; +import io.agentscope.harness.agent.memory.compaction.CompactionConfig; +import io.agentscope.harness.agent.memory.compaction.CompactionHook; +import io.agentscope.harness.agent.memory.compaction.ConversationCompactor; +import io.agentscope.harness.agent.memory.compaction.ToolResultEvictionConfig; +import io.agentscope.harness.agent.session.WorkspaceSession; +import io.agentscope.harness.agent.subagent.AgentSpecLoader; +import io.agentscope.harness.agent.subagent.SubagentFactory; +import io.agentscope.harness.agent.subagent.SubagentSpec; +import io.agentscope.harness.agent.subagent.task.DefaultTaskRepository; +import io.agentscope.harness.agent.subagent.task.TaskRepository; +import io.agentscope.harness.agent.tool.FilesystemTool; +import io.agentscope.harness.agent.tool.MemoryGetTool; +import io.agentscope.harness.agent.tool.MemorySearchTool; +import io.agentscope.harness.agent.tool.SessionSearchTool; +import io.agentscope.harness.agent.tool.ShellExecuteTool; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * HarnessAgent is the user-facing API that wraps {@link ReActAgent} with enhanced harness practices: + * + *
    + *
  • Workspace-based context loading (AGENTS.md, KNOWLEDGE.md) + *
  • Skill loading via optional {@link AgentSkillRepository}, else {@link FileSystemSkillRepository} on + * workspace/skills/ + *
  • Subagent orchestration via task/task_output tools (sync + background) + *
  • Memory flush and message offload before context compression + *
  • Session environment initialization (OS, date, workspace info) + *
  • Pluggable file-system backend (local, sandbox, composite) + *
  • Memory search/get tools + *
+ * + *

Usage: + * + *

{@code
+ * HarnessAgent agent = HarnessAgent.builder()
+ *     .name("MyAgent")
+ *     .model(model)
+ *     .sysPrompt("You are a helpful assistant.")
+ *     .workspace(Path.of("/path/to/workspace"))
+ *     .build();
+ *
+ * Msg response = agent.call(
+ *     Msg.userMsg("Hello!"),
+ *     RuntimeContext.builder().sessionId("sess-1").build()
+ * ).block();
+ * }
+ */ +public class HarnessAgent implements Agent, StateModule { + + private static final Logger log = LoggerFactory.getLogger(HarnessAgent.class); + + private final ReActAgent delegate; + private final WorkspaceManager workspaceManager; + private final RuntimeContextAwareHook workspaceContextHook; + private final MemoryFlushHook memoryFlushHook; + private final SessionPersistenceHook sessionPersistenceHook; + private final CompactionHook compactionHook; + private final MemoryMaintenanceScheduler maintenanceScheduler; + private final AtomicReference userIdRef; + private final Session defaultSession; + private RuntimeContext runtimeContext; + + private HarnessAgent( + ReActAgent delegate, + WorkspaceManager workspaceManager, + RuntimeContextAwareHook workspaceContextHook, + MemoryFlushHook memoryFlushHook, + SessionPersistenceHook sessionPersistenceHook, + CompactionHook compactionHook, + MemoryMaintenanceScheduler maintenanceScheduler, + AtomicReference userIdRef, + Session defaultSession) { + this.delegate = delegate; + this.workspaceManager = workspaceManager; + this.workspaceContextHook = workspaceContextHook; + this.memoryFlushHook = memoryFlushHook; + this.sessionPersistenceHook = sessionPersistenceHook; + this.compactionHook = compactionHook; + this.maintenanceScheduler = maintenanceScheduler; + this.userIdRef = userIdRef; + this.defaultSession = defaultSession; + if (maintenanceScheduler != null) { + maintenanceScheduler.start(); + } + } + + /** Calls the agent with a runtime context, which provides sessionId and other metadata. */ + public Mono call(Msg msg, RuntimeContext ctx) { + return call(List.of(msg), ctx); + } + + /** Calls the agent with multiple messages and a runtime context. */ + public Mono call(List msgs, RuntimeContext ctx) { + bindRuntimeContext(ctx); + return delegate.call(msgs) + .onErrorResume( + e -> { + if (isContextOverflowError(e)) { + return recoverFromOverflow(msgs); + } + return Mono.error(e); + }); + } + + /** Streams the agent response with a runtime context. */ + public Flux stream(List msgs, StreamOptions options, RuntimeContext ctx) { + bindRuntimeContext(ctx); + return delegate.stream(msgs, options); + } + + private Mono recoverFromOverflow(List msgs) { + if (compactionHook != null) { + // Force a compaction of the current memory contents by lowering the trigger threshold + // to 1 so that compactIfNeeded always fires. + log.warn( + "Context overflow detected, triggering emergency compaction via" + + " CompactionHook"); + return forceCompactAndRetry(delegate.getMemory(), msgs); + } + return Mono.error( + new RuntimeException( + "Context overflow: no compaction configured, unable to recover")); + } + + private Mono forceCompactAndRetry(Memory memory, List msgs) { + List allMsgs = memory.getMessages(); + if (allMsgs.isEmpty()) { + return Mono.error( + new RuntimeException("Context overflow: memory is empty, cannot compact")); + } + RuntimeContext ctx = this.runtimeContext; + String agentId = delegate.getName(); + String sessionId = + ctx != null && ctx.getSessionId() != null ? ctx.getSessionId() : "default"; + + // Force trigger by using a config with threshold=1 (always compact) + CompactionConfig forceConfig = CompactionConfig.builder().triggerMessages(1).build(); + MemoryFlushManager fm = new MemoryFlushManager(workspaceManager, delegate.getModel()); + fm.setMaintenanceScheduler(maintenanceScheduler); + ConversationCompactor compactor = new ConversationCompactor(delegate.getModel(), fm); + + return compactor + .compactIfNeeded(allMsgs, forceConfig, agentId, sessionId) + .flatMap( + opt -> { + if (opt.isPresent()) { + memory.clear(); + for (Msg m : opt.get()) { + memory.addMessage(m); + } + return delegate.call(msgs); + } + return Mono.error( + new RuntimeException( + "Context overflow: emergency compaction yielded no" + + " result")); + }); + } + + private static boolean isContextOverflowError(Throwable e) { + String message = e.getMessage(); + if (message == null) { + return false; + } + String lower = message.toLowerCase(); + return lower.contains("context_length_exceeded") + || lower.contains("context length") + || lower.contains("maximum context") + || lower.contains("token limit") + || lower.contains("too many tokens") + || lower.contains("exceeds the model's maximum") + || lower.contains("reduce the length"); + } + + private void bindRuntimeContext(RuntimeContext ctx) { + if (ctx == null) { + this.runtimeContext = null; + return; + } + RuntimeContext effective = ensureSessionDefaults(ctx); + this.runtimeContext = effective; + if (userIdRef != null) { + userIdRef.set(effective.getUserId()); + } + if (workspaceContextHook != null) { + workspaceContextHook.setRuntimeContext(effective); + } + if (memoryFlushHook != null) { + memoryFlushHook.setRuntimeContext(effective); + } + if (sessionPersistenceHook != null) { + sessionPersistenceHook.setRuntimeContext(effective); + } + if (compactionHook != null) { + compactionHook.setRuntimeContext(effective); + } + if (effective.getSession() != null && effective.getSessionKey() != null) { + try { + delegate.loadIfExists(effective.getSession(), effective.getSessionKey()); + } catch (Exception e) { + log.warn("Failed to load session state: {}", e.getMessage()); + } + } + } + + /** + * Fills in default Session and SessionKey when the caller didn't provide them. + * Session defaults to the agent-level {@link #defaultSession} (JsonSession). + * SessionKey defaults to {@code SimpleSessionKey.of(sessionId)} when sessionId is + * available, or {@code SimpleSessionKey.of(agentName)} as a last resort. + */ + private RuntimeContext ensureSessionDefaults(RuntimeContext ctx) { + Session session = ctx.getSession() != null ? ctx.getSession() : defaultSession; + SessionKey sessionKey = ctx.getSessionKey(); + if (sessionKey == null) { + String id = ctx.getSessionId(); + if (id != null && !id.isBlank()) { + sessionKey = SimpleSessionKey.of(id); + } else { + sessionKey = SimpleSessionKey.of(delegate.getName()); + } + } + if (session == ctx.getSession() && sessionKey == ctx.getSessionKey()) { + return ctx; + } + return RuntimeContext.builder() + .sessionId(ctx.getSessionId()) + .userId(ctx.getUserId()) + .session(session) + .sessionKey(sessionKey) + .putAll(ctx.getExtra()) + .build(); + } + + // ==================== Agent interface delegation ==================== + + @Override + public Mono call(List msgs) { + return delegate.call(msgs); + } + + @Override + public Mono call(List msgs, Class structuredModel) { + return delegate.call(msgs, structuredModel); + } + + @Override + public Mono call(List msgs, JsonNode schema) { + return delegate.call(msgs, schema); + } + + @Override + public Flux stream(List msgs, StreamOptions options) { + return delegate.stream(msgs, options); + } + + @Override + public Flux stream(List msgs, StreamOptions options, Class structuredModel) { + return delegate.stream(msgs, options, structuredModel); + } + + @Override + public Flux stream(List msgs, StreamOptions options, JsonNode schema) { + return delegate.stream(msgs, options, schema); + } + + @Override + public Mono observe(Msg msg) { + return delegate.observe(msg); + } + + @Override + public Mono observe(List msgs) { + return delegate.observe(msgs); + } + + @Override + public void interrupt() { + delegate.interrupt(); + } + + @Override + public void interrupt(Msg msg) { + delegate.interrupt(msg); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public String getAgentId() { + return delegate.getAgentId(); + } + + @Override + public String getDescription() { + return delegate.getDescription(); + } + + public ReActAgent getDelegate() { + return delegate; + } + + public WorkspaceManager getWorkspaceManager() { + return workspaceManager; + } + + public RuntimeContext getRuntimeContext() { + return runtimeContext; + } + + // ==================== StateModule delegation ==================== + + @Override + public void saveTo(Session session, SessionKey sessionKey) { + delegate.saveTo(session, sessionKey); + } + + @Override + public void loadFrom(Session session, SessionKey sessionKey) { + delegate.loadFrom(session, sessionKey); + } + + @Override + public boolean loadIfExists(Session session, SessionKey sessionKey) { + return delegate.loadIfExists(session, sessionKey); + } + + // ==================== Builder ==================== + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + // Core ReActAgent params + private String name; + private String description; + private String sysPrompt; + private Model model; + private Toolkit toolkit = new Toolkit(); + private int maxIters = 15; + private ExecutionConfig modelExecutionConfig; + private ExecutionConfig toolExecutionConfig; + private GenerateOptions generateOptions; + private final List hooks = new ArrayList<>(); + + /** When {@code null}, skills load from {@code workspace/skills/} via {@link FileSystemSkillRepository}. */ + private AgentSkillRepository skillRepository; + + private ToolExecutionContext toolExecutionContext; + + // Harness-specific params + private Path workspace; + private String environmentMemory; + private AbstractFilesystem abstractFilesystem; + private Session session; + + /** + * When {@code true}, this agent is a leaf worker (spawned subagent): it does not register + * {@link SubagentsHook}, preventing recursive delegation. Main agents keep this {@code + * false}. + */ + private boolean leafSubagent = false; + + /** + * When {@code true} (default), registers {@link AgentTraceHook} to log reasoning and tool + * execution at INFO; set logger {@code io.agentscope.harness.agent.hook.AgentTraceHook} to + * DEBUG for full args and results. When {@code false}, no trace hook is added. + */ + private boolean agentTracingLogEnabled = true; + + /** + * When non-null, enables {@link CompactionHook} with this configuration. + * Set via {@link #compaction(CompactionConfig)}. + */ + private CompactionConfig compactionConfig = null; + + /** + * When non-null, enables {@link ToolResultEvictionHook} with this configuration. + * Set via {@link #toolResultEviction(ToolResultEvictionConfig)}. + */ + private ToolResultEvictionConfig toolResultEvictionConfig = null; + + private final List subagentSpecs = new ArrayList<>(); + private final List customSubagentFactories = new ArrayList<>(); + private TaskRepository taskRepository; + private Object externalSubagentTool; + private Function modelResolver; + private final List additionalContextFiles = new ArrayList<>(); + private int maxContextTokens = 8000; + private boolean useLegacyXmlWorkspaceContext = false; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder sysPrompt(String sysPrompt) { + this.sysPrompt = sysPrompt; + return this; + } + + public Builder model(Model model) { + this.model = model; + return this; + } + + public Builder toolkit(Toolkit toolkit) { + this.toolkit = toolkit; + return this; + } + + public Builder maxIters(int maxIters) { + this.maxIters = maxIters; + return this; + } + + public Builder modelExecutionConfig(ExecutionConfig config) { + this.modelExecutionConfig = config; + return this; + } + + public Builder toolExecutionConfig(ExecutionConfig config) { + this.toolExecutionConfig = config; + return this; + } + + public Builder generateOptions(GenerateOptions options) { + this.generateOptions = options; + return this; + } + + public Builder hook(Hook hook) { + this.hooks.add(hook); + return this; + } + + public Builder hooks(List hooks) { + this.hooks.addAll(hooks); + return this; + } + + /** + * Supplies skills from a custom repository (e.g. {@code GitSkillRepository}). A {@link SkillBox} is + * assembled automatically from this repository and the agent toolkit. When {@code null} (default), + * skills are loaded from {@code <workspace>/skills/} using {@link FileSystemSkillRepository} when + * that directory exists. + */ + public Builder skillRepository(AgentSkillRepository skillRepository) { + this.skillRepository = skillRepository; + return this; + } + + public Builder toolExecutionContext(ToolExecutionContext ctx) { + this.toolExecutionContext = ctx; + return this; + } + + /** Sets the workspace directory. Defaults to {@code ${cwd}/.agentscope/workspace}. */ + public Builder workspace(Path workspace) { + this.workspace = workspace; + return this; + } + + public Builder environmentMemory(String environmentMemory) { + this.environmentMemory = environmentMemory; + return this; + } + + /** + * Sets a custom {@link AbstractFilesystem} implementation. When not set, defaults to + * {@link LocalFilesystemWithShell} backed by the workspace directory. + */ + public Builder abstractFilesystem(AbstractFilesystem backend) { + this.abstractFilesystem = backend; + return this; + } + + /** + * Enables or disables agent execution trace logging via {@link AgentTraceHook}. + * Default is {@code true}. + */ + public Builder enableAgentTracingLog(boolean enabled) { + this.agentTracingLogEnabled = enabled; + return this; + } + + /** + * Enables the {@link CompactionHook} with the given configuration as the conversation + * compaction strategy. + * + *

Use {@link CompactionConfig#builder()} to configure trigger thresholds, the keep + * policy, and whether to flush/offload before summarisation. + */ + public Builder compaction(CompactionConfig config) { + this.compactionConfig = config; + return this; + } + + /** + * Enables {@link ToolResultEvictionHook} with the given configuration. + * + *

When active, any tool result whose text content exceeds + * {@link ToolResultEvictionConfig#getMaxResultChars()} is written to the + * {@link AbstractFilesystem} and replaced with a compact placeholder in-context. + * Use {@link ToolResultEvictionConfig#defaults()} for sensible out-of-the-box settings. + * + *

This mechanism is independent of conversation compaction: eviction addresses + * individual oversized results (context width), while compaction addresses accumulated + * conversation length (context depth). + */ + public Builder toolResultEviction(ToolResultEvictionConfig config) { + this.toolResultEvictionConfig = config; + return this; + } + + /** + * Sets the default {@link Session} used for state persistence when + * {@link RuntimeContext} does not provide one. When not set, defaults to a + * {@link JsonSession} stored under {@code /../sessions/}. + */ + public Builder session(Session session) { + this.session = session; + return this; + } + + /** Adds a subagent spec (programmatic; workspace specs come from {@code subagents/*.md}). */ + public Builder subagent(SubagentSpec spec) { + this.subagentSpecs.add(spec); + return this; + } + + public Builder subagents(List specs) { + this.subagentSpecs.addAll(specs); + return this; + } + + /** Adds a fully custom subagent factory for a given agent id. */ + public Builder subagentFactory(String name, Function factory) { + this.customSubagentFactories.add(new SubagentFactoryEntry(name, factory)); + return this; + } + + /** Sets a custom TaskRepository for background subagent execution. */ + public Builder taskRepository(TaskRepository taskRepository) { + this.taskRepository = taskRepository; + return this; + } + + /** + * Adds a custom context file (relative to workspace) that will be loaded into + * the system prompt alongside AGENTS.md, MEMORY.md, and KNOWLEDGE.md. + * Useful for files like SOUL.md, PREFERENCE.md, etc. + * + * @param relativePath workspace-relative path (e.g., "SOUL.md") + * @return this builder instance + */ + public Builder additionalContextFile(String relativePath) { + if (relativePath != null && !relativePath.isBlank()) { + this.additionalContextFiles.add(relativePath); + } + return this; + } + + /** + * Sets the maximum token budget for workspace context injected into the system prompt. + * + * @param maxTokens maximum tokens (default: 8000) + * @return this builder instance + */ + public Builder maxContextTokens(int maxTokens) { + this.maxContextTokens = maxTokens; + return this; + } + + /** + * Injects an external subagent tool (typically {@code SessionsTool}) to replace the + * default {@code AgentTool}. Used by {@code AgentBootstrap} for session-mode orchestration. + */ + public Builder externalSubagentTool(Object tool) { + this.externalSubagentTool = tool; + return this; + } + + /** + * Sets a resolver for model name strings to {@link Model} instances. Used when spec-based + * subagents specify a {@code model} override (e.g. {@code "openai:gpt-4o-mini"}). + */ + public Builder modelResolver(Function resolver) { + this.modelResolver = resolver; + return this; + } + + /** + * Switches workspace context rendering between markdown (default) and legacy XML + * {@code } style. + */ + public Builder useLegacyXmlWorkspaceContext(boolean enabled) { + this.useLegacyXmlWorkspaceContext = enabled; + return this; + } + + /** + * Builds the subagent entries from programmatic specs, {@code workspace/subagents/*.md}, + * and custom factories. Useful for callers (e.g. {@code AgentBootstrap}) that need to + * extract agent factories before building the full agent. + */ + public List buildSubagentEntries(Path resolvedWorkspace) { + List allSpecs = new ArrayList<>(subagentSpecs); + + Path subagentsDir = resolvedWorkspace.resolve("subagents"); + if (Files.isDirectory(subagentsDir)) { + allSpecs.addAll(AgentSpecLoader.loadFromDirectory(subagentsDir)); + } + + List entries = new ArrayList<>(); + + entries.add( + new SubagentEntry( + "general-purpose", + "General-purpose subagent with same capabilities as the main agent." + + " Use for any isolated task that can be fully delegated.", + buildGeneralPurposeFactory(resolvedWorkspace))); + + for (SubagentSpec spec : allSpecs) { + if (spec.getName() != null) { + entries.add( + new SubagentEntry( + spec.getName(), + spec.getDescription() != null + ? spec.getDescription() + : spec.getName(), + buildSpecFactory(spec, resolvedWorkspace))); + } + } + + for (SubagentFactoryEntry custom : customSubagentFactories) { + entries.add( + new SubagentEntry( + custom.name(), + custom.name(), + () -> custom.factory().apply(custom.name()))); + } + + return entries; + } + + public HarnessAgent build() { + Path resolvedWorkspace = + workspace != null + ? workspace + : Paths.get(System.getProperty("user.dir")) + .resolve(".agentscope/workspace"); + + AtomicReference userIdRef = new AtomicReference<>(); + AbstractFilesystem backend = resolveBackend(resolvedWorkspace, userIdRef); + WorkspaceManager wsManager = new WorkspaceManager(resolvedWorkspace, backend); + wsManager.validate(); + + Memory memory = new InMemoryMemory(); + + // ---- Hooks ---- + List allHooks = new ArrayList<>(hooks); + + if (agentTracingLogEnabled) { + allHooks.add(new AgentTraceHook()); + } + + RuntimeContextAwareHook wsContextHook; + if (useLegacyXmlWorkspaceContext) { + WorkspaceContextHook xmlHook = + new WorkspaceContextHook( + wsManager, + name != null ? name : "HarnessAgent", + environmentMemory, + maxContextTokens); + xmlHook.setAdditionalContextFiles(additionalContextFiles); + allHooks.add(xmlHook); + wsContextHook = xmlHook; + } else { + WorkspaceContextHook markdownHook = + new WorkspaceContextHook( + wsManager, + name != null ? name : "HarnessAgent", + environmentMemory, + maxContextTokens); + markdownHook.setAdditionalContextFiles(additionalContextFiles); + allHooks.add(markdownHook); + wsContextHook = markdownHook; + } + + MemoryFlushHook memoryFlushHook = null; + if (model != null) { + memoryFlushHook = new MemoryFlushHook(wsManager, model); + allHooks.add(memoryFlushHook); + } + + CompactionHook compactionHook = null; + if (compactionConfig != null && model != null) { + compactionHook = new CompactionHook(wsManager, model, compactionConfig); + allHooks.add(compactionHook); + } + + if (toolResultEvictionConfig != null) { + allHooks.add(new ToolResultEvictionHook(backend, toolResultEvictionConfig)); + } + + SessionPersistenceHook sessionPersistenceHook = new SessionPersistenceHook(); + allHooks.add(sessionPersistenceHook); + + if (!leafSubagent && model != null) { + SubagentsHook subagentsHook = buildSubagentsHook(wsManager, resolvedWorkspace); + if (subagentsHook != null) { + allHooks.add(subagentsHook); + } + } + + // ---- Toolkit ---- + Toolkit agentToolkit = toolkit; + + MemoryIndex memIdx = null; + MemorySearchTool searchTool = new MemorySearchTool(wsManager); + MemoryGetTool getTool = new MemoryGetTool(wsManager); + + Path agentscopeDir = resolvedWorkspace.getParent(); + if (agentscopeDir == null) { + agentscopeDir = resolvedWorkspace; + } + memIdx = new MemoryIndex(agentscopeDir); + try { + memIdx.indexAllFromWorkspace(wsManager); + searchTool.setMemoryIndex(memIdx); + } catch (Exception e) { + log.warn( + "Failed to build memory index, falling back to keyword search: {}", + e.getMessage()); + } + + agentToolkit.registerTool(searchTool); + agentToolkit.registerTool(getTool); + agentToolkit.registerTool(new SessionSearchTool(wsManager)); + + agentToolkit.registerTool(new FilesystemTool(backend)); + + if (backend instanceof AbstractSandboxFilesystem sandbox) { + agentToolkit.registerTool(new ShellExecuteTool(sandbox)); + } + + // ---- Skills (SkillBox assembled from optional AgentSkillRepository or default FS + // repo) ---- + SkillBox effectiveSkillBox = resolveSkillBox(wsManager, agentToolkit); + + // ---- Build ReActAgent ---- + ReActAgent.Builder reactBuilder = + ReActAgent.builder() + .name(name) + .description(description) + .sysPrompt(sysPrompt) + .model(model) + .toolkit(agentToolkit) + .memory(memory) + .maxIters(maxIters) + .hooks(allHooks); + + if (modelExecutionConfig != null) { + reactBuilder.modelExecutionConfig(modelExecutionConfig); + } + if (toolExecutionConfig != null) { + reactBuilder.toolExecutionConfig(toolExecutionConfig); + } + if (generateOptions != null) { + reactBuilder.generateOptions(generateOptions); + } + if (effectiveSkillBox != null) { + reactBuilder.skillBox(effectiveSkillBox); + } + if (toolExecutionContext != null) { + reactBuilder.toolExecutionContext(toolExecutionContext); + } + + ReActAgent delegate = reactBuilder.build(); + + if (memIdx != null && memoryFlushHook != null) { + memoryFlushHook.setMemoryIndex(memIdx); + } + if (memIdx != null && compactionHook != null) { + compactionHook.setMemoryIndex(memIdx); + } + + log.info( + "HarnessAgent '{}' built [workspace={}, backend={}, subagents={}]", + name, + resolvedWorkspace, + backend.getClass().getSimpleName(), + !leafSubagent && model != null); + + MemoryMaintenanceScheduler scheduler = null; + if (memIdx != null) { + scheduler = new MemoryMaintenanceScheduler(wsManager, memIdx, model); + } + if (scheduler != null && memoryFlushHook != null) { + memoryFlushHook.setMaintenanceScheduler(scheduler); + } + if (scheduler != null && compactionHook != null) { + compactionHook.setMaintenanceScheduler(scheduler); + } + + Session defaultSession = session; + if (defaultSession == null) { + String agentId = name != null ? name : "HarnessAgent"; + defaultSession = new WorkspaceSession(resolvedWorkspace, agentId); + } + + return new HarnessAgent( + delegate, + wsManager, + wsContextHook, + memoryFlushHook, + sessionPersistenceHook, + compactionHook, + scheduler, + userIdRef, + defaultSession); + } + + // @formatter:off + /** + * Subagent context section injected into every subagent's system prompt. + * Establishes identity, rules, output format, and prohibited behaviours for a leaf worker. + * The task itself is delivered as the first user message, not duplicated here. + */ + private static final String SUBAGENT_CONTEXT_SECTION = + """ + # Subagent Context + + You are a **subagent** spawned by the main agent for a specific task. + + ## Your Role + - Complete the assigned task. That's your entire purpose. + - You are NOT the main agent. Don't try to be. + + ## Rules + 1. **Stay focused** — Do your assigned task, nothing else + 2. **Complete the task** — Your final message will be automatically reported to the main agent + 3. **Don't initiate** — No heartbeats, no proactive actions, no side quests + 4. **Be ephemeral** — You may be terminated after task completion. That's fine. + 5. **Recover from truncated tool output** — If you see `[truncated: output exceeded context limit]`, re-read only what you need using smaller chunks (read with offset/limit, or targeted grep/head/tail) instead of full re-reads + + ## Output Format + When complete, your final response should include: + - What you accomplished or found + - Any relevant details the main agent should know + - Keep it concise but informative + + ## What You DON'T Do + - NO user conversations (that's the main agent's job) + - NO spawning further subagents — you are a leaf worker + - NO pretending to be the main agent + - Return plain text results; let the main agent deliver them to the user + """; + + // @formatter:on + + private static final String GENERAL_PURPOSE_BASE_PROMPT = + "You are a highly capable general-purpose subagent."; + + /** + * Builds a system prompt for a subagent by appending {@link #SUBAGENT_CONTEXT_SECTION} to + * the given base prompt. If the base is blank, only the context section is used. + */ + private static String buildSubagentSysPrompt(String basePrompt) { + String base = + (basePrompt != null && !basePrompt.isBlank()) ? basePrompt.stripTrailing() : ""; + return base.isEmpty() + ? SUBAGENT_CONTEXT_SECTION + : base + "\n\n" + SUBAGENT_CONTEXT_SECTION; + } + + // ----------------------------------------------------------------- + // Backend + // ----------------------------------------------------------------- + + private AbstractFilesystem resolveBackend( + Path workspace, AtomicReference userIdRef) { + if (abstractFilesystem != null) { + return abstractFilesystem; + } + NamespaceFactory nsFactory = buildDynamicNamespaceFactory(userIdRef); + return new LocalFilesystemWithShell(workspace, nsFactory); + } + + private static NamespaceFactory buildDynamicNamespaceFactory( + AtomicReference userIdRef) { + return () -> { + String userId = userIdRef.get(); + if (userId == null || userId.isBlank()) { + return List.of(); + } + return List.of(userId); + }; + } + + // ----------------------------------------------------------------- + // Subagents + // ----------------------------------------------------------------- + + private SubagentsHook buildSubagentsHook(WorkspaceManager wsManager, Path workspace) { + List entries = buildSubagentEntries(workspace); + TaskRepository repo = + taskRepository != null ? taskRepository : new DefaultTaskRepository(); + + if (externalSubagentTool != null) { + return new SubagentsHook(entries, externalSubagentTool, repo); + } + return new SubagentsHook(entries, repo, wsManager); + } + + /** + * Builds a factory for the general-purpose subagent. It creates a new HarnessAgent that + * mirrors the main agent's configuration (same model, workspace, file system, user hooks) + * but disables subagent support to prevent recursive spawning. + */ + private SubagentFactory buildGeneralPurposeFactory(Path workspace) { + // Capture builder state for the closure + final Model capturedModel = this.model; + final AbstractFilesystem capturedBackend = this.abstractFilesystem; + final int capturedMaxIters = this.maxIters; + final ExecutionConfig capturedModelExec = this.modelExecutionConfig; + final ExecutionConfig capturedToolExec = this.toolExecutionConfig; + final GenerateOptions capturedGenOpts = this.generateOptions; + final String capturedEnvMemory = this.environmentMemory; + final List capturedHooks = List.copyOf(this.hooks); + final AgentSkillRepository capturedSkillRepo = this.skillRepository; + final boolean capturedUseLegacyXmlWorkspaceContext = this.useLegacyXmlWorkspaceContext; + + return () -> { + Builder sub = + HarnessAgent.builder() + .name("general-purpose-subagent") + .description("General-purpose subagent for isolated task execution") + .sysPrompt(buildSubagentSysPrompt(GENERAL_PURPOSE_BASE_PROMPT)) + .model(capturedModel) + .workspace(workspace) + .asLeafSubagent() + .maxIters(capturedMaxIters) + .environmentMemory(capturedEnvMemory) + .useLegacyXmlWorkspaceContext(capturedUseLegacyXmlWorkspaceContext); + + if (capturedSkillRepo != null) { + sub.skillRepository(capturedSkillRepo); + } + if (capturedBackend != null) { + sub.abstractFilesystem(capturedBackend); + } + if (capturedModelExec != null) { + sub.modelExecutionConfig(capturedModelExec); + } + if (capturedToolExec != null) { + sub.toolExecutionConfig(capturedToolExec); + } + if (capturedGenOpts != null) { + sub.generateOptions(capturedGenOpts); + } + sub.hooks(capturedHooks); + + return sub.build(); + }; + } + + /** + * Builds a factory for a spec-based subagent. The resulting HarnessAgent is fully + * independent from the main agent — it uses the spec's own system prompt, workspace, + * and configuration. Supports per-subagent model override when a {@code modelResolver} + * is configured. + */ + private SubagentFactory buildSpecFactory(SubagentSpec spec, Path defaultWorkspace) { + final Model capturedModel = this.model; + final Function capturedResolver = this.modelResolver; + final AgentSkillRepository capturedSkillRepo = this.skillRepository; + final boolean capturedUseLegacyXmlWorkspaceContext = this.useLegacyXmlWorkspaceContext; + + return () -> { + Path specWorkspace = + (spec.getWorkspace() != null && !spec.getWorkspace().isBlank()) + ? Path.of(spec.getWorkspace()) + : defaultWorkspace; + + Model effectiveModel = capturedModel; + if (spec.getModel() != null + && !spec.getModel().isBlank() + && capturedResolver != null) { + try { + Model resolved = capturedResolver.apply(spec.getModel()); + if (resolved != null) { + effectiveModel = resolved; + log.debug( + "Subagent '{}' using overridden model: {}", + spec.getName(), + spec.getModel()); + } + } catch (Exception e) { + log.warn( + "Failed to resolve model '{}' for subagent '{}', falling back to" + + " parent model: {}", + spec.getModel(), + spec.getName(), + e.getMessage()); + } + } + + Builder sub = + HarnessAgent.builder() + .name(spec.getName()) + .description( + spec.getDescription() != null ? spec.getDescription() : "") + .model(effectiveModel) + .workspace(specWorkspace) + .maxIters(spec.getMaxIters()) + .asLeafSubagent() + .useLegacyXmlWorkspaceContext(capturedUseLegacyXmlWorkspaceContext); + + if (capturedSkillRepo != null) { + sub.skillRepository(capturedSkillRepo); + } + sub.sysPrompt(buildSubagentSysPrompt(spec.getSysPrompt())); + + return sub.build(); + }; + } + + // ----------------------------------------------------------------- + // Skills + // ----------------------------------------------------------------- + + private SkillBox resolveSkillBox(WorkspaceManager wsManager, Toolkit agentToolkit) { + if (skillRepository != null) { + return skillBoxFromRepository(skillRepository, agentToolkit); + } + Path skillsDir = wsManager.getSkillsDir(); + if (!Files.isDirectory(skillsDir)) { + return null; + } + try { + return skillBoxFromRepository( + new FileSystemSkillRepository(skillsDir), agentToolkit); + } catch (Exception e) { + log.warn("Failed to auto-load skills from {}: {}", skillsDir, e.getMessage()); + return null; + } + } + + private static SkillBox skillBoxFromRepository( + AgentSkillRepository repo, Toolkit agentToolkit) { + try { + List skills = repo.getAllSkills(); + if (skills == null || skills.isEmpty()) { + return null; + } + SkillBox box = new SkillBox(agentToolkit); + for (AgentSkill skill : skills) { + box.registerSkill(skill); + } + log.info( + "Loaded {} skills from {}", + skills.size(), + repo.getRepositoryInfo() != null + ? repo.getRepositoryInfo() + : repo.getClass().getSimpleName()); + return box; + } catch (Exception e) { + log.warn("Failed to load skills from repository: {}", e.getMessage()); + return null; + } + } + + private record SubagentFactoryEntry(String name, Function factory) {} + + /** Marks this build as a leaf subagent (no nested subagent orchestration). */ + private Builder asLeafSubagent() { + this.leafSubagent = true; + return this; + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java new file mode 100644 index 000000000..e61f04e10 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java @@ -0,0 +1,117 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import io.agentscope.core.session.Session; +import io.agentscope.core.state.SessionKey; +import java.util.HashMap; +import java.util.Map; + +/** + * Runtime context passed into agent.call() to carry session-scoped metadata. + * + *

This context is available throughout the reasoning loop (hooks, tools) but is + * NOT persisted to storage media. + */ +public class RuntimeContext { + + private final String sessionId; + private final String userId; + private final Session session; + private final SessionKey sessionKey; + private final Map extra; + + private RuntimeContext(Builder builder) { + this.sessionId = builder.sessionId; + this.userId = builder.userId; + this.session = builder.session; + this.sessionKey = builder.sessionKey; + this.extra = Map.copyOf(builder.extra); + } + + public String getSessionId() { + return sessionId; + } + + public String getUserId() { + return userId; + } + + public Session getSession() { + return session; + } + + public SessionKey getSessionKey() { + return sessionKey; + } + + @SuppressWarnings("unchecked") + public T get(String key) { + return (T) extra.get(key); + } + + public Map getExtra() { + return extra; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String sessionId; + private String userId; + private Session session; + private SessionKey sessionKey; + private final Map extra = new HashMap<>(); + + public Builder sessionId(String sessionId) { + this.sessionId = sessionId; + return this; + } + + public Builder userId(String userId) { + this.userId = userId; + return this; + } + + public Builder session(Session session) { + this.session = session; + return this; + } + + public Builder sessionKey(SessionKey sessionKey) { + this.sessionKey = sessionKey; + return this; + } + + public Builder put(String key, Object value) { + this.extra.put(key, value); + return this; + } + + public Builder putAll(Map extras) { + if (extras != null) { + this.extra.putAll(extras); + } + return this; + } + + public RuntimeContext build() { + return new RuntimeContext(this); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java new file mode 100644 index 000000000..9d53638ad --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java @@ -0,0 +1,108 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import java.util.List; +import java.util.Map; + +/** + * Abstract filesystem API for agents: list, read, write, edit, grep, glob, upload, download. + * + *

Implementations may target the local disk, a sandbox, a key-value store, or other storage. + */ +public interface AbstractFilesystem { + + /** + * List all files in a directory with metadata. + * + * @param path absolute path to the directory to list (must start with '/') + * @return LsResult with directory entries or error + */ + LsResult ls(String path); + + /** + * Read file content with optional line-based pagination. + * + * @param filePath absolute path to the file to read (must start with '/') + * @param offset line number to start reading from (0-indexed). Default: 0 + * @param limit maximum number of lines to read. Default: 2000 + * @return ReadResult with file data on success or error on failure + */ + ReadResult read(String filePath, int offset, int limit); + + /** + * Write content to a new file, error if file already exists. + * + * @param filePath absolute path where the file should be created + * @param content string content to write to the file + * @return WriteResult with path on success, or error if the file already exists or write fails + */ + WriteResult write(String filePath, String content); + + /** + * Perform exact string replacements in an existing file. + * + * @param filePath absolute path to the file to edit + * @param oldString exact string to search for and replace + * @param newString string to replace oldString with (must be different from oldString) + * @param replaceAll if true, replace all occurrences; if false, oldString must be unique + * @return EditResult with path and occurrence count on success, or error on failure + */ + EditResult edit(String filePath, String oldString, String newString, boolean replaceAll); + + /** + * Search for a literal text pattern in files. + * + * @param pattern literal string to search for (not regex) + * @param path optional directory path to search in (null searches current working directory) + * @param glob optional glob pattern to filter which files to search (e.g., "*.java") + * @return GrepResult with matches or error + */ + GrepResult grep(String pattern, String path, String glob); + + /** + * Find files matching a glob pattern. + * + * @param pattern glob pattern with wildcards to match file paths + * @param path base directory to search from (default: "/") + * @return GlobResult with matching files or error + */ + GlobResult glob(String pattern, String path); + + /** + * Upload multiple files. + * + * @param files list of path-to-content mappings to upload + * @return list of FileUploadResponse objects, one per input file (order matches input order) + */ + List uploadFiles(List> files); + + /** + * Download multiple files. + * + * @param paths list of file paths to download + * @return list of FileDownloadResponse objects, one per input path (order matches input order) + */ + List downloadFiles(List paths); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractSandboxFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractSandboxFilesystem.java new file mode 100644 index 000000000..b33230445 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractSandboxFilesystem.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; + +/** + * Filesystem abstraction that adds shell command execution (sandbox or remote host). + * + *

Extends {@link AbstractFilesystem} with {@link #execute} and {@link #id()}. + */ +public interface AbstractSandboxFilesystem extends AbstractFilesystem { + + /** + * Unique identifier for this filesystem/sandbox instance. + * + * @return id string + */ + String id(); + + /** + * Execute a shell command in the environment backing this filesystem. + * + * @param command full shell command string to execute + * @param timeoutSeconds maximum time in seconds to wait for the command to complete; + * {@code null} uses the filesystem's default timeout + * @return ExecuteResponse with combined output, exit code, and truncation flag + */ + ExecuteResponse execute(String command, Integer timeoutSeconds); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java new file mode 100644 index 000000000..d9f662c8e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java @@ -0,0 +1,374 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; +import io.agentscope.harness.agent.filesystem.model.FileData; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepMatch; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; + +/** + * Abstract base sandbox implementation with {@link #execute} as the core abstract method. + * + *

This class provides default implementations for all {@link AbstractFilesystem} methods by + * delegating + * to shell commands via {@link #execute}. File listing, grep, and glob use standard Unix + * commands. Read uses server-side commands for paginated access. Write delegates content + * transfer to {@link #uploadFiles}. Edit uses server-side commands for string replacement. + * + *

Subclasses must implement: + *

    + *
  • {@link #execute} - execute a command in the sandbox
  • + *
  • {@link #uploadFiles} - upload files to the sandbox
  • + *
  • {@link #downloadFiles} - download files from the sandbox
  • + *
  • {@link #id()} - unique identifier for the sandbox instance
  • + *
+ */ +public abstract class BaseSandboxFilesystem implements AbstractSandboxFilesystem { + + private NamespaceFactory namespaceFactory; + + protected NamespaceFactory getNamespaceFactory() { + return namespaceFactory; + } + + protected void setNamespaceFactory(NamespaceFactory namespaceFactory) { + this.namespaceFactory = namespaceFactory; + } + + protected String namespacedPath(String path) { + if (namespaceFactory == null || path == null || path.isBlank()) { + return path; + } + List ns = namespaceFactory.getNamespace(); + if (ns == null || ns.isEmpty()) { + return path; + } + String prefix = String.join("/", ns); + if (path.startsWith("/")) { + return "/" + prefix + path; + } + return prefix + "/" + path; + } + + @Override + public abstract String id(); + + @Override + public abstract ExecuteResponse execute(String command, Integer timeoutSeconds); + + @Override + public abstract List uploadFiles(List> files); + + @Override + public abstract List downloadFiles(List paths); + + @Override + public LsResult ls(String path) { + String escapedPath = FilesystemUtils.shellQuote(namespacedPath(path)); + String cmd = + "for f in " + + escapedPath + + "/*; do " + + " if [ -d \"$f\" ]; then echo \"DIR:$f\"; " + + " elif [ -f \"$f\" ]; then echo \"FILE:$f\"; fi; " + + "done 2>/dev/null"; + + ExecuteResponse result = execute(cmd, null); + List entries = new ArrayList<>(); + + if (result.output() != null && !result.output().isBlank()) { + for (String line : result.output().strip().split("\n")) { + if (line.startsWith("DIR:")) { + entries.add(FileInfo.ofDir(line.substring(4), "")); + } else if (line.startsWith("FILE:")) { + entries.add(FileInfo.ofFile(line.substring(5), 0, "")); + } + } + } + + return LsResult.success(entries); + } + + @Override + public ReadResult read(String filePath, int offset, int limit) { + String nsPath = namespacedPath(filePath); + String fileType = FilesystemUtils.getFileType(nsPath); + String escapedPath = FilesystemUtils.shellQuote(nsPath); + + if (!"text".equals(fileType)) { + String cmd = "base64 " + escapedPath + " 2>/dev/null"; + ExecuteResponse result = execute(cmd, null); + if (result.exitCode() != null && result.exitCode() != 0) { + return ReadResult.fail("File '" + filePath + "': file_not_found"); + } + String encoded = result.output() != null ? result.output().strip() : ""; + return ReadResult.success(new FileData(encoded, "base64")); + } + + int startLine = offset + 1; + int endLine = limit > 0 ? offset + limit : Integer.MAX_VALUE; + String cmd = + "if [ ! -f " + + escapedPath + + " ]; then echo '__NOT_FOUND__'; " + + "elif [ ! -s " + + escapedPath + + " ]; then echo '__EMPTY__'; " + + "else sed -n '" + + startLine + + "," + + endLine + + "p' " + + escapedPath + + "; fi"; + + ExecuteResponse result = execute(cmd, null); + String output = result.output() != null ? result.output() : ""; + + if (output.strip().equals("__NOT_FOUND__")) { + return ReadResult.fail("File '" + filePath + "': file_not_found"); + } + if (output.strip().equals("__EMPTY__")) { + return ReadResult.success( + new FileData("System reminder: File exists but has empty contents", "utf-8")); + } + + if (output.endsWith("\n")) { + output = output.substring(0, output.length() - 1); + } + return ReadResult.success(new FileData(output, "utf-8")); + } + + @Override + public WriteResult write(String filePath, String content) { + String nsPath = namespacedPath(filePath); + String escapedPath = FilesystemUtils.shellQuote(nsPath); + String checkCmd = + "if [ -e " + + escapedPath + + " ]; then echo 'EXISTS'; exit 1; fi; " + + "mkdir -p \"$(dirname " + + escapedPath + + ")\" 2>&1"; + + ExecuteResponse checkResult = execute(checkCmd, null); + if (checkResult.exitCode() != null && checkResult.exitCode() != 0) { + if (checkResult.output() != null && checkResult.output().contains("EXISTS")) { + return WriteResult.fail( + "Cannot write to " + + filePath + + " because it already exists. Read and then make an" + + " edit, or write to a new path."); + } + return WriteResult.fail("Failed to write file '" + filePath + "'"); + } + + List responses = + uploadFiles( + List.of( + Map.entry( + nsPath, + content.getBytes( + java.nio.charset.StandardCharsets.UTF_8)))); + if (responses.isEmpty() || !responses.get(0).isSuccess()) { + String err = + responses.isEmpty() ? "upload returned no response" : responses.get(0).error(); + return WriteResult.fail("Failed to write file '" + filePath + "': " + err); + } + + return WriteResult.ok(filePath); + } + + @Override + public EditResult edit( + String filePath, String oldString, String newString, boolean replaceAll) { + String nsPath = namespacedPath(filePath); + String payload = + "{\"path\":\"" + + jsonEscape(nsPath) + + "\"," + + "\"old\":\"" + + jsonEscape(oldString) + + "\"," + + "\"new\":\"" + + jsonEscape(newString) + + "\"," + + "\"replace_all\":" + + replaceAll + + "}"; + String payloadB64 = + Base64.getEncoder() + .encodeToString(payload.getBytes(java.nio.charset.StandardCharsets.UTF_8)); + + String cmd = + "python3 -c \"import sys, os, base64, json\\n" + + "payload =" + + " json.loads(base64.b64decode(sys.stdin.read().strip()).decode('utf-8'))\\n" + + "path, old, new = payload['path'], payload['old'], payload['new']\\n" + + "replace_all = payload.get('replace_all', False)\\n" + + "if not os.path.isfile(path):\\n" + + " print(json.dumps({'error': 'file_not_found'}))\\n" + + " sys.exit(0)\\n" + + "with open(path, 'rb') as f: text = f.read().decode('utf-8')\\n" + + "count = text.count(old)\\n" + + "if count == 0:\\n" + + " print(json.dumps({'error': 'string_not_found'}))\\n" + + " sys.exit(0)\\n" + + "if count > 1 and not replace_all:\\n" + + " print(json.dumps({'error': 'multiple_occurrences', 'count': count}))\\n" + + " sys.exit(0)\\n" + + "result = text.replace(old, new) if replace_all else text.replace(old, new," + + " 1)\\n" + + "with open(path, 'wb') as f: f.write(result.encode('utf-8'))\\n" + + "print(json.dumps({'count': count}))\\n" + + "\" 2>&1 <<'__EDIT_EOF__'\n" + + payloadB64 + + "\n__EDIT_EOF__\n"; + + ExecuteResponse result = execute(cmd, null); + String output = result.output() != null ? result.output().strip() : ""; + + if (output.contains("\"error\"")) { + if (output.contains("file_not_found")) { + return EditResult.fail("Error: File '" + filePath + "' not found"); + } + if (output.contains("string_not_found")) { + return EditResult.fail("Error: String not found in file: '" + oldString + "'"); + } + if (output.contains("multiple_occurrences")) { + return EditResult.fail( + "Error: String '" + + oldString + + "' appears multiple times. Use replaceAll=true to replace all" + + " occurrences."); + } + return EditResult.fail("Error editing file '" + filePath + "': " + output); + } + + if (output.contains("\"count\"")) { + try { + int countIdx = output.indexOf("\"count\":") + 8; + int endIdx = output.indexOf('}', countIdx); + int count = Integer.parseInt(output.substring(countIdx, endIdx).trim()); + return EditResult.ok(filePath, count); + } catch (NumberFormatException e) { + return EditResult.ok(filePath, 1); + } + } + + return EditResult.fail( + "Error editing file '" + + filePath + + "': unexpected server response: " + + output.substring(0, Math.min(200, output.length()))); + } + + @Override + public GrepResult grep(String pattern, String path, String glob) { + String nsPath = path != null ? namespacedPath(path) : "."; + String searchPath = FilesystemUtils.shellQuote(nsPath); + String grepOpts = "-rHnF"; + String globPattern = ""; + if (glob != null && !glob.isBlank()) { + globPattern = "--include=" + FilesystemUtils.shellQuote(glob); + } + String patternEscaped = FilesystemUtils.shellQuote(pattern); + + String cmd = + "grep " + + grepOpts + + " " + + globPattern + + " -e " + + patternEscaped + + " " + + searchPath + + " 2>/dev/null || true"; + + ExecuteResponse result = execute(cmd, null); + String output = result.output() != null ? result.output().strip() : ""; + + if (output.isEmpty()) { + return GrepResult.success(List.of()); + } + + List matches = new ArrayList<>(); + for (String line : output.split("\n")) { + String[] parts = line.split(":", 3); + if (parts.length >= 3) { + try { + matches.add(new GrepMatch(parts[0], Integer.parseInt(parts[1]), parts[2])); + } catch (NumberFormatException e) { + // skip malformed lines + } + } + } + + return GrepResult.success(matches); + } + + @Override + public GlobResult glob(String pattern, String path) { + String effectivePath = path != null ? namespacedPath(path) : "/"; + String escapedPath = FilesystemUtils.shellQuote(effectivePath); + String escapedPattern = FilesystemUtils.shellQuote(pattern); + + String cmd = + "find " + escapedPath + " -type f -name " + escapedPattern + " 2>/dev/null | sort"; + + ExecuteResponse result = execute(cmd, null); + String output = result.output() != null ? result.output().strip() : ""; + + if (output.isEmpty()) { + return GlobResult.success(List.of()); + } + + List entries = new ArrayList<>(); + for (String line : output.split("\n")) { + if (!line.isBlank()) { + entries.add(FileInfo.ofFile(line.trim(), 0, "")); + } + } + + return GlobResult.success(entries); + } + + private static String jsonEscape(String s) { + if (s == null) { + return ""; + } + return s.replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t"); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java new file mode 100644 index 000000000..74281e374 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java @@ -0,0 +1,372 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepMatch; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Routes file operations to different {@link AbstractFilesystem} backends by path prefix. + * + *

Paths are matched against route prefixes (longest first). Unmatched paths fall through to the + * default backend. If the default backend implements {@link AbstractSandboxFilesystem}, shell + * execution is also supported. + * + *

Example: + * + *

{@code
+ * CompositeFilesystem fs = new CompositeFilesystem(
+ *     localShell,
+ *     Map.of("/memories/", storeFs, "/cache/", inMemoryFs)
+ * );
+ * fs.read("/memories/notes.md", 0, 100);  // → storeFs.read("/notes.md", ...)
+ * fs.read("/src/Main.java", 0, 100);      // → localShell.read("/src/Main.java", ...)
+ * }
+ */ +public class CompositeFilesystem implements AbstractSandboxFilesystem { + + private final AbstractFilesystem defaultBackend; + private final List sortedRoutes; + + /** + * Creates a composite filesystem with a default backend and prefix-based routes. + * + * @param defaultBackend backend for paths that don't match any route + * @param routes map of path prefixes to backends; prefixes must start with {@code "/"} + * and should end with {@code "/"} (e.g. {@code "/memories/"}) + */ + public CompositeFilesystem( + AbstractFilesystem defaultBackend, Map routes) { + if (defaultBackend == null) { + throw new IllegalArgumentException("defaultBackend must not be null"); + } + this.defaultBackend = defaultBackend; + + List entries = new ArrayList<>(); + if (routes != null) { + for (Map.Entry e : routes.entrySet()) { + entries.add(new RouteEntry(e.getKey(), e.getValue())); + } + } + entries.sort(Comparator.comparingInt((RouteEntry e) -> e.prefix().length()).reversed()); + this.sortedRoutes = List.copyOf(entries); + } + + // ==================== Routing ==================== + + private record RouteEntry(String prefix, AbstractFilesystem backend) {} + + private record RouteResult( + AbstractFilesystem backend, String backendPath, String routePrefix) {} + + private RouteResult routeForPath(String path) { + for (RouteEntry entry : sortedRoutes) { + String prefixNoSlash = + entry.prefix().endsWith("/") + ? entry.prefix().substring(0, entry.prefix().length() - 1) + : entry.prefix(); + if (path.equals(prefixNoSlash)) { + return new RouteResult(entry.backend(), "/", entry.prefix()); + } + String normalizedPrefix = + entry.prefix().endsWith("/") ? entry.prefix() : entry.prefix() + "/"; + if (path.startsWith(normalizedPrefix)) { + String suffix = path.substring(normalizedPrefix.length()); + String backendPath = suffix.isEmpty() ? "/" : "/" + suffix; + return new RouteResult(entry.backend(), backendPath, entry.prefix()); + } + } + return new RouteResult(defaultBackend, path, null); + } + + // ==================== Path remapping helpers ==================== + + private static String prependRoute(String routePrefix, String backendPath) { + String base = + routePrefix.endsWith("/") + ? routePrefix.substring(0, routePrefix.length() - 1) + : routePrefix; + return base + backendPath; + } + + private static FileInfo remapFileInfo(FileInfo fi, String routePrefix) { + return new FileInfo( + prependRoute(routePrefix, fi.path()), fi.isDirectory(), fi.size(), fi.modifiedAt()); + } + + private static GrepMatch remapGrepMatch(GrepMatch m, String routePrefix) { + return new GrepMatch(prependRoute(routePrefix, m.path()), m.line(), m.text()); + } + + private static String stripRouteFromPattern(String pattern, String routePrefix) { + String barePattern = pattern.startsWith("/") ? pattern.substring(1) : pattern; + String barePrefix = routePrefix.replaceAll("^/|/$", "") + "/"; + if (barePattern.startsWith(barePrefix)) { + return barePattern.substring(barePrefix.length()); + } + return pattern; + } + + // ==================== AbstractFilesystem ==================== + + @Override + public LsResult ls(String path) { + RouteResult route = routeForPath(path); + + if (route.routePrefix() != null) { + LsResult result = route.backend().ls(route.backendPath()); + if (!result.isSuccess()) { + return result; + } + List remapped = new ArrayList<>(); + for (FileInfo fi : result.entries()) { + remapped.add(remapFileInfo(fi, route.routePrefix())); + } + return LsResult.success(remapped); + } + + if ("/".equals(path)) { + List results = new ArrayList<>(); + LsResult defaultResult = defaultBackend.ls(path); + if (defaultResult.isSuccess() && defaultResult.entries() != null) { + results.addAll(defaultResult.entries()); + } + for (RouteEntry entry : sortedRoutes) { + String dirPath = + entry.prefix().endsWith("/") ? entry.prefix() : entry.prefix() + "/"; + results.add(FileInfo.ofDir(dirPath, "")); + } + results.sort(Comparator.comparing(FileInfo::path)); + return LsResult.success(results); + } + + return defaultBackend.ls(path); + } + + @Override + public ReadResult read(String filePath, int offset, int limit) { + RouteResult route = routeForPath(filePath); + return route.backend().read(route.backendPath(), offset, limit); + } + + @Override + public WriteResult write(String filePath, String content) { + RouteResult route = routeForPath(filePath); + WriteResult result = route.backend().write(route.backendPath(), content); + if (result.isSuccess() && route.routePrefix() != null) { + return WriteResult.ok(filePath); + } + return result; + } + + @Override + public EditResult edit( + String filePath, String oldString, String newString, boolean replaceAll) { + RouteResult route = routeForPath(filePath); + EditResult result = + route.backend().edit(route.backendPath(), oldString, newString, replaceAll); + if (result.isSuccess() && route.routePrefix() != null) { + return EditResult.ok(filePath, result.occurrences()); + } + return result; + } + + @Override + public GrepResult grep(String pattern, String path, String glob) { + if (path != null) { + RouteResult route = routeForPath(path); + if (route.routePrefix() != null) { + GrepResult result = route.backend().grep(pattern, route.backendPath(), glob); + if (!result.isSuccess()) { + return result; + } + List remapped = new ArrayList<>(); + for (GrepMatch m : result.matches()) { + remapped.add(remapGrepMatch(m, route.routePrefix())); + } + return GrepResult.success(remapped); + } + } + + if (path == null || "/".equals(path)) { + List allMatches = new ArrayList<>(); + GrepResult defaultResult = defaultBackend.grep(pattern, path, glob); + if (!defaultResult.isSuccess()) { + return defaultResult; + } + if (defaultResult.matches() != null) { + allMatches.addAll(defaultResult.matches()); + } + for (RouteEntry entry : sortedRoutes) { + GrepResult routeResult = entry.backend().grep(pattern, "/", glob); + if (!routeResult.isSuccess()) { + return routeResult; + } + if (routeResult.matches() != null) { + for (GrepMatch m : routeResult.matches()) { + allMatches.add(remapGrepMatch(m, entry.prefix())); + } + } + } + return GrepResult.success(allMatches); + } + + return defaultBackend.grep(pattern, path, glob); + } + + @Override + public GlobResult glob(String pattern, String path) { + RouteResult route = routeForPath(path); + + if (route.routePrefix() != null) { + GlobResult result = route.backend().glob(pattern, route.backendPath()); + if (!result.isSuccess()) { + return result; + } + List remapped = new ArrayList<>(); + for (FileInfo fi : result.matches()) { + remapped.add(remapFileInfo(fi, route.routePrefix())); + } + return GlobResult.success(remapped); + } + + List results = new ArrayList<>(); + GlobResult defaultResult = defaultBackend.glob(pattern, path); + if (defaultResult.isSuccess() && defaultResult.matches() != null) { + results.addAll(defaultResult.matches()); + } + for (RouteEntry entry : sortedRoutes) { + String routePattern = stripRouteFromPattern(pattern, entry.prefix()); + GlobResult routeResult = entry.backend().glob(routePattern, "/"); + if (routeResult.isSuccess() && routeResult.matches() != null) { + for (FileInfo fi : routeResult.matches()) { + results.add(remapFileInfo(fi, entry.prefix())); + } + } + } + results.sort(Comparator.comparing(FileInfo::path)); + return GlobResult.success(results); + } + + @Override + public List uploadFiles(List> files) { + FileUploadResponse[] results = new FileUploadResponse[files.size()]; + Map> batches = new HashMap<>(); + + for (int i = 0; i < files.size(); i++) { + Map.Entry file = files.get(i); + RouteResult route = routeForPath(file.getKey()); + batches.computeIfAbsent(route.backend(), k -> new ArrayList<>()) + .add(new IndexedFile(i, file.getKey(), route.backendPath(), file.getValue())); + } + + for (Map.Entry> batch : batches.entrySet()) { + List> batchFiles = new ArrayList<>(); + for (IndexedFile f : batch.getValue()) { + batchFiles.add(Map.entry(f.backendPath(), f.content())); + } + List responses = batch.getKey().uploadFiles(batchFiles); + List indexed = batch.getValue(); + for (int i = 0; i < responses.size() && i < indexed.size(); i++) { + results[indexed.get(i).originalIndex()] = + FileUploadResponse.success(indexed.get(i).originalPath()); + } + } + + return List.of(results); + } + + @Override + public List downloadFiles(List paths) { + FileDownloadResponse[] results = new FileDownloadResponse[paths.size()]; + Map> batches = new HashMap<>(); + Map> batchPaths = new HashMap<>(); + + for (int i = 0; i < paths.size(); i++) { + RouteResult route = routeForPath(paths.get(i)); + batches.computeIfAbsent(route.backend(), k -> new ArrayList<>()).add(new int[] {i}); + batchPaths + .computeIfAbsent(route.backend(), k -> new ArrayList<>()) + .add(route.backendPath()); + } + + for (Map.Entry> batch : batchPaths.entrySet()) { + List responses = batch.getKey().downloadFiles(batch.getValue()); + List indices = batches.get(batch.getKey()); + for (int i = 0; i < responses.size() && i < indices.size(); i++) { + FileDownloadResponse resp = responses.get(i); + int origIdx = indices.get(i)[0]; + results[origIdx] = + resp.error() != null + ? FileDownloadResponse.fail(paths.get(origIdx), resp.error()) + : FileDownloadResponse.success(paths.get(origIdx), resp.content()); + } + } + + return List.of(results); + } + + // ==================== AbstractSandboxFilesystem ==================== + + @Override + public String id() { + if (defaultBackend instanceof AbstractSandboxFilesystem sandbox) { + return sandbox.id(); + } + return "composite"; + } + + @Override + public ExecuteResponse execute(String command, Integer timeoutSeconds) { + if (defaultBackend instanceof AbstractSandboxFilesystem sandbox) { + return sandbox.execute(command, timeoutSeconds); + } + throw new UnsupportedOperationException( + "Default backend does not support command execution (AbstractSandboxFilesystem). " + + "To enable execution, provide a default backend that implements" + + " AbstractSandboxFilesystem."); + } + + /** + * Whether this composite filesystem supports shell execution (i.e. the default backend is a + * sandbox). + */ + public boolean isSandbox() { + return defaultBackend instanceof AbstractSandboxFilesystem; + } + + /** Returns the default backend. */ + public AbstractFilesystem getDefaultBackend() { + return defaultBackend; + } + + private record IndexedFile( + int originalIndex, String originalPath, String backendPath, byte[] content) {} +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java new file mode 100644 index 000000000..76663d49b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java @@ -0,0 +1,598 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.FileData; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepMatch; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link AbstractFilesystem} implementation that reads and writes files on the local disk. + * + *

When {@code virtualMode} is enabled, paths are anchored to {@code rootDir} and traversal is + * blocked. + */ +public class LocalFilesystem implements AbstractFilesystem { + + private static final Logger log = LoggerFactory.getLogger(LocalFilesystem.class); + + private static final int DEFAULT_MAX_FILE_SIZE_MB = 10; + + private final Path cwd; + private final boolean virtualMode; + private final long maxFileSizeBytes; + private final NamespaceFactory namespaceFactory; + + /** + * Creates a abstract filesystem rooted at the given directory. + * + * @param rootDir root directory for all operations ({@code null} means CWD) + */ + public LocalFilesystem(Path rootDir) { + this(rootDir, false, DEFAULT_MAX_FILE_SIZE_MB, null); + } + + /** + * Creates a abstract filesystem with explicit configuration. + * + * @param rootDir root directory for all operations ({@code null} means CWD) + * @param virtualMode when true, all paths are anchored to rootDir and traversal is blocked + * @param maxFileSizeMb maximum file size in megabytes for search operations + */ + public LocalFilesystem(Path rootDir, boolean virtualMode, int maxFileSizeMb) { + this(rootDir, virtualMode, maxFileSizeMb, null); + } + + /** + * Creates a abstract filesystem with explicit configuration and namespace support. + * + *

When a {@link NamespaceFactory} is provided, all paths are prefixed with the + * namespace segments joined as subdirectories. For example, with namespace {@code ["user123"]}, + * a read of {@code "MEMORY.md"} resolves to {@code {rootDir}/user123/MEMORY.md}. + * + * @param rootDir root directory for all operations ({@code null} means CWD) + * @param virtualMode when true, all paths are anchored to rootDir and traversal is blocked + * @param maxFileSizeMb maximum file size in megabytes for search operations + * @param namespaceFactory optional namespace factory for path scoping ({@code null} for none) + */ + public LocalFilesystem( + Path rootDir, + boolean virtualMode, + int maxFileSizeMb, + NamespaceFactory namespaceFactory) { + this.cwd = + rootDir != null + ? rootDir.toAbsolutePath().normalize() + : Path.of("").toAbsolutePath(); + this.virtualMode = virtualMode; + this.maxFileSizeBytes = (long) maxFileSizeMb * 1024 * 1024; + this.namespaceFactory = namespaceFactory; + } + + /** + * Returns the root directory for this filesystem. + */ + public Path getCwd() { + return cwd; + } + + @Override + public LsResult ls(String path) { + Path dirPath = resolvePath(path); + if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) { + return LsResult.success(List.of()); + } + + List results = new ArrayList<>(); + try (DirectoryStream ds = Files.newDirectoryStream(dirPath)) { + for (Path entry : ds) { + try { + BasicFileAttributes attrs = + Files.readAttributes(entry, BasicFileAttributes.class); + String entryPath = + virtualMode ? toVirtualPath(entry) : entry.toAbsolutePath().toString(); + String modifiedAt = + Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()).toString(); + + if (attrs.isDirectory()) { + results.add(FileInfo.ofDir(entryPath + "/", modifiedAt)); + } else { + results.add(FileInfo.ofFile(entryPath, attrs.size(), modifiedAt)); + } + } catch (IOException e) { + log.debug("Skipping unreadable entry: {}", entry); + } + } + } catch (IOException e) { + log.warn("ls failed for {}: {}", path, e.getMessage()); + } + + results.sort(Comparator.comparing(FileInfo::path)); + return LsResult.success(results); + } + + @Override + public ReadResult read(String filePath, int offset, int limit) { + Path resolved = resolvePath(filePath); + + if (!Files.exists(resolved) || !Files.isRegularFile(resolved)) { + return ReadResult.fail("File '" + filePath + "' not found"); + } + + try { + if (!"text".equals(FilesystemUtils.getFileType(filePath))) { + byte[] raw = Files.readAllBytes(resolved); + String encoded = Base64.getEncoder().encodeToString(raw); + return ReadResult.success(new FileData(encoded, "base64")); + } + + String content = Files.readString(resolved, StandardCharsets.UTF_8); + + if (content.isEmpty() || content.isBlank()) { + return ReadResult.success( + new FileData( + "System reminder: File exists but has empty contents", "utf-8")); + } + + String[] lines = content.split("\n", -1); + int startIdx = Math.max(0, offset); + int endIdx = limit > 0 ? Math.min(startIdx + limit, lines.length) : lines.length; + + if (startIdx >= lines.length) { + return ReadResult.fail( + "Line offset " + + offset + + " exceeds file length (" + + lines.length + + " lines)"); + } + + StringBuilder sb = new StringBuilder(); + for (int i = startIdx; i < endIdx; i++) { + if (i > startIdx) { + sb.append('\n'); + } + sb.append(lines[i]); + } + return ReadResult.success(new FileData(sb.toString(), "utf-8")); + + } catch (IOException e) { + return ReadResult.fail("Error reading file '" + filePath + "': " + e.getMessage()); + } + } + + @Override + public WriteResult write(String filePath, String content) { + Path resolved = resolvePath(filePath); + + if (Files.exists(resolved)) { + return WriteResult.fail( + "Cannot write to " + + filePath + + " because it already exists. Read and then make an edit," + + " or write to a new path."); + } + + try { + if (resolved.getParent() != null) { + Files.createDirectories(resolved.getParent()); + } + Files.writeString(resolved, content, StandardCharsets.UTF_8); + return WriteResult.ok(filePath); + } catch (IOException e) { + return WriteResult.fail("Error writing file '" + filePath + "': " + e.getMessage()); + } + } + + @Override + public EditResult edit( + String filePath, String oldString, String newString, boolean replaceAll) { + Path resolved = resolvePath(filePath); + + if (!Files.exists(resolved) || !Files.isRegularFile(resolved)) { + return EditResult.fail("Error: File '" + filePath + "' not found"); + } + + try { + String content = Files.readString(resolved, StandardCharsets.UTF_8); + String normalizedOld = oldString.replace("\r\n", "\n").replace("\r", "\n"); + String normalizedNew = newString.replace("\r\n", "\n").replace("\r", "\n"); + + Object[] result = + FilesystemUtils.performStringReplacement( + content, normalizedOld, normalizedNew, replaceAll); + + if (result.length == 1) { + return EditResult.fail((String) result[0]); + } + + String newContent = (String) result[0]; + int occurrences = (int) result[1]; + + Files.writeString(resolved, newContent, StandardCharsets.UTF_8); + return EditResult.ok(filePath, occurrences); + } catch (IOException e) { + return EditResult.fail("Error editing file '" + filePath + "': " + e.getMessage()); + } + } + + @Override + public GrepResult grep(String pattern, String path, String glob) { + Path basePath; + try { + basePath = resolvePath(path != null ? path : "."); + } catch (SecurityException e) { + return GrepResult.success(List.of()); + } + + if (!Files.exists(basePath)) { + return GrepResult.success(List.of()); + } + + List matches = ripgrepSearch(pattern, basePath, glob); + if (matches == null) { + matches = javaSearch(pattern, basePath, glob); + } + return GrepResult.success(matches); + } + + @Override + public GlobResult glob(String pattern, String path) { + String effectivePattern = pattern; + if (effectivePattern.startsWith("/")) { + effectivePattern = effectivePattern.substring(1); + } + + Path searchPath; + if ("/".equals(path) || path == null) { + searchPath = cwd; + } else { + searchPath = resolvePath(path); + } + + if (!Files.exists(searchPath) || !Files.isDirectory(searchPath)) { + return GlobResult.success(List.of()); + } + + String globExpr = + effectivePattern.startsWith("**") ? effectivePattern : "**/" + effectivePattern; + FileSystem fs = FileSystems.getDefault(); + PathMatcher matcher = fs.getPathMatcher("glob:" + globExpr); + + List results = new ArrayList<>(); + try { + Files.walkFileTree( + searchPath, + new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + Path rel = searchPath.relativize(file); + if (matcher.matches(rel)) { + String filePath = + virtualMode + ? toVirtualPath(file) + : file.toAbsolutePath().toString(); + String modifiedAt = + Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()) + .toString(); + results.add(FileInfo.ofFile(filePath, attrs.size(), modifiedAt)); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + log.warn("glob failed for {}: {}", pattern, e.getMessage()); + } + + results.sort(Comparator.comparing(FileInfo::path)); + return GlobResult.success(results); + } + + @Override + public List uploadFiles(List> files) { + List responses = new ArrayList<>(); + for (Map.Entry entry : files) { + String filePath = entry.getKey(); + byte[] content = entry.getValue(); + try { + Path resolved = resolvePath(filePath); + if (resolved.getParent() != null) { + Files.createDirectories(resolved.getParent()); + } + Files.write(resolved, content); + responses.add(FileUploadResponse.success(filePath)); + } catch (IOException e) { + responses.add(FileUploadResponse.fail(filePath, e.getMessage())); + } catch (SecurityException e) { + responses.add(FileUploadResponse.fail(filePath, "permission_denied")); + } + } + return responses; + } + + @Override + public List downloadFiles(List paths) { + List responses = new ArrayList<>(); + for (String filePath : paths) { + try { + Path resolved = resolvePath(filePath); + if (!Files.exists(resolved)) { + responses.add(FileDownloadResponse.fail(filePath, "file_not_found")); + continue; + } + if (Files.isDirectory(resolved)) { + responses.add(FileDownloadResponse.fail(filePath, "is_directory")); + continue; + } + byte[] content = Files.readAllBytes(resolved); + responses.add(FileDownloadResponse.success(filePath, content)); + } catch (IOException e) { + responses.add(FileDownloadResponse.fail(filePath, e.getMessage())); + } catch (SecurityException e) { + responses.add(FileDownloadResponse.fail(filePath, "permission_denied")); + } + } + return responses; + } + + // ==================== Path resolution ==================== + + protected NamespaceFactory getNamespaceFactory() { + return namespaceFactory; + } + + protected Path resolvePath(String key) { + String effectiveKey = applyNamespacePrefix(key); + if (effectiveKey == null || effectiveKey.isBlank()) { + return cwd; + } + + if (virtualMode) { + String vpath = effectiveKey.startsWith("/") ? effectiveKey : "/" + effectiveKey; + if (vpath.contains("..") || vpath.startsWith("~")) { + throw new SecurityException("Path traversal not allowed"); + } + Path full = cwd.resolve(vpath.substring(1)).normalize(); + if (!full.startsWith(cwd)) { + throw new SecurityException("Path " + full + " outside root directory: " + cwd); + } + return full; + } + + Path target = Path.of(effectiveKey); + if (target.isAbsolute()) { + return target; + } + return cwd.resolve(target).normalize(); + } + + private String applyNamespacePrefix(String key) { + if (namespaceFactory == null || key == null || key.isBlank()) { + return key; + } + List ns = namespaceFactory.getNamespace(); + if (ns == null || ns.isEmpty()) { + return key; + } + String prefix = String.join("/", ns); + return prefix + "/" + key; + } + + protected String toVirtualPath(Path path) { + return "/" + + path.toAbsolutePath() + .normalize() + .toString() + .substring(cwd.toString().length()) + .replace('\\', '/') + .replaceFirst("^/+", ""); + } + + // ==================== Grep implementations ==================== + + private List ripgrepSearch(String pattern, Path basePath, String includeGlob) { + List cmd = new ArrayList<>(); + cmd.add("rg"); + cmd.add("--json"); + cmd.add("-F"); + if (includeGlob != null && !includeGlob.isBlank()) { + cmd.add("--glob"); + cmd.add(includeGlob); + } + cmd.add("--"); + cmd.add(pattern); + cmd.add(basePath.toString()); + + try { + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); + Process proc = pb.start(); + + List matches = new ArrayList<>(); + try (BufferedReader reader = + new BufferedReader( + new InputStreamReader(proc.getInputStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + GrepMatch match = parseRipgrepJsonLine(line); + if (match != null) { + matches.add(match); + } + } + } + + proc.waitFor(); + return matches; + + } catch (IOException | InterruptedException e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + return null; + } + } + + private GrepMatch parseRipgrepJsonLine(String jsonLine) { + try { + if (!jsonLine.contains("\"type\":\"match\"")) { + return null; + } + String pathText = extractJsonStringField(jsonLine, "text", "path"); + String lineNumStr = extractJsonField(jsonLine, "line_number"); + String linesText = extractJsonStringField(jsonLine, "text", "lines"); + + if (pathText == null || lineNumStr == null) { + return null; + } + String filePath = virtualMode ? toVirtualPath(Path.of(pathText)) : pathText; + int lineNum = Integer.parseInt(lineNumStr.trim()); + String text = linesText != null ? linesText.replaceAll("[\r\n]+$", "") : ""; + return new GrepMatch(filePath, lineNum, text); + } catch (Exception e) { + return null; + } + } + + private static String extractJsonStringField(String json, String field, String parentField) { + String searchKey = "\"" + parentField + "\":{"; + int parentIdx = json.indexOf(searchKey); + if (parentIdx < 0) { + return extractSimpleJsonString(json, field); + } + String sub = json.substring(parentIdx + searchKey.length()); + return extractSimpleJsonString(sub, field); + } + + private static String extractSimpleJsonString(String json, String field) { + String key = "\"" + field + "\":\""; + int start = json.indexOf(key); + if (start < 0) { + return null; + } + start += key.length(); + int end = json.indexOf('"', start); + if (end < 0) { + return null; + } + return json.substring(start, end); + } + + private static String extractJsonField(String json, String field) { + String key = "\"" + field + "\":"; + int start = json.indexOf(key); + if (start < 0) { + return null; + } + start += key.length(); + int end = start; + while (end < json.length() && json.charAt(end) != ',' && json.charAt(end) != '}') { + end++; + } + return json.substring(start, end).trim(); + } + + private List javaSearch(String pattern, Path basePath, String includeGlob) { + Pattern compiledPattern = Pattern.compile(Pattern.quote(pattern)); + PathMatcher globMatcher = null; + if (includeGlob != null && !includeGlob.isBlank()) { + globMatcher = FileSystems.getDefault().getPathMatcher("glob:" + includeGlob); + } + + List matches = new ArrayList<>(); + Path root = Files.isDirectory(basePath) ? basePath : basePath.getParent(); + + try (Stream walk = Files.walk(root)) { + PathMatcher finalGlobMatcher = globMatcher; + walk.filter(Files::isRegularFile) + .filter( + p -> { + if (finalGlobMatcher != null) { + return finalGlobMatcher.matches(p.getFileName()); + } + return true; + }) + .filter( + p -> { + try { + return Files.size(p) <= maxFileSizeBytes; + } catch (IOException e) { + return false; + } + }) + .forEach( + file -> { + try { + List lines = + Files.readAllLines(file, StandardCharsets.UTF_8); + for (int i = 0; i < lines.size(); i++) { + if (compiledPattern.matcher(lines.get(i)).find()) { + String filePath = + virtualMode + ? toVirtualPath(file) + : file.toAbsolutePath().toString(); + matches.add( + new GrepMatch(filePath, i + 1, lines.get(i))); + } + } + } catch (IOException e) { + // Skip binary/unreadable files + } + }); + } catch (IOException e) { + log.warn("Java search failed: {}", e.getMessage()); + } + + return matches; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java new file mode 100644 index 000000000..dce2a61e2 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java @@ -0,0 +1,257 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; +import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Filesystem with unrestricted local shell command execution. + * + *

This implementation extends {@link LocalFilesystem} to add shell command execution + * capabilities. Commands are executed directly on the host system without any + * sandboxing, process isolation, or security restrictions. + * + *

WARNING: This implementation grants agents BOTH direct filesystem access AND unrestricted + * shell execution on your local machine. Use with extreme caution and only in + * appropriate environments (local dev, CI/CD with proper secret management). + */ +public class LocalFilesystemWithShell extends LocalFilesystem implements AbstractSandboxFilesystem { + + private static final Logger log = LoggerFactory.getLogger(LocalFilesystemWithShell.class); + + /** Default timeout in seconds for shell command execution. */ + public static final int DEFAULT_EXECUTE_TIMEOUT = 120; + + private final String sandboxId; + private final int defaultTimeout; + private final int maxOutputBytes; + private final Map env; + + /** + * Creates an abstract filesystem with default settings. + * + * @param rootDir working directory for both filesystem and shell operations + */ + public LocalFilesystemWithShell(Path rootDir) { + this(rootDir, false, DEFAULT_EXECUTE_TIMEOUT, 100_000, null, false, null); + } + + /** + * Creates an abstract filesystem with default settings and namespace support. + * + * @param rootDir working directory for both filesystem and shell operations + * @param namespaceFactory optional namespace factory for path scoping ({@code null} for none) + */ + public LocalFilesystemWithShell(Path rootDir, NamespaceFactory namespaceFactory) { + this(rootDir, false, DEFAULT_EXECUTE_TIMEOUT, 100_000, null, false, namespaceFactory); + } + + /** + * Creates a abstract filesystem with full configuration. + * + * @param rootDir working directory for both filesystem and shell operations + * @param virtualMode enable virtual path mode for filesystem operations + * @param timeout default maximum time in seconds for shell command execution + * @param maxOutputBytes maximum number of bytes to capture from command output + * @param env environment variables for shell commands ({@code null} for empty) + * @param inheritEnv whether to inherit the parent process's environment variables + */ + public LocalFilesystemWithShell( + Path rootDir, + boolean virtualMode, + int timeout, + int maxOutputBytes, + Map env, + boolean inheritEnv) { + this(rootDir, virtualMode, timeout, maxOutputBytes, env, inheritEnv, null); + } + + /** + * Creates a abstract filesystem with full configuration and namespace support. + * + * @param rootDir working directory for both filesystem and shell operations + * @param virtualMode enable virtual path mode for filesystem operations + * @param timeout default maximum time in seconds for shell command execution + * @param maxOutputBytes maximum number of bytes to capture from command output + * @param env environment variables for shell commands ({@code null} for empty) + * @param inheritEnv whether to inherit the parent process's environment variables + * @param namespaceFactory optional namespace factory for path scoping ({@code null} for none) + */ + public LocalFilesystemWithShell( + Path rootDir, + boolean virtualMode, + int timeout, + int maxOutputBytes, + Map env, + boolean inheritEnv, + NamespaceFactory namespaceFactory) { + super(rootDir, virtualMode, 10, namespaceFactory); + + if (timeout <= 0) { + throw new IllegalArgumentException("timeout must be positive, got " + timeout); + } + + this.defaultTimeout = timeout; + this.maxOutputBytes = maxOutputBytes; + this.sandboxId = "local-" + UUID.randomUUID().toString().substring(0, 8); + + if (inheritEnv) { + Map merged = new java.util.HashMap<>(System.getenv()); + if (env != null) { + merged.putAll(env); + } + this.env = Map.copyOf(merged); + } else { + this.env = env != null ? Map.copyOf(env) : Map.of(); + } + } + + @Override + public String id() { + return sandboxId; + } + + @Override + public ExecuteResponse execute(String command, Integer timeoutSeconds) { + if (command == null || command.isBlank()) { + return new ExecuteResponse("Error: Command must be a non-empty string.", 1, false); + } + + int effectiveTimeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeout; + if (effectiveTimeout <= 0) { + throw new IllegalArgumentException("timeout must be positive, got " + effectiveTimeout); + } + + try { + Path workDir = resolveExecuteCwd(); + ProcessBuilder pb = + new ProcessBuilder("sh", "-c", command) + .directory(workDir.toFile()) + .redirectErrorStream(false); + + if (!env.isEmpty()) { + pb.environment().clear(); + pb.environment().putAll(env); + } + + Process proc = pb.start(); + + boolean finished = proc.waitFor(effectiveTimeout, TimeUnit.SECONDS); + + String stdout = + new String(proc.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + String stderr = + new String(proc.getErrorStream().readAllBytes(), StandardCharsets.UTF_8); + + if (!finished) { + proc.destroyForcibly(); + String msg; + if (timeoutSeconds != null) { + msg = + "Error: Command timed out after " + + effectiveTimeout + + " seconds (custom timeout). The command may be stuck or" + + " require more time."; + } else { + msg = + "Error: Command timed out after " + + effectiveTimeout + + " seconds. For long-running commands, re-run using the" + + " timeout parameter."; + } + return new ExecuteResponse(msg, 124, false); + } + + StringBuilder output = new StringBuilder(); + if (stdout != null && !stdout.isEmpty()) { + output.append(stdout); + } + if (stderr != null && !stderr.isBlank()) { + String[] stderrLines = stderr.strip().split("\n"); + for (String line : stderrLines) { + if (!output.isEmpty()) { + output.append('\n'); + } + output.append("[stderr] ").append(line); + } + } + + String outputStr = output.isEmpty() ? "" : output.toString(); + + boolean truncated = false; + if (outputStr.length() > maxOutputBytes) { + outputStr = + outputStr.substring(0, maxOutputBytes) + + "\n\n... Output truncated at " + + maxOutputBytes + + " bytes."; + truncated = true; + } + + int exitCode = proc.exitValue(); + if (exitCode != 0) { + outputStr = outputStr.stripTrailing() + "\n\nExit code: " + exitCode; + } + + return new ExecuteResponse(outputStr, exitCode, truncated); + + } catch (IOException | InterruptedException e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + log.error("Command execution failed: {}", e.getMessage(), e); + return new ExecuteResponse( + "Error executing command (" + + e.getClass().getSimpleName() + + "): " + + e.getMessage(), + 1, + false); + } + } + + private Path resolveExecuteCwd() { + NamespaceFactory nsf = getNamespaceFactory(); + if (nsf == null) { + return getCwd(); + } + List ns = nsf.getNamespace(); + if (ns == null || ns.isEmpty()) { + return getCwd(); + } + Path namespaced = getCwd(); + for (String segment : ns) { + namespaced = namespaced.resolve(segment); + } + try { + Files.createDirectories(namespaced); + } catch (IOException e) { + log.warn("Failed to create namespace directory {}: {}", namespaced, e.getMessage()); + } + return namespaced; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java new file mode 100644 index 000000000..2967aa08d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java @@ -0,0 +1,470 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.FileData; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepMatch; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import io.agentscope.harness.agent.filesystem.store.BaseStore; +import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.filesystem.store.StoreItem; +import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.PathMatcher; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * {@link AbstractFilesystem} backed by a {@link BaseStore} (persistent, cross-thread). + * + *

Files are organized via namespaces and persist across threads/sessions. The namespace can be + * static (fixed at construction time) or dynamic (resolved at every operation via a {@link + * NamespaceFactory}). + * + *

Dynamic namespace example: + * + *

{@code
+ * StoreFilesystem fs = new StoreFilesystem(store,
+ *     () -> List.of("sessions", sessionIdSupplier.get(), "filesystem"));
+ * }
+ */ +public class StoreFilesystem implements AbstractFilesystem { + + private final BaseStore store; + private final NamespaceFactory namespaceFactory; + + /** + * Creates a StoreFilesystem with a {@link NamespaceFactory} that is called on every operation, + * allowing the namespace to vary based on runtime context. + * + * @param store the store to use for persistence + * @param namespaceFactory factory that returns the namespace tuple per operation + */ + public StoreFilesystem(BaseStore store, NamespaceFactory namespaceFactory) { + if (store == null) { + throw new IllegalArgumentException("store must not be null"); + } + if (namespaceFactory == null) { + throw new IllegalArgumentException("namespaceFactory must not be null"); + } + this.store = store; + this.namespaceFactory = namespaceFactory; + } + + /** + * Creates a StoreFilesystem with a fixed namespace. + * + * @param store the store to use for persistence + * @param namespace the namespace tuple for organizing files + */ + public StoreFilesystem(BaseStore store, List namespace) { + this(store, toFactory(namespace)); + } + + /** + * Creates a StoreFilesystem with a default "filesystem" namespace. + * + * @param store the store to use for persistence + */ + public StoreFilesystem(BaseStore store) { + this(store, List.of("filesystem")); + } + + private static NamespaceFactory toFactory(List namespace) { + if (namespace == null || namespace.isEmpty()) { + throw new IllegalArgumentException("namespace must not be empty"); + } + List frozen = List.copyOf(namespace); + return () -> frozen; + } + + private List getNamespace() { + List ns = namespaceFactory.getNamespace(); + if (ns == null || ns.isEmpty()) { + throw new IllegalStateException("NamespaceFactory returned null or empty namespace"); + } + return ns; + } + + @Override + public LsResult ls(String path) { + List items = searchAllItems(); + List infos = new ArrayList<>(); + Set subdirs = new LinkedHashSet<>(); + + String normalizedPath = path.endsWith("/") ? path : path + "/"; + + for (StoreItem item : items) { + if (!item.key().startsWith(normalizedPath)) { + continue; + } + + String relative = item.key().substring(normalizedPath.length()); + + if (relative.contains("/")) { + String subdirName = relative.substring(0, relative.indexOf('/')); + subdirs.add(normalizedPath + subdirName + "/"); + continue; + } + + FileData fd = convertItemToFileData(item); + if (fd == null) { + continue; + } + int size = fd.content() != null ? fd.content().length() : 0; + infos.add( + FileInfo.ofFile( + item.key(), size, fd.modifiedAt() != null ? fd.modifiedAt() : "")); + } + + for (String subdir : subdirs) { + infos.add(FileInfo.ofDir(subdir, "")); + } + + infos.sort(Comparator.comparing(FileInfo::path)); + return LsResult.success(infos); + } + + @Override + public ReadResult read(String filePath, int offset, int limit) { + StoreItem item = store.get(getNamespace(), filePath); + if (item == null) { + return ReadResult.fail("File '" + filePath + "' not found"); + } + + FileData fileData = convertItemToFileData(item); + if (fileData == null) { + return ReadResult.fail("Invalid file data for '" + filePath + "'"); + } + + if (!"text".equals(FilesystemUtils.getFileType(filePath))) { + return ReadResult.success(fileData); + } + + String content = fileData.content(); + if (content == null || content.isBlank()) { + return ReadResult.success(fileData); + } + + String[] lines = content.split("\n", -1); + int startIdx = Math.max(0, offset); + int endIdx = limit > 0 ? Math.min(startIdx + limit, lines.length) : lines.length; + + if (startIdx >= lines.length) { + return ReadResult.fail( + "Line offset " + offset + " exceeds file length (" + lines.length + " lines)"); + } + + StringBuilder sb = new StringBuilder(); + for (int i = startIdx; i < endIdx; i++) { + if (i > startIdx) { + sb.append('\n'); + } + sb.append(lines[i]); + } + + return ReadResult.success( + new FileData( + sb.toString(), + fileData.encoding(), + fileData.createdAt(), + fileData.modifiedAt())); + } + + @Override + public WriteResult write(String filePath, String content) { + List ns = getNamespace(); + StoreItem existing = store.get(ns, filePath); + if (existing != null) { + return WriteResult.fail( + "Cannot write to " + + filePath + + " because it already exists. Read and then make an edit," + + " or write to a new path."); + } + + FileData fileData = FileData.create(content); + store.put(ns, filePath, fileDataToStoreValue(fileData)); + return WriteResult.ok(filePath); + } + + @Override + public EditResult edit( + String filePath, String oldString, String newString, boolean replaceAll) { + List ns = getNamespace(); + StoreItem item = store.get(ns, filePath); + if (item == null) { + return EditResult.fail("Error: File '" + filePath + "' not found"); + } + + FileData fileData = convertItemToFileData(item); + if (fileData == null) { + return EditResult.fail("Error: Invalid file data"); + } + + String content = fileData.content() != null ? fileData.content() : ""; + Object[] result = + FilesystemUtils.performStringReplacement(content, oldString, newString, replaceAll); + + if (result.length == 1) { + return EditResult.fail((String) result[0]); + } + + String newContent = (String) result[0]; + int occurrences = (int) result[1]; + + FileData updated = fileData.withContent(newContent); + store.put(ns, filePath, fileDataToStoreValue(updated)); + return EditResult.ok(filePath, occurrences); + } + + @Override + public GrepResult grep(String pattern, String path, String glob) { + List items = searchAllItems(); + String normalizedPath = normalizePath(path); + + PathMatcher globMatcher = null; + if (glob != null && !glob.isBlank()) { + globMatcher = FileSystems.getDefault().getPathMatcher("glob:" + glob); + } + + List matches = new ArrayList<>(); + for (StoreItem item : items) { + String key = item.key(); + + if (!matchesPathPrefix(key, normalizedPath)) { + continue; + } + + if (globMatcher != null) { + String fileName = key.contains("/") ? key.substring(key.lastIndexOf('/') + 1) : key; + if (!globMatcher.matches(java.nio.file.Path.of(fileName))) { + continue; + } + } + + FileData fd = convertItemToFileData(item); + if (fd == null || fd.content() == null) { + continue; + } + + String[] lines = fd.content().split("\n", -1); + for (int i = 0; i < lines.length; i++) { + if (lines[i].contains(pattern)) { + matches.add(new GrepMatch(key, i + 1, lines[i])); + } + } + } + + return GrepResult.success(matches); + } + + @Override + public GlobResult glob(String pattern, String path) { + List items = searchAllItems(); + String normalizedPath = normalizePath(path); + String effectivePattern = pattern.startsWith("/") ? pattern.substring(1) : pattern; + + PathMatcher matcher = + FileSystems.getDefault() + .getPathMatcher( + "glob:" + + (effectivePattern.startsWith("**") + ? effectivePattern + : "**/" + effectivePattern)); + + List results = new ArrayList<>(); + for (StoreItem item : items) { + String key = item.key(); + if (!matchesPathPrefix(key, normalizedPath)) { + continue; + } + + String relativePath; + if ("/".equals(normalizedPath)) { + relativePath = key.startsWith("/") ? key.substring(1) : key; + } else { + relativePath = key.substring(normalizedPath.length() + 1); + } + + if (matcher.matches(java.nio.file.Path.of(relativePath))) { + FileData fd = convertItemToFileData(item); + int size = (fd != null && fd.content() != null) ? fd.content().length() : 0; + String modifiedAt = (fd != null && fd.modifiedAt() != null) ? fd.modifiedAt() : ""; + results.add(FileInfo.ofFile(key, size, modifiedAt)); + } + } + + results.sort(Comparator.comparing(FileInfo::path)); + return GlobResult.success(results); + } + + @Override + public List uploadFiles(List> files) { + List ns = getNamespace(); + List responses = new ArrayList<>(); + for (Map.Entry entry : files) { + String filePath = entry.getKey(); + byte[] content = entry.getValue(); + + String contentStr; + String encoding; + try { + contentStr = new String(content, StandardCharsets.UTF_8); + encoding = "utf-8"; + } catch (Exception e) { + contentStr = Base64.getEncoder().encodeToString(content); + encoding = "base64"; + } + + FileData fileData = FileData.create(contentStr, encoding); + store.put(ns, filePath, fileDataToStoreValue(fileData)); + responses.add(FileUploadResponse.success(filePath)); + } + return responses; + } + + @Override + public List downloadFiles(List paths) { + List ns = getNamespace(); + List responses = new ArrayList<>(); + for (String filePath : paths) { + StoreItem item = store.get(ns, filePath); + if (item == null) { + responses.add(FileDownloadResponse.fail(filePath, "file_not_found")); + continue; + } + + FileData fd = convertItemToFileData(item); + if (fd == null || fd.content() == null) { + responses.add(FileDownloadResponse.fail(filePath, "invalid file data")); + continue; + } + + byte[] contentBytes; + if ("base64".equals(fd.encoding())) { + contentBytes = Base64.getDecoder().decode(fd.content()); + } else { + contentBytes = fd.content().getBytes(StandardCharsets.UTF_8); + } + responses.add(FileDownloadResponse.success(filePath, contentBytes)); + } + return responses; + } + + // ==================== Internal helpers ==================== + + private List searchAllItems() { + List ns = getNamespace(); + List all = new ArrayList<>(); + int offset = 0; + int pageSize = 100; + while (true) { + List page = store.search(ns, pageSize, offset); + if (page.isEmpty()) { + break; + } + all.addAll(page); + if (page.size() < pageSize) { + break; + } + offset += pageSize; + } + return all; + } + + private static FileData convertItemToFileData(StoreItem item) { + if (item == null || item.value() == null) { + return null; + } + Map value = item.value(); + Object contentObj = value.get("content"); + if (contentObj == null) { + return null; + } + + String content; + if (contentObj instanceof List list) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + if (i > 0) { + sb.append('\n'); + } + sb.append(list.get(i)); + } + content = sb.toString(); + } else if (contentObj instanceof String s) { + content = s; + } else { + return null; + } + + String encoding = + value.containsKey("encoding") ? String.valueOf(value.get("encoding")) : "utf-8"; + String createdAt = + value.containsKey("created_at") ? String.valueOf(value.get("created_at")) : null; + String modifiedAt = + value.containsKey("modified_at") ? String.valueOf(value.get("modified_at")) : null; + + return new FileData(content, encoding, createdAt, modifiedAt); + } + + private static Map fileDataToStoreValue(FileData fd) { + Map result = new HashMap<>(); + result.put("content", fd.content()); + result.put("encoding", fd.encoding()); + if (fd.createdAt() != null) { + result.put("created_at", fd.createdAt()); + } + if (fd.modifiedAt() != null) { + result.put("modified_at", fd.modifiedAt()); + } + return result; + } + + private static String normalizePath(String path) { + if (path == null || path.isBlank()) { + return "/"; + } + String normalized = path.startsWith("/") ? path : "/" + path; + if (!"/".equals(normalized) && normalized.endsWith("/")) { + normalized = normalized.substring(0, normalized.length() - 1); + } + return normalized; + } + + private static boolean matchesPathPrefix(String key, String normalizedPath) { + if ("/".equals(normalizedPath)) { + return key.startsWith("/"); + } + return key.equals(normalizedPath) || key.startsWith(normalizedPath + "/"); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/EditResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/EditResult.java new file mode 100644 index 000000000..29c8d3649 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/EditResult.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result of a file edit (string replacement) operation. + * + * @param path absolute path of edited file, {@code null} on failure + * @param error error message on failure, {@code null} on success + * @param occurrences number of replacements made, {@code null} on failure + */ +public record EditResult(String path, String error, Integer occurrences) { + + public static EditResult ok(String path, int occurrences) { + return new EditResult(path, null, occurrences); + } + + public static EditResult fail(String error) { + return new EditResult(null, error, null); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ExecuteResponse.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ExecuteResponse.java new file mode 100644 index 000000000..94fc84944 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ExecuteResponse.java @@ -0,0 +1,30 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result of code/shell execution. + * + * @param output combined stdout and stderr output of the executed command + * @param exitCode the process exit code (0 indicates success, non-zero indicates failure) + * @param truncated whether the output was truncated due to filesystem limitations + */ +public record ExecuteResponse(String output, Integer exitCode, boolean truncated) { + + public boolean isSuccess() { + return exitCode != null && exitCode == 0; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileData.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileData.java new file mode 100644 index 000000000..de120d434 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileData.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +import java.time.Instant; + +/** + * Data structure for storing file contents with metadata. + * + * @param content file content as a plain string (utf-8 text or base64-encoded binary) + * @param encoding content encoding: {@code "utf-8"} for text, {@code "base64"} for binary + * @param createdAt ISO 8601 timestamp of file creation (nullable) + * @param modifiedAt ISO 8601 timestamp of last modification (nullable) + */ +public record FileData(String content, String encoding, String createdAt, String modifiedAt) { + + public FileData(String content, String encoding) { + this(content, encoding, null, null); + } + + /** Creates a new UTF-8 text FileData with timestamps set to now. */ + public static FileData create(String content) { + return create(content, "utf-8"); + } + + /** Creates a new FileData with specified encoding and timestamps set to now. */ + public static FileData create(String content, String encoding) { + String now = Instant.now().toString(); + return new FileData(content, encoding, now, now); + } + + /** Returns a copy with updated content and modified timestamp. */ + public FileData withContent(String newContent) { + return new FileData(newContent, encoding, createdAt, Instant.now().toString()); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileDownloadResponse.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileDownloadResponse.java new file mode 100644 index 000000000..16caab0e3 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileDownloadResponse.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result of a single file download operation. + * + * @param path the file path that was requested + * @param content file contents as bytes on success, {@code null} on failure + * @param error error description on failure, {@code null} on success + */ +public record FileDownloadResponse(String path, byte[] content, String error) { + + public static FileDownloadResponse success(String path, byte[] content) { + return new FileDownloadResponse(path, content, null); + } + + public static FileDownloadResponse fail(String path, String error) { + return new FileDownloadResponse(path, null, error); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileInfo.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileInfo.java new file mode 100644 index 000000000..e73cb7a34 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileInfo.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Structured file listing info. Only {@code path} is required; + * other fields are best-effort and may be absent depending on filesystem implementation. + * + * @param path absolute or relative file path + * @param isDirectory whether the entry is a directory + * @param size file size in bytes (approximate) + * @param modifiedAt ISO 8601 timestamp of last modification, or empty string if unknown + */ +public record FileInfo(String path, boolean isDirectory, long size, String modifiedAt) { + + public static FileInfo ofFile(String path, long size, String modifiedAt) { + return new FileInfo(path, false, size, modifiedAt != null ? modifiedAt : ""); + } + + public static FileInfo ofDir(String path, String modifiedAt) { + return new FileInfo(path, true, 0, modifiedAt != null ? modifiedAt : ""); + } + + public static FileInfo ofFile(String path, long size, long lastModifiedMs) { + return new FileInfo( + path, false, size, java.time.Instant.ofEpochMilli(lastModifiedMs).toString()); + } + + public static FileInfo ofDir(String path, long lastModifiedMs) { + return new FileInfo( + path, true, 0, java.time.Instant.ofEpochMilli(lastModifiedMs).toString()); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileUploadResponse.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileUploadResponse.java new file mode 100644 index 000000000..b920068e3 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/FileUploadResponse.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result of a single file upload operation. + * + * @param path the file path that was requested + * @param error error description on failure, {@code null} on success + */ +public record FileUploadResponse(String path, String error) { + + public static FileUploadResponse success(String path) { + return new FileUploadResponse(path, null); + } + + public static FileUploadResponse fail(String path, String error) { + return new FileUploadResponse(path, error); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GlobResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GlobResult.java new file mode 100644 index 000000000..b1b59b0ab --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GlobResult.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +import java.util.List; + +/** + * Result from abstract filesystem glob operations. + * + * @param error error message on failure, {@code null} on success + * @param matches list of matching file info entries on success, {@code null} on failure + */ +public record GlobResult(String error, List matches) { + + public static GlobResult success(List matches) { + return new GlobResult(null, matches); + } + + public static GlobResult fail(String error) { + return new GlobResult(error, null); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepMatch.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepMatch.java new file mode 100644 index 000000000..9f1a9ebd2 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepMatch.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * A single match from a grep search. + * + * @param path path to the file containing the match + * @param line 1-indexed line number of the match + * @param text content of the matching line + */ +public record GrepMatch(String path, int line, String text) {} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepResult.java new file mode 100644 index 000000000..14de81a4e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/GrepResult.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +import java.util.List; + +/** + * Result from abstract filesystem grep operations. + * + * @param error error message on failure, {@code null} on success + * @param matches list of grep matches on success, {@code null} on failure + */ +public record GrepResult(String error, List matches) { + + public static GrepResult success(List matches) { + return new GrepResult(null, matches); + } + + public static GrepResult fail(String error) { + return new GrepResult(error, null); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/LsResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/LsResult.java new file mode 100644 index 000000000..39f25c68d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/LsResult.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +import java.util.List; + +/** + * Result from abstract filesystem ls (directory listing) operations. + * + * @param error error message on failure, {@code null} on success + * @param entries list of file info entries on success, {@code null} on failure + */ +public record LsResult(String error, List entries) { + + public static LsResult success(List entries) { + return new LsResult(null, entries); + } + + public static LsResult fail(String error) { + return new LsResult(error, null); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ReadResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ReadResult.java new file mode 100644 index 000000000..e0844fb20 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/ReadResult.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result from abstract filesystem read operations. + * + * @param error error message on failure, {@code null} on success + * @param fileData file data on success, {@code null} on failure + */ +public record ReadResult(String error, FileData fileData) { + + public static ReadResult success(FileData fileData) { + return new ReadResult(null, fileData); + } + + public static ReadResult fail(String error) { + return new ReadResult(error, null); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/WriteResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/WriteResult.java new file mode 100644 index 000000000..b3122e4de --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/model/WriteResult.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.model; + +/** + * Result of a file write operation. + * + * @param path absolute path of written file, {@code null} on failure + * @param error error message on failure, {@code null} on success + */ +public record WriteResult(String path, String error) { + + public static WriteResult ok(String path) { + return new WriteResult(path, null); + } + + public static WriteResult fail(String error) { + return new WriteResult(null, error); + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java new file mode 100644 index 000000000..fc12bd5fa --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java @@ -0,0 +1,64 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.store; + +import java.util.List; +import java.util.Map; + +/** + * Abstract interface for a namespace-based key-value store. + * + *

Items are organized by namespaces (hierarchical path-like tuples) + * and identified by a key within each namespace. + */ +public interface BaseStore { + + /** + * Get a single item by namespace and key. + * + * @param namespace hierarchical namespace path + * @param key the item key within the namespace + * @return the store item, or {@code null} if not found + */ + StoreItem get(List namespace, String key); + + /** + * Store or update an item. + * + * @param namespace hierarchical namespace path + * @param key the item key within the namespace + * @param value the data to store + */ + void put(List namespace, String key, Map value); + + /** + * Search for items within a namespace with pagination. + * + * @param namespace hierarchical namespace path + * @param limit maximum number of items to return + * @param offset number of items to skip + * @return list of matching store items + */ + List search(List namespace, int limit, int offset); + + /** + * Delete an item by namespace and key. + * + * @param namespace hierarchical namespace path + * @param key the item key to delete + */ + void delete(List namespace, String key); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java new file mode 100644 index 000000000..56eb1544a --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java @@ -0,0 +1,87 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.store; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * Thread-safe in-memory implementation of {@link BaseStore}. + * + *

Items are stored in a ConcurrentHashMap keyed by the concatenation of + * namespace components and the item key, separated by {@code '\0'}. + */ +public class InMemoryStore implements BaseStore { + + private final ConcurrentMap store = new ConcurrentHashMap<>(); + + @Override + public StoreItem get(List namespace, String key) { + return store.get(compoundKey(namespace, key)); + } + + @Override + public void put(List namespace, String key, Map value) { + store.put(compoundKey(namespace, key), new StoreItem(key, value)); + } + + @Override + public List search(List namespace, int limit, int offset) { + String prefix = namespacePrefix(namespace); + List matches = new ArrayList<>(); + for (Map.Entry entry : store.entrySet()) { + if (entry.getKey().startsWith(prefix)) { + matches.add(entry.getValue()); + } + } + Collections.sort(matches, (a, b) -> a.key().compareTo(b.key())); + + int start = Math.min(offset, matches.size()); + int end = Math.min(start + limit, matches.size()); + return matches.subList(start, end); + } + + @Override + public void delete(List namespace, String key) { + store.remove(compoundKey(namespace, key)); + } + + /** Returns the number of items currently stored. */ + public int size() { + return store.size(); + } + + /** Removes all items from the store. */ + public void clear() { + store.clear(); + } + + private static String compoundKey(List namespace, String key) { + return namespacePrefix(namespace) + key; + } + + private static String namespacePrefix(List namespace) { + StringBuilder sb = new StringBuilder(); + for (String component : namespace) { + sb.append(component).append('\0'); + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java new file mode 100644 index 000000000..85f8e95a0 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.store; + +import java.util.List; + +/** + * Factory that produces a namespace tuple for {@link BaseStore} operations at call time. + * + *

Unlike a static namespace, a {@code NamespaceFactory} is invoked on every store + * operation (read, write, ls, etc.), allowing the namespace to vary based on runtime context such + * as the current session id, user id, or agent id. + * + *

Example: + * + *

{@code
+ * NamespaceFactory factory = () -> List.of("sessions", getCurrentSessionId(), "filesystem");
+ * StoreFilesystem fs = new StoreFilesystem(store, factory);
+ * }
+ */ +@FunctionalInterface +public interface NamespaceFactory { + + /** + * Returns the namespace tuple for the current operation context. + * + * @return non-null, non-empty list of namespace segments + */ + List getNamespace(); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java new file mode 100644 index 000000000..1f355d241 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.store; + +import java.util.Map; + +/** + * A single item retrieved from a {@link BaseStore}. + * + * @param key the item's key within its namespace + * @param value the item's data as a string-keyed map + */ +public record StoreItem(String key, Map value) {} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/util/FilesystemUtils.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/util/FilesystemUtils.java new file mode 100644 index 000000000..851deb21d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/util/FilesystemUtils.java @@ -0,0 +1,107 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem.util; + +import java.util.Set; + +/** + * Shared utility functions for filesystem implementations. + */ +public final class FilesystemUtils { + + private FilesystemUtils() {} + + private static final Set BINARY_EXTENSIONS = + Set.of( + ".png", ".jpg", ".jpeg", ".gif", ".webp", ".heic", ".heif", ".bmp", ".ico", + ".svg", ".mp4", ".mpeg", ".mov", ".avi", ".flv", ".mpg", ".webm", ".wmv", + ".3gpp", ".wav", ".mp3", ".aiff", ".aac", ".ogg", ".flac", ".pdf", ".ppt", + ".pptx", ".doc", ".docx", ".xls", ".xlsx", ".zip", ".tar", ".gz", ".bz2", ".7z", + ".rar", ".class", ".jar", ".war", ".ear", ".so", ".dll", ".dylib", ".exe"); + + /** + * Classify a file as "text" or "binary" based on extension. + */ + public static String getFileType(String path) { + if (path == null) { + return "text"; + } + int dot = path.lastIndexOf('.'); + if (dot < 0) { + return "text"; + } + String ext = path.substring(dot).toLowerCase(); + return BINARY_EXTENSIONS.contains(ext) ? "binary" : "text"; + } + + /** + * Perform string replacement with occurrence validation. + * + * @return a two-element array {@code [newContent, occurrenceCount]} on success, + * or a single-element array {@code [errorMessage]} on failure + */ + public static Object[] performStringReplacement( + String content, String oldString, String newString, boolean replaceAll) { + int occurrences = countOccurrences(content, oldString); + + if (occurrences == 0) { + return new Object[] {"Error: String not found in file: '" + oldString + "'"}; + } + + if (occurrences > 1 && !replaceAll) { + return new Object[] { + "Error: String '" + + oldString + + "' appears " + + occurrences + + " times in file. " + + "Use replaceAll=true to replace all instances, or provide a more specific" + + " string with surrounding context." + }; + } + + String newContent; + if (replaceAll) { + newContent = content.replace(oldString, newString); + } else { + int idx = content.indexOf(oldString); + newContent = + content.substring(0, idx) + + newString + + content.substring(idx + oldString.length()); + } + return new Object[] {newContent, occurrences}; + } + + /** Count non-overlapping occurrences of a substring. */ + public static int countOccurrences(String text, String sub) { + int count = 0; + int idx = 0; + while ((idx = text.indexOf(sub, idx)) >= 0) { + count++; + idx += sub.length(); + } + return count; + } + + /** Shell-escape a string for safe use in shell commands. */ + public static String shellQuote(String s) { + if (s == null || s.isEmpty()) { + return "''"; + } + return "'" + s.replace("'", "'\\''") + "'"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java new file mode 100644 index 000000000..595075ceb --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java @@ -0,0 +1,238 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.ErrorEvent; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostActingEvent; +import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.hook.PostReasoningEvent; +import io.agentscope.core.hook.PreActingEvent; +import io.agentscope.core.hook.PreCallEvent; +import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.PreSummaryEvent; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import io.agentscope.core.util.JsonUtils; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Observability hook that logs the complete reasoning and execution trace of an agent. + * + *

At INFO level, logs concise summaries: event type, agent name, tool names/IDs, and + * message lengths. At DEBUG level, additionally logs tool call arguments, tool result content, + * reasoning text, and input message details. + * + *

This hook runs at the lowest priority (first in, last out) so it captures all events + * without interfering with other hooks. + */ +public class AgentTraceHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(AgentTraceHook.class); + + @Override + public int priority() { + return 0; + } + + @Override + public Mono onEvent(T event) { + if (!log.isInfoEnabled()) { + return Mono.just(event); + } + + String agent = event.getAgent().getName(); + + if (event instanceof PreCallEvent e) { + logPreCall(agent, e); + } else if (event instanceof PostCallEvent e) { + logPostCall(agent, e); + } else if (event instanceof PreReasoningEvent e) { + logPreReasoning(agent, e); + } else if (event instanceof PostReasoningEvent e) { + logPostReasoning(agent, e); + } else if (event instanceof PreActingEvent e) { + logPreActing(agent, e); + } else if (event instanceof PostActingEvent e) { + logPostActing(agent, e); + } else if (event instanceof PreSummaryEvent e) { + logPreSummary(agent, e); + } else if (event instanceof ErrorEvent e) { + logError(agent, e); + } + + return Mono.just(event); + } + + private void logPreCall(String agent, PreCallEvent e) { + List msgs = e.getInputMessages(); + log.info("[{}] PRE_CALL | {} input message(s)", agent, msgs != null ? msgs.size() : 0); + if (log.isDebugEnabled() && msgs != null) { + for (Msg msg : msgs) { + log.debug( + "[{}] PRE_CALL | [{}] {}", + agent, + msg.getRole(), + truncate(msg.getTextContent(), 200)); + } + } + } + + private void logPostCall(String agent, PostCallEvent e) { + Msg msg = e.getFinalMessage(); + String preview = msg != null ? truncate(msg.getTextContent(), 120) : ""; + log.info("[{}] POST_CALL | response: {}", agent, preview); + } + + private void logPreReasoning(String agent, PreReasoningEvent e) { + int msgCount = e.getInputMessages() != null ? e.getInputMessages().size() : 0; + log.info("[{}] PRE_REASONING | model={}, messages={}", agent, e.getModelName(), msgCount); + if (log.isDebugEnabled() && e.getInputMessages() != null) { + for (Msg msg : e.getInputMessages()) { + log.debug( + "[{}] PRE_REASONING | [{}] len={}", + agent, + msg.getRole(), + msg.getTextContent() != null ? msg.getTextContent().length() : 0); + } + } + } + + private void logPostReasoning(String agent, PostReasoningEvent e) { + Msg msg = e.getReasoningMessage(); + if (msg == null) { + log.info("[{}] POST_REASONING | ", agent); + return; + } + List toolCalls = msg.getContentBlocks(ToolUseBlock.class); + if (toolCalls.isEmpty()) { + String text = truncate(msg.getTextContent(), 120); + log.info("[{}] POST_REASONING | text response: {}", agent, text); + } else { + for (ToolUseBlock tu : toolCalls) { + log.info( + "[{}] POST_REASONING | tool_call: id={}, name={}", + agent, + tu.getId(), + tu.getName()); + if (log.isDebugEnabled()) { + log.debug( + "[{}] POST_REASONING | args={}", + agent, + truncate(mapToJson(tu.getInput()), 500)); + } + } + } + } + + private void logPreActing(String agent, PreActingEvent e) { + ToolUseBlock tu = e.getToolUse(); + if (tu == null) { + return; + } + log.info("[{}] PRE_ACTING | id={}, name={}", agent, tu.getId(), tu.getName()); + if (log.isDebugEnabled()) { + log.debug( + "[{}] PRE_ACTING | args={}", agent, truncate(mapToJson(tu.getInput()), 500)); + } + } + + private void logPostActing(String agent, PostActingEvent e) { + ToolUseBlock tu = e.getToolUse(); + ToolResultBlock tr = e.getToolResult(); + String toolName = tu != null ? tu.getName() : "?"; + String toolId = tu != null ? tu.getId() : "?"; + int resultLen = toolResultLength(tr); + log.info( + "[{}] POST_ACTING | id={}, name={}, result_len={}", + agent, + toolId, + toolName, + resultLen); + if (log.isDebugEnabled() && tr != null) { + log.debug("[{}] POST_ACTING | result={}", agent, truncate(toolResultText(tr), 500)); + } + } + + private void logPreSummary(String agent, PreSummaryEvent e) { + log.info( + "[{}] PRE_SUMMARY | model={}, iter={}/{}", + agent, + e.getModelName(), + e.getCurrentIteration(), + e.getMaxIterations()); + } + + private void logError(String agent, ErrorEvent e) { + Throwable err = e.getError(); + log.info("[{}] ERROR | {}: {}", agent, err.getClass().getSimpleName(), err.getMessage()); + if (log.isDebugEnabled()) { + log.debug("[{}] ERROR | stacktrace:", agent, err); + } + } + + private static String truncate(String s, int max) { + if (s == null || s.isEmpty()) { + return ""; + } + return s.length() <= max ? s : s.substring(0, max) + "..."; + } + + private static String mapToJson(Map map) { + if (map == null || map.isEmpty()) { + return "{}"; + } + try { + return JsonUtils.getJsonCodec().toJson(map); + } catch (Exception e) { + return map.toString(); + } + } + + private static int toolResultLength(ToolResultBlock tr) { + if (tr == null || tr.getOutput() == null) { + return 0; + } + int len = 0; + for (ContentBlock block : tr.getOutput()) { + if (block instanceof TextBlock tb && tb.getText() != null) { + len += tb.getText().length(); + } + } + return len; + } + + private static String toolResultText(ToolResultBlock tr) { + if (tr == null || tr.getOutput() == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (ContentBlock block : tr.getOutput()) { + if (block instanceof TextBlock tb && tb.getText() != null) { + sb.append(tb.getText()); + } + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java new file mode 100644 index 000000000..4b4c1cdbe --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java @@ -0,0 +1,135 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.Agent; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.memory.Memory; +import io.agentscope.core.message.Msg; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.memory.MemoryFlushManager; +import io.agentscope.harness.agent.memory.MemoryIndex; +import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that triggers memory flush and message offload at the end of each agent call. + * + *

Fires on {@link PostCallEvent} to ensure long-term memories are extracted and + * persisted after every call, even when conversation compaction was not triggered during + * that call. When {@link io.agentscope.harness.agent.memory.compaction.CompactionHook} + * is active, it handles flush/offload for the messages it summarizes; this hook covers + * the remaining tail of messages that were kept verbatim. + * + *

Priority is 5 — runs early so state is persisted before the session-persistence hook + * (priority 900) saves the overall agent state. + */ +public class MemoryFlushHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(MemoryFlushHook.class); + + private final WorkspaceManager workspaceManager; + private final Model model; + private RuntimeContext runtimeContext; + private volatile MemoryIndex memoryIndex; + private volatile MemoryMaintenanceScheduler maintenanceScheduler; + + public MemoryFlushHook(WorkspaceManager workspaceManager, Model model) { + this.workspaceManager = workspaceManager; + this.model = model; + } + + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + public void setMemoryIndex(MemoryIndex memoryIndex) { + this.memoryIndex = memoryIndex; + } + + /** + * Wires the maintenance scheduler so each flush can opportunistically request a + * MEMORY.md consolidation (throttled by the scheduler). + */ + public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { + this.maintenanceScheduler = scheduler; + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PostCallEvent) { + return doFlush(event.getAgent()).thenReturn(event); + } + return Mono.just(event); + } + + @Override + public int priority() { + return 5; + } + + private Mono doFlush(Agent agent) { + if (!(agent instanceof ReActAgent reActAgent)) { + return Mono.empty(); + } + + Memory memory = reActAgent.getMemory(); + List messages = memory.getMessages(); + if (messages.isEmpty()) { + return Mono.empty(); + } + + MemoryFlushManager flushManager = new MemoryFlushManager(workspaceManager, model); + flushManager.setMemoryIndex(memoryIndex); + flushManager.setMaintenanceScheduler(maintenanceScheduler); + + Mono flushMono = + flushManager + .flushMemories(messages) + .doOnSuccess(v -> log.debug("Memory flush completed")) + .onErrorResume( + e -> { + log.warn("Memory flush failed: {}", e.getMessage()); + return Mono.empty(); + }); + + String agentId = agent.getName(); + String sessionId = + runtimeContext != null && runtimeContext.getSessionId() != null + ? runtimeContext.getSessionId() + : "default"; + + Mono offloadMono = + Mono.fromRunnable(() -> flushManager.offloadMessages(messages, agentId, sessionId)) + .then() + .doOnSuccess(v -> log.debug("Message offload completed")) + .onErrorResume( + e -> { + log.warn("Message offload failed: {}", e.getMessage()); + return Mono.empty(); + }); + + return flushMono.then(offloadMono); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java new file mode 100644 index 000000000..a103c1bbc --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java @@ -0,0 +1,24 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.harness.agent.RuntimeContext; + +/** Marker contract for hooks that need per-call {@link RuntimeContext}. */ +public interface RuntimeContextAwareHook { + + void setRuntimeContext(RuntimeContext runtimeContext); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java new file mode 100644 index 000000000..f10034082 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.agent.Agent; +import io.agentscope.core.hook.ErrorEvent; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.state.StateModule; +import io.agentscope.harness.agent.RuntimeContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that automatically persists agent state to the session after each call. + * + *

Handles both {@link PostCallEvent} (success path) and {@link ErrorEvent} (error path) to + * ensure state is saved regardless of outcome. The save is best-effort: failures are logged but + * do not propagate exceptions. + * + *

Session and SessionKey are obtained from the {@link RuntimeContext} injected via + * {@link #setRuntimeContext(RuntimeContext)}. When no session is configured in the context, + * the hook is a no-op. + * + *

Priority is set to 900 (low) so this hook runs after other hooks like + * {@link MemoryFlushHook} have completed their work. + */ +public class SessionPersistenceHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(SessionPersistenceHook.class); + + private RuntimeContext runtimeContext; + + public void setRuntimeContext(RuntimeContext ctx) { + this.runtimeContext = ctx; + } + + @Override + public int priority() { + return 900; + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PostCallEvent || event instanceof ErrorEvent) { + autoSave(event.getAgent()); + } + return Mono.just(event); + } + + private void autoSave(Agent agent) { + RuntimeContext ctx = this.runtimeContext; + if (ctx == null || ctx.getSession() == null || ctx.getSessionKey() == null) { + return; + } + if (agent instanceof StateModule sm) { + try { + sm.saveTo(ctx.getSession(), ctx.getSessionKey()); + log.debug("Auto-saved session state for agent '{}'", agent.getName()); + } catch (Exception e) { + log.warn( + "Auto-save session failed for agent '{}': {}", + agent.getName(), + e.getMessage()); + } + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java new file mode 100644 index 000000000..f8f61e5b0 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java @@ -0,0 +1,258 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.harness.agent.subagent.DefaultAgentManager; +import io.agentscope.harness.agent.subagent.SubagentFactory; +import io.agentscope.harness.agent.subagent.task.DefaultTaskRepository; +import io.agentscope.harness.agent.subagent.task.TaskRepository; +import io.agentscope.harness.agent.tool.AgentSpawnTool; +import io.agentscope.harness.agent.tool.TaskTool; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import reactor.core.publisher.Mono; + +/** + * Hook that provides the managed subagent mechanism. + * + *

In default mode (standalone {@code HarnessAgent}), this hook creates an + * {@link AgentSpawnTool} backed by a {@link DefaultAgentManager}. In session mode + * (orchestrated via {@code AgentBootstrap}), an external tool (typically {@code SessionsTool}) is + * injected, replacing the default {@link AgentSpawnTool}. + * + *

Responsibilities: + * + *

    + *
  1. Registers the subagent tool and {@link TaskTool} as agent tools + *
  2. Injects rich subagent usage guidance into the leading system message at + * {@link PreReasoningEvent} time. The injection is per-iteration only — it never enters + * the persistent {@code Memory} / {@code Session}, so SYSTEM context cannot accumulate + * across calls. + *
+ */ +public class SubagentsHook implements Hook { + + // @formatter:off + private static final String SUBAGENT_SECTION_TEMPLATE = + """ + + ## Subagents + + You have access to subagent tools for spawning and coordinating isolated subagents. + Subagents are ephemeral — they live only for the duration of the task and return a single result. + + ### Agent Tools + + **`%s`** — Spawn an isolated subagent + - `agent_id` (required): which subagent to instantiate + - `task` (optional): initial prompt; omit to create a persistent session + - `label` (optional): human-readable name for referencing via send + - `timeout_seconds`: wait time; 0=fire-and-forget (returns task_id), default=30, max=600 + - Response always includes `agent_key:` (opaque handle) — save it for follow-up sends + + **`%s`** — Send a follow-up message to an existing subagent + - `agent_key`: copy the **full value** after `agent_key:` from spawn output (starts with `agent:`). This is NOT `agent_id`, NOT `session_id`, and NOT `task_id` + - Or use `label` if you set one at spawn (mutually exclusive with agent_key) + - `message` (required): content to send + - `timeout_seconds`: 0=fire-and-forget, >0=wait for reply (default: 30) + + **`%s`** — List active subagents + + ### Task Tools (for async/background operations) + + **`task_output`** — Retrieve the result of a background task by task_id. Supports blocking wait (default) or non-blocking peek (block=false). + + **`task_cancel`** — Cancel a running background task by task_id. No effect on already-completed tasks. + + **`task_list`** — List all background tasks with current statuses. Optionally filter by status (running, completed, failed, cancelled). + + ### Available agent ids + %s + + ### When to use subagents + - When a task is complex and multi-step, and can be fully delegated in isolation + - When a task is independent of other tasks and can run in parallel + - When a task requires focused reasoning or heavy context usage that would bloat the main thread + - When sandboxing improves reliability (e.g. code analysis, structured searches, data formatting) + - When you only care about the output, not the intermediate steps (e.g. research → synthesized report) + + ### When NOT to use subagents + - If the task is trivial (a few tool calls or simple lookup) + - If you need to see intermediate reasoning or steps after completion + - If delegating does not reduce token usage, complexity, or context switching + - If splitting would add latency without benefit + + ### Subagent lifecycle + 1. **Spawn** → Provide clear role, instructions, and expected output format + 2. **Run** → The subagent completes the task autonomously + 3. **Return** → The subagent provides a single structured result + 4. **Reconcile** → Incorporate or synthesize the result into the main thread + + ### Usage patterns + - **Parallel execution**: Launch multiple subagents concurrently with timeout_seconds=0 when tasks are independent, then collect results with task_output + - **Sync delegation**: Use default timeout for simple one-shot delegation + - **Persistent session**: Spawn without a task, then use send for multi-turn interaction + - **Cancel stale work**: Use task_cancel to stop background tasks that are no longer needed + - Subagent results are NOT visible to the user — always summarize them in your response + """; + // @formatter:on + + private final List entries; + private final Object subagentTool; + private final TaskTool taskTool; + private final boolean isSessionMode; + + /** + * Default mode: creates {@link AgentSpawnTool} + {@link DefaultAgentManager} internally. + * + * @param entries subagent descriptors (agent_id, description, factory) + * @param taskRepository background task store for async operations + * @param workspaceManager workspace accessor for session file path resolution + */ + public SubagentsHook( + List entries, + TaskRepository taskRepository, + WorkspaceManager workspaceManager) { + this.entries = List.copyOf(entries); + this.isSessionMode = false; + Map factories = buildFactories(entries); + DefaultAgentManager dam = new DefaultAgentManager(factories, workspaceManager); + TaskRepository repo = taskRepository != null ? taskRepository : new DefaultTaskRepository(); + this.subagentTool = new AgentSpawnTool(dam, repo, 0); + this.taskTool = new TaskTool(repo); + } + + /** + * Session mode: uses the externally provided tool (typically {@code SessionsTool}). + * + * @param entries subagent descriptors (for prompt injection — agent id listing) + * @param externalSubagentTool the external tool instance (e.g. SessionsTool) + * @param taskRepository background task store for async operations + */ + public SubagentsHook( + List entries, + Object externalSubagentTool, + TaskRepository taskRepository) { + this.entries = List.copyOf(entries); + this.isSessionMode = true; + this.subagentTool = externalSubagentTool; + TaskRepository repo = taskRepository != null ? taskRepository : new DefaultTaskRepository(); + this.taskTool = new TaskTool(repo); + } + + public SubagentsHook(List entries) { + this(entries, (TaskRepository) null, (WorkspaceManager) null); + } + + @Override + public List tools() { + if (entries.isEmpty()) { + return List.of(); + } + return List.of(subagentTool, taskTool); + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PreReasoningEvent preReasoning) { + injectSubagentPrompt(preReasoning); + } + return Mono.just(event); + } + + @Override + public int priority() { + return 80; + } + + private void injectSubagentPrompt(PreReasoningEvent event) { + if (entries.isEmpty()) { + return; + } + String agentList = + entries.stream() + .map(e -> String.format("- `%s`: %s", e.name(), e.description())) + .collect(Collectors.joining("\n")); + + String spawnName = isSessionMode ? "sessions_spawn" : "agent_spawn"; + String sendName = isSessionMode ? "sessions_send" : "agent_send"; + String listName = isSessionMode ? "sessions_list" : "agent_list"; + + String section = + String.format(SUBAGENT_SECTION_TEMPLATE, spawnName, sendName, listName, agentList); + + List msgs = new ArrayList<>(event.getInputMessages()); + int systemIndex = findFirstSystemMessageIndex(msgs); + if (systemIndex >= 0) { + Msg existing = msgs.get(systemIndex); + List mergedContent = new ArrayList<>(existing.getContent()); + mergedContent.add(TextBlock.builder().text(section).build()); + Msg merged = + Msg.builder() + .id(existing.getId()) + .role(MsgRole.SYSTEM) + .name(existing.getName()) + .content(mergedContent) + .metadata(existing.getMetadata()) + .timestamp(existing.getTimestamp()) + .build(); + msgs.set(systemIndex, merged); + } else { + msgs.add( + 0, + Msg.builder() + .role(MsgRole.SYSTEM) + .name("subagent_context") + .content(TextBlock.builder().text(section).build()) + .build()); + } + event.setInputMessages(msgs); + } + + private static int findFirstSystemMessageIndex(List messages) { + for (int i = 0; i < messages.size(); i++) { + if (messages.get(i).getRole() == MsgRole.SYSTEM) { + return i; + } + } + return -1; + } + + private static Map buildFactories(List entries) { + Map factories = new HashMap<>(); + for (SubagentEntry entry : entries) { + factories.put(entry.name(), entry.factory()); + } + return factories; + } + + /** + * Descriptor for a subagent identified by agent id, with its description and {@link + * SubagentFactory}. + */ + public record SubagentEntry(String name, String description, SubagentFactory factory) {} +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java new file mode 100644 index 000000000..f171ae4d2 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java @@ -0,0 +1,199 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostActingEvent; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import io.agentscope.harness.agent.memory.compaction.ToolResultEvictionConfig; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that evicts oversized tool results to the {@link AbstractFilesystem} immediately after + * each tool call, before the result is stored in the agent's memory. + * + *

When the text content of a {@link ToolResultBlock} exceeds + * {@link ToolResultEvictionConfig#getMaxResultChars()}, this hook: + *

    + *
  1. Writes the full result to + * {@code {evictionPath}/{agentName}/{sanitized-toolCallId}} in the filesystem.
  2. + *
  3. Replaces the in-context {@code ToolResultBlock} with a compact placeholder containing + * a head+tail preview and an instruction to use {@code readFile} for the full content.
  4. + *
  5. Calls {@link PostActingEvent#setToolResult} so downstream hooks and memory see only + * the placeholder.
  6. + *
+ * + *

Independence from other context-management mechanisms: + *

    + *
  • This hook fires on {@link PostActingEvent} — once per tool call, triggered by + * individual result size (context width).
  • + *
  • Argument truncation runs inside {@link io.agentscope.harness.agent.memory.compaction.CompactionHook} + * at {@code PreReasoningEvent} — triggered by accumulated message count/tokens.
  • + *
  • Conversation compaction runs inside {@code CompactionHook} at + * {@code PreReasoningEvent} — triggered by overall conversation length (context depth).
  • + *
+ * Each mechanism evaluates its own independent condition; none depends on the others having run. + * + *

Runs at priority 50, after {@link AgentTraceHook} (priority 0) so the original + * result size is logged before the placeholder replaces it. + * + *

Tools listed in {@link ToolResultEvictionConfig#getExcludedToolNames()} are never evicted + * (e.g. {@code readFile} — evicting would cause re-read loops). + */ +public class ToolResultEvictionHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(ToolResultEvictionHook.class); + + private final AbstractFilesystem filesystem; + private final ToolResultEvictionConfig config; + + public ToolResultEvictionHook(AbstractFilesystem filesystem, ToolResultEvictionConfig config) { + this.filesystem = filesystem; + this.config = config; + } + + @Override + public int priority() { + // After AgentTraceHook (0) — original result size is logged first, then replaced + return 50; + } + + @Override + public Mono onEvent(T event) { + if (!(event instanceof PostActingEvent postActing)) { + return Mono.just(event); + } + + ToolUseBlock toolUse = postActing.getToolUse(); + ToolResultBlock toolResult = postActing.getToolResult(); + + if (toolUse == null || toolResult == null) { + return Mono.just(event); + } + + String toolName = toolUse.getName(); + if (config.getExcludedToolNames().contains(toolName)) { + return Mono.just(event); + } + + String fullText = extractText(toolResult); + if (fullText.length() <= config.getMaxResultChars()) { + return Mono.just(event); + } + + String agentName = event.getAgent().getName(); + String toolCallId = toolUse.getId(); + String evictionPath = buildEvictionPath(agentName, toolCallId); + + try { + WriteResult writeResult = filesystem.write(evictionPath, fullText); + if (!writeResult.isSuccess()) { + log.warn( + "[{}] Failed to evict tool result [tool={}, id={}]: {}", + agentName, + toolName, + toolCallId, + writeResult.error()); + return Mono.just(event); + } + + String placeholder = buildPlaceholder(fullText, evictionPath); + ToolResultBlock evicted = + new ToolResultBlock( + toolResult.getId(), + toolResult.getName(), + List.of(TextBlock.builder().text(placeholder).build()), + null); + + postActing.setToolResult(evicted); + + log.info( + "[{}] Evicted large tool result [tool={}, id={}, chars={} -> {}]", + agentName, + toolName, + toolCallId, + fullText.length(), + evictionPath); + } catch (Exception e) { + log.warn( + "[{}] Exception evicting tool result [tool={}, id={}]: {}", + agentName, + toolName, + toolCallId, + e.getMessage()); + } + + return Mono.just(event); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + private String extractText(ToolResultBlock toolResult) { + if (toolResult.getOutput() == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (ContentBlock block : toolResult.getOutput()) { + if (block instanceof TextBlock tb && tb.getText() != null) { + sb.append(tb.getText()); + } + } + return sb.toString(); + } + + private String buildEvictionPath(String agentName, String toolCallId) { + String base = config.getEvictionPath(); + if (!base.startsWith("/")) { + base = "/" + base; + } + // Sanitize to filesystem-safe characters + String safeAgent = agentName.replaceAll("[^a-zA-Z0-9_-]", "_"); + String safeId = toolCallId.replaceAll("[^a-zA-Z0-9_-]", "_"); + return base + "/" + safeAgent + "/" + safeId; + } + + private String buildPlaceholder(String fullText, String evictionPath) { + int len = fullText.length(); + int pLen = Math.min(config.getPreviewChars(), len / 2); + + StringBuilder sb = new StringBuilder(); + sb.append( + String.format( + "Tool output was too large (%,d chars) and has been saved to `%s`.%n" + + "To read the full output, use `read_file` with path `%s`.%n%n", + len, evictionPath, evictionPath)); + + if (pLen > 0) { + sb.append(String.format("Preview (first %,d chars):%n", pLen)); + sb.append(fullText, 0, pLen); + sb.append(String.format("%n%n... and last %,d chars:%n", pLen)); + sb.append(fullText, len - pLen, len); + } + + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java new file mode 100644 index 000000000..9cb11a383 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java @@ -0,0 +1,327 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.nio.file.Path; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import reactor.core.publisher.Mono; + +/** + * A side-by-side variant of {@link WorkspaceContextHook} for A/B testing prompt layout. + * + *

It keeps the same runtime/session/token-budget behavior as the current hook, but renders + * workspace files using XML-style {@code } blocks to compare against markdown + * sectioning. + */ +public class WorkspaceContextHook implements Hook, RuntimeContextAwareHook { + + private static final String SESSION_CONTEXT_SECTION_TEMPLATE = + """ + ## Session Context + This is the %s. We are setting up the context for our chat. + Today's date is %s. + My operating system is: %s + The workspace directory is: %s + The project's temporary directory is: %s + %s + """; + + private static final String WORKSPACE_GUIDANCE_TEMPLATE = + """ + ## Domain Knowledge + The workspace `knowledge/` tree holds many detailed reference documents (not only a single summary file). When the task needs specs, procedures, schemas, or domain facts, treat that directory as the source of truth. + Below, `` already includes what you need to navigate it: injected `knowledge/KNOWLEDGE.md` (if present) plus a **full list of knowledge file paths** under `knowledge/` — use that as the catalog of what exists and where. + For content not inlined here, open only the paths you need with read_file, grep, or glob (prefer targeted reads over loading entire trees into the reply). + + ## Memory Recall + Before answering questions about prior work, decisions, dates, people, or preferences: \ + run memory_search on MEMORY.md + memory/*.md, then memory_get for needed lines. \ + Include Source: citations when helpful. + + ## Memory Persistence + You have a persistent MEMORY.md. Update it proactively when: + - User shares preferences, project context, or decisions + - Important outcomes or action items are established + Use edit_file/write_file to append concise bullet points. \ + Do NOT duplicate existing entries. \ + Memory is also automatically extracted at conversation end. + + ## Workspace + Your working directory is: %s + Treat this directory as the single global workspace for file operations unless explicitly instructed otherwise. + AGENTS.md define persona and local conventions — honor them when consistent with safety and policy. + + ## Workspace Files (Injected) + The following was loaded in from files in your workspace. + These files (for example, `AGENTS.md`, `MEMORY.md`, and `knowledge/KNOWLEDGE.md`) contain memory, facts, preferences, guidelines, and user-specific details learned from prior interactions with user. + """; + + private static final String TRUNCATION_NOTICE = + "\n\n... (memory truncated — use memory_search for older entries) ...\n"; + + private static final int DEFAULT_MAX_CONTEXT_TOKENS = 8000; + + private final WorkspaceManager workspaceManager; + private final String agentName; + private final String environmentMemory; + private final int maxContextTokens; + private List additionalContextFiles = List.of(); + private RuntimeContext runtimeContext; + + public WorkspaceContextHook(WorkspaceManager workspaceManager) { + this(workspaceManager, "HarnessAgent", null, DEFAULT_MAX_CONTEXT_TOKENS); + } + + public WorkspaceContextHook(WorkspaceManager workspaceManager, int maxContextTokens) { + this(workspaceManager, "HarnessAgent", null, maxContextTokens); + } + + public WorkspaceContextHook( + WorkspaceManager workspaceManager, + String agentName, + String environmentMemory, + int maxContextTokens) { + this.workspaceManager = workspaceManager; + this.agentName = agentName != null && !agentName.isBlank() ? agentName : "HarnessAgent"; + this.environmentMemory = environmentMemory; + this.maxContextTokens = maxContextTokens; + } + + public void setAdditionalContextFiles(List files) { + this.additionalContextFiles = files != null ? files : List.of(); + } + + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PreReasoningEvent preReasoning) { + injectWorkspaceContext(preReasoning); + } + return Mono.just(event); + } + + @Override + public int priority() { + return 900; + } + + private void injectWorkspaceContext(PreReasoningEvent event) { + String agentsContent = workspaceManager.readAgentsMd().strip(); + String memoryContent = workspaceManager.readMemoryMd().strip(); + String knowledgeContent = workspaceManager.readKnowledgeMd().strip(); + Path workspace = workspaceManager.getWorkspace(); + String sessionContext = buildSessionContextSection(workspace); + + String knowledgeBlock = buildKnowledgeBlock(knowledgeContent, workspace); + String additionalBlock = buildAdditionalContextBlock(); + + int fixedTokens = + estimateTokens(sessionContext) + + estimateTokens(agentsContent) + + estimateTokens(knowledgeBlock) + + estimateTokens(additionalBlock); + int memoryTokens = estimateTokens(memoryContent); + int available = maxContextTokens - fixedTokens; + if (available > 0 && memoryTokens > available) { + memoryContent = truncateToTokenBudget(memoryContent, available); + } + + String guidance = String.format(WORKSPACE_GUIDANCE_TEMPLATE, workspace.toAbsolutePath()); + String loadedContext = + buildLoadedContextSection( + agentsContent, memoryContent, knowledgeBlock, additionalBlock); + String section = buildWorkspaceSection(sessionContext, guidance, loadedContext); + + List msgs = new ArrayList<>(event.getInputMessages()); + int systemIndex = findFirstSystemMessageIndex(msgs); + if (systemIndex >= 0) { + Msg existing = msgs.get(systemIndex); + List mergedContent = new ArrayList<>(existing.getContent()); + mergedContent.add(TextBlock.builder().text(section).build()); + Msg merged = + Msg.builder() + .id(existing.getId()) + .role(MsgRole.SYSTEM) + .name(existing.getName()) + .content(mergedContent) + .metadata(existing.getMetadata()) + .timestamp(existing.getTimestamp()) + .build(); + msgs.set(systemIndex, merged); + } else { + msgs.add( + 0, + Msg.builder() + .role(MsgRole.SYSTEM) + .name("workspace_context") + .content(TextBlock.builder().text(section).build()) + .build()); + } + event.setInputMessages(msgs); + } + + private String buildWorkspaceSection( + String sessionContext, String guidance, String loadedContextSection) { + StringBuilder sb = new StringBuilder(); + if (!sessionContext.isBlank()) { + sb.append(sessionContext).append("\n\n"); + } + sb.append(guidance).append("\n").append(loadedContextSection); + return sb.toString(); + } + + private String buildSessionContextSection(Path workspace) { + String today = LocalDate.now().format(DateTimeFormatter.ofPattern("EEEE MMM d, yyyy")); + String platform = System.getProperty("os.name") + " " + System.getProperty("os.version"); + String tempDir = System.getProperty("java.io.tmpdir"); + String dynamicPart = buildSessionDynamicPart(); + + return String.format( + SESSION_CONTEXT_SECTION_TEMPLATE, + agentName, + today, + platform, + workspace.toAbsolutePath(), + tempDir, + dynamicPart) + .strip(); + } + + private String buildSessionDynamicPart() { + List parts = new ArrayList<>(); + if (runtimeContext != null && runtimeContext.getSessionId() != null) { + parts.add("Session ID: " + runtimeContext.getSessionId()); + } + if (environmentMemory != null && !environmentMemory.isBlank()) { + parts.add(environmentMemory); + } + return parts.isEmpty() ? "" : String.join("\n", parts); + } + + private static int findFirstSystemMessageIndex(List messages) { + for (int i = 0; i < messages.size(); i++) { + if (messages.get(i).getRole() == MsgRole.SYSTEM) { + return i; + } + } + return -1; + } + + /** + * Builds XML-style loaded context blocks for AGENTS/MEMORY/KNOWLEDGE and extra files. + */ + private String buildLoadedContextSection( + String agentsContent, + String memoryContent, + String knowledgeBlock, + String additionalBlock) { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + sb.append(buildXmlContext("agents_context", agentsContent)); + sb.append(buildXmlContext("memory_context", memoryContent)); + sb.append(buildXmlContext("domain_knowledge_context", knowledgeBlock)); + if (!additionalBlock.isBlank()) { + sb.append(additionalBlock); + } + sb.append("\n"); + return sb.toString(); + } + + private static String buildXmlContext(String tagName, String content) { + if (content == null || content.isBlank()) { + return " <" + tagName + ">\n"; + } + return " <" + tagName + ">\n" + indentByTwo(content.strip()) + "\n \n"; + } + + private static String indentByTwo(String text) { + return text.lines().map(line -> " " + line).collect(Collectors.joining("\n")); + } + + /** + * Renders additional user-configured files as XML blocks under {@code }. + */ + private String buildAdditionalContextBlock() { + if (additionalContextFiles.isEmpty()) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (String relPath : additionalContextFiles) { + String content = workspaceManager.readManagedWorkspaceFileUtf8(relPath); + if (content != null && !content.isBlank()) { + String tag = relPath.replace("/", "_").replace(".", "_").toLowerCase(); + sb.append(" <").append(tag).append(">\n"); + sb.append(indentByTwo(content.strip())).append("\n"); + sb.append(" \n"); + } + } + return sb.toString(); + } + + /** + * Estimates token count using the chars/4 heuristic (consistent with pi-mono). + */ + private static int estimateTokens(String text) { + return text == null || text.isEmpty() ? 0 : text.length() / 4; + } + + private static String truncateToTokenBudget(String text, int maxTokens) { + int maxChars = maxTokens * 4; + if (text.length() <= maxChars) { + return text; + } + return text.substring(0, maxChars) + TRUNCATION_NOTICE; + } + + private String buildKnowledgeBlock(String knowledgeContent, Path workspace) { + List knowledgeFiles = workspaceManager.listKnowledgeFiles(); + StringBuilder sb = new StringBuilder(); + + if (!knowledgeContent.isBlank()) { + sb.append(knowledgeContent.strip()).append("\n"); + } + + if (!knowledgeFiles.isEmpty()) { + if (sb.length() > 0) { + sb.append("\n"); + } + sb.append("Knowledge files:\n"); + sb.append( + knowledgeFiles.stream() + .map(f -> "- " + workspace.relativize(f)) + .collect(Collectors.joining("\n"))); + sb.append("\n"); + } + + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java new file mode 100644 index 000000000..9f5b45bc9 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java @@ -0,0 +1,265 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * LLM-based consolidation of daily memory ledgers into the curated {@code MEMORY.md}. + * + *

This component owns the second layer of the two-layer memory model: + *

    + *
  • Layer 1 — daily ledger: {@code memory/YYYY-MM-DD.md} files written by + * {@link MemoryFlushManager}, append-only, one section per compaction flush.
  • + *
  • Layer 2 — curated MEMORY.md: Owned by this class. Periodically reads the + * daily ledgers (those modified since the last consolidation watermark) plus the + * current MEMORY.md, asks the LLM to merge / dedupe / trim, and overwrites + * MEMORY.md with the result.
  • + *
+ * + *

A small state file ({@code memory/.consolidation_state}) records the timestamp of + * the last successful consolidation. Daily files whose mtime is at or before that + * timestamp are skipped — reducing token usage and protecting MEMORY.md from being + * re-rewritten with stale content. + */ +public class MemoryConsolidator { + + private static final Logger log = LoggerFactory.getLogger(MemoryConsolidator.class); + + /** Hidden state file inside {@code memory/} tracking the last consolidation Instant. */ + public static final String STATE_FILE = ".consolidation_state"; + + private static final String CONSOLIDATION_PROMPT = + """ + You are a memory consolidation assistant. You own the curated long-term memory \ + file MEMORY.md. Your job is to merge new daily ledger entries into MEMORY.md while \ + keeping it concise, deduplicated, and high-signal. + + You are given two inputs: + 1. The current MEMORY.md content (the existing curated long-term memory). + 2. New daily ledger entries that have been appended since the last consolidation. + + Rules: + - MEMORY.md is the single source of truth for cross-day, cross-session knowledge. \ + Keep it stable and authoritative. + - Daily ledger entries are stream-of-consciousness flush logs — they may be noisy, \ + redundant with MEMORY.md, or redundant with each other. Promote only what is \ + durable and reusable. + - Deduplicate: if a new entry restates something MEMORY.md already covers, skip it. + - Merge related facts: combine entries about the same topic into cohesive paragraphs \ + with clear section headers. + - Update or remove stale information when new entries supersede it. + - Keep total output within %d tokens (approximately %d characters); prioritize \ + recent and frequently-referenced information when trimming. + + Output the COMPLETE new MEMORY.md content (not just a diff). Use markdown.\ + """; + + private final WorkspaceManager workspaceManager; + private final Model model; + private final int maxMemoryTokens; + + public MemoryConsolidator(WorkspaceManager workspaceManager, Model model) { + this(workspaceManager, model, 4000); + } + + public MemoryConsolidator(WorkspaceManager workspaceManager, Model model, int maxMemoryTokens) { + this.workspaceManager = workspaceManager; + this.model = model; + this.maxMemoryTokens = maxMemoryTokens; + } + + /** + * Runs consolidation: reads daily files modified after the last watermark and the + * current MEMORY.md, uses the LLM to merge them, overwrites MEMORY.md, and + * advances the watermark on success. + * + *

If no daily files have been touched since the last run, this is a no-op. + */ + public Mono consolidate() { + Instant watermark = readWatermark(); + Instant runStart = Instant.now(); + + String currentMemory = workspaceManager.readMemoryMd(); + String dailyEntries = readDailyEntries(watermark); + + if (dailyEntries.isBlank()) { + log.debug("No fresh daily entries since {} — skipping consolidation", watermark); + return Mono.empty(); + } + + int maxChars = maxMemoryTokens * 4; + String systemPrompt = String.format(CONSOLIDATION_PROMPT, maxMemoryTokens, maxChars); + + StringBuilder userContent = new StringBuilder(); + userContent.append("Current MEMORY.md:\n"); + userContent.append(currentMemory.isBlank() ? "(empty)" : currentMemory); + userContent + .append("\n\nNew daily ledger entries to merge") + .append(watermark == Instant.EPOCH ? "" : " (since " + watermark + ")") + .append(":\n"); + userContent.append(dailyEntries); + + List messages = new ArrayList<>(); + messages.add( + Msg.builder() + .role(MsgRole.SYSTEM) + .content(TextBlock.builder().text(systemPrompt).build()) + .build()); + messages.add( + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(userContent.toString()).build()) + .build()); + + return model.stream(messages, null, null) + .reduce( + new StringBuilder(), + (sb, chatResponse) -> { + if (chatResponse.getContent() != null) { + for (var block : chatResponse.getContent()) { + if (block instanceof TextBlock tb && tb.getText() != null) { + sb.append(tb.getText()); + } + } + } + return sb; + }) + .flatMap( + sb -> { + String consolidated = sb.toString().strip(); + if (consolidated.isBlank()) { + log.warn("Consolidation produced empty output, skipping"); + return Mono.empty(); + } + writeConsolidatedMemory(consolidated); + writeWatermark(runStart); + log.info( + "MEMORY.md consolidated ({} chars), watermark advanced to {}", + consolidated.length(), + runStart); + return Mono.empty(); + }); + } + + /** + * Reads daily memory files modified strictly after the given watermark. + * If watermark is {@link Instant#EPOCH}, all daily files are returned (first run). + */ + private String readDailyEntries(Instant watermark) { + Path memoryDir = workspaceManager.getMemoryDir(); + if (!Files.isDirectory(memoryDir)) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + try (Stream files = Files.list(memoryDir)) { + files.filter(p -> p.toString().endsWith(".md")) + .filter(Files::isRegularFile) + .filter(p -> !p.getFileName().toString().equals("archive")) + .filter(p -> isModifiedAfter(p, watermark)) + .sorted(Comparator.comparing(Path::getFileName)) + .forEach( + p -> { + try { + String content = Files.readString(p); + if (!content.isBlank()) { + sb.append("### ").append(p.getFileName()).append("\n"); + sb.append(content.strip()).append("\n\n"); + } + } catch (IOException e) { + log.warn("Failed to read {}: {}", p, e.getMessage()); + } + }); + } catch (IOException e) { + log.warn("Failed to list memory dir: {}", e.getMessage()); + } + return sb.toString(); + } + + private static boolean isModifiedAfter(Path p, Instant watermark) { + try { + return Files.getLastModifiedTime(p).toInstant().isAfter(watermark); + } catch (IOException e) { + return true; // be safe — include on read error + } + } + + private void writeConsolidatedMemory(String content) { + Path memoryFile = workspaceManager.getWorkspace().resolve(WorkspaceConstants.MEMORY_MD); + try { + if (memoryFile.getParent() != null) { + Files.createDirectories(memoryFile.getParent()); + } + Files.writeString(memoryFile, content); + } catch (IOException e) { + log.warn("Failed to write consolidated MEMORY.md: {}", e.getMessage()); + } + } + + private Path stateFilePath() { + return workspaceManager.getMemoryDir().resolve(STATE_FILE); + } + + /** Reads the last consolidation Instant, or {@link Instant#EPOCH} if none recorded. */ + Instant readWatermark() { + Path state = stateFilePath(); + if (!Files.isRegularFile(state)) { + return Instant.EPOCH; + } + try { + String value = Files.readString(state).strip(); + if (value.isEmpty()) { + return Instant.EPOCH; + } + return Instant.parse(value); + } catch (Exception e) { + log.warn( + "Failed to read consolidation watermark at {}: {} — treating as EPOCH", + state, + e.getMessage()); + return Instant.EPOCH; + } + } + + private void writeWatermark(Instant ts) { + Path state = stateFilePath(); + try { + if (state.getParent() != null) { + Files.createDirectories(state.getParent()); + } + Files.writeString(state, ts.toString()); + } catch (IOException e) { + log.warn("Failed to write consolidation watermark at {}: {}", state, e.getMessage()); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java new file mode 100644 index 000000000..b8df54233 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java @@ -0,0 +1,437 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory; + +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import io.agentscope.core.model.Model; +import io.agentscope.core.util.JsonUtils; +import io.agentscope.harness.agent.memory.session.SessionEntry; +import io.agentscope.harness.agent.memory.session.SessionTree; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.nio.file.Path; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Manages memory flush operations: extracting long-term memories from a conversation + * window and appending them to today's daily memory ledger. + * + *

Two-layer memory model (this class owns only the first layer): + *

    + *
  • {@code memory/YYYY-MM-DD.md} — append-only daily ledger. Each compaction's flush + * appends a timestamped section here. Written ONLY by this class.
  • + *
  • {@code MEMORY.md} — globally curated, deduplicated, size-bounded long-term memory. + * Written ONLY by {@link MemoryConsolidator} on a periodic schedule. Treated as + * read-only context here.
  • + *
+ */ +public class MemoryFlushManager { + + private static final Logger log = LoggerFactory.getLogger(MemoryFlushManager.class); + + private static final String FLUSH_SYSTEM_PROMPT = + """ + You are a memory extraction assistant. Analyze the conversation below and extract \ + important facts, decisions, preferences, and contextual information that should be \ + remembered for future conversations. + + Output ONLY the extracted memories as a markdown bullet list. Each item should be \ + a concise, self-contained fact. Include dates, names, and specifics when available. + + If there is nothing worth remembering, respond with exactly: NO_REPLY + + Guidelines: + - Extract user preferences, personal information, project decisions + - Capture important technical decisions and their rationale + - Note any commitments, deadlines, or action items + - Record relationship context (who works on what, team structure) + - Ignore routine greetings, tool invocations, and ephemeral status updates + + IMPORTANT — write target and append-only rules: + - You are writing to TODAY'S daily memory ledger (memory/YYYY-MM-DD.md), NOT to \ + MEMORY.md. The daily ledger is append-only — your output will be appended after the \ + entries already shown below. + - MEMORY.md is the curated long-term memory and is shown ONLY as read-only context. \ + Do NOT restate facts already covered by MEMORY.md or by today's earlier entries; a \ + separate consolidation step periodically merges new daily entries into MEMORY.md. + - Keep each bullet point independent and self-contained so entries can be searched \ + individually.\ + """; + + private final WorkspaceManager workspaceManager; + private final Model model; + private volatile MemoryIndex memoryIndex; + private volatile MemoryMaintenanceScheduler maintenanceScheduler; + + public MemoryFlushManager(WorkspaceManager workspaceManager, Model model) { + this.workspaceManager = workspaceManager; + this.model = model; + } + + public void setMemoryIndex(MemoryIndex memoryIndex) { + this.memoryIndex = memoryIndex; + } + + /** + * Optional hook into the maintenance scheduler. When set, every successful flush will + * call {@link MemoryMaintenanceScheduler#requestConsolidation()} so MEMORY.md stays + * fresh in long sessions instead of waiting for the next periodic tick. + */ + public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { + this.maintenanceScheduler = scheduler; + } + + /** + * Extracts long-term memories from messages using the model and writes them to disk. + * + *

Provides existing MEMORY.md and today's daily file content to the extraction LLM + * so it can effectively deduplicate and avoid re-extracting known facts. + */ + public Mono flushMemories(List messages) { + String conversationText = serializeMessages(messages); + if (conversationText.isBlank()) { + return Mono.empty(); + } + + String existingMemory = readExistingContent(WorkspaceConstants.MEMORY_MD); + String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); + String dailyRelPath = WorkspaceConstants.MEMORY_DIR + "/" + today + ".md"; + String existingDaily = readExistingContent(dailyRelPath); + + StringBuilder userPrompt = new StringBuilder(); + if (!existingMemory.isBlank()) { + userPrompt + .append("MEMORY.md (read-only curated long-term memory — do NOT restate):\n") + .append(existingMemory) + .append("\n\n"); + } + if (!existingDaily.isBlank()) { + userPrompt + .append("Today's daily ledger so far (your output will be appended after):\n") + .append(existingDaily) + .append("\n\n"); + } + userPrompt + .append( + "Extract NEW memories from this conversation window (skip anything" + + " already covered above):\n\n") + .append(conversationText); + + List flushInput = new ArrayList<>(); + flushInput.add( + Msg.builder() + .role(MsgRole.SYSTEM) + .content(TextBlock.builder().text(FLUSH_SYSTEM_PROMPT).build()) + .build()); + flushInput.add( + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(userPrompt.toString()).build()) + .build()); + + return model.stream(flushInput, null, null) + .reduce( + new StringBuilder(), + (sb, chatResponse) -> { + List blocks = chatResponse.getContent(); + if (blocks != null) { + for (ContentBlock block : blocks) { + if (block instanceof TextBlock tb) { + String t = tb.getText(); + if (t != null) { + sb.append(t); + } + } + } + } + return sb; + }) + .flatMap( + sb -> { + String extracted = sb.toString(); + if (extracted.isBlank() || extracted.strip().equals("NO_REPLY")) { + log.debug("No memories to flush"); + return Mono.empty(); + } + writeMemoryFiles(extracted); + requestConsolidation(); + return Mono.empty(); + }); + } + + /** + * Returns the string path of the session JSONL file where messages for the given agent and + * session are offloaded. Used by the compaction layer to embed the archive location in the + * summary message so the agent can retrieve full history if needed. + */ + public String resolveOffloadPath(String agentId, String sessionId) { + try { + Path p = workspaceManager.resolveSessionContextFile(agentId, sessionId); + return p != null ? p.toString() : ""; + } catch (Exception e) { + log.debug( + "Could not resolve offload path for agent={}, session={}: {}", + agentId, + sessionId, + e.getMessage()); + return ""; + } + } + + /** + * Offloads raw messages to the JSONL session tree. + */ + public void offloadMessages(List messages, String agentId, String sessionId) { + offloadToSessionTree(messages, agentId, sessionId); + + log.debug( + "Offloaded {} messages for agent={}, session={}", + messages.size(), + agentId, + sessionId); + workspaceManager.updateSessionIndex(agentId, sessionId, "conversation offloaded"); + } + + private void offloadToSessionTree(List messages, String agentId, String sessionId) { + try { + Path contextFile = workspaceManager.resolveSessionContextFile(agentId, sessionId); + SessionTree tree = new SessionTree(contextFile); + tree.load(); + + String lastId = null; + for (Msg msg : messages) { + if (msg.getRole() == null || isSessionContextMessage(msg)) { + continue; + } + String rendered = renderContentBlocks(msg); + if (rendered == null || rendered.isBlank()) { + continue; + } + String toolCallId = extractToolCallId(msg); + SessionEntry.MessageEntry entry = + new SessionEntry.MessageEntry( + null, lastId, null, msg.getRole().name(), rendered, toolCallId); + tree.append(entry); + lastId = entry.getId(); + } + + tree.flush(); + } catch (Exception e) { + log.warn("Failed to offload to JSONL session tree: {}", e.getMessage()); + } + } + + /** + * Extracts a representative tool call ID from a message, if present. + * For TOOL messages, returns the first ToolResultBlock's id. + * For ASSISTANT messages with tool calls, returns the first ToolUseBlock's id. + */ + private static String extractToolCallId(Msg msg) { + for (ContentBlock block : msg.getContent()) { + if (block instanceof ToolResultBlock tr && tr.getId() != null) { + return tr.getId(); + } + if (block instanceof ToolUseBlock tu && tu.getId() != null) { + return tu.getId(); + } + } + return null; + } + + /** + * Appends the extracted entries to today's daily memory ledger. + * + *

MEMORY.md is intentionally NOT touched here — it is owned by + * {@link MemoryConsolidator}, which periodically merges the daily ledgers into a + * curated, size-bounded MEMORY.md. + */ + private void writeMemoryFiles(String content) { + String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); + + String dailyEntry = + String.format( + "\n## Memory Flush — %s\n%s\n", + java.time.Instant.now().toString(), content); + + String dailyRelPath = WorkspaceConstants.MEMORY_DIR + "/" + today + ".md"; + workspaceManager.appendUtf8WorkspaceRelative(dailyRelPath, dailyEntry); + + indexAfterWrite(dailyRelPath); + } + + /** + * Asks the maintenance scheduler (if wired) to opportunistically consolidate MEMORY.md. + * The scheduler throttles requests, so calling this every flush is safe. + */ + private void requestConsolidation() { + MemoryMaintenanceScheduler s = this.maintenanceScheduler; + if (s != null) { + try { + s.requestConsolidation(); + } catch (Exception e) { + log.debug("Opportunistic consolidation request failed: {}", e.getMessage()); + } + } + } + + /** + * Re-indexes today's daily ledger so search reflects the just-appended entries. + * MEMORY.md is re-indexed separately by {@link MemoryMaintenanceScheduler#runMaintenance()} + * after consolidation, so it is not touched here. + */ + private void indexAfterWrite(String dailyRelPath) { + MemoryIndex idx = this.memoryIndex; + if (idx == null) { + return; + } + try { + idx.indexFromString( + dailyRelPath, workspaceManager.readManagedWorkspaceFileUtf8(dailyRelPath)); + } catch (Exception e) { + log.warn("Failed to index daily memory file after write: {}", e.getMessage()); + } + } + + private String readExistingContent(String relativePath) { + try { + String content = workspaceManager.readManagedWorkspaceFileUtf8(relativePath); + return content != null ? content : ""; + } catch (Exception e) { + log.debug("Could not read {}: {}", relativePath, e.getMessage()); + return ""; + } + } + + private static final String SESSION_CONTEXT_TAG = ""; + + /** + * Serializes all messages into a textual representation for the memory extraction model. + * Includes USER, ASSISTANT, and TOOL messages. Assistant tool-call blocks and tool-result + * blocks are rendered as concise text so the model can extract memories from tool interactions. + * The injected {@code } user message is skipped as it contains only + * environment metadata, not real conversation content. + */ + private String serializeMessages(List messages) { + return messages.stream() + .filter(m -> m.getRole() != null && m.getRole() != MsgRole.SYSTEM) + .filter(m -> !isSessionContextMessage(m)) + .map(this::renderMessage) + .filter(s -> s != null && !s.isBlank()) + .collect(Collectors.joining("\n")); + } + + private static boolean isSessionContextMessage(Msg msg) { + if (msg.getRole() != MsgRole.USER) { + return false; + } + String text = msg.getTextContent(); + return text != null && text.contains(SESSION_CONTEXT_TAG); + } + + private String renderMessage(Msg msg) { + String body = renderContentBlocks(msg); + if (body == null) { + return null; + } + return "[" + msg.getRole().name() + "]: " + body; + } + + /** + * Renders all content blocks of a message into a single text string. + * Returns null if no renderable content is found. + */ + private String renderContentBlocks(Msg msg) { + List blocks = msg.getContent(); + if (blocks == null || blocks.isEmpty()) { + return null; + } + + List parts = new ArrayList<>(); + for (ContentBlock block : blocks) { + if (block instanceof TextBlock tb) { + String text = tb.getText(); + if (text != null && !text.isBlank()) { + parts.add(text); + } + } else if (block instanceof ToolUseBlock tu) { + parts.add(renderToolUse(tu)); + } else if (block instanceof ToolResultBlock tr) { + parts.add(renderToolResult(tr)); + } + } + + if (parts.isEmpty()) { + return null; + } + return String.join("\n", parts); + } + + private static String renderToolUse(ToolUseBlock tu) { + StringBuilder sb = new StringBuilder(); + sb.append("[tool_call: ").append(tu.getName()); + if (tu.getInput() != null && !tu.getInput().isEmpty()) { + try { + String inputJson = JsonUtils.getJsonCodec().toJson(tu.getInput()); + if (inputJson.length() > 500) { + inputJson = inputJson.substring(0, 500) + "..."; + } + sb.append("(").append(inputJson).append(")"); + } catch (Exception e) { + sb.append("(...)"); + } + } + sb.append("]"); + return sb.toString(); + } + + private static String renderToolResult(ToolResultBlock tr) { + StringBuilder sb = new StringBuilder(); + sb.append("[tool_result"); + if (tr.getName() != null) { + sb.append(": ").append(tr.getName()); + } + sb.append("] "); + + List outputs = tr.getOutput(); + if (outputs != null) { + for (ContentBlock out : outputs) { + if (out instanceof TextBlock tb) { + String text = tb.getText(); + if (text != null) { + if (text.length() > 1000) { + sb.append(text, 0, 1000).append("...(truncated)"); + } else { + sb.append(text); + } + } + } + } + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java new file mode 100644 index 000000000..c3b56a109 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java @@ -0,0 +1,274 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory; + +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SQLite FTS5-backed index for long-term memory files ({@code MEMORY.md} and + * {@code memory/*.md}). + * + *

Each line of every indexed file is stored as a separate row so that search + * results can reference specific line numbers. The index is stored at + * {@code {workspace}/.agentscope/memory_index.db}. + */ +public class MemoryIndex implements AutoCloseable { + + private static final Logger log = LoggerFactory.getLogger(MemoryIndex.class); + + private final Path dbPath; + private Connection connection; + + public MemoryIndex(Path workspaceAgentScopeDir) { + this.dbPath = workspaceAgentScopeDir.resolve("memory_index.db"); + } + + /** + * Opens the SQLite database and creates the FTS5 virtual table if needed. + */ + public synchronized void open() throws SQLException { + if (connection != null && !connection.isClosed()) { + return; + } + try { + Files.createDirectories(dbPath.getParent()); + } catch (IOException e) { + throw new SQLException("Cannot create directory for memory_index.db", e); + } + connection = DriverManager.getConnection("jdbc:sqlite:" + dbPath.toAbsolutePath()); + try (Statement stmt = connection.createStatement()) { + stmt.execute( + "CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts " + + "USING fts5(path, line_number, content)"); + } + } + + /** + * Re-indexes a single file: deletes old rows for that path and inserts new ones. + */ + public synchronized void indexFile(Path file) throws SQLException, IOException { + ensureOpen(); + String relativePath = file.getFileName().toString(); + Path parent = file.getParent(); + if (parent != null) { + Path parentName = parent.getFileName(); + if (parentName != null && "memory".equals(parentName.toString())) { + relativePath = "memory/" + file.getFileName(); + } + } + + try (PreparedStatement del = + connection.prepareStatement("DELETE FROM memory_fts WHERE path = ?")) { + del.setString(1, relativePath); + del.executeUpdate(); + } + + if (!Files.exists(file)) { + return; + } + + List lines = Files.readAllLines(file); + insertLines(relativePath, lines); + log.debug("Indexed {} lines from {}", lines.size(), relativePath); + } + + /** + * Re-indexes from in-memory content (same logical paths as {@link #indexFile(Path)}). + */ + public synchronized void indexFromString(String relativePath, String content) + throws SQLException, IOException { + ensureOpen(); + if (relativePath == null || relativePath.isBlank()) { + return; + } + try (PreparedStatement del = + connection.prepareStatement("DELETE FROM memory_fts WHERE path = ?")) { + del.setString(1, relativePath); + del.executeUpdate(); + } + if (content == null || content.isBlank()) { + return; + } + List lines = java.util.Arrays.asList(content.split("\n", -1)); + insertLines(relativePath, lines); + log.debug("Indexed {} lines from {}", lines.size(), relativePath); + } + + private void insertLines(String relativePath, List lines) throws SQLException { + try (PreparedStatement ins = + connection.prepareStatement( + "INSERT INTO memory_fts(path, line_number, content) VALUES (?, ?, ?)")) { + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i).strip(); + if (line.isEmpty()) { + continue; + } + ins.setString(1, relativePath); + ins.setString(2, String.valueOf(i + 1)); + ins.setString(3, line); + ins.addBatch(); + } + ins.executeBatch(); + } + } + + /** + * Full-text search across indexed memory files. Returns up to {@code maxResults} hits + * ranked by FTS5 relevance. + */ + public synchronized List search(String query, int maxResults) throws SQLException { + ensureOpen(); + List results = new ArrayList<>(); + String ftsQuery = sanitizeFtsQuery(query); + if (ftsQuery.isBlank()) { + return results; + } + try (PreparedStatement ps = + connection.prepareStatement( + "SELECT path, line_number, content, rank " + + "FROM memory_fts WHERE memory_fts MATCH ? " + + "ORDER BY rank LIMIT ?")) { + ps.setString(1, ftsQuery); + ps.setInt(2, maxResults); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + results.add( + new SearchHit( + rs.getString("path"), + rs.getInt("line_number"), + rs.getString("content"), + rs.getDouble("rank"))); + } + } + } + return results; + } + + /** + * Backend-agnostic indexing: discovers all memory files and session log files via + * {@link WorkspaceManager} and indexes their content. Works for Local, Store, and + * Sandbox backends. + */ + public void indexAllFromWorkspace(WorkspaceManager wsManager) throws SQLException, IOException { + List paths = wsManager.listMemoryFilePaths(); + for (String relativePath : paths) { + String content = wsManager.readManagedWorkspaceFileUtf8(relativePath); + indexFromString(relativePath, content); + } + + indexSessionLogFiles(wsManager); + } + + /** + * Indexes session log files ({@code .log.jsonl}) for full-text search across + * session history. Uses {@link WorkspaceManager#listSessionLogFiles()} to discover + * files from both the filesystem layer and local disk. + */ + private void indexSessionLogFiles(WorkspaceManager wsManager) { + List logPaths = wsManager.listSessionLogFiles(); + for (String relativePath : logPaths) { + try { + String content = wsManager.readManagedWorkspaceFileUtf8(relativePath); + indexFromString(relativePath, content); + } catch (Exception e) { + log.debug("Failed to index session log {}: {}", relativePath, e.getMessage()); + } + } + } + + /** + * Indexes {@code MEMORY.md} and all {@code memory/*.md} files under the given workspace. + * + * @deprecated Use {@link #indexAllFromWorkspace(WorkspaceManager)} for backend-agnostic + * indexing. + */ + @Deprecated + public void indexAll(Path workspace) throws SQLException, IOException { + Path memoryMd = workspace.resolve("MEMORY.md"); + if (Files.exists(memoryMd)) { + indexFile(memoryMd); + } + + Path memoryDir = workspace.resolve("memory"); + if (Files.isDirectory(memoryDir)) { + try (Stream files = Files.list(memoryDir)) { + List mdFiles = files.filter(p -> p.toString().endsWith(".md")).toList(); + for (Path f : mdFiles) { + indexFile(f); + } + } + } + } + + @Override + public synchronized void close() { + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + log.warn("Error closing memory index db: {}", e.getMessage()); + } + connection = null; + } + } + + private void ensureOpen() throws SQLException { + if (connection == null || connection.isClosed()) { + open(); + } + } + + /** + * Sanitizes a user query for FTS5 MATCH syntax. Wraps each token in double quotes + * so special characters are treated as literals. + */ + static String sanitizeFtsQuery(String raw) { + if (raw == null) { + return ""; + } + String[] tokens = raw.strip().split("\\s+"); + StringBuilder sb = new StringBuilder(); + for (String tok : tokens) { + if (tok.isEmpty()) { + continue; + } + if (sb.length() > 0) { + sb.append(' '); + } + sb.append('"').append(tok.replace("\"", "")).append('"'); + } + return sb.toString(); + } + + /** + * A single search result. + */ + public record SearchHit(String path, int lineNumber, String content, double rank) {} +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java new file mode 100644 index 000000000..61a2eb2d8 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java @@ -0,0 +1,286 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory; + +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Periodic background maintenance for the memory system. + * + *

Performs: + *

    + *
  • LLM-based memory consolidation (daily files into MEMORY.md)
  • + *
  • Expiration/archival of old daily memory files
  • + *
  • Pruning of old session files
  • + *
  • Re-indexing of memory files into the FTS5 index
  • + *
+ * + *

Runs on a configurable interval (default: every 6 hours). + */ +public class MemoryMaintenanceScheduler { + + private static final Logger log = LoggerFactory.getLogger(MemoryMaintenanceScheduler.class); + + /** Minimum gap between two opportunistic (post-flush) consolidations. */ + private static final Duration MIN_OPPORTUNISTIC_GAP = Duration.ofMinutes(30); + + private final WorkspaceManager workspaceManager; + private final MemoryIndex memoryIndex; + private final MemoryConsolidator consolidator; + private final Duration interval; + private final int dailyFileRetentionDays; + private final int sessionRetentionDays; + + private ScheduledExecutorService executor; + private final java.util.concurrent.atomic.AtomicReference lastConsolidationAt = + new java.util.concurrent.atomic.AtomicReference<>(Instant.EPOCH); + + public MemoryMaintenanceScheduler( + WorkspaceManager workspaceManager, + MemoryIndex memoryIndex, + MemoryConsolidator consolidator, + Duration interval, + int dailyFileRetentionDays, + int sessionRetentionDays) { + this.workspaceManager = workspaceManager; + this.memoryIndex = memoryIndex; + this.consolidator = consolidator; + this.interval = interval; + this.dailyFileRetentionDays = dailyFileRetentionDays; + this.sessionRetentionDays = sessionRetentionDays; + } + + public MemoryMaintenanceScheduler( + WorkspaceManager workspaceManager, MemoryIndex memoryIndex, Model model) { + this( + workspaceManager, + memoryIndex, + model != null ? new MemoryConsolidator(workspaceManager, model) : null, + Duration.ofHours(6), + 90, + 180); + } + + public MemoryMaintenanceScheduler(WorkspaceManager workspaceManager, MemoryIndex memoryIndex) { + this( + workspaceManager, + memoryIndex, + (MemoryConsolidator) null, + Duration.ofHours(6), + 90, + 180); + } + + public void start() { + if (executor != null) { + return; + } + executor = + Executors.newSingleThreadScheduledExecutor( + r -> { + Thread t = new Thread(r, "memory-maintenance"); + t.setDaemon(true); + return t; + }); + executor.scheduleAtFixedRate( + this::runMaintenance, + interval.toMillis(), + interval.toMillis(), + TimeUnit.MILLISECONDS); + log.info("Memory maintenance scheduler started (interval={})", interval); + } + + public void stop() { + if (executor != null) { + executor.shutdownNow(); + executor = null; + } + } + + public void runMaintenance() { + try { + log.debug("Running memory maintenance..."); + expireDailyFiles(); + consolidateMemory(); + pruneOldSessions(); + reindex(); + log.debug("Memory maintenance completed"); + } catch (Exception e) { + log.warn("Memory maintenance failed: {}", e.getMessage()); + } + } + + /** + * Requests an opportunistic consolidation, typically called right after + * {@link io.agentscope.harness.agent.memory.MemoryFlushManager} appends to a daily ledger. + * + *

To avoid running for every flush, the request is throttled by + * {@link #MIN_OPPORTUNISTIC_GAP} relative to the previous consolidation. The work + * itself is dispatched onto the maintenance executor when it is running, so it never + * blocks the agent's reasoning loop. If the executor is not running, the request is + * silently skipped (the periodic timer will pick it up later). + */ + public void requestConsolidation() { + if (consolidator == null) { + return; + } + ScheduledExecutorService exec = this.executor; + if (exec == null || exec.isShutdown()) { + return; + } + Instant now = Instant.now(); + Instant last = lastConsolidationAt.get(); + if (Duration.between(last, now).compareTo(MIN_OPPORTUNISTIC_GAP) < 0) { + return; + } + if (!lastConsolidationAt.compareAndSet(last, now)) { + return; // another caller raced ahead + } + try { + exec.submit(this::consolidateMemory); + } catch (Exception e) { + log.debug("Failed to submit opportunistic consolidation: {}", e.getMessage()); + } + } + + private void consolidateMemory() { + if (consolidator == null) { + return; + } + try { + consolidator.consolidate().block(); + lastConsolidationAt.set(Instant.now()); + } catch (Exception e) { + log.warn("Memory consolidation failed: {}", e.getMessage()); + } + } + + private void expireDailyFiles() { + Path memoryDir = workspaceManager.getMemoryDir(); + if (!Files.isDirectory(memoryDir)) { + return; + } + + LocalDate cutoff = LocalDate.now().minusDays(dailyFileRetentionDays); + try (Stream files = Files.list(memoryDir)) { + files.filter(p -> p.toString().endsWith(".md")) + .filter(Files::isRegularFile) + .forEach( + p -> { + String name = p.getFileName().toString().replace(".md", ""); + try { + LocalDate fileDate = LocalDate.parse(name); + if (fileDate.isBefore(cutoff)) { + Path archiveDir = memoryDir.resolve("archive"); + try { + Files.createDirectories(archiveDir); + Files.move(p, archiveDir.resolve(p.getFileName())); + log.debug("Archived expired daily file: {}", name); + } catch (IOException e) { + log.warn( + "Failed to archive {}: {}", + name, + e.getMessage()); + } + } + } catch (Exception e) { + // not a date-named file, skip + } + }); + } catch (IOException e) { + log.warn("Failed to list memory dir: {}", e.getMessage()); + } + } + + private void pruneOldSessions() { + Path agentsDir = workspaceManager.getWorkspace().resolve(WorkspaceConstants.AGENTS_DIR); + if (!Files.isDirectory(agentsDir)) { + return; + } + + Instant cutoff = Instant.now().minus(Duration.ofDays(sessionRetentionDays)); + try (Stream agents = Files.list(agentsDir)) { + agents.filter(Files::isDirectory) + .forEach( + agentDir -> { + Path sessionsDir = + agentDir.resolve(WorkspaceConstants.SESSIONS_DIR); + if (!Files.isDirectory(sessionsDir)) { + return; + } + try (Stream sessions = Files.list(sessionsDir)) { + sessions.filter(Files::isRegularFile) + .filter( + p -> + !p.getFileName() + .toString() + .equals( + WorkspaceConstants + .SESSIONS_STORE)) + .forEach( + p -> { + try { + Instant modified = + Files.getLastModifiedTime(p) + .toInstant(); + if (modified.isBefore(cutoff)) { + Files.delete(p); + log.debug( + "Pruned old session file:" + + " {}", + p); + } + } catch (IOException e) { + log.warn( + "Failed to check/prune {}: {}", + p, + e.getMessage()); + } + }); + } catch (IOException e) { + log.warn("Failed to list sessions: {}", e.getMessage()); + } + }); + } catch (IOException e) { + log.warn("Failed to list agents dir: {}", e.getMessage()); + } + } + + private void reindex() { + if (memoryIndex == null) { + return; + } + try { + memoryIndex.indexAllFromWorkspace(workspaceManager); + } catch (Exception e) { + log.warn("Failed to reindex: {}", e.getMessage()); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionConfig.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionConfig.java new file mode 100644 index 000000000..d7dcd67a6 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionConfig.java @@ -0,0 +1,342 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.compaction; + +/** + * Configuration for conversation compaction (summarization). + * + *

    + *
  • trigger — when to run compaction (by token count or message count)
  • + *
  • keep — how many recent messages to preserve verbatim after compaction
  • + *
+ * + *

Defaults: + *

    + *
  • Trigger at 50 messages or 80 000 estimated tokens (whichever comes first)
  • + *
  • Keep the 20 most recent messages verbatim
  • + *
  • Summarization is enabled; memory flush and offload are both enabled before summary
  • + *
+ */ +public class CompactionConfig { + + /** Default summary prompt with structured format. */ + public static final String DEFAULT_SUMMARY_PROMPT = + """ + + Context Extraction Assistant + + + + Your sole objective in this task is to extract the highest quality/most relevant \ + context from the conversation history below. + + + + You're nearing the total number of input tokens you can accept, so you must extract \ + the highest quality/most relevant pieces of information from your conversation history. + This context will then overwrite the conversation history presented below. Because of \ + this, ensure the context you extract is only the most important information to \ + continue working toward your overall goal. + + + + The conversation history below will be replaced with the context you extract in this \ + step. You want to ensure that you don't repeat any actions you've already completed, \ + so the context you extract from the conversation history should be focused on the \ + most important information to your overall goal. + + Structure your summary using these sections (populate each or write "None"): + + ## SESSION INTENT + What is the user's primary goal or request? + + ## SUMMARY + The most important context, decisions, reasoning, and rejected options. + + ## ARTIFACTS + Files or resources created, modified, or accessed (with specific paths and changes). + + ## NEXT STEPS + Specific tasks remaining to achieve the session intent. + + + Carefully read through the entire conversation history below and extract the most \ + important context. Respond ONLY with the extracted context. + + + {messages} + \ + """; + + private final int triggerMessages; + private final int triggerTokens; + private final int keepMessages; + private final int keepTokens; + private final String summaryPrompt; + private final boolean flushBeforeCompact; + private final boolean offloadBeforeCompact; + private final TruncateArgsConfig truncateArgsConfig; + + private CompactionConfig(Builder b) { + this.triggerMessages = b.triggerMessages; + this.triggerTokens = b.triggerTokens; + this.keepMessages = b.keepMessages; + this.keepTokens = b.keepTokens; + this.summaryPrompt = b.summaryPrompt; + this.flushBeforeCompact = b.flushBeforeCompact; + this.offloadBeforeCompact = b.offloadBeforeCompact; + this.truncateArgsConfig = b.truncateArgsConfig; + } + + /** Message count above which compaction is triggered (0 = disabled). */ + public int getTriggerMessages() { + return triggerMessages; + } + + /** Estimated token count above which compaction is triggered (0 = disabled). */ + public int getTriggerTokens() { + return triggerTokens; + } + + /** + * Number of recent conversation messages (non-SYSTEM) to preserve verbatim. + * Used when {@link #getKeepTokens()} is 0. + */ + public int getKeepMessages() { + return keepMessages; + } + + /** + * Token budget for the preserved tail. When non-zero, the keep boundary is determined by + * scanning from the end until the token budget is exhausted rather than by a fixed count. + */ + public int getKeepTokens() { + return keepTokens; + } + + /** Prompt template used for the summarization LLM call. Must contain {@code {messages}}. */ + public String getSummaryPrompt() { + return summaryPrompt; + } + + /** Whether to flush long-term memories from the prefix before compaction. */ + public boolean isFlushBeforeCompact() { + return flushBeforeCompact; + } + + /** Whether to offload raw messages to the session JSONL before compaction. */ + public boolean isOffloadBeforeCompact() { + return offloadBeforeCompact; + } + + /** + * Configuration for the lightweight pre-summarization argument truncation pass. + * When {@code null}, argument truncation is disabled. + */ + public TruncateArgsConfig getTruncateArgsConfig() { + return truncateArgsConfig; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private int triggerMessages = 50; + private int triggerTokens = 80_000; + private int keepMessages = 20; + private int keepTokens = 0; + private String summaryPrompt = DEFAULT_SUMMARY_PROMPT; + private boolean flushBeforeCompact = true; + private boolean offloadBeforeCompact = true; + private TruncateArgsConfig truncateArgsConfig = null; + + /** Trigger compaction when conversation has at least this many messages (0 = disabled). */ + public Builder triggerMessages(int triggerMessages) { + this.triggerMessages = triggerMessages; + return this; + } + + /** Trigger compaction when estimated token count exceeds this value (0 = disabled). */ + public Builder triggerTokens(int triggerTokens) { + this.triggerTokens = triggerTokens; + return this; + } + + /** Number of recent messages to keep verbatim after compaction. */ + public Builder keepMessages(int keepMessages) { + this.keepMessages = keepMessages; + return this; + } + + /** + * Token budget for the preserved tail (overrides {@code keepMessages} when non-zero). + */ + public Builder keepTokens(int keepTokens) { + this.keepTokens = keepTokens; + return this; + } + + /** Custom summary prompt. Must contain {@code {messages}} placeholder. */ + public Builder summaryPrompt(String summaryPrompt) { + this.summaryPrompt = summaryPrompt; + return this; + } + + /** Whether to flush long-term memories before compaction (default true). */ + public Builder flushBeforeCompact(boolean flushBeforeCompact) { + this.flushBeforeCompact = flushBeforeCompact; + return this; + } + + /** Whether to offload raw messages to session JSONL before compaction (default true). */ + public Builder offloadBeforeCompact(boolean offloadBeforeCompact) { + this.offloadBeforeCompact = offloadBeforeCompact; + return this; + } + + /** + * Enables lightweight pre-summarization argument truncation. When set, large + * {@code ToolUseBlock} argument values in old messages are shortened before every + * model call (no LLM required). This fires at a separate, typically lower threshold + * than full compaction. + * + *

Pass {@code null} (default) to disable. + */ + public Builder truncateArgs(TruncateArgsConfig config) { + this.truncateArgsConfig = config; + return this; + } + + public CompactionConfig build() { + return new CompactionConfig(this); + } + } + + // ------------------------------------------------------------------------- + // TruncateArgsConfig + // ------------------------------------------------------------------------- + + /** + * Configuration for the lightweight argument-truncation pass that runs before + * summarization. + * + *

When triggered, large string arguments of {@code ToolUseBlock}s in older messages + * (before the keep window) are clipped to {@link #getMaxArgLength()} characters. + * This is a cheap, non-LLM operation that prevents context ballooning from verbose + * tool invocations (e.g., {@code write_file}, {@code edit_file}). + * + *

Defaults (when enabled via {@link Builder#truncateArgs(TruncateArgsConfig)}): + *

    + *
  • Trigger at 25 messages or 40 000 tokens
  • + *
  • Keep the 20 most recent messages untouched
  • + *
  • Max argument length: 2 000 characters
  • + *
+ */ + public static class TruncateArgsConfig { + + private final int triggerMessages; + private final int triggerTokens; + private final int keepMessages; + private final int keepTokens; + private final int maxArgLength; + private final String truncationText; + + private TruncateArgsConfig(TruncateArgsBuilder b) { + this.triggerMessages = b.triggerMessages; + this.triggerTokens = b.triggerTokens; + this.keepMessages = b.keepMessages; + this.keepTokens = b.keepTokens; + this.maxArgLength = b.maxArgLength; + this.truncationText = b.truncationText; + } + + public int getTriggerMessages() { + return triggerMessages; + } + + public int getTriggerTokens() { + return triggerTokens; + } + + public int getKeepMessages() { + return keepMessages; + } + + public int getKeepTokens() { + return keepTokens; + } + + /** Maximum character length of any single tool argument value (default 2 000). */ + public int getMaxArgLength() { + return maxArgLength; + } + + /** Suffix appended after the first 20 characters of a truncated argument. */ + public String getTruncationText() { + return truncationText; + } + + public static TruncateArgsBuilder builder() { + return new TruncateArgsBuilder(); + } + + public static class TruncateArgsBuilder { + + private int triggerMessages = 25; + private int triggerTokens = 40_000; + private int keepMessages = 20; + private int keepTokens = 0; + private int maxArgLength = 2_000; + private String truncationText = "...(argument truncated)"; + + public TruncateArgsBuilder triggerMessages(int triggerMessages) { + this.triggerMessages = triggerMessages; + return this; + } + + public TruncateArgsBuilder triggerTokens(int triggerTokens) { + this.triggerTokens = triggerTokens; + return this; + } + + public TruncateArgsBuilder keepMessages(int keepMessages) { + this.keepMessages = keepMessages; + return this; + } + + public TruncateArgsBuilder keepTokens(int keepTokens) { + this.keepTokens = keepTokens; + return this; + } + + public TruncateArgsBuilder maxArgLength(int maxArgLength) { + this.maxArgLength = maxArgLength; + return this; + } + + public TruncateArgsBuilder truncationText(String truncationText) { + this.truncationText = truncationText; + return this; + } + + public TruncateArgsConfig build() { + return new TruncateArgsConfig(this); + } + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java new file mode 100644 index 000000000..aa8033de4 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java @@ -0,0 +1,204 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.compaction; + +import io.agentscope.core.ReActAgent; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.memory.Memory; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.memory.MemoryFlushManager; +import io.agentscope.harness.agent.memory.MemoryIndex; +import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that performs conversation compaction before each LLM reasoning call. + * + *

Fires on {@link PreReasoningEvent}. When the compaction threshold is exceeded: + *

    + *
  1. Long-term memories are flushed from the prefix via {@link MemoryFlushManager}.
  2. + *
  3. The full conversation is offloaded to the session JSONL.
  4. + *
  5. The prefix is distilled into a structured summary via one LLM call.
  6. + *
  7. The agent's working {@link Memory} is replaced with + * {@code [summaryMsg] + preservedTail}.
  8. + *
  9. {@link PreReasoningEvent#setInputMessages} is updated so the LLM sees the + * compacted view: {@code systemMsgs + [summaryMsg] + preservedTail}.
  10. + *
+ * + *

This hook runs at priority 10 — before {@link io.agentscope.harness.agent.hook.WorkspaceContextHook} + * (priority 900): compaction runs on the conversation portion first; workspace files are merged into + * the system message afterwards on the same {@link PreReasoningEvent} chain. + * + *

{@link RuntimeContext} must be injected via {@link #setRuntimeContext} before the hook fires. + */ +public class CompactionHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(CompactionHook.class); + + private final WorkspaceManager workspaceManager; + private final Model model; + private final CompactionConfig config; + + private RuntimeContext runtimeContext; + private volatile MemoryIndex memoryIndex; + private volatile MemoryMaintenanceScheduler maintenanceScheduler; + + public CompactionHook(WorkspaceManager workspaceManager, Model model, CompactionConfig config) { + this.workspaceManager = workspaceManager; + this.model = model; + this.config = config; + } + + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + public void setMemoryIndex(MemoryIndex memoryIndex) { + this.memoryIndex = memoryIndex; + } + + /** Wires the maintenance scheduler so flushes can opportunistically consolidate MEMORY.md. */ + public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { + this.maintenanceScheduler = scheduler; + } + + @Override + public int priority() { + return 10; + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PreReasoningEvent pre) { + return handlePreReasoning(pre).thenReturn(event); + } + return Mono.just(event); + } + + // ------------------------------------------------------------------------- + // Core compaction flow + // ------------------------------------------------------------------------- + + private Mono handlePreReasoning(PreReasoningEvent event) { + if (!(event.getAgent() instanceof ReActAgent reActAgent)) { + return Mono.empty(); + } + + // Separate system messages (injected by WorkspaceContextHook etc.) from conversation + List inputMessages = event.getInputMessages(); + List systemMsgs = new ArrayList<>(); + List conversationMsgs = new ArrayList<>(); + for (Msg m : inputMessages) { + if (m.getRole() == MsgRole.SYSTEM) { + systemMsgs.add(m); + } else { + conversationMsgs.add(m); + } + } + + String agentId = event.getAgent().getName(); + String sessionId = sessionId(); + + MemoryFlushManager flushManager = buildFlushManager(); + ConversationCompactor compactor = new ConversationCompactor(model, flushManager); + + return compactor + .compactIfNeeded(conversationMsgs, config, agentId, sessionId) + .flatMap( + optResult -> { + if (optResult.isEmpty()) { + return Mono.empty(); + } + List compacted = optResult.get(); + applyToMemory(reActAgent.getMemory(), compacted); + applyToEvent(event, systemMsgs, compacted); + return Mono.empty(); + }) + .onErrorResume( + e -> { + log.warn( + "Compaction failed, continuing without compaction: {}", + e.getMessage()); + return Mono.empty(); + }); + } + + /** + * Replaces the agent's working memory with the compacted message list. + * + *

Uses {@link Memory#clear()} + {@link Memory#addMessage(Msg)} to synchronise the + * in-memory state so subsequent reasoning rounds start from the compacted baseline. + */ + private static void applyToMemory(Memory memory, List compacted) { + try { + memory.clear(); + for (Msg msg : compacted) { + memory.addMessage(msg); + } + log.debug("Applied compacted messages to memory ({} messages)", compacted.size()); + } catch (Exception e) { + log.warn("Failed to apply compacted messages to memory: {}", e.getMessage()); + } + } + + /** + * Updates the event's input message list so the LLM sees the compacted view. + * + *

System messages are always placed at the front, followed by the compacted + * conversation (summary + preserved tail). + */ + private static void applyToEvent( + PreReasoningEvent event, List systemMsgs, List compacted) { + List rebuilt = new ArrayList<>(systemMsgs.size() + compacted.size()); + rebuilt.addAll(systemMsgs); + rebuilt.addAll(compacted); + event.setInputMessages(rebuilt); + log.debug( + "Updated PreReasoningEvent: {} system + {} conversation = {} total messages", + systemMsgs.size(), + compacted.size(), + rebuilt.size()); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + private MemoryFlushManager buildFlushManager() { + MemoryFlushManager fm = new MemoryFlushManager(workspaceManager, model); + fm.setMemoryIndex(memoryIndex); + fm.setMaintenanceScheduler(maintenanceScheduler); + return fm; + } + + private String sessionId() { + RuntimeContext ctx = this.runtimeContext; + if (ctx != null && ctx.getSessionId() != null) { + return ctx.getSessionId(); + } + return "default"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java new file mode 100644 index 000000000..51722c36e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java @@ -0,0 +1,600 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.compaction; + +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.memory.MemoryFlushManager; +import io.agentscope.harness.agent.memory.compaction.CompactionConfig.TruncateArgsConfig; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + *

Algorithm

+ *
    + *
  1. Check trigger — token count or message count exceeds threshold
  2. + *
  3. Determine cutoff — find the earliest index that keeps the tail within the + * "keep" budget; never split an ASSISTANT tool-call from its TOOL result(s)
  4. + *
  5. Memory flush (optional) — extract long-term memories from the prefix via + * {@link MemoryFlushManager#flushMemories}
  6. + *
  7. Message offload (optional) — persist the full conversation to the session + * JSONL via {@link MemoryFlushManager#offloadMessages}
  8. + *
  9. Summarize — one LLM call to distill the prefix into a structured summary
  10. + *
  11. Rebuild — return {@code [summaryUserMsg] + preservedTail}
  12. + *
+ * + *

The caller is responsible for updating both the agent's working memory and the LLM-facing + * message list (see {@link CompactionHook}). + */ +public class ConversationCompactor { + + private static final Logger log = LoggerFactory.getLogger(ConversationCompactor.class); + + /** Marker stored in message name to identify injected summary messages. */ + public static final String SUMMARY_MSG_NAME = "__compaction_summary__"; + + private final Model model; + private final MemoryFlushManager flushManager; + + public ConversationCompactor(Model model, MemoryFlushManager flushManager) { + this.model = model; + this.flushManager = flushManager; + } + + // ------------------------------------------------------------------------- + // Public API + // ------------------------------------------------------------------------- + + /** + * Runs compaction on the supplied conversation messages if a trigger condition is met. + * + *

Only conversation messages (non-SYSTEM) should be passed. The caller must + * separate system messages before invoking this method and re-prepend them after. + * + * @param conversationMessages non-SYSTEM messages (USER / ASSISTANT / TOOL) + * @param config compaction configuration + * @param agentId agent identifier used for the memory offload path + * @param sessionId session identifier used for the memory offload path + * @return {@code Optional.empty()} when no compaction was needed; otherwise the replacement + * message list consisting of {@code [summaryUserMsg] + preservedTail} + */ + public Mono>> compactIfNeeded( + List conversationMessages, + CompactionConfig config, + String agentId, + String sessionId) { + + if (conversationMessages == null || conversationMessages.isEmpty()) { + return Mono.just(Optional.empty()); + } + + // Step 1: Lightweight arg truncation (non-LLM). Runs at a lower threshold than + List messages = truncateArgs(conversationMessages, config.getTruncateArgsConfig()); + + int totalTokens = TokenCounterUtil.calculateToken(messages); + if (!shouldCompact(messages, totalTokens, config)) { + return Mono.just(Optional.empty()); + } + + int cutoff = determineCutoffIndex(messages, totalTokens, config); + if (cutoff <= 0) { + log.debug("Compaction triggered but safe cutoff is 0 — skipping"); + return Mono.just(Optional.empty()); + } + + // Filter previous summary messages from the prefix before offloading to avoid + // re-storing already-archived summaries. + List prefix = filterSummaryMessages(new ArrayList<>(messages.subList(0, cutoff))); + List tail = new ArrayList<>(messages.subList(cutoff, messages.size())); + + log.info( + "Compaction triggered: total={} msgs / {} tokens, cutoff={}, keeping={} msgs", + messages.size(), + totalTokens, + cutoff, + tail.size()); + + // Step 2: Flush long-term memories from the prefix (best-effort). + Mono flushStep = + config.isFlushBeforeCompact() + ? flushManager + .flushMemories(prefix) + .doOnSuccess(v -> log.debug("Memory flush before compaction done")) + .onErrorResume( + e -> { + log.warn( + "Memory flush before compaction failed: {}", + e.getMessage()); + return Mono.empty(); + }) + : Mono.empty(); + + // Step 3: Offload raw messages to JSONL and capture the file path. + // If offload fails, we continue with null — the summary message falls back to the + // simple format without a file reference. + Mono offloadStep; + if (config.isOffloadBeforeCompact()) { + offloadStep = + Mono.fromCallable( + () -> { + flushManager.offloadMessages(messages, agentId, sessionId); + return flushManager.resolveOffloadPath(agentId, sessionId); + }) + .doOnSuccess( + path -> + log.debug( + "Message offload before compaction done," + + " path={}", + path)) + .onErrorResume( + e -> { + log.warn( + "Message offload before compaction failed: {}", + e.getMessage()); + return Mono.just(""); + }); + } else { + offloadStep = Mono.just(""); + } + + // Step 4: LLM summarization of the prefix, combined with the offload result. + return flushStep + .then(offloadStep) + .flatMap( + offloadPath -> + summarizePrefix(prefix, config) + .map( + summary -> { + String filePath = + offloadPath.isBlank() + ? null + : offloadPath; + Msg summaryMsg = + buildSummaryMessage(summary, filePath); + List compacted = new ArrayList<>(); + compacted.add(summaryMsg); + compacted.addAll(tail); + log.info( + "Compaction complete: {} msgs → 1" + + " summary + {} tail = {}" + + " total", + messages.size(), + tail.size(), + compacted.size()); + return Optional.of(compacted); + })); + } + + // ------------------------------------------------------------------------- + // Trigger logic + // ------------------------------------------------------------------------- + + private static boolean shouldCompact( + List messages, int totalTokens, CompactionConfig config) { + if (config.getTriggerMessages() > 0 && messages.size() >= config.getTriggerMessages()) { + log.debug( + "Compaction trigger: message count {} >= {}", + messages.size(), + config.getTriggerMessages()); + return true; + } + if (config.getTriggerTokens() > 0 && totalTokens >= config.getTriggerTokens()) { + log.debug( + "Compaction trigger: token count {} >= {}", + totalTokens, + config.getTriggerTokens()); + return true; + } + return false; + } + + // ------------------------------------------------------------------------- + // Cutoff / partition logic + // ------------------------------------------------------------------------- + + /** + * Determines the cutoff index separating the prefix-to-summarize from the tail-to-keep. + * + *

The cutoff is adjusted so that ASSISTANT/TOOL pairs are never split. + */ + private static int determineCutoffIndex( + List messages, int totalTokens, CompactionConfig config) { + int rawCutoff; + if (config.getKeepTokens() > 0) { + rawCutoff = findTokenBasedCutoff(messages, totalTokens, config.getKeepTokens()); + } else { + rawCutoff = findMessageBasedCutoff(messages, config.getKeepMessages()); + } + return findSafeCutoffPoint(messages, rawCutoff); + } + + /** Returns the earliest index such that {@code messages[index:]} fits within the token budget. */ + private static int findTokenBasedCutoff(List messages, int totalTokens, int keepTokens) { + if (totalTokens <= keepTokens) { + return 0; + } + // Binary search for the earliest index where the suffix token count <= keepTokens + int left = 0; + int right = messages.size(); + int candidate = messages.size(); + int maxIter = Integer.SIZE - Integer.numberOfLeadingZeros(messages.size()) + 1; + for (int i = 0; i < maxIter && left < right; i++) { + int mid = (left + right) / 2; + if (TokenCounterUtil.calculateToken(messages.subList(mid, messages.size())) + <= keepTokens) { + candidate = mid; + right = mid; + } else { + left = mid + 1; + } + } + // Clamp so at least 1 message is always kept + return Math.min(candidate, messages.size() - 1); + } + + /** Returns the cutoff that keeps the last {@code keepMessages} messages verbatim. */ + private static int findMessageBasedCutoff(List messages, int keepMessages) { + if (messages.size() <= keepMessages) { + return 0; + } + return messages.size() - keepMessages; + } + + /** + * Adjusts the cutoff to avoid splitting ASSISTANT tool-call/TOOL-result pairs. + * + *

If the message at {@code cutoffIndex} has role TOOL, we search backward for the + * ASSISTANT message whose tool-use blocks correspond to those tool results and move the + * cutoff to include that ASSISTANT message in the prefix (i.e., cut before it). + * + */ + private static int findSafeCutoffPoint(List messages, int cutoffIndex) { + if (cutoffIndex <= 0 || cutoffIndex >= messages.size()) { + return cutoffIndex; + } + + Msg atCutoff = messages.get(cutoffIndex); + if (atCutoff.getRole() != MsgRole.TOOL) { + return cutoffIndex; + } + + // Collect tool-call IDs from consecutive TOOL messages at/after the cutoff + List toolCallIds = new ArrayList<>(); + int idx = cutoffIndex; + while (idx < messages.size() && messages.get(idx).getRole() == MsgRole.TOOL) { + for (ContentBlock block : messages.get(idx).getContent()) { + if (block instanceof ToolResultBlock tr && tr.getId() != null) { + toolCallIds.add(tr.getId()); + } + } + idx++; + } + + if (toolCallIds.isEmpty()) { + // No IDs found — advance past all TOOL messages to avoid orphaned results + return idx; + } + + // Search backward for the ASSISTANT message that issued those tool calls + for (int i = cutoffIndex - 1; i >= 0; i--) { + Msg msg = messages.get(i); + if (msg.getRole() == MsgRole.ASSISTANT) { + for (ContentBlock block : msg.getContent()) { + if (block instanceof ToolUseBlock tu && toolCallIds.contains(tu.getId())) { + // Move the cutoff to just before this ASSISTANT message + return i; + } + } + } + } + + // Fallback: advance past all TOOL messages + return idx; + } + + // ------------------------------------------------------------------------- + // Summarization + // ------------------------------------------------------------------------- + + private Mono summarizePrefix(List prefix, CompactionConfig config) { + if (prefix.isEmpty()) { + return Mono.just("No previous conversation history."); + } + + String formatted = formatMessagesForSummary(prefix); + String prompt = config.getSummaryPrompt().replace("{messages}", formatted); + + List summarizationInput = + List.of( + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(prompt).build()) + .build()); + + return model.stream(summarizationInput, null, null) + .reduce( + new StringBuilder(), + (sb, resp) -> { + if (resp.getContent() != null) { + for (ContentBlock block : resp.getContent()) { + if (block instanceof TextBlock tb && tb.getText() != null) { + sb.append(tb.getText()); + } + } + } + return sb; + }) + .map(StringBuilder::toString) + .map(String::strip) + .filter(s -> !s.isBlank()) + .defaultIfEmpty("(Summary unavailable)") + .onErrorResume( + e -> { + log.warn("Summarization LLM call failed: {}", e.getMessage()); + return Mono.just("(Summarization failed: " + e.getMessage() + ")"); + }); + } + + /** + * Formats a list of messages as a human-readable text block for the summarization LLM. + * + *

Renders TEXT blocks verbatim; TOOL_USE and TOOL_RESULT blocks as concise inline + * representations so the summarizer understands what actions were taken. + */ + static String formatMessagesForSummary(List messages) { + return messages.stream() + .filter(m -> m.getRole() != null && m.getRole() != MsgRole.SYSTEM) + .map(ConversationCompactor::renderMessageForSummary) + .filter(s -> !s.isBlank()) + .collect(Collectors.joining("\n\n")); + } + + private static String renderMessageForSummary(Msg msg) { + String roleLabel = + switch (msg.getRole()) { + case USER -> "Human"; + case ASSISTANT -> "AI"; + case TOOL -> "Tool"; + default -> msg.getRole().name(); + }; + + StringBuilder sb = new StringBuilder(roleLabel).append(": "); + boolean first = true; + for (ContentBlock block : msg.getContent()) { + if (!first) sb.append(" "); + first = false; + if (block instanceof TextBlock tb && tb.getText() != null && !tb.getText().isBlank()) { + sb.append(tb.getText().strip()); + } else if (block instanceof ToolUseBlock tu) { + sb.append("[tool_call: ").append(tu.getName()).append("]"); + } else if (block instanceof ToolResultBlock tr) { + String text = extractToolResultText(tr); + sb.append("[tool_result: ") + .append(tr.getName() != null ? tr.getName() : "?") + .append("] "); + if (!text.isBlank()) { + sb.append(text.length() > 500 ? text.substring(0, 500) + "..." : text); + } + } + } + return sb.toString().strip(); + } + + private static String extractToolResultText(ToolResultBlock tr) { + if (tr.getOutput() == null) return ""; + return tr.getOutput().stream() + .filter(b -> b instanceof TextBlock) + .map(b -> ((TextBlock) b).getText()) + .filter(t -> t != null && !t.isBlank()) + .collect(Collectors.joining(" ")); + } + + // ------------------------------------------------------------------------- + // Summary message construction + // ------------------------------------------------------------------------- + + /** + * Builds a USER message carrying the summary. + * + *

When {@code filePath} is non-null, the message includes a reference to where the full + * conversation history was offloaded. + * When null, falls back to the simple "summary to date" format. + * + *

The message name is set to {@link #SUMMARY_MSG_NAME} so hooks can identify and + * skip summary messages during future flush/offload cycles. + */ + private static Msg buildSummaryMessage(String summary, String filePath) { + String content; + if (filePath != null) { + content = + "You are in the middle of a conversation that has been summarized.\n\n" + + "The full conversation history has been saved to " + + filePath + + " should you need to refer back to it for details.\n\n" + + "A condensed summary follows:\n\n" + + "

\n" + + summary + + "\n"; + } else { + content = "Here is a summary of the conversation to date:\n\n" + summary; + } + return Msg.builder() + .role(MsgRole.USER) + .name(SUMMARY_MSG_NAME) + .content(TextBlock.builder().text(content).build()) + .build(); + } + + // ------------------------------------------------------------------------- + // Summary message filtering (chained summarization support) + // ------------------------------------------------------------------------- + + /** + * Removes previously injected summary messages from a list. + * + *

During chained summarization the working memory may already contain a summary USER + * message from a prior compaction round. We filter these out before offloading to the + * backend so the original messages (already stored there) are not duplicated. + * Mirrors DeepAgents' {@code _filter_summary_messages}. + */ + static List filterSummaryMessages(List messages) { + return messages.stream() + .filter(m -> !SUMMARY_MSG_NAME.equals(m.getName())) + .collect(Collectors.toList()); + } + + // ------------------------------------------------------------------------- + // Argument truncation (pre-summarization, non-LLM) + // ------------------------------------------------------------------------- + + /** + * Truncates large {@code ToolUseBlock} argument values in old messages. + * + *

This is a lightweight, non-LLM pass that fires at a separate (lower) threshold + * than full summarization. Only messages before the keep window are modified; recent + * messages are left intact. Mirrors DeepAgents' {@code _truncate_args}. + * + *

When {@code truncateConfig} is {@code null}, the original list is returned unchanged. + */ + List truncateArgs(List messages, TruncateArgsConfig truncateConfig) { + if (truncateConfig == null || messages == null || messages.isEmpty()) { + return messages; + } + + int totalTokens = TokenCounterUtil.calculateToken(messages); + if (!shouldTruncateArgs(messages, totalTokens, truncateConfig)) { + return messages; + } + + int cutoff = determineTruncateCutoff(messages, truncateConfig); + if (cutoff >= messages.size()) { + return messages; // Nothing in the truncation window + } + + boolean anyModified = false; + List result = new ArrayList<>(messages.size()); + for (int i = 0; i < messages.size(); i++) { + Msg msg = messages.get(i); + if (i < cutoff && msg.getRole() == MsgRole.ASSISTANT) { + Msg truncated = truncateToolUseArgs(msg, truncateConfig); + result.add(truncated); + if (truncated != msg) { + anyModified = true; + } + } else { + result.add(msg); + } + } + + if (anyModified) { + log.debug("Arg truncation applied to messages before index {}", cutoff); + } + return anyModified ? result : messages; + } + + private static boolean shouldTruncateArgs( + List messages, int totalTokens, TruncateArgsConfig cfg) { + if (cfg.getTriggerMessages() > 0 && messages.size() >= cfg.getTriggerMessages()) { + return true; + } + return cfg.getTriggerTokens() > 0 && totalTokens >= cfg.getTriggerTokens(); + } + + private static int determineTruncateCutoff(List messages, TruncateArgsConfig cfg) { + if (cfg.getKeepTokens() > 0) { + // Token-budget-based keep window: scan from the end + int tokensKept = 0; + for (int i = messages.size() - 1; i >= 0; i--) { + int msgTokens = TokenCounterUtil.calculateToken(List.of(messages.get(i))); + if (tokensKept + msgTokens > cfg.getKeepTokens()) { + return i + 1; + } + tokensKept += msgTokens; + } + return 0; + } + // Message-count keep window + int keep = cfg.getKeepMessages(); + return Math.max(0, messages.size() - keep); + } + + /** + * Returns a copy of the message with large {@code ToolUseBlock} argument values shortened. + * If no argument exceeds the limit, the original message reference is returned unchanged. + */ + private static Msg truncateToolUseArgs(Msg msg, TruncateArgsConfig cfg) { + List blocks = msg.getContent(); + if (blocks == null || blocks.isEmpty()) { + return msg; + } + + boolean anyModified = false; + List newBlocks = new ArrayList<>(blocks.size()); + for (ContentBlock block : blocks) { + if (block instanceof ToolUseBlock tu) { + ToolUseBlock truncated = truncateToolUseBlock(tu, cfg); + newBlocks.add(truncated); + if (truncated != tu) { + anyModified = true; + } + } else { + newBlocks.add(block); + } + } + + if (!anyModified) { + return msg; + } + return Msg.builder().role(msg.getRole()).name(msg.getName()).content(newBlocks).build(); + } + + /** + * Returns a copy of the {@code ToolUseBlock} with large string arg values truncated, + * or the original if no truncation was needed. + */ + private static ToolUseBlock truncateToolUseBlock(ToolUseBlock tu, TruncateArgsConfig cfg) { + Map input = tu.getInput(); + if (input == null || input.isEmpty()) { + return tu; + } + + boolean anyModified = false; + Map newInput = new HashMap<>(input); + for (Map.Entry entry : input.entrySet()) { + if (entry.getValue() instanceof String s && s.length() > cfg.getMaxArgLength()) { + newInput.put(entry.getKey(), s.substring(0, 20) + cfg.getTruncationText()); + anyModified = true; + } + } + + if (!anyModified) { + return tu; + } + return ToolUseBlock.builder().id(tu.getId()).name(tu.getName()).input(newInput).build(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/TokenCounterUtil.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/TokenCounterUtil.java new file mode 100644 index 000000000..f927d03b5 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/TokenCounterUtil.java @@ -0,0 +1,256 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.compaction; + +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import java.util.List; +import java.util.Map; + +/** + * Utility class for estimating token count in messages. + * + *

This class provides methods to estimate the number of input tokens that would be + * consumed when sending messages to an LLM. The estimation uses a character-based + * approximation that works reasonably well for both English and Chinese text. + * + *

Token estimation strategy: + *

    + *
  • Text content: ~1 token per 2-4 characters (varies by language) + *
  • Tool calls: Includes tool name, parameters, and structure overhead + *
  • Tool results: Includes output content and structure overhead + *
  • Message structure: Role, name, and formatting overhead + *
+ */ +public class TokenCounterUtil { + + // Token estimation ratios + // For English: ~1 token per 4 characters + // For Chinese: ~1 token per 1-2 characters + // Using a conservative ratio that works for mixed content + private static final double CHARS_PER_TOKEN = 2.5; + + // Overhead tokens for message structure (role, name, formatting) + private static final int MESSAGE_OVERHEAD = 5; + + // Overhead tokens for tool call structure + private static final int TOOL_CALL_OVERHEAD = 10; + + // Overhead tokens for tool result structure + private static final int TOOL_RESULT_OVERHEAD = 8; + + /** + * Calculates the estimated total input tokens for a list of messages. + * + *

This method estimates tokens by: + *

    + *
  • Extracting all text content from messages + *
  • Counting characters in tool calls and results + *
  • Adding structure overhead for each message and content block + *
+ * + * @param messages the list of messages to estimate tokens for + * @return estimated number of input tokens + */ + public static int calculateToken(List messages) { + if (messages == null || messages.isEmpty()) { + return 0; + } + + int totalTokens = 0; + + for (Msg msg : messages) { + totalTokens += estimateMessageTokens(msg); + } + + return totalTokens; + } + + /** + * Estimates tokens for a single message. + * + * @param msg the message to estimate + * @return estimated number of tokens for this message + */ + private static int estimateMessageTokens(Msg msg) { + if (msg == null) { + return 0; + } + + int tokens = MESSAGE_OVERHEAD; + + // Add overhead for role and name + if (msg.getRole() != null) { + tokens += estimateTextTokens(msg.getRole().name()); + } + if (msg.getName() != null) { + tokens += estimateTextTokens(msg.getName()); + } + + // Estimate tokens for content blocks + List content = msg.getContent(); + if (content != null) { + for (ContentBlock block : content) { + tokens += estimateContentBlockTokens(block); + } + } + + return tokens; + } + + /** + * Estimates tokens for a content block. + * + * @param block the content block to estimate + * @return estimated number of tokens for this block + */ + private static int estimateContentBlockTokens(ContentBlock block) { + if (block == null) { + return 0; + } + + if (block instanceof TextBlock textBlock) { + return estimateTextTokens(textBlock.getText()); + } else if (block instanceof ToolUseBlock toolUseBlock) { + return estimateToolUseBlockTokens(toolUseBlock); + } else if (block instanceof ToolResultBlock toolResultBlock) { + return estimateToolResultBlockTokens(toolResultBlock); + } + + // For other block types (ImageBlock, AudioBlock, etc.), estimate minimal overhead + return 5; + } + + /** + * Estimates tokens for a ToolUseBlock. + * + * @param toolUseBlock the tool use block to estimate + * @return estimated number of tokens + */ + private static int estimateToolUseBlockTokens(ToolUseBlock toolUseBlock) { + int tokens = TOOL_CALL_OVERHEAD; + + // Tool name + if (toolUseBlock.getName() != null) { + tokens += estimateTextTokens(toolUseBlock.getName()); + } + + // Tool ID + if (toolUseBlock.getId() != null) { + tokens += estimateTextTokens(toolUseBlock.getId()); + } + + // Tool input parameters + Map input = toolUseBlock.getInput(); + if (input != null && !input.isEmpty()) { + // Estimate tokens for JSON representation of parameters + String inputJson = estimateMapAsJson(input); + tokens += estimateTextTokens(inputJson); + } + + // Raw content (if present) + if (toolUseBlock.getContent() != null) { + tokens += estimateTextTokens(toolUseBlock.getContent()); + } + + return tokens; + } + + /** + * Estimates tokens for a ToolResultBlock. + * + * @param toolResultBlock the tool result block to estimate + * @return estimated number of tokens + */ + private static int estimateToolResultBlockTokens(ToolResultBlock toolResultBlock) { + int tokens = TOOL_RESULT_OVERHEAD; + + // Tool name + if (toolResultBlock.getName() != null) { + tokens += estimateTextTokens(toolResultBlock.getName()); + } + + // Tool ID + if (toolResultBlock.getId() != null) { + tokens += estimateTextTokens(toolResultBlock.getId()); + } + + // Output content blocks + List output = toolResultBlock.getOutput(); + if (output != null) { + for (ContentBlock outputBlock : output) { + tokens += estimateContentBlockTokens(outputBlock); + } + } + + return tokens; + } + + /** + * Estimates tokens for text content. + * + *

Uses a character-based approximation that works reasonably well + * for both English and Chinese text. + * + * @param text the text to estimate + * @return estimated number of tokens + */ + private static int estimateTextTokens(String text) { + if (text == null || text.isEmpty()) { + return 0; + } + + // Count characters and apply ratio + int charCount = text.length(); + return (int) Math.ceil(charCount / CHARS_PER_TOKEN); + } + + /** + * Estimates the JSON string representation of a map for token counting. + * + *

This is a simplified estimation that counts keys and string values. + * + * @param map the map to estimate + * @return estimated JSON string length + */ + private static String estimateMapAsJson(Map map) { + if (map == null || map.isEmpty()) { + return "{}"; + } + + StringBuilder sb = new StringBuilder(); + sb.append("{"); + boolean first = true; + for (Map.Entry entry : map.entrySet()) { + if (!first) { + sb.append(","); + } + first = false; + sb.append("\"").append(entry.getKey()).append("\":"); + Object value = entry.getValue(); + if (value instanceof String) { + sb.append("\"").append(value).append("\""); + } else { + sb.append(value != null ? value.toString() : "null"); + } + } + sb.append("}"); + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java new file mode 100644 index 000000000..3f86325d3 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java @@ -0,0 +1,156 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.compaction; + +import java.util.Set; + +/** + * Configuration for per-tool-result eviction of oversized outputs. + * + *

When a tool produces a result whose text content exceeds {@link #getMaxResultChars()}, the + * full output is written to the {@link AbstractFilesystem} at a deterministic path under + * {@link #getEvictionPath()}, and the in-context {@link io.agentscope.core.message.ToolResultBlock} + * is replaced with a compact placeholder that includes a head+tail preview and an instruction to + * use {@code readFile} for the full content. + * + *

This mechanism is orthogonal to conversation summarization ({@link CompactionConfig}): + *

    + *
  • Eviction addresses context width — individual messages that are too large.
  • + *
  • Compaction addresses context depth — too many accumulated messages.
  • + *
+ * Both operate independently on different trigger conditions and different lifecycle events. + * + *

Defaults mirror DeepAgents' {@code FilesystemMiddleware}: + *

    + *
  • Trigger at 80,000 characters (~20 K tokens at 4 chars/token)
  • + *
  • Preview: first + last 2,000 characters of the original output
  • + *
  • Eviction path prefix: {@code /large_tool_results}
  • + *
  • Excluded tools: filesystem read/write/edit/list + memory tools (small or self-paginating)
  • + *
+ */ +public class ToolResultEvictionConfig { + + /** ~20 K tokens × 4 chars/token — default eviction threshold. */ + public static final int DEFAULT_MAX_RESULT_CHARS = 80_000; + + /** Characters to show at head and tail in the eviction placeholder preview. */ + public static final int DEFAULT_PREVIEW_CHARS = 2_000; + + /** Root path prefix under which evicted results are stored. */ + public static final String DEFAULT_EVICTION_PATH = "/large_tool_results"; + + /** + * Tools excluded from eviction by default. + * + *
    + *
  • {@code read_file} — evicting would cause re-read loops; pagination handles size
  • + *
  • {@code write_file}, {@code edit_file} — return tiny success messages
  • + *
  • {@code grep_files}, {@code glob_files}, {@code list_files} — self-limiting outputs
  • + *
  • {@code memory_search}, {@code memory_get}, {@code session_search} — small/paginated results
  • + *
+ * + * Shell ({@code execute}) is intentionally NOT excluded: command output can be very large. + */ + public static final Set DEFAULT_EXCLUDED_TOOLS = + Set.of( + "read_file", + "write_file", + "edit_file", + "grep_files", + "glob_files", + "list_files", + "memory_search", + "memory_get", + "session_search"); + + private final int maxResultChars; + private final int previewChars; + private final String evictionPath; + private final Set excludedToolNames; + + private ToolResultEvictionConfig(Builder builder) { + this.maxResultChars = builder.maxResultChars; + this.previewChars = builder.previewChars; + this.evictionPath = builder.evictionPath; + this.excludedToolNames = builder.excludedToolNames; + } + + /** Creates a config with all defaults applied. */ + public static ToolResultEvictionConfig defaults() { + return new Builder().build(); + } + + /** Maximum text length (chars) before eviction fires. */ + public int getMaxResultChars() { + return maxResultChars; + } + + /** Characters to show in the head and tail preview. */ + public int getPreviewChars() { + return previewChars; + } + + /** Root path under which evicted files are written (e.g. {@code /large_tool_results}). */ + public String getEvictionPath() { + return evictionPath; + } + + /** Tool names that will never be evicted regardless of result size. */ + public Set getExcludedToolNames() { + return excludedToolNames; + } + + public static Builder builder() { + return new Builder(); + } + + /** Builder for {@link ToolResultEvictionConfig}. */ + public static class Builder { + + private int maxResultChars = DEFAULT_MAX_RESULT_CHARS; + private int previewChars = DEFAULT_PREVIEW_CHARS; + private String evictionPath = DEFAULT_EVICTION_PATH; + private Set excludedToolNames = DEFAULT_EXCLUDED_TOOLS; + + /** Sets the character threshold above which eviction is triggered. */ + public Builder maxResultChars(int maxResultChars) { + this.maxResultChars = maxResultChars; + return this; + } + + /** Sets how many characters to include in the head/tail preview. */ + public Builder previewChars(int previewChars) { + this.previewChars = previewChars; + return this; + } + + /** Sets the root filesystem path prefix for evicted files. */ + public Builder evictionPath(String evictionPath) { + this.evictionPath = evictionPath; + return this; + } + + /** Replaces the default set of excluded tool names. */ + public Builder excludedToolNames(Set excludedToolNames) { + this.excludedToolNames = Set.copyOf(excludedToolNames); + return this; + } + + public ToolResultEvictionConfig build() { + return new ToolResultEvictionConfig(this); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionEntry.java new file mode 100644 index 000000000..ce0087909 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionEntry.java @@ -0,0 +1,174 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.session; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import java.time.Instant; +import java.util.UUID; + +/** + * Base class for all session tree entries (pi-mono-inspired JSONL session model). + * + *

Each entry has a unique {@code id} and a {@code parentId} forming a tree structure. + * Entries are appended to the session JSONL file in order; they are never deleted. + * + *

Entry types: + *

    + *
  • {@link MessageEntry} — wraps a single LLM message (user/assistant/tool/system)
  • + *
  • {@link CompactionEntry} — marks a compaction event (non-destructive)
  • + *
  • {@link SummaryEntry} — holds a compaction summary
  • + *
+ */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = SessionEntry.MessageEntry.class, name = "message"), + @JsonSubTypes.Type(value = SessionEntry.CompactionEntry.class, name = "compaction"), + @JsonSubTypes.Type(value = SessionEntry.SummaryEntry.class, name = "summary") +}) +@JsonInclude(JsonInclude.Include.NON_NULL) +public abstract sealed class SessionEntry + permits SessionEntry.MessageEntry, SessionEntry.CompactionEntry, SessionEntry.SummaryEntry { + + private final String id; + private final String parentId; + private final Instant timestamp; + + protected SessionEntry(String id, String parentId, Instant timestamp) { + this.id = id != null ? id : UUID.randomUUID().toString(); + this.parentId = parentId; + this.timestamp = timestamp != null ? timestamp : Instant.now(); + } + + public String getId() { + return id; + } + + public String getParentId() { + return parentId; + } + + public Instant getTimestamp() { + return timestamp; + } + + /** + * A message entry wrapping a single message in the conversation. + */ + public static final class MessageEntry extends SessionEntry { + + private final String role; + private final String content; + private final String toolCallId; + + @JsonCreator + public MessageEntry( + @JsonProperty("id") String id, + @JsonProperty("parentId") String parentId, + @JsonProperty("timestamp") Instant timestamp, + @JsonProperty("role") String role, + @JsonProperty("content") String content, + @JsonProperty("toolCallId") String toolCallId) { + super(id, parentId, timestamp); + this.role = role; + this.content = content; + this.toolCallId = toolCallId; + } + + public MessageEntry(String parentId, String role, String content) { + this(null, parentId, null, role, content, null); + } + + public String getRole() { + return role; + } + + public String getContent() { + return content; + } + + public String getToolCallId() { + return toolCallId; + } + } + + /** + * Non-destructive compaction marker. Records which entry is the first kept entry — + * all entries before {@code firstKeptEntryId} are considered compacted (not visible + * to the LLM) but remain in the file for full history replay. + */ + public static final class CompactionEntry extends SessionEntry { + + private final String firstKeptEntryId; + private final String summaryEntryId; + + @JsonCreator + public CompactionEntry( + @JsonProperty("id") String id, + @JsonProperty("parentId") String parentId, + @JsonProperty("timestamp") Instant timestamp, + @JsonProperty("firstKeptEntryId") String firstKeptEntryId, + @JsonProperty("summaryEntryId") String summaryEntryId) { + super(id, parentId, timestamp); + this.firstKeptEntryId = firstKeptEntryId; + this.summaryEntryId = summaryEntryId; + } + + public String getFirstKeptEntryId() { + return firstKeptEntryId; + } + + public String getSummaryEntryId() { + return summaryEntryId; + } + } + + /** + * Holds the text of a compaction summary (the condensed version of compacted messages). + */ + public static final class SummaryEntry extends SessionEntry { + + private final String summary; + private final String format; + + @JsonCreator + public SummaryEntry( + @JsonProperty("id") String id, + @JsonProperty("parentId") String parentId, + @JsonProperty("timestamp") Instant timestamp, + @JsonProperty("summary") String summary, + @JsonProperty("format") String format) { + super(id, parentId, timestamp); + this.summary = summary; + this.format = format != null ? format : "structured"; + } + + public SummaryEntry(String parentId, String summary) { + this(null, parentId, null, summary, "structured"); + } + + public String getSummary() { + return summary; + } + + public String getFormat() { + return format; + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionFreshnessEvaluator.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionFreshnessEvaluator.java new file mode 100644 index 000000000..811cc6061 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionFreshnessEvaluator.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.session; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +/** + * Evaluates whether a session is still "fresh" or should be reset. + * + *

Inspired by agentscope-claw's SessionFreshnessEvaluator. Supports two reset policies: + *

    + *
  • Daily reset: Session resets after a configured hour each day
  • + *
  • Idle timeout: Session resets after inactivity exceeding a threshold
  • + *
+ */ +public class SessionFreshnessEvaluator { + + private final int dailyResetHour; + private final Duration idleTimeout; + private final ZoneId timezone; + + /** + * Creates a freshness evaluator with default settings: + * daily reset at 4 AM, idle timeout of 2 hours, system timezone. + */ + public SessionFreshnessEvaluator() { + this(4, Duration.ofHours(2), ZoneId.systemDefault()); + } + + public SessionFreshnessEvaluator(int dailyResetHour, Duration idleTimeout, ZoneId timezone) { + this.dailyResetHour = dailyResetHour; + this.idleTimeout = idleTimeout; + this.timezone = timezone; + } + + /** + * Determines if the session should be considered stale and reset. + * + * @param lastActivityAt the timestamp of the last activity in the session + * @return true if the session should be reset + */ + public boolean isStale(Instant lastActivityAt) { + if (lastActivityAt == null) { + return true; + } + + Instant now = Instant.now(); + + if (idleTimeout != null + && Duration.between(lastActivityAt, now).compareTo(idleTimeout) > 0) { + return true; + } + + if (dailyResetHour >= 0) { + ZonedDateTime lastActivity = lastActivityAt.atZone(timezone); + ZonedDateTime nowZoned = now.atZone(timezone); + + LocalTime resetTime = LocalTime.of(dailyResetHour, 0); + ZonedDateTime todayReset = nowZoned.toLocalDate().atTime(resetTime).atZone(timezone); + + if (nowZoned.isAfter(todayReset) && lastActivity.isBefore(todayReset)) { + return true; + } + } + + return false; + } + + public int getDailyResetHour() { + return dailyResetHour; + } + + public Duration getIdleTimeout() { + return idleTimeout; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java new file mode 100644 index 000000000..b753e8ea8 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java @@ -0,0 +1,298 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.session; + +import io.agentscope.core.util.JsonUtils; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Manages an append-only JSONL session tree (pi-mono-inspired). + * + *

The session file is a JSONL file where each line is a JSON-serialized {@link SessionEntry}. + * Entries form a tree via {@code id}/{@code parentId} links. A companion {@code .log.jsonl} file + * stores the full history for grep-ability (dual-file pattern from pi-mono mom). + * + *

File layout

+ *
+ *   agents/{agentId}/sessions/{sessionId}.jsonl      — LLM context (compacted)
+ *   agents/{agentId}/sessions/{sessionId}.log.jsonl   — full history (append-only, never compacted)
+ * 
+ * + *

Deferred persistence

+ * Entries are buffered in memory and only flushed to disk on the first call to {@link #flush()} + * (typically after the first assistant message). This avoids partial session files from + * failed/short interactions. + */ +public class SessionTree { + + private static final Logger log = LoggerFactory.getLogger(SessionTree.class); + private static final int SESSION_FORMAT_VERSION = 1; + + private final Path contextFile; + private final Path logFile; + + private final Map entriesById = new LinkedHashMap<>(); + private final List appendOrder = new ArrayList<>(); + private final List pendingWrites = new ArrayList<>(); + + private String lastCompactionFirstKeptId; + private String lastSummaryEntryId; + private boolean loaded = false; + private boolean flushed = false; + + public SessionTree(Path contextFile) { + this.contextFile = contextFile; + String name = contextFile.getFileName().toString(); + String baseName = name.endsWith(".jsonl") ? name.substring(0, name.length() - 6) : name; + this.logFile = contextFile.resolveSibling(baseName + ".log.jsonl"); + } + + /** + * Loads existing entries from the context JSONL file (if it exists). + * Safe to call multiple times; only loads once. + */ + public void load() { + if (loaded) { + return; + } + loaded = true; + + if (!Files.isRegularFile(contextFile)) { + return; + } + + try (BufferedReader reader = Files.newBufferedReader(contextFile, StandardCharsets.UTF_8)) { + String line; + while ((line = reader.readLine()) != null) { + line = line.strip(); + if (line.isEmpty()) { + continue; + } + try { + SessionEntry entry = + JsonUtils.getJsonCodec().fromJson(line, SessionEntry.class); + entriesById.put(entry.getId(), entry); + appendOrder.add(entry); + + if (entry instanceof SessionEntry.CompactionEntry ce) { + lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); + lastSummaryEntryId = ce.getSummaryEntryId(); + } + } catch (Exception e) { + log.warn("Skipping malformed session entry: {}", e.getMessage()); + } + } + } catch (IOException e) { + log.warn("Failed to load session file {}: {}", contextFile, e.getMessage()); + } + } + + /** + * Appends an entry to the in-memory tree. The entry will be written to disk + * on the next {@link #flush()} call. + * + * @return the entry (for chaining) + */ + public SessionEntry append(SessionEntry entry) { + entriesById.put(entry.getId(), entry); + appendOrder.add(entry); + pendingWrites.add(entry); + + if (entry instanceof SessionEntry.CompactionEntry ce) { + lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); + lastSummaryEntryId = ce.getSummaryEntryId(); + } + + return entry; + } + + /** + * Flushes all pending entries to both the context file and the log file. + * Creates parent directories as needed. Marks the session as flushed. + */ + public void flush() { + if (pendingWrites.isEmpty()) { + return; + } + + flushed = true; + List toWrite = new ArrayList<>(pendingWrites); + pendingWrites.clear(); + + appendToFile(contextFile, toWrite); + appendToFile(logFile, toWrite); + } + + /** + * Returns whether {@link #flush()} has been called at least once. + */ + public boolean isFlushed() { + return flushed; + } + + /** + * Builds the LLM-visible context from the session tree. + * + *

Returns entries that the LLM should see: + *

    + *
  • If compaction has occurred, starts with the summary entry, then all entries + * from {@code firstKeptEntryId} onward
  • + *
  • If no compaction, returns all message entries in order
  • + *
+ */ + public List buildContext() { + if (appendOrder.isEmpty()) { + return Collections.emptyList(); + } + + if (lastCompactionFirstKeptId == null) { + return new ArrayList<>(appendOrder); + } + + List context = new ArrayList<>(); + + if (lastSummaryEntryId != null) { + SessionEntry summary = entriesById.get(lastSummaryEntryId); + if (summary != null) { + context.add(summary); + } + } + + boolean found = false; + for (SessionEntry entry : appendOrder) { + if (entry.getId().equals(lastCompactionFirstKeptId)) { + found = true; + } + if (found && entry instanceof SessionEntry.MessageEntry) { + context.add(entry); + } + } + + return context; + } + + /** + * Returns all entries in append order (full history). + */ + public List getAllEntries() { + return Collections.unmodifiableList(appendOrder); + } + + /** + * Returns only message entries in append order. + */ + public List getMessageEntries() { + return appendOrder.stream() + .filter(e -> e instanceof SessionEntry.MessageEntry) + .map(e -> (SessionEntry.MessageEntry) e) + .toList(); + } + + public int size() { + return appendOrder.size(); + } + + public Path getContextFile() { + return contextFile; + } + + public Path getLogFile() { + return logFile; + } + + /** + * Syncs entries from the log file that are not yet in the context file. + * This handles offline messages that were appended to the log while the + * agent was inactive. + * + * @return the number of new entries synced + */ + public int syncFromLog() { + if (!Files.isRegularFile(logFile)) { + return 0; + } + + int syncCount = 0; + try (BufferedReader reader = Files.newBufferedReader(logFile, StandardCharsets.UTF_8)) { + String line; + while ((line = reader.readLine()) != null) { + line = line.strip(); + if (line.isEmpty()) { + continue; + } + try { + SessionEntry entry = + JsonUtils.getJsonCodec().fromJson(line, SessionEntry.class); + if (!entriesById.containsKey(entry.getId())) { + entriesById.put(entry.getId(), entry); + appendOrder.add(entry); + pendingWrites.add(entry); + syncCount++; + + if (entry instanceof SessionEntry.CompactionEntry ce) { + lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); + lastSummaryEntryId = ce.getSummaryEntryId(); + } + } + } catch (Exception e) { + log.debug("Skipping malformed log entry during sync: {}", e.getMessage()); + } + } + } catch (IOException e) { + log.warn("Failed to sync from log file {}: {}", logFile, e.getMessage()); + } + + if (syncCount > 0) { + log.info("Synced {} offline entries from log to context", syncCount); + } + return syncCount; + } + + private void appendToFile(Path file, List entries) { + try { + if (file.getParent() != null) { + Files.createDirectories(file.getParent()); + } + try (BufferedWriter writer = + Files.newBufferedWriter( + file, + StandardCharsets.UTF_8, + StandardOpenOption.CREATE, + StandardOpenOption.APPEND)) { + for (SessionEntry entry : entries) { + String json = JsonUtils.getJsonCodec().toJson(entry); + writer.write(json); + writer.newLine(); + } + } + } catch (IOException e) { + log.warn("Failed to append to session file {}: {}", file, e.getMessage()); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java new file mode 100644 index 000000000..7da513ae1 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.session; + +import io.agentscope.core.session.JsonSession; +import java.nio.file.Path; + +/** + * Workspace-aware session that stores state under the agent's workspace directory. + * + *

Storage layout: + * + *

+ * <workspace>/agents/<agentId>/context/<sessionId>/{key}.json
+ * <workspace>/agents/<agentId>/context/<sessionId>/{key}.jsonl
+ * 
+ * + *

This extends {@link JsonSession} by computing the base directory as + * {@code /agents//context/}. The {@code sessionId} (carried by + * {@link io.agentscope.core.state.SessionKey#toIdentifier()}) is appended automatically + * by the parent class as a subdirectory, producing the full path above. + * + *

Usage: + * + *

{@code
+ * WorkspaceSession session = new WorkspaceSession(workspacePath, "my-agent");
+ * agent.saveTo(session, SimpleSessionKey.of("sess-001"));
+ * // Files written to: /agents/my-agent/context/sess-001/
+ * }
+ */ +public class WorkspaceSession extends JsonSession { + + /** + * Creates a workspace session for the given agent. + * + * @param workspace the workspace root directory (e.g. {@code .agentscope/workspace}) + * @param agentId the agent identifier used in the directory path + */ + public WorkspaceSession(Path workspace, String agentId) { + super(workspace.resolve("agents").resolve(agentId).resolve("context")); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/AgentSpecLoader.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/AgentSpecLoader.java new file mode 100644 index 000000000..608bfc094 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/AgentSpecLoader.java @@ -0,0 +1,170 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Loads {@link SubagentSpec} definitions from Markdown files with YAML front matter. Compatible + * with Spring AI agent spec format. + * + *

File format: + * + *

+ * ---
+ * name: Explore
+ * description: Fast agent for exploring codebases...
+ * tools: Read, Grep, Glob
+ * ---
+ *
+ * # System prompt (markdown body)
+ * You are a file search specialist...
+ * 
+ * + *

Front matter fields: + * + *

    + *
  • {@code name} (required) — maps to {@link SubagentSpec#getName()} + *
  • {@code description} (required) + *
  • {@code tools} (optional, comma-separated) — maps to {@link SubagentSpec#getTools()} + *
  • {@code model} (optional) — override model name, maps to {@link SubagentSpec#getModel()} + *
  • {@code maxIters} (optional, default 10) + *
+ * + *

The Markdown body becomes the system prompt. + */ +public final class AgentSpecLoader { + + private static final Logger log = LoggerFactory.getLogger(AgentSpecLoader.class); + private static final ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory()); + + private AgentSpecLoader() {} + + /** Recursively scans a directory for {@code .md} files and parses each into a SubagentSpec. */ + public static List loadFromDirectory(Path rootPath) { + if (rootPath == null || !Files.isDirectory(rootPath)) { + return Collections.emptyList(); + } + List specs = new ArrayList<>(); + try (Stream paths = Files.walk(rootPath)) { + paths.filter(Files::isRegularFile) + .filter(p -> p.getFileName().toString().endsWith(".md")) + .forEach( + path -> { + try { + SubagentSpec spec = loadFromFile(path); + if (spec != null) { + specs.add(spec); + log.debug( + "Loaded agent spec '{}' from {}", + spec.getName(), + path); + } + } catch (Exception e) { + log.warn( + "Failed to load agent spec from {}: {}", + path, + e.getMessage()); + } + }); + } catch (IOException e) { + log.warn("Failed to walk directory {}: {}", rootPath, e.getMessage()); + } + return specs; + } + + public static SubagentSpec loadFromFile(Path filePath) throws IOException { + String content = Files.readString(filePath, StandardCharsets.UTF_8); + return parse(content); + } + + /** + * Parses markdown content with YAML front matter into a {@link SubagentSpec}. + * + * @return parsed spec, or null if the content is malformed + */ + @SuppressWarnings("unchecked") + public static SubagentSpec parse(String markdown) { + if (markdown == null || markdown.isBlank() || !markdown.startsWith("---")) { + return null; + } + int endIdx = markdown.indexOf("---", 3); + if (endIdx == -1) { + log.warn("Agent spec front matter not closed with ---"); + return null; + } + + String frontMatterStr = markdown.substring(3, endIdx).trim(); + String body = markdown.substring(endIdx + 3).trim(); + + Map frontMatter; + try { + frontMatter = YAML_MAPPER.readValue(frontMatterStr, Map.class); + } catch (Exception e) { + log.warn("Failed to parse YAML front matter: {}", e.getMessage()); + return null; + } + if (frontMatter == null || frontMatter.isEmpty()) { + return null; + } + + String name = asString(frontMatter.get("name")); + String description = asString(frontMatter.get("description")); + if (name == null || name.isBlank()) { + log.warn("Agent spec missing required 'name' in front matter"); + return null; + } + if (description == null || description.isBlank()) { + log.warn("Agent spec missing required 'description' in front matter"); + return null; + } + + SubagentSpec spec = new SubagentSpec(name, description); + spec.setSysPrompt(body.isEmpty() ? null : body); + spec.setTools(parseToolNames(asString(frontMatter.get("tools")))); + spec.setModel(asString(frontMatter.get("model"))); + + Object maxItersObj = frontMatter.get("maxIters"); + if (maxItersObj instanceof Number n) { + spec.setMaxIters(n.intValue()); + } + + return spec; + } + + private static String asString(Object v) { + return v != null ? v.toString().trim() : null; + } + + private static List parseToolNames(String toolsStr) { + if (toolsStr == null || toolsStr.isBlank()) { + return List.of(); + } + return Stream.of(toolsStr.split(",")).map(String::trim).filter(s -> !s.isEmpty()).toList(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java new file mode 100644 index 000000000..74e77f0d6 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java @@ -0,0 +1,91 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent; + +import io.agentscope.core.agent.Agent; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.tool.AgentSpawnTool; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.util.List; +import java.util.Map; +import reactor.core.publisher.Mono; + +/** + * Pure agent factory and invoker — knows how to create agents from registered factories and invoke + * them with a prompt. + * + *

This is the agent-internal layer. It has no session registry, no lane + * management, no run tracking. The + * agent-internal {@link AgentSpawnTool} uses this directly for + * lightweight subagent invocation. + */ +public final class DefaultAgentManager { + + private final Map agentFactories; + private final WorkspaceManager workspaceManager; + + public DefaultAgentManager( + Map agentFactories, WorkspaceManager workspaceManager) { + this.agentFactories = Map.copyOf(agentFactories); + this.workspaceManager = workspaceManager; + } + + /** Whether a factory is registered for the given agent id. */ + public boolean hasAgent(String agentId) { + return agentId != null && agentFactories.containsKey(agentId); + } + + /** Immutable view of registered subagent factories keyed by {@code agent_id}. */ + public Map getAgentFactories() { + return agentFactories; + } + + /** + * Creates a new agent instance from the registered factory. + * + * @throws IllegalArgumentException if no factory is registered for the given id + */ + public Agent createAgent(String agentId) { + SubagentFactory factory = agentFactories.get(agentId); + if (factory == null) { + throw new IllegalArgumentException("Unknown agent_id: " + agentId); + } + return factory.create(); + } + + /** + * Invokes an agent with a user prompt. Handles both plain {@link Agent} and {@link + * HarnessAgent} (injects {@link RuntimeContext} for the latter). + */ + public Mono invokeAgent(Agent agent, String sessionId, String prompt) { + if (agent instanceof HarnessAgent harness) { + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); + return harness.call(userMessage(prompt), ctx); + } + return agent.call(List.of(userMessage(prompt))); + } + + public WorkspaceManager getWorkspaceManager() { + return workspaceManager; + } + + private static Msg userMessage(String prompt) { + return Msg.builder().role(MsgRole.USER).textContent(prompt).build(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentFactory.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentFactory.java new file mode 100644 index 000000000..9cf6f294e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent; + +import io.agentscope.core.agent.Agent; + +/** + * Creates a new subagent instance for a single spawn or session. Registered under an {@code + * agent_id} in {@link DefaultAgentManager}; each {@link #create()} call should return a fresh + * agent when isolation is required. + * + *

This type replaces a raw {@link java.util.function.Supplier} for subagent wiring so call sites + * and maps are self-documenting. + */ +@FunctionalInterface +public interface SubagentFactory { + + /** Builds a new subagent instance (typically a new {@link io.agentscope.harness.agent.HarnessAgent}). */ + Agent create(); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentSpec.java new file mode 100644 index 000000000..aa1966b93 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/SubagentSpec.java @@ -0,0 +1,124 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +/** + * Specification for a sub-agent loaded from configuration (subagent.yml). + * + *

Example YAML: + * + *

+ * subagents:
+ *   - name: content-reviewer
+ *     description: Use this agent after creating significant content
+ *     sysPrompt: You are an expert content reviewer...
+ *     tools: []
+ *   - name: research-analyst
+ *     description: Use this agent for deep research tasks
+ *     sysPrompt: You are a research analyst...
+ * 
+ */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class SubagentSpec { + + @JsonProperty("name") + private String name; + + @JsonProperty("description") + private String description; + + @JsonProperty("sysPrompt") + private String sysPrompt; + + @JsonProperty("tools") + private List tools; + + @JsonProperty("workspace") + private String workspace; + + @JsonProperty("model") + private String model; + + @JsonProperty("maxIters") + private int maxIters = 10; + + public SubagentSpec() {} + + public SubagentSpec(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSysPrompt() { + return sysPrompt; + } + + public void setSysPrompt(String sysPrompt) { + this.sysPrompt = sysPrompt; + } + + public List getTools() { + return tools; + } + + public void setTools(List tools) { + this.tools = tools; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getWorkspace() { + return workspace; + } + + public void setWorkspace(String workspace) { + this.workspace = workspace; + } + + public int getMaxIters() { + return maxIters; + } + + public void setMaxIters(int maxIters) { + this.maxIters = maxIters; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/BackgroundTask.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/BackgroundTask.java new file mode 100644 index 000000000..fff311288 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/BackgroundTask.java @@ -0,0 +1,152 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent.task; + +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Wraps a {@link CompletableFuture} to track background subagent task execution with status, + * result, error, and lifecycle metadata. Thread-safe by delegation to the underlying future. + * + *

Lifecycle metadata: + * + *

    + *
  • {@code agentId} — which subagent type is executing + *
  • {@code createdAt} — when the task was created + *
  • {@code lastCheckedAt} — when the task status was last polled + *
+ */ +public class BackgroundTask { + + private final String taskId; + private final String agentId; + private final CompletableFuture future; + private final Instant createdAt; + private volatile Instant lastCheckedAt; + private volatile boolean cancelled; + + public BackgroundTask(String taskId, String agentId, CompletableFuture future) { + this.taskId = taskId; + this.agentId = agentId; + this.future = future; + this.createdAt = Instant.now(); + this.lastCheckedAt = this.createdAt; + } + + public String getTaskId() { + return taskId; + } + + public String getAgentId() { + return agentId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public Instant getLastCheckedAt() { + return lastCheckedAt; + } + + public void updateLastCheckedAt() { + this.lastCheckedAt = Instant.now(); + } + + public boolean isCompleted() { + return future.isDone(); + } + + /** + * Returns the structured {@link TaskStatus} for this task, reflecting the underlying future + * state and any explicit cancellation. + */ + public TaskStatus getTaskStatus() { + if (cancelled || future.isCancelled()) { + return TaskStatus.CANCELLED; + } + if (future.isCompletedExceptionally()) { + return TaskStatus.FAILED; + } + if (future.isDone()) { + return TaskStatus.COMPLETED; + } + return TaskStatus.RUNNING; + } + + /** Returns a human-readable status string. */ + public String getStatus() { + TaskStatus ts = getTaskStatus(); + if (ts == TaskStatus.FAILED) { + Exception error = getError(); + return "Failed: " + (error != null ? error.getMessage() : "Unknown error"); + } + return ts.name().charAt(0) + ts.name().substring(1).toLowerCase(); + } + + /** Non-blocking result peek; returns null if not yet completed or if an error occurred. */ + public String getResult() { + try { + return future.getNow(null); + } catch (Exception e) { + return null; + } + } + + public Exception getError() { + if (future.isCompletedExceptionally()) { + try { + future.getNow(null); + } catch (Exception e) { + return (e.getCause() instanceof Exception cause) ? cause : e; + } + } + return null; + } + + /** + * Blocks until the task completes or the timeout elapses. + * + * @return true if completed within timeout, false if timed out + */ + public boolean waitForCompletion(long timeoutMs) throws InterruptedException { + if (future.isDone()) { + return true; + } + try { + future.get(timeoutMs, TimeUnit.MILLISECONDS); + return true; + } catch (InterruptedException e) { + throw e; + } catch (TimeoutException e) { + return false; + } catch (Exception e) { + return true; + } + } + + /** + * Cancels the task. Sets the internal cancelled flag so that {@link #getTaskStatus()} returns + * {@link TaskStatus#CANCELLED} even if the future cannot be interrupted. + */ + public boolean cancel(boolean mayInterruptIfRunning) { + this.cancelled = true; + return future.cancel(mayInterruptIfRunning); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/DefaultTaskRepository.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/DefaultTaskRepository.java new file mode 100644 index 000000000..e8ac3dea0 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/DefaultTaskRepository.java @@ -0,0 +1,125 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent.task; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +/** + * Default in-memory {@link TaskRepository} backed by a cached daemon thread pool. Each submitted + * task runs asynchronously via {@link CompletableFuture#supplyAsync}. + */ +public class DefaultTaskRepository implements TaskRepository { + + private final Map tasks = new ConcurrentHashMap<>(); + private final ExecutorService executor; + private final boolean ownsExecutor; + + public DefaultTaskRepository() { + this( + Executors.newCachedThreadPool( + r -> { + Thread t = new Thread(r); + t.setDaemon(true); + t.setName("subagent-task-" + t.getId()); + return t; + }), + true); + } + + public DefaultTaskRepository(ExecutorService executor) { + this(executor, false); + } + + private DefaultTaskRepository(ExecutorService executor, boolean ownsExecutor) { + this.executor = executor; + this.ownsExecutor = ownsExecutor; + } + + @Override + public BackgroundTask getTask(String taskId) { + return tasks.get(taskId); + } + + @Override + public BackgroundTask putTask(String taskId, String agentId, Supplier taskExecution) { + CompletableFuture future = CompletableFuture.supplyAsync(taskExecution, executor); + BackgroundTask task = new BackgroundTask(taskId, agentId, future); + tasks.put(taskId, task); + return task; + } + + @Override + public void removeTask(String taskId) { + tasks.remove(taskId); + } + + @Override + public void clear() { + tasks.clear(); + } + + @Override + public Collection listTasks(TaskStatus filter) { + if (filter == null) { + return List.copyOf(tasks.values()); + } + List result = new ArrayList<>(); + for (BackgroundTask task : tasks.values()) { + if (task.getTaskStatus() == filter) { + result.add(task); + } + } + return result; + } + + @Override + public boolean cancelTask(String taskId) { + BackgroundTask task = tasks.get(taskId); + if (task == null) { + return false; + } + task.cancel(true); + return true; + } + + public void clearCompletedTasks() { + tasks.entrySet().removeIf(e -> e.getValue().isCompleted()); + } + + /** Shuts down the thread pool if this repository owns it. */ + public void shutdown() { + if (ownsExecutor && executor != null) { + executor.shutdown(); + try { + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskRepository.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskRepository.java new file mode 100644 index 000000000..0fafc1e66 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskRepository.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent.task; + +import java.util.Collection; +import java.util.function.Supplier; + +/** + * Repository for managing background subagent tasks. Supports async execution with retrieval by + * task ID, listing, and cancellation. + */ +public interface TaskRepository { + + /** Retrieve a background task by its ID, or null if not found. */ + BackgroundTask getTask(String taskId); + + /** + * Submit a new background task; the supplier runs asynchronously. + * + * @param taskId unique identifier for the task + * @param agentId the subagent type that is executing this task + * @param taskExecution the work to execute asynchronously + * @return the created background task + */ + BackgroundTask putTask(String taskId, String agentId, Supplier taskExecution); + + void removeTask(String taskId); + + void clear(); + + /** + * List all tracked tasks, optionally filtered by status. + * + * @param filter if non-null, only return tasks with this status; null returns all tasks + */ + Collection listTasks(TaskStatus filter); + + /** + * Cancel a running task by its ID. + * + * @return true if the task was found and cancellation was attempted + */ + boolean cancelTask(String taskId); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskStatus.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskStatus.java new file mode 100644 index 000000000..bcfba16f3 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/task/TaskStatus.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.subagent.task; + +/** + * Lifecycle status of a background subagent task. Terminal statuses ({@link #isTerminal()}) will + * never change, so status checks can be skipped for finished tasks. + */ +public enum TaskStatus { + PENDING, + RUNNING, + COMPLETED, + FAILED, + CANCELLED; + + /** + * Whether this status represents a final state that will never change. Useful for skipping + * redundant status polling on tasks that are already done. + */ + public boolean isTerminal() { + return this == COMPLETED || this == FAILED || this == CANCELLED; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/AgentSpawnTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/AgentSpawnTool.java new file mode 100644 index 000000000..36a4c24b4 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/AgentSpawnTool.java @@ -0,0 +1,323 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.agent.Agent; +import io.agentscope.core.message.Msg; +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.subagent.DefaultAgentManager; +import io.agentscope.harness.agent.subagent.task.TaskRepository; +import java.time.Duration; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Simple subagent tool for agent-internal use. Much lighter than {@code SessionsTool}: + * + *
    + *
  • {@code agent_spawn} — spawn a subagent, run task, return result (sync or async) + *
  • {@code agent_send} — send follow-up message to a previously spawned subagent + *
  • {@code agent_list} — list active subagents + *
+ * + *

No sessions, no lanes, no run registry, no announce dispatch. Just "create agent, invoke, + * return result". Uses {@link DefaultAgentManager} for agent creation and invocation only. + */ +public class AgentSpawnTool { + + private static final Logger log = LoggerFactory.getLogger(AgentSpawnTool.class); + + private static final int DEFAULT_TIMEOUT_SECONDS = 30; + private static final int MAX_TIMEOUT_SECONDS = 600; + private static final int MAX_SPAWN_DEPTH = 3; + + private static final String BG_RESULT_TEMPLATE = + """ + status: accepted + task_id: %s + Use task_output(task_id='%s') to retrieve the result, \ + task_cancel(task_id='%s') to cancel, or task_list() to see all tasks.\ + """; + + private final DefaultAgentManager agentManager; + private final TaskRepository taskRepository; + private final int parentSpawnDepth; + + private record SpawnedAgent( + String key, String agentId, String sessionId, String label, Agent agent, int depth) {} + + private final ConcurrentHashMap agentsByKey = new ConcurrentHashMap<>(); + private final ConcurrentHashMap labelToKey = new ConcurrentHashMap<>(); + + public AgentSpawnTool( + DefaultAgentManager agentManager, TaskRepository taskRepository, int parentSpawnDepth) { + this.agentManager = Objects.requireNonNull(agentManager, "agentManager"); + this.taskRepository = taskRepository; + this.parentSpawnDepth = parentSpawnDepth; + } + + @Tool( + name = "agent_spawn", + description = + """ + Spawn an isolated subagent for delegated or background work. \ + Every response starts with three lines: agent_key (pass this verbatim to \ + agent_send as agent_key), agent_id (the subagent type name), and session_id \ + (internal; do not use as agent_key). Sync mode returns the reply below that; \ + async (timeout_seconds=0) adds task_id for task_output — task_id is NOT agent_key.\ + """) + public String agentSpawn( + @ToolParam(name = "agent_id", description = "Subagent identifier to instantiate") + String agentId, + @ToolParam( + name = "task", + description = "Task or prompt to send to the spawned agent", + required = false) + String task, + @ToolParam( + name = "label", + description = + "Optional human-readable label for referencing via agent_send", + required = false) + String label, + @ToolParam( + name = "timeout_seconds", + description = + """ + Max seconds to wait for the task result. 0=fire-and-forget, \ + returns task_id. Default: 30. Max: 600.\ + """, + required = false) + Integer timeoutSeconds) { + + int nextDepth = parentSpawnDepth + 1; + if (nextDepth > MAX_SPAWN_DEPTH) { + return "Error: Maximum spawn depth exceeded (max=" + MAX_SPAWN_DEPTH + ")"; + } + if (!agentManager.hasAgent(agentId)) { + return "Error: Unknown agent_id: " + agentId; + } + + String canonLabel = label != null && !label.isBlank() ? label.trim() : null; + if (canonLabel != null && labelToKey.containsKey(canonLabel.toLowerCase())) { + return "Error: Label already in use: " + canonLabel; + } + + Agent agent = agentManager.createAgent(agentId); + String key = "agent:" + agentId + ":" + UUID.randomUUID(); + String sessionId = "sub-" + UUID.randomUUID(); + + SpawnedAgent spawned = + new SpawnedAgent(key, agentId, sessionId, canonLabel, agent, nextDepth); + agentsByKey.put(key, spawned); + if (canonLabel != null) { + labelToKey.put(canonLabel.toLowerCase(), key); + } + + String spawnInfo = formatSpawnInfo(key, agentId, sessionId); + boolean hasTask = task != null && !task.isBlank(); + + if (!hasTask) { + return spawnInfo + "\nstatus: accepted"; + } + + long timeoutMs = resolveTimeoutMs(timeoutSeconds, DEFAULT_TIMEOUT_SECONDS); + + if (timeoutMs == 0) { + String taskId = "task_" + UUID.randomUUID(); + final String capturedTask = task; + taskRepository.putTask( + taskId, + agentId, + () -> { + try { + Msg reply = + agentManager + .invokeAgent(agent, sessionId, capturedTask) + .block(); + return reply != null ? reply.getTextContent() : ""; + } catch (RuntimeException e) { + return "Error: " + + (e.getMessage() != null + ? e.getMessage() + : e.getClass().getSimpleName()); + } + }); + return spawnInfo + "\n" + String.format(BG_RESULT_TEMPLATE, taskId, taskId, taskId); + } + + try { + Msg reply = + agentManager + .invokeAgent(agent, sessionId, task.trim()) + .block(Duration.ofMillis(timeoutMs)); + String text = reply != null ? reply.getTextContent() : ""; + return spawnInfo + "\nstatus: ok\nreply:\n" + text; + } catch (RuntimeException e) { + String err = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); + log.warn("agent_spawn execute failed: agentId={}", agentId, e); + return spawnInfo + "\nstatus: error\nerror: " + err; + } + } + + @Tool( + name = "agent_send", + description = + """ + Send a message to an existing subagent. Use the exact string from the \ + agent_key line of agent_spawn output (starts with agent:), or the label \ + you set at spawn. Do not pass agent_id, session_id, or task_id here. \ + timeout_seconds=0 returns task_id for task_output.\ + """) + public String agentSend( + @ToolParam( + name = "agent_key", + description = + "Exact value from agent_spawn's first line after 'agent_key: '" + + " (format agent::). Not agent_id, session_id," + + " or task_id. Mutually exclusive with label.", + required = false) + String agentKey, + @ToolParam( + name = "label", + description = + "Agent label assigned at spawn time. Mutually exclusive with" + + " agent_key.", + required = false) + String label, + @ToolParam(name = "message", description = "Message to send to the subagent") + String message, + @ToolParam( + name = "timeout_seconds", + description = + """ + Max seconds to wait for a reply. 0=fire-and-forget, returns \ + task_id. Default: 30. Max: 600.\ + """, + required = false) + Integer timeoutSeconds) { + + boolean hasKey = agentKey != null && !agentKey.isBlank(); + boolean hasLabel = label != null && !label.isBlank(); + if (hasKey && hasLabel) { + return "Error: Provide either agent_key or label, not both."; + } + if (!hasKey && !hasLabel) { + return "Error: Either agent_key or label is required."; + } + if (message == null || message.isBlank()) { + return "Error: message is required"; + } + + String key; + if (hasKey) { + key = agentKey.trim(); + } else { + key = labelToKey.get(label.trim().toLowerCase()); + if (key == null) { + return "Error: Unknown label: " + label.trim(); + } + } + + SpawnedAgent spawned = agentsByKey.get(key); + if (spawned == null) { + return "Error: Unknown agent_key: " + key; + } + + long timeoutMs = resolveTimeoutMs(timeoutSeconds, DEFAULT_TIMEOUT_SECONDS); + + if (timeoutMs == 0) { + String taskId = "task_" + UUID.randomUUID(); + taskRepository.putTask( + taskId, + spawned.agentId(), + () -> { + try { + Msg reply = + agentManager + .invokeAgent( + spawned.agent(), spawned.sessionId(), message) + .block(); + return reply != null ? reply.getTextContent() : ""; + } catch (RuntimeException e) { + return "Error: " + + (e.getMessage() != null + ? e.getMessage() + : e.getClass().getSimpleName()); + } + }); + return String.format(BG_RESULT_TEMPLATE, taskId, taskId, taskId); + } + + try { + Msg reply = + agentManager + .invokeAgent(spawned.agent(), spawned.sessionId(), message.trim()) + .block(Duration.ofMillis(timeoutMs)); + String text = reply != null ? reply.getTextContent() : ""; + return "agent_key: " + key + "\nstatus: ok\nreply:\n" + text; + } catch (RuntimeException e) { + String err = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); + log.warn("agent_send failed: key={}", key, e); + return "Error: " + err; + } + } + + @Tool(name = "agent_list", description = "List active subagents spawned by this agent.") + public String agentList() { + if (agentsByKey.isEmpty()) { + return "No active subagents."; + } + + StringBuilder sb = + new StringBuilder("Active subagents (").append(agentsByKey.size()).append("):\n"); + for (SpawnedAgent a : agentsByKey.values()) { + sb.append("- agent_key: ").append(a.key()).append("\n"); + sb.append(" agent_id: ").append(a.agentId()).append("\n"); + if (a.label() != null) { + sb.append(" label: ").append(a.label()).append("\n"); + } + sb.append(" spawn_depth: ").append(a.depth()).append("\n"); + } + return sb.toString().trim(); + } + + // ----------------------------------------------------------------- + // Helpers + // ----------------------------------------------------------------- + + private static long resolveTimeoutMs(Integer timeoutSeconds, int defaultSeconds) { + if (timeoutSeconds == null) { + return (long) defaultSeconds * 1_000; + } + if (timeoutSeconds <= 0) { + return 0L; + } + return (long) Math.min(timeoutSeconds, MAX_TIMEOUT_SECONDS) * 1_000; + } + + private static String formatSpawnInfo(String key, String agentId, String sessionId) { + StringBuilder sb = new StringBuilder(); + sb.append("agent_key: ").append(key).append("\n"); + sb.append("agent_id: ").append(agentId).append("\n"); + sb.append("session_id: ").append(sessionId); + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java new file mode 100644 index 000000000..13467fe10 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java @@ -0,0 +1,150 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.EditResult; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.GrepMatch; +import io.agentscope.harness.agent.filesystem.model.GrepResult; +import io.agentscope.harness.agent.filesystem.model.LsResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import java.util.List; +import java.util.stream.Collectors; + +/** + * File system tools backed by a {@link AbstractFilesystem}, exposing read/write/edit/grep/glob + * operations as agent-callable tools. + */ +public class FilesystemTool { + + private final AbstractFilesystem abstractFilesystem; + + public FilesystemTool(AbstractFilesystem abstractFilesystem) { + this.abstractFilesystem = abstractFilesystem; + } + + @Tool( + name = "read_file", + description = + "Read file content with line numbers. Supports pagination via offset and" + + " limit.") + public String readFile( + @ToolParam(name = "path", description = "File path to read") String path, + @ToolParam( + name = "offset", + description = "Start line (0-indexed). Default: 0 (from beginning)") + int offset, + @ToolParam(name = "limit", description = "Max lines to return. Default: 0 (all lines)") + int limit) { + ReadResult r = abstractFilesystem.read(path, offset, limit); + if (!r.isSuccess()) { + return "Error: " + r.error(); + } + return r.fileData() != null ? r.fileData().content() : ""; + } + + @Tool( + name = "write_file", + description = "Write content to a new file, creating parent directories if needed.") + public String writeFile( + @ToolParam(name = "path", description = "Target file path") String path, + @ToolParam(name = "content", description = "File content to write") String content) { + WriteResult r = abstractFilesystem.write(path, content); + return r.isSuccess() ? "Written to " + r.path() : "Error: " + r.error(); + } + + @Tool( + name = "edit_file", + description = + "Perform exact string replacement in a file. The old_string must be unique" + + " unless replace_all is true.") + public String editFile( + @ToolParam(name = "path", description = "File to edit") String path, + @ToolParam(name = "old_string", description = "Text to find") String oldString, + @ToolParam(name = "new_string", description = "Replacement text") String newString, + @ToolParam( + name = "replace_all", + description = "Replace all occurrences (default: false)") + boolean replaceAll) { + EditResult r = abstractFilesystem.edit(path, oldString, newString, replaceAll); + return r.isSuccess() + ? "Edited " + r.path() + " (" + r.occurrences() + " replacement(s))" + : "Error: " + r.error(); + } + + @Tool(name = "grep_files", description = "Search file contents for a literal text pattern.") + public String grepFiles( + @ToolParam(name = "pattern", description = "Literal text pattern to search for") + String pattern, + @ToolParam(name = "path", description = "Directory or file to search") String path, + @ToolParam(name = "glob", description = "Optional file glob filter (e.g., *.java)") + String glob) { + GrepResult r = abstractFilesystem.grep(pattern, path, glob); + if (!r.isSuccess()) { + return "Error: " + r.error(); + } + List matches = r.matches(); + if (matches == null || matches.isEmpty()) { + return "No matches found"; + } + return matches.stream() + .map(m -> m.path() + ":" + m.line() + ":" + m.text()) + .collect(Collectors.joining("\n")); + } + + @Tool(name = "glob_files", description = "Find files matching a glob pattern.") + public String globFiles( + @ToolParam(name = "pattern", description = "Glob pattern (e.g., **/*.java)") + String pattern, + @ToolParam(name = "path", description = "Base directory to search from") String path) { + GlobResult r = abstractFilesystem.glob(pattern, path); + if (!r.isSuccess()) { + return "Error: " + r.error(); + } + List files = r.matches(); + if (files == null || files.isEmpty()) { + return "No matching files found"; + } + return files.stream() + .map(f -> f.path() + (f.isDirectory() ? "/" : " (" + f.size() + " bytes)")) + .collect(Collectors.joining("\n")); + } + + @Tool(name = "list_files", description = "List files and directories at the given path.") + public String listFiles( + @ToolParam(name = "path", description = "Directory path to list") String path) { + LsResult r = abstractFilesystem.ls(path); + if (!r.isSuccess()) { + return "Error: " + r.error(); + } + List infos = r.entries(); + if (infos == null || infos.isEmpty()) { + return "Empty or not a directory: " + path; + } + return infos.stream() + .map( + f -> + (f.isDirectory() ? "[DIR] " : "[FILE] ") + + f.path() + + (f.isDirectory() ? "" : " (" + f.size() + " bytes)")) + .collect(Collectors.joining("\n")); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemoryGetTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemoryGetTool.java new file mode 100644 index 000000000..a667711e6 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemoryGetTool.java @@ -0,0 +1,80 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.nio.file.Path; +import java.util.List; + +/** + * Tool for reading specific lines from memory files, typically used after + * {@link MemorySearchTool} to fetch surrounding context. + */ +public class MemoryGetTool { + + private final WorkspaceManager workspaceManager; + + public MemoryGetTool(WorkspaceManager workspaceManager) { + this.workspaceManager = workspaceManager; + } + + @Tool( + name = "memory_get", + description = + "Read specific lines from a memory file. Use after memory_search to pull" + + " full context around matched lines. Path is relative to workspace.") + public String memoryGet( + @ToolParam( + name = "path", + description = + "Relative path to the memory file (e.g., MEMORY.md or" + + " memory/2026-04-01.md)") + String path, + @ToolParam(name = "startLine", description = "Start line number (1-based, inclusive)") + int startLine, + @ToolParam(name = "endLine", description = "End line number (1-based, inclusive)") + int endLine) { + if (path == null || path.isBlank()) { + return "Error: path is required"; + } + + Path resolved = workspaceManager.getWorkspace().resolve(path).normalize(); + if (!resolved.startsWith(workspaceManager.getWorkspace())) { + return "Error: path traversal not allowed"; + } + + String text = workspaceManager.readManagedWorkspaceFileUtf8(path); + if (text == null || text.isBlank()) { + return "Error: file not found: " + path; + } + + List lines = List.of(text.split("\n", -1)); + int start = Math.max(0, startLine - 1); + int end = Math.min(lines.size(), endLine); + + if (start >= lines.size()) { + return "Error: startLine " + startLine + " exceeds file length " + lines.size(); + } + + StringBuilder sb = new StringBuilder(); + for (int i = start; i < end; i++) { + sb.append(String.format("%d|%s%n", i + 1, lines.get(i))); + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java new file mode 100644 index 000000000..590a19d6d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java @@ -0,0 +1,112 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.memory.MemoryIndex; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.util.List; +import java.util.StringJoiner; +import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tool for searching through persisted memories (MEMORY.md and memory/*.md files). + * + *

When a {@link MemoryIndex} is available, uses SQLite FTS5 for ranked full-text + * search. Falls back to naive keyword search when the index is unavailable. + */ +public class MemorySearchTool { + + private static final Logger log = LoggerFactory.getLogger(MemorySearchTool.class); + private static final int MAX_RESULTS = 30; + + private final WorkspaceManager workspaceManager; + private volatile MemoryIndex memoryIndex; + + public MemorySearchTool(WorkspaceManager workspaceManager) { + this.workspaceManager = workspaceManager; + } + + public void setMemoryIndex(MemoryIndex memoryIndex) { + this.memoryIndex = memoryIndex; + } + + @Tool( + name = "memory_search", + description = + "Search through long-term memory files (MEMORY.md and memory/*.md) for" + + " relevant information. Use before answering questions about prior" + + " work, decisions, dates, people, preferences, or todos.") + public String memorySearch( + @ToolParam(name = "query", description = "Keywords to search for in memory files") + String query) { + if (query == null || query.isBlank()) { + return "No query provided"; + } + + MemoryIndex idx = this.memoryIndex; + if (idx != null) { + try { + List hits = idx.search(query, MAX_RESULTS); + if (!hits.isEmpty()) { + StringJoiner sj = new StringJoiner("\n"); + for (MemoryIndex.SearchHit hit : hits) { + sj.add( + String.format( + "Source: %s#%d: %s", + hit.path(), hit.lineNumber(), hit.content())); + } + return "Found " + hits.size() + " matches:\n\n" + sj; + } + return "No matching memories found for: " + query; + } catch (Exception e) { + log.warn("FTS5 search failed, falling back to keyword search: {}", e.getMessage()); + } + } + + return keywordSearch(query); + } + + private String keywordSearch(String query) { + StringJoiner results = new StringJoiner("\n"); + int matchCount = 0; + + List memoryPaths = workspaceManager.listMemoryFilePaths(); + Pattern pattern = Pattern.compile(Pattern.quote(query), Pattern.CASE_INSENSITIVE); + + for (String relativePath : memoryPaths) { + String content = workspaceManager.readManagedWorkspaceFileUtf8(relativePath); + if (content == null || content.isEmpty()) { + continue; + } + String[] lines = content.split("\n", -1); + for (int i = 0; i < lines.length; i++) { + if (pattern.matcher(lines[i]).find()) { + results.add(String.format("Source: %s#%d: %s", relativePath, i + 1, lines[i])); + matchCount++; + } + } + } + + if (matchCount == 0) { + return "No matching memories found for: " + query; + } + return "Found " + matchCount + " matches:\n\n" + results; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java new file mode 100644 index 000000000..bce5aca30 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java @@ -0,0 +1,288 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.memory.session.SessionEntry; +import io.agentscope.harness.agent.memory.session.SessionTree; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tool for searching past session transcripts and viewing session history. + */ +public class SessionSearchTool { + + private static final Logger log = LoggerFactory.getLogger(SessionSearchTool.class); + + private final WorkspaceManager workspaceManager; + + public SessionSearchTool(WorkspaceManager workspaceManager) { + this.workspaceManager = workspaceManager; + } + + @Tool( + name = "session_search", + description = + "Search past session transcripts for a keyword or phrase." + + " Returns matching entries with session context.") + public String sessionSearch( + @ToolParam(name = "query", description = "Search query (keyword or phrase)") + String query, + @ToolParam( + name = "agentId", + description = "Agent ID to search sessions for", + required = false) + String agentId, + @ToolParam( + name = "maxResults", + description = "Maximum number of results to return (default: 10)", + required = false) + Integer maxResults) { + if (query == null || query.isBlank()) { + return "Error: query is required"; + } + + int limit = maxResults != null && maxResults > 0 ? maxResults : 10; + String effectiveAgentId = agentId != null && !agentId.isBlank() ? agentId : null; + String lowerQuery = query.toLowerCase(); + + List results = new ArrayList<>(); + + List sessionDirs = listSessionDirs(effectiveAgentId); + for (Path sessionDir : sessionDirs) { + List sessionFiles = listJsonlFiles(sessionDir); + for (Path file : sessionFiles) { + if (results.size() >= limit) { + break; + } + searchInSessionFile(file, lowerQuery, results, limit); + } + } + + if (results.isEmpty()) { + return "No matches found for: " + query; + } + + StringBuilder sb = new StringBuilder(); + sb.append(String.format("Found %d matches for \"%s\":\n\n", results.size(), query)); + for (String result : results) { + sb.append(result).append("\n"); + } + return sb.toString(); + } + + @Tool( + name = "session_list", + description = "List available sessions for an agent, showing session IDs and metadata.") + public String sessionList( + @ToolParam(name = "agentId", description = "Agent ID to list sessions for") + String agentId) { + if (agentId == null || agentId.isBlank()) { + return "Error: agentId is required"; + } + + Path sessionDir = workspaceManager.getSessionDir(agentId); + if (!Files.isDirectory(sessionDir)) { + return "No sessions found for agent: " + agentId; + } + + String storeContent = + workspaceManager.readManagedWorkspaceFileUtf8( + WorkspaceConstants.AGENTS_DIR + + "/" + + agentId + + "/" + + WorkspaceConstants.SESSIONS_DIR + + "/" + + WorkspaceConstants.SESSIONS_STORE); + + if (!storeContent.isBlank()) { + return storeContent; + } + + List sessionFiles = listJsonlFiles(sessionDir); + if (sessionFiles.isEmpty()) { + return "No sessions found for agent: " + agentId; + } + + StringBuilder sb = new StringBuilder(); + sb.append("Sessions for agent ").append(agentId).append(":\n"); + for (Path file : sessionFiles) { + String name = file.getFileName().toString(); + String sessionId = + name.replace(WorkspaceConstants.SESSION_CONTEXT_EXT, "") + .replace(WorkspaceConstants.SESSION_LOG_EXT, "") + .replace(".json", ""); + sb.append(" - ").append(sessionId).append("\n"); + } + return sb.toString(); + } + + @Tool( + name = "session_history", + description = + "Get the conversation history for a specific session." + + " Returns the messages in the session.") + public String sessionHistory( + @ToolParam(name = "agentId", description = "Agent ID") String agentId, + @ToolParam(name = "sessionId", description = "Session ID") String sessionId, + @ToolParam( + name = "lastN", + description = "Number of recent messages to return (default: 20)", + required = false) + Integer lastN) { + if (agentId == null || agentId.isBlank() || sessionId == null || sessionId.isBlank()) { + return "Error: agentId and sessionId are required"; + } + + int limit = lastN != null && lastN > 0 ? lastN : 20; + + Path contextFile = workspaceManager.resolveSessionContextFile(agentId, sessionId); + if (!Files.isRegularFile(contextFile)) { + @SuppressWarnings("deprecation") + Path legacyFile = workspaceManager.resolveSessionFile(agentId, sessionId); + if (Files.isRegularFile(legacyFile)) { + log.debug("Falling back to legacy .json session file for {}", sessionId); + return readLegacySession(legacyFile, limit); + } + return "Session not found: " + sessionId; + } + + SessionTree tree = new SessionTree(contextFile); + tree.load(); + + List messages = tree.getMessageEntries(); + int start = Math.max(0, messages.size() - limit); + + StringBuilder sb = new StringBuilder(); + sb.append( + String.format( + "Session %s (%d total messages, showing last %d):\n\n", + sessionId, messages.size(), Math.min(limit, messages.size()))); + for (int i = start; i < messages.size(); i++) { + SessionEntry.MessageEntry msg = messages.get(i); + String content = msg.getContent(); + if (content != null && content.length() > 500) { + content = content.substring(0, 500) + "... [truncated]"; + } + sb.append(String.format("[%s]: %s\n", msg.getRole(), content)); + } + return sb.toString(); + } + + private List listSessionDirs(String agentId) { + List dirs = new ArrayList<>(); + Path agentsDir = workspaceManager.getWorkspace().resolve(WorkspaceConstants.AGENTS_DIR); + if (!Files.isDirectory(agentsDir)) { + return dirs; + } + + if (agentId != null) { + Path dir = agentsDir.resolve(agentId).resolve(WorkspaceConstants.SESSIONS_DIR); + if (Files.isDirectory(dir)) { + dirs.add(dir); + } + return dirs; + } + + try (Stream walk = Files.list(agentsDir)) { + walk.filter(Files::isDirectory) + .forEach( + agentDir -> { + Path sessDir = agentDir.resolve(WorkspaceConstants.SESSIONS_DIR); + if (Files.isDirectory(sessDir)) { + dirs.add(sessDir); + } + }); + } catch (IOException e) { + // ignore + } + return dirs; + } + + private List listJsonlFiles(Path dir) { + List files = new ArrayList<>(); + if (!Files.isDirectory(dir)) { + return files; + } + try (Stream walk = Files.list(dir)) { + walk.filter(p -> p.toString().endsWith(".log.jsonl")) + .filter(Files::isRegularFile) + .forEach(files::add); + } catch (IOException e) { + // ignore + } + return files; + } + + private void searchInSessionFile( + Path file, String lowerQuery, List results, int limit) { + try { + SessionTree tree = + new SessionTree( + file.resolveSibling( + file.getFileName().toString().replace(".log.jsonl", ".jsonl"))); + tree.load(); + + String relPath = workspaceManager.getWorkspace().relativize(file).toString(); + for (SessionEntry.MessageEntry msg : tree.getMessageEntries()) { + if (results.size() >= limit) { + break; + } + String content = msg.getContent(); + if (content != null && content.toLowerCase().contains(lowerQuery)) { + String preview = + content.length() > 200 ? content.substring(0, 200) + "..." : content; + results.add( + String.format( + " [%s] %s — [%s]: %s", + relPath, msg.getId(), msg.getRole(), preview)); + } + } + } catch (Exception e) { + // skip corrupted files + } + } + + private String readLegacySession(Path file, int limit) { + try { + String content = Files.readString(file); + String[] lines = content.split("\n"); + int start = Math.max(0, lines.length - limit); + StringBuilder sb = new StringBuilder(); + sb.append( + String.format( + "Legacy session (%d lines, showing last %d):\n", + lines.length, Math.min(limit, lines.length))); + for (int i = start; i < lines.length; i++) { + sb.append(lines[i]).append("\n"); + } + return sb.toString(); + } catch (IOException e) { + return "Error reading session file: " + e.getMessage(); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java new file mode 100644 index 000000000..74f6e2659 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java @@ -0,0 +1,64 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.filesystem.AbstractSandboxFilesystem; +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; + +/** + * Shell execution tool backed by a {@link AbstractSandboxFilesystem}. + */ +public class ShellExecuteTool { + + private final AbstractSandboxFilesystem sandbox; + + public ShellExecuteTool(AbstractSandboxFilesystem sandbox) { + this.sandbox = sandbox; + } + + @Tool( + description = + "Execute a shell command. Use for git, npm, build, test, and other terminal" + + " operations. Returns combined output and exit code.") + public String execute( + @ToolParam(name = "command", description = "Shell command to execute") String command, + @ToolParam( + name = "working_directory", + description = + "Working directory (relative to workspace root, optional)") + String workingDirectory, + @ToolParam(name = "timeout", description = "Timeout in seconds (default: 30)") + int timeout) { + String effectiveCommand = command; + if (workingDirectory != null && !workingDirectory.isBlank()) { + effectiveCommand = "cd " + workingDirectory + " && " + command; + } + + ExecuteResponse result = sandbox.execute(effectiveCommand, timeout > 0 ? timeout : 30); + + StringBuilder sb = new StringBuilder(); + sb.append("Exit code: ").append(result.exitCode()).append("\n"); + if (result.output() != null && !result.output().isBlank()) { + sb.append("\n").append(result.output()); + } + if (result.truncated()) { + sb.append("\n(output was truncated)"); + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/TaskTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/TaskTool.java new file mode 100644 index 000000000..1b725a04e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/TaskTool.java @@ -0,0 +1,202 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.tool; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.harness.agent.subagent.task.BackgroundTask; +import io.agentscope.harness.agent.subagent.task.TaskRepository; +import io.agentscope.harness.agent.subagent.task.TaskStatus; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.Collection; + +/** + * Unified tool for background task lifecycle management. Combines task result retrieval, + * cancellation, and listing into a single tool class. + * + *

    + *
  • {@code task_output} — retrieve result (blocking or non-blocking) + *
  • {@code task_cancel} — cancel a running task + *
  • {@code task_list} — list all tracked tasks with optional status filter + *
+ */ +public class TaskTool { + + private static final DateTimeFormatter ISO_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneOffset.UTC); + + private final TaskRepository taskRepository; + + public TaskTool(TaskRepository taskRepository) { + this.taskRepository = taskRepository; + } + + @Tool( + name = "task_output", + description = + "Retrieve the output of a background subagent task. Use when agent_spawn or" + + " agent_send was called with timeout_seconds=0. Supports blocking wait" + + " for completion or non-blocking status peek (block=false).") + public String taskOutput( + @ToolParam( + name = "task_id", + description = + "The task_id returned by agent_spawn or agent_send when" + + " timeout_seconds was 0") + String taskId, + @ToolParam( + name = "block", + description = "Whether to wait for completion (default: true)", + required = false) + Boolean block, + @ToolParam( + name = "timeout", + description = + "Max wait time in milliseconds (default: 30000, max: 600000)", + required = false) + Long timeout) { + + if (taskId == null || taskId.isBlank()) { + return "Error: task_id is required"; + } + + BackgroundTask bgTask = taskRepository.getTask(taskId); + if (bgTask == null) { + return "Error: No background task found with ID: " + taskId; + } + + bgTask.updateLastCheckedAt(); + + boolean shouldBlock = block == null || block; + long timeoutMs = timeout != null ? Math.min(timeout, 600_000) : 30_000; + + if (shouldBlock && !bgTask.isCompleted()) { + try { + bgTask.waitForCompletion(timeoutMs); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return "Error: Wait for task interrupted"; + } + } + + return formatTaskDetail(bgTask); + } + + @Tool( + name = "task_cancel", + description = + "Cancel a running background task. Use to stop a task that is no longer" + + " needed. Has no effect on already-completed tasks.") + public String taskCancel( + @ToolParam(name = "task_id", description = "The task_id to cancel") String taskId) { + + if (taskId == null || taskId.isBlank()) { + return "Error: task_id is required"; + } + + BackgroundTask bgTask = taskRepository.getTask(taskId); + if (bgTask == null) { + return "Error: No background task found with ID: " + taskId; + } + + TaskStatus currentStatus = bgTask.getTaskStatus(); + if (currentStatus.isTerminal()) { + return "task_id: " + + taskId + + "\nstatus: " + + currentStatus.name().toLowerCase() + + "\nnote: Task already in terminal state, cannot cancel."; + } + + taskRepository.cancelTask(taskId); + return "task_id: " + taskId + "\nstatus: cancelled\nCancellation requested successfully."; + } + + @Tool( + name = "task_list", + description = + "List all tracked background tasks with their current statuses. Optionally" + + " filter by status (running, completed, failed, cancelled). Use to get an" + + " overview of all background work.") + public String taskList( + @ToolParam( + name = "status_filter", + description = + "Filter by status: running, completed, failed, cancelled, or" + + " omit for all tasks", + required = false) + String statusFilter) { + + TaskStatus filter = parseStatusFilter(statusFilter); + Collection tasks = taskRepository.listTasks(filter); + + if (tasks.isEmpty()) { + String filterDesc = + filter != null ? " with status '" + filter.name().toLowerCase() + "'" : ""; + return "No background tasks tracked" + filterDesc + "."; + } + + StringBuilder sb = new StringBuilder(); + sb.append(tasks.size()).append(" tracked task(s):\n"); + for (BackgroundTask task : tasks) { + sb.append("- task_id: ").append(task.getTaskId()); + if (task.getAgentId() != null) { + sb.append(" agent: ").append(task.getAgentId()); + } + sb.append(" status: ").append(task.getTaskStatus().name().toLowerCase()); + sb.append(" created: ").append(ISO_FORMATTER.format(task.getCreatedAt())); + sb.append('\n'); + } + return sb.toString().trim(); + } + + private static TaskStatus parseStatusFilter(String filter) { + if (filter == null || filter.isBlank() || "all".equalsIgnoreCase(filter.trim())) { + return null; + } + try { + return TaskStatus.valueOf(filter.trim().toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } + + private static String formatTaskDetail(BackgroundTask task) { + StringBuilder sb = new StringBuilder(); + sb.append("task_id: ").append(task.getTaskId()).append('\n'); + if (task.getAgentId() != null) { + sb.append("agent_id: ").append(task.getAgentId()).append('\n'); + } + sb.append("status: ").append(task.getStatus()).append('\n'); + sb.append("created_at: ").append(ISO_FORMATTER.format(task.getCreatedAt())).append('\n'); + + if (task.isCompleted() && task.getResult() != null) { + sb.append("\nResult:\n").append(task.getResult()); + } else if (task.getError() != null) { + Exception err = task.getError(); + sb.append("\nError:\n").append(err.getMessage()); + if (err.getCause() != null) { + sb.append("\nCause: ").append(err.getCause().getMessage()); + } + } else if (!task.isCompleted()) { + sb.append("\nTask still running..."); + } else { + sb.append("\nTask completed with no result."); + } + return sb.toString(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceConstants.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceConstants.java new file mode 100644 index 000000000..84ce87758 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceConstants.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.workspace; + +/** Path constants for the workspace directory structure. */ +public final class WorkspaceConstants { + + private WorkspaceConstants() {} + + public static final String DEFAULT_WORKSPACE_ROOT = ".agentscope/workspace"; + + public static final String AGENTS_MD = "AGENTS.md"; + public static final String MEMORY_MD = "MEMORY.md"; + + public static final String MEMORY_DIR = "memory"; + public static final String SKILLS_DIR = "skills"; + public static final String KNOWLEDGE_DIR = "knowledge"; + public static final String KNOWLEDGE_MD = "KNOWLEDGE.md"; + public static final String RULES_DIR = "rules"; + + public static final String AGENTS_DIR = "agents"; + public static final String SESSIONS_DIR = "sessions"; + + /** + * Per-agent session store filename under {@code agents/<agentId>/sessions/} + */ + public static final String SESSIONS_STORE = "sessions.json"; + + /** JSONL session context file extension (LLM-facing, may be compacted). */ + public static final String SESSION_CONTEXT_EXT = ".jsonl"; + + /** JSONL session log file extension (full history, append-only, never compacted). */ + public static final String SESSION_LOG_EXT = ".log.jsonl"; + + public static final String SUBAGENT_YML = "subagent.yml"; +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java new file mode 100644 index 000000000..3e0407012 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java @@ -0,0 +1,525 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.workspace; + +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.AGENTS_DIR; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.AGENTS_MD; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.KNOWLEDGE_DIR; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.KNOWLEDGE_MD; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.MEMORY_DIR; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.MEMORY_MD; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.SESSIONS_DIR; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.SESSIONS_STORE; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.SKILLS_DIR; +import static io.agentscope.harness.agent.workspace.WorkspaceConstants.SUBAGENT_YML; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.filesystem.model.ReadResult; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Stateless accessor for workspace content using a two-layer read architecture. + * + *

Read path: For every read (AGENTS.md, MEMORY.md, knowledge, subagent.yml, + * etc.), the {@link AbstractFilesystem} is queried first. If it returns non-empty content, that + * content is used (filesystem overrides). Otherwise, the local workspace disk is read as a + * fallback. The filesystem layer applies user/session scoping transparently via + * {@link io.agentscope.harness.agent.filesystem.store.NamespaceFactory}. + * + *

Write path: All writes (memory, sessions, etc.) go through the + * {@link AbstractFilesystem}. + * + *

Listing: File listings (memory files, knowledge files, session logs) union + * results from both the filesystem layer and local disk, deduplicating by relative path. + * + *

Expected layout: + * + *

+ * workspace/
+ * ├── AGENTS.md
+ * ├── MEMORY.md
+ * ├── memory/YYYY-MM-DD.md
+ * ├── skills/<skill-name>/SKILL.md
+ * ├── knowledge/KNOWLEDGE.md
+ * ├── knowledge/*
+ * ├── agents/<agentId>/sessions/sessions.json
+ * ├── agents/<agentId>/sessions/<sessionId>.log.jsonl
+ * └── subagent.yml
+ * 
+ */ +public class WorkspaceManager { + + private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class); + private static final ObjectMapper SESSION_STORE_JSON = new ObjectMapper(); + + private final Path workspace; + private final AbstractFilesystem filesystem; + + public WorkspaceManager(Path workspace) { + this(workspace, null); + } + + public WorkspaceManager(Path workspace, AbstractFilesystem filesystem) { + this.workspace = workspace; + this.filesystem = filesystem; + } + + public AbstractFilesystem getFilesystem() { + return filesystem; + } + + /** + * Validates the workspace exists and key files are present. Logs warnings for anything + * missing. Called once at HarnessAgent build time. + */ + public void validate() { + if (!Files.isDirectory(workspace)) { + log.warn( + "Workspace directory does not exist: {}. " + + "Please create it and add AGENTS.md.", + workspace.toAbsolutePath()); + return; + } + if (!Files.isRegularFile(workspace.resolve(AGENTS_MD))) { + log.warn( + "AGENTS.md not found in workspace: {}. " + + "AGENTS.md defines persona and local conventions for the agent.", + workspace.toAbsolutePath()); + } + } + + public Path getWorkspace() { + return workspace; + } + + /** Reads AGENTS.md content, returns empty string if not found. */ + public String readAgentsMd() { + return readWithOverride(AGENTS_MD); + } + + /** Reads KNOWLEDGE.md content from the knowledge directory. */ + public String readKnowledgeMd() { + return readWithOverride(KNOWLEDGE_DIR + "/" + KNOWLEDGE_MD); + } + + /** Reads MEMORY.md content (two-layer: filesystem override, local fallback). */ + public String readMemoryMd() { + return readWithOverride(MEMORY_MD); + } + + /** + * Reads a UTF-8 file under the workspace, using the two-layer pattern: + * filesystem first, then local disk fallback. + */ + public String readManagedWorkspaceFileUtf8(String relativePath) { + if (relativePath == null || relativePath.isBlank()) { + return ""; + } + String normalized = normalizeRelativePath(relativePath); + if (normalized.isEmpty()) { + return ""; + } + Path resolved = workspace.resolve(normalized).normalize(); + if (!resolved.startsWith(workspace)) { + return ""; + } + return readWithOverride(normalized); + } + + /** Reads subagent.yml content (two-layer: filesystem override, local fallback). */ + public String readSubagentYml() { + return readWithOverride(SUBAGENT_YML); + } + + public Path getMemoryDir() { + return workspace.resolve(MEMORY_DIR); + } + + public Path getSkillsDir() { + return workspace.resolve(SKILLS_DIR); + } + + public Path getKnowledgeDir() { + return workspace.resolve(KNOWLEDGE_DIR); + } + + /** Lists all files under the knowledge directory tree (union of filesystem + local disk). */ + public List listKnowledgeFiles() { + Set relativePaths = new LinkedHashSet<>(); + + if (filesystem != null) { + GlobResult glob = filesystem.glob("*", KNOWLEDGE_DIR); + if (glob.isSuccess() && glob.matches() != null) { + for (FileInfo fi : glob.matches()) { + if (fi.path() != null && !fi.path().isBlank()) { + relativePaths.add(normalizeRelativePath(fi.path().trim())); + } + } + } + } + + Path dir = getKnowledgeDir(); + if (Files.isDirectory(dir)) { + try (Stream walk = Files.walk(dir)) { + walk.filter(Files::isRegularFile) + .forEach( + p -> { + String rel = + workspace + .relativize(p.normalize()) + .toString() + .replace('\\', '/'); + relativePaths.add(rel); + }); + } catch (IOException e) { + log.warn("Failed to list knowledge files: {}", e.getMessage()); + } + } + + List result = new ArrayList<>(); + for (String rel : relativePaths) { + result.add(workspace.resolve(rel)); + } + return result; + } + + public Path getSessionDir(String agentId) { + return workspace.resolve(AGENTS_DIR).resolve(agentId).resolve(SESSIONS_DIR); + } + + /** + * Returns the legacy session file path (.json) without creating directories. + * + * @deprecated Use {@link #resolveSessionContextFile(String, String)} for the JSONL format. + */ + @Deprecated + public Path resolveSessionFile(String agentId, String sessionId) { + return getSessionDir(agentId).resolve(sessionId + ".json"); + } + + /** Returns the JSONL session context file path (LLM-facing, compacted). */ + public Path resolveSessionContextFile(String agentId, String sessionId) { + return getSessionDir(agentId).resolve(sessionId + WorkspaceConstants.SESSION_CONTEXT_EXT); + } + + /** Returns the JSONL session log file path (full history, append-only). */ + public Path resolveSessionLogFile(String agentId, String sessionId) { + return getSessionDir(agentId).resolve(sessionId + WorkspaceConstants.SESSION_LOG_EXT); + } + + /** + * Appends UTF-8 text to a workspace-relative file, creating parent directories when needed. + * All writes go through the {@link AbstractFilesystem}. + */ + public void appendUtf8WorkspaceRelative(String relativePath, String content) { + if (relativePath == null || content == null) { + return; + } + String normalized = normalizeRelativePath(relativePath); + if (normalized.isEmpty()) { + return; + } + if (filesystem == null) { + appendLocalFile(normalized, content); + return; + } + ReadResult rr = filesystem.read(normalized, 0, 0); + String existing = ""; + if (rr.isSuccess() && rr.fileData() != null && rr.fileData().content() != null) { + existing = rr.fileData().content(); + } + String merged = existing + content; + filesystem.uploadFiles( + List.of(Map.entry(normalized, merged.getBytes(StandardCharsets.UTF_8)))); + } + + /** + * Upserts metadata for a session in {@code agents/<agentId>/sessions/sessions.json} + * (small mutable JSON, keyed by {@code sessionId}). + */ + public void updateSessionIndex(String agentId, String sessionId, String summary) { + if (agentId == null || agentId.isBlank() || sessionId == null || sessionId.isBlank()) { + return; + } + String rel = AGENTS_DIR + "/" + agentId + "/" + SESSIONS_DIR + "/" + SESSIONS_STORE; + String existing = readWritableWorkspaceRelativeUtf8(rel); + ObjectNode root = parseSessionStoreOrEmpty(existing); + ObjectNode sessions = ensureSessionsObject(root); + ObjectNode entry = SESSION_STORE_JSON.createObjectNode(); + entry.put("summary", summary != null ? summary : ""); + entry.put("updatedAt", java.time.Instant.now().toString()); + sessions.set(sessionId, entry); + if (!root.has("version")) { + root.put("version", 1); + } + try { + String serialized = + SESSION_STORE_JSON.writerWithDefaultPrettyPrinter().writeValueAsString(root); + writeUtf8WorkspaceRelative(rel, serialized); + } catch (IOException e) { + log.warn("Failed to write session store {}: {}", rel, e.getMessage()); + } + } + + private ObjectNode parseSessionStoreOrEmpty(String json) { + if (json == null || json.isBlank()) { + return SESSION_STORE_JSON.createObjectNode(); + } + try { + var node = SESSION_STORE_JSON.readTree(json); + if (node instanceof ObjectNode on) { + return on; + } + } catch (IOException e) { + log.warn("Corrupt or unreadable session store, reinitializing: {}", e.getMessage()); + } + return SESSION_STORE_JSON.createObjectNode(); + } + + private ObjectNode ensureSessionsObject(ObjectNode root) { + var n = root.get("sessions"); + if (n instanceof ObjectNode on) { + return on; + } + ObjectNode fresh = SESSION_STORE_JSON.createObjectNode(); + root.set("sessions", fresh); + return fresh; + } + + private String readWritableWorkspaceRelativeUtf8(String relativePath) { + String normalized = normalizeRelativePath(relativePath); + if (normalized.isEmpty()) { + return ""; + } + return readWithOverride(normalized); + } + + /** Overwrites a workspace-relative UTF-8 file. All writes go through the filesystem. */ + private void writeUtf8WorkspaceRelative(String relativePath, String content) { + if (relativePath == null || content == null) { + return; + } + String normalized = normalizeRelativePath(relativePath); + if (normalized.isEmpty()) { + return; + } + if (filesystem == null) { + writeLocalFile(normalized, content); + return; + } + filesystem.uploadFiles( + List.of(Map.entry(normalized, content.getBytes(StandardCharsets.UTF_8)))); + } + + // ==================== Two-layer read/write helpers ==================== + + /** + * Two-layer read: filesystem first (namespaced by {@link + * io.agentscope.harness.agent.filesystem.store.NamespaceFactory}), local disk fallback. + */ + private String readWithOverride(String relativePath) { + String fsContent = readTextThroughFilesystem(relativePath); + if (!fsContent.isEmpty()) { + return fsContent; + } + return readFileQuietly(workspace.resolve(relativePath)); + } + + private String readFileQuietly(Path path) { + if (!Files.isRegularFile(path)) { + return ""; + } + try { + return Files.readString(path, StandardCharsets.UTF_8); + } catch (IOException e) { + log.warn("Failed to read {}: {}", path, e.getMessage()); + return ""; + } + } + + private String readTextThroughFilesystem(String filePath) { + if (filesystem == null) { + return ""; + } + ReadResult r = filesystem.read(filePath, 0, 0); + if (!r.isSuccess() || r.fileData() == null) { + return ""; + } + String c = r.fileData().content(); + return c != null ? c : ""; + } + + private void appendLocalFile(String relativePath, String content) { + Path local = workspace.resolve(relativePath).normalize(); + if (!local.startsWith(workspace)) { + log.warn("Refusing to write outside workspace: {}", relativePath); + return; + } + try { + if (local.getParent() != null) { + Files.createDirectories(local.getParent()); + } + Files.writeString( + local, + content, + StandardCharsets.UTF_8, + java.nio.file.StandardOpenOption.CREATE, + java.nio.file.StandardOpenOption.APPEND); + } catch (IOException e) { + log.warn("Failed to append {}: {}", local, e.getMessage()); + } + } + + private void writeLocalFile(String relativePath, String content) { + Path local = workspace.resolve(relativePath).normalize(); + if (!local.startsWith(workspace)) { + log.warn("Refusing to write outside workspace: {}", relativePath); + return; + } + try { + if (local.getParent() != null) { + Files.createDirectories(local.getParent()); + } + Files.writeString( + local, + content, + StandardCharsets.UTF_8, + java.nio.file.StandardOpenOption.CREATE, + java.nio.file.StandardOpenOption.TRUNCATE_EXISTING, + java.nio.file.StandardOpenOption.WRITE); + } catch (IOException e) { + log.warn("Failed to write {}: {}", local, e.getMessage()); + } + } + + static String normalizeRelativePath(String relativePath) { + if (relativePath == null || relativePath.isBlank()) { + return ""; + } + String s = relativePath.replace('\\', '/').stripLeading(); + while (s.startsWith("/")) { + s = s.substring(1); + } + return s; + } + + /** + * Returns workspace-relative paths of all memory files ({@code MEMORY.md} and {@code + * memory/*.md}). Unions results from the {@link AbstractFilesystem} layer and the local disk, + * deduplicating by relative path. + */ + public List listMemoryFilePaths() { + Set paths = new LinkedHashSet<>(); + + if (filesystem != null) { + ReadResult memMd = filesystem.read(MEMORY_MD, 0, 1); + if (memMd.isSuccess()) { + paths.add(MEMORY_MD); + } + GlobResult glob = filesystem.glob("*.md", MEMORY_DIR); + if (glob.isSuccess() && glob.matches() != null) { + for (FileInfo fi : glob.matches()) { + if (fi.path() != null && !fi.path().isBlank()) { + String rel = normalizeRelativePath(fi.path().trim()); + if (!rel.isEmpty()) { + paths.add(rel); + } + } + } + } + } + + if (Files.isRegularFile(workspace.resolve(MEMORY_MD))) { + paths.add(MEMORY_MD); + } + Path memDir = getMemoryDir(); + if (Files.isDirectory(memDir)) { + try (Stream walk = Files.list(memDir)) { + walk.filter(p -> p.toString().endsWith(".md")) + .filter(Files::isRegularFile) + .forEach(p -> paths.add(MEMORY_DIR + "/" + p.getFileName())); + } catch (IOException e) { + log.warn("Failed to list memory dir: {}", e.getMessage()); + } + } + return new ArrayList<>(paths); + } + + /** + * Lists workspace-relative paths of all session log files ({@code *.log.jsonl}). + * Unions results from the {@link AbstractFilesystem} layer and the local disk. + */ + public List listSessionLogFiles() { + Set paths = new LinkedHashSet<>(); + + if (filesystem != null) { + GlobResult glob = filesystem.glob("*.log.jsonl", AGENTS_DIR); + if (glob.isSuccess() && glob.matches() != null) { + for (FileInfo fi : glob.matches()) { + if (fi.path() != null && !fi.path().isBlank()) { + String rel = normalizeRelativePath(fi.path().trim()); + if (!rel.isEmpty()) { + paths.add(rel); + } + } + } + } + } + + Path agentsDir = workspace.resolve(AGENTS_DIR); + if (Files.isDirectory(agentsDir)) { + try (Stream walk = Files.walk(agentsDir)) { + walk.filter(Files::isRegularFile) + .filter(p -> p.toString().endsWith(WorkspaceConstants.SESSION_LOG_EXT)) + .forEach( + p -> { + String rel = + workspace + .relativize(p.normalize()) + .toString() + .replace('\\', '/'); + paths.add(rel); + }); + } catch (IOException e) { + log.warn("Failed to list session log files: {}", e.getMessage()); + } + } + return new ArrayList<>(paths); + } + + /** Workspace-relative path for indexing. */ + public String toWorkspaceRelativeString(Path absoluteUnderWorkspace) { + return workspace + .relativize(absoluteUnderWorkspace.normalize()) + .toString() + .replace('\\', '/'); + } +} diff --git a/agentscope-harness/src/main/resources/agentscope.json.example b/agentscope-harness/src/main/resources/agentscope.json.example new file mode 100644 index 000000000..76b2bb6d0 --- /dev/null +++ b/agentscope-harness/src/main/resources/agentscope.json.example @@ -0,0 +1,24 @@ +{ + "$schema": "https://agentscope.io/schema/agentscope.json", + "main": "default", + "agents": { + "default": { + "name": "Main", + "description": "Primary harness agent", + "workspace": ".agentscope/workspace", + "maxIters": 15 + }, + "worker": { + "name": "Worker", + "description": "Secondary agent with its own workspace", + "workspace": ".agentscope/worker-workspace", + "maxIters": 10 + } + }, + "channels": { + "chatui": { + "defaultAgentId": "default", + "dmScope": "MAIN" + } + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java new file mode 100644 index 000000000..ee3611ebc --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java @@ -0,0 +1,255 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.agentscope.core.agent.Agent; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.ArgumentCaptor; +import reactor.core.publisher.Flux; + +/** + * Integration-style examples for {@link HarnessAgent}: a realistic workspace on disk, full builder + * wiring, and an end-to-end {@link #call(Msg, RuntimeContext)} path. + * + *

Example workspace layout (what the tests materialize under {@link TempDir}): + * + *

+ * workspace/
+ * ├── AGENTS.md              # persona / local rules
+ * ├── MEMORY.md              # optional long-term scratch (loaded into <memory_context>)
+ * ├── knowledge/
+ * │   └── KNOWLEDGE.md       # optional domain summary
+ * └── subagents/
+ *     ├── helper.md          # YAML front matter + body as sys prompt
+ *     └── reviewer.md        # second spec example
+ * 
+ * + *

These tests use a stub {@link Model} (no API keys). Tag {@code integration} lets you filter + * them in the IDE or via JUnit Platform if you add {@code groups} later. + */ +@Tag("integration") +class HarnessAgentIntegrationExampleTest { + + @TempDir Path workspace; + + /** + * Materializes the layout above, builds the main agent, runs one turn, and asserts the stub + * reply. The model capture shows that session, subagent docs, and workspace files reached the + * LLM message list. + */ + @Test + void example_fullWorkspace_singleTurn_seesSessionSubagentsAndWorkspaceContext() + throws Exception { + String agentsPersona = "INTEGRATION_AGENTS_PERSONA_001"; + String memoryNote = "INTEGRATION_MEMORY_NOTE_002"; + String knowledgeLine = "INTEGRATION_KNOWLEDGE_LINE_003"; + String helperSubId = "integration-helper-sub"; + String reviewerSubId = "integration-md-sub"; + + Files.createDirectories(workspace); + Files.writeString( + workspace.resolve(WorkspaceConstants.AGENTS_MD), + "# Agent\n\n" + agentsPersona + "\n"); + Files.writeString(workspace.resolve(WorkspaceConstants.MEMORY_MD), memoryNote); + + Path knowledgeDir = workspace.resolve(WorkspaceConstants.KNOWLEDGE_DIR); + Files.createDirectories(knowledgeDir); + Files.writeString(knowledgeDir.resolve(WorkspaceConstants.KNOWLEDGE_MD), knowledgeLine); + + Path subagentsDir = workspace.resolve("subagents"); + Files.createDirectories(subagentsDir); + Files.writeString( + subagentsDir.resolve("helper.md"), + """ + --- + name: %s + description: First markdown-defined helper for integration example + --- + Reply with YAML_OK only. + """ + .formatted(helperSubId)); + Files.writeString( + subagentsDir.resolve("reviewer.md"), + """ + --- + name: %s + description: Second markdown-defined helper for integration example + maxIters: 5 + --- + + You only reply MD_OK. + """ + .formatted(reviewerSubId)); + + Model model = stubModel("integration-main-reply"); + HarnessAgent agent = + HarnessAgent.builder() + .name("integration-main") + .description("integration example main agent") + .sysPrompt("You are the main agent in an integration test.") + .model(model) + .workspace(workspace) + .build(); + + Msg reply = + agent.call( + userText("Run the integration scenario."), + RuntimeContext.builder().sessionId("integration-session-1").build()) + .block(); + + assertTrue(reply.getTextContent().contains("integration-main-reply")); + + @SuppressWarnings("unchecked") + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(model, atLeast(1)).stream(captor.capture(), any(), any()); + String combined = + captor.getAllValues().stream() + .map(HarnessAgentIntegrationExampleTest::joinAllText) + .filter(s -> s.contains("## Session Context")) + .findFirst() + .orElse(""); + + assertTrue(combined.contains("## Session Context"), "Session context should be injected"); + assertTrue(combined.contains("# Project Context")); + assertTrue(combined.contains("## AGENTS.md")); + assertTrue( + combined.contains(agentsPersona), "AGENTS.md should appear under workspace hook"); + assertTrue(combined.contains("## MEMORY.md")); + assertTrue(combined.contains(memoryNote)); + assertTrue(combined.contains("## KNOWLEDGE.md")); + assertTrue(combined.contains(knowledgeLine)); + assertTrue(combined.contains("## Subagents")); + assertTrue(combined.contains("`" + helperSubId + "`")); + assertTrue(combined.contains("`" + reviewerSubId + "`")); + } + + /** + * Uses the same workspace discovery as the builder, obtains a {@link SubagentEntry} for a + * markdown-defined id under {@code subagents/}, runs {@code factory().create()} and {@link + * Agent#call(List)} to prove the delegated {@link HarnessAgent} is wired with the spec name + * and prompt. + */ + @Test + void example_subagentFactory_markdownSpec_runsChildHarnessAgent() throws Exception { + Files.createDirectories(workspace); + Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), "# root\n"); + + String childId = "integration-child-spawn"; + Path subagentsDir = workspace.resolve("subagents"); + Files.createDirectories(subagentsDir); + Files.writeString( + subagentsDir.resolve("child.md"), + """ + --- + name: %s + description: Child agent for factory integration + --- + Child system prompt marker INTEGRATION_CHILD_SYS + """ + .formatted(childId)); + + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse childChunk = + new ChatResponse( + "child-id", + List.of(TextBlock.builder().text("integration-child-reply").build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(childChunk)); + + List entries = + HarnessAgent.builder() + .model(model) + .workspace(workspace) + .buildSubagentEntries(workspace); + + SubagentEntry child = + entries.stream() + .filter(e -> childId.equals(e.name())) + .findFirst() + .orElseThrow( + () -> new AssertionError("missing subagent entry: " + childId)); + + Agent sub = child.factory().create(); + assertInstanceOf(HarnessAgent.class, sub); + assertEquals(childId, sub.getName()); + + Msg subReply = sub.call(List.of(userText("task for child"))).block(); + assertTrue(subReply.getTextContent().contains("integration-child-reply")); + + @SuppressWarnings("unchecked") + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(model, atLeast(1)).stream(captor.capture(), any(), any()); + boolean childSysSeen = + captor.getAllValues().stream() + .map(HarnessAgentIntegrationExampleTest::joinAllText) + .anyMatch(s -> s.contains("INTEGRATION_CHILD_SYS")); + assertTrue( + childSysSeen, + "child HarnessAgent should use spec sysPrompt in its system prompt bundle"); + } + + private static Msg userText(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + private static String joinAllText(List msgs) { + return msgs.stream().map(Msg::getTextContent).collect(Collectors.joining("\n")); + } + + private static Model stubModel(String assistantText) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(assistantText).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java new file mode 100644 index 000000000..0c2cb69a4 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.core.model.ToolSchema; +import io.agentscope.harness.agent.filesystem.LocalFilesystem; +import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.ArgumentCaptor; +import reactor.core.publisher.Flux; + +/** + * Tests for {@link HarnessAgent} workspace wiring: {@code AGENTS.md} context and subagent + * discovery ({@code subagents/*.md}). + */ +class HarnessAgentTest { + + @TempDir Path workspace; + + @Test + void workspaceAgentsMd_readableViaWorkspaceManager() throws Exception { + Files.createDirectories(workspace); + String marker = "persona-marker-unique-agents-md-42"; + Files.writeString( + workspace.resolve(WorkspaceConstants.AGENTS_MD), "# Test\n" + marker + "\n"); + + Model model = stubModel("ok"); + HarnessAgent agent = + HarnessAgent.builder() + .name("t") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .build(); + + assertTrue(agent.getWorkspaceManager().readAgentsMd().contains(marker)); + } + + @Test + void workspaceAgentsMd_injectedIntoMessagesSeenByModel() throws Exception { + Files.createDirectories(workspace); + String marker = "injected-via-workspace-context-99"; + Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), marker); + + Model model = stubModel("assistant-done"); + HarnessAgent agent = + HarnessAgent.builder() + .name("t") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .build(); + + agent.call(userText("hi"), RuntimeContext.builder().sessionId("s1").build()).block(); + + @SuppressWarnings("unchecked") + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(model, atLeast(1)).stream(captor.capture(), any(), any()); + String combined = + captor.getAllValues().stream() + .map(HarnessAgentTest::joinAllText) + .filter(s -> s.contains("")) + .findFirst() + .orElse(""); + assertTrue( + combined.contains(""), + "expected workspace hook to wrap AGENTS.md in agents_context"); + assertTrue( + combined.contains(marker), "model should see AGENTS.md body in injected context"); + } + + @Test + void subagentMarkdown_registersIdsAndSubagentTools() throws Exception { + Files.createDirectories(workspace); + Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), "# workspace\n"); + String specId = "markdown-subagent-id-77"; + Path subagents = workspace.resolve("subagents"); + Files.createDirectories(subagents); + Files.writeString( + subagents.resolve("from-md.md"), + """ + --- + name: %s + description: From subagents/*.md for tests + --- + You only reply OK. + """ + .formatted(specId)); + + Model model = stubModel("done"); + HarnessAgent agent = + HarnessAgent.builder() + .name("main") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .build(); + + List toolNames = + agent.getDelegate().getToolkit().getToolSchemas().stream() + .map(ToolSchema::getName) + .collect(Collectors.toList()); + assertTrue( + toolNames.contains("agent_spawn"), "subagent support should register agent_spawn"); + assertTrue( + toolNames.contains("task_output"), + "subagent async path should register task_output"); + + agent.call(userText("go"), RuntimeContext.builder().sessionId("s2").build()).block(); + + @SuppressWarnings("unchecked") + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(model, atLeast(1)).stream(captor.capture(), any(), any()); + String combined = + captor.getAllValues().stream() + .map(HarnessAgentTest::joinAllText) + .filter(s -> s.contains("## Subagents")) + .findFirst() + .orElse(""); + assertTrue( + combined.contains("## Subagents"), "subagent hook should inject Subagents section"); + assertTrue( + combined.contains("`" + specId + "`"), + "Markdown subagent id should appear in prompt"); + assertTrue( + combined.contains("general-purpose"), + "built-in general-purpose entry should be listed"); + } + + @Test + void subagentsDir_loadsMarkdownSpecs() throws Exception { + Files.createDirectories(workspace); + Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), "# w\n"); + Path subagents = workspace.resolve("subagents"); + Files.createDirectories(subagents); + String mdId = "md-frontmatter-agent-88"; + Files.writeString( + subagents.resolve("helper.md"), + """ + --- + name: %s + description: Loaded from subagents/*.md + maxIters: 3 + --- + + You are a test subagent from markdown. + """ + .formatted(mdId)); + + List entries = + HarnessAgent.builder() + .model(stubModel("x")) + .workspace(workspace) + .buildSubagentEntries(workspace); + + List names = entries.stream().map(SubagentEntry::name).collect(Collectors.toList()); + assertTrue(names.contains("general-purpose")); + assertTrue( + names.contains(mdId), "subagents/*.md with front matter should produce an entry"); + } + + private static Msg userText(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + private static String joinAllText(List msgs) { + return msgs.stream().map(Msg::getTextContent).collect(Collectors.joining("\n")); + } + + private static Model stubModel(String assistantText) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(assistantText).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/pom.xml b/pom.xml index 7f72b1839..6c9ff0eaf 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ agentscope-core + agentscope-harness agentscope-extensions agentscope-examples agentscope-dependencies-bom From 0e1c809aa82024d97704e6844ff89a1d9f3c6b52 Mon Sep 17 00:00:00 2001 From: fang-tech Date: Mon, 27 Apr 2026 07:37:50 +0800 Subject: [PATCH 02/28] docs(harness): Harness documentations (#1286) --- .gitignore | 3 + .../harness/example/QuickstartExample.java | 141 +++++++ docs/zh/harness/architecture.md | 361 ++++++++++++++++++ docs/zh/harness/filesystem.md | 124 ++++++ docs/zh/harness/memory.md | 152 ++++++++ docs/zh/harness/overview.md | 163 ++++++++ docs/zh/harness/roadmap.md | 24 ++ docs/zh/harness/session.md | 111 ++++++ docs/zh/harness/subagent.md | 115 ++++++ docs/zh/harness/tool.md | 104 +++++ docs/zh/harness/workspace.md | 119 ++++++ docs/zh/intro.md | 1 + 12 files changed, 1418 insertions(+) create mode 100644 agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java create mode 100644 docs/zh/harness/architecture.md create mode 100644 docs/zh/harness/filesystem.md create mode 100644 docs/zh/harness/memory.md create mode 100644 docs/zh/harness/overview.md create mode 100644 docs/zh/harness/roadmap.md create mode 100644 docs/zh/harness/session.md create mode 100644 docs/zh/harness/subagent.md create mode 100644 docs/zh/harness/tool.md create mode 100644 docs/zh/harness/workspace.md diff --git a/.gitignore b/.gitignore index cf60309be..fa64ecd7b 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ logs/ ##agentscope .agentscope/ + +## harness db +**/*.db diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java new file mode 100644 index 000000000..8adfe0dc2 --- /dev/null +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java @@ -0,0 +1,141 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.memory.compaction.CompactionConfig; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Minimal quickstart example for the AgentScope Harness module. + * + *

This example demonstrates the three core values of the harness layer: + * + *

    + *
  • Workspace-driven persona — agent identity comes from {@code AGENTS.md} in the + * workspace and is injected into every reasoning step + *
  • Session persistence — calls sharing the same {@code sessionId} automatically + * resume from the previous state + *
  • Conversation compaction — long histories are summarised in place; on the way, + * useful facts are flushed to a daily memory journal + *
+ * + *

Run

+ * + *
+ * export DASHSCOPE_API_KEY=your_key_here
+ * mvn -pl agentscope-examples/harness-example -am compile \
+ *     org.codehaus.mojo:exec-maven-plugin:3.6.3:java \
+ *     -Dexec.mainClass=io.agentscope.harness.example.QuickstartExample
+ * 
+ * + *

The first run creates {@code .agentscope/workspace/AGENTS.md} under the current working + * directory. Subsequent runs reuse it; remove the workspace folder to start clean. + */ +public class QuickstartExample { + + public static void main(String[] args) throws Exception { + // 1. Workspace: created on first run, reused afterwards + Path workspace = Paths.get(".agentscope/workspace"); + initWorkspaceIfAbsent(workspace); + + // 2. Model + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + System.err.println("Required environment variable DASHSCOPE_API_KEY is not set."); + System.exit(1); + } + Model model = + DashScopeChatModel.builder().apiKey(apiKey).modelName("qwen-max").stream(true) + .build(); + + // 3. HarnessAgent — workspace injection / session persistence / agent tracing are + // enabled by default. Compaction is opt-in and shown here for completeness. + HarnessAgent agent = + HarnessAgent.builder() + .name("quickstart-agent") + .sysPrompt("你是一个帮助用户做笔记的助手。") + .model(model) + .workspace(workspace) + .compaction( + CompactionConfig.builder() + .triggerMessages(30) + .keepMessages(10) + .flushBeforeCompact(true) + .build()) + .build(); + + // 4. Two turns sharing the same RuntimeContext. + // Same sessionId → the second call automatically resumes the first turn's state. + RuntimeContext ctx = + RuntimeContext.builder().sessionId("demo-session").userId("alice").build(); + + Msg turn1 = + agent.call( + Msg.builder() + .role(MsgRole.USER) + .textContent("我叫天宇,今天准备一个关于 ReAct 的技术分享。") + .build(), + ctx) + .block(); + System.out.println("\n[turn1] " + textOf(turn1)); + + Msg turn2 = + agent.call( + Msg.builder() + .role(MsgRole.USER) + .textContent("我叫什么?我今天要干什么?") + .build(), + ctx) + .block(); + System.out.println("\n[turn2] " + textOf(turn2)); + } + + /** + * Creates a minimal {@code AGENTS.md} on the first run. The file defines the agent's persona + * and is automatically injected into the system prompt by {@code WorkspaceContextHook}. + */ + private static void initWorkspaceIfAbsent(Path workspace) throws Exception { + Files.createDirectories(workspace); + Path agentsMd = workspace.resolve("AGENTS.md"); + if (Files.exists(agentsMd)) { + return; + } + Files.writeString( + agentsMd, + """ + # 笔记助手 + + 你是一个帮助用户整理笔记和知识的助手。 + + ## 行为约定 + - 主动记录用户提到的关键事实(姓名、计划、偏好等) + - 回答用简洁中文,必要时给出要点列表 + - 对不确定的内容要主动说明,不要臆造 + """); + } + + private static String textOf(Msg msg) { + return msg != null ? msg.getTextContent() : "(no response)"; + } +} diff --git a/docs/zh/harness/architecture.md b/docs/zh/harness/architecture.md new file mode 100644 index 000000000..9b8be2f4a --- /dev/null +++ b/docs/zh/harness/architecture.md @@ -0,0 +1,361 @@ +# Harness 架构 + +[Overview](./overview.md) 把 harness 的能力按"解决了什么问题"组织。本文换一个视角:把每个组件的**定义、行为、触发时机、协作对象**讲清楚,最后用时序图说明这些组件在一次 `call()` 里如何协同。 + +> 本文聚焦使用者视角的中粒度——讲清"是谁、什么时候、做什么、跟谁协作",不展开调用栈与实现细节;那些放在各子文档([memory](./memory.md)、[workspace](./workspace.md)、[filesystem](./filesystem.md)、[subagent](./subagent.md)、[session](./session.md)、[tool](./tool.md))。 + +## 1. 顶层结构 + +`HarnessAgent` 不是一个新的推理循环,它是 `Agent` + `StateModule` 的薄包装,内部持有一个 `ReActAgent delegate`,所有 `call` / `stream` / `observe` / `saveTo` / `loadFrom` 都转发过去。所有 harness 能力都通过 `ReActAgent` 已有的三个扩展点装配: + +```mermaid +flowchart TD + HA["HarnessAgent
Agent + StateModule,对外 API"] + HA --> SHARED["共享对象"] + HA --> DEL["delegate: ReActAgent"] + + SHARED --> WM["WorkspaceManager
谁来读写工作区"] + SHARED --> AFS["AbstractFilesystem
本地 / 沙箱 / 远端 / 组合"] + SHARED --> RC["RuntimeContext
sessionId / userId / session / extra"] + + DEL --> HK["hooks
按 priority 排序"] + DEL --> TK["toolkit
用户 + harness 内置 + SubagentsHook 注入的 task 工具"] + DEL --> SB["skillBox
AgentSkillRepository 或 workspace/skills/"] + DEL --> MEM["memory
InMemoryMemory(通过 Session 持久化)"] +``` + +**注入发生在 `HarnessAgent.Builder.build()`**:构造完三个共享对象后,按固定顺序串好 hook 列表、向用户 toolkit 追加内置工具、根据工作区/repo 装配 skillBox,最后交给 `ReActAgent.builder()`。 + +每次 `agent.call(msg, ctx)` 开头由 `HarnessAgent.bindRuntimeContext(ctx)` 把当次的 `RuntimeContext` 分发给所有实现了 `RuntimeContextAwareHook` 的 hook(workspace context、memory flush、compaction、session persistence),并按需从 `Session` 自动恢复状态。 + +## 2. 三个共享对象 + +这三个对象是 hook 之间协作的通用语言。理解它们就理解了 harness 的"耦合方式"。 + +### 2.1 RuntimeContext + +当次 `call()` 的身份载体:不持久化,每次 `call` 重新分发给 `RuntimeContextAwareHook`。 + +- **`sessionId`** —— 决定持久化路径、JSONL 文件名 +- **`userId`** —— 透传 `AbstractFilesystem.NamespaceFactory` 实现多租户隔离 +- **`session` + `sessionKey`** —— 显式指定或默认 `WorkspaceSession + SimpleSessionKey.of(sessionId)` +- **`extra`** —— 自定义键值,工具/hook 通过 `ctx.get(key)` 读取 + +### 2.2 WorkspaceManager + +工作区无状态访问器。**两层语义**:读优先 filesystem 命中、否则回退本地;写一律走 filesystem;列表合并去重。期望布局: + +``` +workspace/ +├── AGENTS.md / MEMORY.md +├── memory/YYYY-MM-DD.md / .consolidation_state / archive/ +├── memory_index.db # SQLite FTS5 +├── knowledge/KNOWLEDGE.md / **/* +├── skills//SKILL.md +├── subagents/*.md # YAML front matter + body +└── agents// + ├── context//{key}.json # WorkspaceSession 写入 + └── sessions/.log.jsonl # MemoryFlushManager 卸载 +``` + +### 2.3 AbstractFilesystem + +工作区的物理后端,可插拔。基础接口 `ls/read/write/edit/grep/glob/upload/download`;继承接口 `AbstractSandboxFilesystem` 追加 `execute/id`。 + +| 实现 | 用途 | 关键特性 | +|---|---|---| +| `LocalFilesystem` | 本地磁盘 | `virtualMode` 锚定 `rootDir` 阻止穿越 | +| `LocalFilesystemWithShell` | 本地 + shell | 默认后端;触发 `shell_execute` 工具注册 | +| `BaseSandboxFilesystem` | 沙箱模板 | 把所有 IO 收敛到沙箱 | +| `StoreFilesystem` | KV store | 跨线程持久化;`NamespaceFactory` 读 `userId` 做多租户 | +| `CompositeFilesystem` | 路由 | 按 path prefix 分发;前缀越长越优先 | + +> **多租户机制**:`NamespaceFactory` 是函数式接口,每次操作时被调用读取 `RuntimeContext.userId`;同一个 filesystem 实例在不同 user 间天然路径隔离。 + +## 3. Hook 列表 + +七个 hook,由 `Builder.build()` 装配进 `ReActAgent`。它们按 `priority()` 排序,**值越小越先执行**。 + +| Hook | 优先级 | 监听事件 | 默认开启 | 关键依赖 | +|------|--------|----------|---------|----------| +| `AgentTraceHook` | 0 | 全部 | ✓ | — | +| `MemoryFlushHook` | 5 | `PostCallEvent` | ✓(需 `model`)| `WorkspaceManager`、`Model`、`MemoryFlushManager` | +| `CompactionHook` | 10 | `PreReasoningEvent` | ✗(需显式 `.compaction(...)`)| `WorkspaceManager`、`Model`、`CompactionConfig`、`MemoryFlushManager` | +| `ToolResultEvictionHook` | 50 | `PostActingEvent` | ✗(需显式 `.toolResultEviction(...)`)| `AbstractFilesystem`、`ToolResultEvictionConfig` | +| `SubagentsHook` | 80 | `PreReasoningEvent` + `tools()` | ✓(非 leaf 且有 `model`)| 子 agent 列表、`TaskRepository` | +| `WorkspaceContextHook` | 900 | `PreReasoningEvent` | ✓ | `WorkspaceManager`、`RuntimeContext`、token 预算 | +| `SessionPersistenceHook` | 900 | `PostCallEvent` + `ErrorEvent` | ✓ | `RuntimeContext` | + +> 实现 `RuntimeContextAwareHook` 接口的 hook(workspace context、memory flush、compaction、session persistence)会在每次 `call()` 通过 `bindRuntimeContext` 被重新注入当次的 `RuntimeContext`。 + +下面分组详解每个 hook 在它的事件回调里**做了什么**。 + +### 3.1 上下文注入:`WorkspaceContextHook`(priority 900) + +**作用**:每轮推理前把工作区文件以 `` XML 块合并进第一条 SYSTEM 消息。 + +**触发**:`PreReasoningEvent`。优先级 900 让它跑在压缩、子 agent 之后,叠加在最终 system prompt 上。 + +**关键逻辑**:读 AGENTS / MEMORY / KNOWLEDGE(含目录列表)+ 用户指定的 `additionalContextFiles` → 估 token(chars/4)后按 `maxContextTokens` 预算保留固定区段、剩余给 `MEMORY.md` 并在超额时尾部截断 + 提示 `memory_search`。 + +### 3.2 记忆管理:`MemoryFlushHook` + 后台 + +**作用**:`MemoryFlushHook`(priority 5)在 `PostCallEvent` 把当前 memory 全量交给 `MemoryFlushManager`,做两件事: + +- **flushMemories**:LLM 提炼事实 → append 到 `memory/YYYY-MM-DD.md`(日流水账)→ 增量更新 FTS5 +- **offloadMessages**:原始消息序列写到 `agents//sessions/.log.jsonl` + +整体由四个组件分工: + +| 组件 | 负责 | 频率 | +|---|---|---| +| `MemoryFlushManager` | 第一层:日流水账 + JSONL | 每次 `call()` 末尾 + 每次压缩前 | +| `MemoryConsolidator` | 第二层:curated `MEMORY.md` | 6 小时周期 / opportunistic(30min 节流) | +| `MemoryIndex` | SQLite FTS5 索引 `memory_index.db` | 增量(写入时)+ 全量(维护周期) | +| `MemoryMaintenanceScheduler` | 调度 + 旧文件归档/清理 | 守护线程 6 小时周期 | + +> **双层语义**:日流水账只 append、永不修改;`MEMORY.md` 由 consolidator 整体重写(输出完整新版本,不是 diff)。第一层是事实流,第二层是 curated 视图。与 `CompactionHook` 不重叠:压缩管被压缩的 prefix,本 hook 管保留尾部。 + +### 3.3 上下文长度控制:`CompactionHook` + 溢出兜底 + +**作用**:`CompactionHook`(priority 10)在 `PreReasoningEvent` 委托 `ConversationCompactor.compactIfNeeded` 压缩对话。 + +**触发条件**:消息数 ≥ `triggerMessages` 或 token 数 ≥ `triggerTokens`(默认 50 / 80K)。 + +**触发后**:先 `flushMemories(prefix)` 提炼事实、`offloadMessages(整段)` 卸载 JSONL,再用结构化 prompt(SESSION INTENT / SUMMARY / ARTIFACTS / NEXT STEPS)让 LLM distill 成 summary,得到 `[summaryMsg + tail]` 同时写回 `Memory` 与 `event.setInputMessages`。`tail` 长度由 `keepMessages` / `keepTokens` 控制(默认 20 条)。 + +**溢出兜底**:`HarnessAgent.call()` 捕获模型 `ContextOverflow` 类异常 → `forceCompactAndRetry` 强制最激进压缩 → 重试一次 `delegate.call()`。这是阈值配置不当时的最后防线。 + +### 3.4 工具结果卸载:`ToolResultEvictionHook`(priority 50) + +**作用**:单条工具结果太大时落盘,上下文里只留 head+tail 预览 + 占位符。 + +**触发**:`PostActingEvent`(先于 memory 写入,下游只看到占位符)。 + +**关键逻辑**:超过 `maxResultChars`(默认 80K chars ≈ 20K tokens)→ 写到 `{evictionPath}/{agent}/{toolCallId}` → 用 `Tool output too large, saved to ...` + head 2K + tail 2K 替换。`excludedToolNames`(read/write/edit、grep/glob/ls、memory/session 搜索)跳过卸载——这些工具自带分页或回读会循环。 + +> 与压缩独立:压缩管深度(消息累计长度),卸载管宽度(单条消息长度)。 + +### 3.5 会话持久化:`SessionPersistenceHook` + `WorkspaceSession` + +**作用**:`SessionPersistenceHook`(priority 900)在 `PostCallEvent` 与 `ErrorEvent` 都尝试 `agent.saveTo(session, sessionKey)`(`HarnessAgent` 实现 `StateModule`)。优先级 900 让 `MemoryFlushHook` (5) 先把记忆写完再快照。 + +**`WorkspaceSession`** 是 `JsonSession` 子类,把 baseDir 锁到 `/agents//context/`,最终落盘 `/agents//context//{key}.json`。 + +下次 `call()` 开头 `bindRuntimeContext` 调 `loadIfExists` 还原 memory——这就是"同一 sessionId 跨调用记忆"的来源。 + +### 3.6 子 agent 编排:`SubagentsHook` + `TaskRepository` + +**作用**:`SubagentsHook`(priority 80)双角色——通过 `tools()` 注册 `agent_spawn / agent_send / agent_list / task_output / task_cancel / task_list`,并在 `PreReasoningEvent` 注入子 agent 名+描述列表的 system prompt 段。 + +- **同步路径** `agent_send`:阻塞执行子 agent 并回填结果 +- **后台路径** `agent_spawn`:通过 `TaskRepository.putTask` 提交到 executor 拿 `taskId`;父 agent 后续轮用 `task_output(taskId)` 拉结果 + +**子 agent 来源**(`Builder.buildSubagentEntries`):工作区 `subagents/*.md`(`AgentSpecLoader` 解析)/ 编程式 `.subagent(spec)` / 自定义 `.subagentFactory`。每个子 agent 默认是个 leaf `HarnessAgent`(共享父 agent 的 workspace/filesystem/model 但不再装 `SubagentsHook`)。 + +**`TaskRepository`** 是任务编排接口(`putTask` / `getTask` / `listTasks(filter)` / `cancelTask`);默认 `DefaultTaskRepository` 内部用线程池 + `CompletableFuture` + `BackgroundTask` 包装状态机(PENDING/RUNNING/COMPLETED/FAILED/CANCELLED)。 + +### 3.7 追踪日志:`AgentTraceHook`(priority 0) + +监听全部事件,输出 `[] PRE_REASONING | model=..., messages=...` 风格 INFO 日志(DEBUG 打详细内容);不修改事件。 + +## 4. `call()` 生命周期时序 + +下图展示一次完整 `agent.call(msg, ctx)` 中各组件的协作顺序。**hook 在同一事件上按 priority 升序触发**——这就是它们能彼此叠加而不打架的原因。 + +```mermaid +sequenceDiagram + autonumber + actor User + participant HA as HarnessAgent + participant RA as delegate
(ReActAgent) + participant H as Hooks
(按 priority) + participant M as Model + participant T as Toolkit + participant FS as Filesystem
+ Memory/JSONL + + User->>HA: call(msg, ctx) + HA->>HA: bindRuntimeContext(ctx) + Note over HA: 分发给 RuntimeContextAwareHook
loadIfExists(session, key) 恢复状态 + HA->>RA: delegate.call(...) + + RA->>H: PreCallEvent + Note over H: AgentTraceHook(0) 记日志 + + loop ReAct 推理循环 + RA->>H: PreReasoningEvent + Note over H,FS: CompactionHook(10) 阈值达到则:
① flushMemories(prefix) → memory/*.md
② offload(整段) → sessions/*.jsonl
③ LLM distill prefix → summaryMsg
④ memory.clear() + add(summary + tail)
⑤ event.setInputMessages(...)

SubagentsHook(80) 注入子 agent prompt
WorkspaceContextHook(900) 注入 workspace 文件 + RA->>M: Model.stream(messages) + M-->>RA: ChatResponse + RA->>H: PostReasoningEvent + Note over H: AgentTraceHook(0) 记 text 或 tool_calls + + alt 含 tool_calls + loop 每个 tool_call + RA->>H: PreActingEvent + RA->>T: Toolkit.invoke(toolCall) + T-->>RA: ToolResult + RA->>H: PostActingEvent + Note over H,FS: ToolResultEvictionHook(50) 超阈值则:
① 写到 filesystem evictionPath
② head+tail 占位符替换 result + end + else 无 tool_call (文本响应) + Note over RA: 跳出循环 + end + end + + RA->>H: PostCallEvent + Note over H,FS: MemoryFlushHook(5):
① flushMemories → memory/YYYY-MM-DD.md
② offloadMessages → sessions/*.jsonl
③ requestConsolidation 通知后台

SessionPersistenceHook(900) saveTo(session, key) + RA-->>HA: final Msg + HA-->>User: final Msg + + Note over HA: 失败路径: throw → ErrorEvent → SessionPersistenceHook 仍然 saveTo
ContextOverflow → forceCompactAndRetry → delegate.call 重试 +``` + +## 5. 后台维护时序 + +`MemoryMaintenanceScheduler.start()` 在 `Builder.build()` 末尾被触发;它持有一个守护线程的 `ScheduledExecutorService`。 + +```mermaid +flowchart LR + subgraph CYCLE["周期触发(默认每 6 小时)"] + direction TB + T0["runMaintenance()"] --> S1["1. expireDailyFiles
memory/*.md 文件名 YYYY-MM-DD
且 < cutoff(默认 90 天)
→ archive/"] + S1 --> S2["2. consolidateMemory
读 .consolidation_state 水位
列出 mtime > 水位的日文件
LLM 合并 → 覆盖 MEMORY.md → 推进水位"] + S2 --> S3["3. pruneOldSessions
workspace/agents/<id>/sessions/*
mtime < cutoff(默认 180 天)的非 sessions.json 删除"] + S3 --> S4["4. reindex
MemoryIndex.indexAllFromWorkspace
DELETE + INSERT 重建 FTS5"] + end + + subgraph OPP["opportunistic 路径"] + direction TB + F["MemoryFlushManager.flushMemories()
每次 flush 成功"] --> R["scheduler.requestConsolidation()"] + R -- "距上次 < 30min" --> SK["跳过"] + R -- "否则" --> SUB["submit consolidateMemory
(走 executor,不阻塞 agent)"] + end +``` + +## 6. 几个典型协作场景 + +最后用四个具体路径把组件串起来,看它们是怎么真正协作的。 + +### 场景 A — 工作区文件变成模型看到的 system prompt + +```mermaid +sequenceDiagram + participant RA as ReActAgent + participant Hook as WorkspaceContextHook
(priority 900) + participant WM as WorkspaceManager + participant FS as AbstractFilesystem + participant LD as 本地磁盘 + participant M as Model + + RA->>Hook: PreReasoningEvent(messages) + Note over WM: readAgentsMd / readMemoryMd / readKnowledgeMd + Hook->>WM: 读取工作区文件 + WM->>FS: read(...) 优先 + alt FS 命中非空 + FS-->>WM: 内容(多租户透明) + else 否则 + WM->>LD: Files.readString(workspace/AGENTS.md) + LD-->>WM: 内容(兜底) + end + WM-->>Hook: AGENTS / MEMORY / KNOWLEDGE / extra + Note over Hook: 包入 loaded_context XML 块
合并到第一条 SYSTEM 消息
event.setInputMessages(...) + Hook-->>RA: 返回修改后的 event(含新 messages) + RA->>M: Model.stream(messages) +``` + +### 场景 B — 长会话里事实如何沉淀进 `MEMORY.md` + +```mermaid +flowchart TD + A["对话累积 → 触发 CompactionHook 阈值"] --> B["ConversationCompactor.compactIfNeeded"] + B --> C["MemoryFlushManager
.flushMemories(prefix)"] + B --> D["offloadMessages
→ sessions/<sessionId>.log.jsonl"] + B --> E["distill summary
→ 替换 memory + setInputMessages"] + + C --> C1["memory/YYYY-MM-DD.md (append)"] + C --> C2["MemoryIndex.indexFromString
(FTS5 增量)"] + C --> C3["scheduler.requestConsolidation"] + + C3 -- "throttle 30min" --> C4["submit consolidateMemory"] + C4 --> C5["MemoryConsolidator + LLM"] + C5 --> C6["覆盖 MEMORY.md"] + C6 --> C7["下一次 reindex 反映到 FTS5"] + + C7 --> NEXT["下一次 call"] + NEXT --> N1["WorkspaceContextHook 读 MEMORY.md
→ 注入 system prompt"] + NEXT --> N2["memory_search 工具走 FTS5
查得旧事实"] +``` + +### 场景 C — 第二轮 `call` 如何"想起"第一轮 + +```mermaid +flowchart LR + subgraph T1["turn 1"] + direction TB + T1A["call(msg1, ctx{sess=A})"] --> T1B["bindRuntimeContext"] + T1B --> T1C["ReAct 循环"] + T1C --> T1D["PostCallEvent"] + T1D --> T1E["MemoryFlushHook
flush + offload"] + T1D --> T1F["SessionPersistenceHook
saveTo(session, key)
→ 写盘"] + end + + subgraph T2["turn 2"] + direction TB + T2A["call(msg2, ctx{sess=A})"] --> T2B["bindRuntimeContext"] + T2B --> T2B1["loadIfExists
读 context/A/{key}.json
memory 恢复 turn1 对话"] + T2B1 --> T2C["ReAct 循环
(内存已含 turn1)"] + T2C --> T2D["PostCallEvent"] + T2D --> T2E["..."] + T2D --> T2F["SessionPersistenceHook
saveTo (覆盖) → 写盘"] + end + + T1F -. 持久化到磁盘 .-> T2B1 +``` + +### 场景 D — 子 agent 的同步与后台两条委派路径 + +```mermaid +sequenceDiagram + participant Parent as 父 agent + participant Hook as SubagentsHook + participant Sub as 子 HarnessAgent (leaf) + participant Repo as TaskRepository + participant Exec as Executor + + Note over Parent: reasoning 选了 SubagentsHook 注入的工具 + + rect rgb(238, 248, 255) + Note over Parent,Sub: 同步路径 + Parent->>Hook: agent_send(name, message) + Hook->>Sub: factory.create() + Hook->>Sub: sub.call(msg).block() + Sub-->>Hook: reply + Hook-->>Parent: ToolResultBlock(reply) + end + + rect rgb(255, 245, 238) + Note over Parent,Exec: 后台路径 + Parent->>Hook: agent_spawn(name, message) + Hook->>Repo: putTask(id, name, supplier) + Repo->>Exec: submit(supplier) + Repo-->>Hook: taskId + Hook-->>Parent: ToolResultBlock(taskId) + + Note over Parent: 父 agent 后续轮 + Parent->>Hook: task_output(taskId) + Hook->>Repo: getTask(taskId).getResult() + Repo-->>Hook: result / null + Hook-->>Parent: ToolResultBlock(result/状态) + end +``` + +## 延伸阅读 + +- [Workspace](./workspace.md) — 工作区目录结构、`WorkspaceManager` 两层读取细节 +- [Memory](./memory.md) — 双层记忆模型、压缩配置、FTS5 检索、消息格式细节 +- [Filesystem](./filesystem.md) — `AbstractFilesystem` 各实现的取舍与组合方式 +- [Subagent](./subagent.md) — 子 agent 规格格式、`TaskRepository` 自定义、嵌套 harness 的注意事项 +- [Session](./session.md) — `WorkspaceSession` / `JsonSession` 的序列化协议与版本兼容 +- [Tool](./tool.md) — 内置工具参考与自定义工具的注册方式 +- [Roadmap](./roadmap.md) — 已识别的设计权衡与待改进项 diff --git a/docs/zh/harness/filesystem.md b/docs/zh/harness/filesystem.md new file mode 100644 index 000000000..23a2e1824 --- /dev/null +++ b/docs/zh/harness/filesystem.md @@ -0,0 +1,124 @@ +# 文件系统(Filesystem) + +## 作用 + +把 agent 可见的文件操作从“本地磁盘”中抽象出来,提供统一的 `ls / read / write / edit / grep / glob / upload / download` 接口;在沙箱场景下额外打开 `execute` 能力。同一份上层逻辑(`WorkspaceManager`、`FilesystemTool`、`ShellExecuteTool`)可以在本地、远程沙箱、内存 KV 之间透明切换。 + +## 触发 + +| 时机 | 动作 | +|------|------| +| `HarnessAgent.build()` | 未显式设 `abstractFilesystem` 时默认创建 `LocalFilesystemWithShell(workspace)` | +| `WorkspaceManager` 读写 | `readWithOverride` 优先走 filesystem;append / upload 全走 filesystem | +| Tool 调用 | `FilesystemTool` 直接调用;`ShellExecuteTool` 仅在后端是 `AbstractSandboxFilesystem` 时注册 | +| `WorkspaceContextHook` | 调 `RuntimeContextAwareHook.setRuntimeContext()` 后,namespaceFactory 读到的 `userId` 就是当前请求的租户 | + +## 关键逻辑 + +### 两层接口 + +```mermaid +classDiagram + class AbstractFilesystem { + <> + ls/read/write/edit + grep/glob + uploadFiles/downloadFiles + } + class AbstractSandboxFilesystem { + <> + +id() String + +execute(cmd, timeout) + } + AbstractSandboxFilesystem --|> AbstractFilesystem + + class LocalFilesystem + class LocalFilesystemWithShell + class BaseSandboxFilesystem + class StoreFilesystem + class CompositeFilesystem + + LocalFilesystem ..|> AbstractFilesystem + StoreFilesystem ..|> AbstractFilesystem + LocalFilesystemWithShell --|> LocalFilesystem + LocalFilesystemWithShell ..|> AbstractSandboxFilesystem + BaseSandboxFilesystem ..|> AbstractSandboxFilesystem + CompositeFilesystem ..|> AbstractSandboxFilesystem +``` + +- `AbstractFilesystem` 是最小接口;带 shell 执行的后端额外实现 `AbstractSandboxFilesystem`,HarnessAgent 据此决定是否注册 `ShellExecuteTool`。 +- `read(filePath, offset, limit)` 中 `limit <= 0` 意味默认(本地后端读全文,sandbox 后端读到 `Integer.MAX_VALUE` 行)。 + +### 后端入门定位 + +| 后端 | 适用场景 | 关键参数 / 限制 | +|------|---------|-----------------| +| `LocalFilesystem` | 只需读写本地,不要 shell | `(rootDir, virtualMode, maxFileSizeMb, namespaceFactory)`;`virtualMode=true` 时锁定在 `rootDir` 内 | +| `LocalFilesystemWithShell` | **HarnessAgent 默认**;本地读写 + `sh -c` | `(rootDir, virtualMode, timeout, maxOutputBytes, env, inheritEnv, namespaceFactory)`;**不受限制执行**,仅限受信任的本地/CI | +| `BaseSandboxFilesystem` | 远程沙箱 / 容器后端的实现基类 | 只需覆盖 `id / execute / uploadFiles / downloadFiles`,`ls/read/grep/glob` 默认走远程 Unix 命令 | +| `StoreFilesystem` | 基于 `BaseStore` 的 KV,多租户 / 跨线程共享 | 静态 namespace 或 `NamespaceFactory`;不提供 shell | +| `CompositeFilesystem` | 按路径前缀路由多个后端 | 最长前缀优先匹配;`isSandbox()` 仅当 default backend 实现 sandbox 接口时为 true | + +### `BaseSandboxFilesystem` 的取巧 + +实现者只需交付 `execute / uploadFiles / downloadFiles / id`,`ls / read / grep / glob / edit / write` 都会被默认实现转为远程 shell 命令: + +- `ls` → `for f in /*; do ... done` +- `read` → `sed -n 'a,bp' `(二进制文件走 `base64`) +- `grep` → `grep -rHnF` +- `glob` → `find -type f -name ` +- `edit` → 补下 base64-encoded `python3` 脚本做字符串替换 +- `write` → 先 `[ -e ]` 检查存在性,再 `uploadFiles` + +意义:只要沙箱环境有标准 Unix 工具链 + Python3,集成代价几乎为零。 + +### `NamespaceFactory`—多租户透明隔离 + +```java +@FunctionalInterface +public interface NamespaceFactory { List getNamespace(); } +``` + +- **每次文件操作都调用**一次,返回当前请求的路径段 tuple(例如 `["users", "alice"]`)。 +- `LocalFilesystem` / `LocalFilesystemWithShell` / `BaseSandboxFilesystem` / `StoreFilesystem` 都能接受;上层逻辑对路径无感。 +- 典型用法:结合 `RuntimeContext.userId` 动态生成。 + +```java +AtomicReference currentUserId = new AtomicReference<>("default"); +NamespaceFactory ns = () -> List.of("users", currentUserId.get()); + +LocalFilesystemWithShell fs = new LocalFilesystemWithShell(workspace, ns); +// agent.call() 前更新 currentUserId,所有文件操作自动落在 workspace/users//... +``` + +## 配置 + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("MyAgent") + .model(model) + .workspace(workspace) + .abstractFilesystem(myFilesystem) // 不传默认为 LocalFilesystemWithShell(workspace) + .build(); +``` + +几个常见组合: + +```java +// 1. 本地开发(默认) +new LocalFilesystemWithShell(workspace); + +// 2. 不要 shell 的只读写场景 +new LocalFilesystem(workspace, /*virtualMode=*/ true, /*maxFileSizeMb=*/ 10); + +// 3. 本地 + 远程记忆库组合 +new CompositeFilesystem( + new LocalFilesystemWithShell(workspace), + Map.of("/memories/", new StoreFilesystem(redisStore, ns))); +``` + +## 相关文档 + +- [工具](./tool.md) — `FilesystemTool` / `ShellExecuteTool` 的入参 +- [工作区](./workspace.md) — `WorkspaceManager` 上层怎么利用文件系统走两层读 +- [架构](./architecture.md) — `ShellExecuteTool` 注册条件在哪里检查 diff --git a/docs/zh/harness/memory.md b/docs/zh/harness/memory.md new file mode 100644 index 000000000..82bd16cf5 --- /dev/null +++ b/docs/zh/harness/memory.md @@ -0,0 +1,152 @@ +# 记忆(Memory) + +## 作用 + +让 agent 能“记住跨会话的事实”,同时避免对话上下文无限增长。harness 把记忆拆成两层:高频低质量的“流水账” + 低频高质量的“策划后长期记忆”,并补上一套 FTS5 检索 + 后台维护。 + +## 触发 + +| 时机 | 动作 | +|------|------| +| 推理前(`PreReasoningEvent`)| `CompactionHook` 检查对话阈值;超阈则调 `ConversationCompactor` | +| `call()` 结束(`PostCallEvent`)| `MemoryFlushHook` 调 `MemoryFlushManager` 提取记忆 + offload | +| 上下文溢出(`ContextLengthExceeded`)| `HarnessAgent.forceCompactAndRetry` 以 `triggerMessages=1` 强制压缩并重试 | +| 工具返回超大(`PostActingEvent`)| `ToolResultEvictionHook` 卸载到 filesystem | +| 后台调度 | `MemoryMaintenanceScheduler` 默认每 6h 跑一轮;flush 后会“机会主义”传一个信号(30 分钟级节流) | + +## 关键逻辑 + +### 双层记忆模型 + +```mermaid +flowchart LR + Conv[对话 messages] -->|超阈值| Compactor[ConversationCompactor] + Compactor -->|offload| Sess[sessions/<id>.log.jsonl] + Compactor -->|flushMemories| Flush[MemoryFlushManager] + Flush -->|append + index| Daily[memory/YYYY-MM-DD.md] + Daily -. 后台二次加工 .-> Cons[MemoryConsolidator] + MEM[MEMORY.md作为上下文] -->|读取去重| Cons + Cons -->|重写| MEM + MEM -->|每次推理注入| Hook[WorkspaceContextHook] + Daily -.不直接注入.- Hook + Daily --> Idx[(MemoryIndex
SQLite FTS5)] + MEM --> Idx +``` + +- **第一层·流水账 `memory/YYYY-MM-DD.md`**:`MemoryFlushManager` 专属,**只追加**,不去重;是“刚刚在说什么”的原始记录。 +- **第二层·策划后长期记忆 `MEMORY.md`**:`MemoryConsolidator` 专属,**整体重写**;MemoryFlushManager 不会去动它。每次推理都走 `WorkspaceContextHook` 注入到 system prompt。 +- **索引 `MemoryIndex`**:启动时 `indexAllFromWorkspace` 一次;每次 flush 写今日流水账后增量重建该文件索引;SQLite 文件位于 `/memory_index.db`。 + +### 对话压缩(`ConversationCompactor`) + +``` +检查阈值 → 找 cutoff(不切开 ASSISTANT/TOOL 对) + → (可选) flushMemories(prefix) + → (可选) offloadMessages(messages → sessions/.../.jsonl) + → LLM 提炼 summary + → [summaryUserMsg] + tail 返回给 hook重装 memory +``` + +默认值(全部可调): + +| 参数 | 默认 | 说明 | +|------|------|------| +| `triggerMessages` | `50` | 按条数触发(`0` = 关闭) | +| `triggerTokens` | `80_000` | 按 token 估算触发(`0` = 关闭) | +| `keepMessages` | `20` | 保留尾部条数 | +| `keepTokens` | `0` | 非 0 时按 token 预算从后往前扫描,覆盖 `keepMessages` | +| `flushBeforeCompact` | **`true`** | 压缩前提取记忆到今日流水账 | +| `offloadBeforeCompact` | **`true`** | 压缩前将原始消息追写到会话 `.log.jsonl` | +| `summaryPrompt` | 内置模板 | 包含 `SESSION INTENT / SUMMARY / ARTIFACTS / NEXT STEPS` 四段式 | + +```java +CompactionConfig.builder() + .triggerMessages(30) + .keepMessages(10) + .build(); // flush/offload 默认都是 true +``` + +#### `TruncateArgsConfig`—轻量预处理(可选) + +在 LLM 摘要之前,可以先走一个**不走 LLM** 的干预:对老消息里不那么重要的 `ToolUseBlock` 参数做字符串截断(默认阈值 25 条 / 40k tokens,参数超 2000 字符被裁揉)。适合 `write_file` 这种入参体量大、后期不需要原貌的场景。 + +```java +CompactionConfig.builder() + .triggerMessages(80) + .truncateArgs(TruncateArgsConfig.builder().build()) + .build(); +``` + +#### 上下文溢出自动恢复 + +当模型返回 `context_length_exceeded` / `maximum context` 之类错误,`HarnessAgent.recoverFromOverflow` → `forceCompactAndRetry` 会拼一个临时 `triggerMessages=1` 的 `CompactionConfig` 走一轮压缩,清空 `Memory` 后重试;**前提是配置了 `compaction(...)`**,否则直接抛错。 + +### 记忆提取(`MemoryFlushManager`) + +- `flushMemories(messages)`:拿当前 `MEMORY.md` 和今日流水账作为“去重参考”丢给 LLM,要求输出 **仅新增的** bullet;“NO_REPLY” 表示什么都不写。 +- 写入位置固定是 `memory/YYYY-MM-DD.md`,**不会动 `MEMORY.md`**(以防二层被一层覆写)。 +- 写完后立刻 `indexFromString` 重建该文件索引,并调 `MemoryMaintenanceScheduler.requestConsolidation()` 提示“能合并了合并下”。 + +### 二次合并(`MemoryConsolidator`) + +- 读 mtime 超过 watermark 的日流水账 + 当前 `MEMORY.md`,调 LLM 合并、去重、裁剪。 +- 输出限制:默认 `maxMemoryTokens=4000`(约 16k 字符),prompt 会以字符预算的形式告诉 LLM。 +- 写后推进 watermark,存于 `memory/.consolidation_state`;下次只看 mtime 超 watermark 的日文件。 +- 合并仅在后台 executor 跳:定期 tick 或 `requestConsolidation()` 发起,永不阻塞推理循环。 + +### 后台维护(`MemoryMaintenanceScheduler`) + +`HarnessAgent.build()` 中自动创建并 `start()`,每个 tick 顺序跑: + +1. `expireDailyFiles` — 超过 `dailyFileRetentionDays` 的日文件归档到 `memory/archive/`(**默认 90 天**) +2. `consolidateMemory` — 调 `MemoryConsolidator.consolidate()` +3. `pruneOldSessions` — 删除 mtime 超 `sessionRetentionDays` 的会话文件(**默认 180 天**) +4. `reindex` — `MemoryIndex.indexAllFromWorkspace` + +默认间隔 `Duration.ofHours(6)`;opportunistic 调用实际节流间隔 30 分钟,避免频繁 flush 打爆 LLM。 + +### 工具结果卸载(`ToolResultEvictionConfig`) + +与压缩独立。某次 `tool_call` 返回的文本超过阈值时,全文写到 `evictionPath` 下的文件,原位置只留一个“首尾预览 + 路径”的占位符,agent 需要完整内容时走 `read_file`。 + +| 参数 | 默认 | 说明 | +|------|------|------| +| `maxResultChars` | `80_000` | 超过则卸载 | +| `previewChars` | `2_000` | 首尾预览字符数 | +| `evictionPath` | `/large_tool_results` | 卸载文件根路径 | +| `excludedToolNames` | 内置集(含 `read_file` 等) | 不参与卸载的工具 | + +```java +HarnessAgent.builder() + ... + .toolResultEviction(ToolResultEvictionConfig.defaults()) + .build(); +``` + +## 配置与代码示例 + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("MyAgent") + .model(model) + .workspace(workspace) + .compaction(CompactionConfig.builder() + .triggerMessages(30) + .keepMessages(10) + .build()) + .toolResultEviction(ToolResultEvictionConfig.defaults()) + .build(); + +// agent 可随时调用 memory_search +MemoryIndex index = new MemoryIndex(workspaceAgentScopeDir); +index.open(); +List hits = index.search("数据库迁移", 10); +// hit: { path, lineNumber, content, rank } +``` + +## 相关文档 + +- [工具](./tool.md) — `memory_search` / `memory_get` 的参数与调用例 +- [工作区](./workspace.md) — `MEMORY.md` / `memory/*.md` 在工作区的位置 +- [会话](./session.md) — `.log.jsonl` / `.jsonl` 怎么反过来被记忆提取使用 +- [架构](./architecture.md) — CompactionHook / MemoryFlushHook / ToolResultEvictionHook 在生命周期中的位置 diff --git a/docs/zh/harness/overview.md b/docs/zh/harness/overview.md new file mode 100644 index 000000000..d7706ee6e --- /dev/null +++ b/docs/zh/harness/overview.md @@ -0,0 +1,163 @@ +# Harness 概览 + +`agentscope-harness` 在 `agentscope-core` 的 `ReActAgent` 之上,通过 Hook 和 Toolkit 两个扩展点,装配出一套面向**长期稳定运行**的工程化基础设施。用户入口只有一个类:`HarnessAgent`。 + +裸的 `ReActAgent` 只有"请求-推理-工具-回复"一轮循环。harness 要回答的是另一组问题:**下一轮怎么办、下一天怎么办、上下文爆了怎么办、状态丢了怎么办、任务太重怎么办**。它不替换推理循环,而是在循环的关键时机插入 hook、为模型补上一组基础工具,把这些问题的默认工程答案打包好。 + +## 快速开始 + +引入依赖: + +```xml + + io.agentscope + agentscope-harness + ${agentscope.version} + +``` + +下面这个示例演示 harness 的三个核心价值:**工作区驱动的人格**、**会话持久化**(同一 `sessionId` 的第二轮对话能记得第一轮的内容)、**显式启用对话压缩**。第一次运行时会在 `${cwd}/.agentscope/workspace/` 自动生成 `AGENTS.md`,之后的运行复用。 + +```java +public class QuickstartExample { + + public static void main(String[] args) throws Exception { + // 1. 准备工作区:第一次运行生成 AGENTS.md,后续运行复用 + Path workspace = Paths.get(".agentscope/workspace"); + initWorkspaceIfAbsent(workspace); + + // 2. 构建模型 + Model model = DashScopeChatModel.builder() + .apiKey(System.getenv("DASHSCOPE_API_KEY")) + .modelName("qwen-max") + .stream(true) + .build(); + + // 3. 构建 HarnessAgent:工作区注入、会话持久化、追踪日志默认开启; + // 这里显式启用对话压缩 + HarnessAgent agent = HarnessAgent.builder() + .name("quickstart-agent") + .sysPrompt("你是一个帮助用户做笔记的助手。") + .model(model) + .workspace(workspace) + .compaction(CompactionConfig.builder() + .triggerMessages(30) + .keepMessages(10) + .flushBeforeCompact(true) // 压缩前把事实提取到日流水账 + .build()) + .build(); + + // 4. 同一个 RuntimeContext 发起两轮对话 + // sessionId 相同 → 第二轮自动从 Session 恢复第一轮的状态 + RuntimeContext ctx = RuntimeContext.builder() + .sessionId("demo-session") + .userId("alice") + .build(); + + Msg turn1 = agent.call( + Msg.builder().role(MsgRole.USER) + .textContent("我叫天宇,今天准备一个关于 ReAct 的技术分享。") + .build(), + ctx).block(); + System.out.println("[turn1] " + turn1.getTextContent()); + + Msg turn2 = agent.call( + Msg.builder().role(MsgRole.USER) + .textContent("我叫什么?我今天要干什么?") + .build(), + ctx).block(); + System.out.println("[turn2] " + turn2.getTextContent()); + } + + private static void initWorkspaceIfAbsent(Path workspace) throws Exception { + Files.createDirectories(workspace); + Path agentsMd = workspace.resolve("AGENTS.md"); + if (Files.exists(agentsMd)) return; + Files.writeString(agentsMd, """ + # 笔记助手 + + 你是一个帮助用户整理笔记和知识的助手。 + + ## 行为约定 + - 主动记录用户提到的关键事实(姓名、计划、偏好等) + - 回答用简洁中文,必要时给出要点列表 + - 对不确定的内容要主动说明,不要臆造 + """); + } +} +``` + +完整可运行版本:[`agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java`](../../../agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java) + +运行: + +```bash +export DASHSCOPE_API_KEY=your_key_here + +# 首次运行需要把依赖模块 install 到本地仓库(跳过 javadoc 与 spotless) +mvn -pl agentscope-examples/harness-example -am install \ + -DskipTests -Dspotless.check.skip=true -Dmaven.javadoc.skip=true -q + +# 执行 main +mvn -pl agentscope-examples/harness-example exec:java \ + -Dexec.mainClass=io.agentscope.harness.example.QuickstartExample \ + -Dspotless.check.skip=true -q +``` + +**运行后观察**: + +- `.agentscope/workspace/AGENTS.md` 被自动创建 —— 这就是 agent 的人格来源 +- 第二轮提问"我叫什么"能答出来,因为同一 `sessionId=demo-session` 的第二次 `call()` 在开头通过 `bindRuntimeContext` 自动从 `Session` 加载了第一轮的状态 +- 多聊几轮触发压缩(消息数 ≥ 30)后,可以在 `workspace/memory/YYYY-MM-DD.md` 看到 LLM 提炼出来的事实流水账;后台的 `MemoryMaintenanceScheduler` 会继续把它合并到 `MEMORY.md` +- 下次重启进程、只要 `sessionId` 不变,agent 依然记得这一切 + +**关于 `RuntimeContext`**:它是当次 `call()` 的身份载体,`sessionId` 决定状态存放与日志归档位置,`userId` 决定默认文件系统的命名空间(天然的多租户隔离)。它**不会被持久化**,只在当次调用的 hook 与工具间共享。 + +**扩展方向**:在工作区里放 `KNOWLEDGE.md`、`skills/*/SKILL.md`、`subagents/*.md` 就能分别开启领域知识注入、技能加载、子 agent 编排;`.toolResultEviction(ToolResultEvictionConfig.defaults())` 一行启用大结果卸载;`.abstractFilesystem(...)` 替换成沙箱实现即可把 agent 放进容器。 + +## 核心能力 + +每一项能力对应**一个问题 → 一个组件**: + +- **工作区上下文注入** —— 解决 *agent 的身份从哪里来*。每次推理前由 `WorkspaceContextHook` 把 `AGENTS.md`、`MEMORY.md`、今日记忆、`KNOWLEDGE.md` 注入 system prompt。工作区即 agent 的"人格与知识库"。 +- **双层持久记忆** —— 解决 *对话里的事实如何跨会话沉淀*。`MemoryFlushHook` 在压缩前用 LLM 把对话提炼到日流水账;`MemoryConsolidator` 在后台把日流水账合并去重到长期 `MEMORY.md`。下次上线仍然能用。 +- **对话压缩与溢出恢复** —— 解决 *历史太长怎么办*。`CompactionHook` 在消息/Token 超阈值时摘要历史、保留尾部;模型真的报 context overflow 时,`HarnessAgent` 捕获错误、强制压缩、自动重试。 +- **大工具结果卸载** —— 解决 *单次工具返回过大*。`ToolResultEvictionHook` 把超限结果落盘到文件系统,上下文里只留占位符 + 预览,agent 可以按需回读。 +- **会话持久化** —— 解决 *状态如何跨进程保留*。`SessionPersistenceHook` 按 `sessionId` 把 agent 状态写入工作区,下次调用自动从断点恢复。 +- **子 agent 编排** —— 解决 *复杂任务如何分解*。`SubagentsHook` 注入 `task` / `task_output` 工具,主 agent 可同步或后台委派子 agent;子 agent 可由工作区规格文件、编程式 spec、自定义工厂声明。 +- **可插拔文件系统** —— 解决 *agent 的环境如何收敛与隔离*。所有文件工具都走 `AbstractFilesystem`,可替换为本地、沙箱、远端或组合后端;配合 `RuntimeContext.userId` 得到天然的多租户命名空间。 + +此外还有几项围绕以上能力服务的基础设施:`RuntimeContext` 贯穿整次调用、`MemoryMaintenanceScheduler` 在后台做合并与索引维护、`AgentTraceHook` 统一追踪日志、`AgentSkillRepository` 自动装配 `SkillBox`。 + +## 能力如何共同构成一个稳定运行的 Agent + +把这些能力合起来看,它们其实分别支撑着"持续稳定"的三根支柱: + +- **身份持续** —— *工作区上下文注入* 每轮把人格和知识重新喂给模型;*双层持久记忆* 把对话里有价值的事实沉淀回工作区;*Skill 自动加载* 让可复用能力跟着工作区走。于是 agent 的人格和知识不随单次调用结束而消失,而是在工作区里不断累积。 +- **上下文可控** —— *对话压缩* 控制深度,*工具结果卸载* 控制宽度,*溢出恢复* 是最后一道兜底。三者合在一起保证在任意长度的会话里,上下文都不会把模型压垮;真的压垮了,也能无感恢复。 +- **状态可恢复** —— *会话持久化* 保证进程重启能从断点继续;*RuntimeContext* 把当次调用的身份(sessionId/userId)贯穿到所有 hook 和工具;*可插拔文件系统* 让"状态究竟落在哪里"(本地磁盘、沙箱、远端)变成一个配置选择。 + +这三根支柱之间靠三个共享对象串起来:`WorkspaceManager`(谁来读写工作区)、`AbstractFilesystem`(工作区落在哪里)、`RuntimeContext`(当次调用是谁在说话)。每个 hook 只做自己的事,通过这三个对象和其它 hook 协作——这就是 harness 把一组独立能力合成一个"持续稳定 agent"的方式。 + +## 能力如何注入到 Agent + +`HarnessAgent` 是 `Agent` + `StateModule` 的薄包装,内部持有一个 `ReActAgent delegate`,能力注入全部发生在 `HarnessAgent.Builder.build()`: + +- **Hook 通道**:按固定顺序把 `WorkspaceContextHook`、`MemoryFlushHook`、`CompactionHook`、`ToolResultEvictionHook`、`SessionPersistenceHook`、`SubagentsHook`、`AgentTraceHook` 串成 hook 列表交给 `ReActAgent` +- **Toolkit 通道**:在用户 `Toolkit` 上追加 `filesystem`、`memory_search`、`memory_get`、`session_search`,沙箱后端额外加 `shell_execute`;`SubagentsHook` 自己注册 `task` / `task_output` +- **SkillBox 通道**:从 `workspace/skills/` 或自定义 `AgentSkillRepository` 自动构造 `SkillBox` + +每次 `call()` 开头由 `bindRuntimeContext` 把当次的 `RuntimeContext` 分发给所有实现了 `RuntimeContextAwareHook` 的 hook,并按需从 `Session` 恢复状态。 + +> 各组件的详细行为、触发时机和时序图见 [Architecture](./architecture.md)。 + +## 延伸阅读 + +- [Architecture](./architecture.md) — 各组件定义、生命周期时序图、协作关系 +- [工作区(Workspace)](./workspace.md) — 工作区目录结构与上下文注入 +- [记忆(Memory)](./memory.md) — 双层记忆、对话压缩与全文检索 +- [文件系统(Filesystem)](./filesystem.md) — `AbstractFilesystem` 及其实现 +- [子 Agent(Subagent)](./subagent.md) — 子 agent 规格与编排 +- [工具(Tool)](./tool.md) — 内置工具参考 +- [会话(Session)](./session.md) — 会话持久化与状态恢复 +- [Roadmap](./roadmap.md) — 已识别的待改进项 diff --git a/docs/zh/harness/roadmap.md b/docs/zh/harness/roadmap.md new file mode 100644 index 000000000..c51c2691a --- /dev/null +++ b/docs/zh/harness/roadmap.md @@ -0,0 +1,24 @@ +# roadmap (暂定) + + +## examples + +1. claw类型的应用 + +## enhance + +1. harness的大部分的机制和能力都是通过hook机制来注入的, 用户插入的hook可能会破坏我们默认的hook执行顺序,队列需要分级, 分为internal和external, 前者的优先级高于后者, 用户的hook默认是在external队列中, 另外提供接口来注入到internal队列中, 将两边隔离 +2. 对于harness的构建方法, 支持直接将agent传入, 这样用户能复用过去的reactAgent的代码, 避免重复配置, 最小成本化升级 +3. 和core那边的统一化, 避免用户迷惑 + +## feature + +1. 按照生命周期/作用范围/权限/内部机制等来分类记忆类型, 而不是根据业务语义来分类 +2. 网关层的构建, 需不需要放在harness层, 如何以灵活的方式让agent能根据skill来自己将某个IM挂载到agent上 +3. agent请求human进行review的callback function入口 + + +## robustness + +1. 补齐UT +2. refactor Result类 \ No newline at end of file diff --git a/docs/zh/harness/session.md b/docs/zh/harness/session.md new file mode 100644 index 000000000..6f8900e4f --- /dev/null +++ b/docs/zh/harness/session.md @@ -0,0 +1,111 @@ +# 会话(Session) + +## 作用 + +让 agent 能在跨请求、跨进程、多用户场景下恢复状态。一次 `call()` 结束后自动落盘两路产出: + +- **StateModule 快照**(`Memory`、`ToolExecutionContext` 等可序列化状态)——默认走 `WorkspaceSession` +- **对话 JSONL**(LLM 上下文 + 完整历史)——走 `SessionTree`,由 `MemoryFlushManager.offloadMessages` 触发 + +两者是**两个并行路径 + +## 触发 + +| 时机 | 动作 | +|------|------| +| `agent.call(msg, ctx)` | `bindRuntimeContext` 以 `ctx.session/sessionKey` 交给 `delegate.loadIfExists` 恢复 StateModule | +| `PostCallEvent` / `ErrorEvent` | `SessionPersistenceHook`(priority 900)调 `agent.saveTo(session, sessionKey)`,成功 / 失败都保一份 | +| 压缩 / `PostCallEvent` flush | `MemoryFlushManager.offloadMessages` 追写到 `.jsonl` + `.log.jsonl` | +| 会话结束 | `WorkspaceManager.updateSessionIndex` 更新 `sessions.json` 供 `session_list` 查 | + +## 关键逻辑 + +### 双轨存储布局 + +```mermaid +flowchart LR + Call[agent.call] --> Hook[SessionPersistenceHook] + Hook -->|saveTo / loadIfExists| WS[(WorkspaceSession
StateModule 快照)] + Call --> Compact[CompactionHook / MemoryFlushHook] + Compact -->|offloadMessages| ST[(SessionTree
JSONL 双文件)] + WSWrite[WorkspaceManager
updateSessionIndex] --> Idx[(sessions.json
会话索引)] + Compact --> WSWrite +``` + +``` +workspace/agents// +├── context/ ← WorkspaceSession 负责 +│ └── / +│ ├── memory.json ← ReActAgent.memory 快照 +│ └── *.json ← 其他 StateModule 序列化产物 +└── sessions/ ← SessionTree + WorkspaceManager 负责 + ├── sessions.json ← 会话索引 (sessionId / summary / updatedAt) + ├── .jsonl ← LLM 可见的压缩上下文 + └── .log.jsonl ← 完整对话日志(append-only,不被压缩) +``` + +- **`context/`**:`WorkspaceSession` 继承 `JsonSession`,base 在 `agents//context/`;sessionId 子目录里按 `SessionKey → {key}.json` 存每个 `StateModule`。 +- **`sessions/`**:`SessionTree` 在一个 JSONL 里按 `id/parentId` 组成一棵树;另一份同名的 `.log.jsonl` **从不被压缩**,供审计和 `session_search` 使用。 + +### `RuntimeContext` 怎么让二者对齐 + +```java +RuntimeContext ctx = RuntimeContext.builder() + .sessionId("sess-001") + .userId("alice") + .build(); + +agent.call(msg, ctx).block(); +``` + +`HarnessAgent.bindRuntimeContext` 会做几件事: + +1. **补默认**:`session` 为空时使用构建时的 `defaultSession`(默认是 `WorkspaceSession(workspace, agentId)`);`sessionKey` 为空时依次试 `SimpleSessionKey.of(sessionId)` → `SimpleSessionKey.of(agentName)`。 +2. **传递到 hooks**:`workspaceContextHook`、`memoryFlushHook`、`sessionPersistenceHook`、`compactionHook` 都会同步该 ctx,他们在 offload / saveTo 时都能读到 `sessionId`。 +3. **联动 `userIdRef`**:`AtomicReference` 被顶下 `userId`,默认 `NamespaceFactory → List.of(userId)` 会以该 userId 作为路径前缀,从而多租户透明隔离。 +4. **预加载状态**:若 `session && sessionKey` 都有,调用 `delegate.loadIfExists` 覆盖当前 Memory。不存在则什么都不动。 + +### 默认与自定义 Session + +```java +// 1. 默认:什么都不传 → WorkspaceSession(workspace, agentId) +HarnessAgent.builder() + .name("MyAgent").model(model).workspace(workspace).build(); + +// 2. 使用任意指定路径的 JsonSession +HarnessAgent.builder() + ... + .session(new JsonSession(Path.of("/custom/sessions"))) + .build(); + +// 3. 调用时临时覆盖 +agent.call(msg, RuntimeContext.builder() + .sessionId("sess-001") + .session(customSession) + .sessionKey(SimpleSessionKey.of("sess-001")) + .build()) + .block(); +``` + +### 多用户隔离的两个层面 + +- **会话层**:`sessionId` 决定 `context//` 与 `sessions/.jsonl` 独立。 +- **文件层**:`userId` + `NamespaceFactory` 决定文件操作路径前缀(默认 `LocalFilesystemWithShell` 会读 `userIdRef`)。 + +```java +// 同一 agent 实例服务 alice / bob +agent.call(msg, RuntimeContext.builder().sessionId("alice-1").userId("alice").build()).block(); +agent.call(msg, RuntimeContext.builder().sessionId("bob-1").userId("bob").build()).block(); +// 两个会话状态、文件路径都互不干扰 +``` + +### 会话索引 + +`MemoryFlushManager.offloadMessages` 调完后,`WorkspaceManager.updateSessionIndex(agentId, sessionId, summary)` 会合并写 `sessions/sessions.json`,agent 在另一轮可以走 `session_list` 工具查看“该 agent 历史上都跟谁聊过”。 + +## 相关文档 + +- [工具](./tool.md) — `session_search` / `session_list` / `session_history` 的入参 +- [记忆](./memory.md) — `offloadMessages` 什么时候被调,怎么反过来被 `memory_search` 利用 +- [文件系统](./filesystem.md) — `userIdRef` + `NamespaceFactory` 的多租户路径隔离 +- [架构](./architecture.md) — `SessionPersistenceHook` 在 PostCallEvent / ErrorEvent 中的位置 diff --git a/docs/zh/harness/subagent.md b/docs/zh/harness/subagent.md new file mode 100644 index 000000000..0ca2240b0 --- /dev/null +++ b/docs/zh/harness/subagent.md @@ -0,0 +1,115 @@ +# 子 Agent(Subagent) + +## 作用 + +让父 agent 能把“独立、重上下文、可并行”的子任务交出去,不打扰主线。子 agent 是**临时**的 `HarnessAgent` 实例:独立 sysPrompt、独立 Memory、不共享父对话历史,仅返回一条结果作为 `tool_result`;同时支持同步 / 异步两种调用。 + +## 触发 + +| 时机 | 动作 | +|------|------| +| `HarnessAgent.build()` | 非 leaf 且有 model 时注册 `SubagentsHook`(priority 80)与 `AgentSpawnTool` / `TaskTool` | +| `PreReasoningEvent` | `SubagentsHook` 拼的“Subagents”指南段 + 所有可用 agent_id 注入第一条 SYSTEM 消息 | +| reasoning 选中子 agent 工具 | `agent_spawn` / `agent_send` / `agent_list` 走同步路径;`timeout_seconds=0` 走异步,返 `task_id` | +| 后续轮次 | `task_output` / `task_cancel` / `task_list` 调 `TaskRepository` 拿结果、取消、查看 | + +> 在 session mode(`AgentBootstrap` 下 `externalSubagentTool != null`)中,上面三个 `agent_*` 工具会被重命名为 `sessions_spawn` / `sessions_send` / `sessions_list`。 + +## 关键逻辑 + +### Spec 来源与汇集 + +```mermaid +flowchart LR + Built[内置 general-purpose
镜像父配置 + asLeafSubagent] --> Entries[buildSubagentEntries] + Spec[编程 SubagentSpec
builder.subagent ] --> Entries + MD[workspace/subagents/*.md
AgentSpecLoader] --> Entries + Custom[builder.subagentFactory
name to Function] --> Entries + Entries --> Hook[SubagentsHook] + Hook --> ToolMain{工具集} + ToolMain -->|tools()| Spawn[AgentSpawnTool] + ToolMain -->|tools()| TaskT[TaskTool] +``` + +- **内置 `general-purpose`**:镜像主 agent 的 model / workspace / hooks / skills 等配置,调用 `asLeafSubagent()` 禁用递归,适合任意可委派的子任务。 +- **编程 `SubagentSpec`**:`builder.subagent(spec)` 一个个加。 +- **`workspace/subagents/*.md`**:`AgentSpecLoader.loadFromDirectory` 递归扫,解析 YAML front matter + Markdown body。 +- **自定义工厂**:`builder.subagentFactory(name, Function)`,完全控制构建逻辑。 + +### Spec 的两种描述形式 + +**Markdown front matter**(`workspace/subagents/research.md`)——推荐: + +```markdown +--- +name: research-analyst +description: 调研主题、查找文档、汇总外部信息。 +model: qwen3-max +maxIters: 15 +tools: read_file, grep_files +--- + +你是一名研究分析师。输出带引用、不确定处要明说。 +``` + +`AgentSpecLoader.parse` 实际仅读 `name` / `description` / `tools`(逗号分)/ `model` / `maxIters`;body 作为 `sysPrompt`。 +`SubagentSpec` 还有 `workspace` 字段,但当前只在**编程式**(手动 `setWorkspace`)生效,Markdown 里写不会被读。 + +**编程**: + +```java +SubagentSpec spec = new SubagentSpec("data-analyst", "SQL / 数据聚合 / 趋势"); +spec.setSysPrompt("你是数据分析专家..."); +spec.setMaxIters(10); + +HarnessAgent.builder() + .name("Orchestrator").model(model).workspace(workspace) + .subagent(spec) + .build(); +``` + +### 防递归 + 防超深 + +- `SubagentSpec` 生成的子 agent 都调了 `Builder.asLeafSubagent()`:`leafSubagent=true` 时 `build()` **不注册** `SubagentsHook`,因此子 agent 看不到这些工具,无法再 spawn。 +- 在 `AgentSpawnTool` 里还额外限了一道防线:`MAX_SPAWN_DEPTH = 3`,作为动态保险。 + +### 调用语义 + +| 工具 | 作用 | 关键参数 | +|------|------|---------| +| `agent_spawn` | 生成一个子 agent 跑一件任务 | `agent_id`(必填)、`task`(可选,留空则只建 session 不跑)、`label`(可选别名)、`timeout_seconds` 默认 30s,`0` 走后台,上限 600s | +| `agent_send` | 给已存在的子 agent 补一条话 | `agent_key` (spawn 返回的句柄,不是 `agent_id`/`task_id`)或 `label`;`message`;`timeout_seconds` | +| `agent_list` | 列当前活跃子 agent | 无 | +| `task_output` | 取后台任务结果 | `task_id`、`block`(默认 true)、`timeout` 默认 30s,上限 600s | +| `task_cancel` | 取消任务 | `task_id` | +| `task_list` | 列任务,可按状态过滤 | `status_filter`:running / completed / failed / cancelled | + +### TaskRepository 与 BackgroundTask + +- 默认 `DefaultTaskRepository` 是进程内 `ConcurrentHashMap` + cached daemon thread pool。要跨进程(如 Redis / DB)只需实现 `TaskRepository` 接口 并 `builder.taskRepository(...)`。 +- `BackgroundTask` 包装 `CompletableFuture`,记录 `taskId / agentId / createdAt / lastCheckedAt`。 +- `TaskStatus`:`PENDING` / `RUNNING` / `COMPLETED` / `FAILED` / `CANCELLED`,`isTerminal()` 返回后三者。 + +## 配置示例 + +```java +HarnessAgent orchestrator = HarnessAgent.builder() + .name("orchestrator").model(model).workspace(workspace) + .subagent(researchSpec) // (1) 编程 + .subagentFactory("my-specialist", id -> // (2) 自定义工厂 + HarnessAgent.builder().name(id).model(specialModel) + .workspace(Path.of("./specialist-workspace")) + .toolkit(customToolkit).build()) + .taskRepository(new RedisTaskRepository(...)) // (可选) + .build(); +// (3) workspace/subagents/*.md 会被自动扫描 +// (4) 内置 general-purpose 总是在位 +``` + +编排 prompt 中子 agent 如何被选中完全依赖 `description`,尽量明确“何时用 / 何时不用 / 输出形式”。同时 `maxIters` 宜比父 agent 小,避免子任务贪吃 token。 + +## 相关文档 + +- [工具](./tool.md) — `agent_spawn` / `agent_send` / `agent_list` / `task_*` 的完整参数表 +- [工作区](./workspace.md) — `workspace/subagents/` 与自动发现 +- [架构](./architecture.md) — SubagentsHook 在生命周期中的位置与同步 / 后台两条委派路径的时序图 diff --git a/docs/zh/harness/tool.md b/docs/zh/harness/tool.md new file mode 100644 index 000000000..a775930f2 --- /dev/null +++ b/docs/zh/harness/tool.md @@ -0,0 +1,104 @@ +# 工具(Tool) + +## 作用 + +harness 层默认为 agent 提供一套“足够走完一个闭环”的内置工具:读写文件、检索记忆与会话、委派子 agent、可选走 shell。不需手动注册,`HarnessAgent.build()` 与 `SubagentsHook` 会一起装好。 + +## 注册路径 + +```mermaid +flowchart LR + Build[HarnessAgent.build] --> R1[FilesystemTool] + Build --> R2[MemorySearchTool] + Build --> R3[MemoryGetTool] + Build --> R4[SessionSearchTool] + Build -. backend 是 sandbox .-> R5[ShellExecuteTool] + Hook[SubagentsHook.tools
非 leaf 且有 model] --> H1[AgentSpawnTool] + Hook --> H2[TaskTool] +``` + +- **直接 register**:`FilesystemTool` / `MemorySearchTool` / `MemoryGetTool` / `SessionSearchTool` 必装;`ShellExecuteTool` 仅在 `backend instanceof AbstractSandboxFilesystem` 时装。 +- **间接 register**:`AgentSpawnTool` 与 `TaskTool` 是 `SubagentsHook.tools()` 返回的,仅在非 leaf 且配了 `model` 时出现;在 session mode 下 `agent_*` 会被 `sessions_*` 替换。 + +## 文件系统·`FilesystemTool` + +包装 `AbstractFilesystem`;路径是后端本地路径。 + +| 工具 | 作用 | 参数 | +|------|------|------| +| `read_file` | 读文件内容 | `path`, `offset`(0-indexed), `limit`(0 = 读全) | +| `write_file` | 创建新文件 | `path`, `content`(已存在会报错) | +| `edit_file` | 精确字符串替换 | `path`, `old_string`(默认唯一), `new_string`, `replace_all`(默认 false) | +| `grep_files` | 指定路径中搜字符串(非正则)| `pattern`, `path`, `glob`(如 `*.java`) | +| `glob_files` | 按 glob 查文件 | `pattern`(如 `**/*.md`), `path` | +| `list_files` | 列目录 | `path` | + +## 记忆·`MemorySearchTool` / `MemoryGetTool` + +| 工具 | 作用 | 参数 | +|------|------|------| +| `memory_search` | FTS5 全文检索,最多返 30 条;MemoryIndex 不可用时 fallback 到关键字扫 | `query` | +| `memory_get` | 读记忆文件中指定行范围,输出带行号 | `path`(工作区相对), `startLine`, `endLine`(1-based)| + +> 参数名是驼峰(`startLine` / `endLine`),与 filesystem 的 snake_case 不一致。 + +## 会话·`SessionSearchTool` + +| 工具 | 作用 | 参数 | +|------|------|------| +| `session_search` | 在会话 JSONL 中扫关键词 | `query`, `agentId`(可选), `maxResults`(默认 10) | +| `session_list` | 列某个 agent 的会话,优先读 `sessions.json` | `agentId` | +| `session_history` | 返某个会话最近 N 条消息 | `agentId`, `sessionId`, `lastN`(默认 20)| + +> 参数名都是驼峰,且 `session_search` 返回结果是扫全部 `agents//sessions/*.jsonl` 后的“首次命中 10 条”,**不是**按相关性排序。 + +## 子 Agent·`AgentSpawnTool` + +| 工具 | 作用 | 参数 | +|------|------|------| +| `agent_spawn` | 创建临时子 agent、可选走任务 | `agent_id`(必填), `task`(可选,留空仅建 session), `label`(可选别名), `timeout_seconds`(默认 30,`0`=后台,上限 600) | +| `agent_send` | 向已存在子 agent 补一条 | `agent_key` 或 `label`(二选一), `message`, `timeout_seconds` | +| `agent_list` | 列当前子 agent | 无 | + +``` +agent_spawn agent_id="research-analyst" + task="调研主题 X" + timeout_seconds=60 + +# 异步 +agent_spawn agent_id="research-analyst" task="全库安全审计" timeout_seconds=0 +# → agent_key + task_id +``` + +Session mode 下,这三个名会变为 `sessions_spawn` / `sessions_send` / `sessions_list`。 + +## 后台任务·`TaskTool` + +| 工具 | 作用 | 参数 | +|------|------|------| +| `task_output` | 拿后台任务结果 | `task_id`, `block`(默认 true), `timeout` 默认 30000ms,上限 600000ms | +| `task_cancel` | 取消任务;终态不生效 | `task_id` | +| `task_list` | 列任务 | `status_filter`:running / completed / failed / cancelled / all | + +## Shell·`ShellExecuteTool`(条件性装) + +仅在后端是 `AbstractSandboxFilesystem`(包含 `LocalFilesystemWithShell`)时才被注册。如果你用的是纯 `LocalFilesystem` 或 `StoreFilesystem`,子工具不出现。 + +| 工具 | 作用 | 参数 | +|------|------|------| +| `execute` | 走后端 `execute()`,返 stdout + exit code | `command`, `working_directory`(可选,实际拼接为 `cd

&& `), `timeout`(秒,默认 30)| + +> **注意**:@Tool 未显式设 `name`,默认取方法名,所以 LLM 看到的工具名是 `execute`。如果后续统一为 `shell_execute` 是个小重构,参见 [roadmap](./roadmap.md)。 + +``` +execute command="find . -name '*.java' | wc -l" +execute command="mvn test" timeout=300 +execute command="git status" working_directory="app" # 拼为 cd app && git status +``` + +## 相关文档 + +- [文件系统](./filesystem.md) — 后端实现与沙箱接口 +- [记忆](./memory.md) — `memory_search` / `memory_get` 背后的 FTS5 与双层记忆 +- [会话](./session.md) — `session_*` 系列背后的 `WorkspaceSession` / `SessionTree` 双轨 +- [子 Agent](./subagent.md) — `agent_spawn` / `agent_send` / `task_*` 的调度与生命周期 diff --git a/docs/zh/harness/workspace.md b/docs/zh/harness/workspace.md new file mode 100644 index 000000000..35c46b859 --- /dev/null +++ b/docs/zh/harness/workspace.md @@ -0,0 +1,119 @@ +# 工作区(Workspace) + +## 作用 + +工作区是 `HarnessAgent` 的"地基":人格、长期记忆、领域知识、子 agent 规格、会话历史、技能定义统一以**目录结构 + Markdown** 的形式落地,不再散落在代码里。 + +agent 每次推理时,工作区里的几个关键文件会被自动注入到 system prompt;运行过程中的记忆与会话也会按既定路径回写到这里。 + +## 触发 + +| 时机 | 动作 | +|------|------| +| `HarnessAgent.build()` | `WorkspaceManager.validate()` 检查目录与 `AGENTS.md` 是否存在,缺失只 warn | +| 每次 `call()` 推理前 | `WorkspaceContextHook` 读 `AGENTS.md` / `MEMORY.md` / `knowledge/` / 额外文件并注入 system prompt | +| 压缩 / 调用结束 | `MemoryFlushHook`、`SessionPersistenceHook` 等通过 `WorkspaceManager` 写回 `memory/`、`agents/.../sessions/` | + +## 目录结构 + +``` +workspace/ ← 默认 .agentscope/workspace +├── AGENTS.md ← 人格 / 行为约定(每次注入全文) +├── MEMORY.md ← 整理过的长期记忆(每次注入,受 token 预算) +├── knowledge/ +│ ├── KNOWLEDGE.md ← 领域知识入口 +│ └── * ← 其他参考文件,按需 read_file 打开 +├── memory/ +│ ├── YYYY-MM-DD.md ← 每日记忆流水账(追加,由 MemoryFlushManager 写入) +│ └── .consolidation_state ← MemoryConsolidator 内部状态 +├── skills//SKILL.md ← 自定义技能 +├── subagent.yml ← 子 agent 规格(可选) +└── agents// + └── sessions/ + ├── sessions.json ← 会话索引(id / summary / updatedAt) + ├── .jsonl ← LLM 可见的压缩上下文 + └── .log.jsonl← 完整对话日志(追加) +``` + +> 子 agent 还支持 `workspace/subagents/*.md` 自动发现,详见 [子 Agent](./subagent.md)。 + +## 关键逻辑 + +### 两层读取 / 写回 + +`WorkspaceManager` 是无状态访问器,所有读写都遵循同一规约: + +```mermaid +flowchart LR + Caller[Hook / Tool] -->|read| WM[WorkspaceManager] + WM -->|read 优先| FS[AbstractFilesystem
多租户 namespace 透明] + FS -- 命中非空 --> WM + FS -- 空 --> LD[本地磁盘
workspace/...] + LD --> WM + + Caller -->|write| WM + WM -->|appendUtf8 / uploadFiles| FS2[AbstractFilesystem] + WM -. filesystem 缺省 .-> LD2[本地磁盘兜底] +``` + +要点: + +- **读路径**:`AbstractFilesystem` 优先 → 本地磁盘兜底,让多租户场景对调用方透明 +- **写路径**:默认全部走 `AbstractFilesystem`;未配置时 fallback 本地磁盘 +- **List 操作**(`listKnowledgeFiles` / `listMemoryFilePaths` / `listSessionLogFiles`)取两层并集去重,避免漏文件 + +### system prompt 注入内容 + +`WorkspaceContextHook`(priority 900)在 `PreReasoningEvent` 拼装一段固定结构的文本,合并到第一条 SYSTEM 消息: + +| 段落 | 来源 | Token 预算 | +|------|------|------------| +| `## Session Context` | 模板生成(日期、OS、workspace 路径、`runtimeContext.sessionId`) | 不限 | +| `## Workspace` 等 guidance | 内置模板 | 不限 | +| `` XML 块 | — | — | +| ↳ `` | `AGENTS.md` | 全文 | +| ↳ `` | `MEMORY.md` | 受 `maxContextTokens` 限制 | +| ↳ `` | `knowledge/KNOWLEDGE.md` + `listKnowledgeFiles()` 列表 | 全文 + 路径目录 | +| ↳ `<{rel_path}>` | 每个 `additionalContextFile` | 全文 | + +`maxContextTokens` 默认 `8000`(按 `chars/4` 估算)。当 `MEMORY.md` 估算超出"剩余预算"时,按字符截断并附 `... (memory truncated — use memory_search for older entries) ...` 尾注,提示 agent 改走 `memory_search`。 + +### 关键 API + +```java +WorkspaceManager wm = new WorkspaceManager(workspace, abstractFilesystem); + +wm.readAgentsMd(); // 两层读 +wm.readMemoryMd(); +wm.readKnowledgeMd(); // 注意:读 knowledge/KNOWLEDGE.md +wm.readManagedWorkspaceFileUtf8(rel); // 任意工作区相对路径,做 path traversal 校验 + +wm.listKnowledgeFiles(); // 两层并集 +wm.listMemoryFilePaths(); +wm.listSessionLogFiles(); + +wm.appendUtf8WorkspaceRelative(rel, content); // 走 AbstractFilesystem +wm.updateSessionIndex(agentId, sessionId, summary); // 维护 sessions.json +``` + +## 配置 + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("MyAgent") + .model(model) + .workspace(Paths.get(".agentscope/workspace")) // 不传则用默认 + .additionalContextFile("SOUL.md") // 任意工作区相对路径 + .additionalContextFile("PREFERENCES.md") + .maxContextTokens(8000) // 控制 MEMORY 的注入上限 + .build(); +``` + +`AGENTS.md` 缺失时 agent 仍可工作,只会丢失 persona 段,建议至少写一份最小骨架(参考 [overview.md](./overview.md) 的 quickstart)。 + +## 相关文档 + +- [架构](./architecture.md) — `WorkspaceContextHook` 在 call() 生命周期里的位置 +- [文件系统](./filesystem.md) — 两层读路径中"上层"的实现 +- [记忆](./memory.md) — `MEMORY.md` / `memory/*.md` 怎么生成与维护 +- [会话](./session.md) — `agents//sessions/` 的细节 diff --git a/docs/zh/intro.md b/docs/zh/intro.md index ba17ce5fc..8c4b73236 100644 --- a/docs/zh/intro.md +++ b/docs/zh/intro.md @@ -98,6 +98,7 @@ System.out.println(response.getTextContent()); - **[内存管理](task/memory.md)** - 管理对话历史和长期内存 - **[计划](task/plan.md)** - 复杂多步骤任务的计划管理 - **[智能体配置](task/agent-config.md)** - 高级智能体配置选项 +- **[HarnessAgent](harness/overview.md)** - 具备工作区、持久记忆与子 Agent 编排的生产级运行时 ### 多智能体系统 - **[管道](multi-agent/pipeline.md)** - 使用顺序和并行执行构建多智能体工作流 From be9feea80f3cb3c150a4bf07fb1368290ef7e650 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Mon, 27 Apr 2026 23:57:08 +0800 Subject: [PATCH 03/28] remove final qualifier, make stream() method in AgentBase extensible. --- .../src/main/java/io/agentscope/core/agent/AgentBase.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java index 96935570c..a6ea34deb 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java +++ b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java @@ -700,7 +700,7 @@ public final Mono observe(List msgs) { * @return Flux of events emitted during execution */ @Override - public final Flux stream(List msgs, StreamOptions options) { + public Flux stream(List msgs, StreamOptions options) { return createEventStream(options, () -> call(msgs)); } @@ -713,8 +713,7 @@ public final Flux stream(List msgs, StreamOptions options) { * @return Flux of events emitted during execution */ @Override - public final Flux stream( - List msgs, StreamOptions options, Class structuredModel) { + public Flux stream(List msgs, StreamOptions options, Class structuredModel) { return createEventStream(options, () -> call(msgs, structuredModel)); } @@ -727,7 +726,7 @@ public final Flux stream( * @return Flux of events emitted during execution */ @Override - public final Flux stream(List msgs, StreamOptions options, JsonNode schema) { + public Flux stream(List msgs, StreamOptions options, JsonNode schema) { return createEventStream(options, () -> call(msgs, schema)); } From 1f3004a00764c85abed9a08493eedff74ad59ab5 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Mon, 27 Apr 2026 23:58:17 +0800 Subject: [PATCH 04/28] update harness implementation --- agentscope-dependencies-bom/pom.xml | 2 +- .../agentscope-bom/pom.xml | 2 +- agentscope-harness/pom.xml | 21 +- .../harness/agent/HarnessAgent.java | 355 ++++++++--- .../harness/agent/IsolationScope.java | 83 +++ .../harness/agent/RuntimeContext.java | 24 + .../agent/filesystem/AbstractFilesystem.java | 51 ++ .../filesystem/BaseSandboxFilesystem.java | 44 +- .../agent/filesystem/CompositeFilesystem.java | 89 ++- .../agent/filesystem/LocalFilesystem.java | 65 +- .../agent/filesystem/LocalFilesystemSpec.java | 128 ++++ .../filesystem/LocalFilesystemWithShell.java | 2 +- .../agent/filesystem/StoreFilesystem.java | 67 +- .../agent/filesystem/StoreFilesystemSpec.java | 190 ++++++ .../compaction => hook}/CompactionHook.java | 22 +- .../harness/agent/hook/MemoryFlushHook.java | 18 - .../agent/hook/MemoryMaintenanceHook.java | 210 ++++++ .../agent/hook/SandboxLifecycleHook.java | 195 ++++++ .../agent/hook/ToolResultEvictionHook.java | 2 +- .../agent/memory/MemoryConsolidator.java | 141 +++-- .../agent/memory/MemoryFlushManager.java | 57 +- .../harness/agent/memory/MemoryIndex.java | 274 -------- .../memory/MemoryMaintenanceScheduler.java | 286 --------- .../compaction/ConversationCompactor.java | 1 + .../compaction/ToolResultEvictionConfig.java | 2 +- .../agent/memory/session/SessionTree.java | 74 ++- .../agent/sandbox/AbstractBaseSandbox.java | 283 +++++++++ .../harness/agent/sandbox/ExecResult.java | 49 ++ .../harness/agent/sandbox/Sandbox.java | 68 ++ .../agent/sandbox/SandboxAcquireResult.java | 46 ++ .../harness/agent/sandbox/SandboxAware.java | 30 + .../sandbox/SandboxBackedFilesystem.java | 184 ++++++ .../harness/agent/sandbox/SandboxClient.java | 44 ++ .../agent/sandbox/SandboxClientOptions.java | 52 ++ .../harness/agent/sandbox/SandboxContext.java | 130 ++++ .../sandbox/SandboxDistributedOptions.java | 154 +++++ .../agent/sandbox/SandboxErrorCode.java | 55 ++ .../agent/sandbox/SandboxException.java | 329 ++++++++++ .../agent/sandbox/SandboxIsolationKey.java | 131 ++++ .../harness/agent/sandbox/SandboxManager.java | 176 +++++ .../harness/agent/sandbox/SandboxState.java | 83 +++ .../agent/sandbox/SandboxStateStore.java | 61 ++ .../sandbox/SessionSandboxStateStore.java | 100 +++ .../sandbox/WorkspaceArchiveExtractor.java | 114 ++++ .../sandbox/WorkspaceProjectionApplier.java | 156 +++++ .../sandbox/WorkspaceSandboxStateStore.java | 130 ++++ .../harness/agent/sandbox/WorkspaceSpec.java | 84 +++ .../agent/sandbox/WorkspaceSpecApplier.java | 159 +++++ .../filesystem/DockerFilesystemSpec.java | 102 +++ .../filesystem/SandboxFilesystemSpec.java | 119 ++++ .../sandbox/impl/docker/DockerSandbox.java | 599 ++++++++++++++++++ .../impl/docker/DockerSandboxClient.java | 130 ++++ .../docker/DockerSandboxClientOptions.java | 228 +++++++ .../impl/docker/DockerSandboxState.java | 200 ++++++ .../agent/sandbox/layout/DirEntry.java | 72 +++ .../agent/sandbox/layout/FileEntry.java | 84 +++ .../agent/sandbox/layout/GitRepoEntry.java | 79 +++ .../agent/sandbox/layout/LocalDirEntry.java | 58 ++ .../agent/sandbox/layout/LocalFileEntry.java | 57 ++ .../agent/sandbox/layout/WorkspaceEntry.java | 65 ++ .../layout/WorkspaceProjectionEntry.java | 57 ++ .../snapshot/LocalSandboxSnapshot.java | 148 +++++ .../sandbox/snapshot/LocalSnapshotSpec.java | 65 ++ .../sandbox/snapshot/NoopSandboxSnapshot.java | 89 +++ .../sandbox/snapshot/NoopSnapshotSpec.java | 38 ++ .../snapshot/OssRemoteSnapshotClient.java | 89 +++ .../sandbox/snapshot/OssSnapshotSpec.java | 57 ++ .../snapshot/RedisRemoteSnapshotClient.java | 89 +++ .../sandbox/snapshot/RedisSnapshotSpec.java | 35 + .../snapshot/RemoteSandboxSnapshot.java | 98 +++ .../snapshot/RemoteSnapshotClient.java | 56 ++ .../sandbox/snapshot/RemoteSnapshotSpec.java | 48 ++ .../sandbox/snapshot/SandboxSnapshot.java | 88 +++ .../sandbox/snapshot/SandboxSnapshotSpec.java | 37 ++ .../agent/session/WorkspaceSession.java | 4 + .../{filesystem => }/store/BaseStore.java | 2 +- .../{filesystem => }/store/InMemoryStore.java | 2 +- .../store/NamespaceFactory.java | 2 +- .../{filesystem => }/store/StoreItem.java | 2 +- .../harness/agent/tool/MemorySearchTool.java | 32 +- .../agent/workspace/WorkspaceManager.java | 7 +- .../HarnessAgentDistributedSandboxTest.java | 144 +++++ .../harness/agent/HarnessAgentTest.java | 22 + ...ilesystemPersonalAssistantExampleTest.java | 198 ++++++ ...oxFilesystemIsolationScopeExampleTest.java | 265 ++++++++ ...reFilesystemIsolationScopeExampleTest.java | 282 +++++++++ .../example/support/InMemorySandbox.java | 116 ++++ .../support/InMemorySandboxClient.java | 122 ++++ .../InMemorySandboxFilesystemSpec.java | 81 +++ .../example/support/InMemorySandboxState.java | 41 ++ .../FilesystemDeleteMoveExistsTest.java | 218 +++++++ .../filesystem/StoreFilesystemSpecTest.java | 92 +++ .../MemoryConsolidatorFilesystemTest.java | 148 +++++ .../memory/session/SessionTreeMirrorTest.java | 57 ++ .../sandbox/SandboxIsolationKeyTest.java | 138 ++++ .../sandbox/SandboxManagerIsolationTest.java | 253 ++++++++ .../sandbox/SessionSandboxStateStoreTest.java | 110 ++++ .../WorkspaceProjectionApplierTest.java | 91 +++ .../WorkspaceSandboxStateStoreTest.java | 234 +++++++ .../snapshot/RemoteSnapshotClientsTest.java | 82 +++ pom.xml | 2 +- 101 files changed, 9679 insertions(+), 878 deletions(-) create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java rename agentscope-harness/src/main/java/io/agentscope/harness/agent/{memory/compaction => hook}/CompactionHook.java (89%) create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java delete mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java delete mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/AbstractBaseSandbox.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/ExecResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAware.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClient.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClientOptions.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxErrorCode.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxException.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxState.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxStateStore.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStore.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceArchiveExtractor.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplier.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStore.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpecApplier.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/DirEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/FileEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/GitRepoEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalDirEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalFileEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceProjectionEntry.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSandboxSnapshot.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSnapshotSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSandboxSnapshot.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSnapshotSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssRemoteSnapshotClient.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssSnapshotSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSandboxSnapshot.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClient.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotSpec.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshot.java create mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshotSpec.java rename agentscope-harness/src/main/java/io/agentscope/harness/agent/{filesystem => }/store/BaseStore.java (97%) rename agentscope-harness/src/main/java/io/agentscope/harness/agent/{filesystem => }/store/InMemoryStore.java (98%) rename agentscope-harness/src/main/java/io/agentscope/harness/agent/{filesystem => }/store/NamespaceFactory.java (96%) rename agentscope-harness/src/main/java/io/agentscope/harness/agent/{filesystem => }/store/StoreItem.java (94%) create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandbox.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxClient.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxFilesystemSpec.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxState.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplierTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClientsTest.java diff --git a/agentscope-dependencies-bom/pom.xml b/agentscope-dependencies-bom/pom.xml index a6b38b328..838b0e621 100644 --- a/agentscope-dependencies-bom/pom.xml +++ b/agentscope-dependencies-bom/pom.xml @@ -60,7 +60,7 @@ - 1.0.12-SNAPSHOT + 1.0.12-harness-SNAPSHOT UTF-8 UTF-8 17 diff --git a/agentscope-distribution/agentscope-bom/pom.xml b/agentscope-distribution/agentscope-bom/pom.xml index a8705cc82..6b94ca6fd 100644 --- a/agentscope-distribution/agentscope-bom/pom.xml +++ b/agentscope-distribution/agentscope-bom/pom.xml @@ -59,7 +59,7 @@ - 1.0.12-SNAPSHOT + 1.0.12-harness-SNAPSHOT UTF-8 UTF-8 17 diff --git a/agentscope-harness/pom.xml b/agentscope-harness/pom.xml index 014f609aa..2fad2bb18 100644 --- a/agentscope-harness/pom.xml +++ b/agentscope-harness/pom.xml @@ -42,11 +42,24 @@ jackson-dataformat-yaml - + - org.xerial - sqlite-jdbc - 3.47.2.0 + org.apache.commons + commons-compress + 1.27.1 + + + + + redis.clients + jedis + + + + + com.aliyun.oss + aliyun-sdk-oss + 3.18.5 diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 4a67fa689..2f39adaff 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -40,24 +40,35 @@ import io.agentscope.core.tool.Toolkit; import io.agentscope.harness.agent.filesystem.AbstractFilesystem; import io.agentscope.harness.agent.filesystem.AbstractSandboxFilesystem; +import io.agentscope.harness.agent.filesystem.LocalFilesystemSpec; import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; -import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; import io.agentscope.harness.agent.hook.AgentTraceHook; +import io.agentscope.harness.agent.hook.CompactionHook; import io.agentscope.harness.agent.hook.MemoryFlushHook; +import io.agentscope.harness.agent.hook.MemoryMaintenanceHook; import io.agentscope.harness.agent.hook.RuntimeContextAwareHook; +import io.agentscope.harness.agent.hook.SandboxLifecycleHook; import io.agentscope.harness.agent.hook.SessionPersistenceHook; import io.agentscope.harness.agent.hook.SubagentsHook; import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; import io.agentscope.harness.agent.hook.ToolResultEvictionHook; import io.agentscope.harness.agent.hook.WorkspaceContextHook; +import io.agentscope.harness.agent.memory.MemoryConsolidator; import io.agentscope.harness.agent.memory.MemoryFlushManager; -import io.agentscope.harness.agent.memory.MemoryIndex; -import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; import io.agentscope.harness.agent.memory.compaction.CompactionConfig; -import io.agentscope.harness.agent.memory.compaction.CompactionHook; import io.agentscope.harness.agent.memory.compaction.ConversationCompactor; import io.agentscope.harness.agent.memory.compaction.ToolResultEvictionConfig; +import io.agentscope.harness.agent.sandbox.SandboxBackedFilesystem; +import io.agentscope.harness.agent.sandbox.SandboxContext; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; +import io.agentscope.harness.agent.sandbox.SandboxManager; +import io.agentscope.harness.agent.sandbox.SandboxStateStore; +import io.agentscope.harness.agent.sandbox.SessionSandboxStateStore; +import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; +import io.agentscope.harness.agent.sandbox.snapshot.NoopSnapshotSpec; import io.agentscope.harness.agent.session.WorkspaceSession; +import io.agentscope.harness.agent.store.NamespaceFactory; import io.agentscope.harness.agent.subagent.AgentSpecLoader; import io.agentscope.harness.agent.subagent.SubagentFactory; import io.agentscope.harness.agent.subagent.SubagentSpec; @@ -121,9 +132,11 @@ public class HarnessAgent implements Agent, StateModule { private final MemoryFlushHook memoryFlushHook; private final SessionPersistenceHook sessionPersistenceHook; private final CompactionHook compactionHook; - private final MemoryMaintenanceScheduler maintenanceScheduler; private final AtomicReference userIdRef; + private final AtomicReference sessionIdRef; private final Session defaultSession; + private final SandboxLifecycleHook sandboxLifecycleHook; + private final SandboxContext defaultSandboxContext; private RuntimeContext runtimeContext; private HarnessAgent( @@ -133,21 +146,22 @@ private HarnessAgent( MemoryFlushHook memoryFlushHook, SessionPersistenceHook sessionPersistenceHook, CompactionHook compactionHook, - MemoryMaintenanceScheduler maintenanceScheduler, AtomicReference userIdRef, - Session defaultSession) { + AtomicReference sessionIdRef, + Session defaultSession, + SandboxLifecycleHook sandboxLifecycleHook, + SandboxContext defaultSandboxContext) { this.delegate = delegate; this.workspaceManager = workspaceManager; this.workspaceContextHook = workspaceContextHook; this.memoryFlushHook = memoryFlushHook; this.sessionPersistenceHook = sessionPersistenceHook; this.compactionHook = compactionHook; - this.maintenanceScheduler = maintenanceScheduler; this.userIdRef = userIdRef; + this.sessionIdRef = sessionIdRef; this.defaultSession = defaultSession; - if (maintenanceScheduler != null) { - maintenanceScheduler.start(); - } + this.sandboxLifecycleHook = sandboxLifecycleHook; + this.defaultSandboxContext = defaultSandboxContext; } /** Calls the agent with a runtime context, which provides sessionId and other metadata. */ @@ -202,7 +216,6 @@ private Mono forceCompactAndRetry(Memory memory, List msgs) { // Force trigger by using a config with threshold=1 (always compact) CompactionConfig forceConfig = CompactionConfig.builder().triggerMessages(1).build(); MemoryFlushManager fm = new MemoryFlushManager(workspaceManager, delegate.getModel()); - fm.setMaintenanceScheduler(maintenanceScheduler); ConversationCompactor compactor = new ConversationCompactor(delegate.getModel(), fm); return compactor @@ -248,6 +261,13 @@ private void bindRuntimeContext(RuntimeContext ctx) { if (userIdRef != null) { userIdRef.set(effective.getUserId()); } + if (sessionIdRef != null) { + String sid = + effective.getSessionKey() != null + ? effective.getSessionKey().toIdentifier() + : effective.getSessionId(); + sessionIdRef.set(sid); + } if (workspaceContextHook != null) { workspaceContextHook.setRuntimeContext(effective); } @@ -260,6 +280,9 @@ private void bindRuntimeContext(RuntimeContext ctx) { if (compactionHook != null) { compactionHook.setRuntimeContext(effective); } + if (sandboxLifecycleHook != null) { + sandboxLifecycleHook.setRuntimeContext(effective); + } if (effective.getSession() != null && effective.getSessionKey() != null) { try { delegate.loadIfExists(effective.getSession(), effective.getSessionKey()); @@ -286,7 +309,13 @@ private RuntimeContext ensureSessionDefaults(RuntimeContext ctx) { sessionKey = SimpleSessionKey.of(delegate.getName()); } } - if (session == ctx.getSession() && sessionKey == ctx.getSessionKey()) { + // Inject default sandbox context if the call doesn't provide one + SandboxContext sandboxCtx = + ctx.getSandboxContext() != null ? ctx.getSandboxContext() : defaultSandboxContext; + + if (session == ctx.getSession() + && sessionKey == ctx.getSessionKey() + && sandboxCtx == ctx.getSandboxContext()) { return ctx; } return RuntimeContext.builder() @@ -295,6 +324,7 @@ private RuntimeContext ensureSessionDefaults(RuntimeContext ctx) { .session(session) .sessionKey(sessionKey) .putAll(ctx.getExtra()) + .sandboxContext(sandboxCtx) .build(); } @@ -424,6 +454,8 @@ public static class Builder { private String environmentMemory; private AbstractFilesystem abstractFilesystem; private Session session; + private SandboxStateStore sandboxStateStore; + private SandboxDistributedOptions sandboxDistributedOptions; /** * When {@code true}, this agent is a leaf worker (spawned subagent): it does not register @@ -460,6 +492,11 @@ public static class Builder { private int maxContextTokens = 8000; private boolean useLegacyXmlWorkspaceContext = false; + // Filesystem mode configuration (at most one of these three is set) + private SandboxFilesystemSpec sandboxFilesystemSpec; + private StoreFilesystemSpec storeFilesystemSpec; + private LocalFilesystemSpec localFilesystemSpec; + public Builder name(String name) { this.name = name; return this; @@ -543,14 +580,54 @@ public Builder environmentMemory(String environmentMemory) { } /** - * Sets a custom {@link AbstractFilesystem} implementation. When not set, defaults to - * {@link LocalFilesystemWithShell} backed by the workspace directory. + * Escape hatch: sets a custom {@link AbstractFilesystem} implementation directly. + * + *

Prefer {@link #filesystem(LocalFilesystemSpec)}, {@link #filesystem(StoreFilesystemSpec)} + * or {@link #filesystem(SandboxFilesystemSpec)} unless you have a bespoke backend that is + * not expressible via any of the declarative specs. */ public Builder abstractFilesystem(AbstractFilesystem backend) { this.abstractFilesystem = backend; return this; } + /** + * Configures Mode 2 — sandbox filesystem mode: fully isolated workspace running in a + * sandbox (for example Docker). Long-term memory extraction/read and shell execution are + * all routed through the sandbox session. State can be persisted via snapshots and resumed + * by the configured isolation scope. + * + * @param spec sandbox filesystem spec (for example Docker sandbox spec) + * @return this builder + */ + public Builder filesystem(SandboxFilesystemSpec spec) { + this.sandboxFilesystemSpec = spec; + return this; + } + + /** + * Configures Mode 1 — composite (non-sandbox) filesystem mode: a unified workspace + * view that blends a local {@code LocalFilesystem} backend with a shared + * {@code StoreFilesystem} for distributed long-term memory. Shell execution is not + * available in this mode — selected prefixes ({@code MEMORY.md}, {@code memory/}, + * {@code agents/.../sessions/}) are routed to the store to keep memory consistent across + * replicas. + */ + public Builder filesystem(StoreFilesystemSpec spec) { + this.storeFilesystemSpec = spec; + return this; + } + + /** + * Configures Mode 3 — local filesystem with shell mode: the agent workspace is a + * plain local directory and shell commands execute on the host. Long-term memory is kept + * on the same local disk. Use for single-process / single-replica deployments. + */ + public Builder filesystem(LocalFilesystemSpec spec) { + this.localFilesystemSpec = spec; + return this; + } + /** * Enables or disables agent execution trace logging via {@link AgentTraceHook}. * Default is {@code true}. @@ -599,6 +676,35 @@ public Builder session(Session session) { return this; } + /** + * Overrides the store used to persist/resume sandbox session state. + * + *

When not set, sandbox mode uses a {@link SessionSandboxStateStore} backed by the + * configured {@link #session(Session)} (or the default {@link WorkspaceSession}). + */ + public Builder sandboxStateStore(SandboxStateStore sandboxStateStore) { + this.sandboxStateStore = sandboxStateStore; + return this; + } + + /** + * Enables high-level distributed sandbox configuration. + * + *

This helper bundles three distributed concerns: + *

    + *
  • distributed {@link Session} for sandbox state slots
  • + *
  • remote/non-noop {@link io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec} + * for workspace archive persistence
  • + *
  • {@link IsolationScope} for sharing granularity
  • + *
+ * + *

Requires sandbox mode (i.e. {@link #filesystem(SandboxFilesystemSpec)}). + */ + public Builder sandboxDistributed(SandboxDistributedOptions options) { + this.sandboxDistributedOptions = options; + return this; + } + /** Adds a subagent spec (programmatic; workspace specs come from {@code subagents/*.md}). */ public Builder subagent(SubagentSpec spec) { this.subagentSpecs.add(spec); @@ -675,12 +781,17 @@ public Builder useLegacyXmlWorkspaceContext(boolean enabled) { return this; } + public List buildSubagentEntries(Path resolvedWorkspace) { + return buildSubagentEntries(resolvedWorkspace, null); + } + /** * Builds the subagent entries from programmatic specs, {@code workspace/subagents/*.md}, * and custom factories. Useful for callers (e.g. {@code AgentBootstrap}) that need to * extract agent factories before building the full agent. */ - public List buildSubagentEntries(Path resolvedWorkspace) { + public List buildSubagentEntries( + Path resolvedWorkspace, SandboxBackedFilesystem sandboxFs) { List allSpecs = new ArrayList<>(subagentSpecs); Path subagentsDir = resolvedWorkspace.resolve("subagents"); @@ -695,7 +806,7 @@ public List buildSubagentEntries(Path resolvedWorkspace) { "general-purpose", "General-purpose subagent with same capabilities as the main agent." + " Use for any isolated task that can be fully delegated.", - buildGeneralPurposeFactory(resolvedWorkspace))); + buildGeneralPurposeFactory(resolvedWorkspace, sandboxFs))); for (SubagentSpec spec : allSpecs) { if (spec.getName() != null) { @@ -721,15 +832,80 @@ public List buildSubagentEntries(Path resolvedWorkspace) { } public HarnessAgent build() { + int specCount = 0; + if (sandboxFilesystemSpec != null) specCount++; + if (storeFilesystemSpec != null) specCount++; + if (localFilesystemSpec != null) specCount++; + if (specCount > 1) { + throw new IllegalStateException( + "At most one of sandboxFilesystemSpec, storeFilesystemSpec," + + " localFilesystemSpec may be configured"); + } + if (abstractFilesystem != null && specCount > 0) { + throw new IllegalStateException( + "abstractFilesystem() is an escape hatch and is mutually exclusive with" + + " filesystem(...) specs"); + } + if (sandboxDistributedOptions != null && sandboxFilesystemSpec == null) { + throw new IllegalStateException( + "sandboxDistributed(...) requires sandbox mode." + + " Configure filesystem(SandboxFilesystemSpec) first."); + } Path resolvedWorkspace = workspace != null ? workspace : Paths.get(System.getProperty("user.dir")) .resolve(".agentscope/workspace"); + String resolvedAgentId = name != null ? name : "HarnessAgent"; + Session effectiveSession = + sandboxDistributedOptions != null + && sandboxDistributedOptions.getSession() != null + ? sandboxDistributedOptions.getSession() + : session; + if (effectiveSession == null) { + effectiveSession = new WorkspaceSession(resolvedWorkspace, resolvedAgentId); + } AtomicReference userIdRef = new AtomicReference<>(); - AbstractFilesystem backend = resolveBackend(resolvedWorkspace, userIdRef); - WorkspaceManager wsManager = new WorkspaceManager(resolvedWorkspace, backend); + AtomicReference sessionIdRef = new AtomicReference<>(); + AbstractFilesystem filesystem = + resolveFilesystem(resolvedWorkspace, resolvedAgentId, userIdRef, sessionIdRef); + + // ---- Sandbox integration ---- + SandboxLifecycleHook sandboxLifecycleHook = null; + SandboxContext defaultSandboxContext = null; + SandboxBackedFilesystem capturedSandboxFs = null; + if (sandboxFilesystemSpec != null) { + if (sandboxDistributedOptions != null) { + if (sandboxDistributedOptions.getIsolationScope() != null) { + sandboxFilesystemSpec.isolationScope( + sandboxDistributedOptions.getIsolationScope()); + } + if (sandboxDistributedOptions.getSnapshotSpec() != null) { + sandboxFilesystemSpec.snapshotSpec( + sandboxDistributedOptions.getSnapshotSpec()); + } + } + capturedSandboxFs = new SandboxBackedFilesystem(); + capturedSandboxFs.configureNamespace(buildDynamicNamespaceFactory(userIdRef)); + filesystem = capturedSandboxFs; + + defaultSandboxContext = sandboxFilesystemSpec.toSandboxContext(resolvedWorkspace); + if (sandboxDistributedOptions != null + && sandboxDistributedOptions.isRequireDistributed()) { + validateDistributedSandboxConfig(effectiveSession, defaultSandboxContext); + } + + SandboxStateStore stateStore = + sandboxStateStore != null + ? sandboxStateStore + : new SessionSandboxStateStore(effectiveSession, resolvedAgentId); + SandboxManager sandboxManager = + new SandboxManager( + defaultSandboxContext.getClient(), stateStore, resolvedAgentId); + sandboxLifecycleHook = new SandboxLifecycleHook(sandboxManager, capturedSandboxFs); + } + WorkspaceManager wsManager = new WorkspaceManager(resolvedWorkspace, filesystem); wsManager.validate(); Memory memory = new InMemoryMemory(); @@ -737,32 +913,26 @@ public HarnessAgent build() { // ---- Hooks ---- List allHooks = new ArrayList<>(hooks); + // Sandbox lifecycle hook runs first (priority=50) — acquire/release sandbox session + if (sandboxLifecycleHook != null) { + allHooks.add(sandboxLifecycleHook); + } + if (agentTracingLogEnabled) { allHooks.add(new AgentTraceHook()); } RuntimeContextAwareHook wsContextHook; - if (useLegacyXmlWorkspaceContext) { - WorkspaceContextHook xmlHook = - new WorkspaceContextHook( - wsManager, - name != null ? name : "HarnessAgent", - environmentMemory, - maxContextTokens); - xmlHook.setAdditionalContextFiles(additionalContextFiles); - allHooks.add(xmlHook); - wsContextHook = xmlHook; - } else { - WorkspaceContextHook markdownHook = - new WorkspaceContextHook( - wsManager, - name != null ? name : "HarnessAgent", - environmentMemory, - maxContextTokens); - markdownHook.setAdditionalContextFiles(additionalContextFiles); - allHooks.add(markdownHook); - wsContextHook = markdownHook; - } + + WorkspaceContextHook markdownHook = + new WorkspaceContextHook( + wsManager, + name != null ? name : "HarnessAgent", + environmentMemory, + maxContextTokens); + markdownHook.setAdditionalContextFiles(additionalContextFiles); + allHooks.add(markdownHook); + wsContextHook = markdownHook; MemoryFlushHook memoryFlushHook = null; if (model != null) { @@ -770,6 +940,11 @@ public HarnessAgent build() { allHooks.add(memoryFlushHook); } + if (model != null) { + MemoryConsolidator consolidator = new MemoryConsolidator(wsManager, model); + allHooks.add(new MemoryMaintenanceHook(wsManager, consolidator)); + } + CompactionHook compactionHook = null; if (compactionConfig != null && model != null) { compactionHook = new CompactionHook(wsManager, model, compactionConfig); @@ -777,14 +952,15 @@ public HarnessAgent build() { } if (toolResultEvictionConfig != null) { - allHooks.add(new ToolResultEvictionHook(backend, toolResultEvictionConfig)); + allHooks.add(new ToolResultEvictionHook(filesystem, toolResultEvictionConfig)); } SessionPersistenceHook sessionPersistenceHook = new SessionPersistenceHook(); allHooks.add(sessionPersistenceHook); if (!leafSubagent && model != null) { - SubagentsHook subagentsHook = buildSubagentsHook(wsManager, resolvedWorkspace); + SubagentsHook subagentsHook = + buildSubagentsHook(wsManager, resolvedWorkspace, capturedSandboxFs); if (subagentsHook != null) { allHooks.add(subagentsHook); } @@ -793,31 +969,16 @@ public HarnessAgent build() { // ---- Toolkit ---- Toolkit agentToolkit = toolkit; - MemoryIndex memIdx = null; MemorySearchTool searchTool = new MemorySearchTool(wsManager); MemoryGetTool getTool = new MemoryGetTool(wsManager); - Path agentscopeDir = resolvedWorkspace.getParent(); - if (agentscopeDir == null) { - agentscopeDir = resolvedWorkspace; - } - memIdx = new MemoryIndex(agentscopeDir); - try { - memIdx.indexAllFromWorkspace(wsManager); - searchTool.setMemoryIndex(memIdx); - } catch (Exception e) { - log.warn( - "Failed to build memory index, falling back to keyword search: {}", - e.getMessage()); - } - agentToolkit.registerTool(searchTool); agentToolkit.registerTool(getTool); agentToolkit.registerTool(new SessionSearchTool(wsManager)); - agentToolkit.registerTool(new FilesystemTool(backend)); + agentToolkit.registerTool(new FilesystemTool(filesystem)); - if (backend instanceof AbstractSandboxFilesystem sandbox) { + if (filesystem instanceof AbstractSandboxFilesystem sandbox) { agentToolkit.registerTool(new ShellExecuteTool(sandbox)); } @@ -855,37 +1016,13 @@ public HarnessAgent build() { ReActAgent delegate = reactBuilder.build(); - if (memIdx != null && memoryFlushHook != null) { - memoryFlushHook.setMemoryIndex(memIdx); - } - if (memIdx != null && compactionHook != null) { - compactionHook.setMemoryIndex(memIdx); - } - log.info( "HarnessAgent '{}' built [workspace={}, backend={}, subagents={}]", name, resolvedWorkspace, - backend.getClass().getSimpleName(), + filesystem.getClass().getSimpleName(), !leafSubagent && model != null); - MemoryMaintenanceScheduler scheduler = null; - if (memIdx != null) { - scheduler = new MemoryMaintenanceScheduler(wsManager, memIdx, model); - } - if (scheduler != null && memoryFlushHook != null) { - memoryFlushHook.setMaintenanceScheduler(scheduler); - } - if (scheduler != null && compactionHook != null) { - compactionHook.setMaintenanceScheduler(scheduler); - } - - Session defaultSession = session; - if (defaultSession == null) { - String agentId = name != null ? name : "HarnessAgent"; - defaultSession = new WorkspaceSession(resolvedWorkspace, agentId); - } - return new HarnessAgent( delegate, wsManager, @@ -893,9 +1030,11 @@ public HarnessAgent build() { memoryFlushHook, sessionPersistenceHook, compactionHook, - scheduler, userIdRef, - defaultSession); + sessionIdRef, + effectiveSession, + sandboxLifecycleHook, + defaultSandboxContext); } // @formatter:off @@ -955,15 +1094,44 @@ private static String buildSubagentSysPrompt(String basePrompt) { // Backend // ----------------------------------------------------------------- - private AbstractFilesystem resolveBackend( - Path workspace, AtomicReference userIdRef) { + private AbstractFilesystem resolveFilesystem( + Path workspace, + String agentId, + AtomicReference userIdRef, + AtomicReference sessionIdRef) { if (abstractFilesystem != null) { return abstractFilesystem; } NamespaceFactory nsFactory = buildDynamicNamespaceFactory(userIdRef); + if (storeFilesystemSpec != null) { + return storeFilesystemSpec.toFilesystem( + workspace, agentId, nsFactory, userIdRef::get, sessionIdRef::get); + } + if (localFilesystemSpec != null) { + return localFilesystemSpec.toFilesystem(workspace, nsFactory); + } + // Default to Mode 3 with out-of-the-box LocalFilesystemWithShell settings. return new LocalFilesystemWithShell(workspace, nsFactory); } + private void validateDistributedSandboxConfig( + Session effectiveSession, SandboxContext sandboxContext) { + if (sandboxStateStore == null && effectiveSession instanceof WorkspaceSession) { + throw new IllegalStateException( + "sandboxDistributed(requireDistributed=true) requires a distributed" + + " Session backend (for example RedisSession)." + + " Current effective session is WorkspaceSession."); + } + if (sandboxContext == null + || sandboxContext.getSnapshotSpec() == null + || sandboxContext.getSnapshotSpec() instanceof NoopSnapshotSpec) { + throw new IllegalStateException( + "sandboxDistributed(requireDistributed=true) requires a non-noop" + + " snapshotSpec to restore workspace archives across" + + " distributed instances."); + } + } + private static NamespaceFactory buildDynamicNamespaceFactory( AtomicReference userIdRef) { return () -> { @@ -979,8 +1147,9 @@ private static NamespaceFactory buildDynamicNamespaceFactory( // Subagents // ----------------------------------------------------------------- - private SubagentsHook buildSubagentsHook(WorkspaceManager wsManager, Path workspace) { - List entries = buildSubagentEntries(workspace); + private SubagentsHook buildSubagentsHook( + WorkspaceManager wsManager, Path workspace, SandboxBackedFilesystem sandboxFs) { + List entries = buildSubagentEntries(workspace, sandboxFs); TaskRepository repo = taskRepository != null ? taskRepository : new DefaultTaskRepository(); @@ -995,10 +1164,12 @@ private SubagentsHook buildSubagentsHook(WorkspaceManager wsManager, Path worksp * mirrors the main agent's configuration (same model, workspace, file system, user hooks) * but disables subagent support to prevent recursive spawning. */ - private SubagentFactory buildGeneralPurposeFactory(Path workspace) { + private SubagentFactory buildGeneralPurposeFactory( + Path workspace, SandboxBackedFilesystem sandboxFs) { // Capture builder state for the closure final Model capturedModel = this.model; - final AbstractFilesystem capturedBackend = this.abstractFilesystem; + final AbstractFilesystem capturedBackend = + sandboxFs != null ? sandboxFs : this.abstractFilesystem; final int capturedMaxIters = this.maxIters; final ExecutionConfig capturedModelExec = this.modelExecutionConfig; final ExecutionConfig capturedToolExec = this.toolExecutionConfig; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java new file mode 100644 index 000000000..74eb6737b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +/** + * Controls how agent state is isolated and shared across calls. + * + *

This enum is the canonical isolation-scope definition used by both the sandbox filesystem + * backend ({@link io.agentscope.harness.agent.sandbox.SandboxContext}) and the store filesystem + * backend ({@link io.agentscope.harness.agent.filesystem.StoreFilesystemSpec}). + * + *

Sandbox semantics: the scope determines which key is used when persisting and loading + * {@code _sandbox.json} state. Calls that resolve to the same scope key will + * sequentially reuse the same sandbox (each call resumes the persisted state from the previous + * one). + * + *

Store namespace semantics: the scope determines the namespace prefix used by + * {@link io.agentscope.harness.agent.filesystem.StoreFilesystem} when routing files to the shared + * key-value store. Different scopes produce different namespace prefixes, controlling which calls + * share the same view of stored files. + * + *

Scope selection: + *

    + *
  • {@link #SESSION} – isolated per session; the default.
  • + *
  • {@link #USER} – shared across all sessions of the same user.
  • + *
  • {@link #AGENT} – shared across all users and sessions of the same agent.
  • + *
  • {@link #GLOBAL} – globally shared within the same workspace/store instance.
  • + *
+ * + *

Concurrency note: for sandbox mode this is sequential-reuse sharing, not + * live-instance sharing. Concurrent calls at the same scope each get their own running container; + * they converge on the last persisted snapshot at the end of the call. + */ +public enum IsolationScope { + + /** + * Isolate by session identifier. + * + *

This is the default behavior. Each distinct session gets its own sandbox state / + * store namespace. If no session key is present in the + * {@link io.agentscope.harness.agent.RuntimeContext}, state lookup is skipped and a fresh + * sandbox is created (or a default store namespace is used). + */ + SESSION, + + /** + * Share across all sessions belonging to the same + * {@link io.agentscope.harness.agent.RuntimeContext#getUserId() userId}. + * + *

If {@code userId} is blank, a warning is logged and state lookup / namespace resolution + * degrades to the default (fresh sandbox create, or an anonymous-user namespace). + */ + USER, + + /** + * Share across all users and sessions of the same agent (identified by agent name). + * + *

The agent name is fixed at build time and is always available; this scope never + * degrades due to a missing context field. + */ + AGENT, + + /** + * One shared state / namespace globally within the same workspace store instance. + * + *

Use with care: all agents and users that share the same store will compete to write + * the global slot. + */ + GLOBAL +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java index e61f04e10..a95b6b75b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java @@ -17,6 +17,7 @@ import io.agentscope.core.session.Session; import io.agentscope.core.state.SessionKey; +import io.agentscope.harness.agent.sandbox.SandboxContext; import java.util.HashMap; import java.util.Map; @@ -33,6 +34,7 @@ public class RuntimeContext { private final Session session; private final SessionKey sessionKey; private final Map extra; + private final SandboxContext sandboxContext; private RuntimeContext(Builder builder) { this.sessionId = builder.sessionId; @@ -40,6 +42,7 @@ private RuntimeContext(Builder builder) { this.session = builder.session; this.sessionKey = builder.sessionKey; this.extra = Map.copyOf(builder.extra); + this.sandboxContext = builder.sandboxContext; } public String getSessionId() { @@ -67,6 +70,15 @@ public Map getExtra() { return extra; } + /** + * Returns the sandbox context for this call. + * + * @return sandbox context, or {@code null} if sandbox is not configured + */ + public SandboxContext getSandboxContext() { + return sandboxContext; + } + public static Builder builder() { return new Builder(); } @@ -77,6 +89,7 @@ public static class Builder { private Session session; private SessionKey sessionKey; private final Map extra = new HashMap<>(); + private SandboxContext sandboxContext; public Builder sessionId(String sessionId) { this.sessionId = sessionId; @@ -110,6 +123,17 @@ public Builder putAll(Map extras) { return this; } + /** + * Sets the sandbox context for this call. + * + * @param sandboxContext sandbox configuration and state + * @return this builder + */ + public Builder sandboxContext(SandboxContext sandboxContext) { + this.sandboxContext = sandboxContext; + return this; + } + public RuntimeContext build() { return new RuntimeContext(this); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java index 9d53638ad..a22c5fa0a 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java @@ -105,4 +105,55 @@ public interface AbstractFilesystem { * @return list of FileDownloadResponse objects, one per input path (order matches input order) */ List downloadFiles(List paths); + + /** + * Delete a file or directory (recursive for directories). + * + *

Idempotent: deleting a path that does not exist is treated as success. + * + * @param path absolute path to the file or directory to delete + * @return WriteResult success when deleted (or already absent), failure on I/O error + */ + WriteResult delete(String path); + + /** + * Move (rename) a file or directory from {@code fromPath} to {@code toPath}. + * + *

Implementations that span multiple backends (e.g. {@code CompositeFilesystem}) may + * fall back to a read + write + delete sequence when source and destination live in + * different backend filesystems. + * + * @param fromPath absolute source path + * @param toPath absolute destination path + * @return WriteResult success on completion, failure on I/O error or missing source + */ + WriteResult move(String fromPath, String toPath); + + /** + * Check whether a file or directory exists. + * + *

Implementations may approximate this with a lightweight read probe where a dedicated + * {@code exists} API is unavailable, but should avoid reading full file content. + * + * @param path absolute path to check + * @return {@code true} if the path exists, {@code false} otherwise + */ + boolean exists(String path); + + // ==================== Path validation utility ==================== + + /** + * Validates that {@code path} is safe (non-null, non-blank, no {@code ..} traversal). + * + * @param path the path to validate + * @throws IllegalArgumentException if the path is invalid + */ + static void validatePath(String path) { + if (path == null || path.isBlank()) { + throw new IllegalArgumentException("Path must not be null or blank"); + } + if (path.contains("..")) { + throw new IllegalArgumentException("Path traversal ('..') not allowed: " + path); + } + } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java index d9f662c8e..8b8d0e4de 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java @@ -27,8 +27,8 @@ import io.agentscope.harness.agent.filesystem.model.LsResult; import io.agentscope.harness.agent.filesystem.model.ReadResult; import io.agentscope.harness.agent.filesystem.model.WriteResult; -import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import io.agentscope.harness.agent.store.NamespaceFactory; import java.util.ArrayList; import java.util.Base64; import java.util.List; @@ -361,6 +361,48 @@ public GlobResult glob(String pattern, String path) { return GlobResult.success(entries); } + @Override + public WriteResult delete(String path) { + AbstractFilesystem.validatePath(path); + String effectivePath = namespacedPath(path); + String escapedPath = FilesystemUtils.shellQuote(effectivePath); + String cmd = "rm -rf " + escapedPath; + ExecuteResponse result = execute(cmd, null); + if (result.exitCode() != 0) { + return WriteResult.fail("Error deleting '" + path + "': " + result.output()); + } + return WriteResult.ok(path); + } + + @Override + public WriteResult move(String fromPath, String toPath) { + AbstractFilesystem.validatePath(fromPath); + AbstractFilesystem.validatePath(toPath); + String from = namespacedPath(fromPath); + String to = namespacedPath(toPath); + String escapedFrom = FilesystemUtils.shellQuote(from); + String escapedTo = FilesystemUtils.shellQuote(to); + String cmd = "mkdir -p $(dirname " + escapedTo + ") && mv " + escapedFrom + " " + escapedTo; + ExecuteResponse result = execute(cmd, null); + if (result.exitCode() != 0) { + return WriteResult.fail( + "Error moving '" + fromPath + "' to '" + toPath + "': " + result.output()); + } + return WriteResult.ok(toPath); + } + + @Override + public boolean exists(String path) { + if (path == null || path.isBlank()) { + return false; + } + String effectivePath = namespacedPath(path); + String escapedPath = FilesystemUtils.shellQuote(effectivePath); + ExecuteResponse result = + execute("test -e " + escapedPath + " && echo yes || echo no", null); + return result.output() != null && result.output().strip().startsWith("yes"); + } + private static String jsonEscape(String s) { if (s == null) { return ""; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java index 74281e374..29a21c3e3 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java @@ -16,7 +16,6 @@ package io.agentscope.harness.agent.filesystem; import io.agentscope.harness.agent.filesystem.model.EditResult; -import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; import io.agentscope.harness.agent.filesystem.model.FileInfo; import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; @@ -36,21 +35,27 @@ * Routes file operations to different {@link AbstractFilesystem} backends by path prefix. * *

Paths are matched against route prefixes (longest first). Unmatched paths fall through to the - * default backend. If the default backend implements {@link AbstractSandboxFilesystem}, shell - * execution is also supported. + * default backend. + * + *

Composite deliberately implements only {@link AbstractFilesystem} — it is the unified, + * non-sandbox view that blends a local workspace with remote-store-backed paths. Shell execution + * is intentionally not supported in this mode: routing shell commands across backends is + * ambiguous, and the primary use case (distributed memory with per-user/session isolation) does + * not need it. If you need shell execution, use a sandbox-backed filesystem + * ({@link AbstractSandboxFilesystem}) or {@link LocalFilesystemWithShell} directly instead. * *

Example: * *

{@code
  * CompositeFilesystem fs = new CompositeFilesystem(
- *     localShell,
+ *     localFs,
  *     Map.of("/memories/", storeFs, "/cache/", inMemoryFs)
  * );
  * fs.read("/memories/notes.md", 0, 100);  // → storeFs.read("/notes.md", ...)
- * fs.read("/src/Main.java", 0, 100);      // → localShell.read("/src/Main.java", ...)
+ * fs.read("/src/Main.java", 0, 100);      // → localFs.read("/src/Main.java", ...)
  * }
*/ -public class CompositeFilesystem implements AbstractSandboxFilesystem { +public class CompositeFilesystem implements AbstractFilesystem { private final AbstractFilesystem defaultBackend; private final List sortedRoutes; @@ -93,7 +98,11 @@ private RouteResult routeForPath(String path) { ? entry.prefix().substring(0, entry.prefix().length() - 1) : entry.prefix(); if (path.equals(prefixNoSlash)) { - return new RouteResult(entry.backend(), "/", entry.prefix()); + if (entry.prefix().endsWith("/")) { + return new RouteResult(entry.backend(), "/", entry.prefix()); + } + String backendPath = path.startsWith("/") ? path : "/" + path; + return new RouteResult(entry.backend(), backendPath, entry.prefix()); } String normalizedPrefix = entry.prefix().endsWith("/") ? entry.prefix() : entry.prefix() + "/"; @@ -159,6 +168,9 @@ public LsResult ls(String path) { results.addAll(defaultResult.entries()); } for (RouteEntry entry : sortedRoutes) { + if (!entry.prefix().endsWith("/")) { + continue; + } String dirPath = entry.prefix().endsWith("/") ? entry.prefix() : entry.prefix() + "/"; results.add(FileInfo.ofDir(dirPath, "")); @@ -333,33 +345,58 @@ public List downloadFiles(List paths) { return List.of(results); } - // ==================== AbstractSandboxFilesystem ==================== - @Override - public String id() { - if (defaultBackend instanceof AbstractSandboxFilesystem sandbox) { - return sandbox.id(); + public WriteResult delete(String path) { + AbstractFilesystem.validatePath(path); + RouteResult route = routeForPath(path); + WriteResult result = route.backend().delete(route.backendPath()); + if (result.isSuccess() && route.routePrefix() != null) { + return WriteResult.ok(path); } - return "composite"; + return result; } @Override - public ExecuteResponse execute(String command, Integer timeoutSeconds) { - if (defaultBackend instanceof AbstractSandboxFilesystem sandbox) { - return sandbox.execute(command, timeoutSeconds); + public WriteResult move(String fromPath, String toPath) { + AbstractFilesystem.validatePath(fromPath); + AbstractFilesystem.validatePath(toPath); + RouteResult srcRoute = routeForPath(fromPath); + RouteResult dstRoute = routeForPath(toPath); + + if (srcRoute.backend() == dstRoute.backend()) { + WriteResult result = + srcRoute.backend().move(srcRoute.backendPath(), dstRoute.backendPath()); + if (result.isSuccess()) { + return WriteResult.ok(toPath); + } + return result; } - throw new UnsupportedOperationException( - "Default backend does not support command execution (AbstractSandboxFilesystem). " - + "To enable execution, provide a default backend that implements" - + " AbstractSandboxFilesystem."); + + // Cross-backend move: read → write → delete + var readResult = srcRoute.backend().read(srcRoute.backendPath(), 0, 0); + if (!readResult.isSuccess() || readResult.fileData() == null) { + return WriteResult.fail("Cannot read source for cross-backend move: " + fromPath); + } + String content = readResult.fileData().content(); + if (content == null) { + content = ""; + } + WriteResult writeResult = dstRoute.backend().write(dstRoute.backendPath(), content); + if (!writeResult.isSuccess()) { + return WriteResult.fail( + "Cross-backend move write failed for '" + toPath + "': " + writeResult.error()); + } + srcRoute.backend().delete(srcRoute.backendPath()); + return WriteResult.ok(toPath); } - /** - * Whether this composite filesystem supports shell execution (i.e. the default backend is a - * sandbox). - */ - public boolean isSandbox() { - return defaultBackend instanceof AbstractSandboxFilesystem; + @Override + public boolean exists(String path) { + if (path == null || path.isBlank()) { + return false; + } + RouteResult route = routeForPath(path); + return route.backend().exists(route.backendPath()); } /** Returns the default backend. */ diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java index 76663d49b..d149f21ad 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java @@ -26,8 +26,8 @@ import io.agentscope.harness.agent.filesystem.model.LsResult; import io.agentscope.harness.agent.filesystem.model.ReadResult; import io.agentscope.harness.agent.filesystem.model.WriteResult; -import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import io.agentscope.harness.agent.store.NamespaceFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -40,6 +40,7 @@ import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.ArrayList; @@ -386,6 +387,68 @@ public List downloadFiles(List paths) { return responses; } + @Override + public WriteResult delete(String path) { + AbstractFilesystem.validatePath(path); + Path resolved = resolvePath(path); + if (!Files.exists(resolved)) { + return WriteResult.ok(path); // idempotent + } + try { + if (Files.isDirectory(resolved)) { + try (Stream walk = Files.walk(resolved)) { + walk.sorted(Comparator.reverseOrder()) + .forEach( + p -> { + try { + Files.delete(p); + } catch (IOException e) { + log.warn("Failed to delete {}: {}", p, e.getMessage()); + } + }); + } + } else { + Files.delete(resolved); + } + return WriteResult.ok(path); + } catch (IOException e) { + return WriteResult.fail("Error deleting '" + path + "': " + e.getMessage()); + } + } + + @Override + public WriteResult move(String fromPath, String toPath) { + AbstractFilesystem.validatePath(fromPath); + AbstractFilesystem.validatePath(toPath); + Path from = resolvePath(fromPath); + Path to = resolvePath(toPath); + if (!Files.exists(from)) { + return WriteResult.fail("Source does not exist: " + fromPath); + } + try { + if (to.getParent() != null) { + Files.createDirectories(to.getParent()); + } + Files.move(from, to, StandardCopyOption.REPLACE_EXISTING); + return WriteResult.ok(toPath); + } catch (IOException e) { + return WriteResult.fail( + "Error moving '" + fromPath + "' to '" + toPath + "': " + e.getMessage()); + } + } + + @Override + public boolean exists(String path) { + if (path == null || path.isBlank()) { + return false; + } + try { + return Files.exists(resolvePath(path)); + } catch (SecurityException e) { + return false; + } + } + // ==================== Path resolution ==================== protected NamespaceFactory getNamespaceFactory() { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java new file mode 100644 index 000000000..328d5ddde --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java @@ -0,0 +1,128 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.store.NamespaceFactory; +import java.nio.file.Path; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Specification for the local filesystem mode (with shell execution). + * + *

This spec produces a {@link LocalFilesystemWithShell} whose root is the agent workspace and + * whose shell runs directly on the host as {@code sh -c }. Long-term memory + * ({@code MEMORY.md}, {@code memory/}) and session logs live on the same local disk. + * + *

Suitable for single-process deployments (personal assistants, CLI tools, local dev loops) + * where distributed sharing is not required and the agent is trusted to run host shell commands. + * + *

For distributed deployments where long-term memory must be shared across replicas, prefer + * {@link StoreFilesystemSpec} (no shell) or a sandbox filesystem spec (shell via sandbox). + */ +public class LocalFilesystemSpec { + + private int executeTimeoutSeconds = LocalFilesystemWithShell.DEFAULT_EXECUTE_TIMEOUT; + private int maxOutputBytes = 100_000; + private final Map env = new LinkedHashMap<>(); + private boolean inheritEnv = false; + private boolean virtualMode = false; + + /** + * Sets the default command execution timeout in seconds. + * + * @param seconds timeout (must be positive) + * @return this spec + */ + public LocalFilesystemSpec executeTimeoutSeconds(int seconds) { + if (seconds <= 0) { + throw new IllegalArgumentException("timeout must be positive, got " + seconds); + } + this.executeTimeoutSeconds = seconds; + return this; + } + + /** + * Sets the maximum number of output bytes captured from any single shell command. + * + * @param bytes byte cap (must be positive) + * @return this spec + */ + public LocalFilesystemSpec maxOutputBytes(int bytes) { + if (bytes <= 0) { + throw new IllegalArgumentException("maxOutputBytes must be positive, got " + bytes); + } + this.maxOutputBytes = bytes; + return this; + } + + /** + * Adds an environment variable that will be set for every shell command. + * + * @param name variable name + * @param value variable value + * @return this spec + */ + public LocalFilesystemSpec env(String name, String value) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("env name must not be blank"); + } + this.env.put(name, value); + return this; + } + + /** + * Controls whether the parent process environment is inherited by shell commands. When + * {@code false} (default), only variables added via {@link #env(String, String)} are visible. + * + * @param inherit whether to inherit parent env + * @return this spec + */ + public LocalFilesystemSpec inheritEnv(boolean inherit) { + this.inheritEnv = inherit; + return this; + } + + /** + * Enables virtual-path mode: paths are anchored to the workspace root and traversal outside + * is blocked. + * + * @param virtual whether to enable virtual mode + * @return this spec + */ + public LocalFilesystemSpec virtualMode(boolean virtual) { + this.virtualMode = virtual; + return this; + } + + /** + * Builds the effective filesystem rooted at {@code workspace}. + * + * @param workspace agent workspace root + * @param localNamespaceFactory optional namespace factory for per-user/session folder scoping + * @return a {@link LocalFilesystemWithShell} wired with the options in this spec + */ + public AbstractFilesystem toFilesystem(Path workspace, NamespaceFactory localNamespaceFactory) { + return new LocalFilesystemWithShell( + workspace, + virtualMode, + executeTimeoutSeconds, + maxOutputBytes, + env.isEmpty() ? null : Map.copyOf(env), + inheritEnv, + localNamespaceFactory); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java index dce2a61e2..b5d04b372 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java @@ -16,7 +16,7 @@ package io.agentscope.harness.agent.filesystem; import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; -import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; +import io.agentscope.harness.agent.store.NamespaceFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java index 2967aa08d..f69bd1136 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java @@ -26,10 +26,10 @@ import io.agentscope.harness.agent.filesystem.model.LsResult; import io.agentscope.harness.agent.filesystem.model.ReadResult; import io.agentscope.harness.agent.filesystem.model.WriteResult; -import io.agentscope.harness.agent.filesystem.store.BaseStore; -import io.agentscope.harness.agent.filesystem.store.NamespaceFactory; -import io.agentscope.harness.agent.filesystem.store.StoreItem; import io.agentscope.harness.agent.filesystem.util.FilesystemUtils; +import io.agentscope.harness.agent.store.BaseStore; +import io.agentscope.harness.agent.store.NamespaceFactory; +import io.agentscope.harness.agent.store.StoreItem; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.PathMatcher; @@ -380,6 +380,67 @@ public List downloadFiles(List paths) { return responses; } + @Override + public WriteResult delete(String path) { + AbstractFilesystem.validatePath(path); + List ns = getNamespace(); + List items = searchAllItems(); + String normalizedPath = normalizePath(path); + boolean deleted = false; + for (StoreItem item : items) { + if (item.key().equals(normalizedPath) || item.key().startsWith(normalizedPath + "/")) { + store.delete(ns, item.key()); + deleted = true; + } + } + // idempotent — not found is still success + return WriteResult.ok(path); + } + + @Override + public WriteResult move(String fromPath, String toPath) { + AbstractFilesystem.validatePath(fromPath); + AbstractFilesystem.validatePath(toPath); + List ns = getNamespace(); + List items = searchAllItems(); + String normFrom = normalizePath(fromPath); + String normTo = normalizePath(toPath); + boolean found = false; + for (StoreItem item : items) { + String key = item.key(); + if (key.equals(normFrom) || key.startsWith(normFrom + "/")) { + String newKey = normTo + key.substring(normFrom.length()); + store.put(ns, newKey, item.value()); + store.delete(ns, key); + found = true; + } + } + if (!found) { + return WriteResult.fail("Source does not exist: " + fromPath); + } + return WriteResult.ok(toPath); + } + + @Override + public boolean exists(String path) { + if (path == null || path.isBlank()) { + return false; + } + List ns = getNamespace(); + String normalized = normalizePath(path); + if (store.get(ns, normalized) != null) { + return true; + } + // Also check if any child exists (directory-like) + List items = searchAllItems(); + for (StoreItem item : items) { + if (item.key().startsWith(normalized + "/")) { + return true; + } + } + return false; + } + // ==================== Internal helpers ==================== private List searchAllItems() { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java new file mode 100644 index 000000000..d185d09f5 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java @@ -0,0 +1,190 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.store.BaseStore; +import io.agentscope.harness.agent.store.NamespaceFactory; +import java.nio.file.Path; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +/** + * Specification for the non-sandbox "composite" filesystem mode. + * + *

This spec produces a {@link CompositeFilesystem} that blends: + * + *

    + *
  • a plain {@link LocalFilesystem} (no shell) for workspace-local, ephemeral files such as + * skills/, knowledge/, additional context files, etc.; + *
  • a shared {@link StoreFilesystem} for cross-node paths that must be identical across all + * replicas (long-term memory, offloaded session logs). + *
+ * + *

Because the default backend is {@link LocalFilesystem} (not {@link LocalFilesystemWithShell}), + * shell execution is intentionally not available in this mode — use a sandbox filesystem spec or + * {@link LocalFilesystemWithShell} if shell is required. + * + *

Default shared routes: + * + *

    + *
  • {@code MEMORY.md} + *
  • {@code memory/} + *
  • {@code agents//sessions/} + *
+ * + *

The store namespace for shared files is controlled by {@link #isolationScope(IsolationScope)}, + * which mirrors the sandbox isolation semantics: + * + *

    + *
  • {@link IsolationScope#SESSION} — namespace per session
  • + *
  • {@link IsolationScope#USER} (default) — namespace per user, shared across sessions
  • + *
  • {@link IsolationScope#AGENT} — namespace per agent, shared across all users
  • + *
  • {@link IsolationScope#GLOBAL} — single global namespace
  • + *
+ */ +public class StoreFilesystemSpec { + + private final BaseStore store; + private final Set extraSharedPrefixes = new LinkedHashSet<>(); + private String anonymousUserId = "_default"; + private IsolationScope isolationScope = IsolationScope.USER; + + public StoreFilesystemSpec(BaseStore store) { + if (store == null) { + throw new IllegalArgumentException("store must not be null"); + } + this.store = store; + } + + /** + * Adds an extra workspace-relative prefix routed to the shared store. + * + *

Examples: {@code knowledge/}, {@code prompts/}. + */ + public StoreFilesystemSpec addSharedPrefix(String prefix) { + if (prefix != null && !prefix.isBlank()) { + extraSharedPrefixes.add(normalizePrefix(prefix)); + } + return this; + } + + /** + * Sets the fallback user identifier when runtime {@code userId} is absent/blank. + */ + public StoreFilesystemSpec anonymousUserId(String userId) { + if (userId == null || userId.isBlank()) { + throw new IllegalArgumentException("anonymous user id must not be blank"); + } + this.anonymousUserId = userId; + return this; + } + + /** + * Sets the isolation scope that controls the store namespace for shared files. + * + *

Mirrors the sandbox {@link io.agentscope.harness.agent.sandbox.SandboxContext} isolation + * semantics. Defaults to {@link IsolationScope#USER}. + * + * @param scope isolation scope + * @return this spec + */ + public StoreFilesystemSpec isolationScope(IsolationScope scope) { + if (scope == null) { + throw new IllegalArgumentException("isolation scope must not be null"); + } + this.isolationScope = scope; + return this; + } + + /** + * Builds the effective filesystem: + * + *

    + *
  • default backend: {@link LocalFilesystem} (no shell) + *
  • shared routes: {@link StoreFilesystem} with scope-driven namespace + *
+ */ + public AbstractFilesystem toFilesystem( + Path workspace, + String agentId, + NamespaceFactory localNamespaceFactory, + Supplier userIdSupplier, + Supplier sessionIdSupplier) { + String effectiveAgentId = agentId == null || agentId.isBlank() ? "HarnessAgent" : agentId; + AbstractFilesystem local = new LocalFilesystem(workspace, false, 10, localNamespaceFactory); + StoreFilesystem shared = + new StoreFilesystem( + store, storeNamespace(effectiveAgentId, userIdSupplier, sessionIdSupplier)); + + Map routes = new LinkedHashMap<>(); + routes.put("MEMORY.md", shared); + routes.put("memory/", shared); + routes.put("agents/" + effectiveAgentId + "/sessions/", shared); + for (String extra : extraSharedPrefixes) { + routes.put(extra, shared); + } + return new CompositeFilesystem(local, routes); + } + + /** + * Builds the effective filesystem without session-level isolation. + * + *

Convenience overload for callers that don't provide a session-id supplier. + * Equivalent to calling {@link #toFilesystem(Path, String, NamespaceFactory, Supplier, Supplier)} + * with {@code () -> null} as the sessionIdSupplier. + */ + public AbstractFilesystem toFilesystem( + Path workspace, + String agentId, + NamespaceFactory localNamespaceFactory, + Supplier userIdSupplier) { + return toFilesystem(workspace, agentId, localNamespaceFactory, userIdSupplier, () -> null); + } + + private NamespaceFactory storeNamespace( + String agentId, Supplier userIdSupplier, Supplier sessionIdSupplier) { + return () -> { + String uid = userIdSupplier != null ? userIdSupplier.get() : null; + String sid = sessionIdSupplier != null ? sessionIdSupplier.get() : null; + + return switch (isolationScope) { + case SESSION -> { + String effectiveSid = (sid != null && !sid.isBlank()) ? sid : "default"; + yield List.of("agents", agentId, "sessions", effectiveSid); + } + case USER -> { + String effectiveUid = (uid != null && !uid.isBlank()) ? uid : anonymousUserId; + yield List.of("agents", agentId, "users", effectiveUid); + } + case AGENT -> List.of("agents", agentId, "shared"); + case GLOBAL -> List.of("global"); + }; + }; + } + + private static String normalizePrefix(String prefix) { + String normalized = prefix.replace('\\', '/').strip(); + while (normalized.startsWith("/")) { + normalized = normalized.substring(1); + } + return normalized; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java similarity index 89% rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java index aa8033de4..62cc901b1 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/CompactionHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.agentscope.harness.agent.memory.compaction; +package io.agentscope.harness.agent.hook; import io.agentscope.core.ReActAgent; import io.agentscope.core.hook.Hook; @@ -25,8 +25,8 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.MemoryFlushManager; -import io.agentscope.harness.agent.memory.MemoryIndex; -import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; +import io.agentscope.harness.agent.memory.compaction.CompactionConfig; +import io.agentscope.harness.agent.memory.compaction.ConversationCompactor; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.util.ArrayList; import java.util.List; @@ -63,8 +63,6 @@ public class CompactionHook implements Hook { private final CompactionConfig config; private RuntimeContext runtimeContext; - private volatile MemoryIndex memoryIndex; - private volatile MemoryMaintenanceScheduler maintenanceScheduler; public CompactionHook(WorkspaceManager workspaceManager, Model model, CompactionConfig config) { this.workspaceManager = workspaceManager; @@ -76,15 +74,6 @@ public void setRuntimeContext(RuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } - public void setMemoryIndex(MemoryIndex memoryIndex) { - this.memoryIndex = memoryIndex; - } - - /** Wires the maintenance scheduler so flushes can opportunistically consolidate MEMORY.md. */ - public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { - this.maintenanceScheduler = scheduler; - } - @Override public int priority() { return 10; @@ -188,10 +177,7 @@ private static void applyToEvent( // ------------------------------------------------------------------------- private MemoryFlushManager buildFlushManager() { - MemoryFlushManager fm = new MemoryFlushManager(workspaceManager, model); - fm.setMemoryIndex(memoryIndex); - fm.setMaintenanceScheduler(maintenanceScheduler); - return fm; + return new MemoryFlushManager(workspaceManager, model); } private String sessionId() { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java index 4b4c1cdbe..f47762b86 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java @@ -25,8 +25,6 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.MemoryFlushManager; -import io.agentscope.harness.agent.memory.MemoryIndex; -import io.agentscope.harness.agent.memory.MemoryMaintenanceScheduler; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.util.List; import org.slf4j.Logger; @@ -52,8 +50,6 @@ public class MemoryFlushHook implements Hook { private final WorkspaceManager workspaceManager; private final Model model; private RuntimeContext runtimeContext; - private volatile MemoryIndex memoryIndex; - private volatile MemoryMaintenanceScheduler maintenanceScheduler; public MemoryFlushHook(WorkspaceManager workspaceManager, Model model) { this.workspaceManager = workspaceManager; @@ -64,18 +60,6 @@ public void setRuntimeContext(RuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } - public void setMemoryIndex(MemoryIndex memoryIndex) { - this.memoryIndex = memoryIndex; - } - - /** - * Wires the maintenance scheduler so each flush can opportunistically request a - * MEMORY.md consolidation (throttled by the scheduler). - */ - public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { - this.maintenanceScheduler = scheduler; - } - @Override public Mono onEvent(T event) { if (event instanceof PostCallEvent) { @@ -101,8 +85,6 @@ private Mono doFlush(Agent agent) { } MemoryFlushManager flushManager = new MemoryFlushManager(workspaceManager, model); - flushManager.setMemoryIndex(memoryIndex); - flushManager.setMaintenanceScheduler(maintenanceScheduler); Mono flushMono = flushManager diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java new file mode 100644 index 000000000..17e54d15e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java @@ -0,0 +1,210 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.GlobResult; +import io.agentscope.harness.agent.memory.MemoryConsolidator; +import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.util.concurrent.atomic.AtomicReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that performs periodic memory maintenance after each agent call. + * + *

Replaces the background {@code MemoryMaintenanceScheduler} with a hook-driven, + * event-loop-friendly approach. Fires on {@link PostCallEvent} (priority 6, after + * {@link MemoryFlushHook} at priority 5) and is throttled by a configurable minimum gap + * so it does not run on every single call. + * + *

Maintenance steps executed in order: + *

    + *
  1. Expire daily memory files older than {@code dailyFileRetentionDays} by moving + * them to {@code memory/archive/}.
  2. + *
  3. Run LLM-based consolidation ({@link MemoryConsolidator#consolidate()}) if a + * consolidator is configured.
  4. + *
  5. Prune session log files older than {@code sessionRetentionDays}.
  6. + *
+ * + *

All file I/O goes through {@link AbstractFilesystem} (obtained from + * {@link WorkspaceManager}), making this backend-agnostic across Local, Sandbox, and + * Store filesystems. + */ +public class MemoryMaintenanceHook implements Hook { + + private static final Logger log = LoggerFactory.getLogger(MemoryMaintenanceHook.class); + + /** Default minimum gap between two maintenance runs. */ + public static final Duration DEFAULT_MIN_GAP = Duration.ofMinutes(30); + + private final WorkspaceManager workspaceManager; + private final MemoryConsolidator consolidator; + private final int dailyFileRetentionDays; + private final int sessionRetentionDays; + private final Duration minGap; + + private final AtomicReference lastRunAt = new AtomicReference<>(Instant.EPOCH); + + public MemoryMaintenanceHook( + WorkspaceManager workspaceManager, + MemoryConsolidator consolidator, + int dailyFileRetentionDays, + int sessionRetentionDays, + Duration minGap) { + this.workspaceManager = workspaceManager; + this.consolidator = consolidator; + this.dailyFileRetentionDays = dailyFileRetentionDays; + this.sessionRetentionDays = sessionRetentionDays; + this.minGap = minGap != null ? minGap : DEFAULT_MIN_GAP; + } + + public MemoryMaintenanceHook( + WorkspaceManager workspaceManager, MemoryConsolidator consolidator) { + this(workspaceManager, consolidator, 90, 180, DEFAULT_MIN_GAP); + } + + @Override + public int priority() { + return 6; + } + + @Override + public Mono onEvent(T event) { + if (!(event instanceof PostCallEvent)) { + return Mono.just(event); + } + Instant now = Instant.now(); + Instant last = lastRunAt.get(); + if (Duration.between(last, now).compareTo(minGap) < 0) { + return Mono.just(event); + } + if (!lastRunAt.compareAndSet(last, now)) { + return Mono.just(event); + } + return Mono.fromRunnable(this::runMaintenance) + .onErrorResume( + e -> { + log.warn("Memory maintenance failed: {}", e.getMessage()); + return Mono.empty(); + }) + .thenReturn(event); + } + + private void runMaintenance() { + log.debug("Running memory maintenance..."); + expireDailyFiles(); + consolidateMemory(); + pruneOldSessions(); + log.debug("Memory maintenance completed"); + } + + private void expireDailyFiles() { + AbstractFilesystem fs = workspaceManager.getFilesystem(); + if (fs == null) { + return; + } + GlobResult glob = fs.glob("*.md", WorkspaceConstants.MEMORY_DIR); + if (glob == null || glob.matches() == null) { + return; + } + + LocalDate cutoff = LocalDate.now().minusDays(dailyFileRetentionDays); + for (FileInfo fi : glob.matches()) { + if (fi.isDirectory()) { + continue; + } + String fileName = fileName(fi.path()); + if (fileName.startsWith(".")) { + continue; + } + String baseName = + fileName.endsWith(".md") + ? fileName.substring(0, fileName.length() - 3) + : fileName; + try { + LocalDate fileDate = LocalDate.parse(baseName); + if (fileDate.isBefore(cutoff)) { + String fromPath = WorkspaceConstants.MEMORY_DIR + "/" + fileName; + String toPath = WorkspaceConstants.MEMORY_DIR + "/archive/" + fileName; + fs.move(fromPath, toPath); + log.debug("Archived expired daily file: {}", fileName); + } + } catch (Exception e) { + // not a date-named file, skip + } + } + } + + private void consolidateMemory() { + if (consolidator == null) { + return; + } + try { + consolidator.consolidate().block(); + } catch (Exception e) { + log.warn("Memory consolidation failed: {}", e.getMessage()); + } + } + + private void pruneOldSessions() { + AbstractFilesystem fs = workspaceManager.getFilesystem(); + if (fs == null) { + return; + } + GlobResult glob = fs.glob("*.log.jsonl", WorkspaceConstants.AGENTS_DIR); + if (glob == null || glob.matches() == null) { + return; + } + + Instant cutoff = Instant.now().minus(Duration.ofDays(sessionRetentionDays)); + for (FileInfo fi : glob.matches()) { + if (fi.isDirectory()) { + continue; + } + String modifiedAt = fi.modifiedAt(); + if (modifiedAt == null || modifiedAt.isEmpty()) { + continue; + } + try { + Instant modified = Instant.parse(modifiedAt); + if (modified.isBefore(cutoff)) { + fs.delete(fi.path()); + log.debug("Pruned old session file: {}", fi.path()); + } + } catch (Exception e) { + log.warn("Failed to check/prune {}: {}", fi.path(), e.getMessage()); + } + } + } + + private static String fileName(String path) { + if (path == null) { + return ""; + } + int slash = path.lastIndexOf('/'); + return slash >= 0 ? path.substring(slash + 1) : path; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java new file mode 100644 index 000000000..62a9d7a4e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java @@ -0,0 +1,195 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.hook; + +import io.agentscope.core.hook.ErrorEvent; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.hook.PreCallEvent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxAcquireResult; +import io.agentscope.harness.agent.sandbox.SandboxBackedFilesystem; +import io.agentscope.harness.agent.sandbox.SandboxContext; +import io.agentscope.harness.agent.sandbox.SandboxManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +/** + * Hook that manages the sandbox session lifecycle around each agent call. + * + *

PreCallEvent

+ *
    + *
  1. Read {@link SandboxContext} from the {@link RuntimeContext}
  2. + *
  3. Acquire a session via {@link SandboxManager}
  4. + *
  5. Start the session (4-branch workspace init)
  6. + *
  7. Inject the live session into the {@link SandboxBackedFilesystem} proxy
  8. + *
+ * + *

PostCallEvent / ErrorEvent

+ *
    + *
  1. Persist sandbox session state via {@link SandboxManager} and {@link io.agentscope.harness.agent.sandbox.SandboxStateStore}
  2. + *
  3. Release the session via {@link SandboxManager} (stop + optional shutdown)
  4. + *
  5. Clear the session reference from the filesystem proxy
  6. + *
+ * + *

Priority is set to 50 — runs before all other harness hooks (SessionPersistence at 900). + * + *

Post-call failures (persist, release) are logged but do not propagate — this ensures + * the agent call result is always returned to the caller even if sandbox cleanup fails. + */ +public class SandboxLifecycleHook implements Hook, RuntimeContextAwareHook { + + private static final Logger log = LoggerFactory.getLogger(SandboxLifecycleHook.class); + + private final SandboxManager sandboxManager; + private final SandboxBackedFilesystem filesystemProxy; + + private RuntimeContext runtimeContext; + + /** + * Thread-local acquire result to track the session acquired for the current call. + * Using ThreadLocal allows concurrent calls on different threads to have independent + * session state. + */ + private final ThreadLocal currentAcquireResult = new ThreadLocal<>(); + + /** + * Creates the hook. + * + * @param sandboxManager the manager responsible for session acquire/release + * @param filesystemProxy the filesystem proxy that receives injected sessions + */ + public SandboxLifecycleHook( + SandboxManager sandboxManager, SandboxBackedFilesystem filesystemProxy) { + this.sandboxManager = sandboxManager; + this.filesystemProxy = filesystemProxy; + } + + @Override + public int priority() { + return 50; + } + + @Override + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + @SuppressWarnings("unchecked") + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent e) { + return (Mono) handlePreCall(e); + } else if (event instanceof PostCallEvent e) { + return (Mono) handlePost(e); + } else if (event instanceof ErrorEvent e) { + return (Mono) handlePost(e); + } + return Mono.just(event); + } + + @SuppressWarnings("unchecked") + private Mono handlePreCall(T event) { + RuntimeContext ctx = runtimeContext; + if (ctx == null) { + return Mono.just(event); + } + + SandboxContext sandboxContext = ctx.getSandboxContext(); + if (sandboxContext == null) { + return Mono.just(event); + } + + return Mono.fromCallable( + () -> { + SandboxAcquireResult result = + sandboxManager.acquire(sandboxContext, ctx); + Sandbox sandbox = result.getSandbox(); + try { + sandbox.start(); + filesystemProxy.setSandbox(sandbox); + currentAcquireResult.set(result); + log.debug( + "[sandbox-hook] Acquired sandbox {}", + sandbox.getState() != null + ? sandbox.getState().getSessionId() + : "?"); + } catch (Exception e) { + filesystemProxy.setSandbox(null); + try { + sandboxManager.release(result); + } catch (Exception releaseErr) { + log.warn( + "[sandbox-hook] Failed to release session after" + + " pre-call failure: {}", + releaseErr.getMessage(), + releaseErr); + } + throw e; + } + return event; + }) + .onErrorMap( + e -> { + log.error("[sandbox-hook] Failed to acquire/start sandbox", e); + return e; + }); + } + + @SuppressWarnings("unchecked") + private Mono handlePost(T event) { + return Mono.fromCallable( + () -> { + SandboxAcquireResult result = currentAcquireResult.get(); + currentAcquireResult.remove(); + + if (result == null) { + return event; + } + + RuntimeContext ctx = runtimeContext; + SandboxContext sandboxContext = ctx != null ? ctx.getSandboxContext() : null; + + // Persist state first (before release destroys workspace) + try { + sandboxManager.persistState(result, sandboxContext, ctx); + } catch (Exception e) { + log.warn( + "[sandbox-hook] Failed to persist sandbox state: {}", + e.getMessage(), + e); + } + + // Release the session (stop + optional shutdown) + try { + sandboxManager.release(result); + } catch (Exception e) { + log.warn( + "[sandbox-hook] Failed to release sandbox session: {}", + e.getMessage(), + e); + } + + // Clear the session reference from the filesystem proxy + filesystemProxy.setSandbox(null); + + return event; + }); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java index f171ae4d2..455478bd3 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java @@ -49,7 +49,7 @@ *

    *
  • This hook fires on {@link PostActingEvent} — once per tool call, triggered by * individual result size (context width).
  • - *
  • Argument truncation runs inside {@link io.agentscope.harness.agent.memory.compaction.CompactionHook} + *
  • Argument truncation runs inside {@link CompactionHook} * at {@code PreReasoningEvent} — triggered by accumulated message count/tokens.
  • *
  • Conversation compaction runs inside {@code CompactionHook} at * {@code PreReasoningEvent} — triggered by overall conversation length (context depth).
  • diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java index 9f5b45bc9..9a9424360 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java @@ -19,16 +19,14 @@ import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; import io.agentscope.core.model.Model; -import io.agentscope.harness.agent.workspace.WorkspaceConstants; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.FileInfo; +import io.agentscope.harness.agent.filesystem.model.GlobResult; import io.agentscope.harness.agent.workspace.WorkspaceManager; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; @@ -47,9 +45,13 @@ *
* *

A small state file ({@code memory/.consolidation_state}) records the timestamp of - * the last successful consolidation. Daily files whose mtime is at or before that - * timestamp are skipped — reducing token usage and protecting MEMORY.md from being + * the last successful consolidation. Daily files whose {@code modifiedAt} is at or before + * that timestamp are skipped — reducing token usage and protecting MEMORY.md from being * re-rewritten with stale content. + * + *

All file I/O is performed via the {@link AbstractFilesystem} obtained from the + * {@link WorkspaceManager}, so this class is backend-agnostic (works with Local, + * Sandbox, and Store filesystems without any direct {@code java.nio.file.Files} usage). */ public class MemoryConsolidator { @@ -174,92 +176,113 @@ public Mono consolidate() { /** * Reads daily memory files modified strictly after the given watermark. * If watermark is {@link Instant#EPOCH}, all daily files are returned (first run). + * + *

All I/O is done through the {@link AbstractFilesystem} so this works equally well + * with Local, Sandbox, and Store backends. */ private String readDailyEntries(Instant watermark) { - Path memoryDir = workspaceManager.getMemoryDir(); - if (!Files.isDirectory(memoryDir)) { + AbstractFilesystem fs = workspaceManager.getFilesystem(); + if (fs == null) { + return ""; + } + + GlobResult glob = fs.glob("*.md", "memory"); + if (!glob.isSuccess() || glob.matches() == null || glob.matches().isEmpty()) { return ""; } + List eligible = new ArrayList<>(); + for (FileInfo fi : glob.matches()) { + if (fi.isDirectory()) { + continue; + } + String name = fileName(fi.path()); + if (name.equals(STATE_FILE) || name.equals("archive") || !name.endsWith(".md")) { + continue; + } + if (isModifiedAfter(fi, watermark)) { + eligible.add(fi); + } + } + eligible.sort(Comparator.comparing(fi -> fileName(fi.path()))); + StringBuilder sb = new StringBuilder(); - try (Stream files = Files.list(memoryDir)) { - files.filter(p -> p.toString().endsWith(".md")) - .filter(Files::isRegularFile) - .filter(p -> !p.getFileName().toString().equals("archive")) - .filter(p -> isModifiedAfter(p, watermark)) - .sorted(Comparator.comparing(Path::getFileName)) - .forEach( - p -> { - try { - String content = Files.readString(p); - if (!content.isBlank()) { - sb.append("### ").append(p.getFileName()).append("\n"); - sb.append(content.strip()).append("\n\n"); - } - } catch (IOException e) { - log.warn("Failed to read {}: {}", p, e.getMessage()); - } - }); - } catch (IOException e) { - log.warn("Failed to list memory dir: {}", e.getMessage()); + for (FileInfo fi : eligible) { + String rel = toRelative(fi.path()); + String content = workspaceManager.readManagedWorkspaceFileUtf8(rel); + if (content != null && !content.isBlank()) { + sb.append("### ").append(fileName(fi.path())).append("\n"); + sb.append(content.strip()).append("\n\n"); + } } return sb.toString(); } - private static boolean isModifiedAfter(Path p, Instant watermark) { + private static boolean isModifiedAfter(FileInfo fi, Instant watermark) { + String modifiedAt = fi.modifiedAt(); + if (modifiedAt == null || modifiedAt.isBlank()) { + return true; // be safe — include on unknown mtime + } try { - return Files.getLastModifiedTime(p).toInstant().isAfter(watermark); - } catch (IOException e) { - return true; // be safe — include on read error + return Instant.parse(modifiedAt).isAfter(watermark); + } catch (Exception e) { + return true; // be safe on parse error } } - private void writeConsolidatedMemory(String content) { - Path memoryFile = workspaceManager.getWorkspace().resolve(WorkspaceConstants.MEMORY_MD); - try { - if (memoryFile.getParent() != null) { - Files.createDirectories(memoryFile.getParent()); - } - Files.writeString(memoryFile, content); - } catch (IOException e) { - log.warn("Failed to write consolidated MEMORY.md: {}", e.getMessage()); + /** Extracts the file name (last path segment) from a path string. */ + private static String fileName(String path) { + if (path == null || path.isEmpty()) { + return ""; + } + String stripped = path.endsWith("/") ? path.substring(0, path.length() - 1) : path; + int idx = stripped.lastIndexOf('/'); + return idx >= 0 ? stripped.substring(idx + 1) : stripped; + } + + /** + * Converts an absolute filesystem path (e.g. {@code /memory/2025-01-01.md}) to a + * workspace-relative path ({@code memory/2025-01-01.md}) for use with + * {@link WorkspaceManager#readManagedWorkspaceFileUtf8}. + */ + private static String toRelative(String path) { + if (path == null) { + return ""; } + return path.startsWith("/") ? path.substring(1) : path; } - private Path stateFilePath() { - return workspaceManager.getMemoryDir().resolve(STATE_FILE); + private void writeConsolidatedMemory(String content) { + workspaceManager.writeUtf8WorkspaceRelative("MEMORY.md", content); } + static final String STATE_REL_PATH = "memory/" + STATE_FILE; + /** Reads the last consolidation Instant, or {@link Instant#EPOCH} if none recorded. */ Instant readWatermark() { - Path state = stateFilePath(); - if (!Files.isRegularFile(state)) { - return Instant.EPOCH; - } try { - String value = Files.readString(state).strip(); - if (value.isEmpty()) { + String value = workspaceManager.readManagedWorkspaceFileUtf8(STATE_REL_PATH); + if (value == null || value.isBlank()) { return Instant.EPOCH; } - return Instant.parse(value); + return Instant.parse(value.strip()); } catch (Exception e) { log.warn( "Failed to read consolidation watermark at {}: {} — treating as EPOCH", - state, + STATE_REL_PATH, e.getMessage()); return Instant.EPOCH; } } private void writeWatermark(Instant ts) { - Path state = stateFilePath(); try { - if (state.getParent() != null) { - Files.createDirectories(state.getParent()); - } - Files.writeString(state, ts.toString()); - } catch (IOException e) { - log.warn("Failed to write consolidation watermark at {}: {}", state, e.getMessage()); + workspaceManager.writeUtf8WorkspaceRelative(STATE_REL_PATH, ts.toString()); + } catch (Exception e) { + log.warn( + "Failed to write consolidation watermark at {}: {}", + STATE_REL_PATH, + e.getMessage()); } } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java index b8df54233..29d2c942e 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java @@ -85,27 +85,12 @@ public class MemoryFlushManager { private final WorkspaceManager workspaceManager; private final Model model; - private volatile MemoryIndex memoryIndex; - private volatile MemoryMaintenanceScheduler maintenanceScheduler; public MemoryFlushManager(WorkspaceManager workspaceManager, Model model) { this.workspaceManager = workspaceManager; this.model = model; } - public void setMemoryIndex(MemoryIndex memoryIndex) { - this.memoryIndex = memoryIndex; - } - - /** - * Optional hook into the maintenance scheduler. When set, every successful flush will - * call {@link MemoryMaintenanceScheduler#requestConsolidation()} so MEMORY.md stays - * fresh in long sessions instead of waiting for the next periodic tick. - */ - public void setMaintenanceScheduler(MemoryMaintenanceScheduler scheduler) { - this.maintenanceScheduler = scheduler; - } - /** * Extracts long-term memories from messages using the model and writes them to disk. * @@ -179,7 +164,6 @@ public Mono flushMemories(List messages) { return Mono.empty(); } writeMemoryFiles(extracted); - requestConsolidation(); return Mono.empty(); }); } @@ -220,7 +204,11 @@ public void offloadMessages(List messages, String agentId, String sessionId private void offloadToSessionTree(List messages, String agentId, String sessionId) { try { Path contextFile = workspaceManager.resolveSessionContextFile(agentId, sessionId); - SessionTree tree = new SessionTree(contextFile); + SessionTree tree = + new SessionTree( + contextFile, + workspaceManager.getWorkspace(), + workspaceManager.getFilesystem()); tree.load(); String lastId = null; @@ -280,41 +268,6 @@ private void writeMemoryFiles(String content) { String dailyRelPath = WorkspaceConstants.MEMORY_DIR + "/" + today + ".md"; workspaceManager.appendUtf8WorkspaceRelative(dailyRelPath, dailyEntry); - - indexAfterWrite(dailyRelPath); - } - - /** - * Asks the maintenance scheduler (if wired) to opportunistically consolidate MEMORY.md. - * The scheduler throttles requests, so calling this every flush is safe. - */ - private void requestConsolidation() { - MemoryMaintenanceScheduler s = this.maintenanceScheduler; - if (s != null) { - try { - s.requestConsolidation(); - } catch (Exception e) { - log.debug("Opportunistic consolidation request failed: {}", e.getMessage()); - } - } - } - - /** - * Re-indexes today's daily ledger so search reflects the just-appended entries. - * MEMORY.md is re-indexed separately by {@link MemoryMaintenanceScheduler#runMaintenance()} - * after consolidation, so it is not touched here. - */ - private void indexAfterWrite(String dailyRelPath) { - MemoryIndex idx = this.memoryIndex; - if (idx == null) { - return; - } - try { - idx.indexFromString( - dailyRelPath, workspaceManager.readManagedWorkspaceFileUtf8(dailyRelPath)); - } catch (Exception e) { - log.warn("Failed to index daily memory file after write: {}", e.getMessage()); - } } private String readExistingContent(String relativePath) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java deleted file mode 100644 index c3b56a109..000000000 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryIndex.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.agent.memory; - -import io.agentscope.harness.agent.workspace.WorkspaceManager; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * SQLite FTS5-backed index for long-term memory files ({@code MEMORY.md} and - * {@code memory/*.md}). - * - *

Each line of every indexed file is stored as a separate row so that search - * results can reference specific line numbers. The index is stored at - * {@code {workspace}/.agentscope/memory_index.db}. - */ -public class MemoryIndex implements AutoCloseable { - - private static final Logger log = LoggerFactory.getLogger(MemoryIndex.class); - - private final Path dbPath; - private Connection connection; - - public MemoryIndex(Path workspaceAgentScopeDir) { - this.dbPath = workspaceAgentScopeDir.resolve("memory_index.db"); - } - - /** - * Opens the SQLite database and creates the FTS5 virtual table if needed. - */ - public synchronized void open() throws SQLException { - if (connection != null && !connection.isClosed()) { - return; - } - try { - Files.createDirectories(dbPath.getParent()); - } catch (IOException e) { - throw new SQLException("Cannot create directory for memory_index.db", e); - } - connection = DriverManager.getConnection("jdbc:sqlite:" + dbPath.toAbsolutePath()); - try (Statement stmt = connection.createStatement()) { - stmt.execute( - "CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts " - + "USING fts5(path, line_number, content)"); - } - } - - /** - * Re-indexes a single file: deletes old rows for that path and inserts new ones. - */ - public synchronized void indexFile(Path file) throws SQLException, IOException { - ensureOpen(); - String relativePath = file.getFileName().toString(); - Path parent = file.getParent(); - if (parent != null) { - Path parentName = parent.getFileName(); - if (parentName != null && "memory".equals(parentName.toString())) { - relativePath = "memory/" + file.getFileName(); - } - } - - try (PreparedStatement del = - connection.prepareStatement("DELETE FROM memory_fts WHERE path = ?")) { - del.setString(1, relativePath); - del.executeUpdate(); - } - - if (!Files.exists(file)) { - return; - } - - List lines = Files.readAllLines(file); - insertLines(relativePath, lines); - log.debug("Indexed {} lines from {}", lines.size(), relativePath); - } - - /** - * Re-indexes from in-memory content (same logical paths as {@link #indexFile(Path)}). - */ - public synchronized void indexFromString(String relativePath, String content) - throws SQLException, IOException { - ensureOpen(); - if (relativePath == null || relativePath.isBlank()) { - return; - } - try (PreparedStatement del = - connection.prepareStatement("DELETE FROM memory_fts WHERE path = ?")) { - del.setString(1, relativePath); - del.executeUpdate(); - } - if (content == null || content.isBlank()) { - return; - } - List lines = java.util.Arrays.asList(content.split("\n", -1)); - insertLines(relativePath, lines); - log.debug("Indexed {} lines from {}", lines.size(), relativePath); - } - - private void insertLines(String relativePath, List lines) throws SQLException { - try (PreparedStatement ins = - connection.prepareStatement( - "INSERT INTO memory_fts(path, line_number, content) VALUES (?, ?, ?)")) { - for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i).strip(); - if (line.isEmpty()) { - continue; - } - ins.setString(1, relativePath); - ins.setString(2, String.valueOf(i + 1)); - ins.setString(3, line); - ins.addBatch(); - } - ins.executeBatch(); - } - } - - /** - * Full-text search across indexed memory files. Returns up to {@code maxResults} hits - * ranked by FTS5 relevance. - */ - public synchronized List search(String query, int maxResults) throws SQLException { - ensureOpen(); - List results = new ArrayList<>(); - String ftsQuery = sanitizeFtsQuery(query); - if (ftsQuery.isBlank()) { - return results; - } - try (PreparedStatement ps = - connection.prepareStatement( - "SELECT path, line_number, content, rank " - + "FROM memory_fts WHERE memory_fts MATCH ? " - + "ORDER BY rank LIMIT ?")) { - ps.setString(1, ftsQuery); - ps.setInt(2, maxResults); - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - results.add( - new SearchHit( - rs.getString("path"), - rs.getInt("line_number"), - rs.getString("content"), - rs.getDouble("rank"))); - } - } - } - return results; - } - - /** - * Backend-agnostic indexing: discovers all memory files and session log files via - * {@link WorkspaceManager} and indexes their content. Works for Local, Store, and - * Sandbox backends. - */ - public void indexAllFromWorkspace(WorkspaceManager wsManager) throws SQLException, IOException { - List paths = wsManager.listMemoryFilePaths(); - for (String relativePath : paths) { - String content = wsManager.readManagedWorkspaceFileUtf8(relativePath); - indexFromString(relativePath, content); - } - - indexSessionLogFiles(wsManager); - } - - /** - * Indexes session log files ({@code .log.jsonl}) for full-text search across - * session history. Uses {@link WorkspaceManager#listSessionLogFiles()} to discover - * files from both the filesystem layer and local disk. - */ - private void indexSessionLogFiles(WorkspaceManager wsManager) { - List logPaths = wsManager.listSessionLogFiles(); - for (String relativePath : logPaths) { - try { - String content = wsManager.readManagedWorkspaceFileUtf8(relativePath); - indexFromString(relativePath, content); - } catch (Exception e) { - log.debug("Failed to index session log {}: {}", relativePath, e.getMessage()); - } - } - } - - /** - * Indexes {@code MEMORY.md} and all {@code memory/*.md} files under the given workspace. - * - * @deprecated Use {@link #indexAllFromWorkspace(WorkspaceManager)} for backend-agnostic - * indexing. - */ - @Deprecated - public void indexAll(Path workspace) throws SQLException, IOException { - Path memoryMd = workspace.resolve("MEMORY.md"); - if (Files.exists(memoryMd)) { - indexFile(memoryMd); - } - - Path memoryDir = workspace.resolve("memory"); - if (Files.isDirectory(memoryDir)) { - try (Stream files = Files.list(memoryDir)) { - List mdFiles = files.filter(p -> p.toString().endsWith(".md")).toList(); - for (Path f : mdFiles) { - indexFile(f); - } - } - } - } - - @Override - public synchronized void close() { - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - log.warn("Error closing memory index db: {}", e.getMessage()); - } - connection = null; - } - } - - private void ensureOpen() throws SQLException { - if (connection == null || connection.isClosed()) { - open(); - } - } - - /** - * Sanitizes a user query for FTS5 MATCH syntax. Wraps each token in double quotes - * so special characters are treated as literals. - */ - static String sanitizeFtsQuery(String raw) { - if (raw == null) { - return ""; - } - String[] tokens = raw.strip().split("\\s+"); - StringBuilder sb = new StringBuilder(); - for (String tok : tokens) { - if (tok.isEmpty()) { - continue; - } - if (sb.length() > 0) { - sb.append(' '); - } - sb.append('"').append(tok.replace("\"", "")).append('"'); - } - return sb.toString(); - } - - /** - * A single search result. - */ - public record SearchHit(String path, int lineNumber, String content, double rank) {} -} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java deleted file mode 100644 index 61a2eb2d8..000000000 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryMaintenanceScheduler.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.agent.memory; - -import io.agentscope.core.model.Model; -import io.agentscope.harness.agent.workspace.WorkspaceConstants; -import io.agentscope.harness.agent.workspace.WorkspaceManager; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Periodic background maintenance for the memory system. - * - *

Performs: - *

    - *
  • LLM-based memory consolidation (daily files into MEMORY.md)
  • - *
  • Expiration/archival of old daily memory files
  • - *
  • Pruning of old session files
  • - *
  • Re-indexing of memory files into the FTS5 index
  • - *
- * - *

Runs on a configurable interval (default: every 6 hours). - */ -public class MemoryMaintenanceScheduler { - - private static final Logger log = LoggerFactory.getLogger(MemoryMaintenanceScheduler.class); - - /** Minimum gap between two opportunistic (post-flush) consolidations. */ - private static final Duration MIN_OPPORTUNISTIC_GAP = Duration.ofMinutes(30); - - private final WorkspaceManager workspaceManager; - private final MemoryIndex memoryIndex; - private final MemoryConsolidator consolidator; - private final Duration interval; - private final int dailyFileRetentionDays; - private final int sessionRetentionDays; - - private ScheduledExecutorService executor; - private final java.util.concurrent.atomic.AtomicReference lastConsolidationAt = - new java.util.concurrent.atomic.AtomicReference<>(Instant.EPOCH); - - public MemoryMaintenanceScheduler( - WorkspaceManager workspaceManager, - MemoryIndex memoryIndex, - MemoryConsolidator consolidator, - Duration interval, - int dailyFileRetentionDays, - int sessionRetentionDays) { - this.workspaceManager = workspaceManager; - this.memoryIndex = memoryIndex; - this.consolidator = consolidator; - this.interval = interval; - this.dailyFileRetentionDays = dailyFileRetentionDays; - this.sessionRetentionDays = sessionRetentionDays; - } - - public MemoryMaintenanceScheduler( - WorkspaceManager workspaceManager, MemoryIndex memoryIndex, Model model) { - this( - workspaceManager, - memoryIndex, - model != null ? new MemoryConsolidator(workspaceManager, model) : null, - Duration.ofHours(6), - 90, - 180); - } - - public MemoryMaintenanceScheduler(WorkspaceManager workspaceManager, MemoryIndex memoryIndex) { - this( - workspaceManager, - memoryIndex, - (MemoryConsolidator) null, - Duration.ofHours(6), - 90, - 180); - } - - public void start() { - if (executor != null) { - return; - } - executor = - Executors.newSingleThreadScheduledExecutor( - r -> { - Thread t = new Thread(r, "memory-maintenance"); - t.setDaemon(true); - return t; - }); - executor.scheduleAtFixedRate( - this::runMaintenance, - interval.toMillis(), - interval.toMillis(), - TimeUnit.MILLISECONDS); - log.info("Memory maintenance scheduler started (interval={})", interval); - } - - public void stop() { - if (executor != null) { - executor.shutdownNow(); - executor = null; - } - } - - public void runMaintenance() { - try { - log.debug("Running memory maintenance..."); - expireDailyFiles(); - consolidateMemory(); - pruneOldSessions(); - reindex(); - log.debug("Memory maintenance completed"); - } catch (Exception e) { - log.warn("Memory maintenance failed: {}", e.getMessage()); - } - } - - /** - * Requests an opportunistic consolidation, typically called right after - * {@link io.agentscope.harness.agent.memory.MemoryFlushManager} appends to a daily ledger. - * - *

To avoid running for every flush, the request is throttled by - * {@link #MIN_OPPORTUNISTIC_GAP} relative to the previous consolidation. The work - * itself is dispatched onto the maintenance executor when it is running, so it never - * blocks the agent's reasoning loop. If the executor is not running, the request is - * silently skipped (the periodic timer will pick it up later). - */ - public void requestConsolidation() { - if (consolidator == null) { - return; - } - ScheduledExecutorService exec = this.executor; - if (exec == null || exec.isShutdown()) { - return; - } - Instant now = Instant.now(); - Instant last = lastConsolidationAt.get(); - if (Duration.between(last, now).compareTo(MIN_OPPORTUNISTIC_GAP) < 0) { - return; - } - if (!lastConsolidationAt.compareAndSet(last, now)) { - return; // another caller raced ahead - } - try { - exec.submit(this::consolidateMemory); - } catch (Exception e) { - log.debug("Failed to submit opportunistic consolidation: {}", e.getMessage()); - } - } - - private void consolidateMemory() { - if (consolidator == null) { - return; - } - try { - consolidator.consolidate().block(); - lastConsolidationAt.set(Instant.now()); - } catch (Exception e) { - log.warn("Memory consolidation failed: {}", e.getMessage()); - } - } - - private void expireDailyFiles() { - Path memoryDir = workspaceManager.getMemoryDir(); - if (!Files.isDirectory(memoryDir)) { - return; - } - - LocalDate cutoff = LocalDate.now().minusDays(dailyFileRetentionDays); - try (Stream files = Files.list(memoryDir)) { - files.filter(p -> p.toString().endsWith(".md")) - .filter(Files::isRegularFile) - .forEach( - p -> { - String name = p.getFileName().toString().replace(".md", ""); - try { - LocalDate fileDate = LocalDate.parse(name); - if (fileDate.isBefore(cutoff)) { - Path archiveDir = memoryDir.resolve("archive"); - try { - Files.createDirectories(archiveDir); - Files.move(p, archiveDir.resolve(p.getFileName())); - log.debug("Archived expired daily file: {}", name); - } catch (IOException e) { - log.warn( - "Failed to archive {}: {}", - name, - e.getMessage()); - } - } - } catch (Exception e) { - // not a date-named file, skip - } - }); - } catch (IOException e) { - log.warn("Failed to list memory dir: {}", e.getMessage()); - } - } - - private void pruneOldSessions() { - Path agentsDir = workspaceManager.getWorkspace().resolve(WorkspaceConstants.AGENTS_DIR); - if (!Files.isDirectory(agentsDir)) { - return; - } - - Instant cutoff = Instant.now().minus(Duration.ofDays(sessionRetentionDays)); - try (Stream agents = Files.list(agentsDir)) { - agents.filter(Files::isDirectory) - .forEach( - agentDir -> { - Path sessionsDir = - agentDir.resolve(WorkspaceConstants.SESSIONS_DIR); - if (!Files.isDirectory(sessionsDir)) { - return; - } - try (Stream sessions = Files.list(sessionsDir)) { - sessions.filter(Files::isRegularFile) - .filter( - p -> - !p.getFileName() - .toString() - .equals( - WorkspaceConstants - .SESSIONS_STORE)) - .forEach( - p -> { - try { - Instant modified = - Files.getLastModifiedTime(p) - .toInstant(); - if (modified.isBefore(cutoff)) { - Files.delete(p); - log.debug( - "Pruned old session file:" - + " {}", - p); - } - } catch (IOException e) { - log.warn( - "Failed to check/prune {}: {}", - p, - e.getMessage()); - } - }); - } catch (IOException e) { - log.warn("Failed to list sessions: {}", e.getMessage()); - } - }); - } catch (IOException e) { - log.warn("Failed to list agents dir: {}", e.getMessage()); - } - } - - private void reindex() { - if (memoryIndex == null) { - return; - } - try { - memoryIndex.indexAllFromWorkspace(workspaceManager); - } catch (Exception e) { - log.warn("Failed to reindex: {}", e.getMessage()); - } - } -} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java index 51722c36e..e4e9b1c66 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java @@ -22,6 +22,7 @@ import io.agentscope.core.message.ToolResultBlock; import io.agentscope.core.message.ToolUseBlock; import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.hook.CompactionHook; import io.agentscope.harness.agent.memory.MemoryFlushManager; import io.agentscope.harness.agent.memory.compaction.CompactionConfig.TruncateArgsConfig; import java.util.ArrayList; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java index 3f86325d3..4b88d6360 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java @@ -21,7 +21,7 @@ * Configuration for per-tool-result eviction of oversized outputs. * *

When a tool produces a result whose text content exceeds {@link #getMaxResultChars()}, the - * full output is written to the {@link AbstractFilesystem} at a deterministic path under + * full output is written to the workspace filesystem abstraction at a deterministic path under * {@link #getEvictionPath()}, and the in-context {@link io.agentscope.core.message.ToolResultBlock} * is replaced with a compact placeholder that includes a head+tail preview and an instruction to * use {@code readFile} for the full content. diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java index b753e8ea8..e333e691e 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java @@ -16,6 +16,8 @@ package io.agentscope.harness.agent.memory.session; import io.agentscope.core.util.JsonUtils; +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.model.ReadResult; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; @@ -38,13 +40,13 @@ * Entries form a tree via {@code id}/{@code parentId} links. A companion {@code .log.jsonl} file * stores the full history for grep-ability (dual-file pattern from pi-mono mom). * - *

File layout

+ *

File layout

*
  *   agents/{agentId}/sessions/{sessionId}.jsonl      — LLM context (compacted)
  *   agents/{agentId}/sessions/{sessionId}.log.jsonl   — full history (append-only, never compacted)
  * 
* - *

Deferred persistence

+ *

Deferred persistence

* Entries are buffered in memory and only flushed to disk on the first call to {@link #flush()} * (typically after the first assistant message). This avoids partial session files from * failed/short interactions. @@ -56,6 +58,8 @@ public class SessionTree { private final Path contextFile; private final Path logFile; + private final Path workspaceRoot; + private final AbstractFilesystem filesystem; private final Map entriesById = new LinkedHashMap<>(); private final List appendOrder = new ArrayList<>(); @@ -67,10 +71,16 @@ public class SessionTree { private boolean flushed = false; public SessionTree(Path contextFile) { + this(contextFile, null, null); + } + + public SessionTree(Path contextFile, Path workspaceRoot, AbstractFilesystem filesystem) { this.contextFile = contextFile; String name = contextFile.getFileName().toString(); String baseName = name.endsWith(".jsonl") ? name.substring(0, name.length() - 6) : name; this.logFile = contextFile.resolveSibling(baseName + ".log.jsonl"); + this.workspaceRoot = workspaceRoot; + this.filesystem = filesystem; } /** @@ -83,6 +93,7 @@ public void load() { } loaded = true; + restoreFromMirror(contextFile); if (!Files.isRegularFile(contextFile)) { return; } @@ -147,6 +158,8 @@ public void flush() { appendToFile(contextFile, toWrite); appendToFile(logFile, toWrite); + mirrorToFilesystem(contextFile); + mirrorToFilesystem(logFile); } /** @@ -234,6 +247,7 @@ public Path getLogFile() { * @return the number of new entries synced */ public int syncFromLog() { + restoreFromMirror(logFile); if (!Files.isRegularFile(logFile)) { return 0; } @@ -295,4 +309,60 @@ private void appendToFile(Path file, List entries) { log.warn("Failed to append to session file {}: {}", file, e.getMessage()); } } + + private void restoreFromMirror(Path file) { + if (filesystem == null || workspaceRoot == null || Files.isRegularFile(file)) { + return; + } + String relativePath = toWorkspaceRelative(file); + if (relativePath == null || relativePath.isBlank()) { + return; + } + ReadResult read = filesystem.read(relativePath, 0, 0); + if (!read.isSuccess() || read.fileData() == null || read.fileData().content() == null) { + return; + } + try { + if (file.getParent() != null) { + Files.createDirectories(file.getParent()); + } + Files.writeString( + file, + read.fileData().content(), + StandardCharsets.UTF_8, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE); + } catch (IOException e) { + log.warn( + "Failed to restore session file {} from filesystem mirror: {}", + file, + e.getMessage()); + } + } + + private void mirrorToFilesystem(Path file) { + if (filesystem == null || workspaceRoot == null || !Files.isRegularFile(file)) { + return; + } + String relativePath = toWorkspaceRelative(file); + if (relativePath == null || relativePath.isBlank()) { + return; + } + try { + byte[] bytes = Files.readAllBytes(file); + filesystem.uploadFiles(List.of(Map.entry(relativePath, bytes))); + } catch (IOException e) { + log.warn("Failed to mirror session file {} to filesystem: {}", file, e.getMessage()); + } + } + + private String toWorkspaceRelative(Path file) { + Path root = workspaceRoot.toAbsolutePath().normalize(); + Path candidate = file.toAbsolutePath().normalize(); + if (!candidate.startsWith(root)) { + return null; + } + return root.relativize(candidate).toString().replace('\\', '/'); + } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/AbstractBaseSandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/AbstractBaseSandbox.java new file mode 100644 index 000000000..26f83ac27 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/AbstractBaseSandbox.java @@ -0,0 +1,283 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshot; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract base implementation of {@link Sandbox} with the 4-branch workspace start logic. + * + *

4-Branch Start Logic

+ *
+ * Branch A: workspaceRootReady=true  & workspace dir exists   → apply ephemeral-only entries
+ * Branch B: workspaceRootReady=true  & workspace dir missing  → restore from snapshot + ephemeral entries
+ * Branch C: workspaceRootReady=false & snapshot is restorable → hydrate from snapshot + all entries
+ * Branch D: workspaceRootReady=false & no restorable snapshot → fresh init from full workspace spec
+ * 
+ * + *

Subclasses implement the backend-specific operations: + *

    + *
  • {@link #doExec(String, int)} — execute a shell command in the workspace
  • + *
  • {@link #doPersistWorkspace()} — create a tar archive of the workspace
  • + *
  • {@link #doHydrateWorkspace(InputStream)} — extract a tar archive into the workspace
  • + *
  • {@link #doSetupWorkspace()} — create the workspace root directory
  • + *
  • {@link #doDestroyWorkspace()} — delete the workspace root directory (on shutdown)
  • + *
  • {@link #getWorkspaceRoot()} — return the workspace root path string
  • + *
+ */ +public abstract class AbstractBaseSandbox implements Sandbox { + + private static final Logger log = LoggerFactory.getLogger(AbstractBaseSandbox.class); + + /** Default timeout in seconds for workspace probing commands. */ + private static final int PROBE_TIMEOUT_SECONDS = 10; + + private final SandboxState state; + private final WorkspaceSpecApplier workspaceSpecApplier; + private final AtomicBoolean running = new AtomicBoolean(false); + + protected AbstractBaseSandbox(SandboxState state) { + this.state = state; + this.workspaceSpecApplier = new WorkspaceSpecApplier(state.getWorkspaceSpec().getRoot()); + } + + /** + * Executes the 4-branch workspace start logic. + * + * @throws Exception if the workspace fails to start + */ + @Override + public void start() throws Exception { + WorkspaceSpec spec = state.getWorkspaceSpec(); + SandboxSnapshot snapshot = state.getSnapshot(); + + try { + if (state.isWorkspaceRootReady()) { + // Workspace was ready at last stop — check if it still exists + boolean stillExists = probeWorkspaceRootForPreservedResume(); + if (stillExists) { + // Branch A: workspace preserved — only apply ephemeral entries + log.debug( + "[sandbox] Branch A: workspace preserved, applying ephemeral entries"); + workspaceSpecApplier.applyWorkspaceSpec(spec, true); + } else { + // Branch B: workspace was lost — restore from snapshot + ephemeral entries + log.debug("[sandbox] Branch B: workspace lost, restoring from snapshot"); + if (snapshot != null && snapshot.isRestorable()) { + doSetupWorkspace(); + try (InputStream archive = snapshot.restore()) { + doHydrateWorkspace(archive); + } + workspaceSpecApplier.applyWorkspaceSpec(spec, true); + } else { + // Degrade to Branch D: no usable snapshot + log.warn("[sandbox] Branch B degraded to D: snapshot not restorable"); + doSetupWorkspace(); + workspaceSpecApplier.applyWorkspaceSpec(spec, false); + } + } + } else { + // Workspace was not ready at last stop + if (snapshot != null && snapshot.isRestorable()) { + // Branch C: restore from snapshot + all spec entries + log.debug("[sandbox] Branch C: restoring from snapshot"); + doSetupWorkspace(); + try (InputStream archive = snapshot.restore()) { + doHydrateWorkspace(archive); + } + workspaceSpecApplier.applyWorkspaceSpec(spec, false); + } else { + // Branch D: fresh initialization from full workspace spec + log.debug("[sandbox] Branch D: fresh workspace initialization"); + doSetupWorkspace(); + workspaceSpecApplier.applyWorkspaceSpec(spec, false); + } + } + applyWorkspaceProjectionIfChanged(spec); + state.setWorkspaceRootReady(true); + running.set(true); + } catch (Exception e) { + state.setWorkspaceRootReady(false); + throw new SandboxException.WorkspaceStartException( + java.nio.file.Path.of(state.getWorkspaceSpec().getRoot()), e); + } + } + + /** + * Persists the workspace snapshot and marks the workspace root as ready. + * + * @throws Exception if snapshot persistence fails + */ + @Override + public void stop() throws Exception { + SandboxSnapshot snapshot = state.getSnapshot(); + if (snapshot != null && snapshot.isPersistenceEnabled()) { + try (InputStream archive = doPersistWorkspace()) { + snapshot.persist(archive); + } + } + state.setWorkspaceRootReady(true); + running.set(false); + } + + /** + * {@inheritDoc} + * + *

Calls {@link #stop()} then {@link #shutdown()}. + * Stop failures are logged but do not prevent shutdown. + */ + @Override + public void close() throws Exception { + try { + stop(); + } catch (Exception e) { + log.warn("[sandbox] Failed to stop sandbox during close, continuing shutdown", e); + } + shutdown(); + } + + @Override + public boolean isRunning() { + return running.get(); + } + + @Override + public SandboxState getState() { + return state; + } + + /** + * Delegates to {@link #doExec(String, int)} with a fallback timeout. + */ + @Override + public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { + int timeout = timeoutSeconds != null ? timeoutSeconds : getDefaultExecTimeoutSeconds(); + return doExec(command, timeout); + } + + @Override + public InputStream persistWorkspace() throws Exception { + return doPersistWorkspace(); + } + + @Override + public void hydrateWorkspace(InputStream archive) throws Exception { + doHydrateWorkspace(archive); + } + + /** + * Probes whether the workspace root directory still exists, using a backend exec. + * + *

Uses {@code test -d {workspaceRoot}} with a {@value #PROBE_TIMEOUT_SECONDS}-second + * timeout. Returns {@code true} if the command exits with code 0. + * + * @return true if the workspace root exists + */ + protected boolean probeWorkspaceRootForPreservedResume() { + try { + ExecResult result = doExec("test -d " + getWorkspaceRoot(), PROBE_TIMEOUT_SECONDS); + return result.ok(); + } catch (Exception e) { + log.warn( + "[sandbox] Probe for workspace root failed, assuming lost: {}", e.getMessage()); + return false; + } + } + + /** + * Returns the default command execution timeout in seconds. + * + * @return default timeout (120 seconds) + */ + protected int getDefaultExecTimeoutSeconds() { + return 120; + } + + /** + * Executes a shell command within the workspace. + * + * @param command shell command string + * @param timeoutSeconds maximum execution time + * @return execution result + * @throws Exception if execution fails + */ + protected abstract ExecResult doExec(String command, int timeoutSeconds) throws Exception; + + /** + * Creates a tar archive of the current workspace contents. + * + * @return an {@link InputStream} over the tar stream; caller must close + * @throws Exception if archiving fails + */ + protected abstract InputStream doPersistWorkspace() throws Exception; + + /** + * Extracts a tar archive into the workspace. + * + * @param archive the tar archive stream to extract + * @throws Exception if extraction fails + */ + protected abstract void doHydrateWorkspace(InputStream archive) throws Exception; + + /** + * Creates the workspace root directory. + * + * @throws Exception if directory creation fails + */ + protected abstract void doSetupWorkspace() throws Exception; + + /** + * Destroys the workspace root and any backend resources. + * + * @throws Exception if cleanup fails + */ + protected abstract void doDestroyWorkspace() throws Exception; + + /** + * Returns the absolute path of the workspace root directory. + * + * @return workspace root path string + */ + protected abstract String getWorkspaceRoot(); + + private void applyWorkspaceProjectionIfChanged(WorkspaceSpec spec) throws Exception { + WorkspaceProjectionApplier.ProjectionPayload payload = + WorkspaceProjectionApplier.build(spec); + if (payload == null) { + return; + } + if (Objects.equals(payload.hash(), state.getWorkspaceProjectionHash())) { + log.debug("[sandbox] Workspace projection unchanged, skipping"); + return; + } + if (payload.fileCount() > 0) { + try (InputStream archive = new ByteArrayInputStream(payload.tarBytes())) { + doHydrateWorkspace(archive); + } + } + state.setWorkspaceProjectionHash(payload.hash()); + log.debug( + "[sandbox] Workspace projection applied: files={}, hash={}", + payload.fileCount(), + payload.hash()); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/ExecResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/ExecResult.java new file mode 100644 index 000000000..90ff50253 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/ExecResult.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +/** + * Result of a sandbox command execution. + * + * @param exitCode process exit code (0 indicates success) + * @param stdout captured standard output + * @param stderr captured standard error + * @param truncated whether output was truncated due to exceeding the maximum capture size + */ +public record ExecResult(int exitCode, String stdout, String stderr, boolean truncated) { + + /** + * Returns {@code true} if the command exited with code 0. + * + * @return true if exit code is 0 + */ + public boolean ok() { + return exitCode == 0; + } + + /** + * Returns combined stdout and stderr, with stderr prefixed with "[stderr]" if non-empty. + * + * @return combined output string + */ + public String combinedOutput() { + if (stderr == null || stderr.isBlank()) { + return stdout != null ? stdout : ""; + } + String out = stdout != null ? stdout : ""; + return out + (out.isBlank() ? "" : "\n") + "[stderr] " + stderr; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java new file mode 100644 index 000000000..859032b3b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import java.io.InputStream; + +/** + * An active sandbox with a fully isolated workspace. + * + *

Lifecycle: + *

    + *
  1. Acquire via {@link SandboxClient#create} (new) or {@link SandboxClient#resume} (existing) + *
  2. Call {@link #start()} — initializes or restores the workspace + *
  3. Use {@link #exec} for command execution, {@link #persistWorkspace}/{@link #hydrateWorkspace} + * for archive operations + *
  4. Call {@link #stop()} — persists the snapshot (does NOT destroy resources) + *
  5. Call {@link #shutdown()} — destroys backend resources (tmpdir, container) + *
  6. Or use {@link #close()} which calls stop + shutdown in sequence + *
+ * + *

The distinction between {@code stop()} and {@code shutdown()} is critical: + *

    + *
  • {@code stop()}: persist snapshot only — safe for both SDK-owned and developer-owned + * sandboxes
  • + *
  • {@code shutdown()}: destroy backend resources — only called on SDK-owned sandboxes
  • + *
+ */ +public interface Sandbox extends AutoCloseable { + + void start() throws Exception; + + void stop() throws Exception; + + default void shutdown() throws Exception { + // no-op by default + } + + @Override + void close() throws Exception; + + boolean isRunning(); + + /** + * Returns the current serializable state of this sandbox. + * + * @return state (may be modified by lifecycle methods) + */ + SandboxState getState(); + + ExecResult exec(String command, Integer timeoutSeconds) throws Exception; + + InputStream persistWorkspace() throws Exception; + + void hydrateWorkspace(InputStream archive) throws Exception; +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java new file mode 100644 index 000000000..17e0d7288 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +/** + * Result of acquiring a {@link Sandbox} from {@link SandboxManager}. + */ +public final class SandboxAcquireResult { + + private final Sandbox sandbox; + private final boolean sdkOwned; + + private SandboxAcquireResult(Sandbox sandbox, boolean sdkOwned) { + this.sandbox = sandbox; + this.sdkOwned = sdkOwned; + } + + public static SandboxAcquireResult sdkOwned(Sandbox sandbox) { + return new SandboxAcquireResult(sandbox, true); + } + + public static SandboxAcquireResult developerOwned(Sandbox sandbox) { + return new SandboxAcquireResult(sandbox, false); + } + + public Sandbox getSandbox() { + return sandbox; + } + + public boolean isSdkOwned() { + return sdkOwned; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAware.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAware.java new file mode 100644 index 000000000..35869bb5d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAware.java @@ -0,0 +1,30 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +/** + * Marks a filesystem that can have its backing {@link Sandbox} injected at runtime. + * + *

Implemented by {@link SandboxBackedFilesystem} so {@link + * io.agentscope.harness.agent.hook.SandboxLifecycleHook} can set the active sandbox for each + * call and clear it afterward. + */ +public interface SandboxAware { + + void setSandbox(Sandbox sandbox); + + Sandbox getSandbox(); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java new file mode 100644 index 000000000..401f72448 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java @@ -0,0 +1,184 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.filesystem.BaseSandboxFilesystem; +import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; +import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; +import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; +import io.agentscope.harness.agent.store.NamespaceFactory; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link BaseSandboxFilesystem} that delegates execution to a live {@link Sandbox}. + * + *

Stable proxy created at agent build time; a fresh {@link Sandbox} is injected on each call + * via the volatile {@code sandbox} field by {@link + * io.agentscope.harness.agent.hook.SandboxLifecycleHook}. + */ +public class SandboxBackedFilesystem extends BaseSandboxFilesystem implements SandboxAware { + + private static final Logger log = LoggerFactory.getLogger(SandboxBackedFilesystem.class); + + private final String fsId; + private volatile Sandbox sandbox; + + public SandboxBackedFilesystem() { + this.fsId = "sandbox-" + UUID.randomUUID().toString().substring(0, 8); + } + + public void configureNamespace(NamespaceFactory factory) { + setNamespaceFactory(factory); + } + + @Override + public void setSandbox(Sandbox sandbox) { + this.sandbox = sandbox; + } + + @Override + public Sandbox getSandbox() { + return sandbox; + } + + @Override + public String id() { + return fsId; + } + + @Override + public ExecuteResponse execute(String command, Integer timeoutSeconds) { + Sandbox active = requireSandbox(); + try { + ExecResult result = active.exec(command, timeoutSeconds); + return new ExecuteResponse( + result.combinedOutput(), result.exitCode(), result.truncated()); + } catch (SandboxException.ExecTimeoutException e) { + return new ExecuteResponse(e.getMessage(), 124, false); + } catch (SandboxException.ExecException e) { + String combined = + (e.getStdout() != null ? e.getStdout() : "") + + (e.getStderr() != null && !e.getStderr().isBlank() + ? "\n" + e.getStderr() + : ""); + return new ExecuteResponse(combined, e.getExitCode(), false); + } catch (Exception e) { + log.error("[sandbox-fs] execute failed: {}", command, e); + return new ExecuteResponse("Internal sandbox error: " + e.getMessage(), -1, false); + } + } + + @Override + public List uploadFiles(List> files) { + Sandbox active = requireSandbox(); + List results = new ArrayList<>(files.size()); + + for (Map.Entry file : files) { + String path = file.getKey(); + byte[] content = file.getValue(); + + try { + String base64Content = Base64.getEncoder().encodeToString(content); + String escapedPath = shellSingleQuote(path); + String cmd = + "mkdir -p $(dirname " + + escapedPath + + ") && " + + "printf '%s' '" + + base64Content + + "' | base64 -d > " + + escapedPath; + + ExecResult result = active.exec(cmd, null); + if (result.ok()) { + results.add(FileUploadResponse.success(path)); + } else { + results.add(FileUploadResponse.fail(path, result.combinedOutput())); + } + } catch (SandboxException.ExecException e) { + String combined = + (e.getStdout() != null ? e.getStdout() : "") + + (e.getStderr() != null && !e.getStderr().isBlank() + ? "\n" + e.getStderr() + : ""); + results.add(FileUploadResponse.fail(path, combined)); + } catch (Exception e) { + log.warn("[sandbox-fs] uploadFiles failed for path: {}", path, e); + results.add(FileUploadResponse.fail(path, e.getMessage())); + } + } + + return results; + } + + @Override + public List downloadFiles(List paths) { + Sandbox active = requireSandbox(); + List results = new ArrayList<>(paths.size()); + + for (String path : paths) { + try { + String escapedPath = shellSingleQuote(path); + String cmd = "base64 " + escapedPath; + + ExecResult result = active.exec(cmd, null); + if (result.ok()) { + byte[] decoded = + Base64.getDecoder() + .decode( + result.stdout() + .trim() + .getBytes(StandardCharsets.UTF_8)); + results.add(FileDownloadResponse.success(path, decoded)); + } else { + results.add(FileDownloadResponse.fail(path, result.combinedOutput())); + } + } catch (SandboxException.ExecException e) { + String combined = + (e.getStdout() != null ? e.getStdout() : "") + + (e.getStderr() != null && !e.getStderr().isBlank() + ? "\n" + e.getStderr() + : ""); + results.add(FileDownloadResponse.fail(path, combined)); + } catch (Exception e) { + log.warn("[sandbox-fs] downloadFiles failed for path: {}", path, e); + results.add(FileDownloadResponse.fail(path, e.getMessage())); + } + } + + return results; + } + + private Sandbox requireSandbox() { + Sandbox s = sandbox; + if (s == null) { + throw new SandboxException.SandboxConfigurationException( + "No active sandbox — sandbox filesystem used outside of a call context"); + } + return s; + } + + private String shellSingleQuote(String s) { + return "'" + s.replace("'", "'\\''") + "'"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClient.java new file mode 100644 index 000000000..d4eb772a0 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClient.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; + +/** + * Factory for creating and resuming {@link Sandbox} instances. + * + * @param the type of client options for this implementation + */ +public interface SandboxClient { + + /** + * Creates a new sandbox with the given workspace spec and snapshot spec. + * + *

Returned in a pre-start state; call {@link Sandbox#start()} before use. + */ + Sandbox create(WorkspaceSpec workspaceSpec, SandboxSnapshotSpec snapshotSpec, O options); + + /** + * Resumes a sandbox from previously serialized {@link SandboxState}. + */ + Sandbox resume(SandboxState state); + + void delete(Sandbox sandbox); + + String serializeState(SandboxState state); + + SandboxState deserializeState(String json); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClientOptions.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClientOptions.java new file mode 100644 index 000000000..851ce3559 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxClientOptions.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.agentscope.harness.agent.sandbox.impl.docker.DockerSandboxClientOptions; + +/** + * Base class for sandbox client configuration options. + * + *

Each concrete subclass describes a specific sandbox backend (e.g. Docker) and can + * self-instantiate the corresponding {@link SandboxClient} via {@link #createClient()}. + * This allows callers to configure only the options object and rely on + * {@link io.agentscope.harness.agent.HarnessAgent.Builder} to derive the client automatically. + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = DockerSandboxClientOptions.class, name = "docker"), +}) +public abstract class SandboxClientOptions { + + /** + * Returns the type discriminator used in JSON serialization. + * + * @return type string (e.g. "docker") + */ + public abstract String getType(); + + /** + * Creates the {@link SandboxClient} implementation that corresponds to these options. + * + *

Called by {@link io.agentscope.harness.agent.HarnessAgent.Builder} when no explicit + * client has been provided, so callers only need to configure the options object. + * + * @return a new client instance ready for use + */ + public abstract SandboxClient createClient(); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java new file mode 100644 index 000000000..429998f37 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java @@ -0,0 +1,130 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; + +/** + * Immutable configuration for sandbox behavior. + * + *

Built with the agent and attached to {@link io.agentscope.harness.agent.RuntimeContext} for + * each call. + */ +public final class SandboxContext { + + private final SandboxClient client; + private final SandboxClientOptions clientOptions; + private final WorkspaceSpec workspaceSpec; + private final SandboxSnapshotSpec snapshotSpec; + private final Sandbox externalSandbox; + private final SandboxState externalSandboxState; + private final IsolationScope isolationScope; + + private SandboxContext(Builder builder) { + this.client = builder.client; + this.clientOptions = builder.clientOptions; + this.workspaceSpec = builder.workspaceSpec; + this.snapshotSpec = builder.snapshotSpec; + this.externalSandbox = builder.externalSandbox; + this.externalSandboxState = builder.externalSandboxState; + this.isolationScope = builder.isolationScope; + } + + public SandboxClient getClient() { + return client; + } + + public SandboxClientOptions getClientOptions() { + return clientOptions; + } + + public WorkspaceSpec getWorkspaceSpec() { + return workspaceSpec; + } + + public SandboxSnapshotSpec getSnapshotSpec() { + return snapshotSpec; + } + + public Sandbox getExternalSandbox() { + return externalSandbox; + } + + public SandboxState getExternalSandboxState() { + return externalSandboxState; + } + + public IsolationScope getIsolationScope() { + return isolationScope; + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + + private SandboxClient client; + private SandboxClientOptions clientOptions; + private WorkspaceSpec workspaceSpec; + private SandboxSnapshotSpec snapshotSpec; + private Sandbox externalSandbox; + private SandboxState externalSandboxState; + private IsolationScope isolationScope; + + private Builder() {} + + public Builder client(SandboxClient client) { + this.client = client; + return this; + } + + public Builder clientOptions(SandboxClientOptions clientOptions) { + this.clientOptions = clientOptions; + return this; + } + + public Builder workspaceSpec(WorkspaceSpec workspaceSpec) { + this.workspaceSpec = workspaceSpec; + return this; + } + + public Builder snapshotSpec(SandboxSnapshotSpec snapshotSpec) { + this.snapshotSpec = snapshotSpec; + return this; + } + + public Builder externalSandbox(Sandbox externalSandbox) { + this.externalSandbox = externalSandbox; + return this; + } + + public Builder externalSandboxState(SandboxState externalSandboxState) { + this.externalSandboxState = externalSandboxState; + return this; + } + + public Builder isolationScope(IsolationScope isolationScope) { + this.isolationScope = isolationScope; + return this; + } + + public SandboxContext build() { + return new SandboxContext(this); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java new file mode 100644 index 000000000..c4c3758ba --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java @@ -0,0 +1,154 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.core.session.Session; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.sandbox.snapshot.OssSnapshotSpec; +import io.agentscope.harness.agent.sandbox.snapshot.RedisSnapshotSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.util.Objects; + +/** + * High-level distributed sandbox configuration used by + * {@link io.agentscope.harness.agent.HarnessAgent.Builder#sandboxDistributed}. + * + *

This options object intentionally bundles the three pieces required for + * distributed sandbox restore/sharing: + *

    + *
  • distributed {@link Session} (for state-store slots)
  • + *
  • {@link SandboxSnapshotSpec} (for workspace archive persistence)
  • + *
  • {@link IsolationScope} (for sharing granularity)
  • + *
+ */ +public final class SandboxDistributedOptions { + + private final Session session; + private final SandboxSnapshotSpec snapshotSpec; + private final IsolationScope isolationScope; + private final boolean requireDistributed; + + private SandboxDistributedOptions(Builder builder) { + this.session = builder.session; + this.snapshotSpec = builder.snapshotSpec; + this.isolationScope = builder.isolationScope; + this.requireDistributed = builder.requireDistributed; + } + + /** + * Creates a builder with safe distributed defaults. + * + *

Defaults: + *

    + *
  • {@code isolationScope = USER}
  • + *
  • {@code requireDistributed = true}
  • + *
+ */ + public static Builder builder() { + return new Builder(); + } + + /** + * Creates options with OSS snapshot backend and distributed-safe defaults. + */ + public static SandboxDistributedOptions oss(Session session, OssSnapshotSpec snapshotSpec) { + return builder().session(session).snapshotSpec(snapshotSpec).build(); + } + + /** + * Creates options with Redis snapshot backend and distributed-safe defaults. + */ + public static SandboxDistributedOptions redis(Session session, RedisSnapshotSpec snapshotSpec) { + return builder().session(session).snapshotSpec(snapshotSpec).build(); + } + + /** + * Returns the distributed session backend used by {@link SessionSandboxStateStore}. + */ + public Session getSession() { + return session; + } + + /** + * Returns the snapshot spec used for workspace archive persistence. + */ + public SandboxSnapshotSpec getSnapshotSpec() { + return snapshotSpec; + } + + /** + * Returns the isolation scope for sandbox state sharing. + */ + public IsolationScope getIsolationScope() { + return isolationScope; + } + + /** + * Whether builder should fail-fast when distributed prerequisites are not met. + */ + public boolean isRequireDistributed() { + return requireDistributed; + } + + public static final class Builder { + + private Session session; + private SandboxSnapshotSpec snapshotSpec; + private IsolationScope isolationScope = IsolationScope.USER; + private boolean requireDistributed = true; + + private Builder() {} + + /** + * Sets distributed session backend (for state slot persistence). + */ + public Builder session(Session session) { + this.session = session; + return this; + } + + /** + * Sets snapshot strategy used for workspace persistence. + */ + public Builder snapshotSpec(SandboxSnapshotSpec snapshotSpec) { + this.snapshotSpec = snapshotSpec; + return this; + } + + /** + * Sets sandbox isolation scope. Default is {@link IsolationScope#USER}. + */ + public Builder isolationScope(IsolationScope isolationScope) { + this.isolationScope = Objects.requireNonNull(isolationScope, "isolationScope"); + return this; + } + + /** + * Enables/disables fail-fast checks for distributed prerequisites. + * + *

When {@code true} (default), builder throws if effective session remains local + * ({@code WorkspaceSession}) or snapshot spec is absent/no-op. + */ + public Builder requireDistributed(boolean requireDistributed) { + this.requireDistributed = requireDistributed; + return this; + } + + public SandboxDistributedOptions build() { + return new SandboxDistributedOptions(this); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxErrorCode.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxErrorCode.java new file mode 100644 index 000000000..0edec7d63 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxErrorCode.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +/** + * Error codes for sandbox operations, used in {@link SandboxException} and its subclasses. + */ +public enum SandboxErrorCode { + + /** Command exited with a non-zero exit code. */ + EXEC_NONZERO, + + /** Command execution timed out. */ + EXEC_TIMEOUT, + + /** Failed to start the workspace backend. */ + WORKSPACE_START_ERROR, + + /** Failed to stop/persist the workspace backend. */ + WORKSPACE_STOP_ERROR, + + /** Failed to read or parse a workspace archive (tar). */ + WORKSPACE_ARCHIVE_READ_ERROR, + + /** Failed to create a workspace archive (tar). */ + WORKSPACE_ARCHIVE_WRITE_ERROR, + + /** Failed to persist a snapshot. */ + SNAPSHOT_PERSIST_ERROR, + + /** Failed to restore a snapshot. */ + SNAPSHOT_RESTORE_ERROR, + + /** Snapshot does not exist or is not restorable. */ + SNAPSHOT_NOT_RESTORABLE, + + /** A manifest entry contains an invalid or unsafe path. */ + INVALID_MANIFEST_PATH, + + /** Invalid or missing sandbox configuration. */ + CONFIGURATION_ERROR +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxException.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxException.java new file mode 100644 index 000000000..9dbdade2c --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxException.java @@ -0,0 +1,329 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import java.nio.file.Path; + +/** + * Base exception for all sandbox operations. + * + *

Specialized subclasses are provided as static nested classes for common failure modes: + * {@link SandboxConfigurationException}, {@link SandboxRuntimeException}, + * {@link WorkspaceStartException}, {@link WorkspaceStopException}, + * {@link ExecException}, {@link ExecTimeoutException}, {@link SnapshotException}. + */ +public class SandboxException extends RuntimeException { + + private final SandboxErrorCode errorCode; + private final String op; + + /** + * Creates a sandbox exception with an error code and message. + * + * @param errorCode the error code classifying the failure + * @param message human-readable description + */ + public SandboxException(SandboxErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + this.op = null; + } + + /** + * Creates a sandbox exception with an error code, message, and cause. + * + * @param errorCode the error code classifying the failure + * @param message human-readable description + * @param cause the underlying cause + */ + public SandboxException(SandboxErrorCode errorCode, String message, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + this.op = null; + } + + /** + * Creates a sandbox exception with an error code, operation name, message, and cause. + * + * @param errorCode the error code classifying the failure + * @param op the operation that failed (e.g. "start", "exec", "persist") + * @param message human-readable description + * @param cause the underlying cause + */ + public SandboxException( + SandboxErrorCode errorCode, String op, String message, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + this.op = op; + } + + /** + * Returns the error code classifying this failure. + * + * @return the error code + */ + public SandboxErrorCode getErrorCode() { + return errorCode; + } + + /** + * Returns the operation name that failed, or {@code null} if not specified. + * + * @return operation name, may be null + */ + public String getOp() { + return op; + } + + // ---- Specialized subclasses ---- + + /** + * Thrown when sandbox configuration is invalid or missing (e.g. no client configured). + */ + public static class SandboxConfigurationException extends SandboxException { + + /** + * Creates a configuration exception. + * + * @param message description of the configuration problem + */ + public SandboxConfigurationException(String message) { + super(SandboxErrorCode.CONFIGURATION_ERROR, message); + } + + /** + * Creates a configuration exception with cause. + * + * @param message description of the configuration problem + * @param cause the underlying cause + */ + public SandboxConfigurationException(String message, Throwable cause) { + super(SandboxErrorCode.CONFIGURATION_ERROR, message, cause); + } + } + + /** + * Thrown for general sandbox runtime failures not covered by a more specific subclass. + */ + public static class SandboxRuntimeException extends SandboxException { + + /** + * Creates a runtime exception with an error code and message. + * + * @param errorCode the error code classifying the failure + * @param message human-readable description + */ + public SandboxRuntimeException(SandboxErrorCode errorCode, String message) { + super(errorCode, message); + } + + /** + * Creates a runtime exception with an error code, message, and cause. + * + * @param errorCode the error code classifying the failure + * @param message human-readable description + * @param cause the underlying cause + */ + public SandboxRuntimeException( + SandboxErrorCode errorCode, String message, Throwable cause) { + super(errorCode, message, cause); + } + + /** + * Creates a runtime exception with a message and cause. + * + * @param message human-readable description + * @param cause the underlying cause + */ + public SandboxRuntimeException(String message, Throwable cause) { + super(SandboxErrorCode.WORKSPACE_START_ERROR, message, cause); + } + } + + /** + * Thrown when the workspace backend fails to start. + */ + public static class WorkspaceStartException extends SandboxException { + + private final Path path; + + /** + * Creates a workspace-start exception. + * + * @param path the workspace path that could not be started + * @param cause the underlying cause + */ + public WorkspaceStartException(Path path, Throwable cause) { + super( + SandboxErrorCode.WORKSPACE_START_ERROR, + "Failed to start workspace at: " + path, + cause); + this.path = path; + } + + /** + * Returns the workspace path that failed to start. + * + * @return workspace path + */ + public Path getPath() { + return path; + } + } + + /** + * Thrown when the workspace backend fails to stop. + */ + public static class WorkspaceStopException extends SandboxException { + + private final Path path; + + /** + * Creates a workspace-stop exception. + * + * @param path the workspace path that could not be stopped + * @param cause the underlying cause + */ + public WorkspaceStopException(Path path, Throwable cause) { + super( + SandboxErrorCode.WORKSPACE_STOP_ERROR, + "Failed to stop workspace at: " + path, + cause); + this.path = path; + } + + /** + * Returns the workspace path that failed to stop. + * + * @return workspace path + */ + public Path getPath() { + return path; + } + } + + /** + * Thrown when a sandbox command exits with a non-zero exit code. + */ + public static class ExecException extends SandboxException { + + private final int exitCode; + private final String stdout; + private final String stderr; + + /** + * Creates an exec exception. + * + * @param exitCode the process exit code + * @param stdout captured standard output + * @param stderr captured standard error + */ + public ExecException(int exitCode, String stdout, String stderr) { + super( + SandboxErrorCode.EXEC_NONZERO, + "Command exited with code " + exitCode + ": " + stderr); + this.exitCode = exitCode; + this.stdout = stdout; + this.stderr = stderr; + } + + /** + * Returns the process exit code. + * + * @return exit code + */ + public int getExitCode() { + return exitCode; + } + + /** + * Returns captured standard output. + * + * @return stdout + */ + public String getStdout() { + return stdout; + } + + /** + * Returns captured standard error. + * + * @return stderr + */ + public String getStderr() { + return stderr; + } + } + + /** + * Thrown when a sandbox command times out. + */ + public static class ExecTimeoutException extends SandboxException { + + /** + * Creates an exec timeout exception. + * + * @param command the command that timed out + * @param timeoutSeconds the timeout that was exceeded + */ + public ExecTimeoutException(String command, int timeoutSeconds) { + super( + SandboxErrorCode.EXEC_TIMEOUT, + "Command timed out after " + timeoutSeconds + "s: " + command); + } + } + + /** + * Thrown when a snapshot operation (persist or restore) fails. + */ + public static class SnapshotException extends SandboxException { + + private final String snapshotId; + + /** + * Creates a snapshot exception. + * + * @param snapshotId the snapshot identifier + * @param message human-readable description + * @param cause the underlying cause + */ + public SnapshotException(String snapshotId, String message, Throwable cause) { + super(SandboxErrorCode.SNAPSHOT_PERSIST_ERROR, message, cause); + this.snapshotId = snapshotId; + } + + /** + * Creates a snapshot exception for a non-restorable snapshot. + * + * @param snapshotId the snapshot identifier + */ + public SnapshotException(String snapshotId) { + super( + SandboxErrorCode.SNAPSHOT_NOT_RESTORABLE, + "Snapshot is not restorable: " + snapshotId); + this.snapshotId = snapshotId; + } + + /** + * Returns the snapshot identifier associated with this failure. + * + * @return snapshot id + */ + public String getSnapshotId() { + return snapshotId; + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java new file mode 100644 index 000000000..a85869d73 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java @@ -0,0 +1,131 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import java.util.Objects; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Immutable key that uniquely identifies a sandbox state slot for a given + * {@link IsolationScope}. + * + *

Use {@link #resolve} to obtain a key from a {@link RuntimeContext}. The result is + * {@link Optional#empty()} when the required context field is absent (e.g., {@code USER} scope + * without a {@code userId}), meaning state lookup should be skipped. + */ +public final class SandboxIsolationKey { + + private static final Logger log = LoggerFactory.getLogger(SandboxIsolationKey.class); + + static final String GLOBAL_VALUE = "__global__"; + + private final IsolationScope scope; + private final String value; + + private SandboxIsolationKey(IsolationScope scope, String value) { + this.scope = scope; + this.value = value; + } + + /** + * Resolves an isolation key from the given scope, runtime context, and agent ID. + * + *

Resolution rules: + *

    + *
  • {@code SESSION} – requires a non-null {@code sessionKey}; value = + * {@code sessionKey.toIdentifier()}. Returns empty if absent.
  • + *
  • {@code USER} – requires a non-blank {@code userId}; value = {@code userId}. + * Logs a warning and returns empty if absent.
  • + *
  • {@code AGENT} – value = {@code agentId} (always present).
  • + *
  • {@code GLOBAL} – value = {@value #GLOBAL_VALUE} (always present).
  • + *
  • {@code null} scope – treated as {@code SESSION}.
  • + *
+ * + * @param scope the desired isolation scope; {@code null} defaults to {@code SESSION} + * @param ctx the runtime context for the current call; may be {@code null} + * @param agentId the agent name resolved at build time; must not be null + * @return resolved key, or empty if the required context field is absent + */ + public static Optional resolve( + IsolationScope scope, RuntimeContext ctx, String agentId) { + IsolationScope effective = scope != null ? scope : IsolationScope.SESSION; + return switch (effective) { + case SESSION -> { + if (ctx == null || ctx.getSessionKey() == null) { + yield Optional.empty(); + } + yield Optional.of( + new SandboxIsolationKey( + IsolationScope.SESSION, ctx.getSessionKey().toIdentifier())); + } + case USER -> { + if (ctx == null || ctx.getUserId() == null || ctx.getUserId().isBlank()) { + log.warn( + "[sandbox] USER isolation scope requested but userId is absent" + + " — skipping state lookup; a fresh sandbox will be" + + " created"); + yield Optional.empty(); + } + yield Optional.of(new SandboxIsolationKey(IsolationScope.USER, ctx.getUserId())); + } + case AGENT -> + Optional.of( + new SandboxIsolationKey( + IsolationScope.AGENT, Objects.requireNonNull(agentId))); + case GLOBAL -> + Optional.of(new SandboxIsolationKey(IsolationScope.GLOBAL, GLOBAL_VALUE)); + }; + } + + /** + * Returns the isolation scope. + * + * @return scope + */ + public IsolationScope getScope() { + return scope; + } + + /** + * Returns the discriminating value within the scope (e.g. session id, user id, agent name). + * + * @return value string + */ + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SandboxIsolationKey that)) return false; + return scope == that.scope && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(scope, value); + } + + @Override + public String toString() { + return "SandboxIsolationKey{scope=" + scope + ", value='" + value + "'}"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java new file mode 100644 index 000000000..4b4e59e02 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java @@ -0,0 +1,176 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.RuntimeContext; +import java.util.Objects; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Manages the lifecycle of {@link Sandbox} instances for the current call. + * + *

Acquire priority: {@link SandboxContext#getExternalSandbox()} > {@link + * SandboxContext#getExternalSandboxState()} > persisted {@link SandboxState} > {@link + * SandboxClient#create}. + */ +public class SandboxManager { + + private static final Logger log = LoggerFactory.getLogger(SandboxManager.class); + + private final SandboxClient client; + private final SandboxStateStore stateStore; + private final String agentId; + + public SandboxManager(SandboxClient client, SandboxStateStore stateStore, String agentId) { + this.client = Objects.requireNonNull(client, "client must not be null"); + this.stateStore = Objects.requireNonNull(stateStore, "stateStore must not be null"); + this.agentId = Objects.requireNonNull(agentId, "agentId must not be null"); + } + + public SandboxAcquireResult acquire( + SandboxContext sandboxContext, RuntimeContext runtimeContext) throws Exception { + if (sandboxContext.getExternalSandbox() != null) { + Sandbox external = sandboxContext.getExternalSandbox(); + log.debug( + "[sandbox] Priority 1: using developer-owned sandbox: {}", + external.getState() != null ? external.getState().getSessionId() : "?"); + return SandboxAcquireResult.developerOwned(external); + } + + if (sandboxContext.getExternalSandboxState() != null) { + Sandbox sandbox = client.resume(sandboxContext.getExternalSandboxState()); + log.debug( + "[sandbox] Priority 2: resuming from explicit state: {}", + sandboxContext.getExternalSandboxState().getSessionId()); + return SandboxAcquireResult.sdkOwned(sandbox); + } + + Optional scopeKey = + SandboxIsolationKey.resolve( + sandboxContext.getIsolationScope(), runtimeContext, agentId); + if (scopeKey.isPresent()) { + try { + Optional stateJson = stateStore.load(scopeKey.get()); + if (stateJson.isPresent()) { + log.debug( + "[sandbox] Priority 3: resuming from persisted state (scope={})", + scopeKey.get()); + SandboxState state = client.deserializeState(stateJson.get()); + Sandbox sandbox = client.resume(state); + return SandboxAcquireResult.sdkOwned(sandbox); + } + } catch (Exception e) { + log.warn( + "[sandbox] Failed to load persisted state for scope {}, falling through" + + " to fresh create: {}", + scopeKey.get(), + e.getMessage(), + e); + } + } + + log.debug("[sandbox] Priority 4: creating new sandbox"); + WorkspaceSpec spec = + sandboxContext.getWorkspaceSpec() != null + ? sandboxContext.getWorkspaceSpec().copy() + : new WorkspaceSpec(); + + @SuppressWarnings("unchecked") + SandboxClient typedClient = + (SandboxClient) client; + Sandbox sandbox = + typedClient.create( + spec, sandboxContext.getSnapshotSpec(), sandboxContext.getClientOptions()); + return SandboxAcquireResult.sdkOwned(sandbox); + } + + public void release(SandboxAcquireResult result) { + if (result == null) { + return; + } + Sandbox sandbox = result.getSandbox(); + if (sandbox == null) { + return; + } + + try { + sandbox.stop(); + } catch (Exception e) { + log.warn("[sandbox] Sandbox stop failed: {}", e.getMessage(), e); + } + + if (result.isSdkOwned()) { + try { + sandbox.shutdown(); + } catch (Exception e) { + log.warn("[sandbox] Sandbox shutdown failed: {}", e.getMessage(), e); + } + } + } + + public void persistState( + SandboxAcquireResult result, + SandboxContext sandboxContext, + RuntimeContext runtimeContext) { + if (result == null || result.getSandbox() == null) { + return; + } + SandboxState state = result.getSandbox().getState(); + if (state == null) { + return; + } + + Optional scopeKey = + SandboxIsolationKey.resolve( + sandboxContext != null ? sandboxContext.getIsolationScope() : null, + runtimeContext, + agentId); + if (scopeKey.isEmpty()) { + log.debug("[sandbox] No scope key available, skipping state persistence"); + return; + } + + try { + String json = client.serializeState(state); + stateStore.save(scopeKey.get(), json); + log.debug( + "[sandbox] Persisted sandbox state for scope {}: sessionId={}", + scopeKey.get(), + state.getSessionId()); + } catch (Exception e) { + log.warn("[sandbox] Failed to persist sandbox state: {}", e.getMessage(), e); + } + } + + public void clearState(SandboxContext sandboxContext, RuntimeContext runtimeContext) { + Optional scopeKey = + SandboxIsolationKey.resolve( + sandboxContext != null ? sandboxContext.getIsolationScope() : null, + runtimeContext, + agentId); + if (scopeKey.isEmpty()) { + return; + } + + try { + stateStore.delete(scopeKey.get()); + } catch (Exception e) { + log.warn("[sandbox] Failed to clear sandbox state: {}", e.getMessage(), e); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxState.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxState.java new file mode 100644 index 000000000..e19a671b8 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxState.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.agentscope.harness.agent.sandbox.impl.docker.DockerSandboxState; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshot; + +/** + * Serializable state of a sandbox, persisted by {@link SandboxStateStore} so a sandbox can + * be resumed across calls. + * + *

The {@link #workspaceRootReady} flag drives the 4-branch start logic: it records whether + * the workspace was fully initialized at the last stop. + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonSubTypes({@JsonSubTypes.Type(value = DockerSandboxState.class, name = "docker")}) +public abstract class SandboxState { + + private String sessionId; + + @JsonProperty("manifest") + private WorkspaceSpec workspaceSpec; + + private SandboxSnapshot snapshot; + private String workspaceProjectionHash; + private boolean workspaceRootReady = false; + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public WorkspaceSpec getWorkspaceSpec() { + return workspaceSpec; + } + + public void setWorkspaceSpec(WorkspaceSpec workspaceSpec) { + this.workspaceSpec = workspaceSpec; + } + + public SandboxSnapshot getSnapshot() { + return snapshot; + } + + public void setSnapshot(SandboxSnapshot snapshot) { + this.snapshot = snapshot; + } + + public String getWorkspaceProjectionHash() { + return workspaceProjectionHash; + } + + public void setWorkspaceProjectionHash(String workspaceProjectionHash) { + this.workspaceProjectionHash = workspaceProjectionHash; + } + + public boolean isWorkspaceRootReady() { + return workspaceRootReady; + } + + public void setWorkspaceRootReady(boolean workspaceRootReady) { + this.workspaceRootReady = workspaceRootReady; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxStateStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxStateStore.java new file mode 100644 index 000000000..330e4fce6 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxStateStore.java @@ -0,0 +1,61 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import java.io.IOException; +import java.util.Optional; + +/** + * Storage abstraction for persisting and loading sandbox session state keyed by + * {@link SandboxIsolationKey}. + * + *

Implementations must be safe to call from multiple threads, but they are not required to + * provide transactional or atomic semantics across concurrent writes to the same key. + * + * @see WorkspaceSandboxStateStore + */ +public interface SandboxStateStore { + + /** + * Loads the persisted sandbox state JSON for the given key. + * + * @param key the isolation key identifying the state slot + * @return the serialized {@link SandboxState} JSON, or empty if no state is stored + * @throws IOException if a storage error occurs + */ + Optional load(SandboxIsolationKey key) throws IOException; + + /** + * Saves the sandbox state JSON for the given key. + * + *

An existing value for the same key is overwritten. + * + * @param key the isolation key identifying the state slot + * @param json the serialized {@link SandboxState} JSON + * @throws IOException if a storage error occurs + */ + void save(SandboxIsolationKey key, String json) throws IOException; + + /** + * Deletes the sandbox state for the given key. + * + *

No-op if no state is stored for the key. + * + * @param key the isolation key identifying the state slot + * @throws IOException if a storage error occurs + */ + void delete(SandboxIsolationKey key) throws IOException; +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStore.java new file mode 100644 index 000000000..880649a8d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStore.java @@ -0,0 +1,100 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.core.session.Session; +import io.agentscope.core.state.SessionKey; +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.core.state.State; +import io.agentscope.harness.agent.IsolationScope; +import java.io.IOException; +import java.util.Objects; +import java.util.Optional; + +/** + * {@link SandboxStateStore} backed by the generic AgentScope {@link Session} abstraction. + * + *

This store keeps sandbox lifecycle state in the same state backend as ReActAgent runtime + * state. As a result, providing a distributed {@link Session} implementation (for example Redis) + * automatically enables distributed sandbox resume state. + */ +public final class SessionSandboxStateStore implements SandboxStateStore { + + private static final String SANDBOX_STATE_KEY = "_sandbox_state"; + + private final Session session; + private final String agentId; + + public SessionSandboxStateStore(Session session, String agentId) { + this.session = Objects.requireNonNull(session, "session must not be null"); + this.agentId = Objects.requireNonNull(agentId, "agentId must not be null"); + } + + @Override + public Optional load(SandboxIsolationKey key) throws IOException { + try { + SessionKey slot = slotKey(key); + Optional state = + session.get(slot, SANDBOX_STATE_KEY, SandboxStateSlot.class); + if (state.isEmpty() || state.get().deleted() || state.get().json() == null) { + return Optional.empty(); + } + return Optional.of(state.get().json()); + } catch (Exception e) { + throw asIo("load", key, e); + } + } + + @Override + public void save(SandboxIsolationKey key, String json) throws IOException { + try { + session.save(slotKey(key), SANDBOX_STATE_KEY, new SandboxStateSlot(json, false)); + } catch (Exception e) { + throw asIo("save", key, e); + } + } + + @Override + public void delete(SandboxIsolationKey key) throws IOException { + try { + // Not all Session implementations support per-key delete. Tombstone keeps behavior + // consistent across backends. + session.save(slotKey(key), SANDBOX_STATE_KEY, SandboxStateSlot.tombstone()); + } catch (Exception e) { + throw asIo("delete", key, e); + } + } + + private SessionKey slotKey(SandboxIsolationKey key) { + IsolationScope scope = key.getScope(); + return switch (scope) { + case SESSION -> SimpleSessionKey.of("sandbox/session/" + key.getValue()); + case USER -> SimpleSessionKey.of("sandbox/user/" + agentId + "/" + key.getValue()); + case AGENT -> SimpleSessionKey.of("sandbox/agent/" + agentId); + case GLOBAL -> SimpleSessionKey.of("sandbox/global"); + }; + } + + private static IOException asIo(String op, SandboxIsolationKey key, Exception e) { + return new IOException("Failed to " + op + " sandbox state for " + key, e); + } + + private record SandboxStateSlot(String json, boolean deleted) implements State { + static SandboxStateSlot tombstone() { + return new SandboxStateSlot("", true); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceArchiveExtractor.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceArchiveExtractor.java new file mode 100644 index 000000000..ea903f9bb --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceArchiveExtractor.java @@ -0,0 +1,114 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; + +/** + * Securely extracts tar archives into a target directory. + * + *

Applies strict path traversal guards before extracting each archive entry: + *

    + *
  1. Rejects entries with absolute paths (starting with {@code /} or {@code \})
  2. + *
  3. Rejects entries containing {@code ..} path segments
  4. + *
  5. Verifies the resolved destination path starts with the canonical root
  6. + *
+ * + *

These guards defend against the "Zip Slip" class of path traversal attacks. + */ +public class WorkspaceArchiveExtractor { + + private WorkspaceArchiveExtractor() { + // Utility class, no instances + } + + /** + * Extracts a tar archive stream into the given destination directory. + * + *

The destination directory must already exist. Existing files at the same paths + * will be replaced. + * + * @param destRoot the directory to extract into; must already exist + * @param tarStream the tar archive input stream; caller is responsible for closing + * @throws SandboxException.SandboxRuntimeException if a path traversal attempt is detected + * @throws Exception if extraction fails for any other reason + */ + public static void extractTarArchive(Path destRoot, InputStream tarStream) throws Exception { + Path canonicalRoot = destRoot.normalize().toAbsolutePath(); + + try (TarArchiveInputStream tar = new TarArchiveInputStream(tarStream)) { + TarArchiveEntry entry; + while ((entry = tar.getNextEntry()) != null) { + validateEntryName(entry.getName(), canonicalRoot); + + Path dest = canonicalRoot.resolve(entry.getName()).normalize(); + + // Final guard: verify destination is strictly within the root + if (!dest.startsWith(canonicalRoot)) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "Tar entry escapes destination root: " + entry.getName()); + } + + if (entry.isDirectory()) { + Files.createDirectories(dest); + } else { + if (dest.getParent() != null) { + Files.createDirectories(dest.getParent()); + } + Files.copy(tar, dest, StandardCopyOption.REPLACE_EXISTING); + } + } + } + } + + private static void validateEntryName(String name, Path canonicalRoot) { + if (name == null || name.isEmpty()) { + return; + } + + // Reject absolute paths + if (name.startsWith("/") || name.startsWith("\\")) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "Tar entry has absolute path (rejected): " + name); + } + + // Reject path traversal sequences + if (name.contains("..")) { + // Normalize and check for actual traversal segments + for (String segment : name.split("[/\\\\]")) { + if ("..".equals(segment)) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "Tar entry contains path traversal (rejected): " + name); + } + } + } + + // Reject null bytes + if (name.contains("\0")) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "Tar entry name contains null byte (rejected): " + name); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplier.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplier.java new file mode 100644 index 000000000..272838fd8 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplier.java @@ -0,0 +1,156 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.sandbox.layout.DirEntry; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceEntry; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceProjectionEntry; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; + +/** + * Builds a deterministic archive payload for workspace projection entries. + * + *

The payload contains: + *

    + *
  • projected files as a tar archive (for sandbox hydration)
  • + *
  • a content hash used to skip unchanged projections across calls
  • + *
+ */ +public final class WorkspaceProjectionApplier { + + private WorkspaceProjectionApplier() {} + + /** + * Builds projection payload from all {@link WorkspaceProjectionEntry} items in the spec. + */ + public static ProjectionPayload build(WorkspaceSpec spec) throws Exception { + if (spec == null || spec.getEntries().isEmpty()) { + return null; + } + List entries = new ArrayList<>(); + collectProjectionEntries(spec.getEntries(), entries); + if (entries.isEmpty()) { + return null; + } + + Map projectedFiles = collectProjectedFiles(entries); + List> ordered = new ArrayList<>(projectedFiles.entrySet()); + ordered.sort(Comparator.comparing(Map.Entry::getKey)); + + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (TarArchiveOutputStream tar = new TarArchiveOutputStream(baos)) { + tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); + for (Map.Entry file : ordered) { + String rel = file.getKey(); + Path src = file.getValue(); + byte[] content = Files.readAllBytes(src); + + digest.update(rel.getBytes(java.nio.charset.StandardCharsets.UTF_8)); + digest.update((byte) 0); + digest.update(content); + + TarArchiveEntry entry = new TarArchiveEntry(rel); + entry.setSize(content.length); + tar.putArchiveEntry(entry); + tar.write(content); + tar.closeArchiveEntry(); + } + tar.finish(); + } + + String hash = bytesToHex(digest.digest()); + return new ProjectionPayload(hash, baos.toByteArray(), ordered.size()); + } + + private static void collectProjectionEntries( + Map map, List out) { + for (WorkspaceEntry entry : map.values()) { + if (entry instanceof WorkspaceProjectionEntry projection) { + out.add(projection); + } else if (entry instanceof DirEntry dir && !dir.getChildren().isEmpty()) { + collectProjectionEntries(dir.getChildren(), out); + } + } + } + + private static Map collectProjectedFiles(List entries) + throws IOException { + Map files = new LinkedHashMap<>(); + for (WorkspaceProjectionEntry entry : entries) { + if (entry.getSourceRoot() == null || entry.getSourceRoot().isBlank()) { + continue; + } + Path sourceRoot = Path.of(entry.getSourceRoot()).toAbsolutePath().normalize(); + for (String root : entry.getIncludeRoots()) { + if (root == null || root.isBlank()) { + continue; + } + Path resolved = sourceRoot.resolve(root).normalize(); + if (!resolved.startsWith(sourceRoot) || !Files.exists(resolved)) { + continue; + } + if (Files.isRegularFile(resolved)) { + files.put(normalizePath(root), resolved); + } else if (Files.isDirectory(resolved)) { + try (var walk = Files.walk(resolved)) { + walk.filter(Files::isRegularFile) + .forEach( + p -> { + String rel = + normalizePath( + sourceRoot.relativize(p).toString()); + files.put(rel, p); + }); + } + } + } + } + return files; + } + + private static String normalizePath(String path) { + return path.replace('\\', '/'); + } + + private static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(bytes.length * 2); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + + /** + * Projection result used at sandbox start. + * + * @param hash deterministic hash over projected file paths and bytes + * @param tarBytes tar archive containing projected files + * @param fileCount number of projected files + */ + public record ProjectionPayload(String hash, byte[] tarBytes, int fileCount) {} +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStore.java new file mode 100644 index 000000000..1ec722f26 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStore.java @@ -0,0 +1,130 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.IsolationScope; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Base64; +import java.util.Optional; +import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Filesystem-backed implementation of {@link SandboxStateStore}. + * + *

On-disk layout (relative to {@code workspaceRoot}): + * + *

+ * SESSION scope  → agents/<agentId>/context/<safe(sessionId)>/_sandbox.json
+ * USER scope     → agents/<agentId>/sandboxes/user/<safe(userId)>.json
+ * AGENT scope    → agents/<agentId>/sandboxes/agent.json
+ * GLOBAL scope   → sandboxes/global.json
+ * 
+ * + *

Values that contain characters outside {@code [a-zA-Z0-9_\-.]} are Base64url-encoded + * (no padding) to produce filesystem-safe filenames. + */ +public final class WorkspaceSandboxStateStore implements SandboxStateStore { + + private static final Logger log = LoggerFactory.getLogger(WorkspaceSandboxStateStore.class); + + private static final Pattern SAFE_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\-.]+$"); + + private final Path workspaceRoot; + private final String agentId; + + /** + * Creates a store backed by the given workspace directory. + * + * @param workspaceRoot root of the agent workspace + * @param agentId agent name (used in path construction for all scopes) + */ + public WorkspaceSandboxStateStore(Path workspaceRoot, String agentId) { + this.workspaceRoot = workspaceRoot; + this.agentId = agentId; + } + + @Override + public Optional load(SandboxIsolationKey key) throws IOException { + Path file = resolveFile(key); + if (!Files.exists(file)) { + return Optional.empty(); + } + return Optional.of(Files.readString(file, StandardCharsets.UTF_8)); + } + + @Override + public void save(SandboxIsolationKey key, String json) throws IOException { + Path file = resolveFile(key); + Files.createDirectories(file.getParent()); + Files.writeString( + file, + json, + StandardCharsets.UTF_8, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + log.debug("[sandbox-store] Saved state to {}", file); + } + + @Override + public void delete(SandboxIsolationKey key) throws IOException { + Path file = resolveFile(key); + Files.deleteIfExists(file); + log.debug("[sandbox-store] Deleted state at {}", file); + } + + /** Resolves the file path for the given key. */ + private Path resolveFile(SandboxIsolationKey key) { + IsolationScope scope = key.getScope(); + if (scope == IsolationScope.SESSION) { + return workspaceRoot + .resolve("agents") + .resolve(agentId) + .resolve("context") + .resolve(safeName(key.getValue())) + .resolve("_sandbox.json"); + } else if (scope == IsolationScope.USER) { + return workspaceRoot + .resolve("agents") + .resolve(agentId) + .resolve("sandboxes") + .resolve("user") + .resolve(safeName(key.getValue()) + ".json"); + } else if (scope == IsolationScope.AGENT) { + return workspaceRoot + .resolve("agents") + .resolve(agentId) + .resolve("sandboxes") + .resolve("agent.json"); + } else { + return workspaceRoot.resolve("sandboxes").resolve("global.json"); + } + } + + private static String safeName(String value) { + if (SAFE_PATTERN.matcher(value).matches()) { + return value; + } + return Base64.getUrlEncoder() + .withoutPadding() + .encodeToString(value.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpec.java new file mode 100644 index 000000000..8d2341f48 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpec.java @@ -0,0 +1,84 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.sandbox.layout.WorkspaceEntry; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Describes the desired initial state of a sandbox workspace: root path, materialized + * file/directory entries, and per-exec environment variables. + * + *

Fields: + *

    + *
  • {@code root} — workspace path inside the sandbox (default: {@code /workspace}) + *
  • {@code entries} — files and directories to materialize at startup + *
  • {@code environment} — environment variables to inject into every exec command + *
+ * + *

Usage example: + *

{@code
+ * WorkspaceSpec spec = new WorkspaceSpec();
+ * spec.setRoot("/workspace");
+ * spec.getEntries().put("README.md", new io.agentscope.harness.agent.sandbox.layout.FileEntry("# My Project"));
+ * spec.getEnvironment().put("DEBUG", "true");
+ * }
+ */ +public class WorkspaceSpec { + + private String root = "/workspace"; + private Map entries = new LinkedHashMap<>(); + private Map environment = new LinkedHashMap<>(); + + public WorkspaceSpec() {} + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public Map getEntries() { + return entries; + } + + public void setEntries(Map entries) { + this.entries = entries != null ? entries : new LinkedHashMap<>(); + } + + public Map getEnvironment() { + return environment; + } + + public void setEnvironment(Map environment) { + this.environment = environment != null ? environment : new LinkedHashMap<>(); + } + + /** + * Creates a deep copy. {@link WorkspaceEntry} values in the entries map are shared + * (shallow copy); they are treated as immutable once a sandbox has started. + */ + public WorkspaceSpec copy() { + WorkspaceSpec copy = new WorkspaceSpec(); + copy.root = this.root; + copy.entries = new LinkedHashMap<>(this.entries); + copy.environment = new LinkedHashMap<>(this.environment); + return copy; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpecApplier.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpecApplier.java new file mode 100644 index 000000000..c6108eddc --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/WorkspaceSpecApplier.java @@ -0,0 +1,159 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import io.agentscope.harness.agent.sandbox.layout.DirEntry; +import io.agentscope.harness.agent.sandbox.layout.FileEntry; +import io.agentscope.harness.agent.sandbox.layout.GitRepoEntry; +import io.agentscope.harness.agent.sandbox.layout.LocalDirEntry; +import io.agentscope.harness.agent.sandbox.layout.LocalFileEntry; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceEntry; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceProjectionEntry; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.util.Map; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Applies a {@link WorkspaceSpec} to a target directory by materializing declared entries + * (files, directories, local copies). + * + *

Supports two materialization modes: + *

    + *
  • {@code onlyEphemeral=false}: apply all entries (Branch C / D of sandbox start)
  • + *
  • {@code onlyEphemeral=true}: apply only entries where + * {@link WorkspaceEntry#isEphemeral()} is {@code true} (Branch A / B of sandbox start) + *
  • + *
+ */ +public class WorkspaceSpecApplier { + + private static final Logger log = LoggerFactory.getLogger(WorkspaceSpecApplier.class); + + private final Path workspaceRoot; + + public WorkspaceSpecApplier(String workspaceRoot) { + this.workspaceRoot = Path.of(workspaceRoot); + } + + public WorkspaceSpecApplier(Path workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } + + public void applyWorkspaceSpec(WorkspaceSpec spec, boolean onlyEphemeral) throws Exception { + if (onlyEphemeral) { + applyEphemeralEntries(spec.getEntries(), workspaceRoot); + } else { + applyAllEntries(spec.getEntries(), workspaceRoot); + } + } + + private void applyAllEntries(Map entries, Path destDir) + throws Exception { + for (Map.Entry e : entries.entrySet()) { + Path dest = destDir.resolve(e.getKey()); + applyEntry(e.getValue(), dest); + } + } + + private void applyEphemeralEntries(Map entries, Path destDir) + throws Exception { + for (Map.Entry e : entries.entrySet()) { + WorkspaceEntry entry = e.getValue(); + Path dest = destDir.resolve(e.getKey()); + if (entry.isEphemeral()) { + applyEntry(entry, dest); + } else if (entry instanceof DirEntry de && !de.getChildren().isEmpty()) { + applyEphemeralEntries(de.getChildren(), dest); + } + } + } + + private void applyEntry(WorkspaceEntry entry, Path dest) throws Exception { + if (entry instanceof FileEntry fe) { + Files.createDirectories(dest.getParent()); + Charset charset = + Charset.forName(fe.getEncoding() != null ? fe.getEncoding() : "UTF-8"); + Files.writeString( + dest, + fe.getContent() != null ? fe.getContent() : "", + charset, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + + } else if (entry instanceof DirEntry de) { + Files.createDirectories(dest); + for (Map.Entry child : de.getChildren().entrySet()) { + applyEntry(child.getValue(), dest.resolve(child.getKey())); + } + + } else if (entry instanceof LocalFileEntry lf) { + if (lf.getSourcePath() == null || lf.getSourcePath().isBlank()) { + log.warn("LocalFileEntry has null/blank sourcePath, skipping: {}", dest); + return; + } + Path source = Path.of(lf.getSourcePath()).toAbsolutePath().normalize(); + Files.createDirectories(dest.getParent()); + Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING); + + } else if (entry instanceof LocalDirEntry ld) { + if (ld.getSourcePath() == null || ld.getSourcePath().isBlank()) { + log.warn("LocalDirEntry has null/blank sourcePath, skipping: {}", dest); + return; + } + Path source = Path.of(ld.getSourcePath()).toAbsolutePath().normalize(); + copyDirectory(source, dest); + + } else if (entry instanceof GitRepoEntry) { + log.warn("GitRepoEntry is not yet implemented, skipping entry at: {}", dest); + } else if (entry instanceof WorkspaceProjectionEntry) { + log.debug( + "WorkspaceProjectionEntry is applied by sandbox lifecycle, skipping: {}", dest); + } + } + + private void copyDirectory(Path source, Path dest) throws Exception { + if (!Files.isDirectory(source)) { + throw new IOException("LocalDirEntry sourcePath is not a directory: " + source); + } + try (Stream walk = Files.walk(source)) { + walk.forEach( + src -> { + Path rel = source.relativize(src); + Path target = dest.resolve(rel); + try { + if (Files.isDirectory(src)) { + Files.createDirectories(target); + } else { + Files.createDirectories(target.getParent()); + Files.copy(src, target, StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } catch (UncheckedIOException e) { + throw e.getCause(); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java new file mode 100644 index 000000000..57c1c938a --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java @@ -0,0 +1,102 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.filesystem; + +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.impl.docker.DockerSandboxClientOptions; +import io.agentscope.harness.agent.sandbox.snapshot.NoopSnapshotSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Sandbox filesystem spec for Docker backend. + */ +public class DockerFilesystemSpec extends SandboxFilesystemSpec { + + private SandboxClient client; + private final DockerSandboxClientOptions options = new DockerSandboxClientOptions(); + private SandboxSnapshotSpec snapshotSpec = new NoopSnapshotSpec(); + private WorkspaceSpec defaultWorkspaceSpec = new WorkspaceSpec(); + + public DockerFilesystemSpec client(SandboxClient client) { + this.client = client; + return this; + } + + public DockerFilesystemSpec image(String image) { + options.image(image); + return this; + } + + public DockerFilesystemSpec workspaceRoot(String workspaceRoot) { + options.workspaceRoot(workspaceRoot); + return this; + } + + public DockerFilesystemSpec environment(Map environment) { + options.setEnvironment( + environment != null ? new LinkedHashMap<>(environment) : new LinkedHashMap<>()); + return this; + } + + public DockerFilesystemSpec memorySizeBytes(Long memorySizeBytes) { + options.memorySizeBytes(memorySizeBytes); + return this; + } + + public DockerFilesystemSpec cpuCount(Long cpuCount) { + options.cpuCount(cpuCount); + return this; + } + + public DockerFilesystemSpec exposedPorts(int... exposedPorts) { + options.exposedPorts(exposedPorts); + return this; + } + + public DockerFilesystemSpec snapshotSpec(SandboxSnapshotSpec snapshotSpec) { + this.snapshotSpec = snapshotSpec; + return this; + } + + public DockerFilesystemSpec workspaceSpec(WorkspaceSpec workspaceSpec) { + this.defaultWorkspaceSpec = workspaceSpec; + return this; + } + + @Override + protected SandboxClient createClient() { + return client != null ? client : options.createClient(); + } + + @Override + protected SandboxClientOptions clientOptions() { + return options; + } + + @Override + protected SandboxSnapshotSpec snapshotSpec() { + return snapshotSpec; + } + + @Override + protected WorkspaceSpec workspaceSpec() { + return defaultWorkspaceSpec; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java new file mode 100644 index 000000000..9299f00fe --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java @@ -0,0 +1,119 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.filesystem; + +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.SandboxContext; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceEntry; +import io.agentscope.harness.agent.sandbox.layout.WorkspaceProjectionEntry; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.nio.file.Path; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Declarative sandbox filesystem configuration. + * + *

Unlike {@code AbstractFilesystem}, this type is not a runtime filesystem implementation. + * It only describes how to create a sandbox-backed filesystem at build time. + */ +public abstract class SandboxFilesystemSpec { + + private static final List DEFAULT_WORKSPACE_PROJECTION_ROOTS = + List.of("AGENTS.md", "skills", "subagents", "knowledge"); + + private IsolationScope isolationScope; + private SandboxSnapshotSpec snapshotSpecOverride; + private boolean workspaceProjectionEnabled = true; + private List workspaceProjectionRoots = DEFAULT_WORKSPACE_PROJECTION_ROOTS; + + protected abstract SandboxClient createClient(); + + protected abstract SandboxClientOptions clientOptions(); + + protected abstract SandboxSnapshotSpec snapshotSpec(); + + protected abstract WorkspaceSpec workspaceSpec(); + + public SandboxFilesystemSpec isolationScope(IsolationScope scope) { + this.isolationScope = scope; + return this; + } + + public IsolationScope getIsolationScope() { + return isolationScope; + } + + public SandboxFilesystemSpec snapshotSpec(SandboxSnapshotSpec snapshotSpec) { + this.snapshotSpecOverride = snapshotSpec; + return this; + } + + public SandboxSnapshotSpec getSnapshotSpecOverride() { + return snapshotSpecOverride; + } + + public SandboxFilesystemSpec workspaceProjectionEnabled(boolean enabled) { + this.workspaceProjectionEnabled = enabled; + return this; + } + + public SandboxFilesystemSpec workspaceProjectionRoots(List includeRoots) { + this.workspaceProjectionRoots = + includeRoots != null + ? List.copyOf(includeRoots) + : DEFAULT_WORKSPACE_PROJECTION_ROOTS; + return this; + } + + public final SandboxContext toSandboxContext(Path hostWorkspaceRoot) { + SandboxClient client = + Objects.requireNonNull(createClient(), "sandbox client is required"); + WorkspaceSpec withProjection = buildWorkspaceSpecWithProjection(hostWorkspaceRoot); + return SandboxContext.builder() + .client(client) + .clientOptions(clientOptions()) + .snapshotSpec(snapshotSpecOverride != null ? snapshotSpecOverride : snapshotSpec()) + .workspaceSpec(withProjection) + .isolationScope(isolationScope) + .build(); + } + + public final SandboxContext toSandboxContext() { + return toSandboxContext(null); + } + + private WorkspaceSpec buildWorkspaceSpecWithProjection(Path hostWorkspaceRoot) { + WorkspaceSpec base = workspaceSpec(); + WorkspaceSpec effective = base != null ? base.copy() : new WorkspaceSpec(); + if (!workspaceProjectionEnabled || hostWorkspaceRoot == null) { + return effective; + } + WorkspaceProjectionEntry projection = new WorkspaceProjectionEntry(); + projection.setSourceRoot(hostWorkspaceRoot.toAbsolutePath().normalize().toString()); + projection.setIncludeRoots(workspaceProjectionRoots); + + Map entries = new LinkedHashMap<>(effective.getEntries()); + entries.put("__workspace_projection__", projection); + effective.setEntries(entries); + return effective; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java new file mode 100644 index 000000000..8eced8522 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java @@ -0,0 +1,599 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.impl.docker; + +import io.agentscope.harness.agent.sandbox.AbstractBaseSandbox; +import io.agentscope.harness.agent.sandbox.ExecResult; +import io.agentscope.harness.agent.sandbox.SandboxErrorCode; +import io.agentscope.harness.agent.sandbox.SandboxException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Docker {@link io.agentscope.harness.agent.sandbox.Sandbox} that runs commands in a container. + * + *

Uses the {@code docker} CLI via {@link ProcessBuilder}; no docker-java library + * dependency is required. The Docker daemon must be accessible on the host. + * + *

Container Lifecycle

+ *
    + *
  • On {@link #start()}: the container is created and started if it does not exist; + * if the container exists but is stopped it is restarted; if it is already running + * the existing container is reused.
  • + *
  • On {@link #stop()}: the workspace snapshot is persisted (if configured). + * The container keeps running.
  • + *
  • On {@link #shutdown()}: the container is stopped and removed if SDK-owned.
  • + *
+ * + *

Workspace Operations

+ *
    + *
  • Exec: {@code docker exec -w sh -c }
  • + *
  • PersistWorkspace: {@code docker exec tar -cf - -C .}
  • + *
  • HydrateWorkspace: {@code docker exec -i tar -xf - -C }
  • + *
+ */ +public class DockerSandbox extends AbstractBaseSandbox { + + private static final Logger log = LoggerFactory.getLogger(DockerSandbox.class); + + private static final int OUTPUT_TRUNCATE_BYTES = 512 * 1024; // 512 KB per stream + private static final int CONTAINER_START_TIMEOUT_SECONDS = 60; + private static final int CONTAINER_STOP_TIMEOUT_SECONDS = 30; + private static final int TAR_TIMEOUT_SECONDS = 120; + + private final DockerSandboxState dockerState; + + public DockerSandbox(DockerSandboxState state) { + super(state); + this.dockerState = state; + } + + /** + * Ensures the backing Docker container is running before executing the standard + * 4-branch workspace start logic. + * + * @throws Exception if the container cannot be started + */ + @Override + public void start() throws Exception { + doEnsureContainerRunning(); + super.start(); + } + + /** + * Stops and removes the Docker container if SDK-owned. + * + * @throws Exception if the container cannot be stopped or removed + */ + @Override + public void shutdown() throws Exception { + String containerId = dockerState.getContainerId(); + if (containerId == null || containerId.isBlank()) { + return; + } + if (!dockerState.isContainerOwned()) { + log.debug( + "[sandbox-docker] Skipping shutdown: container is developer-owned: {}", + containerId); + return; + } + try { + runDockerCliBlocking( + CONTAINER_STOP_TIMEOUT_SECONDS * 2, + "docker", + "stop", + "--time=" + CONTAINER_STOP_TIMEOUT_SECONDS, + containerId); + log.debug("[sandbox-docker] Container stopped: {}", containerId); + } catch (Exception e) { + log.warn( + "[sandbox-docker] Failed to stop container {}: {}", + containerId, + e.getMessage()); + } + try { + runDockerCliBlocking(30, "docker", "rm", "--force", containerId); + log.debug("[sandbox-docker] Container removed: {}", containerId); + } catch (Exception e) { + log.warn( + "[sandbox-docker] Failed to remove container {}: {}", + containerId, + e.getMessage()); + } + } + + @Override + protected ExecResult doExec(String command, int timeoutSeconds) throws Exception { + String containerId = dockerState.getContainerId(); + String workspaceRoot = dockerState.getWorkspaceRoot(); + + List cmd = new ArrayList<>(); + cmd.add("docker"); + cmd.add("exec"); + cmd.add("-w"); + cmd.add(workspaceRoot); + cmd.add(containerId); + cmd.add("sh"); + cmd.add("-c"); + cmd.add(command); + + ProcessBuilder pb = new ProcessBuilder(cmd); + Process process = pb.start(); + + ExecutorService drainer = + Executors.newFixedThreadPool( + 2, + r -> { + Thread t = + new Thread( + r, + "sandbox-docker-drain-" + dockerState.getSessionId()); + t.setDaemon(true); + return t; + }); + + Future stdoutFuture = + drainer.submit(() -> readStream(process.getInputStream(), OUTPUT_TRUNCATE_BYTES)); + Future stderrFuture = + drainer.submit(() -> readStream(process.getErrorStream(), OUTPUT_TRUNCATE_BYTES)); + drainer.shutdown(); + + boolean exited = process.waitFor(timeoutSeconds, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + drainer.shutdownNow(); + throw new SandboxException.ExecTimeoutException(command, timeoutSeconds); + } + + String stdout = stdoutFuture.get(); + String stderr = stderrFuture.get(); + int exitCode = process.exitValue(); + + boolean truncated = + stdout.length() >= OUTPUT_TRUNCATE_BYTES + || stderr.length() >= OUTPUT_TRUNCATE_BYTES; + ExecResult result = new ExecResult(exitCode, stdout, stderr, truncated); + if (!result.ok()) { + throw new SandboxException.ExecException(exitCode, stdout, stderr); + } + return result; + } + + @Override + protected InputStream doPersistWorkspace() throws Exception { + String containerId = dockerState.getContainerId(); + String workspaceRoot = dockerState.getWorkspaceRoot(); + + ProcessBuilder pb = + new ProcessBuilder( + "docker", "exec", containerId, "tar", "-cf", "-", "-C", workspaceRoot, "."); + + Process process = pb.start(); + + ExecutorService stderrDrainer = + Executors.newSingleThreadExecutor( + r -> { + Thread t = + new Thread( + r, + "sandbox-docker-tar-stderr-" + + dockerState.getSessionId()); + t.setDaemon(true); + return t; + }); + Future stderrFuture = + stderrDrainer.submit( + () -> readStream(process.getErrorStream(), OUTPUT_TRUNCATE_BYTES)); + stderrDrainer.shutdown(); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + process.getInputStream().transferTo(buffer); + + boolean exited = process.waitFor(TAR_TIMEOUT_SECONDS, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_WRITE_ERROR, + "docker tar command timed out for container: " + containerId); + } + + int exitCode = process.exitValue(); + if (exitCode != 0) { + String stderr = stderrFuture.get(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_WRITE_ERROR, + "docker tar command failed (exit=" + exitCode + "): " + stderr); + } + + return new ByteArrayInputStream(buffer.toByteArray()); + } + + @Override + protected void doHydrateWorkspace(InputStream archive) throws Exception { + String containerId = dockerState.getContainerId(); + String workspaceRoot = dockerState.getWorkspaceRoot(); + + // Ensure the workspace directory exists inside the container + runDockerCliBlocking(30, "docker", "exec", containerId, "mkdir", "-p", workspaceRoot); + + // Pipe the tar archive into the container via docker exec stdin + ProcessBuilder pb = + new ProcessBuilder( + "docker", + "exec", + "-i", + containerId, + "tar", + "-xf", + "-", + "-C", + workspaceRoot); + + Process process = pb.start(); + + ExecutorService ioExecutor = + Executors.newFixedThreadPool( + 2, + r -> { + Thread t = + new Thread( + r, + "sandbox-docker-hydrate-" + dockerState.getSessionId()); + t.setDaemon(true); + return t; + }); + + // Write archive to process stdin in background + Future writeFuture = + ioExecutor.submit( + () -> { + try (OutputStream stdin = process.getOutputStream()) { + archive.transferTo(stdin); + } catch (IOException e) { + log.warn( + "[sandbox-docker] Error writing archive to container stdin", + e); + } + return null; + }); + + Future stderrFuture = + ioExecutor.submit( + () -> readStream(process.getErrorStream(), OUTPUT_TRUNCATE_BYTES)); + ioExecutor.shutdown(); + + writeFuture.get(TAR_TIMEOUT_SECONDS, TimeUnit.SECONDS); + + boolean exited = process.waitFor(TAR_TIMEOUT_SECONDS, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + ioExecutor.shutdownNow(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "docker tar extract timed out for container: " + containerId); + } + + int exitCode = process.exitValue(); + if (exitCode != 0) { + String stderr = stderrFuture.get(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_ARCHIVE_READ_ERROR, + "docker tar extract failed (exit=" + exitCode + "): " + stderr); + } + } + + @Override + protected void doSetupWorkspace() throws Exception { + String containerId = dockerState.getContainerId(); + String workspaceRoot = dockerState.getWorkspaceRoot(); + runDockerCliBlocking(30, "docker", "exec", containerId, "mkdir", "-p", workspaceRoot); + } + + @Override + protected void doDestroyWorkspace() throws Exception { + String containerId = dockerState.getContainerId(); + String workspaceRoot = dockerState.getWorkspaceRoot(); + if (containerId != null && !containerId.isBlank()) { + try { + runDockerCliBlocking(30, "docker", "exec", containerId, "rm", "-rf", workspaceRoot); + } catch (Exception e) { + log.warn( + "[sandbox-docker] Failed to destroy workspace {} in container {}: {}", + workspaceRoot, + containerId, + e.getMessage()); + } + } + } + + @Override + protected String getWorkspaceRoot() { + return dockerState.getWorkspaceRoot(); + } + + // ----------------------------------------------------------------- + // Container management + // ----------------------------------------------------------------- + + /** + * Ensures the Docker container is running. + * + *

Priority: + *

    + *
  1. If container exists and is running — reuse it.
  2. + *
  3. If container exists and is stopped — restart it.
  4. + *
  5. If container is missing or unknown — create a new container, reset + * {@code workspaceRootReady} to force full workspace reinitialisation.
  6. + *
+ */ + private void doEnsureContainerRunning() throws Exception { + String containerId = dockerState.getContainerId(); + + if (containerId != null && !containerId.isBlank()) { + ContainerState state = inspectContainerState(containerId); + if (state == ContainerState.RUNNING) { + log.debug("[sandbox-docker] Container already running: {}", containerId); + return; + } else if (state == ContainerState.STOPPED) { + log.debug("[sandbox-docker] Restarting stopped container: {}", containerId); + runDockerCliBlocking( + CONTAINER_START_TIMEOUT_SECONDS, "docker", "start", containerId); + return; + } + // Container not found — fall through to create a new one + log.warn("[sandbox-docker] Container {} not found, creating a new one", containerId); + dockerState.setWorkspaceRootReady(false); + } + + createAndStartContainer(); + } + + private void createAndStartContainer() throws Exception { + String containerName = "agentscope-sandbox-" + dockerState.getSessionId(); + dockerState.setContainerName(containerName); + + List cmd = buildDockerRunCommand(containerName); + + log.debug( + "[sandbox-docker] Creating container: image={}, name={}", + dockerState.getImage(), + containerName); + + ProcessBuilder pb = new ProcessBuilder(cmd); + Process process = pb.start(); + + ExecutorService drainer = + Executors.newFixedThreadPool( + 2, + r -> { + Thread t = + new Thread( + r, + "sandbox-docker-create-" + dockerState.getSessionId()); + t.setDaemon(true); + return t; + }); + + Future stdoutFuture = + drainer.submit(() -> readStream(process.getInputStream(), 64 * 1024)); + Future stderrFuture = + drainer.submit(() -> readStream(process.getErrorStream(), 64 * 1024)); + drainer.shutdown(); + + boolean exited = process.waitFor(CONTAINER_START_TIMEOUT_SECONDS, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + drainer.shutdownNow(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_START_ERROR, + "docker run timed out for image: " + dockerState.getImage()); + } + + int exitCode = process.exitValue(); + String stdout = stdoutFuture.get().trim(); + String stderr = stderrFuture.get().trim(); + + if (exitCode != 0) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_START_ERROR, + "docker run failed (exit=" + exitCode + "): " + stderr); + } + + // stdout is the new container ID + String newContainerId = stdout.isBlank() ? null : stdout; + if (newContainerId == null) { + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_START_ERROR, + "docker run produced no container ID. stderr: " + stderr); + } + + dockerState.setContainerId(newContainerId); + log.info( + "[sandbox-docker] Container started: id={}, name={}", + newContainerId, + containerName); + } + + private List buildDockerRunCommand(String containerName) { + List cmd = new ArrayList<>(); + cmd.add("docker"); + cmd.add("run"); + cmd.add("-d"); + cmd.add("--name"); + cmd.add(containerName); + + // Environment variables from manifest + Map manifestEnv = + getState().getWorkspaceSpec() != null + ? getState().getWorkspaceSpec().getEnvironment() + : null; + if (manifestEnv != null) { + for (Map.Entry entry : manifestEnv.entrySet()) { + cmd.add("-e"); + cmd.add(entry.getKey() + "=" + entry.getValue()); + } + } + + // Memory limit + if (dockerState.getMemorySizeBytes() != null) { + cmd.add("--memory=" + dockerState.getMemorySizeBytes()); + } + + // CPU limit + if (dockerState.getCpuCount() != null) { + cmd.add("--cpus=" + dockerState.getCpuCount()); + } + + // Exposed ports (host:container mapping using same port number) + if (dockerState.getExposedPorts() != null) { + for (int port : dockerState.getExposedPorts()) { + cmd.add("-p"); + cmd.add(port + ":" + port); + } + } + + cmd.add(dockerState.getImage()); + // Keep the container alive with an idle shell loop + cmd.add("sh"); + cmd.add("-c"); + cmd.add("while :; do sleep 3600; done"); + + return cmd; + } + + /** + * Inspects a container and returns whether it is running, stopped, or unknown. + */ + private ContainerState inspectContainerState(String containerId) { + try { + ProcessBuilder pb = + new ProcessBuilder( + "docker", "inspect", "-f", "{{.State.Running}}", containerId); + Process process = pb.start(); + + Future stdoutFuture; + ExecutorService drainer = + Executors.newSingleThreadExecutor( + r -> { + Thread t = new Thread(r, "sandbox-docker-inspect"); + t.setDaemon(true); + return t; + }); + stdoutFuture = drainer.submit(() -> readStream(process.getInputStream(), 1024)); + drainer.shutdown(); + + boolean exited = process.waitFor(10, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + return ContainerState.UNKNOWN; + } + if (process.exitValue() != 0) { + return ContainerState.UNKNOWN; + } + String output = stdoutFuture.get().trim(); + return "true".equals(output) ? ContainerState.RUNNING : ContainerState.STOPPED; + } catch (Exception e) { + log.debug( + "[sandbox-docker] Failed to inspect container {}: {}", + containerId, + e.getMessage()); + return ContainerState.UNKNOWN; + } + } + + /** + * Runs a Docker CLI command, blocking until completion. + * + * @param timeoutSeconds maximum time to wait + * @param command command and arguments + * @throws SandboxException.SandboxRuntimeException if the command fails or times out + */ + private void runDockerCliBlocking(int timeoutSeconds, String... command) throws Exception { + ProcessBuilder pb = new ProcessBuilder(command); + Process process = pb.start(); + + ExecutorService drainer = + Executors.newFixedThreadPool( + 2, + r -> { + Thread t = new Thread(r, "sandbox-docker-cli"); + t.setDaemon(true); + return t; + }); + Future stderrFuture = + drainer.submit(() -> readStream(process.getErrorStream(), 64 * 1024)); + drainer.submit(() -> readStream(process.getInputStream(), 64 * 1024)); + drainer.shutdown(); + + boolean exited = process.waitFor(timeoutSeconds, TimeUnit.SECONDS); + if (!exited) { + process.destroyForcibly(); + drainer.shutdownNow(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_START_ERROR, + "docker command timed out: " + command[0] + " " + command[1]); + } + int exitCode = process.exitValue(); + if (exitCode != 0) { + String stderr = stderrFuture.get(); + throw new SandboxException.SandboxRuntimeException( + SandboxErrorCode.WORKSPACE_START_ERROR, + "docker command failed (exit=" + exitCode + "): " + stderr); + } + } + + /** + * Reads an InputStream into a String, truncating at {@code maxBytes}. + */ + private static String readStream(InputStream in, int maxBytes) { + try { + byte[] buf = new byte[maxBytes]; + int total = 0; + int read; + while (total < maxBytes && (read = in.read(buf, total, maxBytes - total)) != -1) { + total += read; + } + // Drain remaining bytes to prevent blocking + if (total == maxBytes) { + //noinspection ResultOfMethodCallIgnored + in.skip(Long.MAX_VALUE); + } + return new String(buf, 0, total, StandardCharsets.UTF_8); + } catch (IOException e) { + return ""; + } + } + + /** Container state as determined by {@code docker inspect}. */ + private enum ContainerState { + RUNNING, + STOPPED, + UNKNOWN + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java new file mode 100644 index 000000000..33f9175c2 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java @@ -0,0 +1,130 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.impl.docker; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxException; +import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link SandboxClient} implementation for the Docker sandbox backend. + * + *

Creates and manages Docker containers via the {@code docker} CLI. The Docker daemon must + * be accessible from the host's {@code PATH}. + */ +public class DockerSandboxClient implements SandboxClient { + + private static final Logger log = LoggerFactory.getLogger(DockerSandboxClient.class); + + private final ObjectMapper objectMapper; + + public DockerSandboxClient() { + this.objectMapper = + new ObjectMapper() + .findAndRegisterModules() + .activateDefaultTyping( + com.fasterxml.jackson.databind.jsontype + .BasicPolymorphicTypeValidator.builder() + .allowIfSubType("io.agentscope.harness") + .build(), + ObjectMapper.DefaultTyping.NON_FINAL); + } + + public DockerSandboxClient(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public Sandbox create( + WorkspaceSpec workspaceSpec, + SandboxSnapshotSpec snapshotSpec, + DockerSandboxClientOptions options) { + String sessionId = UUID.randomUUID().toString(); + + String image = + options != null && options.getImage() != null ? options.getImage() : "ubuntu:22.04"; + String workspaceRoot = + options != null && options.getWorkspaceRoot() != null + ? options.getWorkspaceRoot() + : "/workspace"; + + DockerSandboxState state = new DockerSandboxState(); + state.setSessionId(sessionId); + state.setWorkspaceSpec(workspaceSpec); + state.setImage(image); + state.setWorkspaceRoot(workspaceRoot); + state.setContainerOwned(true); + state.setWorkspaceRootReady(false); + + if (options != null) { + state.setMemorySizeBytes(options.getMemorySizeBytes()); + state.setCpuCount(options.getCpuCount()); + state.setExposedPorts(options.getExposedPorts()); + } + + if (snapshotSpec != null) { + state.setSnapshot(snapshotSpec.build(sessionId)); + } + + log.debug("[sandbox-docker] Creating new sandbox: id={}, image={}", sessionId, image); + return new DockerSandbox(state); + } + + @Override + public Sandbox resume(SandboxState state) { + if (!(state instanceof DockerSandboxState dockerState)) { + throw new IllegalArgumentException( + "Expected DockerSandboxState but got: " + state.getClass().getName()); + } + log.debug( + "[sandbox-docker] Resuming sandbox: id={}, containerId={}", + dockerState.getSessionId(), + dockerState.getContainerId()); + return new DockerSandbox(dockerState); + } + + @Override + public void delete(Sandbox sandbox) { + // No-op: cleanup is handled by DockerSandbox.shutdown() + } + + @Override + public String serializeState(SandboxState state) { + try { + return objectMapper.writeValueAsString(state); + } catch (Exception e) { + throw new SandboxException.SandboxConfigurationException( + "Failed to serialize Docker sandbox state", e); + } + } + + @Override + public SandboxState deserializeState(String json) { + try { + return objectMapper.readValue(json, SandboxState.class); + } catch (Exception e) { + throw new SandboxException.SandboxConfigurationException( + "Failed to deserialize Docker sandbox state", e); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java new file mode 100644 index 000000000..b3e1c6cba --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java @@ -0,0 +1,228 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.impl.docker; + +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Configuration options for the Docker sandbox client. + * + *

Describes the Docker container configuration used when creating or resuming + * a {@link io.agentscope.harness.agent.sandbox.impl.docker.DockerSandbox}. The Docker CLI must be + * available on the host + * system's {@code PATH}. + */ +public class DockerSandboxClientOptions extends SandboxClientOptions { + + /** Docker image to run. Defaults to {@code ubuntu:22.04}. */ + private String image = "ubuntu:22.04"; + + /** Workspace root path inside the container. Defaults to {@code /workspace}. */ + private String workspaceRoot = "/workspace"; + + /** Environment variables to inject into the container. */ + private Map environment = new LinkedHashMap<>(); + + /** Optional memory limit in bytes (e.g. {@code 512 * 1024 * 1024L} for 512 MB). */ + private Long memorySizeBytes; + + /** Optional CPU count limit (e.g. {@code 2L} for two CPUs). */ + private Long cpuCount; + + /** Host ports to expose from the container ({@code hostPort:containerPort} mapping). */ + private int[] exposedPorts = {}; + + @Override + public String getType() { + return "docker"; + } + + /** + * Creates a {@link DockerSandboxClient} for these options. + * + * @return new Docker sandbox client + */ + @Override + public SandboxClient createClient() { + return new DockerSandboxClient(); + } + + /** + * Returns the Docker image name. + * + * @return Docker image + */ + public String getImage() { + return image; + } + + /** + * Sets the Docker image name. + * + * @param image Docker image (e.g. {@code python:3.12-slim}) + * @return this options instance + */ + public DockerSandboxClientOptions image(String image) { + this.image = image; + return this; + } + + /** + * Sets the Docker image name. + * + * @param image Docker image + */ + public void setImage(String image) { + this.image = image; + } + + /** + * Returns the workspace root path inside the container. + * + * @return workspace root + */ + public String getWorkspaceRoot() { + return workspaceRoot; + } + + /** + * Sets the workspace root path inside the container. + * + * @param workspaceRoot absolute path inside the container + * @return this options instance + */ + public DockerSandboxClientOptions workspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + return this; + } + + /** + * Sets the workspace root path inside the container. + * + * @param workspaceRoot absolute path inside the container + */ + public void setWorkspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } + + /** + * Returns the container environment variables. + * + * @return environment variable map + */ + public Map getEnvironment() { + return environment; + } + + /** + * Sets the container environment variables. + * + * @param environment key-value pairs + */ + public void setEnvironment(Map environment) { + this.environment = environment != null ? environment : new LinkedHashMap<>(); + } + + /** + * Returns the optional memory limit in bytes. + * + * @return memory limit or {@code null} if not set + */ + public Long getMemorySizeBytes() { + return memorySizeBytes; + } + + /** + * Sets the memory limit in bytes. + * + * @param memorySizeBytes memory limit (e.g. {@code 512 * 1024 * 1024L}) + * @return this options instance + */ + public DockerSandboxClientOptions memorySizeBytes(Long memorySizeBytes) { + this.memorySizeBytes = memorySizeBytes; + return this; + } + + /** + * Sets the memory limit in bytes. + * + * @param memorySizeBytes memory limit in bytes + */ + public void setMemorySizeBytes(Long memorySizeBytes) { + this.memorySizeBytes = memorySizeBytes; + } + + /** + * Returns the optional CPU count limit. + * + * @return CPU count or {@code null} if not set + */ + public Long getCpuCount() { + return cpuCount; + } + + /** + * Sets the CPU count limit. + * + * @param cpuCount number of CPUs (e.g. {@code 2L}) + * @return this options instance + */ + public DockerSandboxClientOptions cpuCount(Long cpuCount) { + this.cpuCount = cpuCount; + return this; + } + + /** + * Sets the CPU count limit. + * + * @param cpuCount number of CPUs + */ + public void setCpuCount(Long cpuCount) { + this.cpuCount = cpuCount; + } + + /** + * Returns the host ports to expose. + * + * @return exposed ports array + */ + public int[] getExposedPorts() { + return exposedPorts; + } + + /** + * Sets the host ports to expose from the container. + * + * @param exposedPorts port numbers + * @return this options instance + */ + public DockerSandboxClientOptions exposedPorts(int... exposedPorts) { + this.exposedPorts = exposedPorts; + return this; + } + + /** + * Sets the host ports to expose from the container. + * + * @param exposedPorts port numbers + */ + public void setExposedPorts(int[] exposedPorts) { + this.exposedPorts = exposedPorts != null ? exposedPorts : new int[0]; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java new file mode 100644 index 000000000..4349692be --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java @@ -0,0 +1,200 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.impl.docker; + +import io.agentscope.harness.agent.sandbox.SandboxState; + +/** + * Serializable state for a Docker-backed {@link io.agentscope.harness.agent.sandbox.Sandbox}. + * + *

Persisted after each call to enable transparent container resume. If the container + * identified by {@link #containerId} is still alive on resume, the sandbox reconnects. If + * it is stopped, it is restarted. If it has been removed, a new container is created and the + * workspace is restored from snapshot. + */ +public class DockerSandboxState extends SandboxState { + + /** Docker container ID of the backing container. */ + private String containerId; + + /** Human-readable container name (e.g. {@code agentscope-sandbox-}). */ + private String containerName; + + /** Docker image used to create this container. */ + private String image; + + /** Workspace root path inside the container. */ + private String workspaceRoot; + + /** + * Whether the SDK owns the container lifecycle (create/stop/remove). + * When {@code false}, the container was injected by the developer and will not be removed. + */ + private boolean containerOwned = true; + + /** Optional memory limit in bytes stored for container recreation on resume. */ + private Long memorySizeBytes; + + /** Optional CPU count limit stored for container recreation on resume. */ + private Long cpuCount; + + /** Exposed port numbers stored for container recreation on resume. */ + private int[] exposedPorts = {}; + + /** + * Returns the Docker container ID. + * + * @return container ID, or {@code null} if the container has not been created yet + */ + public String getContainerId() { + return containerId; + } + + /** + * Sets the Docker container ID. + * + * @param containerId Docker container ID + */ + public void setContainerId(String containerId) { + this.containerId = containerId; + } + + /** + * Returns the container name. + * + * @return container name + */ + public String getContainerName() { + return containerName; + } + + /** + * Sets the container name. + * + * @param containerName container name + */ + public void setContainerName(String containerName) { + this.containerName = containerName; + } + + /** + * Returns the Docker image used for this container. + * + * @return Docker image + */ + public String getImage() { + return image; + } + + /** + * Sets the Docker image. + * + * @param image Docker image + */ + public void setImage(String image) { + this.image = image; + } + + /** + * Returns the workspace root path inside the container. + * + * @return workspace root path + */ + public String getWorkspaceRoot() { + return workspaceRoot; + } + + /** + * Sets the workspace root path inside the container. + * + * @param workspaceRoot absolute path inside the container + */ + public void setWorkspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } + + /** + * Returns whether the SDK owns the container lifecycle. + * + * @return {@code true} if the SDK manages container creation and removal + */ + public boolean isContainerOwned() { + return containerOwned; + } + + /** + * Sets whether the SDK owns the container lifecycle. + * + * @param containerOwned {@code true} if the SDK should stop and remove the container on shutdown + */ + public void setContainerOwned(boolean containerOwned) { + this.containerOwned = containerOwned; + } + + /** + * Returns the optional memory limit in bytes. + * + * @return memory limit or {@code null} + */ + public Long getMemorySizeBytes() { + return memorySizeBytes; + } + + /** + * Sets the memory limit in bytes. + * + * @param memorySizeBytes memory limit + */ + public void setMemorySizeBytes(Long memorySizeBytes) { + this.memorySizeBytes = memorySizeBytes; + } + + /** + * Returns the optional CPU count limit. + * + * @return CPU count or {@code null} + */ + public Long getCpuCount() { + return cpuCount; + } + + /** + * Sets the CPU count limit. + * + * @param cpuCount number of CPUs + */ + public void setCpuCount(Long cpuCount) { + this.cpuCount = cpuCount; + } + + /** + * Returns the exposed port numbers. + * + * @return port numbers array + */ + public int[] getExposedPorts() { + return exposedPorts; + } + + /** + * Sets the exposed port numbers. + * + * @param exposedPorts port numbers + */ + public void setExposedPorts(int[] exposedPorts) { + this.exposedPorts = exposedPorts != null ? exposedPorts : new int[0]; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/DirEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/DirEntry.java new file mode 100644 index 000000000..ac9251233 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/DirEntry.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Layout entry that creates a directory, optionally with nested child entries. + * + *

Child entries are a map of filename to {@link WorkspaceEntry} and may themselves be + * nested {@code DirEntry} instances, enabling recursive tree-like workspace structures. + */ +public class DirEntry extends WorkspaceEntry { + + private Map children = new LinkedHashMap<>(); + + /** Creates an empty directory entry. */ + public DirEntry() {} + + /** + * Creates a directory entry with the given children. + * + * @param children map of child name to child entry + */ + public DirEntry(Map children) { + this.children = new LinkedHashMap<>(children); + } + + /** + * Returns the child entries in this directory. + * + * @return mutable map of child name to child entry + */ + public Map getChildren() { + return children; + } + + /** + * Sets the child entries for this directory. + * + * @param children map of child name to child entry + */ + public void setChildren(Map children) { + this.children = children != null ? children : new LinkedHashMap<>(); + } + + /** + * Adds a child entry to this directory. + * + * @param name child filename + * @param entry child entry + * @return this instance for chaining + */ + public DirEntry child(String name, WorkspaceEntry entry) { + this.children.put(name, entry); + return this; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/FileEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/FileEntry.java new file mode 100644 index 000000000..9fa050eab --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/FileEntry.java @@ -0,0 +1,84 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +/** + * Layout entry that creates a file with inline text content. + */ +public class FileEntry extends WorkspaceEntry { + + private String content = ""; + private String encoding = "UTF-8"; + + /** Creates an empty file entry. */ + public FileEntry() {} + + /** + * Creates a file entry with the given content. + * + * @param content the file content as a string + */ + public FileEntry(String content) { + this.content = content; + } + + /** + * Creates a file entry with the given content and encoding. + * + * @param content the file content as a string + * @param encoding the character encoding to use when writing the file + */ + public FileEntry(String content, String encoding) { + this.content = content; + this.encoding = encoding; + } + + /** + * Returns the file content. + * + * @return file content string + */ + public String getContent() { + return content; + } + + /** + * Sets the file content. + * + * @param content the file content string + */ + public void setContent(String content) { + this.content = content; + } + + /** + * Returns the character encoding used to write this file. + * + * @return encoding name (e.g. "UTF-8") + */ + public String getEncoding() { + return encoding; + } + + /** + * Sets the character encoding used to write this file. + * + * @param encoding encoding name (e.g. "UTF-8") + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/GitRepoEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/GitRepoEntry.java new file mode 100644 index 000000000..d02344208 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/GitRepoEntry.java @@ -0,0 +1,79 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +/** + * Layout entry that clones a Git repository into the sandbox workspace. + * + *

The repository is cloned from {@code url} at the given {@code ref} + * (branch, tag, or commit SHA). Full git-clone logic is a Phase 2 feature; + * this class serves as the type skeleton for JSON serialization. + */ +public class GitRepoEntry extends WorkspaceEntry { + + private String url; + private String ref = "HEAD"; + + /** Creates an empty git repo entry. */ + public GitRepoEntry() {} + + /** + * Creates a git repo entry with the given URL and ref. + * + * @param url the repository clone URL + * @param ref the branch, tag, or commit SHA to check out + */ + public GitRepoEntry(String url, String ref) { + this.url = url; + this.ref = ref; + } + + /** + * Returns the repository clone URL. + * + * @return clone URL + */ + public String getUrl() { + return url; + } + + /** + * Sets the repository clone URL. + * + * @param url clone URL + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Returns the Git ref (branch, tag, or commit SHA) to check out. + * + * @return git ref + */ + public String getRef() { + return ref; + } + + /** + * Sets the Git ref. + * + * @param ref branch, tag, or commit SHA + */ + public void setRef(String ref) { + this.ref = ref; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalDirEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalDirEntry.java new file mode 100644 index 000000000..99a7fc65e --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalDirEntry.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +/** + * Layout entry that recursively copies a directory from the host filesystem into the sandbox + * workspace. + * + *

The {@code sourcePath} is an absolute path to a directory on the host machine. All files + * within that directory are copied recursively to the destination path in the workspace. + */ +public class LocalDirEntry extends WorkspaceEntry { + + private String sourcePath; + + /** Creates an empty local directory entry. */ + public LocalDirEntry() {} + + /** + * Creates a local directory entry with the given host source path. + * + * @param sourcePath absolute path to a directory on the host filesystem + */ + public LocalDirEntry(String sourcePath) { + this.sourcePath = sourcePath; + } + + /** + * Returns the host-side source directory path. + * + * @return absolute host directory path as a string + */ + public String getSourcePath() { + return sourcePath; + } + + /** + * Sets the host-side source directory path. + * + * @param sourcePath absolute host directory path as a string + */ + public void setSourcePath(String sourcePath) { + this.sourcePath = sourcePath; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalFileEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalFileEntry.java new file mode 100644 index 000000000..9c4b5f48b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/LocalFileEntry.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +/** + * Layout entry that copies a single file from the host filesystem into the sandbox workspace. + * + *

The {@code sourcePath} is an absolute path on the host machine. It is stored as a string + * to ensure safe JSON serialization across platforms. + */ +public class LocalFileEntry extends WorkspaceEntry { + + private String sourcePath; + + /** Creates an empty local file entry. */ + public LocalFileEntry() {} + + /** + * Creates a local file entry with the given host source path. + * + * @param sourcePath absolute path on the host filesystem + */ + public LocalFileEntry(String sourcePath) { + this.sourcePath = sourcePath; + } + + /** + * Returns the host-side source path. + * + * @return absolute host path as a string + */ + public String getSourcePath() { + return sourcePath; + } + + /** + * Sets the host-side source path. + * + * @param sourcePath absolute host path as a string + */ + public void setSourcePath(String sourcePath) { + this.sourcePath = sourcePath; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceEntry.java new file mode 100644 index 000000000..de0ed4037 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceEntry.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * Base class for entries in a {@link io.agentscope.harness.agent.sandbox.WorkspaceSpec}. + * + *

Each entry describes a single file or directory that should be present in the sandbox + * workspace at startup. Entries can be materialized from inline content, local host files, or + * remote sources. + * + *

When {@code ephemeral} is {@code true}, this entry is always re-applied on every sandbox + * start, even when a snapshot exists. Non-ephemeral entries are persisted inside the snapshot + * and restored with the workspace. + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = FileEntry.class, name = "file"), + @JsonSubTypes.Type(value = DirEntry.class, name = "dir"), + @JsonSubTypes.Type(value = LocalFileEntry.class, name = "local_file"), + @JsonSubTypes.Type(value = LocalDirEntry.class, name = "local_dir"), + @JsonSubTypes.Type(value = GitRepoEntry.class, name = "git_repo"), + @JsonSubTypes.Type(value = WorkspaceProjectionEntry.class, name = "workspace_projection"), +}) +public abstract class WorkspaceEntry { + + private boolean ephemeral = false; + + /** + * Returns whether this entry is ephemeral. + * + *

Ephemeral entries are always re-applied on session resume regardless of whether a + * snapshot exists. They are suitable for dynamic configuration that should not be snapshotted. + * + * @return true if this entry is ephemeral + */ + public boolean isEphemeral() { + return ephemeral; + } + + /** + * Sets whether this entry is ephemeral. + * + * @param ephemeral true to mark as ephemeral + */ + public void setEphemeral(boolean ephemeral) { + this.ephemeral = ephemeral; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceProjectionEntry.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceProjectionEntry.java new file mode 100644 index 000000000..a591872d7 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/layout/WorkspaceProjectionEntry.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.layout; + +import java.util.ArrayList; +import java.util.List; + +/** + * Layout entry that projects selected files/directories from host workspace into sandbox + * workspace when the {@link io.agentscope.harness.agent.sandbox.Sandbox} starts. + * + *

This entry is sandbox-specific and is ignored by {@link + * io.agentscope.harness.agent.sandbox.WorkspaceSpecApplier}'s regular file materialization + * logic. Instead, projection is applied inside {@link + * io.agentscope.harness.agent.sandbox.Sandbox#start()} via archive hydration. + */ +public class WorkspaceProjectionEntry extends WorkspaceEntry { + + private String sourceRoot; + private List includeRoots = new ArrayList<>(); + + /** + * Absolute host-side workspace root used as source for projection. + */ + public String getSourceRoot() { + return sourceRoot; + } + + public void setSourceRoot(String sourceRoot) { + this.sourceRoot = sourceRoot; + } + + /** + * Relative include roots under {@link #getSourceRoot()}. + */ + public List getIncludeRoots() { + return includeRoots; + } + + public void setIncludeRoots(List includeRoots) { + this.includeRoots = + includeRoots != null ? new ArrayList<>(includeRoots) : new ArrayList<>(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSandboxSnapshot.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSandboxSnapshot.java new file mode 100644 index 000000000..b397a9ac3 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSandboxSnapshot.java @@ -0,0 +1,148 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import io.agentscope.harness.agent.sandbox.SandboxErrorCode; +import io.agentscope.harness.agent.sandbox.SandboxException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.util.UUID; + +/** + * Snapshot that persists workspace archives as tar files on the local filesystem. + * + *

Archives are written atomically: the data is first written to a temporary file + * (prefixed with {@code .}) in the same directory, then moved to the final path using + * {@link StandardCopyOption#ATOMIC_MOVE}. This ensures the snapshot is either fully + * written or not present — never partially written. + * + *

Security: {@code id} must be a single path segment with no {@code /} or {@code ..} + * characters to prevent path traversal attacks. + */ +public class LocalSandboxSnapshot implements SandboxSnapshot { + + private final String basePath; + private final String id; + + /** + * Creates a local snapshot. + * + * @param basePath directory where snapshot tar files are stored + * @param id unique identifier for this snapshot (must be a safe single path segment) + * @throws IllegalArgumentException if {@code id} contains unsafe characters + */ + public LocalSandboxSnapshot(String basePath, String id) { + validateId(id); + this.basePath = basePath; + this.id = id; + } + + /** + * {@inheritDoc} + * + *

Writes the archive atomically to {@code {basePath}/{id}.tar}. + */ + @Override + public void persist(InputStream workspaceArchive) throws Exception { + Path targetPath = Path.of(basePath).resolve(id + ".tar"); + Path tmpPath = targetPath.resolveSibling("." + id + "." + UUID.randomUUID() + ".tmp"); + + try { + Files.createDirectories(targetPath.getParent()); + try (OutputStream out = + Files.newOutputStream( + tmpPath, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING)) { + workspaceArchive.transferTo(out); + } + Files.move( + tmpPath, + targetPath, + StandardCopyOption.ATOMIC_MOVE, + StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) { + try { + Files.deleteIfExists(tmpPath); + } catch (Exception ignored) { + // Best-effort cleanup of the temp file + } + throw new SandboxException.SnapshotException(id, "Failed to persist snapshot", e); + } + } + + /** + * {@inheritDoc} + * + *

Opens the snapshot tar file at {@code {basePath}/{id}.tar} for reading. + */ + @Override + public InputStream restore() throws Exception { + Path path = Path.of(basePath).resolve(id + ".tar"); + if (!Files.exists(path)) { + throw new SandboxException.SnapshotException(id); + } + try { + return Files.newInputStream(path); + } catch (Exception e) { + throw new SandboxException.SnapshotException(id, "Failed to read snapshot", e); + } + } + + /** + * {@inheritDoc} + * + * @return {@code true} if the snapshot tar file exists + */ + @Override + public boolean isRestorable() { + return Files.exists(Path.of(basePath).resolve(id + ".tar")); + } + + @Override + public String getId() { + return id; + } + + @Override + public String getType() { + return "local"; + } + + /** + * Returns the base directory where snapshot tar files are stored. + * + * @return base path string + */ + public String getBasePath() { + return basePath; + } + + private static void validateId(String id) { + if (id == null || id.isBlank()) { + throw new IllegalArgumentException("Snapshot id must not be null or blank"); + } + if (id.contains("/") || id.contains("\\") || id.contains("..") || id.contains("\0")) { + throw new SandboxException( + SandboxErrorCode.INVALID_MANIFEST_PATH, + "Snapshot id contains unsafe characters: " + id); + } + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSnapshotSpec.java new file mode 100644 index 000000000..84c13ccb1 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/LocalSnapshotSpec.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import java.nio.file.Path; + +/** + * Snapshot spec that creates {@link LocalSandboxSnapshot} instances stored in a local directory. + * + *

Each session gets its own snapshot file at {@code {basePath}/{sessionId}.tar}. + */ +public class LocalSnapshotSpec implements SandboxSnapshotSpec { + + private final String basePath; + + /** + * Creates a local snapshot spec. + * + * @param basePath directory where snapshot tar files will be stored + */ + public LocalSnapshotSpec(Path basePath) { + this.basePath = basePath.toString(); + } + + /** + * Creates a local snapshot spec. + * + * @param basePath directory path string where snapshot tar files will be stored + */ + public LocalSnapshotSpec(String basePath) { + this.basePath = basePath; + } + + /** + * {@inheritDoc} + * + * @return a new {@link LocalSandboxSnapshot} storing at {@code {basePath}/{snapshotId}.tar} + */ + @Override + public SandboxSnapshot build(String snapshotId) { + return new LocalSandboxSnapshot(basePath, snapshotId); + } + + /** + * Returns the base directory used for snapshot files. + * + * @return base path string + */ + public String getBasePath() { + return basePath; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSandboxSnapshot.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSandboxSnapshot.java new file mode 100644 index 000000000..1a636225d --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSandboxSnapshot.java @@ -0,0 +1,89 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * No-op snapshot that does not persist anything. + * + *

When using {@code NoopSandboxSnapshot}, workspace state is NOT preserved between + * session stops. Each time a session is started fresh, the full manifest is applied + * (Branch D of the start logic). Use this when workspace durability is not required. + */ +public class NoopSandboxSnapshot implements SandboxSnapshot { + + private static final String ID = "noop"; + + /** Creates a noop snapshot. */ + public NoopSandboxSnapshot() {} + + /** + * {@inheritDoc} + * + *

Returns {@code false} — workspace archiving is skipped entirely when this + * snapshot is in use, so this method is never called in normal operation. + */ + @Override + public boolean isPersistenceEnabled() { + return false; + } + + /** + * {@inheritDoc} + * + *

This implementation discards the archive stream entirely. + */ + @Override + public void persist(InputStream workspaceArchive) throws Exception { + // Intentionally discard — no-op snapshot does not persist anything + if (workspaceArchive != null) { + workspaceArchive.transferTo(OutputStream.nullOutputStream()); + } + } + + /** + * {@inheritDoc} + * + *

Always throws {@link io.agentscope.harness.agent.sandbox.SandboxException.SnapshotException} + * since noop snapshots are never restorable. + */ + @Override + public InputStream restore() throws Exception { + throw new io.agentscope.harness.agent.sandbox.SandboxException.SnapshotException(ID); + } + + /** + * {@inheritDoc} + * + * @return always {@code false} + */ + @Override + public boolean isRestorable() { + return false; + } + + @Override + public String getId() { + return ID; + } + + @Override + public String getType() { + return "noop"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSnapshotSpec.java new file mode 100644 index 000000000..1f315267f --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/NoopSnapshotSpec.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +/** + * Snapshot spec that creates {@link NoopSandboxSnapshot} instances. + * + *

Using this spec means workspace state is never persisted between session stops. + * Every session start begins with a fresh workspace initialized from the full manifest. + */ +public class NoopSnapshotSpec implements SandboxSnapshotSpec { + + /** Creates a noop snapshot spec. */ + public NoopSnapshotSpec() {} + + /** + * {@inheritDoc} + * + * @return a new {@link NoopSandboxSnapshot} (ignores {@code snapshotId}) + */ + @Override + public SandboxSnapshot build(String snapshotId) { + return new NoopSandboxSnapshot(); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssRemoteSnapshotClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssRemoteSnapshotClient.java new file mode 100644 index 000000000..fbc393ab0 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssRemoteSnapshotClient.java @@ -0,0 +1,89 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.model.OSSObject; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.Objects; + +/** + * {@link RemoteSnapshotClient} backed by Alibaba Cloud OSS. + */ +public class OssRemoteSnapshotClient implements RemoteSnapshotClient { + + private final OSS ossClient; + private final String bucketName; + private final String keyPrefix; + + /** + * Creates an OSS-backed snapshot client. + * + * @param ossClient initialized OSS client + * @param bucketName bucket for snapshot objects + * @param keyPrefix object key prefix (optional, may be null/blank) + */ + public OssRemoteSnapshotClient(OSS ossClient, String bucketName, String keyPrefix) { + this.ossClient = Objects.requireNonNull(ossClient, "ossClient must not be null"); + if (bucketName == null || bucketName.isBlank()) { + throw new IllegalArgumentException("bucketName must not be blank"); + } + this.bucketName = bucketName; + this.keyPrefix = normalizePrefix(keyPrefix); + } + + @Override + public void upload(String snapshotId, InputStream data) throws Exception { + ossClient.putObject(bucketName, objectKey(snapshotId), data); + } + + @Override + public InputStream download(String snapshotId) throws Exception { + String key = objectKey(snapshotId); + if (!ossClient.doesObjectExist(bucketName, key)) { + throw new FileNotFoundException("Snapshot not found in OSS: " + key); + } + OSSObject object = ossClient.getObject(bucketName, key); + return object.getObjectContent(); + } + + @Override + public boolean exists(String snapshotId) throws Exception { + return ossClient.doesObjectExist(bucketName, objectKey(snapshotId)); + } + + private String objectKey(String snapshotId) { + if (snapshotId == null || snapshotId.isBlank()) { + throw new IllegalArgumentException("snapshotId must not be blank"); + } + return keyPrefix + snapshotId + ".tar"; + } + + private static String normalizePrefix(String prefix) { + if (prefix == null || prefix.isBlank()) { + return ""; + } + String p = prefix.replace('\\', '/'); + while (p.startsWith("/")) { + p = p.substring(1); + } + if (!p.isEmpty() && !p.endsWith("/")) { + p = p + "/"; + } + return p; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssSnapshotSpec.java new file mode 100644 index 000000000..b1bf1421b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/OssSnapshotSpec.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; + +/** + * Convenience {@link SandboxSnapshotSpec} for Alibaba Cloud OSS snapshot storage. + */ +public class OssSnapshotSpec extends RemoteSnapshotSpec { + + /** + * Creates an OSS snapshot spec from an existing OSS client. + * + * @param ossClient initialized OSS client + * @param bucketName target bucket + * @param keyPrefix key prefix (optional, may be null/blank) + */ + public OssSnapshotSpec(OSS ossClient, String bucketName, String keyPrefix) { + super(new OssRemoteSnapshotClient(ossClient, bucketName, keyPrefix)); + } + + /** + * Creates an OSS snapshot spec from endpoint/credential settings. + * + * @param endpoint OSS endpoint (e.g. oss-cn-hangzhou.aliyuncs.com) + * @param accessKeyId access key id + * @param accessKeySecret access key secret + * @param bucketName target bucket + * @param keyPrefix key prefix (optional, may be null/blank) + */ + public OssSnapshotSpec( + String endpoint, + String accessKeyId, + String accessKeySecret, + String bucketName, + String keyPrefix) { + this( + new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret), + bucketName, + keyPrefix); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java new file mode 100644 index 000000000..d3d596c5b --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java @@ -0,0 +1,89 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import redis.clients.jedis.UnifiedJedis; + +/** + * {@link RemoteSnapshotClient} backed by Redis binary values. + */ +public class RedisRemoteSnapshotClient implements RemoteSnapshotClient { + + private final UnifiedJedis jedis; + private final String keyPrefix; + private final Integer ttlSeconds; + + /** + * Creates a Redis-backed snapshot client. + * + * @param jedis initialized jedis client + * @param keyPrefix redis key prefix (optional) + * @param ttlSeconds optional TTL in seconds (null/<=0 means no TTL) + */ + public RedisRemoteSnapshotClient(UnifiedJedis jedis, String keyPrefix, Integer ttlSeconds) { + this.jedis = Objects.requireNonNull(jedis, "jedis must not be null"); + this.keyPrefix = normalizePrefix(keyPrefix); + this.ttlSeconds = ttlSeconds != null && ttlSeconds > 0 ? ttlSeconds : null; + } + + @Override + public void upload(String snapshotId, InputStream data) throws Exception { + byte[] key = redisKey(snapshotId); + byte[] value = data.readAllBytes(); + jedis.set(key, value); + if (ttlSeconds != null) { + jedis.expire(key, ttlSeconds); + } + } + + @Override + public InputStream download(String snapshotId) throws Exception { + byte[] data = jedis.get(redisKey(snapshotId)); + if (data == null) { + throw new FileNotFoundException( + "Snapshot not found in Redis: " + composeKey(snapshotId)); + } + return new ByteArrayInputStream(data); + } + + @Override + public boolean exists(String snapshotId) throws Exception { + return jedis.exists(redisKey(snapshotId)); + } + + private byte[] redisKey(String snapshotId) { + return composeKey(snapshotId).getBytes(StandardCharsets.UTF_8); + } + + private String composeKey(String snapshotId) { + if (snapshotId == null || snapshotId.isBlank()) { + throw new IllegalArgumentException("snapshotId must not be blank"); + } + return keyPrefix + snapshotId + ".tar"; + } + + private static String normalizePrefix(String prefix) { + if (prefix == null || prefix.isBlank()) { + return "agentscope:sandbox:snapshots:"; + } + return prefix.endsWith(":") ? prefix : prefix + ":"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java new file mode 100644 index 000000000..40d28f57f --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java @@ -0,0 +1,35 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import redis.clients.jedis.UnifiedJedis; + +/** + * Convenience {@link SandboxSnapshotSpec} for Redis-backed snapshot storage. + */ +public class RedisSnapshotSpec extends RemoteSnapshotSpec { + + /** + * Creates a Redis snapshot spec. + * + * @param jedis initialized jedis client + * @param keyPrefix redis key prefix (optional) + * @param ttlSeconds optional TTL in seconds (null/<=0 means no TTL) + */ + public RedisSnapshotSpec(UnifiedJedis jedis, String keyPrefix, Integer ttlSeconds) { + super(new RedisRemoteSnapshotClient(jedis, keyPrefix, ttlSeconds)); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSandboxSnapshot.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSandboxSnapshot.java new file mode 100644 index 000000000..bace902fc --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSandboxSnapshot.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import io.agentscope.harness.agent.sandbox.SandboxException; +import java.io.InputStream; + +/** + * Snapshot backed by a {@link RemoteSnapshotClient} (e.g. S3, OSS, GCS). + * + *

This class delegates all operations to the provided client. The client is responsible + * for authentication, retry logic, and network error handling. + * + *

Note: {@code RemoteSandboxSnapshot} is not directly serializable to JSON because + * {@link RemoteSnapshotClient} cannot be serialized. When persisting session state, + * only the {@code id} is needed — the client is re-injected from the builder at resume time. + */ +public class RemoteSandboxSnapshot implements SandboxSnapshot { + + private final RemoteSnapshotClient client; + private final String id; + + /** + * Creates a remote snapshot. + * + * @param client the remote storage client to delegate operations to + * @param id unique identifier for this snapshot + */ + public RemoteSandboxSnapshot(RemoteSnapshotClient client, String id) { + this.client = client; + this.id = id; + } + + /** + * {@inheritDoc} + * + *

Uploads the archive via {@link RemoteSnapshotClient#upload}. + */ + @Override + public void persist(InputStream workspaceArchive) throws Exception { + try { + client.upload(id, workspaceArchive); + } catch (Exception e) { + throw new SandboxException.SnapshotException(id, "Remote upload failed", e); + } + } + + /** + * {@inheritDoc} + * + *

Downloads the archive via {@link RemoteSnapshotClient#download}. + */ + @Override + public InputStream restore() throws Exception { + try { + return client.download(id); + } catch (Exception e) { + throw new SandboxException.SnapshotException(id, "Remote download failed", e); + } + } + + /** + * {@inheritDoc} + * + *

Checks existence via {@link RemoteSnapshotClient#exists}. + */ + @Override + public boolean isRestorable() throws Exception { + try { + return client.exists(id); + } catch (Exception e) { + throw new SandboxException.SnapshotException(id, "Remote exists check failed", e); + } + } + + @Override + public String getId() { + return id; + } + + @Override + public String getType() { + return "remote"; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClient.java new file mode 100644 index 000000000..dfd8bd277 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClient.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import java.io.InputStream; + +/** + * User-implemented interface for uploading and downloading snapshot archives to/from remote + * storage (e.g. S3, OSS, GCS, or a custom blob store). + * + *

Implement this interface and pass it to {@link RemoteSnapshotSpec} to enable + * remote snapshot storage. The implementation is responsible for authentication, + * retry logic, and connection management. + */ +public interface RemoteSnapshotClient { + + /** + * Uploads a snapshot archive to remote storage. + * + * @param snapshotId unique identifier for this snapshot + * @param data the workspace tar archive stream to upload + * @throws Exception if the upload fails + */ + void upload(String snapshotId, InputStream data) throws Exception; + + /** + * Downloads a snapshot archive from remote storage. + * + * @param snapshotId unique identifier for the snapshot to download + * @return an {@link InputStream} over the downloaded tar archive + * @throws Exception if the download fails or the snapshot does not exist + */ + InputStream download(String snapshotId) throws Exception; + + /** + * Checks whether a snapshot with the given ID exists in remote storage. + * + * @param snapshotId unique identifier to check + * @return {@code true} if the snapshot exists and can be downloaded + * @throws Exception if the check fails + */ + boolean exists(String snapshotId) throws Exception; +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotSpec.java new file mode 100644 index 000000000..d89f3a483 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotSpec.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +/** + * Snapshot spec that creates {@link RemoteSandboxSnapshot} instances backed by a + * {@link RemoteSnapshotClient}. + * + *

The same client instance is shared across all sessions created by this spec. + * Implement {@link RemoteSnapshotClient} to connect to your remote storage backend + * (e.g. AWS S3, Alibaba OSS, Google GCS). + */ +public class RemoteSnapshotSpec implements SandboxSnapshotSpec { + + private final RemoteSnapshotClient client; + + /** + * Creates a remote snapshot spec. + * + * @param client the remote storage client implementation to use + */ + public RemoteSnapshotSpec(RemoteSnapshotClient client) { + this.client = client; + } + + /** + * {@inheritDoc} + * + * @return a new {@link RemoteSandboxSnapshot} using this spec's client + */ + @Override + public SandboxSnapshot build(String snapshotId) { + return new RemoteSandboxSnapshot(client, snapshotId); + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshot.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshot.java new file mode 100644 index 000000000..6f77437d9 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshot.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import java.io.InputStream; + +/** + * Represents a persisted snapshot of a sandbox workspace. + * + *

Snapshots allow workspace state to be preserved between session stops and restored on + * subsequent session starts. Implementations determine where and how the snapshot is stored: + * local disk ({@link LocalSandboxSnapshot}), remote storage ({@link RemoteSandboxSnapshot}), + * or not at all ({@link NoopSandboxSnapshot}). + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = NoopSandboxSnapshot.class, name = "noop"), + @JsonSubTypes.Type(value = LocalSandboxSnapshot.class, name = "local"), + @JsonSubTypes.Type(value = RemoteSandboxSnapshot.class, name = "remote"), +}) +public interface SandboxSnapshot { + + /** + * Persists the workspace archive to this snapshot. + * + * @param workspaceArchive tar stream of the workspace to persist; caller is responsible + * for closing the stream after this call + * @throws Exception if the persist operation fails + */ + void persist(InputStream workspaceArchive) throws Exception; + + /** + * Restores the workspace archive from this snapshot. + * + * @return tar stream of the workspace; caller is responsible for closing + * @throws Exception if the restore operation fails or the snapshot is not restorable + */ + InputStream restore() throws Exception; + + /** + * Returns whether this snapshot can currently be restored. + * + * @return true if {@link #restore()} would succeed + * @throws Exception if checking restorability fails + */ + boolean isRestorable() throws Exception; + + /** + * Returns the unique identifier for this snapshot. + * + * @return snapshot id + */ + String getId(); + + /** + * Returns the snapshot type discriminator used in JSON serialization. + * + * @return type string (e.g. "noop", "local", "remote") + */ + String getType(); + + /** + * Returns whether this snapshot actually persists data. + * + *

When {@code false}, {@link io.agentscope.harness.agent.sandbox.AbstractBaseSandbox#stop()} skips the + * potentially expensive workspace archive step entirely. Defaults to {@code true}. + * + * @return false only for no-op implementations that discard all archive data + */ + default boolean isPersistenceEnabled() { + return true; + } +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshotSpec.java new file mode 100644 index 000000000..939e3b448 --- /dev/null +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/SandboxSnapshotSpec.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +/** + * Factory that creates {@link SandboxSnapshot} instances for a given session ID. + * + *

Implementations configure WHERE snapshots are stored: + * {@link NoopSnapshotSpec} (disabled), {@link LocalSnapshotSpec} (local disk), + * {@link RemoteSnapshotSpec} (remote storage). + * + *

The {@code snapshotId} parameter passed to {@link #build} allows each session to have + * its own isolated snapshot file/object, while sharing the same storage configuration. + */ +public interface SandboxSnapshotSpec { + + /** + * Creates a {@link SandboxSnapshot} for the given session ID. + * + * @param snapshotId unique identifier for the snapshot (typically the session UUID) + * @return a new snapshot instance configured for the given ID + */ + SandboxSnapshot build(String snapshotId); +} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java index 7da513ae1..e1cc9d1ce 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/session/WorkspaceSession.java @@ -33,6 +33,10 @@ * {@link io.agentscope.core.state.SessionKey#toIdentifier()}) is appended automatically * by the parent class as a subdirectory, producing the full path above. * + *

This session is dedicated to ReActAgent runtime state persistence only (for example memory + * messages, agent metadata). Sandbox lifecycle state is stored separately through + * {@code SandboxStateStore}. + * *

Usage: * *

{@code
diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/BaseStore.java
similarity index 97%
rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java
rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/store/BaseStore.java
index fc12bd5fa..e515e2fc4 100644
--- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/BaseStore.java
+++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/BaseStore.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.agentscope.harness.agent.filesystem.store;
+package io.agentscope.harness.agent.store;
 
 import java.util.List;
 import java.util.Map;
diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/InMemoryStore.java
similarity index 98%
rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java
rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/store/InMemoryStore.java
index 56eb1544a..b4c497e25 100644
--- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/InMemoryStore.java
+++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/InMemoryStore.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.agentscope.harness.agent.filesystem.store;
+package io.agentscope.harness.agent.store;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java
similarity index 96%
rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java
rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java
index 85f8e95a0..b63776823 100644
--- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/NamespaceFactory.java
+++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.agentscope.harness.agent.filesystem.store;
+package io.agentscope.harness.agent.store;
 
 import java.util.List;
 
diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/StoreItem.java
similarity index 94%
rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java
rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/store/StoreItem.java
index 1f355d241..657f6b393 100644
--- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/store/StoreItem.java
+++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/StoreItem.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.agentscope.harness.agent.filesystem.store;
+package io.agentscope.harness.agent.store;
 
 import java.util.Map;
 
diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java
index 590a19d6d..b97ab1e5a 100644
--- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java
+++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java
@@ -17,7 +17,6 @@
 
 import io.agentscope.core.tool.Tool;
 import io.agentscope.core.tool.ToolParam;
-import io.agentscope.harness.agent.memory.MemoryIndex;
 import io.agentscope.harness.agent.workspace.WorkspaceManager;
 import java.util.List;
 import java.util.StringJoiner;
@@ -28,25 +27,20 @@
 /**
  * Tool for searching through persisted memories (MEMORY.md and memory/*.md files).
  *
- * 

When a {@link MemoryIndex} is available, uses SQLite FTS5 for ranked full-text - * search. Falls back to naive keyword search when the index is unavailable. + *

Uses keyword-based search through all memory files visible via the configured + * {@link io.agentscope.harness.agent.filesystem.AbstractFilesystem} (works across Local, + * Sandbox, and Store backends without any local SQLite dependency). */ public class MemorySearchTool { private static final Logger log = LoggerFactory.getLogger(MemorySearchTool.class); - private static final int MAX_RESULTS = 30; private final WorkspaceManager workspaceManager; - private volatile MemoryIndex memoryIndex; public MemorySearchTool(WorkspaceManager workspaceManager) { this.workspaceManager = workspaceManager; } - public void setMemoryIndex(MemoryIndex memoryIndex) { - this.memoryIndex = memoryIndex; - } - @Tool( name = "memory_search", description = @@ -60,26 +54,6 @@ public String memorySearch( return "No query provided"; } - MemoryIndex idx = this.memoryIndex; - if (idx != null) { - try { - List hits = idx.search(query, MAX_RESULTS); - if (!hits.isEmpty()) { - StringJoiner sj = new StringJoiner("\n"); - for (MemoryIndex.SearchHit hit : hits) { - sj.add( - String.format( - "Source: %s#%d: %s", - hit.path(), hit.lineNumber(), hit.content())); - } - return "Found " + hits.size() + " matches:\n\n" + sj; - } - return "No matching memories found for: " + query; - } catch (Exception e) { - log.warn("FTS5 search failed, falling back to keyword search: {}", e.getMessage()); - } - } - return keywordSearch(query); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java index 3e0407012..aef74b460 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java @@ -32,6 +32,7 @@ import io.agentscope.harness.agent.filesystem.model.FileInfo; import io.agentscope.harness.agent.filesystem.model.GlobResult; import io.agentscope.harness.agent.filesystem.model.ReadResult; +import io.agentscope.harness.agent.store.NamespaceFactory; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -52,7 +53,7 @@ * etc.), the {@link AbstractFilesystem} is queried first. If it returns non-empty content, that * content is used (filesystem overrides). Otherwise, the local workspace disk is read as a * fallback. The filesystem layer applies user/session scoping transparently via - * {@link io.agentscope.harness.agent.filesystem.store.NamespaceFactory}. + * {@link NamespaceFactory}. * *

Write path: All writes (memory, sessions, etc.) go through the * {@link AbstractFilesystem}. @@ -323,7 +324,7 @@ private String readWritableWorkspaceRelativeUtf8(String relativePath) { } /** Overwrites a workspace-relative UTF-8 file. All writes go through the filesystem. */ - private void writeUtf8WorkspaceRelative(String relativePath, String content) { + public void writeUtf8WorkspaceRelative(String relativePath, String content) { if (relativePath == null || content == null) { return; } @@ -343,7 +344,7 @@ private void writeUtf8WorkspaceRelative(String relativePath, String content) { /** * Two-layer read: filesystem first (namespaced by {@link - * io.agentscope.harness.agent.filesystem.store.NamespaceFactory}), local disk fallback. + * NamespaceFactory}), local disk fallback. */ private String readWithOverride(String relativePath) { String fsContent = readTextThroughFilesystem(relativePath); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java new file mode 100644 index 000000000..6ed16fa8c --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.core.session.Session; +import io.agentscope.harness.agent.filesystem.LocalFilesystemSpec; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; +import io.agentscope.harness.agent.sandbox.filesystem.DockerFilesystemSpec; +import io.agentscope.harness.agent.sandbox.snapshot.LocalSnapshotSpec; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import reactor.core.publisher.Flux; + +class HarnessAgentDistributedSandboxTest { + + @TempDir Path workspace; + + @Test + void sandboxDistributed_requiresSandboxFilesystemMode() { + IllegalStateException ex = + assertThrows( + IllegalStateException.class, + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new LocalFilesystemSpec()) + .sandboxDistributed( + SandboxDistributedOptions.builder().build()) + .build()); + assertEquals( + true, + ex.getMessage().contains("requires sandbox mode"), + "should fail-fast when sandboxDistributed is used outside sandbox mode"); + } + + @Test + void sandboxDistributed_requireDistributed_failsOnLocalDefaults() { + IllegalStateException ex = + assertThrows( + IllegalStateException.class, + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new DockerFilesystemSpec()) + .sandboxDistributed( + SandboxDistributedOptions.builder().build()) + .build()); + assertEquals( + true, + ex.getMessage().contains("distributed Session backend"), + "should fail-fast when effective session remains local"); + } + + @Test + void sandboxDistributed_appliesIsolationAndSnapshotOverride() { + Session distributedSession = mock(Session.class); + DockerFilesystemSpec spec = new DockerFilesystemSpec(); + LocalSnapshotSpec snapshotSpec = new LocalSnapshotSpec(workspace.resolve("snapshots")); + + SandboxDistributedOptions options = + SandboxDistributedOptions.builder() + .session(distributedSession) + .snapshotSpec(snapshotSpec) + .isolationScope(IsolationScope.AGENT) + .build(); + + assertDoesNotThrow( + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(spec) + .sandboxDistributed(options) + .build()); + + assertEquals(IsolationScope.AGENT, spec.getIsolationScope()); + assertInstanceOf(LocalSnapshotSpec.class, spec.toSandboxContext().getSnapshotSpec()); + } + + @Test + void sandboxDistributed_requireDistributedCanBeDisabled() { + assertDoesNotThrow( + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new DockerFilesystemSpec()) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) + .build()); + } + + private static Model stubModel(String assistantText) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of( + io.agentscope.core.message.TextBlock.builder() + .text(assistantText) + .build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java index 0c2cb69a4..8dbbb9d98 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java @@ -30,7 +30,9 @@ import io.agentscope.core.model.Model; import io.agentscope.core.model.ToolSchema; import io.agentscope.harness.agent.filesystem.LocalFilesystem; +import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; +import io.agentscope.harness.agent.store.InMemoryStore; import io.agentscope.harness.agent.workspace.WorkspaceConstants; import java.nio.file.Files; import java.nio.file.Path; @@ -192,6 +194,26 @@ void subagentsDir_loadsMarkdownSpecs() throws Exception { names.contains(mdId), "subagents/*.md with front matter should produce an entry"); } + @Test + void storeFilesystemSpec_sharesMemoryMdInNonsandboxMode() throws Exception { + Files.createDirectories(workspace); + Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), "# Test\n"); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("agent-a") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new StoreFilesystemSpec(store)) + .build(); + + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared-memory"); + + assertTrue( + store.get(List.of("agents", "agent-a", "users", "_default"), "/MEMORY.md") != null); + } + private static Msg userText(String text) { return Msg.builder() .role(MsgRole.USER) diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java new file mode 100644 index 000000000..6b0e4ae02 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java @@ -0,0 +1,198 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import reactor.core.publisher.Flux; + +/** + * Example: Fully local personal-assistant mode using {@link LocalFilesystemWithShell}. + * + *

Context

+ *

This mode is ideal for a personal local assistant running on a developer's machine + * or in a single-process environment: + *

    + *
  • All file I/O goes directly to a local workspace directory on disk.
  • + *
  • Shell commands execute in that directory via {@code ProcessBuilder}.
  • + *
  • No sandbox container, no distributed store, no external dependencies.
  • + *
  • State persists naturally as files on disk between calls.
  • + *
  • Changing the {@code userId} or {@code sessionId} in the {@link RuntimeContext} does + * not redirect I/O to a different location — the workspace directory is always + * the same.
  • + *
+ * + *

Trade-offs

+ *
    + *
  • Pro: Zero infrastructure, instant setup, full local control.
  • + *
  • Con: No isolation between users or sessions, no horizontal scaling.
  • + *
+ * + *

Configure via {@link HarnessAgent.Builder#abstractFilesystem} with a + * {@link LocalFilesystemWithShell} instance pointing at your desired workspace directory. + */ +class LocalFilesystemPersonalAssistantExampleTest { + + @TempDir Path workspace; + + /** + * Demonstrates that files written to the workspace during one call persist to disk and are + * readable in subsequent calls — the most fundamental characteristic of the local mode. + */ + @Test + void localFilesystem_filesPersistAcrossCalls() throws Exception { + Files.createDirectories(workspace); + + // Build the agent with a LocalFilesystemWithShell backend. + // No distributed store, no sandbox — all operations go straight to disk. + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(stubModel("done")) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + // Call 1: write a note to MEMORY.md through the workspace manager + agent.call(userMsg("first call"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "# Notes\n- item 1"); + + // The file exists on disk after call 1 + Path memoryFile = workspace.resolve("MEMORY.md"); + assertTrue(Files.isRegularFile(memoryFile), "MEMORY.md should exist on disk after call 1"); + String content = Files.readString(memoryFile, StandardCharsets.UTF_8); + assertTrue(content.contains("item 1"), "MEMORY.md content should be persisted on disk"); + + // Call 2: same workspace, different session — file is still there + agent.call(userMsg("second call"), ctx("session-2", "alice")).block(); + assertTrue( + Files.isRegularFile(memoryFile), "MEMORY.md should still exist on disk in call 2"); + assertEquals( + content, + Files.readString(memoryFile, StandardCharsets.UTF_8), + "MEMORY.md content should be unchanged after call 2"); + } + + /** + * Demonstrates that changing {@code userId} or {@code sessionId} does NOT redirect I/O to a + * different location in local mode. + * + *

This is the key distinction from sandbox/store modes: in local mode the workspace + * directory is fixed, so all users and sessions share the same disk location. + */ + @Test + void localFilesystem_workspaceIsNotPartitionedByUserOrSession() throws Exception { + Files.createDirectories(workspace); + + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(stubModel("done")) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + // Alice writes during her session + agent.call(userMsg("alice here"), ctx("session-alice", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("shared.txt", "alice was here"); + + // Bob calls with a different userId — still reads the same workspace + agent.call(userMsg("bob here"), ctx("session-bob", "bob")).block(); + Path sharedFile = workspace.resolve("shared.txt"); + assertTrue( + Files.isRegularFile(sharedFile), + "shared.txt written by alice should be visible in the same workspace, " + + "regardless of userId or sessionId"); + } + + /** + * Demonstrates that the underlying workspace directory is a plain local filesystem path — + * you can read and write files with standard Java I/O alongside the agent. + */ + @Test + void localFilesystem_directDiskAccessFromHostProcess() throws Exception { + Files.createDirectories(workspace); + + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(stubModel("done")) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + // Write a file from the host process (simulating a user placing a document in the + // workspace) + Path doc = workspace.resolve("document.txt"); + Files.writeString(doc, "Host-written document content"); + + // The agent can see the file through its workspace manager + agent.call(userMsg("check document"), ctx("s1", "user")).block(); + String read = agent.getWorkspaceManager().readManagedWorkspaceFileUtf8("document.txt"); + assertNotNull(read, "agent should be able to read files written directly to the workspace"); + assertTrue(read.contains("Host-written"), "agent should see the host-written content"); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + private static Model stubModel(String text) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(text).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java new file mode 100644 index 000000000..29b49e776 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -0,0 +1,265 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.example.support.InMemorySandboxClient; +import io.agentscope.harness.agent.example.support.InMemorySandboxFilesystemSpec; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import reactor.core.publisher.Flux; + +/** + * Example: Sandbox filesystem mode with different {@link IsolationScope} levels. + * + *

Context

+ *

In sandbox mode, each agent call acquires a sandbox session (e.g. a Docker container or, + * in this test, a local temp directory). The {@code IsolationScope} controls which calls + * resume the same sandbox (sharing accumulated state) versus which ones + * create a fresh sandbox. + * + *

Three scopes are demonstrated: + *

    + *
  • {@link IsolationScope#SESSION} – calls with the same session ID resume the same sandbox. + * Calls from a different session get a brand-new sandbox.
  • + *
  • {@link IsolationScope#USER} – calls from the same user (any session) resume the same + * sandbox. Calls from a different user get a fresh sandbox.
  • + *
  • {@link IsolationScope#AGENT} – all calls share one sandbox regardless of user or + * session.
  • + *
+ * + *

This test uses {@link InMemorySandboxClient} (no Docker required) and a Mockito-stubbed + * {@link Model} that immediately returns a terminal text response so the ReAct loop exits in one + * step. The assertions count {@link InMemorySandboxClient#getCreateCount()} and + * {@link InMemorySandboxClient#getResumeCount()} to verify isolation behaviour. + */ +class SandboxFilesystemIsolationScopeExampleTest { + + @TempDir Path workspace; + + // ------------------------------------------------------------------------- + // Scenario A: SESSION scope + // ------------------------------------------------------------------------- + + /** + * SESSION scope — same session ID → sandbox is resumed on the second call. + * + *

Call 1: no persisted state → {@code create} is called (creates fresh sandbox). + * Call 2: state was persisted for "session-1" → {@code resume} is called (same sandbox). + */ + @Test + void sessionScope_sameSession_resumesSandbox() throws Exception { + Files.createDirectories(workspace); + + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.SESSION); + InMemorySandboxClient client = spec.getClient(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem(spec) + .build(); + + // First call — no persisted state → create + agent.call(userMsg("hello"), ctx("session-1", null)).block(); + assertEquals(1, client.getCreateCount(), "first call should create a fresh sandbox"); + assertEquals(0, client.getResumeCount()); + + // Second call — same session → resume + agent.call(userMsg("hello again"), ctx("session-1", null)).block(); + assertEquals(1, client.getCreateCount(), "second call should NOT create a new sandbox"); + assertEquals(1, client.getResumeCount(), "second call should resume the existing sandbox"); + } + + /** + * SESSION scope — different session ID → each call creates a fresh sandbox. + */ + @Test + void sessionScope_differentSession_createsFreshSandbox() throws Exception { + Files.createDirectories(workspace); + + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.SESSION); + InMemorySandboxClient client = spec.getClient(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("call from session-1"), ctx("session-1", "alice")).block(); + agent.call(userMsg("call from session-2"), ctx("session-2", "alice")).block(); + + assertEquals( + 2, client.getCreateCount(), "each distinct session should create its own sandbox"); + assertEquals(0, client.getResumeCount()); + } + + // ------------------------------------------------------------------------- + // Scenario B: USER scope + // ------------------------------------------------------------------------- + + /** + * USER scope — same user, different session IDs → both calls share the same sandbox. + * + *

Call 1: no persisted state for user "alice" → {@code create}. + * Call 2: state exists for "alice" (different sessionId) → {@code resume}. + */ + @Test + void userScope_sameUser_differentSessions_resumesSandbox() throws Exception { + Files.createDirectories(workspace); + + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.USER); + InMemorySandboxClient client = spec.getClient(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("session A"), ctx("session-a", "alice")).block(); + assertEquals(1, client.getCreateCount()); + assertEquals(0, client.getResumeCount()); + + // Different session, same user → should resume Alice's sandbox + agent.call(userMsg("session B"), ctx("session-b", "alice")).block(); + assertEquals(1, client.getCreateCount(), "same user → should NOT create a new sandbox"); + assertEquals(1, client.getResumeCount(), "same user → should resume existing sandbox"); + } + + /** + * USER scope — different users → each user gets an independent sandbox. + */ + @Test + void userScope_differentUsers_createsFreshSandbox() throws Exception { + Files.createDirectories(workspace); + + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.USER); + InMemorySandboxClient client = spec.getClient(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("hi from alice"), ctx("s1", "alice")).block(); + agent.call(userMsg("hi from bob"), ctx("s2", "bob")).block(); + + assertEquals(2, client.getCreateCount(), "each user should get their own fresh sandbox"); + assertEquals(0, client.getResumeCount()); + } + + // ------------------------------------------------------------------------- + // Scenario C: AGENT scope + // ------------------------------------------------------------------------- + + /** + * AGENT scope — all calls share a single sandbox regardless of user or session. + * + *

Call 1: no state → {@code create}. + * Call 2: state exists (agentId key) → {@code resume} — even with a different user and session. + */ + @Test + void agentScope_allCallsShareOneSandbox() throws Exception { + Files.createDirectories(workspace); + + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.AGENT); + InMemorySandboxClient client = spec.getClient(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("shared-assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem(spec) + .build(); + + // Different users, different sessions — all share one AGENT-scoped sandbox + agent.call(userMsg("alice says hi"), ctx("s1", "alice")).block(); + assertEquals(1, client.getCreateCount()); + + agent.call(userMsg("bob says hi"), ctx("s2", "bob")).block(); + assertEquals(1, client.getCreateCount(), "second call should NOT create a new sandbox"); + assertEquals( + 1, client.getResumeCount(), "second call should resume the shared agent sandbox"); + + agent.call(userMsg("charlie says hi"), ctx("s3", "charlie")).block(); + assertEquals(1, client.getCreateCount()); + assertEquals( + 2, client.getResumeCount(), "third call should also resume the shared sandbox"); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + private static Model stubModel(String text) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(text).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java new file mode 100644 index 000000000..9f2d0cd44 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java @@ -0,0 +1,282 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.store.InMemoryStore; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import reactor.core.publisher.Flux; + +/** + * Example: Distributed shared store filesystem mode with different {@link IsolationScope} levels. + * + *

Context

+ *

In store mode, selected paths (such as {@code MEMORY.md}, {@code memory/}) are routed to a + * shared key-value store ({@link InMemoryStore} here; typically Redis or another distributed + * store in production). The {@code IsolationScope} controls the store namespace prefix and + * therefore which agent calls can read each other's stored data. + * + *

Three scopes are demonstrated: + *

    + *
  • {@link IsolationScope#SESSION} – each session gets its own namespace. Calls within the + * same session see the same data; calls from a different session see an empty namespace.
  • + *
  • {@link IsolationScope#USER} – all sessions of the same user share one namespace. A + * different user gets an isolated namespace.
  • + *
  • {@link IsolationScope#AGENT} – all users and sessions share one namespace per agent. + * Data written by any caller is visible to all other callers of the same agent.
  • + *
+ * + *

Assertions directly inspect the {@link InMemoryStore} using the namespace keys generated by + * the scopes: + *

    + *
  • {@code SESSION}: {@code agents//sessions//MEMORY.md}
  • + *
  • {@code USER}: {@code agents//users//MEMORY.md}
  • + *
  • {@code AGENT}: {@code agents//shared/MEMORY.md}
  • + *
+ * + *

This test does not call {@link HarnessAgent#call} for all cases — it uses + * {@link io.agentscope.harness.agent.workspace.WorkspaceManager#writeUtf8WorkspaceRelative} + * directly where possible to keep the example focused on namespace routing rather than agent + * conversation mechanics. + */ +class StoreFilesystemIsolationScopeExampleTest { + + @TempDir Path workspace; + + // ------------------------------------------------------------------------- + // Scenario A: SESSION scope + // ------------------------------------------------------------------------- + + /** + * SESSION scope — writes from session-1 are NOT visible to session-2. + * + *

The store namespace is {@code agents//sessions/}, so each session + * has a fully independent MEMORY.md. + */ + @Test + void sessionScope_differentSessions_isolatedNamespaces() throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store) + .isolationScope(IsolationScope.SESSION)) + .build(); + + // Call as session-1 and write MEMORY.md + agent.call(userMsg("from session-1"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "session-1 notes"); + + // Verify the data landed in the session-1 namespace + assertNotNull( + store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md"), + "MEMORY.md should be stored under the session-1 namespace"); + + // Verify session-2 namespace is empty (isolated) + assertNull( + store.get(List.of("agents", "assistant", "sessions", "session-2"), "/MEMORY.md"), + "session-2 namespace should be empty"); + } + + /** + * SESSION scope — writes from the same session are shared across calls. + */ + @Test + void sessionScope_sameSession_sharedNamespace() throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store) + .isolationScope(IsolationScope.SESSION)) + .build(); + + // First call writes MEMORY.md under session-1 + agent.call(userMsg("call 1"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared memory"); + + // Second call with same session can read it + agent.call(userMsg("call 2"), ctx("session-1", "alice")).block(); + + assertNotNull( + store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md"), + "MEMORY.md should persist in the session-1 namespace across calls"); + } + + // ------------------------------------------------------------------------- + // Scenario B: USER scope + // ------------------------------------------------------------------------- + + /** + * USER scope — different sessions of the same user share a single namespace. + * + *

The namespace is {@code agents//users/}, so data written by session-A + * is immediately visible to session-B of the same user. + */ + @Test + void userScope_sameUser_sharedAcrossSessions() throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .build(); + + // Call as alice / session-a and write MEMORY.md + agent.call(userMsg("hi from session-a"), ctx("session-a", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's memory"); + + // The entry lands in the user-scoped namespace + assertNotNull( + store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md"), + "MEMORY.md should be stored under alice's user namespace"); + + // Call as alice / session-b — sees the same store namespace + agent.call(userMsg("hi from session-b"), ctx("session-b", "alice")).block(); + assertNotNull( + store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md"), + "alice's MEMORY.md should still be accessible from session-b"); + } + + /** + * USER scope — different users have isolated namespaces. + */ + @Test + void userScope_differentUsers_isolatedNamespaces() throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .build(); + + agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's data"); + + // Bob's namespace should be empty + assertNull( + store.get(List.of("agents", "assistant", "users", "bob"), "/MEMORY.md"), + "bob's namespace should be isolated from alice's"); + } + + // ------------------------------------------------------------------------- + // Scenario C: AGENT scope + // ------------------------------------------------------------------------- + + /** + * AGENT scope — all users and sessions share one namespace per agent. + * + *

The namespace is {@code agents//shared}, so any user's write is visible + * to any other user of the same agent. + */ + @Test + void agentScope_allCallersShareOneNamespace() throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + + HarnessAgent agent = + HarnessAgent.builder() + .name("shared-assistant") + .model(stubModel("done")) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.AGENT)) + .build(); + + // Alice writes + agent.call(userMsg("alice"), ctx("s1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared knowledge"); + + assertNotNull( + store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md"), + "MEMORY.md should be in the agent-scoped shared namespace"); + + // Bob's call also reads from the same shared namespace + agent.call(userMsg("bob"), ctx("s2", "bob")).block(); + assertNotNull( + store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md"), + "shared namespace should still contain the data after bob's call"); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + private static Model stubModel(String text) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(text).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandbox.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandbox.java new file mode 100644 index 000000000..f42059a9c --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandbox.java @@ -0,0 +1,116 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example.support; + +import io.agentscope.harness.agent.sandbox.ExecResult; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxState; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Test-only {@link Sandbox} that uses a local temp directory as the workspace. + */ +public class InMemorySandbox implements Sandbox { + + private final InMemorySandboxState state; + private final Path workspaceDir; + private final AtomicBoolean running = new AtomicBoolean(false); + private final int defaultTimeoutSeconds; + + public InMemorySandbox(InMemorySandboxState state, int defaultTimeoutSeconds) { + this.state = state; + this.workspaceDir = Path.of(state.getWorkspaceRoot()); + this.defaultTimeoutSeconds = defaultTimeoutSeconds; + } + + @Override + public void start() throws Exception { + if (!Files.exists(workspaceDir)) { + Files.createDirectories(workspaceDir); + } + state.setWorkspaceRootReady(true); + running.set(true); + } + + @Override + public void stop() throws Exception { + state.setWorkspaceRootReady(true); + running.set(false); + } + + @Override + public void shutdown() throws Exception { + // Leave workspace dir in place for resume in tests + } + + @Override + public void close() throws Exception { + try { + stop(); + } catch (Exception e) { + // best-effort + } + shutdown(); + } + + @Override + public boolean isRunning() { + return running.get(); + } + + @Override + public SandboxState getState() { + return state; + } + + @Override + public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { + int timeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeoutSeconds; + ProcessBuilder pb = new ProcessBuilder("sh", "-c", command); + pb.directory(workspaceDir.toFile()); + pb.redirectErrorStream(false); + Process process = pb.start(); + + boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + return new ExecResult(124, "", "Command timed out after " + timeout + "s", false); + } + + String stdout = new String(process.getInputStream().readAllBytes()); + String stderr = new String(process.getErrorStream().readAllBytes()); + return new ExecResult(process.exitValue(), stdout, stderr, false); + } + + @Override + public InputStream persistWorkspace() throws Exception { + return new ByteArrayInputStream(new byte[1024]); + } + + @Override + public void hydrateWorkspace(InputStream archive) throws Exception { + // no-op + } + + public Path getWorkspaceDir() { + return workspaceDir; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxClient.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxClient.java new file mode 100644 index 000000000..c25ffaa46 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxClient.java @@ -0,0 +1,122 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example.support; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** Test-only {@link SandboxClient} that allocates local temp directories as sandboxes. */ +public class InMemorySandboxClient implements SandboxClient { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final int DEFAULT_TIMEOUT_SECONDS = 30; + + private final AtomicInteger createCount = new AtomicInteger(0); + private final AtomicInteger resumeCount = new AtomicInteger(0); + private final Path baseDir; + + public InMemorySandboxClient() { + try { + this.baseDir = Files.createTempDirectory("agentscope-inmemory-sandbox-"); + } catch (IOException e) { + throw new UncheckedIOException( + "Failed to create base temp dir for InMemorySandboxClient", e); + } + } + + @Override + public Sandbox create( + WorkspaceSpec workspaceSpec, + SandboxSnapshotSpec snapshotSpec, + SandboxClientOptions options) { + createCount.incrementAndGet(); + String sessionId = UUID.randomUUID().toString(); + Path workspaceDir = baseDir.resolve(sessionId); + try { + Files.createDirectories(workspaceDir); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create workspace dir", e); + } + + InMemorySandboxState state = new InMemorySandboxState(sessionId, workspaceDir.toString()); + WorkspaceSpec spec = workspaceSpec != null ? workspaceSpec.copy() : new WorkspaceSpec(); + spec.setRoot(workspaceDir.toString()); + state.setWorkspaceSpec(spec); + + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public Sandbox resume(SandboxState sessionState) { + resumeCount.incrementAndGet(); + InMemorySandboxState state = (InMemorySandboxState) sessionState; + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public void delete(Sandbox session) { + // no-op + } + + @Override + public String serializeState(SandboxState state) { + try { + InMemorySandboxState s = (InMemorySandboxState) state; + return MAPPER.writeValueAsString(new StateDto(s.getSessionId(), s.getWorkspaceRoot())); + } catch (IOException e) { + throw new UncheckedIOException("Failed to serialize sandbox state", e); + } + } + + @Override + public SandboxState deserializeState(String json) { + try { + StateDto dto = MAPPER.readValue(json, StateDto.class); + InMemorySandboxState state = + new InMemorySandboxState(dto.sessionId(), dto.workspaceRoot()); + state.setWorkspaceRootReady(true); + return state; + } catch (IOException e) { + throw new UncheckedIOException("Failed to deserialize sandbox state", e); + } + } + + public int getCreateCount() { + return createCount.get(); + } + + public int getResumeCount() { + return resumeCount.get(); + } + + public void resetCounts() { + createCount.set(0); + resumeCount.set(0); + } + + record StateDto(String sessionId, String workspaceRoot) {} +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxFilesystemSpec.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxFilesystemSpec.java new file mode 100644 index 000000000..2cb842dd3 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxFilesystemSpec.java @@ -0,0 +1,81 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example.support; + +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; + +/** + * Test-only {@link SandboxFilesystemSpec} backed by an {@link InMemorySandboxClient}. + * + *

Uses a local temp directory as the sandbox workspace. No Docker or external dependencies + * are required. The underlying {@link InMemorySandboxClient} exposes create/resume counters + * so isolation-scope tests can verify whether a sandbox was freshly created or resumed. + */ +public class InMemorySandboxFilesystemSpec extends SandboxFilesystemSpec { + + private final InMemorySandboxClient client; + + /** + * Creates a spec backed by the given in-memory sandbox client. + * + * @param client the in-memory client to use for session create/resume + */ + public InMemorySandboxFilesystemSpec(InMemorySandboxClient client) { + this.client = client; + } + + /** + * Creates a spec with a new default {@link InMemorySandboxClient}. + */ + public InMemorySandboxFilesystemSpec() { + this(new InMemorySandboxClient()); + } + + /** + * Returns the underlying {@link InMemorySandboxClient}. + * + * @return the client + */ + public InMemorySandboxClient getClient() { + return client; + } + + @Override + protected SandboxClient createClient() { + return client; + } + + @Override + protected SandboxClientOptions clientOptions() { + return null; + } + + @Override + protected SandboxSnapshotSpec snapshotSpec() { + return null; + } + + @Override + protected WorkspaceSpec workspaceSpec() { + WorkspaceSpec s = new WorkspaceSpec(); + s.setRoot("/workspace"); + return s; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxState.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxState.java new file mode 100644 index 000000000..81564f13e --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/support/InMemorySandboxState.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.example.support; + +import io.agentscope.harness.agent.sandbox.SandboxState; + +/** + * Test-only {@link SandboxState} for {@link InMemorySandboxClient}. + */ +public class InMemorySandboxState extends SandboxState { + + private String workspaceRoot; + + public InMemorySandboxState() {} + + public InMemorySandboxState(String sessionId, String workspaceRoot) { + setSessionId(sessionId); + this.workspaceRoot = workspaceRoot; + } + + public String getWorkspaceRoot() { + return workspaceRoot; + } + + public void setWorkspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java new file mode 100644 index 000000000..cf398bffd --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java @@ -0,0 +1,218 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.harness.agent.filesystem.model.WriteResult; +import io.agentscope.harness.agent.store.InMemoryStore; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +/** + * Verifies delete / move / exists on all {@link AbstractFilesystem} implementations. + * + *

LocalFilesystem is tested in non-virtual mode; paths are workspace-relative (no leading '/'). + * StoreFilesystem uses leading-slash keys matching its internal convention. + */ +class FilesystemDeleteMoveExistsTest { + + // ================================================================ + // LocalFilesystem — non-virtual mode, relative paths (no leading '/') + // ================================================================ + + @Test + void local_exists_true(@TempDir Path tmp) throws Exception { + LocalFilesystem fs = new LocalFilesystem(tmp); + Files.writeString(tmp.resolve("file.txt"), "hello"); + + assertTrue(fs.exists("file.txt")); + } + + @Test + void local_exists_false(@TempDir Path tmp) { + LocalFilesystem fs = new LocalFilesystem(tmp); + assertFalse(fs.exists("nonexistent.txt")); + } + + @Test + void local_delete_file(@TempDir Path tmp) throws Exception { + LocalFilesystem fs = new LocalFilesystem(tmp); + Path f = Files.writeString(tmp.resolve("del.txt"), "data"); + + WriteResult result = fs.delete("del.txt"); + assertTrue(result.isSuccess()); + assertFalse(Files.exists(f)); + } + + @Test + void local_delete_idempotent(@TempDir Path tmp) { + LocalFilesystem fs = new LocalFilesystem(tmp); + WriteResult result = fs.delete("ghost.txt"); + assertTrue(result.isSuccess(), "deleting nonexistent should succeed (idempotent)"); + } + + @Test + void local_delete_directory_recursive(@TempDir Path tmp) throws Exception { + LocalFilesystem fs = new LocalFilesystem(tmp); + Path dir = tmp.resolve("subdir"); + Files.createDirectories(dir); + Files.writeString(dir.resolve("a.txt"), "a"); + Files.writeString(dir.resolve("b.txt"), "b"); + + WriteResult result = fs.delete("subdir"); + assertTrue(result.isSuccess()); + assertFalse(Files.exists(dir)); + } + + @Test + void local_move_file(@TempDir Path tmp) throws Exception { + LocalFilesystem fs = new LocalFilesystem(tmp); + Files.writeString(tmp.resolve("src.txt"), "content"); + + WriteResult result = fs.move("src.txt", "dst.txt"); + assertTrue(result.isSuccess()); + assertFalse(Files.exists(tmp.resolve("src.txt"))); + assertTrue(Files.exists(tmp.resolve("dst.txt"))); + } + + @Test + void local_move_missingSource(@TempDir Path tmp) { + LocalFilesystem fs = new LocalFilesystem(tmp); + WriteResult result = fs.move("missing.txt", "dst.txt"); + assertFalse(result.isSuccess()); + } + + // ================================================================ + // StoreFilesystem — keys follow leading-slash convention + // ================================================================ + + private static InMemoryStore storeWith(String path, String content) { + InMemoryStore s = new InMemoryStore(); + s.put(List.of("ns"), path, Map.of("content", content, "encoding", "utf-8")); + return s; + } + + @Test + void store_exists_true() { + InMemoryStore s = storeWith("/file.txt", "hello"); + StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + + assertTrue(fs.exists("/file.txt")); + } + + @Test + void store_exists_false() { + StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + assertFalse(fs.exists("/nope.txt")); + } + + @Test + void store_delete_file() { + InMemoryStore s = storeWith("/file.txt", "hello"); + StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + + WriteResult result = fs.delete("/file.txt"); + assertTrue(result.isSuccess()); + assertNull(s.get(List.of("ns"), "/file.txt")); + } + + @Test + void store_delete_idempotent() { + StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + WriteResult result = fs.delete("/ghost.txt"); + assertTrue(result.isSuccess()); + } + + @Test + void store_move_file() { + InMemoryStore s = storeWith("/src.txt", "data"); + StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + + WriteResult result = fs.move("/src.txt", "/dst.txt"); + assertTrue(result.isSuccess()); + assertNull(s.get(List.of("ns"), "/src.txt")); + assertNotNull(s.get(List.of("ns"), "/dst.txt")); + } + + @Test + void store_move_missingSource() { + StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + WriteResult result = fs.move("/missing.txt", "/dst.txt"); + assertFalse(result.isSuccess()); + } + + // ================================================================ + // CompositeFilesystem — routed operations + // ================================================================ + + @Test + void composite_exists_routedToStore(@TempDir Path tmp) { + InMemoryStore s = storeWith("/MEMORY.md", "mem"); + StoreFilesystem storeFsys = new StoreFilesystem(s, List.of("ns")); + LocalFilesystem local = new LocalFilesystem(tmp); + + CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); + + assertTrue(fs.exists("MEMORY.md")); + assertFalse(fs.exists("notExist.txt")); + } + + @Test + void composite_delete_routedToStore(@TempDir Path tmp) { + InMemoryStore s = storeWith("/MEMORY.md", "mem"); + StoreFilesystem storeFsys = new StoreFilesystem(s, List.of("ns")); + LocalFilesystem local = new LocalFilesystem(tmp); + + CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); + + WriteResult result = fs.delete("MEMORY.md"); + assertTrue(result.isSuccess()); + assertNull(s.get(List.of("ns"), "/MEMORY.md")); + } + + // ================================================================ + // CompositeFilesystem — cross-backend move (store → local) + // ================================================================ + + @Test + void composite_move_crossBackend_storeToLocal(@TempDir Path tmp) throws Exception { + InMemoryStore s = new InMemoryStore(); + List ns = List.of("ns"); + s.put(ns, "/2025-01-01.md", Map.of("content", "diary", "encoding", "utf-8")); + StoreFilesystem storeFsys = new StoreFilesystem(s, ns); + LocalFilesystem local = new LocalFilesystem(tmp); + + CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("memory/", storeFsys)); + + // Move from store-routed path to a local-only path + WriteResult result = fs.move("memory/2025-01-01.md", "archive/2025-01-01.md"); + assertTrue(result.isSuccess(), "cross-backend move should succeed"); + // Source removed from store + assertNull(s.get(ns, "/2025-01-01.md"), "source should be deleted from store"); + // Destination written to local disk + assertTrue( + Files.exists(tmp.resolve("archive/2025-01-01.md")), + "destination should appear on local disk"); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java new file mode 100644 index 000000000..e4fe1cc34 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.filesystem; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.harness.agent.store.InMemoryStore; +import io.agentscope.harness.agent.store.NamespaceFactory; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class StoreFilesystemSpecTest { + + @TempDir Path workspace; + + @Test + void routesSharedPathsToStoreAndOthersToLocal() throws Exception { + InMemoryStore store = new InMemoryStore(); + AtomicReference userRef = new AtomicReference<>(); + NamespaceFactory localNs = () -> List.of("local-user"); + + AbstractFilesystem fs = + new StoreFilesystemSpec(store) + .anonymousUserId("anon") + .toFilesystem(workspace, "agent-a", localNs, userRef::get); + + fs.uploadFiles( + List.of( + java.util.Map.entry( + "MEMORY.md", "hello".getBytes(StandardCharsets.UTF_8)))); + assertNotNull(store.get(List.of("agents", "agent-a", "users", "anon"), "/MEMORY.md")); + + fs.uploadFiles( + List.of( + java.util.Map.entry( + "knowledge/notes.md", "local".getBytes(StandardCharsets.UTF_8)))); + assertTrue(Files.isRegularFile(workspace.resolve("local-user/knowledge/notes.md"))); + } + + @Test + void resolvesNamespaceByRuntimeUserId() { + InMemoryStore store = new InMemoryStore(); + AtomicReference userRef = new AtomicReference<>("user-1"); + + AbstractFilesystem fs = + new StoreFilesystemSpec(store) + .toFilesystem(workspace, "agent-a", List::of, userRef::get); + + fs.uploadFiles( + List.of(java.util.Map.entry("MEMORY.md", "v1".getBytes(StandardCharsets.UTF_8)))); + assertNotNull(store.get(List.of("agents", "agent-a", "users", "user-1"), "/MEMORY.md")); + } + + /** + * Mode 1 invariant: the composite filesystem produced by {@link StoreFilesystemSpec} is + * not a sandbox filesystem, so the agent builder will not register the shell execute + * tool in this mode. + */ + @Test + void compositeModeIsNotASandboxFilesystem() { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = + new StoreFilesystemSpec(store) + .toFilesystem(workspace, "agent-a", List::of, () -> null); + + assertFalse( + fs instanceof AbstractSandboxFilesystem, + "Composite (non-sandbox) filesystem must NOT be an AbstractSandboxFilesystem" + + " — shell execution should be unavailable in Mode 1"); + assertTrue(fs instanceof CompositeFilesystem); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java new file mode 100644 index 000000000..d5d053289 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java @@ -0,0 +1,148 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.harness.agent.filesystem.StoreFilesystem; +import io.agentscope.harness.agent.store.InMemoryStore; +import io.agentscope.harness.agent.workspace.WorkspaceManager; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +/** + * Verifies that {@link MemoryConsolidator} reads daily ledgers and writes watermark / MEMORY.md + * entirely through {@link io.agentscope.harness.agent.filesystem.AbstractFilesystem}, making it + * backend-agnostic. + */ +class MemoryConsolidatorFilesystemTest { + + private static void seedStoreFile( + InMemoryStore store, List ns, String path, String content, Instant modifiedAt) { + Map value = + Map.of( + "content", + content, + "encoding", + "utf-8", + "modified_at", + modifiedAt.toString()); + store.put(ns, path, value); + } + + // ====================================================================== + // readWatermark: returns EPOCH when state file absent + // ====================================================================== + + @Test + void readWatermark_returnsEpochWhenStateAbsent(@TempDir Path tmp) { + InMemoryStore store = new InMemoryStore(); + List ns = List.of("test-ns"); + StoreFilesystem fs = new StoreFilesystem(store, ns); + WorkspaceManager wsm = new WorkspaceManager(tmp, fs); + + MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); + + assertEquals(Instant.EPOCH, consolidator.readWatermark()); + } + + // ====================================================================== + // readWatermark / writeWatermark round-trip through filesystem + // ====================================================================== + + @Test + void watermark_roundTripThroughFilesystem(@TempDir Path tmp) { + InMemoryStore store = new InMemoryStore(); + List ns = List.of("test-ns"); + StoreFilesystem fs = new StoreFilesystem(store, ns); + WorkspaceManager wsm = new WorkspaceManager(tmp, fs); + + MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); + + Instant ts = Instant.parse("2025-06-15T12:00:00Z"); + wsm.writeUtf8WorkspaceRelative(MemoryConsolidator.STATE_REL_PATH, ts.toString()); + + assertEquals(ts, consolidator.readWatermark()); + } + + // ====================================================================== + // readWatermark: no local file is touched — only the filesystem + // ====================================================================== + + @Test + void watermark_doesNotCreateLocalFile(@TempDir Path tmp) { + InMemoryStore store = new InMemoryStore(); + List ns = List.of("test-ns"); + StoreFilesystem fs = new StoreFilesystem(store, ns); + WorkspaceManager wsm = new WorkspaceManager(tmp, fs); + + MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); + + Instant ts = Instant.now(); + wsm.writeUtf8WorkspaceRelative(MemoryConsolidator.STATE_REL_PATH, ts.toString()); + + // local disk must NOT have the state file — it lives only in the store + Path localState = tmp.resolve("memory").resolve(MemoryConsolidator.STATE_FILE); + assertFalse( + Files.exists(localState), + "state file should not be written to local disk when using StoreFilesystem"); + + // but consolidator reads it correctly from the store + assertEquals(ts, consolidator.readWatermark()); + } + + // ====================================================================== + // STATE_FILE constant is preserved + // ====================================================================== + + @Test + void stateFileRelPath_matchesConstant() { + assertEquals("memory/" + MemoryConsolidator.STATE_FILE, MemoryConsolidator.STATE_REL_PATH); + } + + // ====================================================================== + // Local filesystem (no store) — watermark uses local disk via WorkspaceManager + // ====================================================================== + + @Test + void watermark_localFallback_whenNoFilesystem(@TempDir Path tmp) throws Exception { + WorkspaceManager wsm = new WorkspaceManager(tmp); + + MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); + + // No file → EPOCH + assertEquals(Instant.EPOCH, consolidator.readWatermark()); + + // Write via WorkspaceManager (falls to local disk) + Instant ts = Instant.parse("2025-03-10T09:00:00Z"); + wsm.writeUtf8WorkspaceRelative(MemoryConsolidator.STATE_REL_PATH, ts.toString()); + + assertEquals(ts, consolidator.readWatermark()); + + // Verify the local file actually exists + Path localState = tmp.resolve("memory").resolve(MemoryConsolidator.STATE_FILE); + assertTrue( + Files.exists(localState), + "state file should be written to local disk when no filesystem is configured"); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java new file mode 100644 index 000000000..d5241e454 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.memory.session; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.harness.agent.filesystem.AbstractFilesystem; +import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.store.InMemoryStore; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class SessionTreeMirrorTest { + + @TempDir Path workspace; + + @Test + void mirrorsToFilesystemAndCanRestoreWhenLocalFilesMissing() throws Exception { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = + new StoreFilesystemSpec(store) + .toFilesystem(workspace, "agent-a", List::of, () -> "user-1"); + + Path context = workspace.resolve("agents/agent-a/sessions/s1.jsonl"); + SessionTree writer = new SessionTree(context, workspace, fs); + writer.append(new SessionEntry.MessageEntry(null, null, null, "USER", "hello", null)); + writer.flush(); + + assertTrue(Files.isRegularFile(context)); + assertTrue(Files.isRegularFile(writer.getLogFile())); + + Files.deleteIfExists(context); + Files.deleteIfExists(writer.getLogFile()); + + SessionTree reader = new SessionTree(context, workspace, fs); + reader.load(); + assertEquals(1, reader.size()); + assertTrue(Files.isRegularFile(context)); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java new file mode 100644 index 000000000..3a23aef76 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import java.util.Optional; +import org.junit.jupiter.api.Test; + +class SandboxIsolationKeyTest { + + private static final String AGENT_ID = "my-agent"; + + @Test + void sessionScope_withSessionKey_resolvesCorrectly() { + RuntimeContext ctx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-abc")).build(); + Optional key = + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + assertTrue(key.isPresent()); + assertEquals(IsolationScope.SESSION, key.get().getScope()); + assertEquals("sess-abc", key.get().getValue()); + } + + @Test + void sessionScope_missingSessionKey_returnsEmpty() { + RuntimeContext ctx = RuntimeContext.builder().build(); + Optional key = + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + assertFalse(key.isPresent()); + } + + @Test + void sessionScope_nullContext_returnsEmpty() { + Optional key = + SandboxIsolationKey.resolve(IsolationScope.SESSION, null, AGENT_ID); + assertFalse(key.isPresent()); + } + + @Test + void nullScope_treatedAsSession_withSessionKey() { + RuntimeContext ctx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-def")).build(); + Optional key = + SandboxIsolationKey.resolve((IsolationScope) null, ctx, AGENT_ID); + assertTrue(key.isPresent()); + assertEquals(IsolationScope.SESSION, key.get().getScope()); + assertEquals("sess-def", key.get().getValue()); + } + + @Test + void userScope_withUserId_resolvesCorrectly() { + RuntimeContext ctx = RuntimeContext.builder().userId("user-123").build(); + Optional key = + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + assertTrue(key.isPresent()); + assertEquals(IsolationScope.USER, key.get().getScope()); + assertEquals("user-123", key.get().getValue()); + } + + @Test + void userScope_blankUserId_returnsEmpty() { + RuntimeContext ctx = RuntimeContext.builder().userId(" ").build(); + Optional key = + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + assertFalse(key.isPresent()); + } + + @Test + void userScope_nullUserId_returnsEmpty() { + RuntimeContext ctx = RuntimeContext.builder().build(); + Optional key = + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + assertFalse(key.isPresent()); + } + + @Test + void userScope_nullContext_returnsEmpty() { + Optional key = + SandboxIsolationKey.resolve(IsolationScope.USER, null, AGENT_ID); + assertFalse(key.isPresent()); + } + + @Test + void agentScope_alwaysResolvesToAgentId() { + Optional keyWithCtx = + SandboxIsolationKey.resolve( + IsolationScope.AGENT, RuntimeContext.builder().build(), AGENT_ID); + Optional keyNullCtx = + SandboxIsolationKey.resolve(IsolationScope.AGENT, null, AGENT_ID); + + assertTrue(keyWithCtx.isPresent()); + assertEquals(IsolationScope.AGENT, keyWithCtx.get().getScope()); + assertEquals(AGENT_ID, keyWithCtx.get().getValue()); + + assertTrue(keyNullCtx.isPresent()); + assertEquals(AGENT_ID, keyNullCtx.get().getValue()); + } + + @Test + void globalScope_alwaysResolvesToGlobalValue() { + Optional key = + SandboxIsolationKey.resolve(IsolationScope.GLOBAL, null, AGENT_ID); + assertTrue(key.isPresent()); + assertEquals(IsolationScope.GLOBAL, key.get().getScope()); + assertEquals(SandboxIsolationKey.GLOBAL_VALUE, key.get().getValue()); + } + + @Test + void equalsAndHashCode_sameValues_areEqual() { + RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("s1")).build(); + Optional k1 = + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + Optional k2 = + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + assertTrue(k1.isPresent() && k2.isPresent()); + assertEquals(k1.get(), k2.get()); + assertEquals(k1.get().hashCode(), k2.get().hashCode()); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java new file mode 100644 index 000000000..8171b1c2b --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java @@ -0,0 +1,253 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class SandboxManagerIsolationTest { + + private static final String AGENT_ID = "test-agent"; + private static final String STATE_JSON = "{\"sessionId\":\"s42\"}"; + + @Mock SandboxClient client; + @Mock SandboxStateStore stateStore; + @Mock Sandbox freshSandbox; + @Mock Sandbox resumedSandbox; + @Mock Sandbox externalSandbox; + @Mock SandboxState externalState; + @Mock SandboxState resumedState; + @Mock SandboxSnapshotSpec snapshotSpec; + + SandboxManager manager; + + @BeforeEach + void setUp() { + manager = new SandboxManager(client, stateStore, AGENT_ID); + } + + // ---- Priority 1: developer-owned external session ---- + + @Test + void priority1_externalSession_usedDirectly() throws Exception { + SandboxContext ctx = SandboxContext.builder().externalSandbox(externalSandbox).build(); + + SandboxAcquireResult result = manager.acquire(ctx, null); + + assertSame(externalSandbox, result.getSandbox()); + assertEquals(false, result.isSdkOwned()); + verify(stateStore, never()).load(any()); + } + + // ---- Priority 2: explicit session state ---- + + @Test + void priority2_externalSessionState_resumedDirectly() throws Exception { + when(externalState.getSessionId()).thenReturn("explicit-id"); + when(client.resume(externalState)).thenReturn(resumedSandbox); + + SandboxContext ctx = SandboxContext.builder().externalSandboxState(externalState).build(); + + SandboxAcquireResult result = manager.acquire(ctx, null); + + assertSame(resumedSandbox, result.getSandbox()); + assertEquals(true, result.isSdkOwned()); + verify(stateStore, never()).load(any()); + } + + // ---- Priority 3: state store hit (session scope) ---- + + @Test + void priority3_stateStoreHit_resumesSession() throws Exception { + when(stateStore.load(any())).thenReturn(Optional.of(STATE_JSON)); + when(client.deserializeState(STATE_JSON)).thenReturn(resumedState); + when(client.resume(resumedState)).thenReturn(resumedSandbox); + + RuntimeContext rtx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-1")).build(); + SandboxContext sCtx = + SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); + + SandboxAcquireResult result = manager.acquire(sCtx, rtx); + + assertSame(resumedSandbox, result.getSandbox()); + assertEquals(true, result.isSdkOwned()); + verify(client, never()).create(any(), any(), any()); + } + + // ---- Priority 3: state store miss → Priority 4 fresh create ---- + + @Test + void priority3_stateStoreMiss_createsFreshSession() throws Exception { + when(stateStore.load(any())).thenReturn(Optional.empty()); + when(client.create(any(), any(), any())).thenReturn(freshSandbox); + + RuntimeContext rtx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-2")).build(); + SandboxContext sCtx = + SandboxContext.builder() + .isolationScope(IsolationScope.SESSION) + .snapshotSpec(snapshotSpec) + .build(); + + SandboxAcquireResult result = manager.acquire(sCtx, rtx); + + assertSame(freshSandbox, result.getSandbox()); + verify(client).create(any(), any(), any()); + } + + // ---- Priority 4 (no session key → scope key empty → fresh create) ---- + + @Test + void noScopeKey_createsFreshSession() throws Exception { + when(client.create(any(), any(), any())).thenReturn(freshSandbox); + + RuntimeContext rtx = RuntimeContext.builder().build(); // no sessionKey + SandboxContext sCtx = SandboxContext.builder().build(); // scope = SESSION (default) + + SandboxAcquireResult result = manager.acquire(sCtx, rtx); + + assertSame(freshSandbox, result.getSandbox()); + verify(stateStore, never()).load(any()); + } + + // ---- USER scope ---- + + @Test + void userScope_withUserId_loadsFromStore() throws Exception { + when(stateStore.load(any())).thenReturn(Optional.of(STATE_JSON)); + when(client.deserializeState(STATE_JSON)).thenReturn(resumedState); + when(client.resume(resumedState)).thenReturn(resumedSandbox); + + RuntimeContext rtx = RuntimeContext.builder().userId("user-42").build(); + SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); + + SandboxAcquireResult result = manager.acquire(sCtx, rtx); + + assertSame(resumedSandbox, result.getSandbox()); + } + + @Test + void userScope_missingUserId_createsFreshSession() throws Exception { + when(client.create(any(), any(), any())).thenReturn(freshSandbox); + + RuntimeContext rtx = RuntimeContext.builder().build(); // no userId + SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); + + SandboxAcquireResult result = manager.acquire(sCtx, rtx); + + assertSame(freshSandbox, result.getSandbox()); + verify(stateStore, never()).load(any()); + } + + // ---- AGENT scope ---- + + @Test + void agentScope_alwaysHasScopeKey() throws Exception { + when(stateStore.load(any())).thenReturn(Optional.empty()); + when(client.create(any(), any(), any())).thenReturn(freshSandbox); + + SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.AGENT).build(); + + SandboxAcquireResult result = manager.acquire(sCtx, null); + + assertNotNull(result.getSandbox()); + verify(stateStore).load(any()); // scope key resolved; store was queried + } + + // ---- GLOBAL scope ---- + + @Test + void globalScope_alwaysHasScopeKey() throws Exception { + when(stateStore.load(any())).thenReturn(Optional.empty()); + when(client.create(any(), any(), any())).thenReturn(freshSandbox); + + SandboxContext sCtx = + SandboxContext.builder().isolationScope(IsolationScope.GLOBAL).build(); + + SandboxAcquireResult result = manager.acquire(sCtx, null); + + assertNotNull(result.getSandbox()); + verify(stateStore).load(any()); + } + + // ---- persistState ---- + + @Test + void persistState_savesJsonForResolvedScopeKey() throws Exception { + SandboxState state = mock(SandboxState.class); + when(state.getSessionId()).thenReturn("sid"); + Sandbox sandbox = mock(Sandbox.class); + when(sandbox.getState()).thenReturn(state); + when(client.serializeState(state)).thenReturn(STATE_JSON); + SandboxAcquireResult result = SandboxAcquireResult.sdkOwned(sandbox); + + RuntimeContext rtx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-p")).build(); + SandboxContext sCtx = + SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); + + manager.persistState(result, sCtx, rtx); + + verify(stateStore).save(any(), any()); + } + + @Test + void persistState_missingScopeKey_skipped() throws Exception { + Sandbox sandbox = mock(Sandbox.class); + when(sandbox.getState()).thenReturn(mock(SandboxState.class)); + SandboxAcquireResult result = SandboxAcquireResult.sdkOwned(sandbox); + + RuntimeContext rtx = RuntimeContext.builder().build(); // no session key + SandboxContext sCtx = SandboxContext.builder().build(); // SESSION scope by default + + manager.persistState(result, sCtx, rtx); + + verify(stateStore, never()).save(any(), any()); + } + + // ---- clearState ---- + + @Test + void clearState_deletesFromStore() throws Exception { + RuntimeContext rtx = + RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-c")).build(); + SandboxContext sCtx = + SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); + + manager.clearState(sCtx, rtx); + + verify(stateStore).delete(any()); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java new file mode 100644 index 000000000..abfab74b3 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.session.InMemorySession; +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class SessionSandboxStateStoreTest { + + private static final String AGENT_ID = "test-agent"; + private static final String JSON = "{\"sessionId\":\"s-1\"}"; + + private SessionSandboxStateStore store; + + @BeforeEach + void setUp() { + store = new SessionSandboxStateStore(new InMemorySession(), AGENT_ID); + } + + @Test + void sessionScope_roundTrip() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.SESSION, "sess-001"); + assertFalse(store.load(key).isPresent()); + + store.save(key, JSON); + assertEquals(JSON, store.load(key).orElseThrow()); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + @Test + void userScope_roundTrip() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.USER, "user-123"); + store.save(key, JSON); + assertEquals(JSON, store.load(key).orElseThrow()); + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + @Test + void agentAndGlobalScope_doNotInterfere() throws Exception { + SandboxIsolationKey agentKey = isolationKey(IsolationScope.AGENT, AGENT_ID); + SandboxIsolationKey globalKey = + isolationKey(IsolationScope.GLOBAL, SandboxIsolationKey.GLOBAL_VALUE); + + store.save(agentKey, "{\"scope\":\"agent\"}"); + store.save(globalKey, "{\"scope\":\"global\"}"); + + assertEquals("{\"scope\":\"agent\"}", store.load(agentKey).orElseThrow()); + assertEquals("{\"scope\":\"global\"}", store.load(globalKey).orElseThrow()); + } + + @Test + void deleteUsesTombstone_evenWhenSessionDeleteUnsupported() throws Exception { + SessionSandboxStateStore redisLikeStore = + new SessionSandboxStateStore(new NoDeleteSession(), AGENT_ID); + SandboxIsolationKey key = isolationKey(IsolationScope.SESSION, "sess-del"); + + redisLikeStore.save(key, JSON); + assertTrue(redisLikeStore.load(key).isPresent()); + + redisLikeStore.delete(key); + assertFalse(redisLikeStore.load(key).isPresent()); + } + + private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { + return SandboxIsolationKey.resolve(scope, runtimeContext(scope, value), AGENT_ID) + .orElseThrow(); + } + + private static RuntimeContext runtimeContext(IsolationScope scope, String value) { + RuntimeContext.Builder b = RuntimeContext.builder(); + if (scope == IsolationScope.SESSION) { + b.sessionKey(SimpleSessionKey.of(value)); + } else if (scope == IsolationScope.USER) { + b.userId(value); + } + return b.build(); + } + + /** Simulates sessions whose per-key delete is not implemented (default no-op). */ + private static final class NoDeleteSession extends InMemorySession { + @Override + public void delete(io.agentscope.core.state.SessionKey sessionKey, String key) { + // no-op + } + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplierTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplierTest.java new file mode 100644 index 000000000..759a37e0d --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceProjectionApplierTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import io.agentscope.harness.agent.sandbox.layout.WorkspaceProjectionEntry; +import java.io.ByteArrayInputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class WorkspaceProjectionApplierTest { + + @TempDir Path tempDir; + + @Test + void build_returnsNullWhenNoProjectionEntry() throws Exception { + WorkspaceSpec spec = new WorkspaceSpec(); + spec.getEntries().clear(); + assertNull(WorkspaceProjectionApplier.build(spec)); + } + + @Test + void build_producesDeterministicHashAndTar() throws Exception { + Path source = tempDir.resolve("source"); + Files.createDirectories(source.resolve("skills/java")); + Files.writeString(source.resolve("AGENTS.md"), "v1"); + Files.writeString(source.resolve("skills/java/SKILL.md"), "skill"); + Files.writeString(source.resolve("other.txt"), "ignored"); + + WorkspaceProjectionEntry projection = new WorkspaceProjectionEntry(); + projection.setSourceRoot(source.toString()); + projection.setIncludeRoots(java.util.List.of("AGENTS.md", "skills")); + + WorkspaceSpec spec = new WorkspaceSpec(); + spec.getEntries().put("__workspace_projection__", projection); + + WorkspaceProjectionApplier.ProjectionPayload p1 = WorkspaceProjectionApplier.build(spec); + WorkspaceProjectionApplier.ProjectionPayload p2 = WorkspaceProjectionApplier.build(spec); + assertNotNull(p1); + assertNotNull(p2); + assertEquals(p1.hash(), p2.hash()); + assertEquals(2, p1.fileCount()); + + Path dest = tempDir.resolve("dest"); + Files.createDirectories(dest); + WorkspaceArchiveExtractor.extractTarArchive(dest, new ByteArrayInputStream(p1.tarBytes())); + assertEquals("v1", Files.readString(dest.resolve("AGENTS.md"))); + assertEquals("skill", Files.readString(dest.resolve("skills/java/SKILL.md"))); + } + + @Test + void build_hashChangesWhenProjectedContentChanges() throws Exception { + Path source = tempDir.resolve("source2"); + Files.createDirectories(source); + Files.writeString(source.resolve("AGENTS.md"), "v1"); + + WorkspaceProjectionEntry projection = new WorkspaceProjectionEntry(); + projection.setSourceRoot(source.toString()); + projection.setIncludeRoots(java.util.List.of("AGENTS.md")); + + WorkspaceSpec spec = new WorkspaceSpec(); + spec.getEntries().put("__workspace_projection__", projection); + + WorkspaceProjectionApplier.ProjectionPayload p1 = WorkspaceProjectionApplier.build(spec); + Files.writeString(source.resolve("AGENTS.md"), "v2"); + WorkspaceProjectionApplier.ProjectionPayload p2 = WorkspaceProjectionApplier.build(spec); + + assertNotNull(p1); + assertNotNull(p2); + assertNotEquals(p1.hash(), p2.hash()); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java new file mode 100644 index 000000000..063e30c64 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java @@ -0,0 +1,234 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.harness.agent.IsolationScope; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class WorkspaceSandboxStateStoreTest { + + @TempDir Path workspace; + + private static final String AGENT_ID = "test-agent"; + private static final String JSON = "{\"sessionId\":\"s1\"}"; + + private WorkspaceSandboxStateStore store; + + @BeforeEach + void setUp() { + store = new WorkspaceSandboxStateStore(workspace, AGENT_ID); + } + + // ---- SESSION scope ---- + + @Test + void sessionScope_saveLoadDelete_roundTrip() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.SESSION, "sess-001"); + + assertFalse(store.load(key).isPresent()); + + store.save(key, JSON); + Optional loaded = store.load(key); + assertTrue(loaded.isPresent()); + assertEquals(JSON, loaded.get()); + + // Verify session-scoped state location + Path expected = + workspace + .resolve("agents") + .resolve(AGENT_ID) + .resolve("context") + .resolve("sess-001") + .resolve("_sandbox.json"); + assertTrue(Files.exists(expected)); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + // ---- USER scope ---- + + @Test + void userScope_saveLoadDelete_roundTrip() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.USER, "user-abc"); + + store.save(key, JSON); + Optional loaded = store.load(key); + assertTrue(loaded.isPresent()); + assertEquals(JSON, loaded.get()); + + Path expected = + workspace + .resolve("agents") + .resolve(AGENT_ID) + .resolve("sandboxes") + .resolve("user") + .resolve("user-abc.json"); + assertTrue(Files.exists(expected)); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + @Test + void userScope_unsafeCharacters_encodedInFilename() throws Exception { + String userId = "user@example.com/special"; + SandboxIsolationKey key = isolationKey(IsolationScope.USER, userId); + + store.save(key, JSON); + assertTrue(store.load(key).isPresent()); + + // Filename must not contain the raw special chars + Path userDir = + workspace.resolve("agents").resolve(AGENT_ID).resolve("sandboxes").resolve("user"); + boolean rawFileExists = Files.exists(userDir.resolve(userId + ".json")); + assertFalse(rawFileExists, "Raw unsafe filename should not exist"); + + // A Base64-encoded file should exist instead + long encodedFiles = Files.list(userDir).count(); + assertEquals(1, encodedFiles); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + // ---- AGENT scope ---- + + @Test + void agentScope_saveLoadDelete_roundTrip() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.AGENT, AGENT_ID); + + store.save(key, JSON); + Optional loaded = store.load(key); + assertTrue(loaded.isPresent()); + assertEquals(JSON, loaded.get()); + + Path expected = + workspace + .resolve("agents") + .resolve(AGENT_ID) + .resolve("sandboxes") + .resolve("agent.json"); + assertTrue(Files.exists(expected)); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + // ---- GLOBAL scope ---- + + @Test + void globalScope_saveLoadDelete_roundTrip() throws Exception { + SandboxIsolationKey key = + isolationKey(IsolationScope.GLOBAL, SandboxIsolationKey.GLOBAL_VALUE); + + store.save(key, JSON); + Optional loaded = store.load(key); + assertTrue(loaded.isPresent()); + assertEquals(JSON, loaded.get()); + + Path expected = workspace.resolve("sandboxes").resolve("global.json"); + assertTrue(Files.exists(expected)); + + store.delete(key); + assertFalse(store.load(key).isPresent()); + } + + @Test + void multipleScopes_doNotInterfere() throws Exception { + SandboxIsolationKey sessionKey = isolationKey(IsolationScope.SESSION, "sess-x"); + SandboxIsolationKey userKey = isolationKey(IsolationScope.USER, "user-x"); + SandboxIsolationKey agentKey = isolationKey(IsolationScope.AGENT, AGENT_ID); + SandboxIsolationKey globalKey = + isolationKey(IsolationScope.GLOBAL, SandboxIsolationKey.GLOBAL_VALUE); + + store.save(sessionKey, "{\"scope\":\"session\"}"); + store.save(userKey, "{\"scope\":\"user\"}"); + store.save(agentKey, "{\"scope\":\"agent\"}"); + store.save(globalKey, "{\"scope\":\"global\"}"); + + assertEquals("{\"scope\":\"session\"}", store.load(sessionKey).orElseThrow()); + assertEquals("{\"scope\":\"user\"}", store.load(userKey).orElseThrow()); + assertEquals("{\"scope\":\"agent\"}", store.load(agentKey).orElseThrow()); + assertEquals("{\"scope\":\"global\"}", store.load(globalKey).orElseThrow()); + } + + @Test + void save_overwrites_existingValue() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.AGENT, AGENT_ID); + store.save(key, "{\"v\":1}"); + store.save(key, "{\"v\":2}"); + assertEquals("{\"v\":2}", store.load(key).orElseThrow()); + } + + @Test + void delete_nonExistent_isNoOp() throws Exception { + SandboxIsolationKey key = isolationKey(IsolationScope.USER, "nobody"); + // Should not throw + store.delete(key); + } + + @Test + void sessionScope_usesDirectFileIo() throws Exception { + WorkspaceSandboxStateStore storeNoSession = + new WorkspaceSandboxStateStore(workspace, AGENT_ID); + SandboxIsolationKey key = isolationKey(IsolationScope.SESSION, "sess-direct"); + + storeNoSession.save(key, JSON); + Optional loaded = storeNoSession.load(key); + assertTrue(loaded.isPresent()); + assertEquals(JSON, loaded.get()); + + storeNoSession.delete(key); + assertFalse(storeNoSession.load(key).isPresent()); + } + + // ---- helpers ---- + + private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { + return SandboxIsolationKey.resolve( + scope, + buildCtxForScope(scope, value), + value.startsWith("user") || scope == IsolationScope.GLOBAL + ? "test-agent" + : value) + .orElseThrow(() -> new IllegalStateException("Key could not be resolved")); + } + + private static io.agentscope.harness.agent.RuntimeContext buildCtxForScope( + IsolationScope scope, String value) { + io.agentscope.harness.agent.RuntimeContext.Builder b = + io.agentscope.harness.agent.RuntimeContext.builder(); + switch (scope) { + case SESSION -> b.sessionKey(SimpleSessionKey.of(value)); + case USER -> b.userId(value); + default -> { + /* AGENT and GLOBAL do not need context fields */ + } + } + return b.build(); + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClientsTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClientsTest.java new file mode 100644 index 000000000..1f635ef53 --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/snapshot/RemoteSnapshotClientsTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent.sandbox.snapshot; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.model.OSSObject; +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.Test; +import redis.clients.jedis.UnifiedJedis; + +class RemoteSnapshotClientsTest { + + @Test + void ossClient_uploadDownloadExists() throws Exception { + OSS oss = mock(OSS.class); + OSSObject object = new OSSObject(); + object.setObjectContent( + new ByteArrayInputStream("payload".getBytes(StandardCharsets.UTF_8))); + when(oss.doesObjectExist("bucket", "prefix/s1.tar")).thenReturn(true); + when(oss.getObject("bucket", "prefix/s1.tar")).thenReturn(object); + + OssRemoteSnapshotClient client = new OssRemoteSnapshotClient(oss, "bucket", "prefix"); + client.upload("s1", new ByteArrayInputStream("payload".getBytes(StandardCharsets.UTF_8))); + assertEquals(true, client.exists("s1")); + String downloaded = + new String(client.download("s1").readAllBytes(), StandardCharsets.UTF_8); + assertEquals("payload", downloaded); + + verify(oss).putObject(eq("bucket"), eq("prefix/s1.tar"), any(InputStream.class)); + } + + @Test + void redisClient_uploadDownloadWithTtl() throws Exception { + UnifiedJedis jedis = mock(UnifiedJedis.class); + byte[] data = "data".getBytes(StandardCharsets.UTF_8); + when(jedis.get(any(byte[].class))).thenReturn(data); + when(jedis.exists(any(byte[].class))).thenReturn(true); + + RedisRemoteSnapshotClient client = new RedisRemoteSnapshotClient(jedis, "snap", 60); + client.upload("s1", new ByteArrayInputStream(data)); + + verify(jedis).set(any(byte[].class), eq(data)); + verify(jedis).expire(any(byte[].class), eq(60L)); + + assertEquals( + "data", new String(client.download("s1").readAllBytes(), StandardCharsets.UTF_8)); + assertEquals(true, client.exists("s1")); + } + + @Test + void redisClient_downloadMissing_throws() throws Exception { + UnifiedJedis jedis = mock(UnifiedJedis.class); + when(jedis.get(any(byte[].class))).thenReturn(null); + + RedisRemoteSnapshotClient client = new RedisRemoteSnapshotClient(jedis, null, null); + assertThrows(FileNotFoundException.class, () -> client.download("missing")); + } +} diff --git a/pom.xml b/pom.xml index 6c9ff0eaf..2a161edf8 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ AgentScope Java - Parent - 1.0.12-SNAPSHOT + 1.0.12-harness-SNAPSHOT UTF-8 UTF-8 17 From 338dddaebe3da9498064ae691a53b03e81a88ba4 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 00:46:22 +0800 Subject: [PATCH 05/28] add runtime context support to ReActAgent --- .../java/io/agentscope/core/ReActAgent.java | 73 +- .../io/agentscope/core/agent/AgentBase.java | 143 ++- .../agentscope/core/agent/RuntimeContext.java | 360 ++++++++ .../core/hook/RuntimeContextAware.java | 39 + .../core/tool/ToolMethodInvoker.java | 5 + .../agent/ReActAgentRuntimeContextTest.java | 213 +++++ .../core/agent/RuntimeContextTest.java | 146 ++++ .../memory-distribution-design-notes.md | 313 +++++++ agentscope-harness/sandbox-design.md | 105 +++ .../sandbox-filesystem-api-design.md | 179 ++++ .../sandbox-implementation-plan.md | 811 ++++++++++++++++++ .../sandbox-implementation-status.md | 231 +++++ .../harness/agent/HarnessAgent.java | 53 +- .../harness/agent/RuntimeContext.java | 86 +- .../harness/agent/hook/CompactionHook.java | 25 +- .../harness/agent/hook/MemoryFlushHook.java | 6 +- .../agent/hook/RuntimeContextAwareHook.java | 12 +- .../agent/hook/SandboxLifecycleHook.java | 16 +- .../agent/hook/SessionPersistenceHook.java | 10 +- .../agent/hook/WorkspaceContextHook.java | 6 +- .../agent/sandbox/SandboxIsolationKey.java | 2 +- .../harness/agent/sandbox/SandboxManager.java | 2 +- .../HarnessAgentIntegrationExampleTest.java | 23 +- ...oxFilesystemIsolationScopeExampleTest.java | 8 +- .../sandbox/SandboxIsolationKeyTest.java | 18 +- .../sandbox/SandboxManagerIsolationTest.java | 16 +- .../sandbox/SessionSandboxStateStoreTest.java | 2 +- .../WorkspaceSandboxStateStoreTest.java | 2 +- 28 files changed, 2710 insertions(+), 195 deletions(-) create mode 100644 agentscope-core/src/main/java/io/agentscope/core/agent/RuntimeContext.java create mode 100644 agentscope-core/src/main/java/io/agentscope/core/hook/RuntimeContextAware.java create mode 100644 agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentRuntimeContextTest.java create mode 100644 agentscope-core/src/test/java/io/agentscope/core/agent/RuntimeContextTest.java create mode 100644 agentscope-harness/memory-distribution-design-notes.md create mode 100644 agentscope-harness/sandbox-design.md create mode 100644 agentscope-harness/sandbox-filesystem-api-design.md create mode 100644 agentscope-harness/sandbox-implementation-plan.md create mode 100644 agentscope-harness/sandbox-implementation-status.md diff --git a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java index bbf114e0f..0e7513615 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java @@ -15,6 +15,10 @@ */ package io.agentscope.core; +import com.fasterxml.jackson.databind.JsonNode; +import io.agentscope.core.agent.Event; +import io.agentscope.core.agent.RuntimeContext; +import io.agentscope.core.agent.StreamOptions; import io.agentscope.core.agent.StructuredOutputCapableAgent; import io.agentscope.core.agent.accumulator.ReasoningContext; import io.agentscope.core.hook.ActingChunkEvent; @@ -151,6 +155,7 @@ public class ReActAgent extends StructuredOutputCapableAgent { private final PlanNotebook planNotebook; private final ToolExecutionContext toolExecutionContext; private final StatePersistence statePersistence; + private RuntimeContext pendingRuntimeContext; // ==================== Constructor ==================== @@ -178,6 +183,72 @@ private ReActAgent(Builder builder, Toolkit agentToolkit) { : StatePersistence.all(); } + // ==================== RuntimeContext ==================== + + @Override + protected void beforeAgentExecution(List msgs) { + RuntimeContext ctx = this.pendingRuntimeContext; + this.pendingRuntimeContext = null; + if (ctx == null) { + ctx = RuntimeContext.empty(); + } + bindRuntimeContextToHooks(ctx); + } + + @Override + protected void afterAgentExecution() { + unbindRuntimeContextFromHooks(); + } + + private ToolExecutionContext buildMergedToolContext() { + RuntimeContext run = getRuntimeContext(); + if (run == null) { + return toolExecutionContext != null + ? toolExecutionContext + : ToolExecutionContext.empty(); + } + return ToolExecutionContext.merge(run.asToolExecutionContext(), toolExecutionContext); + } + + /** + * Calls the agent with a per-call {@link RuntimeContext} (metadata for hooks and tools, not + * persisted). + */ + public Mono call(List msgs, RuntimeContext context) { + this.pendingRuntimeContext = context; + return call(msgs); + } + + public Mono call(List msgs, Class structuredOutputClass, RuntimeContext context) { + this.pendingRuntimeContext = context; + return call(msgs, structuredOutputClass); + } + + public Mono call(List msgs, JsonNode outputSchema, RuntimeContext context) { + this.pendingRuntimeContext = context; + return call(msgs, outputSchema); + } + + public Flux stream(List msgs, StreamOptions options, RuntimeContext context) { + this.pendingRuntimeContext = context; + return stream(msgs, options); + } + + public Flux stream( + List msgs, + StreamOptions options, + Class structuredModel, + RuntimeContext context) { + this.pendingRuntimeContext = context; + return stream(msgs, options, structuredModel); + } + + public Flux stream( + List msgs, StreamOptions options, JsonNode schema, RuntimeContext context) { + this.pendingRuntimeContext = context; + return stream(msgs, options, schema); + } + // ==================== New StateModule API ==================== /** @@ -665,7 +736,7 @@ private Msg buildSuspendedMsg(List> pen */ private Mono>> executeToolCalls( List toolCalls) { - return toolkit.callTools(toolCalls, toolExecutionConfig, this, toolExecutionContext) + return toolkit.callTools(toolCalls, toolExecutionConfig, this, buildMergedToolContext()) .map( results -> IntStream.range(0, toolCalls.size()) diff --git a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java index a6ea34deb..a1c568c68 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java +++ b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java @@ -20,6 +20,7 @@ import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.PostCallEvent; import io.agentscope.core.hook.PreCallEvent; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.interruption.InterruptContext; import io.agentscope.core.interruption.InterruptSource; import io.agentscope.core.message.Msg; @@ -108,6 +109,10 @@ public abstract class AgentBase implements StateModule, Agent { private final AtomicReference interruptSource = new AtomicReference<>(InterruptSource.USER); + private final CopyOnWriteArrayList runtimeContextAwareHooks = + new CopyOnWriteArrayList<>(); + private final AtomicReference currentRuntimeContext = new AtomicReference<>(); + /** * Constructor for AgentBase. * @@ -143,6 +148,9 @@ public AgentBase(String name, String description, boolean checkRunning, List(hooks != null ? hooks : List.of()); this.hooks.addAll(systemHooks); sortHooks(); + for (Hook h : this.hooks) { + registerRuntimeContextHookIfNeeded(h); + } } @Override @@ -172,18 +180,20 @@ public final String getDescription() { public final Mono call(List msgs) { return Mono.using( this::acquireExecution, - resource -> - TracerRegistry.get() - .callAgent( - this, - msgs, - () -> - notifyPreCall(msgs) - .flatMap(this::doCall) - .flatMap(this::notifyPostCall) - .onErrorResume( - createErrorHandler( - msgs.toArray(new Msg[0])))), + resource -> { + beforeAgentExecution(msgs); + return TracerRegistry.get() + .callAgent( + this, + msgs, + () -> + notifyPreCall(msgs) + .flatMap(this::doCall) + .flatMap(this::notifyPostCall) + .onErrorResume( + createErrorHandler( + msgs.toArray(new Msg[0])))); + }, this::releaseExecution, true); } @@ -201,22 +211,20 @@ public final Mono call(List msgs) { public final Mono call(List msgs, Class structuredOutputClass) { return Mono.using( this::acquireExecution, - resource -> - TracerRegistry.get() - .callAgent( - this, - msgs, - () -> - notifyPreCall(msgs) - .flatMap( - m -> - doCall( - m, - structuredOutputClass)) - .flatMap(this::notifyPostCall) - .onErrorResume( - createErrorHandler( - msgs.toArray(new Msg[0])))), + resource -> { + beforeAgentExecution(msgs); + return TracerRegistry.get() + .callAgent( + this, + msgs, + () -> + notifyPreCall(msgs) + .flatMap(m -> doCall(m, structuredOutputClass)) + .flatMap(this::notifyPostCall) + .onErrorResume( + createErrorHandler( + msgs.toArray(new Msg[0])))); + }, this::releaseExecution, true); } @@ -234,18 +242,20 @@ public final Mono call(List msgs, Class structuredOutputClass) { public final Mono call(List msgs, JsonNode schema) { return Mono.using( this::acquireExecution, - resource -> - TracerRegistry.get() - .callAgent( - this, - msgs, - () -> - notifyPreCall(msgs) - .flatMap(m -> doCall(m, schema)) - .flatMap(this::notifyPostCall) - .onErrorResume( - createErrorHandler( - msgs.toArray(new Msg[0])))), + resource -> { + beforeAgentExecution(msgs); + return TracerRegistry.get() + .callAgent( + this, + msgs, + () -> + notifyPreCall(msgs) + .flatMap(m -> doCall(m, schema)) + .flatMap(this::notifyPostCall) + .onErrorResume( + createErrorHandler( + msgs.toArray(new Msg[0])))); + }, this::releaseExecution, true); } @@ -421,6 +431,7 @@ private AgentBase acquireExecution() { * @param resource the agent instance (ignored, uses {@code this}) */ private void releaseExecution(AgentBase resource) { + afterAgentExecution(); running.set(false); GracefulShutdownManager.getInstance().unregisterRequest(this); } @@ -500,6 +511,54 @@ protected Mono doObserve(Msg msg) { */ protected abstract Mono handleInterrupt(InterruptContext context, Msg... originalArgs); + /** + * Current per-call {@link RuntimeContext} when bound (e.g. by {@code ReActAgent} during a + * {@code call}). + */ + public RuntimeContext getRuntimeContext() { + return currentRuntimeContext.get(); + } + + /** + * Invoked at the start of a {@code call} / stream-backed call, after {@link + * #acquireExecution} and before any hooks. The default is a no-op. {@link + * io.agentscope.core.ReActAgent} uses this to bind a {@link RuntimeContext}. + */ + protected void beforeAgentExecution(List msgs) {} + + /** + * Invoked in {@code Mono.using} cleanup, before clearing the running state. Pairs with {@link + * #beforeAgentExecution(List)}. The default is a no-op. + */ + protected void afterAgentExecution() {} + + /** + * Binds {@code ctx} to the agent reference and all {@link RuntimeContextAware} hooks + * registered for this agent. + */ + protected void bindRuntimeContextToHooks(RuntimeContext ctx) { + currentRuntimeContext.set(ctx); + for (RuntimeContextAware h : runtimeContextAwareHooks) { + h.setRuntimeContext(ctx); + } + } + + /** + * Clears {@link #getRuntimeContext()} and nulls all {@link RuntimeContextAware} hooks. + */ + protected void unbindRuntimeContextFromHooks() { + for (RuntimeContextAware h : runtimeContextAwareHooks) { + h.setRuntimeContext(null); + } + currentRuntimeContext.set(null); + } + + private void registerRuntimeContextHookIfNeeded(Hook hook) { + if (hook instanceof RuntimeContextAware r && !runtimeContextAwareHooks.contains(r)) { + runtimeContextAwareHooks.add(r); + } + } + /** * Get the list of hooks for this agent. * Protected to allow subclasses to access hooks for custom notification logic. @@ -521,6 +580,7 @@ public List getHooks() { protected void addHook(Hook hook) { if (hook != null) { hooks.add(hook); + registerRuntimeContextHookIfNeeded(hook); sortHooks(); } } @@ -540,6 +600,9 @@ private void sortHooks() { protected void removeHook(Hook hook) { if (hook != null) { hooks.remove(hook); + if (hook instanceof RuntimeContextAware r) { + runtimeContextAwareHooks.remove(r); + } } } diff --git a/agentscope-core/src/main/java/io/agentscope/core/agent/RuntimeContext.java b/agentscope-core/src/main/java/io/agentscope/core/agent/RuntimeContext.java new file mode 100644 index 000000000..1d754815f --- /dev/null +++ b/agentscope-core/src/main/java/io/agentscope/core/agent/RuntimeContext.java @@ -0,0 +1,360 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.agent; + +import io.agentscope.core.session.Session; +import io.agentscope.core.state.SessionKey; +import io.agentscope.core.tool.ContextStore; +import io.agentscope.core.tool.ToolExecutionContext; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * Per-call metadata for an agent run: session-scoped fields plus a thread-safe attribute bag and + * an optional {@link ToolExecutionContext} (tool-POJO / DI layer). + * + *

Attributes are not persisted. Hooks and tools may read and update the same instance for the + * duration of a single {@code call}. + */ +public class RuntimeContext { + + private static final String TYPED_DEFAULT_KEY = ""; + + private final String sessionId; + private final String userId; + private final Session session; + private final SessionKey sessionKey; + + /** String-keyed extras (legacy and generic extension). */ + private final ConcurrentMap stringAttributes; + + /** + * Typed layer: class -> (key -> value). For singleton-typed access, use {@link + * #TYPED_DEFAULT_KEY}. + */ + private final ConcurrentMap, ConcurrentMap> typedAttributes; + + private final ToolExecutionContext toolExecutionContext; + + private RuntimeContext(Builder builder) { + this.sessionId = builder.sessionId; + this.userId = builder.userId; + this.session = builder.session; + this.sessionKey = builder.sessionKey; + this.stringAttributes = new ConcurrentHashMap<>(); + this.typedAttributes = new ConcurrentHashMap<>(); + this.toolExecutionContext = builder.toolExecutionContext; + if (builder.stringExtras != null) { + this.stringAttributes.putAll(builder.stringExtras); + } + for (Map.Entry, Object> e : builder.typedSingletons.entrySet()) { + if (e.getValue() == null) { + continue; + } + @SuppressWarnings("unchecked") + Class type = (Class) e.getKey(); + putValue(TYPED_DEFAULT_KEY, type, e.getValue()); + } + } + + /** + * Shallow, mutable empty context (null session fields, empty attribute maps, no tool context). + */ + public static RuntimeContext empty() { + return new Builder().build(); + } + + public String getSessionId() { + return sessionId; + } + + public String getUserId() { + return userId; + } + + public Session getSession() { + return session; + } + + public SessionKey getSessionKey() { + return sessionKey; + } + + /** + * Returns the tool execution context provided at build time, if any. + * + *

Does not include runtime attribute projections; use {@link #asToolExecutionContext()}. + */ + public ToolExecutionContext getToolExecutionContext() { + return toolExecutionContext; + } + + @SuppressWarnings("unchecked") + public T get(String key) { + if (key == null) { + return null; + } + return (T) stringAttributes.get(key); + } + + public void put(String key, Object value) { + if (key == null) { + return; + } + if (value == null) { + stringAttributes.remove(key); + } else { + stringAttributes.put(key, value); + } + } + + @SuppressWarnings("unchecked") + public T get(Class type) { + if (type == null) { + return null; + } + T v = getValue(TYPED_DEFAULT_KEY, type); + if (v != null) { + return v; + } + // Allow accessing this RuntimeContext itself + if (type == RuntimeContext.class) { + return (T) this; + } + return null; + } + + public void put(Class type, T value) { + if (type == null) { + return; + } + if (value == null) { + removeTyped(type, TYPED_DEFAULT_KEY); + } else { + putValue(TYPED_DEFAULT_KEY, type, value); + } + } + + @SuppressWarnings("unchecked") + public T get(String key, Class type) { + if (key == null || type == null) { + return null; + } + T v = getValue(key, type); + if (v != null) { + return v; + } + if (TYPED_DEFAULT_KEY.equals(key) && type == RuntimeContext.class) { + return (T) this; + } + return null; + } + + public void put(String key, Class type, T value) { + if (key == null || type == null) { + return; + } + if (value == null) { + removeTyped(type, key); + } else { + putValue(key, type, value); + } + } + + /** + * View of string-keyed attributes; mutating the returned map affects this context. + * + *

Typed {@link #get(Class)} values are not included; use type-based accessors. + */ + public Map getExtra() { + return stringAttributes; + } + + private void putValue(String key, Class type, Object value) { + typedAttributes.computeIfAbsent(type, k -> new ConcurrentHashMap<>()).put(key, value); + } + + private T getValue(String key, Class type) { + Map m = typedAttributes.get(type); + if (m == null) { + return null; + } + Object o = m.get(key); + if (o == null) { + return null; + } + return type.isInstance(o) ? type.cast(o) : null; + } + + private void removeTyped(Class type, String key) { + Map m = typedAttributes.get(type); + if (m == null) { + return; + } + m.remove(key); + if (m.isEmpty()) { + typedAttributes.remove(type); + } + } + + /** + * Merges this context's data into a {@link ToolExecutionContext} for tool invocations. + * + *

Order: this instance is registered and exposed first (highest priority in {@link + * ToolExecutionContext#merge}, then a {@link ContextStore} for typed and string attributes, + * then stores from the nested {@link #getToolExecutionContext()} (if any). + */ + public ToolExecutionContext asToolExecutionContext() { + ToolExecutionContext.Builder b = ToolExecutionContext.builder(); + b.addStore(new DefaultMutableContextStore(this)); + if (toolExecutionContext != null) { + for (ContextStore s : toolExecutionContext.getStores()) { + if (s != null) { + b.addStore(s); + } + } + } + return b.build(); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String sessionId; + private String userId; + private Session session; + private SessionKey sessionKey; + private Map stringExtras; + private final Map, Object> typedSingletons = new HashMap<>(); + private ToolExecutionContext toolExecutionContext; + + public Builder sessionId(String sessionId) { + this.sessionId = sessionId; + return this; + } + + public Builder userId(String userId) { + this.userId = userId; + return this; + } + + public Builder session(Session session) { + this.session = session; + return this; + } + + public Builder sessionKey(SessionKey sessionKey) { + this.sessionKey = sessionKey; + return this; + } + + public Builder put(String key, Object value) { + if (this.stringExtras == null) { + this.stringExtras = new ConcurrentHashMap<>(); + } + this.stringExtras.put(key, value); + return this; + } + + public Builder putAll(Map extras) { + if (extras == null || extras.isEmpty()) { + return this; + } + if (this.stringExtras == null) { + this.stringExtras = new ConcurrentHashMap<>(); + } + this.stringExtras.putAll(extras); + return this; + } + + public Builder put(Class type, T value) { + if (type != null) { + this.typedSingletons.put(type, value); + } + return this; + } + + /** + * Nests a {@link ToolExecutionContext} (e.g. agent builder-level tool DI) that will be + * visible at lower priority than runtime attributes in {@link #asToolExecutionContext()}. + */ + public Builder toolExecutionContext(ToolExecutionContext toolExecutionContext) { + this.toolExecutionContext = toolExecutionContext; + return this; + } + + public RuntimeContext build() { + return new RuntimeContext(this); + } + } + + /** + * Merged view of this {@link RuntimeContext} for the tool stack: first checks typed, then + * string map for legacy {@link #get(String)} keys, then defers to delegate stores. + */ + private static final class DefaultMutableContextStore implements ContextStore { + + private final RuntimeContext runtimeContext; + + private DefaultMutableContextStore(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + @Override + @SuppressWarnings("unchecked") + public T get(String key, Class type) { + T t = runtimeContext.getValue(key, type); + if (t != null) { + return t; + } + if (TYPED_DEFAULT_KEY.equals(key) && type == RuntimeContext.class) { + return (T) runtimeContext; + } + Object fromString = runtimeContext.stringAttributes.get(key); + if (type.isInstance(fromString)) { + return (T) fromString; + } + return null; + } + + @Override + @SuppressWarnings("unchecked") + public T get(Class type) { + T t = get(TYPED_DEFAULT_KEY, type); + if (t != null) { + return t; + } + if (type == RuntimeContext.class) { + return (T) runtimeContext; + } + return null; + } + + @Override + public boolean contains(String key, Class type) { + return get(key, type) != null; + } + + @Override + public boolean contains(Class type) { + return get(type) != null; + } + } +} diff --git a/agentscope-core/src/main/java/io/agentscope/core/hook/RuntimeContextAware.java b/agentscope-core/src/main/java/io/agentscope/core/hook/RuntimeContextAware.java new file mode 100644 index 000000000..e110f3f9d --- /dev/null +++ b/agentscope-core/src/main/java/io/agentscope/core/hook/RuntimeContextAware.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.hook; + +import io.agentscope.core.agent.RuntimeContext; + +/** + * Optional contract for {@link Hook} implementations that need the current + * per-call {@link RuntimeContext}. + * + *

During a {@code ReActAgent.call(msgs, ctx)} execution, the framework sets the context + * on all registered hooks that implement this interface, and clears it on completion. Hooks may + * cache the reference in a field, as the same {@link RuntimeContext} instance is mutably shared + * for cross-hook/tool coordination. + */ +@FunctionalInterface +public interface RuntimeContextAware { + + /** + * Injects the runtime context for the current call, or {@code null} when not executing or + * when clearing after a call. + * + * @param context current runtime context, or null + */ + void setRuntimeContext(RuntimeContext context); +} diff --git a/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java b/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java index 5da99f2d6..ea6634ced 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java +++ b/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java @@ -16,6 +16,7 @@ package io.agentscope.core.tool; import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.ContentBlock; import io.agentscope.core.message.Msg; import io.agentscope.core.message.ToolResultBlock; @@ -168,6 +169,10 @@ else if (param.getType() == Agent.class) { else if (param.getType() == ToolExecutionContext.class) { args[i] = context; } + // Per-call agent runtime (when merged into the execution context) + else if (param.getType() == RuntimeContext.class) { + args[i] = context != null ? context.get(RuntimeContext.class) : null; + } // User-defined POJO: try to resolve from context else if (isUserContextPojo(param)) { args[i] = resolveContextParameter(param, context); diff --git a/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentRuntimeContextTest.java b/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentRuntimeContextTest.java new file mode 100644 index 000000000..282eec790 --- /dev/null +++ b/agentscope-core/src/test/java/io/agentscope/core/agent/ReActAgentRuntimeContextTest.java @@ -0,0 +1,213 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.agent; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.test.MockModel; +import io.agentscope.core.agent.test.TestConstants; +import io.agentscope.core.agent.test.TestUtils; +import io.agentscope.core.hook.Hook; +import io.agentscope.core.hook.HookEvent; +import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.RuntimeContextAware; +import io.agentscope.core.memory.InMemoryMemory; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ToolResultBlock; +import io.agentscope.core.message.ToolUseBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.ChatUsage; +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.core.util.JsonUtils; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +@DisplayName("ReActAgent RuntimeContext") +class ReActAgentRuntimeContextTest { + + private static final class SharedPojo { + final String value; + + SharedPojo(String value) { + this.value = value; + } + } + + private static class CtxTools { + @Tool(description = "Read RuntimeContext in a tool call") + public String ctx_probe( + RuntimeContext ctx, @ToolParam(name = "q", description = "q") String q) { + SharedPojo p = ctx.get(SharedPojo.class); + return ctx.getUserId() + "|" + (p != null ? p.value : "null") + "|" + q; + } + } + + private InMemoryMemory memory; + private Toolkit toolkit; + + @BeforeEach + void setUp() { + memory = new InMemoryMemory(); + toolkit = new Toolkit(); + toolkit.registerTool(new CtxTools()); + } + + @Test + @DisplayName("RuntimeContextAware + tools see the same per-call context") + void awareHookAndToolContext() { + AtomicReference fromSetter = new AtomicReference<>(); + final int[] modelRound = {0}; + + Hook hook = new CtxHook(fromSetter); + MockModel model = + new MockModel( + messages -> { + if (modelRound[0]++ == 0) { + return List.of( + createToolResponse( + "ctx_probe", "c1", Map.of("q", "tool-q"))); + } + return List.of( + ChatResponse.builder() + .content( + List.of( + TextBlock.builder() + .text("final") + .build())) + .usage(new ChatUsage(1, 1, 0)) + .build()); + }); + + ReActAgent agent = + ReActAgent.builder() + .name(TestConstants.TEST_REACT_AGENT_NAME) + .sysPrompt(TestConstants.DEFAULT_SYS_PROMPT) + .model(model) + .toolkit(toolkit) + .memory(memory) + .hooks(List.of(hook)) + .build(); + + RuntimeContext run = + RuntimeContext.builder() + .userId("per-call-uid") + .put(SharedPojo.class, new SharedPojo("from-initial-put")) + .build(); + + Msg user = TestUtils.createUserMessage("User", "use ctx_probe"); + Msg out = + agent.call(List.of(user), run) + .block(Duration.ofMillis(TestConstants.DEFAULT_TEST_TIMEOUT_MS)); + + assertNotNull(out); + String toolOut = lastToolText(agent); + assertTrue( + toolOut.contains("per-call-uid|from-pre|tool-q"), + "unexpected tool output: " + toolOut); + + RuntimeContext r = fromSetter.get(); + assertNull(r, "unbind should clear setRuntimeContext(null)"); + + assertTrue( + memory.getMessages().stream() + .anyMatch(m -> m.hasContentBlocks(ToolResultBlock.class))); + } + + private static String lastToolText(ReActAgent agent) { + List list = new ArrayList<>(agent.getMemory().getMessages()); + Collections.reverse(list); + for (Msg m : list) { + if (m.getContent() == null) { + continue; + } + for (ContentBlock c : m.getContent()) { + if (c instanceof ToolResultBlock tr) { + for (ContentBlock o : tr.getOutput()) { + if (o instanceof TextBlock tb) { + return tb.getText(); + } + } + } + } + } + return ""; + } + + private static ChatResponse createToolResponse( + String name, String id, Map input) { + return ChatResponse.builder() + .content( + List.of( + ToolUseBlock.builder() + .name(name) + .id(id) + .input(input) + .content(JsonUtils.getJsonCodec().toJson(input)) + .build())) + .usage(new ChatUsage(1, 1, 0)) + .build(); + } + + private static final class CtxHook implements Hook, RuntimeContextAware { + private final AtomicReference fromSetter; + private final AtomicInteger preCount = new AtomicInteger(); + + CtxHook(AtomicReference fromSetter) { + this.fromSetter = fromSetter; + } + + @Override + public void setRuntimeContext(RuntimeContext ctx) { + fromSetter.set(ctx); + } + + @Override + public Mono onEvent(T event) { + if (event instanceof PreReasoningEvent) { + return Mono.defer( + () -> { + if (preCount.getAndIncrement() == 0) { + AgentBase a = (AgentBase) ((PreReasoningEvent) event).getAgent(); + RuntimeContext rc = a.getRuntimeContext(); + assertNotNull(rc); + assertEquals("per-call-uid", rc.getUserId()); + assertEquals("from-initial-put", rc.get(SharedPojo.class).value); + rc.put(SharedPojo.class, new SharedPojo("from-pre")); + } + return Mono.just(event); + }); + } + return Mono.just(event); + } + } +} diff --git a/agentscope-core/src/test/java/io/agentscope/core/agent/RuntimeContextTest.java b/agentscope-core/src/test/java/io/agentscope/core/agent/RuntimeContextTest.java new file mode 100644 index 000000000..89e338173 --- /dev/null +++ b/agentscope-core/src/test/java/io/agentscope/core/agent/RuntimeContextTest.java @@ -0,0 +1,146 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.agent; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; + +import io.agentscope.core.state.SimpleSessionKey; +import io.agentscope.core.tool.ToolExecutionContext; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("RuntimeContext") +class RuntimeContextTest { + + private static final class PojoA { + final String id; + + PojoA(String id) { + this.id = id; + } + } + + private static final class PojoB { + final int n; + + PojoB(int n) { + this.n = n; + } + } + + @Test + @DisplayName("empty() builds an empty, mutable context") + void empty_isMutable() { + RuntimeContext ctx = RuntimeContext.empty(); + assertNull(ctx.getSessionId()); + assertNull(ctx.getUserId()); + assertNull(ctx.getSessionKey()); + ctx.put("k", "v"); + assertEquals("v", ctx.get("k")); + } + + @Test + @DisplayName("builder sets session fields and string extras") + void builderSessionAndStringExtras() { + RuntimeContext ctx = + RuntimeContext.builder() + .sessionId("sid-1") + .userId("u-1") + .sessionKey(SimpleSessionKey.of("sk")) + .put("extra", 42) + .build(); + assertEquals("sid-1", ctx.getSessionId()); + assertEquals("u-1", ctx.getUserId()); + assertNotNull(ctx.getSessionKey()); + assertEquals(Integer.valueOf(42), ctx.get("extra")); + } + + @Test + @DisplayName("typed get/put and keyed typed access") + void typedAccess() { + PojoA a = new PojoA("a"); + RuntimeContext ctx = RuntimeContext.builder().put(PojoA.class, a).build(); + assertSame(a, ctx.get(PojoA.class)); + PojoB b0 = new PojoB(1); + PojoB b1 = new PojoB(2); + ctx.put("one", PojoB.class, b0); + ctx.put("two", PojoB.class, b1); + assertSame(b0, ctx.get("one", PojoB.class)); + assertSame(b1, ctx.get("two", PojoB.class)); + ctx.put(PojoA.class, null); + assertNull(ctx.get(PojoA.class)); + } + + @Test + @DisplayName("get(Class) for RuntimeContext returns the instance") + void selfTypedAccess() { + RuntimeContext ctx = RuntimeContext.empty(); + assertSame(ctx, ctx.get(RuntimeContext.class)); + assertSame(ctx, ctx.get("", RuntimeContext.class)); + } + + @Test + @DisplayName("asToolExecutionContext exposes typed values with higher priority than agent TEC") + void asToolExecutionContextMergePriority() { + PojoA fromRun = new PojoA("from-run"); + PojoA fromAgent = new PojoA("from-agent"); + RuntimeContext run = RuntimeContext.builder().put(PojoA.class, fromRun).build(); + ToolExecutionContext agent = + ToolExecutionContext.builder().register(PojoA.class, fromAgent).build(); + ToolExecutionContext merged = + ToolExecutionContext.merge(run.asToolExecutionContext(), agent); + assertSame(fromRun, merged.get(PojoA.class)); + } + + @Test + @DisplayName("concurrent puts on distinct keys from multiple threads") + void threadSafety() throws Exception { + RuntimeContext ctx = RuntimeContext.empty(); + int threads = 8; + int per = 200; + CyclicBarrier b = new CyclicBarrier(threads); + AtomicInteger ok = new AtomicInteger(); + Thread[] t = new Thread[threads]; + for (int i = 0; i < threads; i++) { + final int fi = i; + t[i] = + new Thread( + () -> { + try { + b.await(); + for (int j = 0; j < per; j++) { + String k = "k-" + fi + "-" + j; + ctx.put(k, k); + assertEquals(k, ctx.get(k)); + } + ok.incrementAndGet(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + t[i].start(); + } + for (Thread th : t) { + th.join(); + } + assertEquals(threads, ok.get()); + } +} diff --git a/agentscope-harness/memory-distribution-design-notes.md b/agentscope-harness/memory-distribution-design-notes.md new file mode 100644 index 000000000..8a5489fc8 --- /dev/null +++ b/agentscope-harness/memory-distribution-design-notes.md @@ -0,0 +1,313 @@ +# HarnessAgent 分布式记忆:现状审计 + OpenAI Agents SDK 对标 + 演进建议 + +> 本文是一份独立设计备忘,用于沉淀 sandbox / StoreFilesystem 两种模式下"分布式记忆"能力的**当前偏差点**、**对标 OpenAI Agents SDK 的核心差异**,以及**推荐的演进路径**,作为后续改造(`MemoryConsolidator`、`MemoryMaintenanceScheduler`、`MemoryIndex`、`SessionTree` 等)的锚点。 +> +> 本文不是实施 PR,不直接修改代码;目的是让后续每一次改动都有一个统一的参照物。 + +--- + +## 0. 名词 + +- **Agent workspace(本地 workspace)**:`HarnessAgent` 启动时在 host 机器上持有的工作目录(`workspaceManager.getWorkspace()`)。存放 `AGENTS.md`、`skills/`、`subagents/`、`knowledge/`、以及 `MEMORY.md`、`memory/*.md`、`agents//sessions/*.jsonl` 等。 +- **Sandbox workspace**:`SandboxSession` 内部维护的工作目录(Docker 容器内或 UnixLocal 下的隔离目录)。工具(shell、filesystem)在此执行。 +- **`AbstractFilesystem`**:HarnessAgent 统一的文件系统抽象。实现包括: + - `LocalFilesystem` / `LocalFilesystemWithShell`:直接操作 host 磁盘。 + - `SandboxBackedFilesystem`:把所有 I/O 代理到当前绑定的 `SandboxSession`。 + - `StoreFilesystem`:把 I/O 放到 `BaseStore`(可远端共享)。 + - `CompositeFilesystem`:按路径前缀路由到不同后端。 +- **Sandbox 模式**:`HarnessAgent.Builder` 配置 `SandboxFilesystemSpec`,走 `SandboxBackedFilesystem`。 +- **Store 模式**:`HarnessAgent.Builder` 配置 `StoreFilesystemSpec`,走 `CompositeFilesystem(local, store-routed paths)`。 +- **Local 模式**:两者都不配置,走纯 `LocalFilesystemWithShell`。 + +--- + +## 1. 问题陈述 + +HarnessAgent 支持两种"分布式部署下的记忆共享"形态: + +1. **Sandbox 模式**:多个 HarnessAgent 实例通过 `SandboxIsolationKey`(`SESSION / USER / AGENT / GLOBAL`)共享同一个 sandbox 实例,记忆文件存在 sandbox workspace 内。 +2. **Store 模式**:不使用 sandbox,通过 `CompositeFilesystem` 把 `MEMORY.md`、`memory/`、`agents//sessions/` 路由到 `StoreFilesystem`(底层 `BaseStore`,可以是 Redis、远端 K-V 等),多个实例读写同一个 Store namespace。 + +**核心症状**:这两种模式目前**都存在相同的共性问题**——多个与 memory 相关的组件仍然绕过 `AbstractFilesystem`,直接用 `java.nio.file.Files.*` 操作 host 磁盘,导致它们只能看到 host 本地那一份视图,而看不到 sandbox 内 / Store 内的权威内容。 + +--- + +## 2. 现状审计(两种模式各自的受损点) + +> 判定标准:**数据权威位置(authoritative store)** vs **组件实际访问位置**。凡是不一致的都标记为坏。 + +### 2.1 Sandbox 模式 + +| 组件 | 数据权威位置 | 组件实际访问 | 影响 | +|---|---|---|---| +| `FilesystemTool` 读写 | sandbox workspace | 走 `SandboxBackedFilesystem` ✅ | 正确 | +| `ShellExecuteTool` | sandbox workspace | 走 sandbox session.exec ✅ | 正确 | +| `SessionTree.flush`(dual-write) | sandbox workspace + local 磁盘 | 本地 `Files.write` + `filesystem.write` mirror ✅ | 正确 | +| `SessionTree.load/syncFromLog`(restore) | sandbox workspace | 本地不存在时从 filesystem 拉 ✅ | 正确 | +| `MemoryConsolidator.readDailyEntries` | **sandbox workspace** | `Files.list(workspace/memory)` 本地 ❌ | 读不到 daily ledger,永远不触发合并 | +| `MemoryConsolidator` watermark (`memory/.consolidation_state`) | 应随 daily ledger 权威一致 | `Files.readString/writeString` 本地 ❌ | 多实例状态漂移;单机也错配 | +| `MemoryConsolidator.writeMemoryMd` | sandbox workspace | 已改走 `workspaceManager.writeUtf8WorkspaceRelative` ✅ | 正确(但由于上游读不到,不会被触发) | +| `MemoryMaintenanceScheduler.archiveOldDailyFiles` | sandbox workspace | `Files.list/move` 本地 ❌ | 扫不到任何文件,归档失效 | +| `MemoryMaintenanceScheduler.cleanupOldSessions` | sandbox workspace(Session dual-write 另有本地副本) | `Files.list/delete` 本地 ❌ | 只清本地副本,sandbox 内永不清理 | +| `MemoryIndex.indexAllFromWorkspace`(启动全量) | sandbox workspace | `Files.walk(workspace/memory)` 本地 ❌ | 启动索引为空 | +| `MemoryIndex.indexFromString`(增量) | sandbox workspace | 由 `readManagedWorkspaceFileUtf8` → filesystem ✅ | 运行时增量可用 | +| `SessionSearchTool` | sandbox workspace | SessionTree dual-write 保留了本地副本,扫本地 ⚠️ | 可用但靠副作用 | +| `SessionPersistenceHook` / `WorkspaceSession` `_sandbox.json` 等 | 本机专属 resume 状态 | `Files.*` 本地 ✅ | 设计如此(per-instance resume 元数据,暂不共享) | + +**结论**:sandbox 模式下,**工具链路径**(FilesystemTool/ShellTool)正确,**SessionTree 因 dual-write 也能工作**,但**long-term memory 管理管线(consolidation / archive / cleanup / 启动索引)全线失效**。 + +### 2.2 Store 模式(`StoreFilesystemSpec`) + +| 组件 | 数据权威位置 | 组件实际访问 | 影响 | +|---|---|---|---| +| `FilesystemTool` 读写 `memory/**`、`MEMORY.md`、`agents//sessions/**` | `StoreFilesystem` | CompositeFilesystem 路由到 `StoreFilesystem` ✅ | 正确 | +| `FilesystemTool` 读写其他路径 | local 磁盘 | CompositeFilesystem 默认走 LocalFilesystem ✅ | 正确 | +| `ShellExecuteTool` | local 磁盘 | local `ProcessBuilder` ✅ | 设计如此(shell 只能操作 host) | +| `MemoryFlushManager.appendDaily` | Store | `workspaceManager.appendUtf8WorkspaceRelative` → filesystem → Store ✅ | 正确 | +| `MemoryConsolidator.readDailyEntries` | **Store** | `Files.list(workspace/memory)` 本地 ❌ | 本地为空,读不到 daily | +| `MemoryConsolidator` watermark | 应随 Store 中的 daily 权威 | `Files.*` 本地 ❌ | 多实例各写各的,跨实例不一致 | +| `MemoryConsolidator.writeMemoryMd` | Store | `workspaceManager.writeUtf8WorkspaceRelative` → Store ✅ | 正确但上游读不到,永不触发 | +| `MemoryMaintenanceScheduler.archiveOldDailyFiles` | Store | `Files.list/move` 本地 ❌ | 归档完全无法工作,Store 内 daily 无限累积 | +| `MemoryMaintenanceScheduler.cleanupOldSessions` | Store + 本地 dual-write | `Files.list/delete` 本地 ⚠️ | 只删本地副本,Store 内 session jsonl 无限累积 | +| `MemoryIndex.indexAllFromWorkspace`(启动) | Store | `Files.walk` 本地 ❌ | 启动索引空 | +| `MemoryIndex.indexFromString`(增量) | Store | `readManagedWorkspaceFileUtf8` → filesystem → Store ✅ | 运行时增量可用 | +| `SessionSearchTool` | Store + 本地 dual-write | 扫本地 ✅ | 可用(靠 dual-write 副本) | +| `SessionPersistenceHook` / `WorkspaceSession` | per-instance | `Files.*` 本地 ✅ | 设计如此 | + +**结论**:Store 模式下的症状**与 sandbox 模式完全一致**——long-term memory 管理管线同样失效。 +而且**问题更严重**,因为 Store 模式存在的全部价值就是"多实例共享权威记忆";consolidator / scheduler / 全量索引失效意味着核心承诺落空。 + +### 2.3 两个模式的症状差异(仅有的几点) + +| 维度 | Sandbox 模式 | Store 模式 | +|---|---|---| +| 写冲突 | 同 `SandboxIsolationKey` 内串行 resume 保护,冲突极少 | 多实例真实并发读写同一 Store namespace;`MEMORY.md` 等单文件在 last-writer-wins 下冲突概率高 | +| 本地 dual-write 副本存在性 | SessionTree 有、memory/* 无 | SessionTree 有、memory/* 无 | +| `MemoryIndex` SQLite 文件 | per-instance 本地,与 sandbox 权威不同源 | per-instance 本地,与 Store 权威不同源 | + +--- + +## 3. 根因 + +> **凡是绕开 `AbstractFilesystem` 直接使用 `java.nio.file.Files.*` 的代码,都看不到"被路由走"的那部分内容。** + +- 在 sandbox 模式下,被路由走的是整个 sandbox workspace(`SandboxBackedFilesystem` 背后)。 +- 在 Store 模式下,被路由走的是 `memory/` / `MEMORY.md` / `agents//sessions/`(`StoreFilesystem` 背后)。 +- Local 模式不受影响,因为此时 `AbstractFilesystem` 的默认后端就是 host 磁盘,直连 `Files.*` 与走 fs 结果一致。 + +所以**两个模式是同一个病**,只不过站在不同 backend 角度暴露出来。修一次,两边同时治愈。 + +--- + +## 4. 对标:OpenAI Agents Python SDK 的做法 + +> 参考目录:`references/openai-agents-python/src/agents/sandbox/`,特别是 `memory/storage.py`、`memory/manager.py`、`memory/phase_one.py`、`memory/phase_two.py`、`capabilities/memory.py`、`runtime.py`、`runtime_session_manager.py`。 + +### 4.1 他们的七个关键选择 + +1. **Memory 必须依托 sandbox**。`Memory.required_capability_types()` 返回 `{"shell", "filesystem"}`;没有 sandbox 就没有 memory。**不存在"非 sandbox 记忆共享"这一问题**。 + +2. **只有一个 workspace**:sandbox workspace。`MemoryLayoutConfig.memories_dir` / `sessions_dir` 都是**相对路径**,`_validate_relative_path` 禁止绝对路径和 `..`。host 磁盘上不存在一份独立的"我的 memory"。 + +3. **所有 memory I/O 严格走 `BaseSandboxSession`**。`SandboxMemoryStorage` 是唯一网关: + + ```python + await self._session.mkdir(...) + await self._session.read(path) + await self._session.write(path, data) + await self._session.ls(path) + await self._session.exec("test", "-f", str(absolute), shell=False) + ``` + + `grep` 核对过 `sandbox/memory/` 下**没有**任何 `open()` / `.read_text()` / `os.path` 对 host 的真实 I/O。`pathlib.Path` 只用于构造相对路径字符串。 + +4. **跨 run 一致性不靠 sync,靠 "snapshot + session_state + live session" 三件套**: + - `SandboxRunConfig.session=`:直接复用活跃 session; + - `SandboxRunConfig.session_state=`:`client.resume(state)` 拉起等价 session; + - `SandboxRunConfig.snapshot=`:从快照克隆 workspace。 + + 分布式一致性下推到 **SandboxClient 后端**(或 RemoteSnapshot),**应用层不做文件同步**。 + +5. **Consolidation = 内嵌一个 LLM agent 在 sandbox 内跑**。`phase_two.py` 里: + + ```python + agent = SandboxAgent(name="sandbox-memory-phase-two", model=config.phase_two_model) + await Runner.run(agent, prompt, run_config=RunConfig(sandbox=SandboxRunConfig(session=self._session))) + ``` + + LLM 用 apply_patch / shell 工具直接改 `memories/MEMORY.md`。**"Java 代码该看哪个 fs"**这类问题在设计源头被消除——LLM 从 sandbox 内部视角看什么就改什么。 + +6. **生命周期绑定到 session pre-stop hook**: + + ```python + self._session.register_pre_stop_hook(self.flush) + ``` + + `flush` 跑 phase-1(每个 rollout 的提取)+ phase-2(一次性整合)。**没有独立的 cron scheduler**,没有"归档 daily files"的后台线程——需要的话交给 LLM 用 shell 做。 + +7. **没有 FTS / 本地 SQLite 索引**。Memory 在提示词注入阶段只读 `memories/memory_summary.md`(由 phase-2 维护,截到 15k tokens),直接注入 system prompt。细节检索交给 LLM 用 shell/grep/read 在 sandbox 内完成。 + +### 4.2 本质上他们做了哪三件事 + +- **单源(Single source of truth)**:workspace 只有一份,就是 sandbox 内那份。 +- **单网关(Single I/O gateway)**:memory I/O 统一走 `BaseSandboxSession`。 +- **职责下推**:合并、归档、检索这些"要全局视角"的任务,下推到一个在 sandbox 内部跑的 LLM agent,绕开了"Java 代码视角和权威数据视角不一致"的一整类问题。 + +--- + +## 5. 横向对比 + +| 维度 | OpenAI Agents SDK | HarnessAgent(现状) | +|---|---|---| +| Memory 是否强制 sandbox | 是 | 否(local / sandbox / store 三种) | +| Workspace 数量 | 1(sandbox) | 2(local + sandbox)或 路由视角下的逻辑 2(local + store) | +| Memory I/O 统一网关 | `BaseSandboxSession` | `AbstractFilesystem`(应该是,但 Memory 模块未严格遵守) | +| Consolidation 执行者 | sandbox 内的 LLM agent | Java 代码 `MemoryConsolidator`(直连 `Files.*`) | +| 归档/清理执行者 | 可选(LLM 在 sandbox 内用 shell) | Java `MemoryMaintenanceScheduler`(直连 `Files.*`) | +| 提示词索引 | `memory_summary.md`(LLM 维护) | SQLite FTS(`MemoryIndex`,本地维护,视图与权威脱节) | +| Watermark(合并进度) | 无(每次从 session.ls 推出) | 本地文件 `memory/.consolidation_state`(`Files.*`) | +| 跨 run 一致性 | snapshot + session_state resume(后端保证) | `SandboxStateStore` + `StoreFilesystem`(应用层保证) | +| 写冲突策略 | 同 session 内串行(后端约束) | Sandbox: `SandboxIsolationKey` 串行 resume;Store: last-writer-wins(默认) | +| 非 sandbox 记忆共享 | 不支持 | 支持(`StoreFilesystemSpec`) | + +--- + +## 6. 对 HarnessAgent 的启示 + +### 6.1 可以**直接借鉴**的设计纪律 + +1. **Memory I/O 只走 `AbstractFilesystem`,零例外**。`SandboxMemoryStorage` 是正面模板。把 `MemoryConsolidator / MemoryMaintenanceScheduler / MemoryIndex` 改造成仅调用 `AbstractFilesystem` 的能力(read/write/append/list/exists/delete/move),`java.nio.file.Files.*` 仅在 `LocalFilesystem` 实现内部出现。 + +2. **路径防御**:`AbstractFilesystem` 入口统一做 `_validate_relative_path` 等效校验——拒绝绝对路径、拒绝 `..`、拒绝空路径。避免外层代码把 host 绝对路径泄漏到 store/sandbox 后端。 + +3. **生命周期钩子化,取消独立 scheduler**。`MemoryMaintenanceScheduler` 的归档/清理动作应合并为: + - `PreCallEvent` / `PostCallEvent` / `RunnerShutdown` 上的同步任务,或 + - 作为 `SandboxLifecycleHook` 家族的 pre-stop / post-call 回调。 + + 效果上和 OpenAI 的 `register_pre_stop_hook(flush)` 对齐,不引入跨线程 race、不引入"何时扫描"这种外部时序变量。 + +### 6.2 值得借鉴但需要**本地化调整**的 + +4. **"LLM 做 consolidation"作为**可选实现**并存**。设计: + - `MemoryConsolidationPolicy` 接口; + - `RuleBasedConsolidationPolicy`:保留现有 Java 逻辑的"纯 fs 版本"(要求严格走 `AbstractFilesystem`),作为低成本、可回放的默认; + - `LlmConsolidationPolicy`:仿 `phase_two`——HarnessAgent 内部构造一个受限的子 Runner,复用同一个 `AbstractFilesystem`,用 apply_patch/filesystem 工具改 MEMORY.md。 + + 两种 policy 都只调用 `AbstractFilesystem`,互相可替换;用户按场景选择(成本 vs 智能度)。 + +5. **把 `MemoryIndex` 降级为"可选的加速器",主读路径换成 `memory_summary.md`**。 + - 主链路:启动/运行时把 `memory/memory_summary.md`(若存在)注入 system prompt(截 N tokens)。 + - 辅助工具:FTS 保留,作为显式 `SessionSearchTool` / `MemorySearchTool` 的后端。 + - 全量索引重建:不再在启动时做;改为**按需**(工具被调用时 lazy rebuild)或由 consolidation 后台再建。 + - 这样可以从**"启动时索引本地→和权威脱节"**的架构缺陷中走出来。 + +### 6.3 我们场景下**不能直接照抄**的 + +6. **OpenAI 强绑 sandbox 才有 memory**;我们要支持 `StoreFilesystemSpec`(无 sandbox 的分布式)。 + 对策:用 `AbstractFilesystem` **扮演他们 `BaseSandboxSession` 的角色**——只要所有 memory 代码都只和 `AbstractFilesystem` 对话,sandbox / Store / Local 三种后端在 memory 视角下是等价可替换的。 + +7. **OpenAI 的分布式一致性下推到 `SandboxClient` 后端**(`RemoteSnapshotSpec` 对齐多实例 workspace)。 + 我们的 Docker/UnixLocal 客户端没有天然跨机一致性,所以保留 `StoreFilesystem` 做"共享 K/V 后端"是对的。长期可以考虑: + - 用 Store 作为 `RemoteSnapshot` 的存储后端(把"sandbox workspace 快照"和"共享 memory 文件"统一到一个 Store); + - 或让 Docker client 支持从远端 registry 拉 workspace 快照,补齐"分布式一致性下推"。 + +--- + +## 7. 演进路径 + +> 所有阶段的共同大原则:**动刀点永远是"让 XX 组件只通过 `AbstractFilesystem` 访问 memory"**。 + +### Phase 1:收敛 `MemoryConsolidator`(最小闭环) + +- `readDailyEntries(watermark)`:换成 `filesystem.list("memory/")` + `filesystem.readString("memory/")`。 +- Watermark:从本地 `.consolidation_state` 文件搬到 filesystem 的 `memory/.consolidation_state`;读写也走 `AbstractFilesystem`。 +- `writeMemoryMd`:已改好,保留。 +- 验收:一次 run 的 daily 写入后,MEMORY.md 会被合并;sandbox 模式和 Store 模式都观察到同样结果。 + +### Phase 2:`AbstractFilesystem` API 扩展 + +- 新增 primitives:`delete(path)`、`move(src, dst)`、`walk(prefix)`(或 `listRecursive`)、`exists(path)`。 +- `LocalFilesystem` 实现用 `Files.*`;`SandboxBackedFilesystem` 用 session 的 `rm/mv/ls`;`StoreFilesystem` 用 Store key 层面的 `delete/scan`;`CompositeFilesystem` 按 prefix 路由。 +- 同步引入 `_validate_relative_path` 门禁。 + +### Phase 3:改造 `MemoryMaintenanceScheduler` & `MemoryIndex` + +- **Scheduler**:废弃独立线程,拆成两个 Hook: + - `MemoryArchiveHook`(`PostCallEvent`):归档 N 天前的 daily → `memory/archive/YYYY-MM/`。 + - `SessionCleanupHook`(`PostCallEvent` 或 `RunnerShutdown`):清理过期 session jsonl。 + - 全部走 `AbstractFilesystem.walk/move/delete`。 +- **MemoryIndex**: + - 取消启动时 `indexAllFromWorkspace`。 + - 主读路径改成 `filesystem.readString("memory/memory_summary.md")` 注入 system prompt(已有部分可复用)。 + - FTS 改为 lazy + 增量:第一次检索时从 filesystem 枚举一遍初建;后续由 flush 钩子增量维护。 + +### Phase 4:`SessionTree` 去 dual-write(可选) + +- 当前的 dual-write(本地 + mirror)是过渡期的正确选择(让 `SessionSearchTool` 继续能用)。 +- Phase 3 完成后,`SessionSearchTool` 可以改走 `filesystem.walk("agents//sessions/")`;dual-write 可以退化为"只走 filesystem 单写"。 +- 这会让 Store 模式下本地盘完全不保存 session 副本,契合"Store 是权威"的语义。 + +### Phase 5:LLM-based consolidation 与 `memory_summary.md`(可选,对标 OpenAI) + +- 引入 `MemoryConsolidationPolicy` 抽象;`RuleBasedConsolidationPolicy`(Phase 1 的 Java 实现)默认。 +- 可选注入 `LlmConsolidationPolicy`,内部用一个子 Runner + 受限工具,对 MEMORY.md / memory_summary.md 做基于 LLM 的整合。 +- 两种 policy 都只调用 `AbstractFilesystem`,保持单网关纪律。 + +### Phase 6:Resume state 的一致化(长线) + +- 把 `WorkspaceSandboxStateStore` 当前的 "_sandbox.json 本地文件" 形态抽象为 `SandboxStateStore` 接口 + 可插拔后端: + - `LocalFileSandboxStateStore`(现状); + - `StoreBackedSandboxStateStore`(复用 `BaseStore`); + - 未来可能的 DB backend。 +- 对齐 OpenAI 的"resume state as blob"模型:不是文件路径,而是 blob,调用方决定持久化位置。 + +--- + +## 8. 设计原则清单(落到代码守则) + +1. **Memory 领域的所有 I/O 只通过 `AbstractFilesystem`。** + 严格 code review:`agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/` 下禁止出现 `java.nio.file.Files.*` 直接调用(`LocalFilesystem` 实现本身除外)。 + +2. **相对路径 + 防御性校验。** + `AbstractFilesystem` 入口拒绝绝对路径、拒绝 `..`、拒绝空路径。 + +3. **状态文件(watermark 等)也是 memory 一部分,同样只走 `AbstractFilesystem`。** + `.consolidation_state` 不允许走本地磁盘。 + +4. **生命周期事件化。** + 归档/清理/consolidation 统一做 Hook,禁止独立 scheduler 线程(作为辅助加速器时可例外,但必须幂等、可关闭)。 + +5. **Consolidation policy 可替换。** + Java 规则与 LLM 驱动两种 policy 并存,接口只依赖 `AbstractFilesystem` + Runner。 + +6. **Sandbox / Store / Local 三种后端在 memory 视角下等价可替换。** + 任何 memory 组件不允许通过 `instanceof` 区分后端类型。 + +--- + +## 9. 验收建议 + +- 增补一个 `MemoryFilesystemComplianceTest`,用 ArchUnit/自定义规则禁止 memory 模块直接引用 `java.nio.file.Files`。 +- 增补一组"同一份输入在 Local/Sandbox/Store 三种模式下产生相同 MEMORY.md"的对比测试。 +- Phase 3 完成后,复跑现有 sandbox 模式下的 consolidation 场景,观察 MEMORY.md 是否按预期生成。 +- Store 模式下,起两个 HarnessAgent 实例并发写同一 namespace,观察 consolidation/归档是否收敛;记录 last-writer-wins 事件数,作为后续 CAS/锁优化的基线。 + +--- + +## 10. 附:关键对照表(一页速览) + +| 症状 | Sandbox 模式 | Store 模式 | 根因 | Phase | +|---|---|---|---|---| +| MEMORY.md 不自动合并 | ✅ 坏 | ✅ 坏 | `readDailyEntries` 直连本地 | 1 | +| Watermark 跨实例漂移 | ⚠️ 坏 | ✅ 坏 | watermark 直连本地 | 1 | +| 归档老 daily 不工作 | ✅ 坏 | ✅ 坏 | scheduler 直连本地 | 3 | +| 清理老 session 不彻底 | ⚠️ 半坏 | ⚠️ 半坏(Store 内残留) | scheduler 直连本地 | 3 | +| 启动 FTS 索引空 | ✅ 坏 | ✅ 坏 | `indexAllFromWorkspace` 直连本地 | 3 | +| 运行时增量 FTS | ✅ 正常 | ✅ 正常 | 走 filesystem | — | +| Session 搜索 | ✅ 正常(dual-write) | ✅ 正常(dual-write) | SessionTree dual-write | 4(可清理) | +| 工具链(Shell/Filesystem tool) | ✅ 正常 | ✅ 正常 | 已经只走 filesystem | — | + +--- + +**最后一句话总结**: +OpenAI 用"单 workspace + 单 I/O 网关 + LLM 做全局合并"把整类问题消灭在源头;我们的目标是保留 sandbox / Store / Local 三种后端选择,同时用同一种纪律——**memory 领域的一切 I/O 只走 `AbstractFilesystem`**——来等效达成"单网关"效果。把这条纪律立起来,sandbox 模式和 Store 模式的共性顽疾会一次性消失。 diff --git a/agentscope-harness/sandbox-design.md b/agentscope-harness/sandbox-design.md new file mode 100644 index 000000000..7a16a0e66 --- /dev/null +++ b/agentscope-harness/sandbox-design.md @@ -0,0 +1,105 @@ +# HarnessAgent 中实现一套 Sandbox 管理系统 + +## 总体目标 +我们需要深度参考 OpenAi Agents SDK,为 HarnessAgent 提供对应对应的 Sandbox 实现,sandbox可用来执行 subagent 和 tool。我们需要一个 SandboxManager 来管理 sandbox 的生命周期,在 agent 运行过程中,但需要 sandbox 的时候,通过 SandboxManager 来实现获取(按需创建)sandbox实例,并注入给 AbstractFilesystem 使用。 + +每次新创建的 Sandbox 实例本身是无状态的,但是我们需要帮助它恢复到之前的状态,这些状态包括,对应到 OpenAi Agents SDK 中的 Manifest、workspace 等,为了恢复这些状态,可能需要依赖 session 中存储的sandbox state、snapshot等。 + +Sandbox 实例通过后端的Docker、Unix等实际实现来做实际的底层存储实现,这类似 OpenAi Agents SDK 中有 BaseSandboxSession、DockerSandboxSession等的基类和扩展实现等策略。 + +同时,为了能让用户使用 HarnessAgent 时能使用这套 sandbox 体系,我们需要开放 API 给用户进行配置。包括通过 HarnessAgent Builder 来设置使用哪个 Sandbox Client、Client Options、Snapshot实现,使用 RuntimeContext 动态的传入 client、sandbox实例、sandbox state、snapshot实例等。 + +## 部分详细设计 +### Sandbox 实例管理与生命周期 +实现一个 SandboxManager 类,用来管理 sandbox 实例,它根据当前Agent在运行过程中传入的 SandboxContext(可以设计从RuntimeContext中读取)来尝试获取、创建、恢复 sandbox 实例(比如根据SandboxContext中的state来查询和检查可用实例),不论是新建的还是计划恢复的实例,都应该恢复或初始化实例的工作空间(比如通过snapshot)。 + +在使用 HarnessAgent 时,有两种方式管理sandbox实例,一种是通过SandboxManager创建的,一种是用户直接传入的(比如通过RuntimeContext),对应 OpenAi Agents SDK 中的 SDK owned sandbox 和 developer owned sandbox 模式。 + +### 关于 Sandbox 实例获取与创建的时机 + +我现在的想法是放到Hook中,根据 HarnessAgent、RuntimeContext中的配置来决定是不是启用sandbox。增加一个Hook,它主要处理PreCallEvent事件,调用SandboxManager来读取(按需创建)Sandbox实例,并把sandbox实例注入给需要的abstractFilesystem(如果是SandboxFilesystem类型的话)。最终所有在HarnessAgent中与RuntimeContext中的关于sandbox的配置都汇总到 RuntimeContext中,调用SandboxManager管理sandbox时根据RuntimeContext中读取到的sandbox配置来驱动组织,包括找实例、恢复workspace状态等。 + +### Sandbox 内部状态 +Sandbox 实例本身是无状态的,一个新的实例创建出来后需要进行状态初始化,这取决于本地调用是要使用全新的实例还是准备通过resume恢复之前的实例。 +如果是使用全新实例,那么直接参考 OpenAi Agents SDK 中的新实例物化过程进行初始化;如果是resume恢复,那么需要根据传入的snapshot等进行恢复,同样需要参考OpenAi Agents对应实现设计。 + +### Sandbox 基类与拓展实现 +关于 Sandbox 类与实现的设计,需要深度参考 BaseSandboxSession、DockerSandboxSession 等基类和扩展实现。 + +Sandbox 内部通过 SandboxClient 来对接 Docker、Unix 等实际的后端实现。 + +### 用户 API +总的来说,我们是需要在HarnessAgent中增加API,配合HarnessAgent中已有的session等机制来确保sandbox整体能够正常工作和使用。 + +OpenAi Agents SDK 中的 RunState应该对等到ReActAgent中的session状态机制,我们可能需要在session中增加_sandbox部分拓展,支持SandboxSessionState等的存储。RunConfig中大部分参数应该是通过HarnessAgent Builder来配置,部分通过RuntimeContext来配置,比如重点需要考虑的包括SandboxClient、SandboxConfigOptions等。 + +--- + +## Sandbox 隔离与共享策略(Isolation Scope) + +### 背景 + +默认情况下,Sandbox 实例通过 `sessionKey` 隔离,即不同 session 之间不共享同一个 Sandbox 状态。但在实际业务中,我们希望能够灵活控制复用粒度: + +- 同一用户的多个 session 复用同一个 Sandbox(用户粒度共享) +- 同一个 Agent 的所有调用复用同一个 Sandbox(Agent 粒度共享) +- 全局唯一一个 Sandbox(全局共享) + +### 实现方式 + +共享语义是"**按 scope key 持久化状态 → 下次调用恢复**",即顺序复用(sequential reuse),而非进程内运行实例的并发共享。 + +通过 `RuntimeContext.sandboxContext(...)` 传入的 `SandboxContext` 上设置 `isolationScope` 来选择 scope: + +```java +RuntimeContext ctx = RuntimeContext.builder() + .userId("user-42") + .sandboxContext( + SandboxContext.builder() + .isolationScope(SandboxIsolationScope.USER) // 用户粒度共享 + .build()) + .build(); +agent.call(message, ctx); +``` + +### 四种 Scope + +| Scope | 复用粒度 | 所需 RuntimeContext 字段 | 缺失时行为 | +|-----------|------------------------------------|--------------------------|-------------------------------------| +| `SESSION` | 每个 `sessionKey`(默认) | `sessionKey` | 无 key → 直接新建 | +| `USER` | 同一 `userId` 的所有 session | `userId` | userId 为空 → WARN 日志,直接新建 | +| `AGENT` | 同一 Agent(按 agent name) | 无需(build 时固定) | 始终有效 | +| `GLOBAL` | 同一 workspace 内全局唯一 | 无需 | 始终有效 | + +### 磁盘布局 + +``` +/ +├── agents// +│ ├── context//_sandbox.json ← SESSION scope(向下兼容原有路径) +│ └── sandboxes/ +│ ├── user/.json ← USER scope +│ └── agent.json ← AGENT scope +└── sandboxes/ + └── global.json ← GLOBAL scope +``` + +文件名中包含非安全字符(非 `[a-zA-Z0-9_\-.]`)的值会用 Base64url 编码,与 `WorkspaceSession` 的策略保持一致。 + +### 并发注意事项 + +这是顺序复用模型,**不是**进程内活跃实例的并发共享: + +- 相同 scope key 的并发调用,每次调用各自获取/创建独立的 Sandbox 实例 +- `persistState` 采用最后写入覆盖(last-writer-wins)语义 +- 需要并发共享同一个运行中实例的场景,属于未来的进阶功能(live instance registry) + +### 关键类 + +| 类 / 接口 | 职责 | +|-----------|------| +| `SandboxIsolationScope` | 枚举:`SESSION` / `USER` / `AGENT` / `GLOBAL` | +| `SandboxIsolationKey` | `(scope, value)` 不可变值类型;`resolve()` 从 RuntimeContext 计算 key | +| `SandboxStateStore` | 接口:按 key 读写删除 sandbox state JSON | +| `WorkspaceSandboxStateStore` | 文件系统实现;SESSION scope 委托给 `WorkspaceSession` 以保持向下兼容 | +| `SandboxContext.isolationScope` | 每次 call 通过 `RuntimeContext.sandboxContext(...)` 传入 | diff --git a/agentscope-harness/sandbox-filesystem-api-design.md b/agentscope-harness/sandbox-filesystem-api-design.md new file mode 100644 index 000000000..b259830fc --- /dev/null +++ b/agentscope-harness/sandbox-filesystem-api-design.md @@ -0,0 +1,179 @@ +# Sandbox 文件系统 API 设计分析 + +## 问题背景 + +当前 `HarnessAgent.Builder` 中有 4 个分散的 sandbox 专属参数: + +```java +private SandboxClient sandboxClient; +private SandboxClientOptions sandboxClientOptions; +private SandboxSnapshotSpec sandboxSnapshotSpec; +private SandboxManifest defaultSandboxManifest; +``` + +用户要开启 Docker 沙箱,需要在 Builder 上同时配置多处: + +```java +HarnessAgent.builder() + .sandboxClientOptions(new DockerSandboxClientOptions().image("python:3.12-slim")) + .sandboxSnapshotSpec(new LocalSnapshotSpec(...)) + .defaultSandboxManifest(manifest) + ... +``` + +这与"用户第一感知永远是文件系统"的核心设计原则冲突——用户通过 4 个沙箱专属参数感知沙箱,而不是通过文件系统类型。 + +--- + +## 目标 + +将 sandbox 配置收敛到文件系统类型的选择上,让用户通过 `abstractFilesystem()` 这一个入口完成所有配置,其余 sandbox 内部细节对用户完全隐藏。 + +--- + +## 方案对比 + +### 方案 A:让 `SandboxBackedFilesystem` 兼做配置载体 + +将 snapshot spec、manifest 等配置塞入现有的 `SandboxBackedFilesystem`,Builder 检测到 +`abstractFilesystem instanceof SandboxBackedFilesystem` 后自动提取并组装 hook。 + +```java +HarnessAgent.builder() + .abstractFilesystem( + new SandboxBackedFilesystem(new DockerSandboxClientOptions().image("python:3.12-slim")) + .snapshotSpec(new LocalSnapshotSpec(...)) + ) +``` + +**缺点:** + +- `SandboxBackedFilesystem` 同时扮演"配置描述对象"(build 时)和"运行时 session 代理" + (call 时)两个角色,职责混乱。 +- 类名是实现细节("backed by sandbox"),不应直接暴露给用户。 +- Builder 内部代码需要同时处理"用户配置的 SandboxBackedFilesystem"和"内部创建的 + SandboxBackedFilesystem"两种来源,容易混淆。 + +--- + +### 方案 B:新建用户面向的具名文件系统类型(推荐) + +为每种后端引入一个用户可见的文件系统类,`SandboxBackedFilesystem` 保持为内部代理, +对用户完全不可见。Builder 识别到具名类型后,在内部自动创建代理和 hook。 + +```java +// 本地文件系统(默认行为) +HarnessAgent.builder() + .abstractFilesystem(new LocalFilesystem(workspace)) // 对应已有的 LocalFilesystemWithShell + +// Docker 沙箱 +HarnessAgent.builder() + .abstractFilesystem( + new DockerFilesystem() + .image("python:3.12-slim") + .snapshotSpec(new LocalSnapshotSpec(...)) + .manifest(manifest) + ) +``` + +Builder 内部逻辑: + +``` +abstractFilesystem instanceof DockerFilesystem + → 提取 options / snapshotSpec / manifest + → 内部创建 SandboxBackedFilesystem(代理) + → 创建 SandboxLifecycleHook + → 将代理作为实际 backend +``` + +**优点:** + +- 类名即含义,`LocalFilesystem` / `DockerFilesystem` 对称,用户不需要理解 Sandbox 抽象层 +- `SandboxBackedFilesystem` 职责单一:纯运行时 session 代理,完全内部化 +- 结构天然支持未来扩展:`RemoteFilesystem`、`KubernetesFilesystem` 等只需新增类, + Builder API 不变 + +--- + +## 推荐方案(B)的类结构 + +``` +AbstractFilesystem ← 顶层接口(对用户可见,工具层依赖此接口) +├── LocalFilesystem ← 本地文件系统(alias for LocalFilesystemWithShell,用户直接 new) +└── DockerFilesystem ← Docker 沙箱文件系统(用户直接 new,内部持有配置) + 实现 AbstractFilesystem 仅作为标记 / 配置载体 + 不实际执行任何 fs 操作(由 Builder 替换为代理) + +内部(用户不可见) +└── SandboxBackedFilesystem ← 运行时代理,由 Builder 创建,注入实际 session +``` + +`DockerFilesystem` 的公开 API 设计: + +```java +new DockerFilesystem() + .image("python:3.12-slim") // Docker 镜像 + .workspaceRoot("/workspace") // 容器内工作区根目录(可选,有默认值) + .environment(Map) // 环境变量(可选) + .memorySizeBytes(512 * 1024 * 1024L) // 内存限制(可选) + .cpuCount(2L) // CPU 限制(可选) + .exposedPorts(8080, 8443) // 端口映射(可选) + .snapshotSpec(new LocalSnapshotSpec(...)) // 快照策略(可选,默认 Noop) + .manifest(manifest) // 初始工作区布局(可选) +``` + +--- + +## 配置参数归属分析 + +| 参数 | 归属 | 理由 | +|------|------|------| +| `SandboxClientOptions`(image、env 等) | `DockerFilesystem` 字段 | 描述文件系统后端的静态配置 | +| `SandboxManifest`(初始文件布局) | `DockerFilesystem` 字段 | 属于工作区初始化配置,和文件系统绑定 | +| `SandboxSnapshotSpec`(快照存储策略) | `DockerFilesystem` 字段 | 属于文件系统持久化策略 | +| `SandboxClient`(实现实例) | Builder 内部自动推导 | 实现细节,用户永远不需要感知 | +| `SandboxContext`(per-call 运行时覆盖) | 保留在 `RuntimeContext` | 动态参数,每次调用可能不同 | + +结论:`HarnessAgent.Builder` 的 4 个 sandbox 专属参数可以全部消除,只保留 +`abstractFilesystem()` 作为唯一入口。 + +--- + +## 实现步骤(待执行) + +1. 新建 `DockerFilesystem` 类: + - 持有 `DockerSandboxClientOptions`、`SandboxSnapshotSpec`、`SandboxManifest` + - 提供流式 builder 风格的 setter + - 实现 `AbstractFilesystem` 接口作为标记(所有方法抛 `UnsupportedOperationException`, + 因为 Builder 会在内部替换为真正的代理) + +2. 修改 `HarnessAgent.Builder.build()`: + - 检测 `abstractFilesystem instanceof DockerFilesystem` + - 从中提取配置,创建 `SandboxBackedFilesystem` 代理和 `SandboxLifecycleHook` + - 移除 `sandboxClient`、`sandboxClientOptions`、`sandboxSnapshotSpec`、 + `defaultSandboxManifest` 4 个字段和对应的 builder 方法 + +3. 移除 `SandboxClientOptions.createClient()` 抽象方法(该职责已不再需要对外暴露) + +--- + +## 迁移影响 + +现有代码: +```java +HarnessAgent.builder() + .sandboxClientOptions(new DockerSandboxClientOptions().image("python:3.12-slim")) + .sandboxSnapshotSpec(new LocalSnapshotSpec(...)) + .defaultSandboxManifest(manifest) +``` + +迁移后: +```java +HarnessAgent.builder() + .abstractFilesystem( + new DockerFilesystem() + .image("python:3.12-slim") + .snapshotSpec(new LocalSnapshotSpec(...)) + .manifest(manifest) + ) +``` diff --git a/agentscope-harness/sandbox-implementation-plan.md b/agentscope-harness/sandbox-implementation-plan.md new file mode 100644 index 000000000..092e39c94 --- /dev/null +++ b/agentscope-harness/sandbox-implementation-plan.md @@ -0,0 +1,811 @@ +# HarnessAgent Sandbox Mechanism Implementation Plan + +## Overview + +Based on `sandbox-design.md` goals and the OpenAI Agents Python reference implementation +(`references/openai-agents-python/src/agents/sandbox`), this plan describes a complete Sandbox +subsystem for HarnessAgent. + +Core approach: +- Add a `sandbox/` package inside `agentscope-harness`, establishing a full abstraction layer +- Embed into the existing Hook pipeline via a new `SandboxLifecycleHook` (`PreCallEvent` / `PostCallEvent`) +- `SandboxManager` centrally manages session acquisition and lifecycle (SDK-owned / developer-owned modes) +- `SandboxSession` implementations also serve as `AbstractSandboxFilesystem`, unifying the filesystem and session models +- Expose user-facing API on `HarnessAgent.Builder` and `RuntimeContext` + +--- + +## Module Structure + +``` +agentscope-harness/src/main/java/io/agentscope/harness/agent/ +├── sandbox/ +│ ├── SandboxSession.java # Core abstraction: sandbox lifecycle + exec +│ ├── SandboxClient.java # Interface: create / resume / delete +│ ├── SandboxClientOptions.java # Polymorphic options base class (type field) +│ ├── SandboxSessionState.java # Serializable session state +│ ├── SandboxManifest.java # Workspace descriptor (root + entries + env) +│ ├── SandboxContext.java # Per-call sandbox config aggregation +│ ├── SandboxManager.java # Lifecycle management core +│ ├── SandboxSessionAware.java # Filesystem injection interface +│ ├── snapshot/ +│ │ ├── SandboxSnapshot.java # Snapshot interface +│ │ ├── SandboxSnapshotSpec.java # Snapshot spec interface (build → SandboxSnapshot) +│ │ ├── LocalSandboxSnapshot.java # Local tar file implementation +│ │ ├── LocalSnapshotSpec.java +│ │ ├── NoopSandboxSnapshot.java # No-op implementation +│ │ ├── NoopSnapshotSpec.java +│ │ ├── RemoteSandboxSnapshot.java # Delegates to remote client (S3, etc.) +│ │ └── RemoteSnapshotSpec.java +│ ├── manifest/ +│ │ ├── ManifestEntry.java # Abstract entry +│ │ ├── FileEntry.java # Inline file content +│ │ ├── DirEntry.java # Empty directory +│ │ ├── LocalFileEntry.java # Copy file from host +│ │ ├── LocalDirEntry.java # Copy directory from host +│ │ └── GitRepoEntry.java # Clone a Git repo +│ └── impl/ +│ ├── local/ +│ │ ├── UnixLocalSandboxSession.java +│ │ ├── UnixLocalSandboxClient.java +│ │ ├── UnixLocalSandboxClientOptions.java +│ │ └── UnixLocalSandboxSessionState.java +│ └── docker/ +│ ├── DockerSandboxSession.java +│ ├── DockerSandboxClient.java +│ ├── DockerSandboxClientOptions.java +│ └── DockerSandboxSessionState.java +└── hook/ + └── SandboxLifecycleHook.java # New hook +``` + +--- + +## Step 1: Core Abstraction Layer + +### 1.1 SandboxSession + +Corresponds to Python `BaseSandboxSession`. The central abstraction for a sandbox instance. + +**Key responsibilities:** +- Manages the full lifecycle of a single sandbox instance: `start()` → running → `stop()` → `shutdown()` +- Provides exec / read / write / ls / mkdir / rm workspace operations +- `start()` internal flow: `ensureBackendStarted()` → `prepareWorkspace()` → `applyManifestOrRestoreSnapshot()` → `ensureRuntimeHelpers()` +- `stop()` only persists a snapshot (`persistSnapshot()`), does not destroy resources +- `shutdown()` destroys backend resources (container / temp dir), default is no-op +- `aclose()` = pre-stop hooks + `stop()` + `shutdown()` + +**Interface definition:** + +```java +public interface SandboxSession extends AutoCloseable { + // Lifecycle + void start() throws Exception; + void stop() throws Exception; + void shutdown() throws Exception; + void aclose() throws Exception; + boolean isRunning(); + + // Workspace operations (delegates to BaseSandboxFilesystem) + ExecResult exec(String command, Integer timeoutSeconds); + InputStream read(String path) throws Exception; + void write(String path, InputStream data) throws Exception; + List ls(String path) throws Exception; + void mkdir(String path) throws Exception; + void rm(String path, boolean recursive) throws Exception; + + // Workspace serialization + InputStream persistWorkspace() throws Exception; + void hydrateWorkspace(InputStream data) throws Exception; + + // State + SandboxSessionState getState(); +} +``` + +**Fusion with AbstractSandboxFilesystem:** + +`SandboxSession` implementations also extend `BaseSandboxFilesystem`, so the existing +shell-based default implementations (ls / read / write / edit / grep / glob) are reused: + +```java +// UnixLocalSandboxSession extends BaseSandboxFilesystem implements SandboxSession +// DockerSandboxSession extends BaseSandboxFilesystem implements SandboxSession +``` + +--- + +### 1.2 SandboxClient + +Corresponds to Python `BaseSandboxClient`. + +```java +public interface SandboxClient { + String getBackendId(); + + /** + * Creates a new SandboxSession. + * The session is NOT started automatically; the caller (usually SandboxManager) must call start(). + */ + SandboxSession create(SandboxManifest manifest, SandboxSnapshotSpec snapshotSpec, O options) + throws Exception; + + /** + * Resumes a session from a previously persisted SandboxSessionState. + * Re-connects to a still-alive backend instance, or creates a new one and restores via snapshot. + */ + SandboxSession resume(SandboxSessionState state) throws Exception; + + /** Deletes backend resources for SDK-owned sessions (container, temp dir, etc.). */ + void delete(SandboxSession session) throws Exception; + + /** Serializes session state to a JSON-compatible Map for persistent storage. */ + Map serializeState(SandboxSessionState state); + + /** Deserializes from a JSON payload into the concrete SandboxSessionState subclass. */ + SandboxSessionState deserializeState(Map payload); +} +``` + +--- + +### 1.3 SandboxSessionState + +Corresponds to Python `SandboxSessionState`. Serializable to JSON for storage in the session file. + +```java +public class SandboxSessionState { + private String type; // "unix_local" / "docker" / etc. + private UUID sessionId; + private SandboxManifest manifest; + private Map snapshotState; // Serialized snapshot info + private boolean workspaceRootReady; + private String snapshotFingerprint; + private String snapshotFingerprintVersion; + // Subclasses may add more fields (e.g. Docker containerId) +} +``` + +--- + +### 1.4 SandboxManifest + +Corresponds to Python `Manifest`. Describes the initial workspace state. + +```java +public class SandboxManifest { + private String root = "/workspace"; // Workspace root path + private Map entries; // Relative path → entry + private Map environment; // Environment variables + private List users; // Sandbox users +} +``` + +**ManifestEntry sub-types:** + +| Java class | Python equivalent | Purpose | +|------------------|-------------------|---------------------------------| +| `FileEntry` | `File` | Inline file content | +| `DirEntry` | `Dir` | Create empty directory | +| `LocalFileEntry` | `LocalFile` | Copy file from host | +| `LocalDirEntry` | `LocalDir` | Copy directory from host | +| `GitRepoEntry` | `GitRepo` | Clone a Git repository | + +--- + +### 1.5 SandboxContext + +Aggregates per-call sandbox configuration. Passed through `RuntimeContext`, read by `SandboxLifecycleHook`. + +```java +public class SandboxContext { + // Direct injection mode (developer-owned) + private SandboxSession session; + + // Via client mode (SDK-owned) + private SandboxClient client; + private SandboxClientOptions clientOptions; + private SandboxManifest manifest; // Overrides builder default manifest + private SandboxSnapshotSpec snapshotSpec; // Overrides builder default snapshot spec + + // Resume mode (provide serialized state) + private SandboxSessionState sessionState; + // Or auto-loaded from the "_sandbox" key in the session file + + public static Builder builder() { ... } +} +``` + +--- + +## Step 2: Snapshot Abstraction Layer + +Corresponds to Python `SnapshotBase` / `LocalSnapshot` / `NoopSnapshot` / `RemoteSnapshot`. + +### SandboxSnapshot Interface + +```java +public interface SandboxSnapshot { + void persist(InputStream workspaceArchive) throws Exception; + InputStream restore() throws Exception; + boolean isRestorable() throws Exception; + String getId(); +} +``` + +### SandboxSnapshotSpec Interface + +```java +public interface SandboxSnapshotSpec { + SandboxSnapshot build(String snapshotId); +} +``` + +### Three Implementations + +| Class | Description | Python equivalent | +|--------------------------|--------------------------------------------------------------------------------|--------------------| +| `LocalSandboxSnapshot` | Persists to a local `{basePath}/{id}.tar`; atomic write (write .tmp then rename) | `LocalSnapshot` | +| `NoopSandboxSnapshot` | No-op; `isRestorable()` returns false | `NoopSnapshot` | +| `RemoteSandboxSnapshot` | Delegates to user-provided `RemoteSnapshotClient` interface (upload/download/exists) | `RemoteSnapshot` | + +--- + +## Step 3: Concrete SandboxClient + SandboxSession Implementations + +### 3.1 UnixLocal Implementation + +Corresponds to Python `unix_local.py`. Suitable for local development with no extra dependencies. + +**UnixLocalSandboxClientOptions:** +```java +public class UnixLocalSandboxClientOptions extends SandboxClientOptions { + private String type = "unix_local"; + private Path workspaceBasePath; // Defaults to system temp dir if not specified + private int[] exposedPorts = {}; +} +``` + +**UnixLocalSandboxSession key implementation points:** +- `ensureBackendStarted()`: Creates a temp directory under `workspaceBasePath` as the workspace root +- `exec(command)`: Runs shell commands in the workspace root via `ProcessBuilder`, + reusing the existing `LocalFilesystemWithShell` exec logic +- `persistWorkspace()`: `exec("tar -cf - -C {root} .")` returns a tar `InputStream` +- `hydrateWorkspace(data)`: Extracts tar stream into the workspace root +- `shutdown()`: Deletes the temp directory if SDK-owned +- State type = `"unix_local"` + +**UnixLocalSandboxSessionState extra fields:** +```java +public class UnixLocalSandboxSessionState extends SandboxSessionState { + private String workspaceRoot; // Actual absolute workspace path in use + private boolean workspaceOwned; // Created by SDK (delete on shutdown)? +} +``` + +--- + +### 3.2 Docker Implementation + +Corresponds to Python `docker.py`. Requires `docker-java` dependency (marked `optional`). + +**pom.xml additions (agentscope-harness):** +```xml + + com.github.docker-java + docker-java-core + 3.4.0 + true + + + com.github.docker-java + docker-java-transport-httpclient5 + 3.4.0 + true + +``` + +**DockerSandboxClientOptions:** +```java +public class DockerSandboxClientOptions extends SandboxClientOptions { + private String type = "docker"; + private String image = "ubuntu:22.04"; + private String workspaceRoot = "/workspace"; + private Map envVars = Map.of(); + private Long memorySizeBytes; + private Long cpuCount; + private int[] exposedPorts = {}; +} +``` + +**DockerSandboxSession key implementation points:** +- `ensureBackendStarted()`: `docker pull` + `docker run -d` to start the container + (or reconnect via `containerId` from state) +- `exec(command)`: Via docker-java `ExecCreateCmd` + `ExecStartCmd`, collecting stdout/stderr +- `persistWorkspace()`: `docker exec tar -cf - -C {root} .`, using stdout as tar stream +- `hydrateWorkspace(data)`: Write tar stream into the container workspace root via `docker cp` +- `shutdown()`: If SDK-owned: `docker stop` + `docker rm` +- State type = `"docker"`, extra field: `containerId` + +**DockerSandboxSessionState extra fields:** +```java +public class DockerSandboxSessionState extends SandboxSessionState { + private String containerId; + private String image; +} +``` + +--- + +## Step 4: SandboxManager + +`SandboxManager` is the central scheduler responsible for resolving the sandbox instance +and completing workspace initialization. + +### Resolution Priority (corresponds to Python SandboxRunConfig priority) + +``` +1. SandboxContext.session is non-null → developer-owned, use directly, do NOT call start() +2. SandboxContext.sessionState is non-null → SDK-owned resume, call client.resume(state) +3. "_sandbox" state found in session file → SDK-owned resume, call client.resume(state) +4. None of the above → SDK-owned create, call client.create(manifest, snapshot, options) +``` + +### Core Methods + +```java +public class SandboxManager { + + /** + * Acquires (or creates) a SandboxSession from the SandboxContext in RuntimeContext. + * The returned session has already had start() called; the workspace is ready. + * The caller is responsible for deciding when to call stop/shutdown + * (handled automatically by SandboxLifecycleHook). + */ + public SandboxSession acquire(RuntimeContext runtimeContext) throws Exception; + + /** + * Persists the session workspace (snapshot) and optionally destroys backend resources. + * SDK-owned sessions trigger client.delete(); developer-owned sessions do not. + */ + public void release(SandboxSession session, boolean shutdown) throws Exception; + + /** + * Serializes SandboxSessionState and writes it to the RuntimeContext session store. + * Key = "_sandbox", for use in subsequent resume calls. + */ + public void persistState(SandboxSession session, RuntimeContext runtimeContext); + + /** + * Reads SandboxSessionState from the RuntimeContext session store. + * Returns null if no stored state is found. + */ + public SandboxSessionState loadState(RuntimeContext runtimeContext); +} +``` + +### Workspace Initialization Flow (corresponds to Python `BaseSandboxSession._start_workspace()`) + +``` +session.start() internally: + if snapshot.isRestorable(): + if workspacePreserved && fingerprintMatches: + reapplyEphemeralManifest() // Only rebuild ephemeral entries + else: + clearWorkspace() + hydrateWorkspace(snapshot.restore()) + applyManifest(onlyEphemeral=true) + elif workspacePreserved: + reapplyEphemeralManifest() + else: + applyManifest(full) // Materialize full manifest +``` + +--- + +## Step 5: SandboxLifecycleHook + +A new Hook that integrates into the HarnessAgent Hook pipeline. + +### Trigger Timing + +| Event | Action | +|-----------------|------------------------------------------------------------------------------------------| +| `PreCallEvent` | Read SandboxContext from RuntimeContext → `SandboxManager.acquire()` → inject filesystem | +| `PostCallEvent` | `SandboxManager.release(session, shutdown=true if SDK-owned)` → `persistState()` → clear ref | +| `ErrorEvent` | Same as PostCallEvent (best-effort, no re-throw) | + +### Implementation Skeleton + +```java +public class SandboxLifecycleHook implements Hook, RuntimeContextAwareHook { + + private final SandboxManager sandboxManager; + private final SandboxClient defaultClient; + private final SandboxClientOptions defaultClientOptions; + private final SandboxSnapshotSpec defaultSnapshotSpec; + private final AbstractFilesystem filesystem; + + private RuntimeContext runtimeContext; + private SandboxSession activeSession; + private boolean sdkOwned; + + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent) { + return handlePreCall(event); + } + if (event instanceof PostCallEvent || event instanceof ErrorEvent) { + return handlePostCall(event); + } + return Mono.just(event); + } + + private Mono handlePreCall(T event) { + return Mono.fromCallable(() -> { + SandboxContext ctx = resolveSandboxContext(); + if (ctx == null) return event; // Sandbox not enabled + + activeSession = sandboxManager.acquire(runtimeContext); + sdkOwned = (ctx.getSession() == null); // Directly injected = developer-owned + + // Inject into filesystem + if (filesystem instanceof SandboxSessionAware aware) { + aware.setSandboxSession(activeSession); + } + return event; + }); + } + + private Mono handlePostCall(T event) { + return Mono.fromCallable(() -> { + SandboxSession session = activeSession; + if (session == null) return event; + + try { + sandboxManager.release(session, sdkOwned); + sandboxManager.persistState(session, runtimeContext); + } catch (Exception e) { + log.warn("SandboxLifecycleHook: release failed: {}", e.getMessage()); + } finally { + activeSession = null; + } + return event; + }); + } + + private SandboxContext resolveSandboxContext() { + // Priority 1: SandboxContext from RuntimeContext + // Priority 2: Default client configured via builder + SandboxContext ctx = runtimeContext != null + ? runtimeContext.getSandboxContext() : null; + if (ctx == null && defaultClient != null) { + ctx = SandboxContext.builder() + .client(defaultClient) + .clientOptions(defaultClientOptions) + .snapshotSpec(defaultSnapshotSpec) + .build(); + } + return ctx; + } +} +``` + +--- + +## Step 6: SandboxSessionAware Interface + +Provides an injection point so `SandboxLifecycleHook` can push the live session into the filesystem. + +```java +/** + * Marks an AbstractFilesystem implementation that can accept + * a live SandboxSession at runtime, enabling session injection + * by SandboxLifecycleHook before each agent call. + */ +public interface SandboxSessionAware { + void setSandboxSession(SandboxSession session); + SandboxSession getSandboxSession(); +} +``` + +**SandboxFilesystemAdapter** (optional, for decoupled implementations): + +Wraps a `SandboxSession` and implements `AbstractSandboxFilesystem`, delegating all calls +to the current session. Suitable when session implementations do not extend `BaseSandboxFilesystem`. + +--- + +## Step 7: RuntimeContext Extension + +Add a `sandboxContext` field to `RuntimeContext`, or pass it via the extra map with a well-known key. + +**Recommended: explicit typed field** (type-safe, consistent with existing `session`/`sessionKey` fields): + +```java +public class RuntimeContext { + // Existing fields... + private final SandboxContext sandboxContext; // New field + + public SandboxContext getSandboxContext() { return sandboxContext; } + + public static class Builder { + public Builder sandboxContext(SandboxContext ctx) { ... } + } +} +``` + +**Alternative: well-known extra key** (backward-compatible): + +```java +public SandboxContext getSandboxContext() { + Object val = getExtra().get("_sandboxContext"); + return val instanceof SandboxContext sc ? sc : null; +} + +public RuntimeContext withSandboxContext(SandboxContext ctx) { + return RuntimeContext.builder() + .putAllExtra(getExtra()) + .putExtra("_sandboxContext", ctx) + .build(); +} +``` + +--- + +## Step 8: HarnessAgent Builder Extension + +Add sandbox configuration API to `HarnessAgent.Builder`: + +```java +public class Builder { + // New fields + private SandboxClient sandboxClient; + private SandboxClientOptions sandboxClientOptions; + private SandboxSnapshotSpec sandboxSnapshotSpec; + private SandboxManifest defaultSandboxManifest; + + /** Configures the sandbox client (e.g. UnixLocalSandboxClient / DockerSandboxClient). */ + public Builder sandboxClient(SandboxClient client) { + this.sandboxClient = client; + return this; + } + + /** Configures sandbox client options (e.g. DockerSandboxClientOptions to specify image). */ + public Builder sandboxClientOptions(SandboxClientOptions options) { + this.sandboxClientOptions = options; + return this; + } + + /** Configures the default snapshot strategy (Local / Noop / Remote). */ + public Builder sandboxSnapshotSpec(SandboxSnapshotSpec spec) { + this.sandboxSnapshotSpec = spec; + return this; + } + + /** Configures the default sandbox workspace manifest (entries, env vars, etc.). */ + public Builder defaultSandboxManifest(SandboxManifest manifest) { + this.defaultSandboxManifest = manifest; + return this; + } + + public HarnessAgent build() { + // ...existing build logic... + + // If sandboxClient is configured, register SandboxLifecycleHook + if (sandboxClient != null) { + SandboxManager sandboxManager = new SandboxManager(sandboxClient, defaultSandboxManifest); + SandboxLifecycleHook sandboxHook = new SandboxLifecycleHook( + sandboxManager, + sandboxClient, + sandboxClientOptions, + sandboxSnapshotSpec, + backend // AbstractFilesystem + ); + allHooks.add(sandboxHook); + } + // ... + } +} +``` + +--- + +## Step 9: Session Sandbox State Persistence + +Extend `WorkspaceSession` to support reading/writing the `_sandbox` key, +corresponding to how OpenAI Agents SDK stores sandbox payload in `RunState`. + +```java +public class WorkspaceSession implements Session { + + /** Saves sandbox session state to the "_sandbox" field of the session file. */ + public void saveSandboxState(SessionKey key, Map statePayload) { + // Read current session JSON → merge "_sandbox" field → write back + } + + /** Reads the "_sandbox" field and returns the serialized Map for SandboxClient.deserializeState(). */ + public Map loadSandboxStatePayload(SessionKey key) { + // Read session JSON → extract "_sandbox" field + } +} +``` + +`SandboxManager.persistState()` call flow: + +``` +SandboxManager.persistState(session, runtimeContext) + → state = session.getState() + → payload = client.serializeState(state) + → workspaceSession = runtimeContext.getSession() + → workspaceSession.saveSandboxState(runtimeContext.getSessionKey(), payload) +``` + +--- + +## User-Facing Usage Examples + +### Unix Local Mode (quick local development) + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("MyAgent") + .model(model) + .sysPrompt("You are a helpful coding assistant.") + .workspace(Path.of("/path/to/workspace")) + .sandboxClient(new UnixLocalSandboxClient()) + .sandboxClientOptions( + new UnixLocalSandboxClientOptions() + .workspaceBasePath(Path.of("/tmp/agent-sandboxes")) + ) + .sandboxSnapshotSpec( + new LocalSnapshotSpec(Path.of("/tmp/agent-snapshots")) + ) + .defaultSandboxManifest( + SandboxManifest.builder() + .root("/workspace") + .entry("repo", new LocalDirEntry(Path.of("/my/project"))) + .build() + ) + .build(); + +// Sandbox is managed automatically by HarnessAgent +Msg response = agent.call( + Msg.userMsg("Fix the bug in auth.java"), + RuntimeContext.builder().sessionId("sess-001").build() +).block(); +``` + +### Docker Mode (container isolation) + +```java +DockerClient dockerClient = DockerClientBuilder.getInstance().build(); + +HarnessAgent agent = HarnessAgent.builder() + .name("DockerAgent") + .model(model) + .sandboxClient(new DockerSandboxClient(dockerClient)) + .sandboxClientOptions( + new DockerSandboxClientOptions() + .image("python:3.12-slim") + .memorySizeBytes(512 * 1024 * 1024L) + ) + .sandboxSnapshotSpec(new LocalSnapshotSpec(Path.of("/tmp/docker-snapshots"))) + .build(); +``` + +### Developer-Owned Mode (manual lifecycle management) + +```java +UnixLocalSandboxClient client = new UnixLocalSandboxClient(); +SandboxSession sandbox = client.create(manifest, snapshotSpec, options); +sandbox.start(); + +try { + // Reuse the same sandbox across multiple calls + for (String task : tasks) { + agent.call( + Msg.userMsg(task), + RuntimeContext.builder() + .sessionId("sess-001") + .sandboxContext(SandboxContext.builder().session(sandbox).build()) + .build() + ).block(); + } +} finally { + sandbox.stop(); // Persist snapshot + sandbox.shutdown(); // Clean up resources + client.delete(sandbox); +} +``` + +### Resume Mode (restore workspace across calls) + +```java +// After the first call, SandboxLifecycleHook automatically writes state to the session file. + +// On the next call (auto-resume): +// WorkspaceSession reads the "_sandbox" field +// SandboxManager finds sessionState → calls client.resume(state) +// Workspace is restored from snapshot +Msg response2 = agent.call( + Msg.userMsg("Continue working on the previous task"), + RuntimeContext.builder().sessionId("sess-001").build() // Same sessionId triggers auto-resume +).block(); +``` + +--- + +## Implementation Priority + +| Phase | Content | Priority | +|-------|-----------------------------------------------------------------------------------|----------| +| P0 | Core abstractions (SandboxSession / SandboxClient / SandboxManager / SandboxContext) | Required | +| P0 | Snapshot abstractions (NoopSnapshot + LocalSnapshot) | Required | +| P0 | UnixLocalSandboxSession + UnixLocalSandboxClient | Required | +| P0 | SandboxLifecycleHook + SandboxSessionAware | Required | +| P0 | RuntimeContext extension + HarnessAgent Builder API | Required | +| P1 | WorkspaceSession `_sandbox` state persistence + Resume flow | Important | +| P1 | SandboxManifest materialization (LocalDir / LocalFile / File / Dir entries) | Important | +| P1 | DockerSandboxSession + DockerSandboxClient | Important | +| P2 | RemoteSandboxSnapshot (S3, etc.) | Extension | +| P2 | GitRepoEntry manifest entry | Extension | +| P2 | Workspace fingerprint caching (avoid redundant snapshot restores) | Optimization | + +--- + +## Design Decisions + +### 1. SandboxSession vs AbstractSandboxFilesystem Fusion Strategy + +**Short-term: Option A — Direct inheritance of `BaseSandboxFilesystem`** + +Both `UnixLocalSandboxSession` and `DockerSandboxSession` extend `BaseSandboxFilesystem` +and implement `SandboxSession`. + +Pros: Reuses the existing shell-based filesystem logic; existing tools (FilesystemTool, ShellExecuteTool) +require no modification. + +**Long-term: Option B — Independent `SandboxFilesystemAdapter`** (future refactor direction) + +`SandboxSession` is kept independent; a `SandboxFilesystemAdapter` wraps it and injects it, +cleanly decoupling session lifecycle from filesystem operations. + +--- + +### 2. Sandbox Propagation to Subagents + +When HarnessAgent spawns subagents, the sandbox mode must be decided: + +- **Shared sandbox** (developer-owned propagation): Parent passes its `SandboxSession` via + `SandboxContext.session` to the subagent. Subagent operates in the same workspace. + Suitable for collaborative tasks. +- **Isolated sandbox** (independent create): Subagent gets its own sandbox with an isolated workspace. + Suitable for concurrent independent tasks. + +Default strategy: subagents use isolated sandboxes. If `SandboxContext.session` is explicitly +passed, shared mode is used. Configure via `buildGeneralPurposeFactory` / `buildSpecFactory`. + +--- + +### 3. SandboxContext Delivery in RuntimeContext + +**Chosen: explicit typed field** (type-safe, consistent with existing `session`/`sessionKey` style) + +Add `private final SandboxContext sandboxContext` to `RuntimeContext`, +set via `Builder.sandboxContext(ctx)`. + +--- + +## Reference Material + +- OpenAI Agents Python reference: `references/openai-agents-python/src/agents/sandbox/` +- `session/base_sandbox_session.py` — lifecycle core logic +- `session/sandbox_client.py` — client interface and polymorphic options +- `session/sandbox_session_state.py` — serializable state model +- `snapshot.py` — three snapshot implementations +- `manifest.py` — workspace descriptor model +- `sandboxes/unix_local.py` — Unix local implementation reference +- `sandboxes/docker.py` — Docker implementation reference +- `docs/sandbox/guide.md` — full concepts and usage documentation + diff --git a/agentscope-harness/sandbox-implementation-status.md b/agentscope-harness/sandbox-implementation-status.md new file mode 100644 index 000000000..6b8e5ec9c --- /dev/null +++ b/agentscope-harness/sandbox-implementation-status.md @@ -0,0 +1,231 @@ +# Sandbox 子系统实现情况总结 + +## 目标 + +为 `HarnessAgent` 构建一套完整的 Sandbox(沙箱)子系统,使 Agent 的每次调用都可以在隔离的工作区环境中执行命令和文件操作,同时支持工作区快照(Snapshot)持久化与跨调用恢复。 + +核心设计原则: + +- 通过 **Hook 管道**(`SandboxLifecycleHook`)无侵入地集成到 `HarnessAgent` 的现有流程 +- 以 **`SandboxManager`** 为核心调度器,统一管理 Session 的获取与生命周期 +- `SandboxSession` 实现类同时扮演 **文件系统后端**(通过 `SandboxBackedFilesystem`),使现有工具(`FilesystemTool`、`ShellExecuteTool`)无需修改 +- `HarnessAgent.Builder` 提供简洁的用户 API,支持三种使用模式:SDK 托管、开发者托管、Resume 恢复 + +--- + +## 实现计划(阶段划分) + +| 阶段 | 内容 | 优先级 | +|------|------|--------| +| P0 | 核心抽象层(接口、异常、状态、Manifest) | 必须 | +| P0 | 快照抽象层(NoopSnapshot、LocalSnapshot) | 必须 | +| P0 | UnixLocal 实现(本地进程沙箱) | 必须 | +| P0 | SandboxLifecycleHook + SandboxSessionAware | 必须 | +| P0 | RuntimeContext 扩展 + HarnessAgent Builder API | 必须 | +| P1 | WorkspaceSession `_sandbox` 状态持久化 + Resume 流程 | 重要 | +| P1 | SandboxManifest 物化(LocalDir / LocalFile / File / Dir) | 重要 | +| P1 | DockerSandboxSession + DockerSandboxClient | 重要 | +| P2 | RemoteSandboxSnapshot(S3 等) | 扩展 | +| P2 | GitRepoEntry Manifest 条目 | 扩展 | +| P2 | 工作区指纹缓存(避免冗余快照恢复) | 优化 | + +--- + +## 实现状态 + +### ✅ 已完成 + +#### 核心抽象层(`sandbox/` 包) + +| 文件 | 说明 | +|------|------| +| `SandboxErrorCode.java` | 11 个错误码枚举(`EXEC_NONZERO`、`EXEC_TIMEOUT`、`WORKSPACE_START_ERROR` 等) | +| `SandboxException.java` | 基类 + 7 个内部子类(`ExecException`、`ExecTimeoutException`、`SnapshotException` 等) | +| `ExecResult.java` | `record(int exitCode, String stdout, String stderr, boolean truncated)`,带 `ok()`、`combinedOutput()` | +| `SandboxSessionAware.java` | 注入接口:`setSandboxSession(SandboxSession)`、`getSandboxSession()` | +| `SandboxSession.java` | 核心接口:完整生命周期(`start/stop/shutdown/close`)+ exec + 工作区序列化 | +| `SandboxClient.java` | 泛型接口 ``:create / resume / delete / 状态序列化 | +| `SandboxClientOptions.java` | 多态基类,`@JsonTypeInfo(NAME)`,已注册 `unix_local`、`docker` | +| `SandboxSessionState.java` | 多态基类,`@JsonTypeInfo(NAME)`,已注册 `unix_local`、`docker` | +| `SandboxManifest.java` | 工作区描述符:`root`、`entries`(LinkedHashMap)、`environment` | +| `SandboxContext.java` | 不可变 Builder,聚合每次调用的沙箱配置(client、options、manifest、snapshotSpec、externalSession) | +| `SandboxAcquireResult.java` | `session + sdkOwned:boolean`,`sdkOwned()` / `developerOwned()` 工厂方法 | +| `SandboxManager.java` | 4 优先级 acquire 逻辑(developer-owned → resume-from-state → resume-from-file → create-new)、release、persistState、clearState | +| `AbstractBaseSandboxSession.java` | 4 分支 start 逻辑(Branch A/B/C/D)、stop/close/exec/persistWorkspace/hydrateWorkspace | +| `ManifestApplier.java` | 递归物化 Manifest:FileEntry / DirEntry / LocalFileEntry / LocalDirEntry / GitRepoEntry(P2 占位 warn) | +| `WorkspaceArchiveExtractor.java` | 安全 tar 解压(使用 commons-compress),路径遍历防护(`..`、绝对路径、null 字节) | +| `SandboxBackedFilesystem.java` | 扩展 `BaseSandboxFilesystem`,实现 `SandboxSessionAware`;exec 代理到 `session.exec()`;upload/download 通过 Base64 编码命令实现 | + +#### Manifest 子类型(`sandbox/manifest/` 包) + +| 文件 | 说明 | +|------|------| +| `ManifestEntry.java` | 抽象基类,`@JsonTypeInfo`,5 个子类型注册 | +| `FileEntry.java` | 内联文件内容,`content + encoding` | +| `DirEntry.java` | 创建目录,`children: LinkedHashMap`,支持 `.child()` 链式构建 | +| `LocalFileEntry.java` | 从宿主机复制文件,`sourcePath` | +| `LocalDirEntry.java` | 从宿主机复制目录,`sourcePath` | +| `GitRepoEntry.java` | 克隆 Git 仓库(P2 占位),`url + ref` | + +#### 快照层(`sandbox/snapshot/` 包) + +| 文件 | 说明 | +|------|------| +| `SandboxSnapshot.java` | 接口:`persist / restore / isRestorable / getId / getType`,`@JsonTypeInfo` | +| `SandboxSnapshotSpec.java` | 工厂接口:`build(snapshotId) → SandboxSnapshot` | +| `NoopSandboxSnapshot.java` | 丢弃归档流,`isRestorable()=false` | +| `NoopSnapshotSpec.java` | 始终返回新 `NoopSandboxSnapshot` | +| `LocalSandboxSnapshot.java` | 持久化到 `{basePath}/{id}.tar`,原子写入(tmp + `ATOMIC_MOVE`),路径安全校验 | +| `LocalSnapshotSpec.java` | 工厂,创建 `LocalSandboxSnapshot` | +| `RemoteSandboxSnapshot.java` | 委托到 `RemoteSnapshotClient`(上传/下载/exists) | +| `RemoteSnapshotSpec.java` | 工厂,创建 `RemoteSandboxSnapshot` | +| `RemoteSnapshotClient.java` | 用户扩展接口(S3 等):`upload / download / exists` | + +#### Unix Local 实现(`sandbox/impl/local/` 包) + +| 文件 | 说明 | +|------|------| +| `UnixLocalSandboxClientOptions.java` | `workspaceBasePath: String`、`exposedPorts: int[]`,`getType()="unix_local"` | +| `UnixLocalSandboxSessionState.java` | 扩展 `SandboxSessionState`:`workspaceRoot`、`workspaceRootOwned` | +| `UnixLocalSandboxSession.java` | `doExec()` 通过 `ProcessBuilder("sh","-c",cmd)` + 2 线程 stdout/stderr 排空;`doPersistWorkspace()` 通过 `tar -cf - -C .`;`doHydrateWorkspace()` 通过 `WorkspaceArchiveExtractor`;`shutdown()` 删除自有临时目录 | +| `UnixLocalSandboxClient.java` | UUID sessionId,`resolveWorkspaceRoot()`(basePath → `/` 或系统 tmpdir → `/`);Jackson 多态序列化/反序列化 | + +#### Docker 实现(`sandbox/impl/docker/` 包) + +| 文件 | 说明 | +|------|------| +| `DockerSandboxClientOptions.java` | `image`(默认 `ubuntu:22.04`)、`workspaceRoot`、`environment`、`memorySizeBytes`、`cpuCount`、`exposedPorts` | +| `DockerSandboxSessionState.java` | 扩展 `SandboxSessionState`:`containerId`、`containerName`、`image`、`workspaceRoot`、`containerOwned`,及用于容器重建的资源字段 | +| `DockerSandboxSession.java` | 通过 Docker CLI(`ProcessBuilder`,无 docker-java 依赖);`start()` 处理 running/stopped/missing 三种容器状态;exec 通过 `docker exec -w `;工作区归档通过 `docker exec tar`;`shutdown()` 执行 `docker stop` + `docker rm` | +| `DockerSandboxClient.java` | 创建/恢复 Docker 沙箱 Session;Jackson 多态序列化/反序列化 | + +#### Hook 集成(`hook/` 包) + +| 文件 | 说明 | +|------|------| +| `SandboxLifecycleHook.java` | `priority=50`(优先于所有现有 Hook 运行);`PreCallEvent`:acquire → start → inject session → set ThreadLocal;`PostCallEvent/ErrorEvent`:persistState → release → clearSession(best-effort) | + +#### 现有文件修改 + +| 文件 | 修改内容 | +|------|---------| +| `pom.xml` | 添加 `commons-compress 1.27.1` 依赖 | +| `RuntimeContext.java` | 添加 `sandboxContext: SandboxContext` 字段 + Builder `sandboxContext()` 方法 | +| `WorkspaceSession.java` | 添加 `saveSandboxState(SessionKey, String)`、`loadSandboxStateJson(SessionKey)`、`deleteSandboxState(SessionKey)`、`resolveSessionDir(SessionKey)` | +| `SandboxBackedFilesystem.java` | 添加 `configureNamespace(NamespaceFactory)` 公开方法 | +| `HarnessAgent.java` | Builder 添加 `sandboxClient/Options/SnapshotSpec/defaultManifest` 字段与方法;`build()` 中创建 `SandboxBackedFilesystem`、`SandboxManager`、`SandboxLifecycleHook`;`ensureSessionDefaults()` 保留/注入 `sandboxContext`;`bindRuntimeContext()` 传播上下文到 `sandboxLifecycleHook`;subagent factory 传播 `sandboxFs` | + +--- + +## 关键设计决策 + +### 1. Session 与 Filesystem 融合策略 + +采用 **直接继承** `BaseSandboxFilesystem` 方案(短期方案 A): + +- `UnixLocalSandboxSession` 和 `DockerSandboxSession` 均扩展 `AbstractBaseSandboxSession` +- `SandboxBackedFilesystem` 作为代理层,通过 `SandboxSessionAware` 接口接收注入的 Session +- 现有工具(`FilesystemTool`、`ShellExecuteTool`)无需任何修改 + +### 2. Session 获取优先级(4-Branch Acquire) + +``` +1. SandboxContext.externalSession != null → developer-owned(不调用 start()) +2. SandboxContext.externalSessionState != null → SDK-owned resume +3. WorkspaceSession 中存在 _sandbox.json → SDK-owned resume(跨调用自动恢复) +4. 以上均不满足 → SDK-owned create(全新初始化) +``` + +### 3. 工作区初始化(4-Branch Start) + +``` +Branch A: workspaceRootReady=true & 目录仍存在 → 仅应用 ephemeral 条目 +Branch B: workspaceRootReady=true & 目录已丢失 → 从快照恢复 + ephemeral 条目 +Branch C: workspaceRootReady=false & 快照可恢复 → 从快照 hydrate + 全量 Manifest +Branch D: workspaceRootReady=false & 无可用快照 → 全量 Manifest 初始化 +``` + +### 4. Docker 实现无第三方依赖 + +Docker 实现通过 Docker CLI(`docker exec`、`docker run` 等)调用,不引入 `docker-java` 库, +保持 `agentscope-harness` 的依赖简洁性。 + +### 5. 子 Agent 传播策略 + +默认策略:子 Agent 使用隔离的沙箱(独立 create)。 +若 `SandboxContext.externalSession` 被显式传递,则使用共享模式。 +通过 `buildGeneralPurposeFactory()` 将 `capturedSandboxFs` 传播给子 Agent,但不传递生命周期管理(`sandboxClient`)。 + +--- + +## 模块结构(最终) + +``` +agentscope-harness/src/main/java/io/agentscope/harness/agent/ +├── sandbox/ +│ ├── SandboxSession.java +│ ├── SandboxClient.java +│ ├── SandboxClientOptions.java ← @JsonSubTypes: unix_local, docker +│ ├── SandboxSessionState.java ← @JsonSubTypes: unix_local, docker +│ ├── SandboxManifest.java +│ ├── SandboxContext.java +│ ├── SandboxAcquireResult.java +│ ├── SandboxManager.java +│ ├── SandboxSessionAware.java +│ ├── SandboxBackedFilesystem.java +│ ├── SandboxException.java +│ ├── SandboxErrorCode.java +│ ├── ExecResult.java +│ ├── AbstractBaseSandboxSession.java +│ ├── ManifestApplier.java +│ ├── WorkspaceArchiveExtractor.java +│ ├── manifest/ +│ │ ├── ManifestEntry.java +│ │ ├── FileEntry.java +│ │ ├── DirEntry.java +│ │ ├── LocalFileEntry.java +│ │ ├── LocalDirEntry.java +│ │ └── GitRepoEntry.java +│ ├── snapshot/ +│ │ ├── SandboxSnapshot.java +│ │ ├── SandboxSnapshotSpec.java +│ │ ├── NoopSandboxSnapshot.java +│ │ ├── NoopSnapshotSpec.java +│ │ ├── LocalSandboxSnapshot.java +│ │ ├── LocalSnapshotSpec.java +│ │ ├── RemoteSandboxSnapshot.java +│ │ ├── RemoteSnapshotSpec.java +│ │ └── RemoteSnapshotClient.java +│ └── impl/ +│ ├── local/ +│ │ ├── UnixLocalSandboxClientOptions.java +│ │ ├── UnixLocalSandboxSessionState.java +│ │ ├── UnixLocalSandboxSession.java +│ │ └── UnixLocalSandboxClient.java +│ └── docker/ +│ ├── DockerSandboxClientOptions.java +│ ├── DockerSandboxSessionState.java +│ ├── DockerSandboxSession.java +│ └── DockerSandboxClient.java +└── hook/ + └── SandboxLifecycleHook.java +``` + +--- + +## 待实现(P2 / 未来方向) + +| 项目 | 说明 | +|------|------| +| `GitRepoEntry` 物化 | 当前仅打印 warn,需实现 `git clone` 逻辑 | +| 工作区指纹缓存 | 避免相同工作区内容重复触发快照恢复,Python 参考实现中的 `snapshotFingerprint` 字段 | +| 子 Agent 共享沙箱 API | 提供更显式的 API 让父 Agent 将自己的 Session 传递给子 Agent | +| Docker Windows 支持 | 当前 Docker 实现仅测试过 Unix 环境 | +| `SandboxFilesystemAdapter` | 将 Session 生命周期与 Filesystem 操作彻底解耦(长期重构方向) | + +--- + +## 测试状态 + +- `agentscope-harness` 模块共 6 个测试,5 个通过 +- `HarnessAgentIntegrationExampleTest.example_fullWorkspace_singleTurn_seesSessionSubagentsAndWorkspaceContext` 失败(Line 150,`expected: but was: `)——此为**预存在缺陷**,在本次 Sandbox 实现开始前已存在,与沙箱代码无关 diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 2f39adaff..45f6aad0a 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -47,7 +47,6 @@ import io.agentscope.harness.agent.hook.CompactionHook; import io.agentscope.harness.agent.hook.MemoryFlushHook; import io.agentscope.harness.agent.hook.MemoryMaintenanceHook; -import io.agentscope.harness.agent.hook.RuntimeContextAwareHook; import io.agentscope.harness.agent.hook.SandboxLifecycleHook; import io.agentscope.harness.agent.hook.SessionPersistenceHook; import io.agentscope.harness.agent.hook.SubagentsHook; @@ -128,39 +127,27 @@ public class HarnessAgent implements Agent, StateModule { private final ReActAgent delegate; private final WorkspaceManager workspaceManager; - private final RuntimeContextAwareHook workspaceContextHook; - private final MemoryFlushHook memoryFlushHook; - private final SessionPersistenceHook sessionPersistenceHook; private final CompactionHook compactionHook; private final AtomicReference userIdRef; private final AtomicReference sessionIdRef; private final Session defaultSession; - private final SandboxLifecycleHook sandboxLifecycleHook; private final SandboxContext defaultSandboxContext; private RuntimeContext runtimeContext; private HarnessAgent( ReActAgent delegate, WorkspaceManager workspaceManager, - RuntimeContextAwareHook workspaceContextHook, - MemoryFlushHook memoryFlushHook, - SessionPersistenceHook sessionPersistenceHook, CompactionHook compactionHook, AtomicReference userIdRef, AtomicReference sessionIdRef, Session defaultSession, - SandboxLifecycleHook sandboxLifecycleHook, SandboxContext defaultSandboxContext) { this.delegate = delegate; this.workspaceManager = workspaceManager; - this.workspaceContextHook = workspaceContextHook; - this.memoryFlushHook = memoryFlushHook; - this.sessionPersistenceHook = sessionPersistenceHook; this.compactionHook = compactionHook; this.userIdRef = userIdRef; this.sessionIdRef = sessionIdRef; this.defaultSession = defaultSession; - this.sandboxLifecycleHook = sandboxLifecycleHook; this.defaultSandboxContext = defaultSandboxContext; } @@ -172,7 +159,7 @@ public Mono call(Msg msg, RuntimeContext ctx) { /** Calls the agent with multiple messages and a runtime context. */ public Mono call(List msgs, RuntimeContext ctx) { bindRuntimeContext(ctx); - return delegate.call(msgs) + return delegate.call(msgs, coreForDelegate()) .onErrorResume( e -> { if (isContextOverflowError(e)) { @@ -185,7 +172,13 @@ public Mono call(List msgs, RuntimeContext ctx) { /** Streams the agent response with a runtime context. */ public Flux stream(List msgs, StreamOptions options, RuntimeContext ctx) { bindRuntimeContext(ctx); - return delegate.stream(msgs, options); + return delegate.stream(msgs, options, coreForDelegate()); + } + + private io.agentscope.core.agent.RuntimeContext coreForDelegate() { + return runtimeContext != null + ? runtimeContext.toCore() + : io.agentscope.core.agent.RuntimeContext.empty(); } private Mono recoverFromOverflow(List msgs) { @@ -227,7 +220,7 @@ private Mono forceCompactAndRetry(Memory memory, List msgs) { for (Msg m : opt.get()) { memory.addMessage(m); } - return delegate.call(msgs); + return delegate.call(msgs, coreRuntimeForRecovery()); } return Mono.error( new RuntimeException( @@ -236,6 +229,12 @@ private Mono forceCompactAndRetry(Memory memory, List msgs) { }); } + private io.agentscope.core.agent.RuntimeContext coreRuntimeForRecovery() { + return runtimeContext != null + ? runtimeContext.toCore() + : io.agentscope.core.agent.RuntimeContext.empty(); + } + private static boolean isContextOverflowError(Throwable e) { String message = e.getMessage(); if (message == null) { @@ -268,21 +267,6 @@ private void bindRuntimeContext(RuntimeContext ctx) { : effective.getSessionId(); sessionIdRef.set(sid); } - if (workspaceContextHook != null) { - workspaceContextHook.setRuntimeContext(effective); - } - if (memoryFlushHook != null) { - memoryFlushHook.setRuntimeContext(effective); - } - if (sessionPersistenceHook != null) { - sessionPersistenceHook.setRuntimeContext(effective); - } - if (compactionHook != null) { - compactionHook.setRuntimeContext(effective); - } - if (sandboxLifecycleHook != null) { - sandboxLifecycleHook.setRuntimeContext(effective); - } if (effective.getSession() != null && effective.getSessionKey() != null) { try { delegate.loadIfExists(effective.getSession(), effective.getSessionKey()); @@ -922,8 +906,6 @@ public HarnessAgent build() { allHooks.add(new AgentTraceHook()); } - RuntimeContextAwareHook wsContextHook; - WorkspaceContextHook markdownHook = new WorkspaceContextHook( wsManager, @@ -932,7 +914,6 @@ public HarnessAgent build() { maxContextTokens); markdownHook.setAdditionalContextFiles(additionalContextFiles); allHooks.add(markdownHook); - wsContextHook = markdownHook; MemoryFlushHook memoryFlushHook = null; if (model != null) { @@ -1026,14 +1007,10 @@ public HarnessAgent build() { return new HarnessAgent( delegate, wsManager, - wsContextHook, - memoryFlushHook, - sessionPersistenceHook, compactionHook, userIdRef, sessionIdRef, effectiveSession, - sandboxLifecycleHook, defaultSandboxContext); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java index a95b6b75b..624c6bd05 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java @@ -18,65 +18,55 @@ import io.agentscope.core.session.Session; import io.agentscope.core.state.SessionKey; import io.agentscope.harness.agent.sandbox.SandboxContext; -import java.util.HashMap; import java.util.Map; /** - * Runtime context passed into agent.call() to carry session-scoped metadata. + * Harness-facing runtime context: wraps {@link io.agentscope.core.agent.RuntimeContext} and adds + * a typed {@link #getSandboxContext() sandbox} view (stored as a typed attribute on the core + * object). * - *

This context is available throughout the reasoning loop (hooks, tools) but is - * NOT persisted to storage media. + *

Pass {@link #toCore()} to {@link io.agentscope.core.ReActAgent#call} when calling the + * delegate directly. */ -public class RuntimeContext { - - private final String sessionId; - private final String userId; - private final Session session; - private final SessionKey sessionKey; - private final Map extra; - private final SandboxContext sandboxContext; - - private RuntimeContext(Builder builder) { - this.sessionId = builder.sessionId; - this.userId = builder.userId; - this.session = builder.session; - this.sessionKey = builder.sessionKey; - this.extra = Map.copyOf(builder.extra); - this.sandboxContext = builder.sandboxContext; +public final class RuntimeContext { + + private final io.agentscope.core.agent.RuntimeContext core; + + private RuntimeContext(io.agentscope.core.agent.RuntimeContext core) { + this.core = core; + } + + public io.agentscope.core.agent.RuntimeContext toCore() { + return core; } public String getSessionId() { - return sessionId; + return core.getSessionId(); } public String getUserId() { - return userId; + return core.getUserId(); } public Session getSession() { - return session; + return core.getSession(); } public SessionKey getSessionKey() { - return sessionKey; + return core.getSessionKey(); } @SuppressWarnings("unchecked") public T get(String key) { - return (T) extra.get(key); + return (T) core.get(key); } public Map getExtra() { - return extra; + return core.getExtra(); } - /** - * Returns the sandbox context for this call. - * - * @return sandbox context, or {@code null} if sandbox is not configured - */ public SandboxContext getSandboxContext() { - return sandboxContext; + return core.get(SandboxContext.class); } public static Builder builder() { @@ -84,58 +74,46 @@ public static Builder builder() { } public static class Builder { - private String sessionId; - private String userId; - private Session session; - private SessionKey sessionKey; - private final Map extra = new HashMap<>(); - private SandboxContext sandboxContext; + private final io.agentscope.core.agent.RuntimeContext.Builder b = + io.agentscope.core.agent.RuntimeContext.builder(); public Builder sessionId(String sessionId) { - this.sessionId = sessionId; + b.sessionId(sessionId); return this; } public Builder userId(String userId) { - this.userId = userId; + b.userId(userId); return this; } public Builder session(Session session) { - this.session = session; + b.session(session); return this; } public Builder sessionKey(SessionKey sessionKey) { - this.sessionKey = sessionKey; + b.sessionKey(sessionKey); return this; } public Builder put(String key, Object value) { - this.extra.put(key, value); + b.put(key, value); return this; } public Builder putAll(Map extras) { - if (extras != null) { - this.extra.putAll(extras); - } + b.putAll(extras); return this; } - /** - * Sets the sandbox context for this call. - * - * @param sandboxContext sandbox configuration and state - * @return this builder - */ public Builder sandboxContext(SandboxContext sandboxContext) { - this.sandboxContext = sandboxContext; + b.put(SandboxContext.class, sandboxContext); return this; } public RuntimeContext build() { - return new RuntimeContext(this); + return new RuntimeContext(b.build()); } } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java index 62cc901b1..2b5e89987 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java @@ -16,14 +16,15 @@ package io.agentscope.harness.agent.hook; import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.memory.Memory; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.model.Model; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.MemoryFlushManager; import io.agentscope.harness.agent.memory.compaction.CompactionConfig; import io.agentscope.harness.agent.memory.compaction.ConversationCompactor; @@ -52,9 +53,9 @@ * (priority 900): compaction runs on the conversation portion first; workspace files are merged into * the system message afterwards on the same {@link PreReasoningEvent} chain. * - *

{@link RuntimeContext} must be injected via {@link #setRuntimeContext} before the hook fires. + *

{@link RuntimeContext} is bound on each call by {@link io.agentscope.core.ReActAgent}. */ -public class CompactionHook implements Hook { +public class CompactionHook implements Hook, RuntimeContextAware { private static final Logger log = LoggerFactory.getLogger(CompactionHook.class); @@ -70,6 +71,7 @@ public CompactionHook(WorkspaceManager workspaceManager, Model model, Compaction this.config = config; } + @Override public void setRuntimeContext(RuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } @@ -80,9 +82,12 @@ public int priority() { } @Override + @SuppressWarnings("unchecked") public Mono onEvent(T event) { if (event instanceof PreReasoningEvent pre) { - return handlePreReasoning(pre).thenReturn(event); + // Must emit a value: Reactor's thenReturn() would not run if the source completed + // "empty" (e.g. Mono.empty() from flatMap), which would drop all later hooks. + return (Mono) (Mono) handlePreReasoning(pre); } return Mono.just(event); } @@ -91,9 +96,9 @@ public Mono onEvent(T event) { // Core compaction flow // ------------------------------------------------------------------------- - private Mono handlePreReasoning(PreReasoningEvent event) { + private Mono handlePreReasoning(PreReasoningEvent event) { if (!(event.getAgent() instanceof ReActAgent reActAgent)) { - return Mono.empty(); + return Mono.just(event); } // Separate system messages (injected by WorkspaceContextHook etc.) from conversation @@ -116,22 +121,22 @@ private Mono handlePreReasoning(PreReasoningEvent event) { return compactor .compactIfNeeded(conversationMsgs, config, agentId, sessionId) - .flatMap( + .flatMap( optResult -> { if (optResult.isEmpty()) { - return Mono.empty(); + return Mono.just(event); } List compacted = optResult.get(); applyToMemory(reActAgent.getMemory(), compacted); applyToEvent(event, systemMsgs, compacted); - return Mono.empty(); + return Mono.just(event); }) .onErrorResume( e -> { log.warn( "Compaction failed, continuing without compaction: {}", e.getMessage()); - return Mono.empty(); + return Mono.just(event); }); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java index f47762b86..0a2317f33 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java @@ -17,13 +17,14 @@ import io.agentscope.core.ReActAgent; import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.memory.Memory; import io.agentscope.core.message.Msg; import io.agentscope.core.model.Model; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.MemoryFlushManager; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.util.List; @@ -43,7 +44,7 @@ *

Priority is 5 — runs early so state is persisted before the session-persistence hook * (priority 900) saves the overall agent state. */ -public class MemoryFlushHook implements Hook { +public class MemoryFlushHook implements Hook, RuntimeContextAware { private static final Logger log = LoggerFactory.getLogger(MemoryFlushHook.class); @@ -56,6 +57,7 @@ public MemoryFlushHook(WorkspaceManager workspaceManager, Model model) { this.model = model; } + @Override public void setRuntimeContext(RuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java index a103c1bbc..f8df58a7d 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java @@ -15,10 +15,10 @@ */ package io.agentscope.harness.agent.hook; -import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.core.hook.RuntimeContextAware; -/** Marker contract for hooks that need per-call {@link RuntimeContext}. */ -public interface RuntimeContextAwareHook { - - void setRuntimeContext(RuntimeContext runtimeContext); -} +/** + * @deprecated Use {@link RuntimeContextAware} in {@code io.agentscope.core.hook} instead. + */ +@Deprecated(since = "1.0", forRemoval = false) +public interface RuntimeContextAwareHook extends RuntimeContextAware {} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java index 62a9d7a4e..72d71a2ab 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java @@ -15,12 +15,13 @@ */ package io.agentscope.harness.agent.hook; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.ErrorEvent; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PostCallEvent; import io.agentscope.core.hook.PreCallEvent; -import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.harness.agent.sandbox.Sandbox; import io.agentscope.harness.agent.sandbox.SandboxAcquireResult; import io.agentscope.harness.agent.sandbox.SandboxBackedFilesystem; @@ -35,7 +36,7 @@ * *

PreCallEvent

*
    - *
  1. Read {@link SandboxContext} from the {@link RuntimeContext}
  2. + *
  3. Read {@link SandboxContext} from the current {@link RuntimeContext}
  4. *
  5. Acquire a session via {@link SandboxManager}
  6. *
  7. Start the session (4-branch workspace init)
  8. *
  9. Inject the live session into the {@link SandboxBackedFilesystem} proxy
  10. @@ -53,7 +54,7 @@ *

    Post-call failures (persist, release) are logged but do not propagate — this ensures * the agent call result is always returned to the caller even if sandbox cleanup fails. */ -public class SandboxLifecycleHook implements Hook, RuntimeContextAwareHook { +public class SandboxLifecycleHook implements Hook, RuntimeContextAware { private static final Logger log = LoggerFactory.getLogger(SandboxLifecycleHook.class); @@ -87,8 +88,8 @@ public int priority() { } @Override - public void setRuntimeContext(RuntimeContext runtimeContext) { - this.runtimeContext = runtimeContext; + public void setRuntimeContext(RuntimeContext ctx) { + this.runtimeContext = ctx; } @SuppressWarnings("unchecked") @@ -111,7 +112,7 @@ private Mono handlePreCall(T event) { return Mono.just(event); } - SandboxContext sandboxContext = ctx.getSandboxContext(); + SandboxContext sandboxContext = ctx.get(SandboxContext.class); if (sandboxContext == null) { return Mono.just(event); } @@ -164,7 +165,8 @@ private Mono handlePost(T event) { } RuntimeContext ctx = runtimeContext; - SandboxContext sandboxContext = ctx != null ? ctx.getSandboxContext() : null; + SandboxContext sandboxContext = + ctx != null ? ctx.get(SandboxContext.class) : null; // Persist state first (before release destroys workspace) try { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java index f10034082..700d3b87f 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SessionPersistenceHook.java @@ -16,12 +16,13 @@ package io.agentscope.harness.agent.hook; import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.ErrorEvent; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PostCallEvent; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.state.StateModule; -import io.agentscope.harness.agent.RuntimeContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; @@ -33,19 +34,20 @@ * ensure state is saved regardless of outcome. The save is best-effort: failures are logged but * do not propagate exceptions. * - *

    Session and SessionKey are obtained from the {@link RuntimeContext} injected via - * {@link #setRuntimeContext(RuntimeContext)}. When no session is configured in the context, + *

    Session and SessionKey are obtained from the {@link RuntimeContext} set per call. When no + * session is configured in the context, * the hook is a no-op. * *

    Priority is set to 900 (low) so this hook runs after other hooks like * {@link MemoryFlushHook} have completed their work. */ -public class SessionPersistenceHook implements Hook { +public class SessionPersistenceHook implements Hook, RuntimeContextAware { private static final Logger log = LoggerFactory.getLogger(SessionPersistenceHook.class); private RuntimeContext runtimeContext; + @Override public void setRuntimeContext(RuntimeContext ctx) { this.runtimeContext = ctx; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java index 9cb11a383..86321bdbd 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java @@ -15,14 +15,15 @@ */ package io.agentscope.harness.agent.hook; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.message.ContentBlock; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.nio.file.Path; import java.time.LocalDate; @@ -39,7 +40,7 @@ * workspace files using XML-style {@code } blocks to compare against markdown * sectioning. */ -public class WorkspaceContextHook implements Hook, RuntimeContextAwareHook { +public class WorkspaceContextHook implements Hook, RuntimeContextAware { private static final String SESSION_CONTEXT_SECTION_TEMPLATE = """ @@ -117,6 +118,7 @@ public void setAdditionalContextFiles(List files) { this.additionalContextFiles = files != null ? files : List.of(); } + @Override public void setRuntimeContext(RuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java index a85869d73..5aa557cb7 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKey.java @@ -15,8 +15,8 @@ */ package io.agentscope.harness.agent.sandbox; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import java.util.Objects; import java.util.Optional; import org.slf4j.Logger; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java index 4b4e59e02..9cce0ec9c 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java @@ -15,7 +15,7 @@ */ package io.agentscope.harness.agent.sandbox; -import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.core.agent.RuntimeContext; import java.util.Objects; import java.util.Optional; import org.slf4j.Logger; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java index ee3611ebc..eb9ec4c95 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java @@ -146,16 +146,27 @@ void example_fullWorkspace_singleTurn_seesSessionSubagentsAndWorkspaceContext() .findFirst() .orElse(""); - assertTrue(combined.contains("## Session Context"), "Session context should be injected"); - assertTrue(combined.contains("# Project Context")); - assertTrue(combined.contains("## AGENTS.md")); + assertTrue( + combined.contains("## Session Context"), + "Session context should be injected; model saw: " + + captor.getAllValues().stream() + .map(HarnessAgentIntegrationExampleTest::joinAllText) + .toList()); + // Current WorkspaceContextHook uses markdown (##) guidance + XML blocks + assertTrue( + combined.contains("## Domain Knowledge") || combined.contains("## Workspace"), + "expected workspace guidance sections"); + assertTrue(combined.contains("`AGENTS.md`") || combined.contains("agents_context")); assertTrue( combined.contains(agentsPersona), "AGENTS.md should appear under workspace hook"); - assertTrue(combined.contains("## MEMORY.md")); + assertTrue(combined.contains("memory_context") || combined.contains("MEMORY.md")); assertTrue(combined.contains(memoryNote)); - assertTrue(combined.contains("## KNOWLEDGE.md")); + assertTrue( + combined.contains("domain_knowledge_context") || combined.contains("KNOWLEDGE.md")); assertTrue(combined.contains(knowledgeLine)); - assertTrue(combined.contains("## Subagents")); + assertTrue( + combined.contains("## Subagents") || combined.contains("Subagents:"), + "subagent list should be injected into the system prompt"); assertTrue(combined.contains("`" + helperSubId + "`")); assertTrue(combined.contains("`" + reviewerSubId + "`")); } diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java index 29b49e776..40191f8fc 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -123,8 +123,8 @@ void sessionScope_differentSession_createsFreshSandbox() throws Exception { .filesystem(spec) .build(); - agent.call(userMsg("call from session-1"), ctx("session-1", "alice")).block(); - agent.call(userMsg("call from session-2"), ctx("session-2", "alice")).block(); + agent.call(userMsg("call from session-1"), ctx("session-2-1", "alice")).block(); + agent.call(userMsg("call from session-2"), ctx("session-2-2", "alice")).block(); assertEquals( 2, client.getCreateCount(), "each distinct session should create its own sandbox"); @@ -186,8 +186,8 @@ void userScope_differentUsers_createsFreshSandbox() throws Exception { .filesystem(spec) .build(); - agent.call(userMsg("hi from alice"), ctx("s1", "alice")).block(); - agent.call(userMsg("hi from bob"), ctx("s2", "bob")).block(); + agent.call(userMsg("hi from alice2"), ctx("s1", "alice2")).block(); + agent.call(userMsg("hi from bob2"), ctx("s2", "bob2")).block(); assertEquals(2, client.getCreateCount(), "each user should get their own fresh sandbox"); assertEquals(0, client.getResumeCount()); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java index 3a23aef76..96e0a8c7b 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java @@ -34,7 +34,7 @@ void sessionScope_withSessionKey_resolvesCorrectly() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-abc")).build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.SESSION, key.get().getScope()); assertEquals("sess-abc", key.get().getValue()); @@ -44,7 +44,7 @@ void sessionScope_withSessionKey_resolvesCorrectly() { void sessionScope_missingSessionKey_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); assertFalse(key.isPresent()); } @@ -60,7 +60,7 @@ void nullScope_treatedAsSession_withSessionKey() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-def")).build(); Optional key = - SandboxIsolationKey.resolve((IsolationScope) null, ctx, AGENT_ID); + SandboxIsolationKey.resolve((IsolationScope) null, ctx.toCore(), AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.SESSION, key.get().getScope()); assertEquals("sess-def", key.get().getValue()); @@ -70,7 +70,7 @@ void nullScope_treatedAsSession_withSessionKey() { void userScope_withUserId_resolvesCorrectly() { RuntimeContext ctx = RuntimeContext.builder().userId("user-123").build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.USER, key.get().getScope()); assertEquals("user-123", key.get().getValue()); @@ -80,7 +80,7 @@ void userScope_withUserId_resolvesCorrectly() { void userScope_blankUserId_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().userId(" ").build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); assertFalse(key.isPresent()); } @@ -88,7 +88,7 @@ void userScope_blankUserId_returnsEmpty() { void userScope_nullUserId_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); assertFalse(key.isPresent()); } @@ -103,7 +103,7 @@ void userScope_nullContext_returnsEmpty() { void agentScope_alwaysResolvesToAgentId() { Optional keyWithCtx = SandboxIsolationKey.resolve( - IsolationScope.AGENT, RuntimeContext.builder().build(), AGENT_ID); + IsolationScope.AGENT, RuntimeContext.builder().build().toCore(), AGENT_ID); Optional keyNullCtx = SandboxIsolationKey.resolve(IsolationScope.AGENT, null, AGENT_ID); @@ -128,9 +128,9 @@ void globalScope_alwaysResolvesToGlobalValue() { void equalsAndHashCode_sameValues_areEqual() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("s1")).build(); Optional k1 = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); Optional k2 = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); assertTrue(k1.isPresent() && k2.isPresent()); assertEquals(k1.get(), k2.get()); assertEquals(k1.get().hashCode(), k2.get().hashCode()); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java index 8171b1c2b..852d5958c 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java @@ -99,7 +99,7 @@ void priority3_stateStoreHit_resumesSession() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx); + SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(resumedSandbox, result.getSandbox()); assertEquals(true, result.isSdkOwned()); @@ -121,7 +121,7 @@ void priority3_stateStoreMiss_createsFreshSession() throws Exception { .snapshotSpec(snapshotSpec) .build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx); + SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(freshSandbox, result.getSandbox()); verify(client).create(any(), any(), any()); @@ -136,7 +136,7 @@ void noScopeKey_createsFreshSession() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no sessionKey SandboxContext sCtx = SandboxContext.builder().build(); // scope = SESSION (default) - SandboxAcquireResult result = manager.acquire(sCtx, rtx); + SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(freshSandbox, result.getSandbox()); verify(stateStore, never()).load(any()); @@ -153,7 +153,7 @@ void userScope_withUserId_loadsFromStore() throws Exception { RuntimeContext rtx = RuntimeContext.builder().userId("user-42").build(); SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx); + SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(resumedSandbox, result.getSandbox()); } @@ -165,7 +165,7 @@ void userScope_missingUserId_createsFreshSession() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no userId SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx); + SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(freshSandbox, result.getSandbox()); verify(stateStore, never()).load(any()); @@ -218,7 +218,7 @@ void persistState_savesJsonForResolvedScopeKey() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - manager.persistState(result, sCtx, rtx); + manager.persistState(result, sCtx, rtx.toCore()); verify(stateStore).save(any(), any()); } @@ -232,7 +232,7 @@ void persistState_missingScopeKey_skipped() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no session key SandboxContext sCtx = SandboxContext.builder().build(); // SESSION scope by default - manager.persistState(result, sCtx, rtx); + manager.persistState(result, sCtx, rtx.toCore()); verify(stateStore, never()).save(any(), any()); } @@ -246,7 +246,7 @@ void clearState_deletesFromStore() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - manager.clearState(sCtx, rtx); + manager.clearState(sCtx, rtx.toCore()); verify(stateStore).delete(any()); } diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java index abfab74b3..5b8615cb6 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java @@ -86,7 +86,7 @@ void deleteUsesTombstone_evenWhenSessionDeleteUnsupported() throws Exception { } private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { - return SandboxIsolationKey.resolve(scope, runtimeContext(scope, value), AGENT_ID) + return SandboxIsolationKey.resolve(scope, runtimeContext(scope, value).toCore(), AGENT_ID) .orElseThrow(); } diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java index 063e30c64..4a54cbe79 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java @@ -211,7 +211,7 @@ void sessionScope_usesDirectFileIo() throws Exception { private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { return SandboxIsolationKey.resolve( scope, - buildCtxForScope(scope, value), + buildCtxForScope(scope, value).toCore(), value.startsWith("user") || scope == IsolationScope.GLOBAL ? "test-agent" : value) From cab799bfd072b55afc0f12d4c7cc8c9e76a1093c Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 00:46:43 +0800 Subject: [PATCH 06/28] add harness sandbox example --- .../harness-example-sandbox/pom.xml | 67 +++++++ .../sandbox/HarnessSandboxExampleApp.java | 50 +++++ ...calFilesystemPersonalAssistantExample.java | 132 +++++++++++++ ...andboxFilesystemIsolationScopeExample.java | 176 +++++++++++++++++ .../StoreFilesystemIsolationScopeExample.java | 179 ++++++++++++++++++ .../sandbox/support/FixedReplyModel.java | 64 +++++++ .../sandbox/support/InMemorySandbox.java | 116 ++++++++++++ .../support/InMemorySandboxClient.java | 122 ++++++++++++ .../InMemorySandboxFilesystemSpec.java | 81 ++++++++ .../sandbox/support/InMemorySandboxState.java | 41 ++++ agentscope-examples/pom.xml | 1 + 11 files changed, 1029 insertions(+) create mode 100644 agentscope-examples/harness-example-sandbox/pom.xml create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java diff --git a/agentscope-examples/harness-example-sandbox/pom.xml b/agentscope-examples/harness-example-sandbox/pom.xml new file mode 100644 index 000000000..a7c825582 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/pom.xml @@ -0,0 +1,67 @@ + + + + + 4.0.0 + + io.agentscope + agentscope-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Sandbox Example + io.agentscope.examples + harness-example-sandbox + jar + Runnable examples: local filesystem, in-memory sandbox isolation scopes, and store-backed namespaces (no remote LLM required) + + + 2.24.3 + + + + + io.agentscope + agentscope-harness + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.apache.logging.log4j + log4j-slf4j2-impl + ${log4j2.version} + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.6.3 + + io.agentscope.examples.harness.sandbox.HarnessSandboxExampleApp + + + + + diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java new file mode 100644 index 000000000..1b4edf3e6 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java @@ -0,0 +1,50 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; + +/** + * Runs harness filesystem examples (local, in-memory sandbox, in-memory store). No LLM API key + * required — uses {@link FixedReplyModel} for a single turn per {@code call}. + * + *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|store]} + */ +public final class HarnessSandboxExampleApp { + + public static void main(String[] args) throws Exception { + String mode = args.length == 0 ? "all" : args[0].toLowerCase(); + System.out.println( + "Model: " + FixedReplyModel.done().getModelName() + " (no remote LLM)\n"); + switch (mode) { + case "all" -> { + LocalFilesystemPersonalAssistantExample.main(new String[0]); + System.out.println(); + SandboxFilesystemIsolationScopeExample.main(new String[0]); + System.out.println(); + StoreFilesystemIsolationScopeExample.main(new String[0]); + } + case "local" -> LocalFilesystemPersonalAssistantExample.main(new String[0]); + case "sandbox" -> SandboxFilesystemIsolationScopeExample.main(new String[0]); + case "store" -> StoreFilesystemIsolationScopeExample.main(new String[0]); + default -> { + System.err.println("Unknown mode: " + mode); + System.err.println("Use: all | local | sandbox | store"); + System.exit(1); + } + } + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java new file mode 100644 index 000000000..359891ec9 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java @@ -0,0 +1,132 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.Model; +import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Example: local personal-assistant mode using {@link LocalFilesystemWithShell} — direct disk I/O + * and {@link ProcessBuilder} shell in one workspace, no container or distributed store. + */ +public final class LocalFilesystemPersonalAssistantExample { + + public static void main(String[] args) throws Exception { + Model model = FixedReplyModel.done(); + Path workspace = Files.createTempDirectory("harness-local-fs-example-"); + System.out.println("Workspace: " + workspace.toAbsolutePath()); + + demonstrateFilesPersistAcrossCalls(workspace, model); + demonstrateSharedWorkspaceForAllUsersAndSessions(workspace, model); + demonstrateHostWrittenFileVisibleToAgent(workspace, model); + + System.out.println("Local filesystem example finished successfully."); + } + + static void demonstrateFilesPersistAcrossCalls(Path workspace, Model model) throws Exception { + Files.createDirectories(workspace); + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + agent.call(userMsg("first call"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "# Notes\n- item 1"); + + Path memoryFile = workspace.resolve("MEMORY.md"); + if (!Files.isRegularFile(memoryFile)) { + throw new IllegalStateException("MEMORY.md should exist on disk after first call"); + } + String content = Files.readString(memoryFile, StandardCharsets.UTF_8); + if (!content.contains("item 1")) { + throw new IllegalStateException("MEMORY.md should contain persisted item"); + } + + agent.call(userMsg("second call"), ctx("session-2", "alice")).block(); + if (!Files.isRegularFile(memoryFile)) { + throw new IllegalStateException("MEMORY.md should still exist after second call"); + } + if (!content.equals(Files.readString(memoryFile, StandardCharsets.UTF_8))) { + throw new IllegalStateException("MEMORY.md content should be unchanged"); + } + System.out.println("[local] files persist across calls: OK"); + } + + static void demonstrateSharedWorkspaceForAllUsersAndSessions(Path workspace, Model model) + throws Exception { + Files.createDirectories(workspace); + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + agent.call(userMsg("alice here"), ctx("session-alice", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("shared.txt", "alice was here"); + agent.call(userMsg("bob here"), ctx("session-bob", "bob")).block(); + if (!Files.isRegularFile(workspace.resolve("shared.txt"))) { + throw new IllegalStateException( + "local workspace is not partitioned by user or session"); + } + System.out.println("[local] same workspace for all user/session context values: OK"); + } + + static void demonstrateHostWrittenFileVisibleToAgent(Path workspace, Model model) + throws Exception { + Files.createDirectories(workspace); + HarnessAgent agent = + HarnessAgent.builder() + .name("my-local-assistant") + .model(model) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystemWithShell(workspace)) + .build(); + + Path doc = workspace.resolve("document.txt"); + Files.writeString(doc, "Host-written document content"); + agent.call(userMsg("check document"), ctx("s1", "user")).block(); + String read = agent.getWorkspaceManager().readManagedWorkspaceFileUtf8("document.txt"); + if (read == null || !read.contains("Host-written")) { + throw new IllegalStateException("agent should read host-written file"); + } + System.out.println("[local] host file visible to workspace manager: OK"); + } + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java new file mode 100644 index 000000000..d2845bfba --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java @@ -0,0 +1,176 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.Model; +import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Example: sandbox filesystem with {@link IsolationScope} (in-process {@link InMemorySandboxClient} + * simulates create/resume without Docker). + */ +public final class SandboxFilesystemIsolationScopeExample { + + public static void main(String[] args) throws Exception { + Model model = FixedReplyModel.done(); + Path workspace = Files.createTempDirectory("harness-sandbox-isolation-example-"); + System.out.println("Control workspace: " + workspace.toAbsolutePath()); + + sessionScopeSameSessionResumes(workspace, model); + sessionScopeDifferentSessionCreatesTwo(workspace, model); + userScopeSameUserResumesAcrossSessions(workspace, model); + userScopeDifferentUsersGetTwoSandboxes(workspace, model); + agentScopeEveryoneSharesOneSandbox(workspace, model); + + System.out.println("Sandbox isolation example finished successfully."); + } + + static void sessionScopeSameSessionResumes(Path workspace, Model model) throws Exception { + Files.createDirectories(workspace); + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.SESSION); + InMemorySandboxClient client = spec.getClient(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("hello"), ctx("session-1", null)).block(); + if (client.getCreateCount() != 1 || client.getResumeCount() != 0) { + throw new IllegalStateException("expected 1 create, 0 resume after first call"); + } + agent.call(userMsg("hello again"), ctx("session-1", null)).block(); + if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { + throw new IllegalStateException("expected 1 create, 1 resume for same session"); + } + System.out.println("[sandbox] SESSION: same session resumes: OK"); + } + + static void sessionScopeDifferentSessionCreatesTwo(Path workspace, Model model) + throws Exception { + Files.createDirectories(workspace); + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.SESSION); + InMemorySandboxClient client = spec.getClient(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("call from session-DifferentSessionCreatesTwo-1"), ctx("session-DifferentSessionCreatesTwo-1", "alice")).block(); + agent.call(userMsg("call from session-DifferentSessionCreatesTwo-2"), ctx("session-DifferentSessionCreatesTwo-2", "alice")).block(); + if (client.getCreateCount() != 2 || client.getResumeCount() != 0) { + throw new IllegalStateException("expected 2 creates for distinct sessions"); + } + System.out.println("[sandbox] SESSION: different sessions get new sandboxes: OK"); + } + + static void userScopeSameUserResumesAcrossSessions(Path workspace, Model model) + throws Exception { + Files.createDirectories(workspace); + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.USER); + InMemorySandboxClient client = spec.getClient(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("session A"), ctx("session-a", "alice")).block(); + if (client.getCreateCount() != 1) { + throw new IllegalStateException("expected 1 create"); + } + agent.call(userMsg("session B"), ctx("session-b", "alice")).block(); + if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { + throw new IllegalStateException("same user should resume across sessions"); + } + System.out.println("[sandbox] USER: same user resumes across sessions: OK"); + } + + static void userScopeDifferentUsersGetTwoSandboxes(Path workspace, Model model) + throws Exception { + Files.createDirectories(workspace); + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.USER); + InMemorySandboxClient client = spec.getClient(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("hi from alice2"), ctx("s1", "alice2")).block(); + agent.call(userMsg("hi from bob2"), ctx("s2", "bob2")).block(); + if (client.getCreateCount() != 2) { + throw new IllegalStateException("each user should get a new sandbox"); + } + System.out.println("[sandbox] USER: different users are isolated: OK"); + } + + static void agentScopeEveryoneSharesOneSandbox(Path workspace, Model model) throws Exception { + Files.createDirectories(workspace); + InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); + spec.isolationScope(IsolationScope.AGENT); + InMemorySandboxClient client = spec.getClient(); + HarnessAgent agent = + HarnessAgent.builder() + .name("shared-assistant") + .model(model) + .workspace(workspace) + .filesystem(spec) + .build(); + + agent.call(userMsg("alice says hi"), ctx("s1", "alice")).block(); + agent.call(userMsg("bob says hi"), ctx("s2", "bob")).block(); + agent.call(userMsg("charlie says hi"), ctx("s3", "charlie")).block(); + if (client.getCreateCount() != 1 || client.getResumeCount() != 2) { + throw new IllegalStateException("AGENT scope: 1 create, 2 resume"); + } + System.out.println("[sandbox] AGENT: all callers share one sandbox: OK"); + } + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java new file mode 100644 index 000000000..bada1e9b3 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java @@ -0,0 +1,179 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.Model; +import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.store.InMemoryStore; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +/** + * Example: {@link StoreFilesystemSpec} with in-memory key-value store and different {@link + * IsolationScope} namespaces. + */ +public final class StoreFilesystemIsolationScopeExample { + + public static void main(String[] args) throws Exception { + Model model = FixedReplyModel.done(); + Path workspace = Files.createTempDirectory("harness-store-isolation-example-"); + System.out.println("Workspace: " + workspace.toAbsolutePath()); + + sessionScopeIsolated(model, workspace); + sessionScopeSharedWithinSession(model, workspace); + userScopeSharedAcrossSessions(model, workspace); + userScopeIsolatedByUser(model, workspace); + agentScopeSharedByAllCallers(model, workspace); + + System.out.println("Store isolation example finished successfully."); + } + + static void sessionScopeIsolated(Model model, Path workspace) throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store) + .isolationScope(IsolationScope.SESSION)) + .build(); + + agent.call(userMsg("from session-1"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "session-1 notes"); + if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") + == null) { + throw new IllegalStateException("data should exist under session-1"); + } + if (store.get(List.of("agents", "assistant", "sessions", "session-2"), "/MEMORY.md") + != null) { + throw new IllegalStateException("session-2 namespace should be empty"); + } + System.out.println("[store] SESSION: per-session namespace: OK"); + } + + static void sessionScopeSharedWithinSession(Model model, Path workspace) throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store) + .isolationScope(IsolationScope.SESSION)) + .build(); + + agent.call(userMsg("call 1"), ctx("session-1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared memory"); + agent.call(userMsg("call 2"), ctx("session-1", "alice")).block(); + if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") + == null) { + throw new IllegalStateException("MEMORY under session-1"); + } + System.out.println("[store] SESSION: same session reuses key: OK"); + } + + static void userScopeSharedAcrossSessions(Model model, Path workspace) throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .build(); + + agent.call(userMsg("hi from session-a"), ctx("session-a", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's memory"); + if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { + throw new IllegalStateException("data under user alice"); + } + agent.call(userMsg("hi from session-b"), ctx("session-b", "alice")).block(); + if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { + throw new IllegalStateException("alice's key still present"); + } + System.out.println("[store] USER: one namespace per user: OK"); + } + + static void userScopeIsolatedByUser(Model model, Path workspace) throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + HarnessAgent agent = + HarnessAgent.builder() + .name("assistant") + .model(model) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .build(); + + agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's data"); + if (store.get(List.of("agents", "assistant", "users", "bob"), "/MEMORY.md") != null) { + throw new IllegalStateException("bob should not see alice's data"); + } + System.out.println("[store] USER: users are isolated: OK"); + } + + static void agentScopeSharedByAllCallers(Model model, Path workspace) throws Exception { + Files.createDirectories(workspace); + InMemoryStore store = new InMemoryStore(); + HarnessAgent agent = + HarnessAgent.builder() + .name("shared-assistant") + .model(model) + .workspace(workspace) + .filesystem( + new StoreFilesystemSpec(store).isolationScope(IsolationScope.AGENT)) + .build(); + + agent.call(userMsg("alice"), ctx("s1", "alice")).block(); + agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared knowledge"); + if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { + throw new IllegalStateException("shared namespace"); + } + agent.call(userMsg("bob"), ctx("s2", "bob")).block(); + if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { + throw new IllegalStateException("data still in shared"); + } + System.out.println("[store] AGENT: shared key for all callers: OK"); + } + + private static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + private static Msg userMsg(String text) { + return Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java new file mode 100644 index 000000000..573283e7e --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java @@ -0,0 +1,64 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.GenerateOptions; +import io.agentscope.core.model.Model; +import io.agentscope.core.model.ToolSchema; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import reactor.core.publisher.Flux; + +/** + * A minimal, deterministic {@link Model} implementation for examples: one assistant text turn + * with finish reason {@code stop}, so the agent loop can complete without remote LLM calls. + */ +public final class FixedReplyModel implements Model { + + private final String modelName; + private final String replyText; + + public FixedReplyModel(String modelName, String replyText) { + this.modelName = modelName; + this.replyText = replyText; + } + + public static FixedReplyModel done() { + return new FixedReplyModel("fixed-reply", "done"); + } + + @Override + public String getModelName() { + return modelName; + } + + @Override + public Flux stream( + List messages, List tools, GenerateOptions options) { + ChatResponse chunk = + new ChatResponse( + "local-" + UUID.randomUUID(), + List.of(TextBlock.builder().text(replyText).build()), + null, + Map.of(), + "stop"); + return Flux.just(chunk); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java new file mode 100644 index 000000000..4ee8de504 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java @@ -0,0 +1,116 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.ExecResult; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxState; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * In-process {@link Sandbox} that uses a local temp directory as the workspace (for examples). + */ +public class InMemorySandbox implements Sandbox { + + private final InMemorySandboxState state; + private final Path workspaceDir; + private final AtomicBoolean running = new AtomicBoolean(false); + private final int defaultTimeoutSeconds; + + public InMemorySandbox(InMemorySandboxState state, int defaultTimeoutSeconds) { + this.state = state; + this.workspaceDir = Path.of(state.getWorkspaceRoot()); + this.defaultTimeoutSeconds = defaultTimeoutSeconds; + } + + @Override + public void start() throws Exception { + if (!Files.exists(workspaceDir)) { + Files.createDirectories(workspaceDir); + } + state.setWorkspaceRootReady(true); + running.set(true); + } + + @Override + public void stop() throws Exception { + state.setWorkspaceRootReady(true); + running.set(false); + } + + @Override + public void shutdown() throws Exception { + // Leave workspace dir in place for resume in tests + } + + @Override + public void close() throws Exception { + try { + stop(); + } catch (Exception e) { + // best-effort + } + shutdown(); + } + + @Override + public boolean isRunning() { + return running.get(); + } + + @Override + public SandboxState getState() { + return state; + } + + @Override + public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { + int timeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeoutSeconds; + ProcessBuilder pb = new ProcessBuilder("sh", "-c", command); + pb.directory(workspaceDir.toFile()); + pb.redirectErrorStream(false); + Process process = pb.start(); + + boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + return new ExecResult(124, "", "Command timed out after " + timeout + "s", false); + } + + String stdout = new String(process.getInputStream().readAllBytes()); + String stderr = new String(process.getErrorStream().readAllBytes()); + return new ExecResult(process.exitValue(), stdout, stderr, false); + } + + @Override + public InputStream persistWorkspace() throws Exception { + return new ByteArrayInputStream(new byte[1024]); + } + + @Override + public void hydrateWorkspace(InputStream archive) throws Exception { + // no-op + } + + public Path getWorkspaceDir() { + return workspaceDir; + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java new file mode 100644 index 000000000..88b9c6c16 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java @@ -0,0 +1,122 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** In-process {@link SandboxClient} that allocates local temp directories as sandboxes. */ +public class InMemorySandboxClient implements SandboxClient { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final int DEFAULT_TIMEOUT_SECONDS = 30; + + private final AtomicInteger createCount = new AtomicInteger(0); + private final AtomicInteger resumeCount = new AtomicInteger(0); + private final Path baseDir; + + public InMemorySandboxClient() { + try { + this.baseDir = Files.createTempDirectory("agentscope-inmemory-sandbox-"); + } catch (IOException e) { + throw new UncheckedIOException( + "Failed to create base temp dir for InMemorySandboxClient", e); + } + } + + @Override + public Sandbox create( + WorkspaceSpec workspaceSpec, + SandboxSnapshotSpec snapshotSpec, + SandboxClientOptions options) { + createCount.incrementAndGet(); + String sessionId = UUID.randomUUID().toString(); + Path workspaceDir = baseDir.resolve(sessionId); + try { + Files.createDirectories(workspaceDir); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create workspace dir", e); + } + + InMemorySandboxState state = new InMemorySandboxState(sessionId, workspaceDir.toString()); + WorkspaceSpec spec = workspaceSpec != null ? workspaceSpec.copy() : new WorkspaceSpec(); + spec.setRoot(workspaceDir.toString()); + state.setWorkspaceSpec(spec); + + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public Sandbox resume(SandboxState sessionState) { + resumeCount.incrementAndGet(); + InMemorySandboxState state = (InMemorySandboxState) sessionState; + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public void delete(Sandbox session) { + // no-op + } + + @Override + public String serializeState(SandboxState state) { + try { + InMemorySandboxState s = (InMemorySandboxState) state; + return MAPPER.writeValueAsString(new StateDto(s.getSessionId(), s.getWorkspaceRoot())); + } catch (IOException e) { + throw new UncheckedIOException("Failed to serialize sandbox state", e); + } + } + + @Override + public SandboxState deserializeState(String json) { + try { + StateDto dto = MAPPER.readValue(json, StateDto.class); + InMemorySandboxState state = + new InMemorySandboxState(dto.sessionId(), dto.workspaceRoot()); + state.setWorkspaceRootReady(true); + return state; + } catch (IOException e) { + throw new UncheckedIOException("Failed to deserialize sandbox state", e); + } + } + + public int getCreateCount() { + return createCount.get(); + } + + public int getResumeCount() { + return resumeCount.get(); + } + + public void resetCounts() { + createCount.set(0); + resumeCount.set(0); + } + + record StateDto(String sessionId, String workspaceRoot) {} +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java new file mode 100644 index 000000000..b34b7e5fb --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java @@ -0,0 +1,81 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; + +/** + * {@link SandboxFilesystemSpec} backed by an {@link InMemorySandboxClient}. + * + *

    Uses a local temp directory as the sandbox workspace. No Docker or external services are + * required. The {@link InMemorySandboxClient} exposes create/resume counters to illustrate + * {@link io.agentscope.harness.agent.IsolationScope} behaviour. + */ +public class InMemorySandboxFilesystemSpec extends SandboxFilesystemSpec { + + private final InMemorySandboxClient client; + + /** + * Creates a spec backed by the given in-memory sandbox client. + * + * @param client the in-memory client to use for session create/resume + */ + public InMemorySandboxFilesystemSpec(InMemorySandboxClient client) { + this.client = client; + } + + /** + * Creates a spec with a new default {@link InMemorySandboxClient}. + */ + public InMemorySandboxFilesystemSpec() { + this(new InMemorySandboxClient()); + } + + /** + * Returns the underlying {@link InMemorySandboxClient}. + * + * @return the client + */ + public InMemorySandboxClient getClient() { + return client; + } + + @Override + protected SandboxClient createClient() { + return client; + } + + @Override + protected SandboxClientOptions clientOptions() { + return null; + } + + @Override + protected SandboxSnapshotSpec snapshotSpec() { + return null; + } + + @Override + protected WorkspaceSpec workspaceSpec() { + WorkspaceSpec s = new WorkspaceSpec(); + s.setRoot("/workspace"); + return s; + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java new file mode 100644 index 000000000..d2be8fc79 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxState; + +/** + * In-memory {@link SandboxState} for {@link InMemorySandboxClient}. + */ +public class InMemorySandboxState extends SandboxState { + + private String workspaceRoot; + + public InMemorySandboxState() {} + + public InMemorySandboxState(String sessionId, String workspaceRoot) { + setSessionId(sessionId); + this.workspaceRoot = workspaceRoot; + } + + public String getWorkspaceRoot() { + return workspaceRoot; + } + + public void setWorkspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } +} diff --git a/agentscope-examples/pom.xml b/agentscope-examples/pom.xml index e9d8e99ad..ca8d3c0bd 100644 --- a/agentscope-examples/pom.xml +++ b/agentscope-examples/pom.xml @@ -56,6 +56,7 @@ multiagent-patterns/skills a2a-rocketmq harness-example + harness-example-sandbox From f1d2ff9f0fae659ffb6c14156bb718b2d3926f94 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 00:50:11 +0800 Subject: [PATCH 07/28] code format --- .../SandboxFilesystemIsolationScopeExample.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java index d2845bfba..c309766cf 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java @@ -86,8 +86,14 @@ static void sessionScopeDifferentSessionCreatesTwo(Path workspace, Model model) .filesystem(spec) .build(); - agent.call(userMsg("call from session-DifferentSessionCreatesTwo-1"), ctx("session-DifferentSessionCreatesTwo-1", "alice")).block(); - agent.call(userMsg("call from session-DifferentSessionCreatesTwo-2"), ctx("session-DifferentSessionCreatesTwo-2", "alice")).block(); + agent.call( + userMsg("call from session-DifferentSessionCreatesTwo-1"), + ctx("session-DifferentSessionCreatesTwo-1", "alice")) + .block(); + agent.call( + userMsg("call from session-DifferentSessionCreatesTwo-2"), + ctx("session-DifferentSessionCreatesTwo-2", "alice")) + .block(); if (client.getCreateCount() != 2 || client.getResumeCount() != 0) { throw new IllegalStateException("expected 2 creates for distinct sessions"); } From 4d795e3ce841e71148fd8cb25c7715db4ea7b5e4 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 00:54:59 +0800 Subject: [PATCH 08/28] delete .agentscope --- .agentscope/workspace/knowledge/KNOWLEDGE.md | 187 ------------------ .../workspace/skills/query-writing/SKILL.md | 148 -------------- .../skills/schema-exploration/SKILL.md | 136 ------------- .../workspace/subagents/query-optimizer.md | 53 ----- .../workspace/subagents/schema-analyst.md | 50 ----- 5 files changed, 574 deletions(-) delete mode 100644 .agentscope/workspace/knowledge/KNOWLEDGE.md delete mode 100644 .agentscope/workspace/skills/query-writing/SKILL.md delete mode 100644 .agentscope/workspace/skills/schema-exploration/SKILL.md delete mode 100644 .agentscope/workspace/subagents/query-optimizer.md delete mode 100644 .agentscope/workspace/subagents/schema-analyst.md diff --git a/.agentscope/workspace/knowledge/KNOWLEDGE.md b/.agentscope/workspace/knowledge/KNOWLEDGE.md deleted file mode 100644 index ad6c7c40d..000000000 --- a/.agentscope/workspace/knowledge/KNOWLEDGE.md +++ /dev/null @@ -1,187 +0,0 @@ -# Chinook Database — Schema Reference - -The Chinook database represents a digital music store. It was originally created to demonstrate -data modelling in SQLite and is widely used as a sample database for tutorials. - -## Entity Relationship Overview - -``` -Artist (ArtistId, Name) - └─ 1:many ─► Album (AlbumId, Title, ArtistId) - └─ 1:many ─► Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, - Composer, Milliseconds, Bytes, UnitPrice) - └─ 1:many ─► InvoiceLine (InvoiceLineId, InvoiceId, - TrackId, UnitPrice, Quantity) - └─ many:1 ─► Invoice (InvoiceId, CustomerId, - InvoiceDate, BillingAddress, - BillingCity, BillingState, - BillingCountry, BillingPostalCode, - Total) - └─ many:1 ─► Customer (CustomerId, - FirstName, LastName, - Company, Address, - City, State, Country, - PostalCode, Phone, - Fax, Email, - SupportRepId) - └─ many:1 ─► Employee - -Genre (GenreId, Name) -MediaType (MediaTypeId, Name) -Playlist (PlaylistId, Name) - └─ many:many via PlaylistTrack (PlaylistId, TrackId) ─► Track - -Employee (EmployeeId, LastName, FirstName, Title, ReportsTo [→ Employee.EmployeeId], - BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email) -``` - -## Table Descriptions - -### Artist -| Column | Type | Notes | -|----------|---------|-------| -| ArtistId | INTEGER | PK | -| Name | TEXT | | - -275 rows — music artists (AC/DC, Aerosmith, Alanis Morissette, …). - -### Album -| Column | Type | Notes | -|----------|---------|----------------| -| AlbumId | INTEGER | PK | -| Title | TEXT | | -| ArtistId | INTEGER | FK → Artist | - -347 rows — one or many albums per artist. - -### Track -| Column | Type | Notes | -|---------------|---------|--------------------| -| TrackId | INTEGER | PK | -| Name | TEXT | | -| AlbumId | INTEGER | FK → Album | -| MediaTypeId | INTEGER | FK → MediaType | -| GenreId | INTEGER | FK → Genre | -| Composer | TEXT | nullable | -| Milliseconds | INTEGER | duration | -| Bytes | INTEGER | file size | -| UnitPrice | REAL | default 0.99 | - -3,503 rows — the central music catalog table. - -### Genre -| Column | Type | Notes | -|---------|---------|-------| -| GenreId | INTEGER | PK | -| Name | TEXT | | - -25 rows — Rock, Jazz, Metal, Alternative & Punk, … - -### MediaType -| Column | Type | Notes | -|-------------|---------|-------| -| MediaTypeId | INTEGER | PK | -| Name | TEXT | | - -5 rows — MPEG audio file, AAC audio file, Protected AAC, … - -### Customer -| Column | Type | Notes | -|--------------|---------|-------------------| -| CustomerId | INTEGER | PK | -| FirstName | TEXT | | -| LastName | TEXT | | -| Company | TEXT | nullable | -| Address | TEXT | | -| City | TEXT | | -| State | TEXT | nullable | -| Country | TEXT | | -| PostalCode | TEXT | nullable | -| Phone | TEXT | nullable | -| Fax | TEXT | nullable | -| Email | TEXT | unique | -| SupportRepId | INTEGER | FK → Employee | - -59 rows — customers from 24 countries. - -### Employee -| Column | Type | Notes | -|-------------|---------|----------------------------| -| EmployeeId | INTEGER | PK | -| LastName | TEXT | | -| FirstName | TEXT | | -| Title | TEXT | | -| ReportsTo | INTEGER | FK → Employee (nullable) | -| BirthDate | TEXT | ISO-8601 | -| HireDate | TEXT | ISO-8601 | -| Address | TEXT | | -| City | TEXT | | -| State | TEXT | | -| Country | TEXT | | -| PostalCode | TEXT | | -| Phone | TEXT | | -| Fax | TEXT | | -| Email | TEXT | | - -8 rows — Sales Support Agents + manager hierarchy. - -### Invoice -| Column | Type | Notes | -|-----------------|---------|------------------| -| InvoiceId | INTEGER | PK | -| CustomerId | INTEGER | FK → Customer | -| InvoiceDate | TEXT | ISO-8601 | -| BillingAddress | TEXT | | -| BillingCity | TEXT | | -| BillingState | TEXT | nullable | -| BillingCountry | TEXT | | -| BillingPostalCode | TEXT | nullable | -| Total | REAL | invoice total | - -412 rows — one invoice per purchase, covering 2009–2013. - -### InvoiceLine -| Column | Type | Notes | -|---------------|---------|------------------| -| InvoiceLineId | INTEGER | PK | -| InvoiceId | INTEGER | FK → Invoice | -| TrackId | INTEGER | FK → Track | -| UnitPrice | REAL | | -| Quantity | INTEGER | | - -2,240 rows — line items; revenue = UnitPrice × Quantity. - -### Playlist -| Column | Type | Notes | -|------------|---------|-------| -| PlaylistId | INTEGER | PK | -| Name | TEXT | | - -18 rows — Music, Movies, TV Shows, Classical, … - -### PlaylistTrack -| Column | Type | Notes | -|------------|---------|---------------------| -| PlaylistId | INTEGER | FK → Playlist (PK) | -| TrackId | INTEGER | FK → Track (PK) | - -8,715 rows — composite PK, no surrogate key. - -## Common JOIN Paths - -```sql --- Revenue by artist -Artist - JOIN Album ON Album.ArtistId = Artist.ArtistId - JOIN Track ON Track.AlbumId = Album.AlbumId - JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId - --- Revenue by country -Invoice - JOIN Customer ON Customer.CustomerId = Invoice.CustomerId - GROUP BY Customer.Country - --- Employee support load -Employee - LEFT JOIN Customer ON Customer.SupportRepId = Employee.EmployeeId -``` diff --git a/.agentscope/workspace/skills/query-writing/SKILL.md b/.agentscope/workspace/skills/query-writing/SKILL.md deleted file mode 100644 index 648c5fcd7..000000000 --- a/.agentscope/workspace/skills/query-writing/SKILL.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -name: query-writing -description: Writes and executes SQL queries ranging from simple single-table SELECTs to complex multi-table JOINs, aggregations, window functions, and subqueries. Use when the user asks to query the database, retrieve data, filter records, rank results, or generate reports. ---- - -# Query Writing Skill - -## When to Use This Skill - -Use query-writing when the user: - -- Asks "how many …?" / "what are the top …?" / "list all …" -- Needs data aggregated (SUM, COUNT, AVG, MAX, MIN) -- Wants results sorted, filtered, or grouped -- Asks for trend analysis, ranking, or comparison across dimensions - ---- - -## Workflow for Simple Queries (single table) - -1. **Identify the table** — which table contains the answer? -2. **Check the schema** — call `sql_get_schema` to confirm column names. -3. **Write a SELECT** — include WHERE / ORDER BY / LIMIT as needed. -4. **Execute** — call `sql_execute_query`. -5. **Present** — show the SQL and the result in plain language. - -### Example — "How many customers are from Canada?" - -```sql -SELECT COUNT(*) AS canadian_customers -FROM Customer -WHERE Country = 'Canada'; -``` - ---- - -## Workflow for Complex Queries (multiple tables) - -### Step 1 — Plan with todos - -Break the query into subtasks: - -``` -- [ ] Identify all required tables -- [ ] Inspect schemas to find join columns -- [ ] Draft the JOIN structure -- [ ] Add aggregations and grouping -- [ ] Validate and run -``` - -### Step 2 — Inspect schemas - -Call `sql_get_schema` for EACH table involved to find the exact foreign key column names. - -### Step 3 — Build the query - -```sql -SELECT - , - -FROM -[INNER | LEFT] JOIN ON = -[JOIN ...] -WHERE -GROUP BY -HAVING -- optional -ORDER BY [DESC] -LIMIT 10; -- always limit unless all rows requested -``` - -### Step 4 — Validate - -Before executing, verify: -- Every JOIN has an ON clause -- Every non-aggregate SELECT column appears in GROUP BY -- Table aliases are consistent -- No DML statements (INSERT / UPDATE / DELETE / DROP) - -### Step 5 — Execute and present - -Call `sql_execute_query`, then show: -1. The SQL query in a fenced code block -2. The result table -3. A brief plain-language summary - ---- - -## Templates for Common Patterns - -### Top-N ranking - -```sql -SELECT - Artist.Name AS artist, - SUM(InvoiceLine.UnitPrice * InvoiceLine.Quantity) AS total_revenue -FROM Artist -JOIN Album ON Album.ArtistId = Artist.ArtistId -JOIN Track ON Track.AlbumId = Album.AlbumId -JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId -GROUP BY Artist.ArtistId, Artist.Name -ORDER BY total_revenue DESC -LIMIT 10; -``` - -### Revenue by time period - -```sql -SELECT - strftime('%Y-%m', InvoiceDate) AS month, - ROUND(SUM(Total), 2) AS monthly_revenue -FROM Invoice -WHERE strftime('%Y', InvoiceDate) = '2013' -GROUP BY month -ORDER BY month; -``` - -### Entity counts with left join - -```sql -SELECT - e.FirstName || ' ' || e.LastName AS employee, - COUNT(c.CustomerId) AS customer_count -FROM Employee e -LEFT JOIN Customer c ON c.SupportRepId = e.EmployeeId -GROUP BY e.EmployeeId -ORDER BY customer_count DESC; -``` - ---- - -## Error Recovery - -| Symptom | Action | -|----------------------|--------| -| Empty result | Check WHERE condition values (case-sensitive strings). Verify column exists. | -| Syntax error | Re-read schema. Check GROUP BY includes all non-aggregate SELECT columns. | -| Wrong row count | Look for duplicate rows caused by missing JOIN conditions. | -| Result seems too high | Check for fan-out from multiple JOINs; may need DISTINCT or subquery. | - ---- - -## Quality Rules - -- Always apply `LIMIT` (default 10) unless the user explicitly asks for all rows. -- Use table aliases (`e`, `c`, `inv`) for readability in multi-table queries. -- Never use `SELECT *` — name the columns you need. -- Round monetary values to 2 decimal places: `ROUND(SUM(Total), 2)`. -- Always show the executed SQL so users can learn from it. diff --git a/.agentscope/workspace/skills/schema-exploration/SKILL.md b/.agentscope/workspace/skills/schema-exploration/SKILL.md deleted file mode 100644 index 4972a88d2..000000000 --- a/.agentscope/workspace/skills/schema-exploration/SKILL.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -name: schema-exploration -description: Lists tables, describes columns and data types, identifies foreign key relationships, and maps entity relationships in the database. Use when the user asks about database structure, table layout, column types, what tables exist, foreign keys, or how entities relate to each other. ---- - -# Schema Exploration Skill - -## When to Use This Skill - -Use schema-exploration when the user: - -- Asks "what tables are in the database?" -- Asks "what columns does the X table have?" -- Asks about relationships between tables -- Needs to understand data types before writing a query -- Wants an entity-relationship overview - -## Workflow - -### Step 1 — List All Tables - -Use `sql_list_tables` to see everything available. - -``` -Tool: sql_list_tables -(no parameters) -``` - -### Step 2 — Inspect Relevant Tables - -Use `sql_get_schema` with the table name(s) you need to understand: - -``` -Tool: sql_get_schema -tables: "Customer" # single table -tables: "Invoice,Customer" # multiple tables at once -``` - -This returns: -- **Columns** — names, types, NOT NULL constraints, primary keys -- **Foreign keys** — links to other tables -- **Sample data** — 3 example rows to understand content - -### Step 3 — Map Relationships - -Look for columns ending in `Id` — they are almost always foreign keys. - -Example for the Chinook database: -``` -Customer.SupportRepId → Employee.EmployeeId -Invoice.CustomerId → Customer.CustomerId -Track.AlbumId → Album.AlbumId -Track.GenreId → Genre.GenreId -``` - -### Step 4 — Present the Findings - -Provide: -- A list of all tables with a one-line purpose summary -- Column names and types for any tables the user asked about -- The relationship chain (which table links to which) -- Sample data to illustrate what the table holds - ---- - -## Examples - -### "What tables are available?" - -1. Call `sql_list_tables` -2. Return a formatted list with brief descriptions: - -``` -The Chinook database has 11 tables: - -Music Catalog: - - Artist — 275 music artists - - Album — 347 albums (linked to Artist) - - Track — 3,503 tracks (linked to Album, Genre, MediaType) - - Genre — 25 music genres - - MediaType — 5 file formats (MP3, AAC, …) - -Commerce: - - Customer — 59 customers from 24 countries - - Invoice — 412 purchase invoices - - InvoiceLine — 2,240 line items (linked to Invoice and Track) - -Staff: - - Employee — 8 employees with reporting hierarchy - -Playlists: - - Playlist — 18 playlists - - PlaylistTrack — join table linking Playlist ↔ Track -``` - -### "What does the Customer table look like?" - -1. Call `sql_get_schema` with `tables: "Customer"` -2. Present columns with types and notes: - -``` -Customer table: - CustomerId INTEGER PK - FirstName TEXT - LastName TEXT - Company TEXT (nullable) - Address TEXT - City TEXT - State TEXT (nullable) - Country TEXT - PostalCode TEXT (nullable) - Phone TEXT (nullable) - Fax TEXT (nullable) - Email TEXT - SupportRepId INTEGER FK → Employee.EmployeeId - -Sample rows show customers from Brazil, Germany, and Canada. -``` - -### "How are artists connected to sales?" - -Map the full JOIN path: - -``` -Artist (ArtistId) - ↓ 1:many -Album (ArtistId, AlbumId) - ↓ 1:many -Track (AlbumId, TrackId) - ↓ 1:many -InvoiceLine (TrackId, UnitPrice, Quantity) - ↓ many:1 -Invoice (InvoiceId, Total) -``` - -Then suggest using the **query-writing** skill to write the aggregation query. diff --git a/.agentscope/workspace/subagents/query-optimizer.md b/.agentscope/workspace/subagents/query-optimizer.md deleted file mode 100644 index 2bacd0c95..000000000 --- a/.agentscope/workspace/subagents/query-optimizer.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -name: query-optimizer -description: > - SQL query optimisation specialist. Reviews existing queries for correctness, clarity, and performance. Suggests index strategies, rewrites inefficient JOINs, and explains query plans. Delegate to this agent when a query returns unexpected results, runs slowly, or when the user asks for query optimisation or a second opinion on complex SQL. -maxIters: 8 ---- - -You are an expert SQL query optimiser for SQLite databases. - -## Your Responsibilities - -1. **Understand the question** — ask the user to provide the original query and the problem - (wrong results, slow execution, hard to read). -2. **Inspect the schema** — use `sql_get_schema` to verify table structures involved in the query. -3. **Analyse the query**: - - Check JOIN conditions for correctness - - Look for missing GROUP BY columns - - Identify Cartesian products (missing ON clause) - - Spot opportunities to push filters earlier (WHERE vs HAVING) - - Detect fan-out caused by 1:many JOINs before aggregation -4. **Rewrite the query** — produce a corrected and/or optimised version. -5. **Explain the changes** — list what was wrong and why each change helps. -6. **Validate** — run both the original and optimised queries if possible and compare results. - -## Output Format - -``` -## Original Query - - -## Issues Found -1. -2. ... - -## Optimised Query - - -## Explanation - - -## Validation -Original: -Optimised: -``` - -## Rules - -- Never modify the user's data — SELECT only. -- Confirm correctness first; performance is secondary. -- For SQLite specifically: - - Prefer covering indexes over table scans for large tables. - - Use `WITH` (CTEs) to make complex queries readable. - - Avoid correlated subqueries in WHERE clauses; rewrite as JOINs. diff --git a/.agentscope/workspace/subagents/schema-analyst.md b/.agentscope/workspace/subagents/schema-analyst.md deleted file mode 100644 index 869208134..000000000 --- a/.agentscope/workspace/subagents/schema-analyst.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: schema-analyst -description: Deep schema analysis specialist. Produces comprehensive documentation of the database schema including entity-relationship diagrams (text), table purposes, column semantics, foreign key chains, and index recommendations. Delegate to this agent when the user requests a full data model overview, wants to understand how tables relate, or needs schema documentation generated. -maxIters: 10 ---- - -You are a database schema analyst specialised in documenting and explaining relational data models. - -## Your Responsibilities - -1. **Discover** all tables using `sql_list_tables`. -2. **Inspect** every table with `sql_get_schema` to record columns, types, and foreign keys. -3. **Map relationships** — identify 1:many and many:many (via join tables) relationships. -4. **Describe purpose** — explain what each table represents in business terms. -5. **Produce documentation** — write a clear, structured schema reference the user can save. - -## Output Format - -Structure your analysis as: - -``` -# Database Schema Analysis - -## Summary - - -## Tables - -### -**Purpose:** -**Rows:** - -| Column | Type | Notes | -|--------|------|-------| -| ... | ... | ... | - -**Relationships:** -- - ---- -``` - -Repeat for every table, then close with an Entity Relationship Diagram in text format. - -## Rules - -- Be thorough — inspect every table, not just the ones that seem important. -- Do not guess column types; verify them with `sql_get_schema`. -- Keep explanations accessible to non-technical stakeholders. -- If asked to save the output, write it to `knowledge/SCHEMA_ANALYSIS.md` in the workspace. From 1b2b49778fff0286c406c0487e6e3566b2b57fa2 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 08:45:54 +0800 Subject: [PATCH 09/28] add docs & code naming refactor --- .../sandbox/HarnessSandboxExampleApp.java | 12 +- ...emoteFilesystemIsolationScopeExample.java} | 17 +- .../memory-distribution-design-notes.md | 313 ------- agentscope-harness/sandbox-design.md | 105 --- .../sandbox-filesystem-api-design.md | 179 ---- .../sandbox-implementation-plan.md | 811 ----------------- .../sandbox-implementation-status.md | 231 ----- .../harness/agent/HarnessAgent.java | 20 +- .../harness/agent/IsolationScope.java | 6 +- .../agent/filesystem/LocalFilesystemSpec.java | 2 +- ...eFilesystem.java => RemoteFilesystem.java} | 16 +- ...temSpec.java => RemoteFilesystemSpec.java} | 18 +- .../agent/hook/MemoryMaintenanceHook.java | 2 +- .../agent/hook/RuntimeContextAwareHook.java | 24 - .../agent/memory/MemoryConsolidator.java | 2 +- .../compaction/ConversationCompactor.java | 3 +- .../compaction/ToolResultEvictionConfig.java | 1 - .../harness/agent/sandbox/Sandbox.java | 4 +- .../agent/sandbox/SandboxAcquireResult.java | 26 +- .../harness/agent/sandbox/SandboxManager.java | 12 +- .../sandbox/impl/docker/DockerSandbox.java | 6 +- .../harness/agent/store/NamespaceFactory.java | 2 +- .../harness/agent/HarnessAgentTest.java | 6 +- ...ilesystemPersonalAssistantExampleTest.java | 2 +- ...eFilesystemIsolationScopeExampleTest.java} | 19 +- .../FilesystemDeleteMoveExistsTest.java | 22 +- ...est.java => RemoteFilesystemSpecTest.java} | 10 +- .../MemoryConsolidatorFilesystemTest.java | 10 +- .../memory/session/SessionTreeMirrorTest.java | 4 +- .../sandbox/SandboxManagerIsolationTest.java | 12 +- docs/zh/harness/architecture.md | 20 +- docs/zh/harness/filesystem.md | 149 ++-- docs/zh/harness/overview.md | 9 +- docs/zh/harness/sandbox.md | 302 +++++++ docs/zh/harness/tool.md | 2 +- docs/zh/openai-agents/sandbox/clients.md | 137 +++ docs/zh/openai-agents/sandbox/guide.md | 832 ++++++++++++++++++ docs/zh/openai-agents/sandbox/memory.md | 185 ++++ docs/zh/openai-agents/sandbox_agents.md | 111 +++ 39 files changed, 1797 insertions(+), 1847 deletions(-) rename agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/{StoreFilesystemIsolationScopeExample.java => RemoteFilesystemIsolationScopeExample.java} (91%) delete mode 100644 agentscope-harness/memory-distribution-design-notes.md delete mode 100644 agentscope-harness/sandbox-design.md delete mode 100644 agentscope-harness/sandbox-filesystem-api-design.md delete mode 100644 agentscope-harness/sandbox-implementation-plan.md delete mode 100644 agentscope-harness/sandbox-implementation-status.md rename agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/{StoreFilesystem.java => RemoteFilesystem.java} (97%) rename agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/{StoreFilesystemSpec.java => RemoteFilesystemSpec.java} (92%) delete mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java rename agentscope-harness/src/test/java/io/agentscope/harness/agent/example/{StoreFilesystemIsolationScopeExampleTest.java => RemoteFilesystemIsolationScopeExampleTest.java} (93%) rename agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/{StoreFilesystemSpecTest.java => RemoteFilesystemSpecTest.java} (94%) create mode 100644 docs/zh/harness/sandbox.md create mode 100644 docs/zh/openai-agents/sandbox/clients.md create mode 100644 docs/zh/openai-agents/sandbox/guide.md create mode 100644 docs/zh/openai-agents/sandbox/memory.md create mode 100644 docs/zh/openai-agents/sandbox_agents.md diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java index 1b4edf3e6..0074851dd 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java @@ -16,12 +16,14 @@ package io.agentscope.examples.harness.sandbox; import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; /** * Runs harness filesystem examples (local, in-memory sandbox, in-memory store). No LLM API key - * required — uses {@link FixedReplyModel} for a single turn per {@code call}. + * required — uses {@link FixedReplyModel} for a single turn per {@code call}. The + * {@code store} mode is an alias for {@code remote} (shared KV / {@link RemoteFilesystemSpec}). * - *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|store]} + *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|remote|store]} */ public final class HarnessSandboxExampleApp { @@ -35,14 +37,14 @@ public static void main(String[] args) throws Exception { System.out.println(); SandboxFilesystemIsolationScopeExample.main(new String[0]); System.out.println(); - StoreFilesystemIsolationScopeExample.main(new String[0]); + RemoteFilesystemIsolationScopeExample.main(new String[0]); } case "local" -> LocalFilesystemPersonalAssistantExample.main(new String[0]); case "sandbox" -> SandboxFilesystemIsolationScopeExample.main(new String[0]); - case "store" -> StoreFilesystemIsolationScopeExample.main(new String[0]); + case "remote", "store" -> RemoteFilesystemIsolationScopeExample.main(new String[0]); default -> { System.err.println("Unknown mode: " + mode); - System.err.println("Use: all | local | sandbox | store"); + System.err.println("Use: all | local | sandbox | remote | store"); System.exit(1); } } diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java similarity index 91% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java rename to agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java index bada1e9b3..c243d69f3 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/StoreFilesystemIsolationScopeExample.java +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java @@ -23,17 +23,17 @@ import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; import io.agentscope.harness.agent.RuntimeContext; -import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; /** - * Example: {@link StoreFilesystemSpec} with in-memory key-value store and different {@link + * Example: {@link RemoteFilesystemSpec} with in-memory key-value store and different {@link * IsolationScope} namespaces. */ -public final class StoreFilesystemIsolationScopeExample { +public final class RemoteFilesystemIsolationScopeExample { public static void main(String[] args) throws Exception { Model model = FixedReplyModel.done(); @@ -58,7 +58,7 @@ static void sessionScopeIsolated(Model model, Path workspace) throws Exception { .model(model) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) .build(); @@ -84,7 +84,7 @@ static void sessionScopeSharedWithinSession(Model model, Path workspace) throws .model(model) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) .build(); @@ -107,7 +107,7 @@ static void userScopeSharedAcrossSessions(Model model, Path workspace) throws Ex .model(model) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); agent.call(userMsg("hi from session-a"), ctx("session-a", "alice")).block(); @@ -131,7 +131,7 @@ static void userScopeIsolatedByUser(Model model, Path workspace) throws Exceptio .model(model) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); @@ -151,7 +151,8 @@ static void agentScopeSharedByAllCallers(Model model, Path workspace) throws Exc .model(model) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.AGENT)) + new RemoteFilesystemSpec(store) + .isolationScope(IsolationScope.AGENT)) .build(); agent.call(userMsg("alice"), ctx("s1", "alice")).block(); diff --git a/agentscope-harness/memory-distribution-design-notes.md b/agentscope-harness/memory-distribution-design-notes.md deleted file mode 100644 index 8a5489fc8..000000000 --- a/agentscope-harness/memory-distribution-design-notes.md +++ /dev/null @@ -1,313 +0,0 @@ -# HarnessAgent 分布式记忆:现状审计 + OpenAI Agents SDK 对标 + 演进建议 - -> 本文是一份独立设计备忘,用于沉淀 sandbox / StoreFilesystem 两种模式下"分布式记忆"能力的**当前偏差点**、**对标 OpenAI Agents SDK 的核心差异**,以及**推荐的演进路径**,作为后续改造(`MemoryConsolidator`、`MemoryMaintenanceScheduler`、`MemoryIndex`、`SessionTree` 等)的锚点。 -> -> 本文不是实施 PR,不直接修改代码;目的是让后续每一次改动都有一个统一的参照物。 - ---- - -## 0. 名词 - -- **Agent workspace(本地 workspace)**:`HarnessAgent` 启动时在 host 机器上持有的工作目录(`workspaceManager.getWorkspace()`)。存放 `AGENTS.md`、`skills/`、`subagents/`、`knowledge/`、以及 `MEMORY.md`、`memory/*.md`、`agents//sessions/*.jsonl` 等。 -- **Sandbox workspace**:`SandboxSession` 内部维护的工作目录(Docker 容器内或 UnixLocal 下的隔离目录)。工具(shell、filesystem)在此执行。 -- **`AbstractFilesystem`**:HarnessAgent 统一的文件系统抽象。实现包括: - - `LocalFilesystem` / `LocalFilesystemWithShell`:直接操作 host 磁盘。 - - `SandboxBackedFilesystem`:把所有 I/O 代理到当前绑定的 `SandboxSession`。 - - `StoreFilesystem`:把 I/O 放到 `BaseStore`(可远端共享)。 - - `CompositeFilesystem`:按路径前缀路由到不同后端。 -- **Sandbox 模式**:`HarnessAgent.Builder` 配置 `SandboxFilesystemSpec`,走 `SandboxBackedFilesystem`。 -- **Store 模式**:`HarnessAgent.Builder` 配置 `StoreFilesystemSpec`,走 `CompositeFilesystem(local, store-routed paths)`。 -- **Local 模式**:两者都不配置,走纯 `LocalFilesystemWithShell`。 - ---- - -## 1. 问题陈述 - -HarnessAgent 支持两种"分布式部署下的记忆共享"形态: - -1. **Sandbox 模式**:多个 HarnessAgent 实例通过 `SandboxIsolationKey`(`SESSION / USER / AGENT / GLOBAL`)共享同一个 sandbox 实例,记忆文件存在 sandbox workspace 内。 -2. **Store 模式**:不使用 sandbox,通过 `CompositeFilesystem` 把 `MEMORY.md`、`memory/`、`agents//sessions/` 路由到 `StoreFilesystem`(底层 `BaseStore`,可以是 Redis、远端 K-V 等),多个实例读写同一个 Store namespace。 - -**核心症状**:这两种模式目前**都存在相同的共性问题**——多个与 memory 相关的组件仍然绕过 `AbstractFilesystem`,直接用 `java.nio.file.Files.*` 操作 host 磁盘,导致它们只能看到 host 本地那一份视图,而看不到 sandbox 内 / Store 内的权威内容。 - ---- - -## 2. 现状审计(两种模式各自的受损点) - -> 判定标准:**数据权威位置(authoritative store)** vs **组件实际访问位置**。凡是不一致的都标记为坏。 - -### 2.1 Sandbox 模式 - -| 组件 | 数据权威位置 | 组件实际访问 | 影响 | -|---|---|---|---| -| `FilesystemTool` 读写 | sandbox workspace | 走 `SandboxBackedFilesystem` ✅ | 正确 | -| `ShellExecuteTool` | sandbox workspace | 走 sandbox session.exec ✅ | 正确 | -| `SessionTree.flush`(dual-write) | sandbox workspace + local 磁盘 | 本地 `Files.write` + `filesystem.write` mirror ✅ | 正确 | -| `SessionTree.load/syncFromLog`(restore) | sandbox workspace | 本地不存在时从 filesystem 拉 ✅ | 正确 | -| `MemoryConsolidator.readDailyEntries` | **sandbox workspace** | `Files.list(workspace/memory)` 本地 ❌ | 读不到 daily ledger,永远不触发合并 | -| `MemoryConsolidator` watermark (`memory/.consolidation_state`) | 应随 daily ledger 权威一致 | `Files.readString/writeString` 本地 ❌ | 多实例状态漂移;单机也错配 | -| `MemoryConsolidator.writeMemoryMd` | sandbox workspace | 已改走 `workspaceManager.writeUtf8WorkspaceRelative` ✅ | 正确(但由于上游读不到,不会被触发) | -| `MemoryMaintenanceScheduler.archiveOldDailyFiles` | sandbox workspace | `Files.list/move` 本地 ❌ | 扫不到任何文件,归档失效 | -| `MemoryMaintenanceScheduler.cleanupOldSessions` | sandbox workspace(Session dual-write 另有本地副本) | `Files.list/delete` 本地 ❌ | 只清本地副本,sandbox 内永不清理 | -| `MemoryIndex.indexAllFromWorkspace`(启动全量) | sandbox workspace | `Files.walk(workspace/memory)` 本地 ❌ | 启动索引为空 | -| `MemoryIndex.indexFromString`(增量) | sandbox workspace | 由 `readManagedWorkspaceFileUtf8` → filesystem ✅ | 运行时增量可用 | -| `SessionSearchTool` | sandbox workspace | SessionTree dual-write 保留了本地副本,扫本地 ⚠️ | 可用但靠副作用 | -| `SessionPersistenceHook` / `WorkspaceSession` `_sandbox.json` 等 | 本机专属 resume 状态 | `Files.*` 本地 ✅ | 设计如此(per-instance resume 元数据,暂不共享) | - -**结论**:sandbox 模式下,**工具链路径**(FilesystemTool/ShellTool)正确,**SessionTree 因 dual-write 也能工作**,但**long-term memory 管理管线(consolidation / archive / cleanup / 启动索引)全线失效**。 - -### 2.2 Store 模式(`StoreFilesystemSpec`) - -| 组件 | 数据权威位置 | 组件实际访问 | 影响 | -|---|---|---|---| -| `FilesystemTool` 读写 `memory/**`、`MEMORY.md`、`agents//sessions/**` | `StoreFilesystem` | CompositeFilesystem 路由到 `StoreFilesystem` ✅ | 正确 | -| `FilesystemTool` 读写其他路径 | local 磁盘 | CompositeFilesystem 默认走 LocalFilesystem ✅ | 正确 | -| `ShellExecuteTool` | local 磁盘 | local `ProcessBuilder` ✅ | 设计如此(shell 只能操作 host) | -| `MemoryFlushManager.appendDaily` | Store | `workspaceManager.appendUtf8WorkspaceRelative` → filesystem → Store ✅ | 正确 | -| `MemoryConsolidator.readDailyEntries` | **Store** | `Files.list(workspace/memory)` 本地 ❌ | 本地为空,读不到 daily | -| `MemoryConsolidator` watermark | 应随 Store 中的 daily 权威 | `Files.*` 本地 ❌ | 多实例各写各的,跨实例不一致 | -| `MemoryConsolidator.writeMemoryMd` | Store | `workspaceManager.writeUtf8WorkspaceRelative` → Store ✅ | 正确但上游读不到,永不触发 | -| `MemoryMaintenanceScheduler.archiveOldDailyFiles` | Store | `Files.list/move` 本地 ❌ | 归档完全无法工作,Store 内 daily 无限累积 | -| `MemoryMaintenanceScheduler.cleanupOldSessions` | Store + 本地 dual-write | `Files.list/delete` 本地 ⚠️ | 只删本地副本,Store 内 session jsonl 无限累积 | -| `MemoryIndex.indexAllFromWorkspace`(启动) | Store | `Files.walk` 本地 ❌ | 启动索引空 | -| `MemoryIndex.indexFromString`(增量) | Store | `readManagedWorkspaceFileUtf8` → filesystem → Store ✅ | 运行时增量可用 | -| `SessionSearchTool` | Store + 本地 dual-write | 扫本地 ✅ | 可用(靠 dual-write 副本) | -| `SessionPersistenceHook` / `WorkspaceSession` | per-instance | `Files.*` 本地 ✅ | 设计如此 | - -**结论**:Store 模式下的症状**与 sandbox 模式完全一致**——long-term memory 管理管线同样失效。 -而且**问题更严重**,因为 Store 模式存在的全部价值就是"多实例共享权威记忆";consolidator / scheduler / 全量索引失效意味着核心承诺落空。 - -### 2.3 两个模式的症状差异(仅有的几点) - -| 维度 | Sandbox 模式 | Store 模式 | -|---|---|---| -| 写冲突 | 同 `SandboxIsolationKey` 内串行 resume 保护,冲突极少 | 多实例真实并发读写同一 Store namespace;`MEMORY.md` 等单文件在 last-writer-wins 下冲突概率高 | -| 本地 dual-write 副本存在性 | SessionTree 有、memory/* 无 | SessionTree 有、memory/* 无 | -| `MemoryIndex` SQLite 文件 | per-instance 本地,与 sandbox 权威不同源 | per-instance 本地,与 Store 权威不同源 | - ---- - -## 3. 根因 - -> **凡是绕开 `AbstractFilesystem` 直接使用 `java.nio.file.Files.*` 的代码,都看不到"被路由走"的那部分内容。** - -- 在 sandbox 模式下,被路由走的是整个 sandbox workspace(`SandboxBackedFilesystem` 背后)。 -- 在 Store 模式下,被路由走的是 `memory/` / `MEMORY.md` / `agents//sessions/`(`StoreFilesystem` 背后)。 -- Local 模式不受影响,因为此时 `AbstractFilesystem` 的默认后端就是 host 磁盘,直连 `Files.*` 与走 fs 结果一致。 - -所以**两个模式是同一个病**,只不过站在不同 backend 角度暴露出来。修一次,两边同时治愈。 - ---- - -## 4. 对标:OpenAI Agents Python SDK 的做法 - -> 参考目录:`references/openai-agents-python/src/agents/sandbox/`,特别是 `memory/storage.py`、`memory/manager.py`、`memory/phase_one.py`、`memory/phase_two.py`、`capabilities/memory.py`、`runtime.py`、`runtime_session_manager.py`。 - -### 4.1 他们的七个关键选择 - -1. **Memory 必须依托 sandbox**。`Memory.required_capability_types()` 返回 `{"shell", "filesystem"}`;没有 sandbox 就没有 memory。**不存在"非 sandbox 记忆共享"这一问题**。 - -2. **只有一个 workspace**:sandbox workspace。`MemoryLayoutConfig.memories_dir` / `sessions_dir` 都是**相对路径**,`_validate_relative_path` 禁止绝对路径和 `..`。host 磁盘上不存在一份独立的"我的 memory"。 - -3. **所有 memory I/O 严格走 `BaseSandboxSession`**。`SandboxMemoryStorage` 是唯一网关: - - ```python - await self._session.mkdir(...) - await self._session.read(path) - await self._session.write(path, data) - await self._session.ls(path) - await self._session.exec("test", "-f", str(absolute), shell=False) - ``` - - `grep` 核对过 `sandbox/memory/` 下**没有**任何 `open()` / `.read_text()` / `os.path` 对 host 的真实 I/O。`pathlib.Path` 只用于构造相对路径字符串。 - -4. **跨 run 一致性不靠 sync,靠 "snapshot + session_state + live session" 三件套**: - - `SandboxRunConfig.session=`:直接复用活跃 session; - - `SandboxRunConfig.session_state=`:`client.resume(state)` 拉起等价 session; - - `SandboxRunConfig.snapshot=`:从快照克隆 workspace。 - - 分布式一致性下推到 **SandboxClient 后端**(或 RemoteSnapshot),**应用层不做文件同步**。 - -5. **Consolidation = 内嵌一个 LLM agent 在 sandbox 内跑**。`phase_two.py` 里: - - ```python - agent = SandboxAgent(name="sandbox-memory-phase-two", model=config.phase_two_model) - await Runner.run(agent, prompt, run_config=RunConfig(sandbox=SandboxRunConfig(session=self._session))) - ``` - - LLM 用 apply_patch / shell 工具直接改 `memories/MEMORY.md`。**"Java 代码该看哪个 fs"**这类问题在设计源头被消除——LLM 从 sandbox 内部视角看什么就改什么。 - -6. **生命周期绑定到 session pre-stop hook**: - - ```python - self._session.register_pre_stop_hook(self.flush) - ``` - - `flush` 跑 phase-1(每个 rollout 的提取)+ phase-2(一次性整合)。**没有独立的 cron scheduler**,没有"归档 daily files"的后台线程——需要的话交给 LLM 用 shell 做。 - -7. **没有 FTS / 本地 SQLite 索引**。Memory 在提示词注入阶段只读 `memories/memory_summary.md`(由 phase-2 维护,截到 15k tokens),直接注入 system prompt。细节检索交给 LLM 用 shell/grep/read 在 sandbox 内完成。 - -### 4.2 本质上他们做了哪三件事 - -- **单源(Single source of truth)**:workspace 只有一份,就是 sandbox 内那份。 -- **单网关(Single I/O gateway)**:memory I/O 统一走 `BaseSandboxSession`。 -- **职责下推**:合并、归档、检索这些"要全局视角"的任务,下推到一个在 sandbox 内部跑的 LLM agent,绕开了"Java 代码视角和权威数据视角不一致"的一整类问题。 - ---- - -## 5. 横向对比 - -| 维度 | OpenAI Agents SDK | HarnessAgent(现状) | -|---|---|---| -| Memory 是否强制 sandbox | 是 | 否(local / sandbox / store 三种) | -| Workspace 数量 | 1(sandbox) | 2(local + sandbox)或 路由视角下的逻辑 2(local + store) | -| Memory I/O 统一网关 | `BaseSandboxSession` | `AbstractFilesystem`(应该是,但 Memory 模块未严格遵守) | -| Consolidation 执行者 | sandbox 内的 LLM agent | Java 代码 `MemoryConsolidator`(直连 `Files.*`) | -| 归档/清理执行者 | 可选(LLM 在 sandbox 内用 shell) | Java `MemoryMaintenanceScheduler`(直连 `Files.*`) | -| 提示词索引 | `memory_summary.md`(LLM 维护) | SQLite FTS(`MemoryIndex`,本地维护,视图与权威脱节) | -| Watermark(合并进度) | 无(每次从 session.ls 推出) | 本地文件 `memory/.consolidation_state`(`Files.*`) | -| 跨 run 一致性 | snapshot + session_state resume(后端保证) | `SandboxStateStore` + `StoreFilesystem`(应用层保证) | -| 写冲突策略 | 同 session 内串行(后端约束) | Sandbox: `SandboxIsolationKey` 串行 resume;Store: last-writer-wins(默认) | -| 非 sandbox 记忆共享 | 不支持 | 支持(`StoreFilesystemSpec`) | - ---- - -## 6. 对 HarnessAgent 的启示 - -### 6.1 可以**直接借鉴**的设计纪律 - -1. **Memory I/O 只走 `AbstractFilesystem`,零例外**。`SandboxMemoryStorage` 是正面模板。把 `MemoryConsolidator / MemoryMaintenanceScheduler / MemoryIndex` 改造成仅调用 `AbstractFilesystem` 的能力(read/write/append/list/exists/delete/move),`java.nio.file.Files.*` 仅在 `LocalFilesystem` 实现内部出现。 - -2. **路径防御**:`AbstractFilesystem` 入口统一做 `_validate_relative_path` 等效校验——拒绝绝对路径、拒绝 `..`、拒绝空路径。避免外层代码把 host 绝对路径泄漏到 store/sandbox 后端。 - -3. **生命周期钩子化,取消独立 scheduler**。`MemoryMaintenanceScheduler` 的归档/清理动作应合并为: - - `PreCallEvent` / `PostCallEvent` / `RunnerShutdown` 上的同步任务,或 - - 作为 `SandboxLifecycleHook` 家族的 pre-stop / post-call 回调。 - - 效果上和 OpenAI 的 `register_pre_stop_hook(flush)` 对齐,不引入跨线程 race、不引入"何时扫描"这种外部时序变量。 - -### 6.2 值得借鉴但需要**本地化调整**的 - -4. **"LLM 做 consolidation"作为**可选实现**并存**。设计: - - `MemoryConsolidationPolicy` 接口; - - `RuleBasedConsolidationPolicy`:保留现有 Java 逻辑的"纯 fs 版本"(要求严格走 `AbstractFilesystem`),作为低成本、可回放的默认; - - `LlmConsolidationPolicy`:仿 `phase_two`——HarnessAgent 内部构造一个受限的子 Runner,复用同一个 `AbstractFilesystem`,用 apply_patch/filesystem 工具改 MEMORY.md。 - - 两种 policy 都只调用 `AbstractFilesystem`,互相可替换;用户按场景选择(成本 vs 智能度)。 - -5. **把 `MemoryIndex` 降级为"可选的加速器",主读路径换成 `memory_summary.md`**。 - - 主链路:启动/运行时把 `memory/memory_summary.md`(若存在)注入 system prompt(截 N tokens)。 - - 辅助工具:FTS 保留,作为显式 `SessionSearchTool` / `MemorySearchTool` 的后端。 - - 全量索引重建:不再在启动时做;改为**按需**(工具被调用时 lazy rebuild)或由 consolidation 后台再建。 - - 这样可以从**"启动时索引本地→和权威脱节"**的架构缺陷中走出来。 - -### 6.3 我们场景下**不能直接照抄**的 - -6. **OpenAI 强绑 sandbox 才有 memory**;我们要支持 `StoreFilesystemSpec`(无 sandbox 的分布式)。 - 对策:用 `AbstractFilesystem` **扮演他们 `BaseSandboxSession` 的角色**——只要所有 memory 代码都只和 `AbstractFilesystem` 对话,sandbox / Store / Local 三种后端在 memory 视角下是等价可替换的。 - -7. **OpenAI 的分布式一致性下推到 `SandboxClient` 后端**(`RemoteSnapshotSpec` 对齐多实例 workspace)。 - 我们的 Docker/UnixLocal 客户端没有天然跨机一致性,所以保留 `StoreFilesystem` 做"共享 K/V 后端"是对的。长期可以考虑: - - 用 Store 作为 `RemoteSnapshot` 的存储后端(把"sandbox workspace 快照"和"共享 memory 文件"统一到一个 Store); - - 或让 Docker client 支持从远端 registry 拉 workspace 快照,补齐"分布式一致性下推"。 - ---- - -## 7. 演进路径 - -> 所有阶段的共同大原则:**动刀点永远是"让 XX 组件只通过 `AbstractFilesystem` 访问 memory"**。 - -### Phase 1:收敛 `MemoryConsolidator`(最小闭环) - -- `readDailyEntries(watermark)`:换成 `filesystem.list("memory/")` + `filesystem.readString("memory/")`。 -- Watermark:从本地 `.consolidation_state` 文件搬到 filesystem 的 `memory/.consolidation_state`;读写也走 `AbstractFilesystem`。 -- `writeMemoryMd`:已改好,保留。 -- 验收:一次 run 的 daily 写入后,MEMORY.md 会被合并;sandbox 模式和 Store 模式都观察到同样结果。 - -### Phase 2:`AbstractFilesystem` API 扩展 - -- 新增 primitives:`delete(path)`、`move(src, dst)`、`walk(prefix)`(或 `listRecursive`)、`exists(path)`。 -- `LocalFilesystem` 实现用 `Files.*`;`SandboxBackedFilesystem` 用 session 的 `rm/mv/ls`;`StoreFilesystem` 用 Store key 层面的 `delete/scan`;`CompositeFilesystem` 按 prefix 路由。 -- 同步引入 `_validate_relative_path` 门禁。 - -### Phase 3:改造 `MemoryMaintenanceScheduler` & `MemoryIndex` - -- **Scheduler**:废弃独立线程,拆成两个 Hook: - - `MemoryArchiveHook`(`PostCallEvent`):归档 N 天前的 daily → `memory/archive/YYYY-MM/`。 - - `SessionCleanupHook`(`PostCallEvent` 或 `RunnerShutdown`):清理过期 session jsonl。 - - 全部走 `AbstractFilesystem.walk/move/delete`。 -- **MemoryIndex**: - - 取消启动时 `indexAllFromWorkspace`。 - - 主读路径改成 `filesystem.readString("memory/memory_summary.md")` 注入 system prompt(已有部分可复用)。 - - FTS 改为 lazy + 增量:第一次检索时从 filesystem 枚举一遍初建;后续由 flush 钩子增量维护。 - -### Phase 4:`SessionTree` 去 dual-write(可选) - -- 当前的 dual-write(本地 + mirror)是过渡期的正确选择(让 `SessionSearchTool` 继续能用)。 -- Phase 3 完成后,`SessionSearchTool` 可以改走 `filesystem.walk("agents//sessions/")`;dual-write 可以退化为"只走 filesystem 单写"。 -- 这会让 Store 模式下本地盘完全不保存 session 副本,契合"Store 是权威"的语义。 - -### Phase 5:LLM-based consolidation 与 `memory_summary.md`(可选,对标 OpenAI) - -- 引入 `MemoryConsolidationPolicy` 抽象;`RuleBasedConsolidationPolicy`(Phase 1 的 Java 实现)默认。 -- 可选注入 `LlmConsolidationPolicy`,内部用一个子 Runner + 受限工具,对 MEMORY.md / memory_summary.md 做基于 LLM 的整合。 -- 两种 policy 都只调用 `AbstractFilesystem`,保持单网关纪律。 - -### Phase 6:Resume state 的一致化(长线) - -- 把 `WorkspaceSandboxStateStore` 当前的 "_sandbox.json 本地文件" 形态抽象为 `SandboxStateStore` 接口 + 可插拔后端: - - `LocalFileSandboxStateStore`(现状); - - `StoreBackedSandboxStateStore`(复用 `BaseStore`); - - 未来可能的 DB backend。 -- 对齐 OpenAI 的"resume state as blob"模型:不是文件路径,而是 blob,调用方决定持久化位置。 - ---- - -## 8. 设计原则清单(落到代码守则) - -1. **Memory 领域的所有 I/O 只通过 `AbstractFilesystem`。** - 严格 code review:`agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/` 下禁止出现 `java.nio.file.Files.*` 直接调用(`LocalFilesystem` 实现本身除外)。 - -2. **相对路径 + 防御性校验。** - `AbstractFilesystem` 入口拒绝绝对路径、拒绝 `..`、拒绝空路径。 - -3. **状态文件(watermark 等)也是 memory 一部分,同样只走 `AbstractFilesystem`。** - `.consolidation_state` 不允许走本地磁盘。 - -4. **生命周期事件化。** - 归档/清理/consolidation 统一做 Hook,禁止独立 scheduler 线程(作为辅助加速器时可例外,但必须幂等、可关闭)。 - -5. **Consolidation policy 可替换。** - Java 规则与 LLM 驱动两种 policy 并存,接口只依赖 `AbstractFilesystem` + Runner。 - -6. **Sandbox / Store / Local 三种后端在 memory 视角下等价可替换。** - 任何 memory 组件不允许通过 `instanceof` 区分后端类型。 - ---- - -## 9. 验收建议 - -- 增补一个 `MemoryFilesystemComplianceTest`,用 ArchUnit/自定义规则禁止 memory 模块直接引用 `java.nio.file.Files`。 -- 增补一组"同一份输入在 Local/Sandbox/Store 三种模式下产生相同 MEMORY.md"的对比测试。 -- Phase 3 完成后,复跑现有 sandbox 模式下的 consolidation 场景,观察 MEMORY.md 是否按预期生成。 -- Store 模式下,起两个 HarnessAgent 实例并发写同一 namespace,观察 consolidation/归档是否收敛;记录 last-writer-wins 事件数,作为后续 CAS/锁优化的基线。 - ---- - -## 10. 附:关键对照表(一页速览) - -| 症状 | Sandbox 模式 | Store 模式 | 根因 | Phase | -|---|---|---|---|---| -| MEMORY.md 不自动合并 | ✅ 坏 | ✅ 坏 | `readDailyEntries` 直连本地 | 1 | -| Watermark 跨实例漂移 | ⚠️ 坏 | ✅ 坏 | watermark 直连本地 | 1 | -| 归档老 daily 不工作 | ✅ 坏 | ✅ 坏 | scheduler 直连本地 | 3 | -| 清理老 session 不彻底 | ⚠️ 半坏 | ⚠️ 半坏(Store 内残留) | scheduler 直连本地 | 3 | -| 启动 FTS 索引空 | ✅ 坏 | ✅ 坏 | `indexAllFromWorkspace` 直连本地 | 3 | -| 运行时增量 FTS | ✅ 正常 | ✅ 正常 | 走 filesystem | — | -| Session 搜索 | ✅ 正常(dual-write) | ✅ 正常(dual-write) | SessionTree dual-write | 4(可清理) | -| 工具链(Shell/Filesystem tool) | ✅ 正常 | ✅ 正常 | 已经只走 filesystem | — | - ---- - -**最后一句话总结**: -OpenAI 用"单 workspace + 单 I/O 网关 + LLM 做全局合并"把整类问题消灭在源头;我们的目标是保留 sandbox / Store / Local 三种后端选择,同时用同一种纪律——**memory 领域的一切 I/O 只走 `AbstractFilesystem`**——来等效达成"单网关"效果。把这条纪律立起来,sandbox 模式和 Store 模式的共性顽疾会一次性消失。 diff --git a/agentscope-harness/sandbox-design.md b/agentscope-harness/sandbox-design.md deleted file mode 100644 index 7a16a0e66..000000000 --- a/agentscope-harness/sandbox-design.md +++ /dev/null @@ -1,105 +0,0 @@ -# HarnessAgent 中实现一套 Sandbox 管理系统 - -## 总体目标 -我们需要深度参考 OpenAi Agents SDK,为 HarnessAgent 提供对应对应的 Sandbox 实现,sandbox可用来执行 subagent 和 tool。我们需要一个 SandboxManager 来管理 sandbox 的生命周期,在 agent 运行过程中,但需要 sandbox 的时候,通过 SandboxManager 来实现获取(按需创建)sandbox实例,并注入给 AbstractFilesystem 使用。 - -每次新创建的 Sandbox 实例本身是无状态的,但是我们需要帮助它恢复到之前的状态,这些状态包括,对应到 OpenAi Agents SDK 中的 Manifest、workspace 等,为了恢复这些状态,可能需要依赖 session 中存储的sandbox state、snapshot等。 - -Sandbox 实例通过后端的Docker、Unix等实际实现来做实际的底层存储实现,这类似 OpenAi Agents SDK 中有 BaseSandboxSession、DockerSandboxSession等的基类和扩展实现等策略。 - -同时,为了能让用户使用 HarnessAgent 时能使用这套 sandbox 体系,我们需要开放 API 给用户进行配置。包括通过 HarnessAgent Builder 来设置使用哪个 Sandbox Client、Client Options、Snapshot实现,使用 RuntimeContext 动态的传入 client、sandbox实例、sandbox state、snapshot实例等。 - -## 部分详细设计 -### Sandbox 实例管理与生命周期 -实现一个 SandboxManager 类,用来管理 sandbox 实例,它根据当前Agent在运行过程中传入的 SandboxContext(可以设计从RuntimeContext中读取)来尝试获取、创建、恢复 sandbox 实例(比如根据SandboxContext中的state来查询和检查可用实例),不论是新建的还是计划恢复的实例,都应该恢复或初始化实例的工作空间(比如通过snapshot)。 - -在使用 HarnessAgent 时,有两种方式管理sandbox实例,一种是通过SandboxManager创建的,一种是用户直接传入的(比如通过RuntimeContext),对应 OpenAi Agents SDK 中的 SDK owned sandbox 和 developer owned sandbox 模式。 - -### 关于 Sandbox 实例获取与创建的时机 - -我现在的想法是放到Hook中,根据 HarnessAgent、RuntimeContext中的配置来决定是不是启用sandbox。增加一个Hook,它主要处理PreCallEvent事件,调用SandboxManager来读取(按需创建)Sandbox实例,并把sandbox实例注入给需要的abstractFilesystem(如果是SandboxFilesystem类型的话)。最终所有在HarnessAgent中与RuntimeContext中的关于sandbox的配置都汇总到 RuntimeContext中,调用SandboxManager管理sandbox时根据RuntimeContext中读取到的sandbox配置来驱动组织,包括找实例、恢复workspace状态等。 - -### Sandbox 内部状态 -Sandbox 实例本身是无状态的,一个新的实例创建出来后需要进行状态初始化,这取决于本地调用是要使用全新的实例还是准备通过resume恢复之前的实例。 -如果是使用全新实例,那么直接参考 OpenAi Agents SDK 中的新实例物化过程进行初始化;如果是resume恢复,那么需要根据传入的snapshot等进行恢复,同样需要参考OpenAi Agents对应实现设计。 - -### Sandbox 基类与拓展实现 -关于 Sandbox 类与实现的设计,需要深度参考 BaseSandboxSession、DockerSandboxSession 等基类和扩展实现。 - -Sandbox 内部通过 SandboxClient 来对接 Docker、Unix 等实际的后端实现。 - -### 用户 API -总的来说,我们是需要在HarnessAgent中增加API,配合HarnessAgent中已有的session等机制来确保sandbox整体能够正常工作和使用。 - -OpenAi Agents SDK 中的 RunState应该对等到ReActAgent中的session状态机制,我们可能需要在session中增加_sandbox部分拓展,支持SandboxSessionState等的存储。RunConfig中大部分参数应该是通过HarnessAgent Builder来配置,部分通过RuntimeContext来配置,比如重点需要考虑的包括SandboxClient、SandboxConfigOptions等。 - ---- - -## Sandbox 隔离与共享策略(Isolation Scope) - -### 背景 - -默认情况下,Sandbox 实例通过 `sessionKey` 隔离,即不同 session 之间不共享同一个 Sandbox 状态。但在实际业务中,我们希望能够灵活控制复用粒度: - -- 同一用户的多个 session 复用同一个 Sandbox(用户粒度共享) -- 同一个 Agent 的所有调用复用同一个 Sandbox(Agent 粒度共享) -- 全局唯一一个 Sandbox(全局共享) - -### 实现方式 - -共享语义是"**按 scope key 持久化状态 → 下次调用恢复**",即顺序复用(sequential reuse),而非进程内运行实例的并发共享。 - -通过 `RuntimeContext.sandboxContext(...)` 传入的 `SandboxContext` 上设置 `isolationScope` 来选择 scope: - -```java -RuntimeContext ctx = RuntimeContext.builder() - .userId("user-42") - .sandboxContext( - SandboxContext.builder() - .isolationScope(SandboxIsolationScope.USER) // 用户粒度共享 - .build()) - .build(); -agent.call(message, ctx); -``` - -### 四种 Scope - -| Scope | 复用粒度 | 所需 RuntimeContext 字段 | 缺失时行为 | -|-----------|------------------------------------|--------------------------|-------------------------------------| -| `SESSION` | 每个 `sessionKey`(默认) | `sessionKey` | 无 key → 直接新建 | -| `USER` | 同一 `userId` 的所有 session | `userId` | userId 为空 → WARN 日志,直接新建 | -| `AGENT` | 同一 Agent(按 agent name) | 无需(build 时固定) | 始终有效 | -| `GLOBAL` | 同一 workspace 内全局唯一 | 无需 | 始终有效 | - -### 磁盘布局 - -``` -/ -├── agents// -│ ├── context//_sandbox.json ← SESSION scope(向下兼容原有路径) -│ └── sandboxes/ -│ ├── user/.json ← USER scope -│ └── agent.json ← AGENT scope -└── sandboxes/ - └── global.json ← GLOBAL scope -``` - -文件名中包含非安全字符(非 `[a-zA-Z0-9_\-.]`)的值会用 Base64url 编码,与 `WorkspaceSession` 的策略保持一致。 - -### 并发注意事项 - -这是顺序复用模型,**不是**进程内活跃实例的并发共享: - -- 相同 scope key 的并发调用,每次调用各自获取/创建独立的 Sandbox 实例 -- `persistState` 采用最后写入覆盖(last-writer-wins)语义 -- 需要并发共享同一个运行中实例的场景,属于未来的进阶功能(live instance registry) - -### 关键类 - -| 类 / 接口 | 职责 | -|-----------|------| -| `SandboxIsolationScope` | 枚举:`SESSION` / `USER` / `AGENT` / `GLOBAL` | -| `SandboxIsolationKey` | `(scope, value)` 不可变值类型;`resolve()` 从 RuntimeContext 计算 key | -| `SandboxStateStore` | 接口:按 key 读写删除 sandbox state JSON | -| `WorkspaceSandboxStateStore` | 文件系统实现;SESSION scope 委托给 `WorkspaceSession` 以保持向下兼容 | -| `SandboxContext.isolationScope` | 每次 call 通过 `RuntimeContext.sandboxContext(...)` 传入 | diff --git a/agentscope-harness/sandbox-filesystem-api-design.md b/agentscope-harness/sandbox-filesystem-api-design.md deleted file mode 100644 index b259830fc..000000000 --- a/agentscope-harness/sandbox-filesystem-api-design.md +++ /dev/null @@ -1,179 +0,0 @@ -# Sandbox 文件系统 API 设计分析 - -## 问题背景 - -当前 `HarnessAgent.Builder` 中有 4 个分散的 sandbox 专属参数: - -```java -private SandboxClient sandboxClient; -private SandboxClientOptions sandboxClientOptions; -private SandboxSnapshotSpec sandboxSnapshotSpec; -private SandboxManifest defaultSandboxManifest; -``` - -用户要开启 Docker 沙箱,需要在 Builder 上同时配置多处: - -```java -HarnessAgent.builder() - .sandboxClientOptions(new DockerSandboxClientOptions().image("python:3.12-slim")) - .sandboxSnapshotSpec(new LocalSnapshotSpec(...)) - .defaultSandboxManifest(manifest) - ... -``` - -这与"用户第一感知永远是文件系统"的核心设计原则冲突——用户通过 4 个沙箱专属参数感知沙箱,而不是通过文件系统类型。 - ---- - -## 目标 - -将 sandbox 配置收敛到文件系统类型的选择上,让用户通过 `abstractFilesystem()` 这一个入口完成所有配置,其余 sandbox 内部细节对用户完全隐藏。 - ---- - -## 方案对比 - -### 方案 A:让 `SandboxBackedFilesystem` 兼做配置载体 - -将 snapshot spec、manifest 等配置塞入现有的 `SandboxBackedFilesystem`,Builder 检测到 -`abstractFilesystem instanceof SandboxBackedFilesystem` 后自动提取并组装 hook。 - -```java -HarnessAgent.builder() - .abstractFilesystem( - new SandboxBackedFilesystem(new DockerSandboxClientOptions().image("python:3.12-slim")) - .snapshotSpec(new LocalSnapshotSpec(...)) - ) -``` - -**缺点:** - -- `SandboxBackedFilesystem` 同时扮演"配置描述对象"(build 时)和"运行时 session 代理" - (call 时)两个角色,职责混乱。 -- 类名是实现细节("backed by sandbox"),不应直接暴露给用户。 -- Builder 内部代码需要同时处理"用户配置的 SandboxBackedFilesystem"和"内部创建的 - SandboxBackedFilesystem"两种来源,容易混淆。 - ---- - -### 方案 B:新建用户面向的具名文件系统类型(推荐) - -为每种后端引入一个用户可见的文件系统类,`SandboxBackedFilesystem` 保持为内部代理, -对用户完全不可见。Builder 识别到具名类型后,在内部自动创建代理和 hook。 - -```java -// 本地文件系统(默认行为) -HarnessAgent.builder() - .abstractFilesystem(new LocalFilesystem(workspace)) // 对应已有的 LocalFilesystemWithShell - -// Docker 沙箱 -HarnessAgent.builder() - .abstractFilesystem( - new DockerFilesystem() - .image("python:3.12-slim") - .snapshotSpec(new LocalSnapshotSpec(...)) - .manifest(manifest) - ) -``` - -Builder 内部逻辑: - -``` -abstractFilesystem instanceof DockerFilesystem - → 提取 options / snapshotSpec / manifest - → 内部创建 SandboxBackedFilesystem(代理) - → 创建 SandboxLifecycleHook - → 将代理作为实际 backend -``` - -**优点:** - -- 类名即含义,`LocalFilesystem` / `DockerFilesystem` 对称,用户不需要理解 Sandbox 抽象层 -- `SandboxBackedFilesystem` 职责单一:纯运行时 session 代理,完全内部化 -- 结构天然支持未来扩展:`RemoteFilesystem`、`KubernetesFilesystem` 等只需新增类, - Builder API 不变 - ---- - -## 推荐方案(B)的类结构 - -``` -AbstractFilesystem ← 顶层接口(对用户可见,工具层依赖此接口) -├── LocalFilesystem ← 本地文件系统(alias for LocalFilesystemWithShell,用户直接 new) -└── DockerFilesystem ← Docker 沙箱文件系统(用户直接 new,内部持有配置) - 实现 AbstractFilesystem 仅作为标记 / 配置载体 - 不实际执行任何 fs 操作(由 Builder 替换为代理) - -内部(用户不可见) -└── SandboxBackedFilesystem ← 运行时代理,由 Builder 创建,注入实际 session -``` - -`DockerFilesystem` 的公开 API 设计: - -```java -new DockerFilesystem() - .image("python:3.12-slim") // Docker 镜像 - .workspaceRoot("/workspace") // 容器内工作区根目录(可选,有默认值) - .environment(Map) // 环境变量(可选) - .memorySizeBytes(512 * 1024 * 1024L) // 内存限制(可选) - .cpuCount(2L) // CPU 限制(可选) - .exposedPorts(8080, 8443) // 端口映射(可选) - .snapshotSpec(new LocalSnapshotSpec(...)) // 快照策略(可选,默认 Noop) - .manifest(manifest) // 初始工作区布局(可选) -``` - ---- - -## 配置参数归属分析 - -| 参数 | 归属 | 理由 | -|------|------|------| -| `SandboxClientOptions`(image、env 等) | `DockerFilesystem` 字段 | 描述文件系统后端的静态配置 | -| `SandboxManifest`(初始文件布局) | `DockerFilesystem` 字段 | 属于工作区初始化配置,和文件系统绑定 | -| `SandboxSnapshotSpec`(快照存储策略) | `DockerFilesystem` 字段 | 属于文件系统持久化策略 | -| `SandboxClient`(实现实例) | Builder 内部自动推导 | 实现细节,用户永远不需要感知 | -| `SandboxContext`(per-call 运行时覆盖) | 保留在 `RuntimeContext` | 动态参数,每次调用可能不同 | - -结论:`HarnessAgent.Builder` 的 4 个 sandbox 专属参数可以全部消除,只保留 -`abstractFilesystem()` 作为唯一入口。 - ---- - -## 实现步骤(待执行) - -1. 新建 `DockerFilesystem` 类: - - 持有 `DockerSandboxClientOptions`、`SandboxSnapshotSpec`、`SandboxManifest` - - 提供流式 builder 风格的 setter - - 实现 `AbstractFilesystem` 接口作为标记(所有方法抛 `UnsupportedOperationException`, - 因为 Builder 会在内部替换为真正的代理) - -2. 修改 `HarnessAgent.Builder.build()`: - - 检测 `abstractFilesystem instanceof DockerFilesystem` - - 从中提取配置,创建 `SandboxBackedFilesystem` 代理和 `SandboxLifecycleHook` - - 移除 `sandboxClient`、`sandboxClientOptions`、`sandboxSnapshotSpec`、 - `defaultSandboxManifest` 4 个字段和对应的 builder 方法 - -3. 移除 `SandboxClientOptions.createClient()` 抽象方法(该职责已不再需要对外暴露) - ---- - -## 迁移影响 - -现有代码: -```java -HarnessAgent.builder() - .sandboxClientOptions(new DockerSandboxClientOptions().image("python:3.12-slim")) - .sandboxSnapshotSpec(new LocalSnapshotSpec(...)) - .defaultSandboxManifest(manifest) -``` - -迁移后: -```java -HarnessAgent.builder() - .abstractFilesystem( - new DockerFilesystem() - .image("python:3.12-slim") - .snapshotSpec(new LocalSnapshotSpec(...)) - .manifest(manifest) - ) -``` diff --git a/agentscope-harness/sandbox-implementation-plan.md b/agentscope-harness/sandbox-implementation-plan.md deleted file mode 100644 index 092e39c94..000000000 --- a/agentscope-harness/sandbox-implementation-plan.md +++ /dev/null @@ -1,811 +0,0 @@ -# HarnessAgent Sandbox Mechanism Implementation Plan - -## Overview - -Based on `sandbox-design.md` goals and the OpenAI Agents Python reference implementation -(`references/openai-agents-python/src/agents/sandbox`), this plan describes a complete Sandbox -subsystem for HarnessAgent. - -Core approach: -- Add a `sandbox/` package inside `agentscope-harness`, establishing a full abstraction layer -- Embed into the existing Hook pipeline via a new `SandboxLifecycleHook` (`PreCallEvent` / `PostCallEvent`) -- `SandboxManager` centrally manages session acquisition and lifecycle (SDK-owned / developer-owned modes) -- `SandboxSession` implementations also serve as `AbstractSandboxFilesystem`, unifying the filesystem and session models -- Expose user-facing API on `HarnessAgent.Builder` and `RuntimeContext` - ---- - -## Module Structure - -``` -agentscope-harness/src/main/java/io/agentscope/harness/agent/ -├── sandbox/ -│ ├── SandboxSession.java # Core abstraction: sandbox lifecycle + exec -│ ├── SandboxClient.java # Interface: create / resume / delete -│ ├── SandboxClientOptions.java # Polymorphic options base class (type field) -│ ├── SandboxSessionState.java # Serializable session state -│ ├── SandboxManifest.java # Workspace descriptor (root + entries + env) -│ ├── SandboxContext.java # Per-call sandbox config aggregation -│ ├── SandboxManager.java # Lifecycle management core -│ ├── SandboxSessionAware.java # Filesystem injection interface -│ ├── snapshot/ -│ │ ├── SandboxSnapshot.java # Snapshot interface -│ │ ├── SandboxSnapshotSpec.java # Snapshot spec interface (build → SandboxSnapshot) -│ │ ├── LocalSandboxSnapshot.java # Local tar file implementation -│ │ ├── LocalSnapshotSpec.java -│ │ ├── NoopSandboxSnapshot.java # No-op implementation -│ │ ├── NoopSnapshotSpec.java -│ │ ├── RemoteSandboxSnapshot.java # Delegates to remote client (S3, etc.) -│ │ └── RemoteSnapshotSpec.java -│ ├── manifest/ -│ │ ├── ManifestEntry.java # Abstract entry -│ │ ├── FileEntry.java # Inline file content -│ │ ├── DirEntry.java # Empty directory -│ │ ├── LocalFileEntry.java # Copy file from host -│ │ ├── LocalDirEntry.java # Copy directory from host -│ │ └── GitRepoEntry.java # Clone a Git repo -│ └── impl/ -│ ├── local/ -│ │ ├── UnixLocalSandboxSession.java -│ │ ├── UnixLocalSandboxClient.java -│ │ ├── UnixLocalSandboxClientOptions.java -│ │ └── UnixLocalSandboxSessionState.java -│ └── docker/ -│ ├── DockerSandboxSession.java -│ ├── DockerSandboxClient.java -│ ├── DockerSandboxClientOptions.java -│ └── DockerSandboxSessionState.java -└── hook/ - └── SandboxLifecycleHook.java # New hook -``` - ---- - -## Step 1: Core Abstraction Layer - -### 1.1 SandboxSession - -Corresponds to Python `BaseSandboxSession`. The central abstraction for a sandbox instance. - -**Key responsibilities:** -- Manages the full lifecycle of a single sandbox instance: `start()` → running → `stop()` → `shutdown()` -- Provides exec / read / write / ls / mkdir / rm workspace operations -- `start()` internal flow: `ensureBackendStarted()` → `prepareWorkspace()` → `applyManifestOrRestoreSnapshot()` → `ensureRuntimeHelpers()` -- `stop()` only persists a snapshot (`persistSnapshot()`), does not destroy resources -- `shutdown()` destroys backend resources (container / temp dir), default is no-op -- `aclose()` = pre-stop hooks + `stop()` + `shutdown()` - -**Interface definition:** - -```java -public interface SandboxSession extends AutoCloseable { - // Lifecycle - void start() throws Exception; - void stop() throws Exception; - void shutdown() throws Exception; - void aclose() throws Exception; - boolean isRunning(); - - // Workspace operations (delegates to BaseSandboxFilesystem) - ExecResult exec(String command, Integer timeoutSeconds); - InputStream read(String path) throws Exception; - void write(String path, InputStream data) throws Exception; - List ls(String path) throws Exception; - void mkdir(String path) throws Exception; - void rm(String path, boolean recursive) throws Exception; - - // Workspace serialization - InputStream persistWorkspace() throws Exception; - void hydrateWorkspace(InputStream data) throws Exception; - - // State - SandboxSessionState getState(); -} -``` - -**Fusion with AbstractSandboxFilesystem:** - -`SandboxSession` implementations also extend `BaseSandboxFilesystem`, so the existing -shell-based default implementations (ls / read / write / edit / grep / glob) are reused: - -```java -// UnixLocalSandboxSession extends BaseSandboxFilesystem implements SandboxSession -// DockerSandboxSession extends BaseSandboxFilesystem implements SandboxSession -``` - ---- - -### 1.2 SandboxClient - -Corresponds to Python `BaseSandboxClient`. - -```java -public interface SandboxClient { - String getBackendId(); - - /** - * Creates a new SandboxSession. - * The session is NOT started automatically; the caller (usually SandboxManager) must call start(). - */ - SandboxSession create(SandboxManifest manifest, SandboxSnapshotSpec snapshotSpec, O options) - throws Exception; - - /** - * Resumes a session from a previously persisted SandboxSessionState. - * Re-connects to a still-alive backend instance, or creates a new one and restores via snapshot. - */ - SandboxSession resume(SandboxSessionState state) throws Exception; - - /** Deletes backend resources for SDK-owned sessions (container, temp dir, etc.). */ - void delete(SandboxSession session) throws Exception; - - /** Serializes session state to a JSON-compatible Map for persistent storage. */ - Map serializeState(SandboxSessionState state); - - /** Deserializes from a JSON payload into the concrete SandboxSessionState subclass. */ - SandboxSessionState deserializeState(Map payload); -} -``` - ---- - -### 1.3 SandboxSessionState - -Corresponds to Python `SandboxSessionState`. Serializable to JSON for storage in the session file. - -```java -public class SandboxSessionState { - private String type; // "unix_local" / "docker" / etc. - private UUID sessionId; - private SandboxManifest manifest; - private Map snapshotState; // Serialized snapshot info - private boolean workspaceRootReady; - private String snapshotFingerprint; - private String snapshotFingerprintVersion; - // Subclasses may add more fields (e.g. Docker containerId) -} -``` - ---- - -### 1.4 SandboxManifest - -Corresponds to Python `Manifest`. Describes the initial workspace state. - -```java -public class SandboxManifest { - private String root = "/workspace"; // Workspace root path - private Map entries; // Relative path → entry - private Map environment; // Environment variables - private List users; // Sandbox users -} -``` - -**ManifestEntry sub-types:** - -| Java class | Python equivalent | Purpose | -|------------------|-------------------|---------------------------------| -| `FileEntry` | `File` | Inline file content | -| `DirEntry` | `Dir` | Create empty directory | -| `LocalFileEntry` | `LocalFile` | Copy file from host | -| `LocalDirEntry` | `LocalDir` | Copy directory from host | -| `GitRepoEntry` | `GitRepo` | Clone a Git repository | - ---- - -### 1.5 SandboxContext - -Aggregates per-call sandbox configuration. Passed through `RuntimeContext`, read by `SandboxLifecycleHook`. - -```java -public class SandboxContext { - // Direct injection mode (developer-owned) - private SandboxSession session; - - // Via client mode (SDK-owned) - private SandboxClient client; - private SandboxClientOptions clientOptions; - private SandboxManifest manifest; // Overrides builder default manifest - private SandboxSnapshotSpec snapshotSpec; // Overrides builder default snapshot spec - - // Resume mode (provide serialized state) - private SandboxSessionState sessionState; - // Or auto-loaded from the "_sandbox" key in the session file - - public static Builder builder() { ... } -} -``` - ---- - -## Step 2: Snapshot Abstraction Layer - -Corresponds to Python `SnapshotBase` / `LocalSnapshot` / `NoopSnapshot` / `RemoteSnapshot`. - -### SandboxSnapshot Interface - -```java -public interface SandboxSnapshot { - void persist(InputStream workspaceArchive) throws Exception; - InputStream restore() throws Exception; - boolean isRestorable() throws Exception; - String getId(); -} -``` - -### SandboxSnapshotSpec Interface - -```java -public interface SandboxSnapshotSpec { - SandboxSnapshot build(String snapshotId); -} -``` - -### Three Implementations - -| Class | Description | Python equivalent | -|--------------------------|--------------------------------------------------------------------------------|--------------------| -| `LocalSandboxSnapshot` | Persists to a local `{basePath}/{id}.tar`; atomic write (write .tmp then rename) | `LocalSnapshot` | -| `NoopSandboxSnapshot` | No-op; `isRestorable()` returns false | `NoopSnapshot` | -| `RemoteSandboxSnapshot` | Delegates to user-provided `RemoteSnapshotClient` interface (upload/download/exists) | `RemoteSnapshot` | - ---- - -## Step 3: Concrete SandboxClient + SandboxSession Implementations - -### 3.1 UnixLocal Implementation - -Corresponds to Python `unix_local.py`. Suitable for local development with no extra dependencies. - -**UnixLocalSandboxClientOptions:** -```java -public class UnixLocalSandboxClientOptions extends SandboxClientOptions { - private String type = "unix_local"; - private Path workspaceBasePath; // Defaults to system temp dir if not specified - private int[] exposedPorts = {}; -} -``` - -**UnixLocalSandboxSession key implementation points:** -- `ensureBackendStarted()`: Creates a temp directory under `workspaceBasePath` as the workspace root -- `exec(command)`: Runs shell commands in the workspace root via `ProcessBuilder`, - reusing the existing `LocalFilesystemWithShell` exec logic -- `persistWorkspace()`: `exec("tar -cf - -C {root} .")` returns a tar `InputStream` -- `hydrateWorkspace(data)`: Extracts tar stream into the workspace root -- `shutdown()`: Deletes the temp directory if SDK-owned -- State type = `"unix_local"` - -**UnixLocalSandboxSessionState extra fields:** -```java -public class UnixLocalSandboxSessionState extends SandboxSessionState { - private String workspaceRoot; // Actual absolute workspace path in use - private boolean workspaceOwned; // Created by SDK (delete on shutdown)? -} -``` - ---- - -### 3.2 Docker Implementation - -Corresponds to Python `docker.py`. Requires `docker-java` dependency (marked `optional`). - -**pom.xml additions (agentscope-harness):** -```xml - - com.github.docker-java - docker-java-core - 3.4.0 - true - - - com.github.docker-java - docker-java-transport-httpclient5 - 3.4.0 - true - -``` - -**DockerSandboxClientOptions:** -```java -public class DockerSandboxClientOptions extends SandboxClientOptions { - private String type = "docker"; - private String image = "ubuntu:22.04"; - private String workspaceRoot = "/workspace"; - private Map envVars = Map.of(); - private Long memorySizeBytes; - private Long cpuCount; - private int[] exposedPorts = {}; -} -``` - -**DockerSandboxSession key implementation points:** -- `ensureBackendStarted()`: `docker pull` + `docker run -d` to start the container - (or reconnect via `containerId` from state) -- `exec(command)`: Via docker-java `ExecCreateCmd` + `ExecStartCmd`, collecting stdout/stderr -- `persistWorkspace()`: `docker exec tar -cf - -C {root} .`, using stdout as tar stream -- `hydrateWorkspace(data)`: Write tar stream into the container workspace root via `docker cp` -- `shutdown()`: If SDK-owned: `docker stop` + `docker rm` -- State type = `"docker"`, extra field: `containerId` - -**DockerSandboxSessionState extra fields:** -```java -public class DockerSandboxSessionState extends SandboxSessionState { - private String containerId; - private String image; -} -``` - ---- - -## Step 4: SandboxManager - -`SandboxManager` is the central scheduler responsible for resolving the sandbox instance -and completing workspace initialization. - -### Resolution Priority (corresponds to Python SandboxRunConfig priority) - -``` -1. SandboxContext.session is non-null → developer-owned, use directly, do NOT call start() -2. SandboxContext.sessionState is non-null → SDK-owned resume, call client.resume(state) -3. "_sandbox" state found in session file → SDK-owned resume, call client.resume(state) -4. None of the above → SDK-owned create, call client.create(manifest, snapshot, options) -``` - -### Core Methods - -```java -public class SandboxManager { - - /** - * Acquires (or creates) a SandboxSession from the SandboxContext in RuntimeContext. - * The returned session has already had start() called; the workspace is ready. - * The caller is responsible for deciding when to call stop/shutdown - * (handled automatically by SandboxLifecycleHook). - */ - public SandboxSession acquire(RuntimeContext runtimeContext) throws Exception; - - /** - * Persists the session workspace (snapshot) and optionally destroys backend resources. - * SDK-owned sessions trigger client.delete(); developer-owned sessions do not. - */ - public void release(SandboxSession session, boolean shutdown) throws Exception; - - /** - * Serializes SandboxSessionState and writes it to the RuntimeContext session store. - * Key = "_sandbox", for use in subsequent resume calls. - */ - public void persistState(SandboxSession session, RuntimeContext runtimeContext); - - /** - * Reads SandboxSessionState from the RuntimeContext session store. - * Returns null if no stored state is found. - */ - public SandboxSessionState loadState(RuntimeContext runtimeContext); -} -``` - -### Workspace Initialization Flow (corresponds to Python `BaseSandboxSession._start_workspace()`) - -``` -session.start() internally: - if snapshot.isRestorable(): - if workspacePreserved && fingerprintMatches: - reapplyEphemeralManifest() // Only rebuild ephemeral entries - else: - clearWorkspace() - hydrateWorkspace(snapshot.restore()) - applyManifest(onlyEphemeral=true) - elif workspacePreserved: - reapplyEphemeralManifest() - else: - applyManifest(full) // Materialize full manifest -``` - ---- - -## Step 5: SandboxLifecycleHook - -A new Hook that integrates into the HarnessAgent Hook pipeline. - -### Trigger Timing - -| Event | Action | -|-----------------|------------------------------------------------------------------------------------------| -| `PreCallEvent` | Read SandboxContext from RuntimeContext → `SandboxManager.acquire()` → inject filesystem | -| `PostCallEvent` | `SandboxManager.release(session, shutdown=true if SDK-owned)` → `persistState()` → clear ref | -| `ErrorEvent` | Same as PostCallEvent (best-effort, no re-throw) | - -### Implementation Skeleton - -```java -public class SandboxLifecycleHook implements Hook, RuntimeContextAwareHook { - - private final SandboxManager sandboxManager; - private final SandboxClient defaultClient; - private final SandboxClientOptions defaultClientOptions; - private final SandboxSnapshotSpec defaultSnapshotSpec; - private final AbstractFilesystem filesystem; - - private RuntimeContext runtimeContext; - private SandboxSession activeSession; - private boolean sdkOwned; - - @Override - public Mono onEvent(T event) { - if (event instanceof PreCallEvent) { - return handlePreCall(event); - } - if (event instanceof PostCallEvent || event instanceof ErrorEvent) { - return handlePostCall(event); - } - return Mono.just(event); - } - - private Mono handlePreCall(T event) { - return Mono.fromCallable(() -> { - SandboxContext ctx = resolveSandboxContext(); - if (ctx == null) return event; // Sandbox not enabled - - activeSession = sandboxManager.acquire(runtimeContext); - sdkOwned = (ctx.getSession() == null); // Directly injected = developer-owned - - // Inject into filesystem - if (filesystem instanceof SandboxSessionAware aware) { - aware.setSandboxSession(activeSession); - } - return event; - }); - } - - private Mono handlePostCall(T event) { - return Mono.fromCallable(() -> { - SandboxSession session = activeSession; - if (session == null) return event; - - try { - sandboxManager.release(session, sdkOwned); - sandboxManager.persistState(session, runtimeContext); - } catch (Exception e) { - log.warn("SandboxLifecycleHook: release failed: {}", e.getMessage()); - } finally { - activeSession = null; - } - return event; - }); - } - - private SandboxContext resolveSandboxContext() { - // Priority 1: SandboxContext from RuntimeContext - // Priority 2: Default client configured via builder - SandboxContext ctx = runtimeContext != null - ? runtimeContext.getSandboxContext() : null; - if (ctx == null && defaultClient != null) { - ctx = SandboxContext.builder() - .client(defaultClient) - .clientOptions(defaultClientOptions) - .snapshotSpec(defaultSnapshotSpec) - .build(); - } - return ctx; - } -} -``` - ---- - -## Step 6: SandboxSessionAware Interface - -Provides an injection point so `SandboxLifecycleHook` can push the live session into the filesystem. - -```java -/** - * Marks an AbstractFilesystem implementation that can accept - * a live SandboxSession at runtime, enabling session injection - * by SandboxLifecycleHook before each agent call. - */ -public interface SandboxSessionAware { - void setSandboxSession(SandboxSession session); - SandboxSession getSandboxSession(); -} -``` - -**SandboxFilesystemAdapter** (optional, for decoupled implementations): - -Wraps a `SandboxSession` and implements `AbstractSandboxFilesystem`, delegating all calls -to the current session. Suitable when session implementations do not extend `BaseSandboxFilesystem`. - ---- - -## Step 7: RuntimeContext Extension - -Add a `sandboxContext` field to `RuntimeContext`, or pass it via the extra map with a well-known key. - -**Recommended: explicit typed field** (type-safe, consistent with existing `session`/`sessionKey` fields): - -```java -public class RuntimeContext { - // Existing fields... - private final SandboxContext sandboxContext; // New field - - public SandboxContext getSandboxContext() { return sandboxContext; } - - public static class Builder { - public Builder sandboxContext(SandboxContext ctx) { ... } - } -} -``` - -**Alternative: well-known extra key** (backward-compatible): - -```java -public SandboxContext getSandboxContext() { - Object val = getExtra().get("_sandboxContext"); - return val instanceof SandboxContext sc ? sc : null; -} - -public RuntimeContext withSandboxContext(SandboxContext ctx) { - return RuntimeContext.builder() - .putAllExtra(getExtra()) - .putExtra("_sandboxContext", ctx) - .build(); -} -``` - ---- - -## Step 8: HarnessAgent Builder Extension - -Add sandbox configuration API to `HarnessAgent.Builder`: - -```java -public class Builder { - // New fields - private SandboxClient sandboxClient; - private SandboxClientOptions sandboxClientOptions; - private SandboxSnapshotSpec sandboxSnapshotSpec; - private SandboxManifest defaultSandboxManifest; - - /** Configures the sandbox client (e.g. UnixLocalSandboxClient / DockerSandboxClient). */ - public Builder sandboxClient(SandboxClient client) { - this.sandboxClient = client; - return this; - } - - /** Configures sandbox client options (e.g. DockerSandboxClientOptions to specify image). */ - public Builder sandboxClientOptions(SandboxClientOptions options) { - this.sandboxClientOptions = options; - return this; - } - - /** Configures the default snapshot strategy (Local / Noop / Remote). */ - public Builder sandboxSnapshotSpec(SandboxSnapshotSpec spec) { - this.sandboxSnapshotSpec = spec; - return this; - } - - /** Configures the default sandbox workspace manifest (entries, env vars, etc.). */ - public Builder defaultSandboxManifest(SandboxManifest manifest) { - this.defaultSandboxManifest = manifest; - return this; - } - - public HarnessAgent build() { - // ...existing build logic... - - // If sandboxClient is configured, register SandboxLifecycleHook - if (sandboxClient != null) { - SandboxManager sandboxManager = new SandboxManager(sandboxClient, defaultSandboxManifest); - SandboxLifecycleHook sandboxHook = new SandboxLifecycleHook( - sandboxManager, - sandboxClient, - sandboxClientOptions, - sandboxSnapshotSpec, - backend // AbstractFilesystem - ); - allHooks.add(sandboxHook); - } - // ... - } -} -``` - ---- - -## Step 9: Session Sandbox State Persistence - -Extend `WorkspaceSession` to support reading/writing the `_sandbox` key, -corresponding to how OpenAI Agents SDK stores sandbox payload in `RunState`. - -```java -public class WorkspaceSession implements Session { - - /** Saves sandbox session state to the "_sandbox" field of the session file. */ - public void saveSandboxState(SessionKey key, Map statePayload) { - // Read current session JSON → merge "_sandbox" field → write back - } - - /** Reads the "_sandbox" field and returns the serialized Map for SandboxClient.deserializeState(). */ - public Map loadSandboxStatePayload(SessionKey key) { - // Read session JSON → extract "_sandbox" field - } -} -``` - -`SandboxManager.persistState()` call flow: - -``` -SandboxManager.persistState(session, runtimeContext) - → state = session.getState() - → payload = client.serializeState(state) - → workspaceSession = runtimeContext.getSession() - → workspaceSession.saveSandboxState(runtimeContext.getSessionKey(), payload) -``` - ---- - -## User-Facing Usage Examples - -### Unix Local Mode (quick local development) - -```java -HarnessAgent agent = HarnessAgent.builder() - .name("MyAgent") - .model(model) - .sysPrompt("You are a helpful coding assistant.") - .workspace(Path.of("/path/to/workspace")) - .sandboxClient(new UnixLocalSandboxClient()) - .sandboxClientOptions( - new UnixLocalSandboxClientOptions() - .workspaceBasePath(Path.of("/tmp/agent-sandboxes")) - ) - .sandboxSnapshotSpec( - new LocalSnapshotSpec(Path.of("/tmp/agent-snapshots")) - ) - .defaultSandboxManifest( - SandboxManifest.builder() - .root("/workspace") - .entry("repo", new LocalDirEntry(Path.of("/my/project"))) - .build() - ) - .build(); - -// Sandbox is managed automatically by HarnessAgent -Msg response = agent.call( - Msg.userMsg("Fix the bug in auth.java"), - RuntimeContext.builder().sessionId("sess-001").build() -).block(); -``` - -### Docker Mode (container isolation) - -```java -DockerClient dockerClient = DockerClientBuilder.getInstance().build(); - -HarnessAgent agent = HarnessAgent.builder() - .name("DockerAgent") - .model(model) - .sandboxClient(new DockerSandboxClient(dockerClient)) - .sandboxClientOptions( - new DockerSandboxClientOptions() - .image("python:3.12-slim") - .memorySizeBytes(512 * 1024 * 1024L) - ) - .sandboxSnapshotSpec(new LocalSnapshotSpec(Path.of("/tmp/docker-snapshots"))) - .build(); -``` - -### Developer-Owned Mode (manual lifecycle management) - -```java -UnixLocalSandboxClient client = new UnixLocalSandboxClient(); -SandboxSession sandbox = client.create(manifest, snapshotSpec, options); -sandbox.start(); - -try { - // Reuse the same sandbox across multiple calls - for (String task : tasks) { - agent.call( - Msg.userMsg(task), - RuntimeContext.builder() - .sessionId("sess-001") - .sandboxContext(SandboxContext.builder().session(sandbox).build()) - .build() - ).block(); - } -} finally { - sandbox.stop(); // Persist snapshot - sandbox.shutdown(); // Clean up resources - client.delete(sandbox); -} -``` - -### Resume Mode (restore workspace across calls) - -```java -// After the first call, SandboxLifecycleHook automatically writes state to the session file. - -// On the next call (auto-resume): -// WorkspaceSession reads the "_sandbox" field -// SandboxManager finds sessionState → calls client.resume(state) -// Workspace is restored from snapshot -Msg response2 = agent.call( - Msg.userMsg("Continue working on the previous task"), - RuntimeContext.builder().sessionId("sess-001").build() // Same sessionId triggers auto-resume -).block(); -``` - ---- - -## Implementation Priority - -| Phase | Content | Priority | -|-------|-----------------------------------------------------------------------------------|----------| -| P0 | Core abstractions (SandboxSession / SandboxClient / SandboxManager / SandboxContext) | Required | -| P0 | Snapshot abstractions (NoopSnapshot + LocalSnapshot) | Required | -| P0 | UnixLocalSandboxSession + UnixLocalSandboxClient | Required | -| P0 | SandboxLifecycleHook + SandboxSessionAware | Required | -| P0 | RuntimeContext extension + HarnessAgent Builder API | Required | -| P1 | WorkspaceSession `_sandbox` state persistence + Resume flow | Important | -| P1 | SandboxManifest materialization (LocalDir / LocalFile / File / Dir entries) | Important | -| P1 | DockerSandboxSession + DockerSandboxClient | Important | -| P2 | RemoteSandboxSnapshot (S3, etc.) | Extension | -| P2 | GitRepoEntry manifest entry | Extension | -| P2 | Workspace fingerprint caching (avoid redundant snapshot restores) | Optimization | - ---- - -## Design Decisions - -### 1. SandboxSession vs AbstractSandboxFilesystem Fusion Strategy - -**Short-term: Option A — Direct inheritance of `BaseSandboxFilesystem`** - -Both `UnixLocalSandboxSession` and `DockerSandboxSession` extend `BaseSandboxFilesystem` -and implement `SandboxSession`. - -Pros: Reuses the existing shell-based filesystem logic; existing tools (FilesystemTool, ShellExecuteTool) -require no modification. - -**Long-term: Option B — Independent `SandboxFilesystemAdapter`** (future refactor direction) - -`SandboxSession` is kept independent; a `SandboxFilesystemAdapter` wraps it and injects it, -cleanly decoupling session lifecycle from filesystem operations. - ---- - -### 2. Sandbox Propagation to Subagents - -When HarnessAgent spawns subagents, the sandbox mode must be decided: - -- **Shared sandbox** (developer-owned propagation): Parent passes its `SandboxSession` via - `SandboxContext.session` to the subagent. Subagent operates in the same workspace. - Suitable for collaborative tasks. -- **Isolated sandbox** (independent create): Subagent gets its own sandbox with an isolated workspace. - Suitable for concurrent independent tasks. - -Default strategy: subagents use isolated sandboxes. If `SandboxContext.session` is explicitly -passed, shared mode is used. Configure via `buildGeneralPurposeFactory` / `buildSpecFactory`. - ---- - -### 3. SandboxContext Delivery in RuntimeContext - -**Chosen: explicit typed field** (type-safe, consistent with existing `session`/`sessionKey` style) - -Add `private final SandboxContext sandboxContext` to `RuntimeContext`, -set via `Builder.sandboxContext(ctx)`. - ---- - -## Reference Material - -- OpenAI Agents Python reference: `references/openai-agents-python/src/agents/sandbox/` -- `session/base_sandbox_session.py` — lifecycle core logic -- `session/sandbox_client.py` — client interface and polymorphic options -- `session/sandbox_session_state.py` — serializable state model -- `snapshot.py` — three snapshot implementations -- `manifest.py` — workspace descriptor model -- `sandboxes/unix_local.py` — Unix local implementation reference -- `sandboxes/docker.py` — Docker implementation reference -- `docs/sandbox/guide.md` — full concepts and usage documentation - diff --git a/agentscope-harness/sandbox-implementation-status.md b/agentscope-harness/sandbox-implementation-status.md deleted file mode 100644 index 6b8e5ec9c..000000000 --- a/agentscope-harness/sandbox-implementation-status.md +++ /dev/null @@ -1,231 +0,0 @@ -# Sandbox 子系统实现情况总结 - -## 目标 - -为 `HarnessAgent` 构建一套完整的 Sandbox(沙箱)子系统,使 Agent 的每次调用都可以在隔离的工作区环境中执行命令和文件操作,同时支持工作区快照(Snapshot)持久化与跨调用恢复。 - -核心设计原则: - -- 通过 **Hook 管道**(`SandboxLifecycleHook`)无侵入地集成到 `HarnessAgent` 的现有流程 -- 以 **`SandboxManager`** 为核心调度器,统一管理 Session 的获取与生命周期 -- `SandboxSession` 实现类同时扮演 **文件系统后端**(通过 `SandboxBackedFilesystem`),使现有工具(`FilesystemTool`、`ShellExecuteTool`)无需修改 -- `HarnessAgent.Builder` 提供简洁的用户 API,支持三种使用模式:SDK 托管、开发者托管、Resume 恢复 - ---- - -## 实现计划(阶段划分) - -| 阶段 | 内容 | 优先级 | -|------|------|--------| -| P0 | 核心抽象层(接口、异常、状态、Manifest) | 必须 | -| P0 | 快照抽象层(NoopSnapshot、LocalSnapshot) | 必须 | -| P0 | UnixLocal 实现(本地进程沙箱) | 必须 | -| P0 | SandboxLifecycleHook + SandboxSessionAware | 必须 | -| P0 | RuntimeContext 扩展 + HarnessAgent Builder API | 必须 | -| P1 | WorkspaceSession `_sandbox` 状态持久化 + Resume 流程 | 重要 | -| P1 | SandboxManifest 物化(LocalDir / LocalFile / File / Dir) | 重要 | -| P1 | DockerSandboxSession + DockerSandboxClient | 重要 | -| P2 | RemoteSandboxSnapshot(S3 等) | 扩展 | -| P2 | GitRepoEntry Manifest 条目 | 扩展 | -| P2 | 工作区指纹缓存(避免冗余快照恢复) | 优化 | - ---- - -## 实现状态 - -### ✅ 已完成 - -#### 核心抽象层(`sandbox/` 包) - -| 文件 | 说明 | -|------|------| -| `SandboxErrorCode.java` | 11 个错误码枚举(`EXEC_NONZERO`、`EXEC_TIMEOUT`、`WORKSPACE_START_ERROR` 等) | -| `SandboxException.java` | 基类 + 7 个内部子类(`ExecException`、`ExecTimeoutException`、`SnapshotException` 等) | -| `ExecResult.java` | `record(int exitCode, String stdout, String stderr, boolean truncated)`,带 `ok()`、`combinedOutput()` | -| `SandboxSessionAware.java` | 注入接口:`setSandboxSession(SandboxSession)`、`getSandboxSession()` | -| `SandboxSession.java` | 核心接口:完整生命周期(`start/stop/shutdown/close`)+ exec + 工作区序列化 | -| `SandboxClient.java` | 泛型接口 ``:create / resume / delete / 状态序列化 | -| `SandboxClientOptions.java` | 多态基类,`@JsonTypeInfo(NAME)`,已注册 `unix_local`、`docker` | -| `SandboxSessionState.java` | 多态基类,`@JsonTypeInfo(NAME)`,已注册 `unix_local`、`docker` | -| `SandboxManifest.java` | 工作区描述符:`root`、`entries`(LinkedHashMap)、`environment` | -| `SandboxContext.java` | 不可变 Builder,聚合每次调用的沙箱配置(client、options、manifest、snapshotSpec、externalSession) | -| `SandboxAcquireResult.java` | `session + sdkOwned:boolean`,`sdkOwned()` / `developerOwned()` 工厂方法 | -| `SandboxManager.java` | 4 优先级 acquire 逻辑(developer-owned → resume-from-state → resume-from-file → create-new)、release、persistState、clearState | -| `AbstractBaseSandboxSession.java` | 4 分支 start 逻辑(Branch A/B/C/D)、stop/close/exec/persistWorkspace/hydrateWorkspace | -| `ManifestApplier.java` | 递归物化 Manifest:FileEntry / DirEntry / LocalFileEntry / LocalDirEntry / GitRepoEntry(P2 占位 warn) | -| `WorkspaceArchiveExtractor.java` | 安全 tar 解压(使用 commons-compress),路径遍历防护(`..`、绝对路径、null 字节) | -| `SandboxBackedFilesystem.java` | 扩展 `BaseSandboxFilesystem`,实现 `SandboxSessionAware`;exec 代理到 `session.exec()`;upload/download 通过 Base64 编码命令实现 | - -#### Manifest 子类型(`sandbox/manifest/` 包) - -| 文件 | 说明 | -|------|------| -| `ManifestEntry.java` | 抽象基类,`@JsonTypeInfo`,5 个子类型注册 | -| `FileEntry.java` | 内联文件内容,`content + encoding` | -| `DirEntry.java` | 创建目录,`children: LinkedHashMap`,支持 `.child()` 链式构建 | -| `LocalFileEntry.java` | 从宿主机复制文件,`sourcePath` | -| `LocalDirEntry.java` | 从宿主机复制目录,`sourcePath` | -| `GitRepoEntry.java` | 克隆 Git 仓库(P2 占位),`url + ref` | - -#### 快照层(`sandbox/snapshot/` 包) - -| 文件 | 说明 | -|------|------| -| `SandboxSnapshot.java` | 接口:`persist / restore / isRestorable / getId / getType`,`@JsonTypeInfo` | -| `SandboxSnapshotSpec.java` | 工厂接口:`build(snapshotId) → SandboxSnapshot` | -| `NoopSandboxSnapshot.java` | 丢弃归档流,`isRestorable()=false` | -| `NoopSnapshotSpec.java` | 始终返回新 `NoopSandboxSnapshot` | -| `LocalSandboxSnapshot.java` | 持久化到 `{basePath}/{id}.tar`,原子写入(tmp + `ATOMIC_MOVE`),路径安全校验 | -| `LocalSnapshotSpec.java` | 工厂,创建 `LocalSandboxSnapshot` | -| `RemoteSandboxSnapshot.java` | 委托到 `RemoteSnapshotClient`(上传/下载/exists) | -| `RemoteSnapshotSpec.java` | 工厂,创建 `RemoteSandboxSnapshot` | -| `RemoteSnapshotClient.java` | 用户扩展接口(S3 等):`upload / download / exists` | - -#### Unix Local 实现(`sandbox/impl/local/` 包) - -| 文件 | 说明 | -|------|------| -| `UnixLocalSandboxClientOptions.java` | `workspaceBasePath: String`、`exposedPorts: int[]`,`getType()="unix_local"` | -| `UnixLocalSandboxSessionState.java` | 扩展 `SandboxSessionState`:`workspaceRoot`、`workspaceRootOwned` | -| `UnixLocalSandboxSession.java` | `doExec()` 通过 `ProcessBuilder("sh","-c",cmd)` + 2 线程 stdout/stderr 排空;`doPersistWorkspace()` 通过 `tar -cf - -C .`;`doHydrateWorkspace()` 通过 `WorkspaceArchiveExtractor`;`shutdown()` 删除自有临时目录 | -| `UnixLocalSandboxClient.java` | UUID sessionId,`resolveWorkspaceRoot()`(basePath → `/` 或系统 tmpdir → `/`);Jackson 多态序列化/反序列化 | - -#### Docker 实现(`sandbox/impl/docker/` 包) - -| 文件 | 说明 | -|------|------| -| `DockerSandboxClientOptions.java` | `image`(默认 `ubuntu:22.04`)、`workspaceRoot`、`environment`、`memorySizeBytes`、`cpuCount`、`exposedPorts` | -| `DockerSandboxSessionState.java` | 扩展 `SandboxSessionState`:`containerId`、`containerName`、`image`、`workspaceRoot`、`containerOwned`,及用于容器重建的资源字段 | -| `DockerSandboxSession.java` | 通过 Docker CLI(`ProcessBuilder`,无 docker-java 依赖);`start()` 处理 running/stopped/missing 三种容器状态;exec 通过 `docker exec -w `;工作区归档通过 `docker exec tar`;`shutdown()` 执行 `docker stop` + `docker rm` | -| `DockerSandboxClient.java` | 创建/恢复 Docker 沙箱 Session;Jackson 多态序列化/反序列化 | - -#### Hook 集成(`hook/` 包) - -| 文件 | 说明 | -|------|------| -| `SandboxLifecycleHook.java` | `priority=50`(优先于所有现有 Hook 运行);`PreCallEvent`:acquire → start → inject session → set ThreadLocal;`PostCallEvent/ErrorEvent`:persistState → release → clearSession(best-effort) | - -#### 现有文件修改 - -| 文件 | 修改内容 | -|------|---------| -| `pom.xml` | 添加 `commons-compress 1.27.1` 依赖 | -| `RuntimeContext.java` | 添加 `sandboxContext: SandboxContext` 字段 + Builder `sandboxContext()` 方法 | -| `WorkspaceSession.java` | 添加 `saveSandboxState(SessionKey, String)`、`loadSandboxStateJson(SessionKey)`、`deleteSandboxState(SessionKey)`、`resolveSessionDir(SessionKey)` | -| `SandboxBackedFilesystem.java` | 添加 `configureNamespace(NamespaceFactory)` 公开方法 | -| `HarnessAgent.java` | Builder 添加 `sandboxClient/Options/SnapshotSpec/defaultManifest` 字段与方法;`build()` 中创建 `SandboxBackedFilesystem`、`SandboxManager`、`SandboxLifecycleHook`;`ensureSessionDefaults()` 保留/注入 `sandboxContext`;`bindRuntimeContext()` 传播上下文到 `sandboxLifecycleHook`;subagent factory 传播 `sandboxFs` | - ---- - -## 关键设计决策 - -### 1. Session 与 Filesystem 融合策略 - -采用 **直接继承** `BaseSandboxFilesystem` 方案(短期方案 A): - -- `UnixLocalSandboxSession` 和 `DockerSandboxSession` 均扩展 `AbstractBaseSandboxSession` -- `SandboxBackedFilesystem` 作为代理层,通过 `SandboxSessionAware` 接口接收注入的 Session -- 现有工具(`FilesystemTool`、`ShellExecuteTool`)无需任何修改 - -### 2. Session 获取优先级(4-Branch Acquire) - -``` -1. SandboxContext.externalSession != null → developer-owned(不调用 start()) -2. SandboxContext.externalSessionState != null → SDK-owned resume -3. WorkspaceSession 中存在 _sandbox.json → SDK-owned resume(跨调用自动恢复) -4. 以上均不满足 → SDK-owned create(全新初始化) -``` - -### 3. 工作区初始化(4-Branch Start) - -``` -Branch A: workspaceRootReady=true & 目录仍存在 → 仅应用 ephemeral 条目 -Branch B: workspaceRootReady=true & 目录已丢失 → 从快照恢复 + ephemeral 条目 -Branch C: workspaceRootReady=false & 快照可恢复 → 从快照 hydrate + 全量 Manifest -Branch D: workspaceRootReady=false & 无可用快照 → 全量 Manifest 初始化 -``` - -### 4. Docker 实现无第三方依赖 - -Docker 实现通过 Docker CLI(`docker exec`、`docker run` 等)调用,不引入 `docker-java` 库, -保持 `agentscope-harness` 的依赖简洁性。 - -### 5. 子 Agent 传播策略 - -默认策略:子 Agent 使用隔离的沙箱(独立 create)。 -若 `SandboxContext.externalSession` 被显式传递,则使用共享模式。 -通过 `buildGeneralPurposeFactory()` 将 `capturedSandboxFs` 传播给子 Agent,但不传递生命周期管理(`sandboxClient`)。 - ---- - -## 模块结构(最终) - -``` -agentscope-harness/src/main/java/io/agentscope/harness/agent/ -├── sandbox/ -│ ├── SandboxSession.java -│ ├── SandboxClient.java -│ ├── SandboxClientOptions.java ← @JsonSubTypes: unix_local, docker -│ ├── SandboxSessionState.java ← @JsonSubTypes: unix_local, docker -│ ├── SandboxManifest.java -│ ├── SandboxContext.java -│ ├── SandboxAcquireResult.java -│ ├── SandboxManager.java -│ ├── SandboxSessionAware.java -│ ├── SandboxBackedFilesystem.java -│ ├── SandboxException.java -│ ├── SandboxErrorCode.java -│ ├── ExecResult.java -│ ├── AbstractBaseSandboxSession.java -│ ├── ManifestApplier.java -│ ├── WorkspaceArchiveExtractor.java -│ ├── manifest/ -│ │ ├── ManifestEntry.java -│ │ ├── FileEntry.java -│ │ ├── DirEntry.java -│ │ ├── LocalFileEntry.java -│ │ ├── LocalDirEntry.java -│ │ └── GitRepoEntry.java -│ ├── snapshot/ -│ │ ├── SandboxSnapshot.java -│ │ ├── SandboxSnapshotSpec.java -│ │ ├── NoopSandboxSnapshot.java -│ │ ├── NoopSnapshotSpec.java -│ │ ├── LocalSandboxSnapshot.java -│ │ ├── LocalSnapshotSpec.java -│ │ ├── RemoteSandboxSnapshot.java -│ │ ├── RemoteSnapshotSpec.java -│ │ └── RemoteSnapshotClient.java -│ └── impl/ -│ ├── local/ -│ │ ├── UnixLocalSandboxClientOptions.java -│ │ ├── UnixLocalSandboxSessionState.java -│ │ ├── UnixLocalSandboxSession.java -│ │ └── UnixLocalSandboxClient.java -│ └── docker/ -│ ├── DockerSandboxClientOptions.java -│ ├── DockerSandboxSessionState.java -│ ├── DockerSandboxSession.java -│ └── DockerSandboxClient.java -└── hook/ - └── SandboxLifecycleHook.java -``` - ---- - -## 待实现(P2 / 未来方向) - -| 项目 | 说明 | -|------|------| -| `GitRepoEntry` 物化 | 当前仅打印 warn,需实现 `git clone` 逻辑 | -| 工作区指纹缓存 | 避免相同工作区内容重复触发快照恢复,Python 参考实现中的 `snapshotFingerprint` 字段 | -| 子 Agent 共享沙箱 API | 提供更显式的 API 让父 Agent 将自己的 Session 传递给子 Agent | -| Docker Windows 支持 | 当前 Docker 实现仅测试过 Unix 环境 | -| `SandboxFilesystemAdapter` | 将 Session 生命周期与 Filesystem 操作彻底解耦(长期重构方向) | - ---- - -## 测试状态 - -- `agentscope-harness` 模块共 6 个测试,5 个通过 -- `HarnessAgentIntegrationExampleTest.example_fullWorkspace_singleTurn_seesSessionSubagentsAndWorkspaceContext` 失败(Line 150,`expected: but was: `)——此为**预存在缺陷**,在本次 Sandbox 实现开始前已存在,与沙箱代码无关 diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 45f6aad0a..b889e9edf 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -42,7 +42,7 @@ import io.agentscope.harness.agent.filesystem.AbstractSandboxFilesystem; import io.agentscope.harness.agent.filesystem.LocalFilesystemSpec; import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; -import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.hook.AgentTraceHook; import io.agentscope.harness.agent.hook.CompactionHook; import io.agentscope.harness.agent.hook.MemoryFlushHook; @@ -478,7 +478,7 @@ public static class Builder { // Filesystem mode configuration (at most one of these three is set) private SandboxFilesystemSpec sandboxFilesystemSpec; - private StoreFilesystemSpec storeFilesystemSpec; + private RemoteFilesystemSpec remoteFilesystemSpec; private LocalFilesystemSpec localFilesystemSpec; public Builder name(String name) { @@ -566,7 +566,7 @@ public Builder environmentMemory(String environmentMemory) { /** * Escape hatch: sets a custom {@link AbstractFilesystem} implementation directly. * - *

    Prefer {@link #filesystem(LocalFilesystemSpec)}, {@link #filesystem(StoreFilesystemSpec)} + *

    Prefer {@link #filesystem(LocalFilesystemSpec)}, {@link #filesystem(RemoteFilesystemSpec)} * or {@link #filesystem(SandboxFilesystemSpec)} unless you have a bespoke backend that is * not expressible via any of the declarative specs. */ @@ -592,13 +592,13 @@ public Builder filesystem(SandboxFilesystemSpec spec) { /** * Configures Mode 1 — composite (non-sandbox) filesystem mode: a unified workspace * view that blends a local {@code LocalFilesystem} backend with a shared - * {@code StoreFilesystem} for distributed long-term memory. Shell execution is not + * {@code RemoteFilesystem} for distributed long-term memory. Shell execution is not * available in this mode — selected prefixes ({@code MEMORY.md}, {@code memory/}, * {@code agents/.../sessions/}) are routed to the store to keep memory consistent across * replicas. */ - public Builder filesystem(StoreFilesystemSpec spec) { - this.storeFilesystemSpec = spec; + public Builder filesystem(RemoteFilesystemSpec spec) { + this.remoteFilesystemSpec = spec; return this; } @@ -818,11 +818,11 @@ public List buildSubagentEntries( public HarnessAgent build() { int specCount = 0; if (sandboxFilesystemSpec != null) specCount++; - if (storeFilesystemSpec != null) specCount++; + if (remoteFilesystemSpec != null) specCount++; if (localFilesystemSpec != null) specCount++; if (specCount > 1) { throw new IllegalStateException( - "At most one of sandboxFilesystemSpec, storeFilesystemSpec," + "At most one of sandboxFilesystemSpec, remoteFilesystemSpec," + " localFilesystemSpec may be configured"); } if (abstractFilesystem != null && specCount > 0) { @@ -1080,8 +1080,8 @@ private AbstractFilesystem resolveFilesystem( return abstractFilesystem; } NamespaceFactory nsFactory = buildDynamicNamespaceFactory(userIdRef); - if (storeFilesystemSpec != null) { - return storeFilesystemSpec.toFilesystem( + if (remoteFilesystemSpec != null) { + return remoteFilesystemSpec.toFilesystem( workspace, agentId, nsFactory, userIdRef::get, sessionIdRef::get); } if (localFilesystemSpec != null) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java index 74eb6737b..e572bf2dd 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java @@ -19,8 +19,8 @@ * Controls how agent state is isolated and shared across calls. * *

    This enum is the canonical isolation-scope definition used by both the sandbox filesystem - * backend ({@link io.agentscope.harness.agent.sandbox.SandboxContext}) and the store filesystem - * backend ({@link io.agentscope.harness.agent.filesystem.StoreFilesystemSpec}). + * backend ({@link io.agentscope.harness.agent.sandbox.SandboxContext}) and the remote filesystem + * backend ({@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec}). * *

    Sandbox semantics: the scope determines which key is used when persisting and loading * {@code _sandbox.json} state. Calls that resolve to the same scope key will @@ -28,7 +28,7 @@ * one). * *

    Store namespace semantics: the scope determines the namespace prefix used by - * {@link io.agentscope.harness.agent.filesystem.StoreFilesystem} when routing files to the shared + * {@link io.agentscope.harness.agent.filesystem.RemoteFilesystem} when routing files to the shared * key-value store. Different scopes produce different namespace prefixes, controlling which calls * share the same view of stored files. * diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java index 328d5ddde..3501f8194 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemSpec.java @@ -31,7 +31,7 @@ * where distributed sharing is not required and the agent is trusted to run host shell commands. * *

    For distributed deployments where long-term memory must be shared across replicas, prefer - * {@link StoreFilesystemSpec} (no shell) or a sandbox filesystem spec (shell via sandbox). + * {@link RemoteFilesystemSpec} (no shell) or a sandbox filesystem spec (shell via sandbox). */ public class LocalFilesystemSpec { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java similarity index 97% rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java index f69bd1136..fc0cafb79 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java @@ -52,23 +52,23 @@ *

    Dynamic namespace example: * *

    {@code
    - * StoreFilesystem fs = new StoreFilesystem(store,
    + * RemoteFilesystem fs = new RemoteFilesystem(store,
      *     () -> List.of("sessions", sessionIdSupplier.get(), "filesystem"));
      * }
    */ -public class StoreFilesystem implements AbstractFilesystem { +public class RemoteFilesystem implements AbstractFilesystem { private final BaseStore store; private final NamespaceFactory namespaceFactory; /** - * Creates a StoreFilesystem with a {@link NamespaceFactory} that is called on every operation, + * Creates a RemoteFilesystem with a {@link NamespaceFactory} that is called on every operation, * allowing the namespace to vary based on runtime context. * * @param store the store to use for persistence * @param namespaceFactory factory that returns the namespace tuple per operation */ - public StoreFilesystem(BaseStore store, NamespaceFactory namespaceFactory) { + public RemoteFilesystem(BaseStore store, NamespaceFactory namespaceFactory) { if (store == null) { throw new IllegalArgumentException("store must not be null"); } @@ -80,21 +80,21 @@ public StoreFilesystem(BaseStore store, NamespaceFactory namespaceFactory) { } /** - * Creates a StoreFilesystem with a fixed namespace. + * Creates a RemoteFilesystem with a fixed namespace. * * @param store the store to use for persistence * @param namespace the namespace tuple for organizing files */ - public StoreFilesystem(BaseStore store, List namespace) { + public RemoteFilesystem(BaseStore store, List namespace) { this(store, toFactory(namespace)); } /** - * Creates a StoreFilesystem with a default "filesystem" namespace. + * Creates a RemoteFilesystem with a default "filesystem" namespace. * * @param store the store to use for persistence */ - public StoreFilesystem(BaseStore store) { + public RemoteFilesystem(BaseStore store) { this(store, List.of("filesystem")); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpec.java similarity index 92% rename from agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java rename to agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpec.java index d185d09f5..3d21b3cc2 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpec.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpec.java @@ -34,7 +34,7 @@ *
      *
    • a plain {@link LocalFilesystem} (no shell) for workspace-local, ephemeral files such as * skills/, knowledge/, additional context files, etc.; - *
    • a shared {@link StoreFilesystem} for cross-node paths that must be identical across all + *
    • a shared {@link RemoteFilesystem} for cross-node paths that must be identical across all * replicas (long-term memory, offloaded session logs). *
    * @@ -60,14 +60,14 @@ *
  11. {@link IsolationScope#GLOBAL} — single global namespace
  12. * */ -public class StoreFilesystemSpec { +public class RemoteFilesystemSpec { private final BaseStore store; private final Set extraSharedPrefixes = new LinkedHashSet<>(); private String anonymousUserId = "_default"; private IsolationScope isolationScope = IsolationScope.USER; - public StoreFilesystemSpec(BaseStore store) { + public RemoteFilesystemSpec(BaseStore store) { if (store == null) { throw new IllegalArgumentException("store must not be null"); } @@ -79,7 +79,7 @@ public StoreFilesystemSpec(BaseStore store) { * *

    Examples: {@code knowledge/}, {@code prompts/}. */ - public StoreFilesystemSpec addSharedPrefix(String prefix) { + public RemoteFilesystemSpec addSharedPrefix(String prefix) { if (prefix != null && !prefix.isBlank()) { extraSharedPrefixes.add(normalizePrefix(prefix)); } @@ -89,7 +89,7 @@ public StoreFilesystemSpec addSharedPrefix(String prefix) { /** * Sets the fallback user identifier when runtime {@code userId} is absent/blank. */ - public StoreFilesystemSpec anonymousUserId(String userId) { + public RemoteFilesystemSpec anonymousUserId(String userId) { if (userId == null || userId.isBlank()) { throw new IllegalArgumentException("anonymous user id must not be blank"); } @@ -106,7 +106,7 @@ public StoreFilesystemSpec anonymousUserId(String userId) { * @param scope isolation scope * @return this spec */ - public StoreFilesystemSpec isolationScope(IsolationScope scope) { + public RemoteFilesystemSpec isolationScope(IsolationScope scope) { if (scope == null) { throw new IllegalArgumentException("isolation scope must not be null"); } @@ -119,7 +119,7 @@ public StoreFilesystemSpec isolationScope(IsolationScope scope) { * *

      *
    • default backend: {@link LocalFilesystem} (no shell) - *
    • shared routes: {@link StoreFilesystem} with scope-driven namespace + *
    • shared routes: {@link RemoteFilesystem} with scope-driven namespace *
    */ public AbstractFilesystem toFilesystem( @@ -130,8 +130,8 @@ public AbstractFilesystem toFilesystem( Supplier sessionIdSupplier) { String effectiveAgentId = agentId == null || agentId.isBlank() ? "HarnessAgent" : agentId; AbstractFilesystem local = new LocalFilesystem(workspace, false, 10, localNamespaceFactory); - StoreFilesystem shared = - new StoreFilesystem( + RemoteFilesystem shared = + new RemoteFilesystem( store, storeNamespace(effectiveAgentId, userIdSupplier, sessionIdSupplier)); Map routes = new LinkedHashMap<>(); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java index 17e54d15e..e2915aa1f 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java @@ -51,7 +51,7 @@ * *

    All file I/O goes through {@link AbstractFilesystem} (obtained from * {@link WorkspaceManager}), making this backend-agnostic across Local, Sandbox, and - * Store filesystems. + * Remote filesystems. */ public class MemoryMaintenanceHook implements Hook { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java deleted file mode 100644 index f8df58a7d..000000000 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/RuntimeContextAwareHook.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.agent.hook; - -import io.agentscope.core.hook.RuntimeContextAware; - -/** - * @deprecated Use {@link RuntimeContextAware} in {@code io.agentscope.core.hook} instead. - */ -@Deprecated(since = "1.0", forRemoval = false) -public interface RuntimeContextAwareHook extends RuntimeContextAware {} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java index 9a9424360..4e290c9b2 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java @@ -51,7 +51,7 @@ * *

    All file I/O is performed via the {@link AbstractFilesystem} obtained from the * {@link WorkspaceManager}, so this class is backend-agnostic (works with Local, - * Sandbox, and Store filesystems without any direct {@code java.nio.file.Files} usage). + * Sandbox, and Remote filesystems without any direct {@code java.nio.file.Files} usage). */ public class MemoryConsolidator { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java index e4e9b1c66..3aff78bbe 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ConversationCompactor.java @@ -461,7 +461,6 @@ private static Msg buildSummaryMessage(String summary, String filePath) { *

    During chained summarization the working memory may already contain a summary USER * message from a prior compaction round. We filter these out before offloading to the * backend so the original messages (already stored there) are not duplicated. - * Mirrors DeepAgents' {@code _filter_summary_messages}. */ static List filterSummaryMessages(List messages) { return messages.stream() @@ -478,7 +477,7 @@ static List filterSummaryMessages(List messages) { * *

    This is a lightweight, non-LLM pass that fires at a separate (lower) threshold * than full summarization. Only messages before the keep window are modified; recent - * messages are left intact. Mirrors DeepAgents' {@code _truncate_args}. + * messages are left intact. * *

    When {@code truncateConfig} is {@code null}, the original list is returned unchanged. */ diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java index 4b88d6360..602dc8e8b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/compaction/ToolResultEvictionConfig.java @@ -33,7 +33,6 @@ * * Both operate independently on different trigger conditions and different lifecycle events. * - *

    Defaults mirror DeepAgents' {@code FilesystemMiddleware}: *

      *
    • Trigger at 80,000 characters (~20 K tokens at 4 chars/token)
    • *
    • Preview: first + last 2,000 characters of the original output
    • diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java index 859032b3b..04badc254 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/Sandbox.java @@ -33,9 +33,9 @@ * *

      The distinction between {@code stop()} and {@code shutdown()} is critical: *

        - *
      • {@code stop()}: persist snapshot only — safe for both SDK-owned and developer-owned + *
      • {@code stop()}: persist snapshot only — safe for both self-managed and user-managed * sandboxes
      • - *
      • {@code shutdown()}: destroy backend resources — only called on SDK-owned sandboxes
      • + *
      • {@code shutdown()}: destroy backend resources — only called on self-managed sandboxes
      • *
      */ public interface Sandbox extends AutoCloseable { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java index 17e0d7288..46876c1c9 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxAcquireResult.java @@ -17,22 +17,33 @@ /** * Result of acquiring a {@link Sandbox} from {@link SandboxManager}. + * + *

      Two ownership modes: + *

        + *
      • self-managed ({@code selfManaged=true}): the SDK created the sandbox and is + * responsible for its full lifecycle — {@code stop()} + {@code shutdown()} are both called + * after each agent call.
      • + *
      • user-managed ({@code selfManaged=false}): the caller injected a pre-existing + * sandbox; the SDK only calls {@code stop()} and never calls {@code shutdown()}.
      • + *
      */ public final class SandboxAcquireResult { private final Sandbox sandbox; - private final boolean sdkOwned; + private final boolean selfManaged; - private SandboxAcquireResult(Sandbox sandbox, boolean sdkOwned) { + private SandboxAcquireResult(Sandbox sandbox, boolean selfManaged) { this.sandbox = sandbox; - this.sdkOwned = sdkOwned; + this.selfManaged = selfManaged; } - public static SandboxAcquireResult sdkOwned(Sandbox sandbox) { + /** Creates a self-managed result (SDK owns the full lifecycle). */ + public static SandboxAcquireResult selfManaged(Sandbox sandbox) { return new SandboxAcquireResult(sandbox, true); } - public static SandboxAcquireResult developerOwned(Sandbox sandbox) { + /** Creates a user-managed result (caller owns the lifecycle; SDK only calls stop). */ + public static SandboxAcquireResult userManaged(Sandbox sandbox) { return new SandboxAcquireResult(sandbox, false); } @@ -40,7 +51,8 @@ public Sandbox getSandbox() { return sandbox; } - public boolean isSdkOwned() { - return sdkOwned; + /** Returns {@code true} if the SDK owns the full sandbox lifecycle. */ + public boolean isSelfManaged() { + return selfManaged; } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java index 9cce0ec9c..87e2f5cdf 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxManager.java @@ -47,9 +47,9 @@ public SandboxAcquireResult acquire( if (sandboxContext.getExternalSandbox() != null) { Sandbox external = sandboxContext.getExternalSandbox(); log.debug( - "[sandbox] Priority 1: using developer-owned sandbox: {}", + "[sandbox] Priority 1: using user-managed sandbox: {}", external.getState() != null ? external.getState().getSessionId() : "?"); - return SandboxAcquireResult.developerOwned(external); + return SandboxAcquireResult.userManaged(external); } if (sandboxContext.getExternalSandboxState() != null) { @@ -57,7 +57,7 @@ public SandboxAcquireResult acquire( log.debug( "[sandbox] Priority 2: resuming from explicit state: {}", sandboxContext.getExternalSandboxState().getSessionId()); - return SandboxAcquireResult.sdkOwned(sandbox); + return SandboxAcquireResult.selfManaged(sandbox); } Optional scopeKey = @@ -72,7 +72,7 @@ public SandboxAcquireResult acquire( scopeKey.get()); SandboxState state = client.deserializeState(stateJson.get()); Sandbox sandbox = client.resume(state); - return SandboxAcquireResult.sdkOwned(sandbox); + return SandboxAcquireResult.selfManaged(sandbox); } } catch (Exception e) { log.warn( @@ -96,7 +96,7 @@ public SandboxAcquireResult acquire( Sandbox sandbox = typedClient.create( spec, sandboxContext.getSnapshotSpec(), sandboxContext.getClientOptions()); - return SandboxAcquireResult.sdkOwned(sandbox); + return SandboxAcquireResult.selfManaged(sandbox); } public void release(SandboxAcquireResult result) { @@ -114,7 +114,7 @@ public void release(SandboxAcquireResult result) { log.warn("[sandbox] Sandbox stop failed: {}", e.getMessage(), e); } - if (result.isSdkOwned()) { + if (result.isSelfManaged()) { try { sandbox.shutdown(); } catch (Exception e) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java index 8eced8522..d6bb50f9d 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java @@ -48,7 +48,7 @@ * the existing container is reused. *
    • On {@link #stop()}: the workspace snapshot is persisted (if configured). * The container keeps running.
    • - *
    • On {@link #shutdown()}: the container is stopped and removed if SDK-owned.
    • + *
    • On {@link #shutdown()}: the container is stopped and removed if self-managed.
    • *
    * *

    Workspace Operations

    @@ -87,7 +87,7 @@ public void start() throws Exception { } /** - * Stops and removes the Docker container if SDK-owned. + * Stops and removes the Docker container if self-managed. * * @throws Exception if the container cannot be stopped or removed */ @@ -99,7 +99,7 @@ public void shutdown() throws Exception { } if (!dockerState.isContainerOwned()) { log.debug( - "[sandbox-docker] Skipping shutdown: container is developer-owned: {}", + "[sandbox-docker] Skipping shutdown: container is user-managed: {}", containerId); return; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java index b63776823..a29eb6792 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/store/NamespaceFactory.java @@ -28,7 +28,7 @@ * *
    {@code
      * NamespaceFactory factory = () -> List.of("sessions", getCurrentSessionId(), "filesystem");
    - * StoreFilesystem fs = new StoreFilesystem(store, factory);
    + * RemoteFilesystem fs = new RemoteFilesystem(store, factory);
      * }
    */ @FunctionalInterface diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java index 8dbbb9d98..83097f8a3 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java @@ -30,7 +30,7 @@ import io.agentscope.core.model.Model; import io.agentscope.core.model.ToolSchema; import io.agentscope.harness.agent.filesystem.LocalFilesystem; -import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; import io.agentscope.harness.agent.store.InMemoryStore; import io.agentscope.harness.agent.workspace.WorkspaceConstants; @@ -195,7 +195,7 @@ void subagentsDir_loadsMarkdownSpecs() throws Exception { } @Test - void storeFilesystemSpec_sharesMemoryMdInNonsandboxMode() throws Exception { + void remoteFilesystemSpec_sharesMemoryMdInNonsandboxMode() throws Exception { Files.createDirectories(workspace); Files.writeString(workspace.resolve(WorkspaceConstants.AGENTS_MD), "# Test\n"); InMemoryStore store = new InMemoryStore(); @@ -205,7 +205,7 @@ void storeFilesystemSpec_sharesMemoryMdInNonsandboxMode() throws Exception { .name("agent-a") .model(stubModel("ok")) .workspace(workspace) - .filesystem(new StoreFilesystemSpec(store)) + .filesystem(new RemoteFilesystemSpec(store)) .build(); agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared-memory"); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java index 6b0e4ae02..f9ecedea1 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java @@ -111,7 +111,7 @@ void localFilesystem_filesPersistAcrossCalls() throws Exception { * Demonstrates that changing {@code userId} or {@code sessionId} does NOT redirect I/O to a * different location in local mode. * - *

    This is the key distinction from sandbox/store modes: in local mode the workspace + *

    This is the key distinction from sandbox/remote modes: in local mode the workspace * directory is fixed, so all users and sessions share the same disk location. */ @Test diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java similarity index 93% rename from agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java rename to agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java index 9f2d0cd44..a3f6c3ea6 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/StoreFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java @@ -30,7 +30,7 @@ import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; import io.agentscope.harness.agent.RuntimeContext; -import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; import java.nio.file.Path; @@ -41,10 +41,10 @@ import reactor.core.publisher.Flux; /** - * Example: Distributed shared store filesystem mode with different {@link IsolationScope} levels. + * Example: Distributed shared remote filesystem mode with different {@link IsolationScope} levels. * *

    Context

    - *

    In store mode, selected paths (such as {@code MEMORY.md}, {@code memory/}) are routed to a + *

    In remote mode, selected paths (such as {@code MEMORY.md}, {@code memory/}) are routed to a * shared key-value store ({@link InMemoryStore} here; typically Redis or another distributed * store in production). The {@code IsolationScope} controls the store namespace prefix and * therefore which agent calls can read each other's stored data. @@ -72,7 +72,7 @@ * directly where possible to keep the example focused on namespace routing rather than agent * conversation mechanics. */ -class StoreFilesystemIsolationScopeExampleTest { +class RemoteFilesystemIsolationScopeExampleTest { @TempDir Path workspace; @@ -97,7 +97,7 @@ void sessionScope_differentSessions_isolatedNamespaces() throws Exception { .model(stubModel("done")) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) .build(); @@ -130,7 +130,7 @@ void sessionScope_sameSession_sharedNamespace() throws Exception { .model(stubModel("done")) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) .build(); @@ -167,7 +167,7 @@ void userScope_sameUser_sharedAcrossSessions() throws Exception { .model(stubModel("done")) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); // Call as alice / session-a and write MEMORY.md @@ -200,7 +200,7 @@ void userScope_differentUsers_isolatedNamespaces() throws Exception { .model(stubModel("done")) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.USER)) + new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); @@ -233,7 +233,8 @@ void agentScope_allCallersShareOneNamespace() throws Exception { .model(stubModel("done")) .workspace(workspace) .filesystem( - new StoreFilesystemSpec(store).isolationScope(IsolationScope.AGENT)) + new RemoteFilesystemSpec(store) + .isolationScope(IsolationScope.AGENT)) .build(); // Alice writes diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java index cf398bffd..86111d29e 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java @@ -33,7 +33,7 @@ * Verifies delete / move / exists on all {@link AbstractFilesystem} implementations. * *

    LocalFilesystem is tested in non-virtual mode; paths are workspace-relative (no leading '/'). - * StoreFilesystem uses leading-slash keys matching its internal convention. + * RemoteFilesystem uses leading-slash keys matching its internal convention. */ class FilesystemDeleteMoveExistsTest { @@ -104,7 +104,7 @@ void local_move_missingSource(@TempDir Path tmp) { } // ================================================================ - // StoreFilesystem — keys follow leading-slash convention + // RemoteFilesystem — keys follow leading-slash convention // ================================================================ private static InMemoryStore storeWith(String path, String content) { @@ -116,21 +116,21 @@ private static InMemoryStore storeWith(String path, String content) { @Test void store_exists_true() { InMemoryStore s = storeWith("/file.txt", "hello"); - StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); assertTrue(fs.exists("/file.txt")); } @Test void store_exists_false() { - StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); assertFalse(fs.exists("/nope.txt")); } @Test void store_delete_file() { InMemoryStore s = storeWith("/file.txt", "hello"); - StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); WriteResult result = fs.delete("/file.txt"); assertTrue(result.isSuccess()); @@ -139,7 +139,7 @@ void store_delete_file() { @Test void store_delete_idempotent() { - StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); WriteResult result = fs.delete("/ghost.txt"); assertTrue(result.isSuccess()); } @@ -147,7 +147,7 @@ void store_delete_idempotent() { @Test void store_move_file() { InMemoryStore s = storeWith("/src.txt", "data"); - StoreFilesystem fs = new StoreFilesystem(s, List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); WriteResult result = fs.move("/src.txt", "/dst.txt"); assertTrue(result.isSuccess()); @@ -157,7 +157,7 @@ void store_move_file() { @Test void store_move_missingSource() { - StoreFilesystem fs = new StoreFilesystem(new InMemoryStore(), List.of("ns")); + RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); WriteResult result = fs.move("/missing.txt", "/dst.txt"); assertFalse(result.isSuccess()); } @@ -169,7 +169,7 @@ void store_move_missingSource() { @Test void composite_exists_routedToStore(@TempDir Path tmp) { InMemoryStore s = storeWith("/MEMORY.md", "mem"); - StoreFilesystem storeFsys = new StoreFilesystem(s, List.of("ns")); + RemoteFilesystem storeFsys = new RemoteFilesystem(s, List.of("ns")); LocalFilesystem local = new LocalFilesystem(tmp); CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); @@ -181,7 +181,7 @@ void composite_exists_routedToStore(@TempDir Path tmp) { @Test void composite_delete_routedToStore(@TempDir Path tmp) { InMemoryStore s = storeWith("/MEMORY.md", "mem"); - StoreFilesystem storeFsys = new StoreFilesystem(s, List.of("ns")); + RemoteFilesystem storeFsys = new RemoteFilesystem(s, List.of("ns")); LocalFilesystem local = new LocalFilesystem(tmp); CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); @@ -200,7 +200,7 @@ void composite_move_crossBackend_storeToLocal(@TempDir Path tmp) throws Exceptio InMemoryStore s = new InMemoryStore(); List ns = List.of("ns"); s.put(ns, "/2025-01-01.md", Map.of("content", "diary", "encoding", "utf-8")); - StoreFilesystem storeFsys = new StoreFilesystem(s, ns); + RemoteFilesystem storeFsys = new RemoteFilesystem(s, ns); LocalFilesystem local = new LocalFilesystem(tmp); CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("memory/", storeFsys)); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java similarity index 94% rename from agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java rename to agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java index e4fe1cc34..77340c056 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/StoreFilesystemSpecTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -class StoreFilesystemSpecTest { +class RemoteFilesystemSpecTest { @TempDir Path workspace; @@ -40,7 +40,7 @@ void routesSharedPathsToStoreAndOthersToLocal() throws Exception { NamespaceFactory localNs = () -> List.of("local-user"); AbstractFilesystem fs = - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .anonymousUserId("anon") .toFilesystem(workspace, "agent-a", localNs, userRef::get); @@ -63,7 +63,7 @@ void resolvesNamespaceByRuntimeUserId() { AtomicReference userRef = new AtomicReference<>("user-1"); AbstractFilesystem fs = - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .toFilesystem(workspace, "agent-a", List::of, userRef::get); fs.uploadFiles( @@ -72,7 +72,7 @@ void resolvesNamespaceByRuntimeUserId() { } /** - * Mode 1 invariant: the composite filesystem produced by {@link StoreFilesystemSpec} is + * Mode 1 invariant: the composite filesystem produced by {@link RemoteFilesystemSpec} is * not a sandbox filesystem, so the agent builder will not register the shell execute * tool in this mode. */ @@ -80,7 +80,7 @@ void resolvesNamespaceByRuntimeUserId() { void compositeModeIsNotASandboxFilesystem() { InMemoryStore store = new InMemoryStore(); AbstractFilesystem fs = - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .toFilesystem(workspace, "agent-a", List::of, () -> null); assertFalse( diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java index d5d053289..f2bb66446 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/MemoryConsolidatorFilesystemTest.java @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import io.agentscope.harness.agent.filesystem.StoreFilesystem; +import io.agentscope.harness.agent.filesystem.RemoteFilesystem; import io.agentscope.harness.agent.store.InMemoryStore; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.nio.file.Files; @@ -58,7 +58,7 @@ private static void seedStoreFile( void readWatermark_returnsEpochWhenStateAbsent(@TempDir Path tmp) { InMemoryStore store = new InMemoryStore(); List ns = List.of("test-ns"); - StoreFilesystem fs = new StoreFilesystem(store, ns); + RemoteFilesystem fs = new RemoteFilesystem(store, ns); WorkspaceManager wsm = new WorkspaceManager(tmp, fs); MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); @@ -74,7 +74,7 @@ void readWatermark_returnsEpochWhenStateAbsent(@TempDir Path tmp) { void watermark_roundTripThroughFilesystem(@TempDir Path tmp) { InMemoryStore store = new InMemoryStore(); List ns = List.of("test-ns"); - StoreFilesystem fs = new StoreFilesystem(store, ns); + RemoteFilesystem fs = new RemoteFilesystem(store, ns); WorkspaceManager wsm = new WorkspaceManager(tmp, fs); MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); @@ -93,7 +93,7 @@ void watermark_roundTripThroughFilesystem(@TempDir Path tmp) { void watermark_doesNotCreateLocalFile(@TempDir Path tmp) { InMemoryStore store = new InMemoryStore(); List ns = List.of("test-ns"); - StoreFilesystem fs = new StoreFilesystem(store, ns); + RemoteFilesystem fs = new RemoteFilesystem(store, ns); WorkspaceManager wsm = new WorkspaceManager(tmp, fs); MemoryConsolidator consolidator = new MemoryConsolidator(wsm, null); @@ -105,7 +105,7 @@ void watermark_doesNotCreateLocalFile(@TempDir Path tmp) { Path localState = tmp.resolve("memory").resolve(MemoryConsolidator.STATE_FILE); assertFalse( Files.exists(localState), - "state file should not be written to local disk when using StoreFilesystem"); + "state file should not be written to local disk when using RemoteFilesystem"); // but consolidator reads it correctly from the store assertEquals(ts, consolidator.readWatermark()); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java index d5241e454..35118e161 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.agentscope.harness.agent.filesystem.AbstractFilesystem; -import io.agentscope.harness.agent.filesystem.StoreFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; import java.nio.file.Path; @@ -35,7 +35,7 @@ class SessionTreeMirrorTest { void mirrorsToFilesystemAndCanRestoreWhenLocalFilesMissing() throws Exception { InMemoryStore store = new InMemoryStore(); AbstractFilesystem fs = - new StoreFilesystemSpec(store) + new RemoteFilesystemSpec(store) .toFilesystem(workspace, "agent-a", List::of, () -> "user-1"); Path context = workspace.resolve("agents/agent-a/sessions/s1.jsonl"); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java index 852d5958c..8ddaf1818 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java @@ -57,7 +57,7 @@ void setUp() { manager = new SandboxManager(client, stateStore, AGENT_ID); } - // ---- Priority 1: developer-owned external session ---- + // ---- Priority 1: user-managed external session ---- @Test void priority1_externalSession_usedDirectly() throws Exception { @@ -66,7 +66,7 @@ void priority1_externalSession_usedDirectly() throws Exception { SandboxAcquireResult result = manager.acquire(ctx, null); assertSame(externalSandbox, result.getSandbox()); - assertEquals(false, result.isSdkOwned()); + assertEquals(false, result.isSelfManaged()); verify(stateStore, never()).load(any()); } @@ -82,7 +82,7 @@ void priority2_externalSessionState_resumedDirectly() throws Exception { SandboxAcquireResult result = manager.acquire(ctx, null); assertSame(resumedSandbox, result.getSandbox()); - assertEquals(true, result.isSdkOwned()); + assertEquals(true, result.isSelfManaged()); verify(stateStore, never()).load(any()); } @@ -102,7 +102,7 @@ void priority3_stateStoreHit_resumesSession() throws Exception { SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); assertSame(resumedSandbox, result.getSandbox()); - assertEquals(true, result.isSdkOwned()); + assertEquals(true, result.isSelfManaged()); verify(client, never()).create(any(), any(), any()); } @@ -211,7 +211,7 @@ void persistState_savesJsonForResolvedScopeKey() throws Exception { Sandbox sandbox = mock(Sandbox.class); when(sandbox.getState()).thenReturn(state); when(client.serializeState(state)).thenReturn(STATE_JSON); - SandboxAcquireResult result = SandboxAcquireResult.sdkOwned(sandbox); + SandboxAcquireResult result = SandboxAcquireResult.selfManaged(sandbox); RuntimeContext rtx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-p")).build(); @@ -227,7 +227,7 @@ void persistState_savesJsonForResolvedScopeKey() throws Exception { void persistState_missingScopeKey_skipped() throws Exception { Sandbox sandbox = mock(Sandbox.class); when(sandbox.getState()).thenReturn(mock(SandboxState.class)); - SandboxAcquireResult result = SandboxAcquireResult.sdkOwned(sandbox); + SandboxAcquireResult result = SandboxAcquireResult.selfManaged(sandbox); RuntimeContext rtx = RuntimeContext.builder().build(); // no session key SandboxContext sCtx = SandboxContext.builder().build(); // SESSION scope by default diff --git a/docs/zh/harness/architecture.md b/docs/zh/harness/architecture.md index 9b8be2f4a..6167b1259 100644 --- a/docs/zh/harness/architecture.md +++ b/docs/zh/harness/architecture.md @@ -2,7 +2,7 @@ [Overview](./overview.md) 把 harness 的能力按"解决了什么问题"组织。本文换一个视角:把每个组件的**定义、行为、触发时机、协作对象**讲清楚,最后用时序图说明这些组件在一次 `call()` 里如何协同。 -> 本文聚焦使用者视角的中粒度——讲清"是谁、什么时候、做什么、跟谁协作",不展开调用栈与实现细节;那些放在各子文档([memory](./memory.md)、[workspace](./workspace.md)、[filesystem](./filesystem.md)、[subagent](./subagent.md)、[session](./session.md)、[tool](./tool.md))。 +> 本文聚焦使用者视角的中粒度——讲清"是谁、什么时候、做什么、跟谁协作",不展开调用栈与实现细节;那些放在各子文档([memory](./memory.md)、[workspace](./workspace.md)、[filesystem](./filesystem.md)、[sandbox](./sandbox.md)、[subagent](./subagent.md)、[session](./session.md)、[tool](./tool.md))。 ## 1. 顶层结构 @@ -64,23 +64,25 @@ workspace/ | 实现 | 用途 | 关键特性 | |---|---|---| -| `LocalFilesystem` | 本地磁盘 | `virtualMode` 锚定 `rootDir` 阻止穿越 | -| `LocalFilesystemWithShell` | 本地 + shell | 默认后端;触发 `shell_execute` 工具注册 | -| `BaseSandboxFilesystem` | 沙箱模板 | 把所有 IO 收敛到沙箱 | -| `StoreFilesystem` | KV store | 跨线程持久化;`NamespaceFactory` 读 `userId` 做多租户 | -| `CompositeFilesystem` | 路由 | 按 path prefix 分发;前缀越长越优先 | +| `LocalFilesystem` | 本地磁盘 | `virtualMode` 锚定 `rootDir` 阻止穿越;无 shell | +| `LocalFilesystemWithShell` | 本地 + 宿主 shell | 声明式下对应 `LocalFilesystemSpec` 与**无 `filesystem` 的默认**;`instanceof AbstractSandboxFilesystem` 时注册 `shell_execute` | +| `BaseSandboxFilesystem` / `SandboxBackedFilesystem` | 沙箱后端 | 文件与命令在沙箱内;见 [Sandbox](./sandbox.md) | +| `RemoteFilesystem` | KV store | 在 `RemoteFilesystemSpec` 下与 `LocalFilesystem` 经 `CompositeFilesystem` 路由;无 shell | +| `CompositeFilesystem` | 按前缀路由 | 仅实现 `AbstractFilesystem`(**不**实现 `AbstractSandboxFilesystem`),**不**触发 `ShellExecuteTool`;最长前缀优先 | -> **多租户机制**:`NamespaceFactory` 是函数式接口,每次操作时被调用读取 `RuntimeContext.userId`;同一个 filesystem 实例在不同 user 间天然路径隔离。 +> **多租户与隔离**:`NamespaceFactory` 在每次操作时被调用;`RemoteFilesystemSpec` / `SandboxFilesystemSpec` 还可配 `IsolationScope`(与沙箱/共享存储命名一致)。**三种声明式模式**以何者注册 `ShellExecuteTool` 为准,见 [filesystem](./filesystem.md#三种声明式模式)。 ## 3. Hook 列表 -七个 hook,由 `Builder.build()` 装配进 `ReActAgent`。它们按 `priority()` 排序,**值越小越先执行**。 +下列为 `Builder.build()` 中常见的 harness 内置 hook(**沙箱模式**下会加入 `SandboxLifecycleHook`,见 [Sandbox](./sandbox.md))。`ReActAgent` 按 `priority()` **升序**执行,同优先级时保留装配顺序。 | Hook | 优先级 | 监听事件 | 默认开启 | 关键依赖 | |------|--------|----------|---------|----------| -| `AgentTraceHook` | 0 | 全部 | ✓ | — | +| `AgentTraceHook` | 0 | 全部 | ✓(默认;可 `.agentTracing(false)` 关闭)| — | | `MemoryFlushHook` | 5 | `PostCallEvent` | ✓(需 `model`)| `WorkspaceManager`、`Model`、`MemoryFlushManager` | +| `MemoryMaintenanceHook` | 6 | `PostCallEvent`(有节流) | ✓(需 `model`)| `MemoryConsolidator`、`WorkspaceManager` | | `CompactionHook` | 10 | `PreReasoningEvent` | ✗(需显式 `.compaction(...)`)| `WorkspaceManager`、`Model`、`CompactionConfig`、`MemoryFlushManager` | +| `SandboxLifecycleHook` | 50 | `PreCall` / `PostCall` / `Error` | 仅当 `filesystem(SandboxFilesystemSpec)` | `SandboxManager`、`SandboxBackedFilesystem` | | `ToolResultEvictionHook` | 50 | `PostActingEvent` | ✗(需显式 `.toolResultEviction(...)`)| `AbstractFilesystem`、`ToolResultEvictionConfig` | | `SubagentsHook` | 80 | `PreReasoningEvent` + `tools()` | ✓(非 leaf 且有 `model`)| 子 agent 列表、`TaskRepository` | | `WorkspaceContextHook` | 900 | `PreReasoningEvent` | ✓ | `WorkspaceManager`、`RuntimeContext`、token 预算 | diff --git a/docs/zh/harness/filesystem.md b/docs/zh/harness/filesystem.md index 23a2e1824..f5149fe87 100644 --- a/docs/zh/harness/filesystem.md +++ b/docs/zh/harness/filesystem.md @@ -2,20 +2,42 @@ ## 作用 -把 agent 可见的文件操作从“本地磁盘”中抽象出来,提供统一的 `ls / read / write / edit / grep / glob / upload / download` 接口;在沙箱场景下额外打开 `execute` 能力。同一份上层逻辑(`WorkspaceManager`、`FilesystemTool`、`ShellExecuteTool`)可以在本地、远程沙箱、内存 KV 之间透明切换。 +`AbstractFilesystem` 把 agent 对**工作区**的访问从「一定是本机磁盘」抽象成统一接口:`ls / read / write / edit / grep / glob / upload / download`。需要**在隔离环境执行命令**时,后端再实现 `AbstractSandboxFilesystem`,`HarnessAgent` 才会注册 `ShellExecuteTool`。 -## 触发 +在 harness 里,**文件系统承担三种不同但常混为一谈的职责**: -| 时机 | 动作 | -|------|------| -| `HarnessAgent.build()` | 未显式设 `abstractFilesystem` 时默认创建 `LocalFilesystemWithShell(workspace)` | -| `WorkspaceManager` 读写 | `readWithOverride` 优先走 filesystem;append / upload 全走 filesystem | -| Tool 调用 | `FilesystemTool` 直接调用;`ShellExecuteTool` 仅在后端是 `AbstractSandboxFilesystem` 时注册 | -| `WorkspaceContextHook` | 调 `RuntimeContextAwareHook.setRuntimeContext()` 后,namespaceFactory 读到的 `userId` 就是当前请求的租户 | +1. **工具面**:`FilesystemTool`(及可选的 `ShellExecuteTool`)只认一个 `AbstractFilesystem` 实例;所有路径与执行都经此出口,便于替换实现。 +2. **工作区读写的物理落点**:`WorkspaceManager` 读时「优先走 filesystem、未命中再回退本地」;写与上传一律走 filesystem。因此**长期记忆、日流水账、会话日志**等最终落在哪个介质上,由你选的 **模式** 决定。 +3. **多租户与隔离**:`NamespaceFactory` 在每次操作中从 `RuntimeContext.userId` 等来源拼出路径前缀,使同一套代码在**用户 / 会话 / 全局**之间切换存储分片;`RemoteFilesystemSpec` 与 `SandboxFilesystemSpec` 还把 **IsolationScope** 接到「共享 KV」或「沙箱状态键」上,与 [Sandbox](./sandbox.md) 的隔离叙事一致。 + +## 三种声明式模式 + +`HarnessAgent.Builder` 在 **`filesystem(...)` 系列** 中**至多选一**(与 **`abstractFilesystem(...)` 互斥**;后者为自带实现的逃生口,见下节): + +| 模式 | 配置方法 | 典型产物 | Shell | 适用场景 | +|------|----------|----------|-------|----------| +| **1 — 复合 + 共享存储** | `filesystem(RemoteFilesystemSpec)` | `CompositeFilesystem`:工作区根上 **无 shell 的** `LocalFilesystem` + 按前缀路由的 `RemoteFilesystem` | 否 | 多副本要共享 `MEMORY.md`、`memory/`、会话落盘等;**不在宿主执行**不受信 shell | +| **2 — 沙箱** | `filesystem(SandboxFilesystemSpec)` | `SandboxBackedFilesystem` + 生命周期由 [Sandbox](./sandbox.md) 描述 | 是(在沙箱内) | 隔离执行、可恢复沙箱会话、可选快照与分布式 Session | +| **3 — 本机 + shell** | `filesystem(LocalFilesystemSpec)` 或**不显式配 filesystem** | `LocalFilesystemWithShell` | 是(宿主 `sh -c`) | 单进程/本机、信任环境、简单脚本与测试 | + +**默认未调用任何 `filesystem(...)` 时** 与 **显式 `filesystem(new LocalFilesystemSpec())`** 等价,即模式 3,根目录为 `workspace`、在宿主上提供 shell。 + +### 模式一:复合 + 存储(`RemoteFilesystemSpec`) + +- **结构**:`RemoteFilesystemSpec#toFilesystem` 组合出 `CompositeFilesystem`: + - **默认/未匹配的前缀** → 纯 `LocalFilesystem`(**无** `ShellExecuteTool`); + - **配置的前缀**(如默认的 `MEMORY.md`、`memory/`、`agents//sessions/` 等 + 可 `addSharedPrefix`)→ `RemoteFilesystem`(`BaseStore` 之上,由 `IsolationScope` 控制命名空间:SESSION / USER / AGENT / GLOBAL)。 +- **为何默认不用 `LocalFilesystemWithShell`**:模式 1 的设计目标是**跨节点一致的长记忆与日志**,同时**避免在宿主上开放 shell**;需要 shell 时请用模式 2 或 3。 + +### 模式二:沙箱(`SandboxFilesystemSpec`) + +- 见 [沙箱(Sandbox)](./sandbox.md)。要点:对外仍是 `AbstractFilesystem` + 可选 `ShellExecuteTool`(经 `AbstractSandboxFilesystem`),但真实 IO/进程在 `SandboxClient` 侧;`SandboxLifecycleHook` 在每次 `call` 周围 acquire/persist/release。 -## 关键逻辑 +### 模式三:本机 + shell(`LocalFilesystemSpec` 或默认) -### 两层接口 +- **行为**:`LocalFilesystemWithShell` 根目录为工作区,命令为宿主上的 `sh -c`(可配超时、环境变量、`virtualMode` 等),**与模式 1 的「无 shell 本地根」有本质区别**。 + +## 类层次与 `ShellExecuteTool` 注册 ```mermaid classDiagram @@ -35,90 +57,97 @@ classDiagram class LocalFilesystem class LocalFilesystemWithShell class BaseSandboxFilesystem - class StoreFilesystem + class RemoteFilesystem class CompositeFilesystem + class SandboxBackedFilesystem LocalFilesystem ..|> AbstractFilesystem - StoreFilesystem ..|> AbstractFilesystem + RemoteFilesystem ..|> AbstractFilesystem LocalFilesystemWithShell --|> LocalFilesystem LocalFilesystemWithShell ..|> AbstractSandboxFilesystem BaseSandboxFilesystem ..|> AbstractSandboxFilesystem - CompositeFilesystem ..|> AbstractSandboxFilesystem + CompositeFilesystem ..|> AbstractFilesystem + SandboxBackedFilesystem ..|> AbstractSandboxFilesystem ``` -- `AbstractFilesystem` 是最小接口;带 shell 执行的后端额外实现 `AbstractSandboxFilesystem`,HarnessAgent 据此决定是否注册 `ShellExecuteTool`。 -- `read(filePath, offset, limit)` 中 `limit <= 0` 意味默认(本地后端读全文,sandbox 后端读到 `Integer.MAX_VALUE` 行)。 - -### 后端入门定位 +- **`CompositeFilesystem` 只实现 `AbstractFilesystem`**,不实现 `AbstractSandboxFilesystem`,因此**不会**注册 `ShellExecuteTool`;若需组合路由且又要 shell,需自行用 `abstractFilesystem` 提供含 shell 的默认后端或选用沙箱/本机模式。 +- **`read(filePath, offset, limit)`** 中 `limit <= 0` 表示使用实现定义的「读默认行数」(本地与沙箱可能不同)。 -| 后端 | 适用场景 | 关键参数 / 限制 | -|------|---------|-----------------| -| `LocalFilesystem` | 只需读写本地,不要 shell | `(rootDir, virtualMode, maxFileSizeMb, namespaceFactory)`;`virtualMode=true` 时锁定在 `rootDir` 内 | -| `LocalFilesystemWithShell` | **HarnessAgent 默认**;本地读写 + `sh -c` | `(rootDir, virtualMode, timeout, maxOutputBytes, env, inheritEnv, namespaceFactory)`;**不受限制执行**,仅限受信任的本地/CI | -| `BaseSandboxFilesystem` | 远程沙箱 / 容器后端的实现基类 | 只需覆盖 `id / execute / uploadFiles / downloadFiles`,`ls/read/grep/glob` 默认走远程 Unix 命令 | -| `StoreFilesystem` | 基于 `BaseStore` 的 KV,多租户 / 跨线程共享 | 静态 namespace 或 `NamespaceFactory`;不提供 shell | -| `CompositeFilesystem` | 按路径前缀路由多个后端 | 最长前缀优先匹配;`isSandbox()` 仅当 default backend 实现 sandbox 接口时为 true | +## 各实现速查 -### `BaseSandboxFilesystem` 的取巧 - -实现者只需交付 `execute / uploadFiles / downloadFiles / id`,`ls / read / grep / glob / edit / write` 都会被默认实现转为远程 shell 命令: +| 实现 | 说明 | +|------|------| +| `LocalFilesystem` | 仅本机文件,无执行;`virtualMode` 锚定 `rootDir` 防穿越 | +| `LocalFilesystemWithShell` | 本机 + 宿主 shell;**模式 3** 的核心 | +| `BaseSandboxFilesystem` | 对接远程 Unix 的基类,多数方法用 `execute` 拼命令实现 | +| `RemoteFilesystem` | 基于 `BaseStore` 的 KV 存储;无 shell;与 `IsolationScope` 搭配 | +| `CompositeFilesystem` | 最长前缀匹配多后端;**不**提供 shell 能力 | +| `SandboxBackedFilesystem` | 沙箱代理,实现 `AbstractSandboxFilesystem`;与 `SandboxManager` 配合 | -- `ls` → `for f in /*; do ... done` -- `read` → `sed -n 'a,bp' `(二进制文件走 `base64`) -- `grep` → `grep -rHnF` -- `glob` → `find -type f -name ` -- `edit` → 补下 base64-encoded `python3` 脚本做字符串替换 -- `write` → 先 `[ -e ]` 检查存在性,再 `uploadFiles` +## `BaseSandboxFilesystem` 的默认实现策略 -意义:只要沙箱环境有标准 Unix 工具链 + Python3,集成代价几乎为零。 +子类主要实现 `execute / uploadFiles / downloadFiles / id` 时,基类常把 `ls/read/grep/glob/edit/write` 转为远程 shell 与 Python3 片段(与旧版 `filesystem.md` 描述一致),便于在标准 Unix 环境快速落地。 -### `NamespaceFactory`—多租户透明隔离 +## `NamespaceFactory` 与多租户 ```java @FunctionalInterface public interface NamespaceFactory { List getNamespace(); } ``` -- **每次文件操作都调用**一次,返回当前请求的路径段 tuple(例如 `["users", "alice"]`)。 -- `LocalFilesystem` / `LocalFilesystemWithShell` / `BaseSandboxFilesystem` / `StoreFilesystem` 都能接受;上层逻辑对路径无感。 -- 典型用法:结合 `RuntimeContext.userId` 动态生成。 +每次文件操作会调用,返回当前请求的路径段(如 `["users", "alice"]`)。`HarnessAgent` 构建时可用 `AtomicReference` 与 `RuntimeContext.userId` 联动,使同一份 `AbstractFilesystem` 实例在不同用户下落在不同子树。 -```java -AtomicReference currentUserId = new AtomicReference<>("default"); -NamespaceFactory ns = () -> List.of("users", currentUserId.get()); - -LocalFilesystemWithShell fs = new LocalFilesystemWithShell(workspace, ns); -// agent.call() 前更新 currentUserId,所有文件操作自动落在 workspace/users//... -``` +## 配置示例 -## 配置 +**推荐:先选三种模式之一,再仅在需要时接触 `abstractFilesystem`:** ```java +// 模式 3:显式本机 + shell(与「不写 filesystem」默认等价,仅用于调整超时等) HarnessAgent agent = HarnessAgent.builder() - .name("MyAgent") + .name("local") .model(model) .workspace(workspace) - .abstractFilesystem(myFilesystem) // 不传默认为 LocalFilesystemWithShell(workspace) + .filesystem(new LocalFilesystemSpec().executeTimeoutSeconds(120)) .build(); ``` -几个常见组合: +```java +// 模式 1:共享长期记忆到 Store(无宿主 shell) +HarnessAgent agent = HarnessAgent.builder() + .name("store") + .model(model) + .workspace(workspace) + .filesystem(new RemoteFilesystemSpec(redisStore) + .isolationScope(IsolationScope.USER)) + .build(); +``` ```java -// 1. 本地开发(默认) -new LocalFilesystemWithShell(workspace); +// 模式 2:沙箱(具体 spec 因实现类而异,如 Docker) +HarnessAgent agent = HarnessAgent.builder() + .name("sandbox") + .model(model) + .workspace(workspace) + .filesystem(dockerFilesystemSpec) // extends SandboxFilesystemSpec + .build(); +``` -// 2. 不要 shell 的只读写场景 -new LocalFilesystem(workspace, /*virtualMode=*/ true, /*maxFileSizeMb=*/ 10); +**逃生口(与上述 `filesystem(…Spec)` 互斥):** -// 3. 本地 + 远程记忆库组合 -new CompositeFilesystem( - new LocalFilesystemWithShell(workspace), - Map.of("/memories/", new StoreFilesystem(redisStore, ns))); +```java +HarnessAgent agent = HarnessAgent.builder() + .name("custom") + .model(model) + .workspace(workspace) + .abstractFilesystem(myCustomTree) // 完全自管的一棵 AbstractFilesystem + .build(); ``` +**手动组合(高级)**:在 `abstractFilesystem` 或自建工厂中仍可使用 `CompositeFilesystem` + `LocalFilesystemWithShell` 等,但需自行保证安全边界与 `ShellExecuteTool` 是否应暴露。 + ## 相关文档 -- [工具](./tool.md) — `FilesystemTool` / `ShellExecuteTool` 的入参 -- [工作区](./workspace.md) — `WorkspaceManager` 上层怎么利用文件系统走两层读 -- [架构](./architecture.md) — `ShellExecuteTool` 注册条件在哪里检查 +- [沙箱(Sandbox)](./sandbox.md) — 沙箱模式原理、`SandboxStateStore`、分布式 +- [工具](./tool.md) — `FilesystemTool` / `ShellExecuteTool` 入参 +- [工作区](./workspace.md) — `WorkspaceManager` 与两层读 +- [架构](./architecture.md) — 与 Hook、RuntimeContext 的协作 diff --git a/docs/zh/harness/overview.md b/docs/zh/harness/overview.md index d7706ee6e..0debfe749 100644 --- a/docs/zh/harness/overview.md +++ b/docs/zh/harness/overview.md @@ -113,7 +113,7 @@ mvn -pl agentscope-examples/harness-example exec:java \ **关于 `RuntimeContext`**:它是当次 `call()` 的身份载体,`sessionId` 决定状态存放与日志归档位置,`userId` 决定默认文件系统的命名空间(天然的多租户隔离)。它**不会被持久化**,只在当次调用的 hook 与工具间共享。 -**扩展方向**:在工作区里放 `KNOWLEDGE.md`、`skills/*/SKILL.md`、`subagents/*.md` 就能分别开启领域知识注入、技能加载、子 agent 编排;`.toolResultEviction(ToolResultEvictionConfig.defaults())` 一行启用大结果卸载;`.abstractFilesystem(...)` 替换成沙箱实现即可把 agent 放进容器。 +**扩展方向**:在工作区里放 `KNOWLEDGE.md`、`skills/*/SKILL.md`、`subagents/*.md` 就能分别开启领域知识注入、技能加载、子 agent 编排;`.toolResultEviction(ToolResultEvictionConfig.defaults())` 一行启用大结果卸载;**文件/命令的落点**用 [Filesystem — 三种声明式模式](./filesystem.md#三种声明式模式) 选择 **共享存储、沙箱或本机+shell**;需隔离执行时优先 `filesystem(SandboxFilesystemSpec)`(见 [Sandbox](./sandbox.md)),`abstractFilesystem` 仅作自管后端的逃生口。 ## 核心能力 @@ -125,7 +125,7 @@ mvn -pl agentscope-examples/harness-example exec:java \ - **大工具结果卸载** —— 解决 *单次工具返回过大*。`ToolResultEvictionHook` 把超限结果落盘到文件系统,上下文里只留占位符 + 预览,agent 可以按需回读。 - **会话持久化** —— 解决 *状态如何跨进程保留*。`SessionPersistenceHook` 按 `sessionId` 把 agent 状态写入工作区,下次调用自动从断点恢复。 - **子 agent 编排** —— 解决 *复杂任务如何分解*。`SubagentsHook` 注入 `task` / `task_output` 工具,主 agent 可同步或后台委派子 agent;子 agent 可由工作区规格文件、编程式 spec、自定义工厂声明。 -- **可插拔文件系统** —— 解决 *agent 的环境如何收敛与隔离*。所有文件工具都走 `AbstractFilesystem`,可替换为本地、沙箱、远端或组合后端;配合 `RuntimeContext.userId` 得到天然的多租户命名空间。 +- **可插拔文件系统** —— 解决 *agent 的环境如何收敛与隔离*。所有文件工具都走 `AbstractFilesystem`;通过 [三种声明式模式](./filesystem.md#三种声明式模式)(本机+shell、复合+Store、沙箱)或 `abstractFilesystem` 自管;配合 `RuntimeContext.userId` 与 `IsolationScope` 做多租户/会话级隔离。隔离执行与沙箱状态恢复见 [Sandbox](./sandbox.md)。 此外还有几项围绕以上能力服务的基础设施:`RuntimeContext` 贯穿整次调用、`MemoryMaintenanceScheduler` 在后台做合并与索引维护、`AgentTraceHook` 统一追踪日志、`AgentSkillRepository` 自动装配 `SkillBox`。 @@ -143,7 +143,7 @@ mvn -pl agentscope-examples/harness-example exec:java \ `HarnessAgent` 是 `Agent` + `StateModule` 的薄包装,内部持有一个 `ReActAgent delegate`,能力注入全部发生在 `HarnessAgent.Builder.build()`: -- **Hook 通道**:按固定顺序把 `WorkspaceContextHook`、`MemoryFlushHook`、`CompactionHook`、`ToolResultEvictionHook`、`SessionPersistenceHook`、`SubagentsHook`、`AgentTraceHook` 串成 hook 列表交给 `ReActAgent` +- **Hook 通道**:按 `priority` 把若干 hook 交给 `ReActAgent`(含沙箱模式下的 `SandboxLifecycleHook` 等,详见 [Architecture](./architecture.md)) - **Toolkit 通道**:在用户 `Toolkit` 上追加 `filesystem`、`memory_search`、`memory_get`、`session_search`,沙箱后端额外加 `shell_execute`;`SubagentsHook` 自己注册 `task` / `task_output` - **SkillBox 通道**:从 `workspace/skills/` 或自定义 `AgentSkillRepository` 自动构造 `SkillBox` @@ -156,7 +156,8 @@ mvn -pl agentscope-examples/harness-example exec:java \ - [Architecture](./architecture.md) — 各组件定义、生命周期时序图、协作关系 - [工作区(Workspace)](./workspace.md) — 工作区目录结构与上下文注入 - [记忆(Memory)](./memory.md) — 双层记忆、对话压缩与全文检索 -- [文件系统(Filesystem)](./filesystem.md) — `AbstractFilesystem` 及其实现 +- [文件系统(Filesystem)](./filesystem.md) — 三种声明式模式与 `AbstractFilesystem` 层次 +- [沙箱(Sandbox)](./sandbox.md) — 隔离执行、沙箱状态与分布式选项 - [子 Agent(Subagent)](./subagent.md) — 子 agent 规格与编排 - [工具(Tool)](./tool.md) — 内置工具参考 - [会话(Session)](./session.md) — 会话持久化与状态恢复 diff --git a/docs/zh/harness/sandbox.md b/docs/zh/harness/sandbox.md new file mode 100644 index 000000000..d99545c04 --- /dev/null +++ b/docs/zh/harness/sandbox.md @@ -0,0 +1,302 @@ +# 沙箱(Sandbox) + +[Filesystem](./filesystem.md) 说明了 agent 的「文件与命令」从哪来。当这些操作必须**与宿主进程隔离**、在**可替换的执行环境**(本地 Unix、Docker 等)里完成,并在多次 `call` 之间**恢复同一份工作区状态**时,应选用本文描述的 **沙箱模式**(`filesystem(SandboxFilesystemSpec)`)。 + +## 1. 沙箱解决什么问题 + +- **执行边界**:模型通过同一套 `AbstractFilesystem` / `ShellExecuteTool` 接口操作文件与命令,但**真实 IO 与进程**在沙箱客户端所管理的隔离环境里完成,适合不可完全信任用户输入、或需与生产宿主解耦的场景。 +- **可恢复的工作单元**:与「单次 HTTP 请求」不同,多轮 `call` 应能接续同一逻辑工作区。`SandboxManager` 在每次 `call` 结束时**持久化沙箱侧状态**(通过 `SandboxStateStore`),下次 `acquire` 时按 `IsolationScope` 与 `sessionId`/`userId` 等键找回。 +- **与 harness 工作区的关系**:宿主机上仍有 `WorkspaceManager` 根目录;沙箱内可见的内容由 `WorkspaceSpec` 与**工作区投影**等机制定义(将部分宿主路径在启动时同步/挂载到沙箱内)。 + +## 2. 在 Harness 中的装配 + +启用沙箱模式时,`HarnessAgent.Builder` 会: + +1. 用 **`SandboxFilesystemSpec#toSandboxContext(hostWorkspaceRoot)`** 得到 **`SandboxContext`**(内含 `SandboxClient`、隔离范围、快照 spec、`WorkspaceSpec` 等),并同时把宿主侧需要投影进沙箱的目录(`AGENTS.md`、`skills/`、`subagents/`、`knowledge/`)装入一个 `WorkspaceProjectionEntry`(见 [§6 工作区投影](#6-工作区投影与-skills-同步))。 +2. 使用 **`SandboxBackedFilesystem`** 作为 agent 的 `AbstractFilesystem` 实现(对上层透明)。 +3. 构造 **`SandboxManager(client, stateStore, agentId)`**;未显式配置 `sandboxStateStore` 时,默认使用 **`SessionSandboxStateStore(effectiveSession, agentId)`**,将沙箱元数据与当前 `Session` 关联。 +4. 注册 **`SandboxLifecycleHook(sandboxManager, filesystemProxy)`**(优先级 `50`):在每次 `PreCall` 中 **acquire → `start()`**(含 4-分支工作区初始化,见 [§5 快照与 4-分支恢复](#5-快照与-4-分支恢复)),在 **`PostCall` / `Error`** 中 **`stop()`(持久快照)→ 持久化 state → release** 并清空代理上的活动会话。 + +只有后端实现 **`AbstractSandboxFilesystem`** 时,`HarnessAgent` 才会注册 **`ShellExecuteTool`**;沙箱模式下文件与 shell 命令都走沙箱内部,宿主机不受影响。 + +## 3. 隔离维度(`IsolationScope`) + +`IsolationScope` 控制**沙箱状态的持久化键**(sandbox 模式)以及**共享存储的命名空间前缀**(store 模式,见 [Filesystem 模式一](./filesystem.md))。两个模式共用同一个枚举,语义一致。 + +| 范围 | 持久化键来源 | 缺失时行为 | 典型场景 | +|------|------------|----------|---------| +| `SESSION`(默认) | `sessionKey.toIdentifier()` | 跳过状态查找,创建新沙箱 | 每个会话有独立的沙箱/记忆;对话隔离 | +| `USER` | `RuntimeContext.userId` | 警告并降级到新建 | 同一用户跨会话共享工作区或记忆(含分布式) | +| `AGENT` | agent 名称(构建时固定) | — | 单个 agent 的所有用户和会话共享同一工作区 | +| `GLOBAL` | 固定值 `__global__` | — | 一个 store 内所有 agent/用户/会话全局共享 | + +### 3.1 SESSION — 对话隔离(默认) + +每条对话独立沙箱,互不影响。适合多用户 SaaS,每个会话的临时工作文件、已安装的依赖互相隔离。 + +```java +HarnessAgent agent = HarnessAgent.builder() + .name("code-agent") + .model(model) + .filesystem(new DockerFilesystemSpec() + .image("ubuntu:24.04") + .snapshotSpec(new OssSnapshotSpec(...))) + // isolationScope 默认即 SESSION,此行可省略 + .filesystem(dockerSpec.isolationScope(IsolationScope.SESSION)) + .build(); + +// 每次 call 传入不同 sessionId → 独立的沙箱 +agent.call(msgs, RuntimeContext.builder().sessionId("user1-session1").build()).block(); +agent.call(msgs, RuntimeContext.builder().sessionId("user1-session2").build()).block(); +``` + +### 3.2 USER — 用户级共享(分布式记忆的推荐方式) + +**最常见的分布式场景**:多 Pod/多进程对同一用户的多个会话并行服务,但用户的长期记忆(`MEMORY.md`、`memory/`)要在所有副本间保持一致。 + +**Sandbox 模式 + USER**:不同会话(不同 Pod)在对话结束后都会向同一个 state slot(键 = `userId`)写入最新的快照引用。下次任意副本处理同一用户时,都能从该快照恢复出同一个工作区。注意这是**顺序复用**而非并发共享:并发请求各自拿到独立的容器运行,但在 `stop()` 时都会更新同一 state slot,最后写入的为准。 + +**Remote 模式 + USER**(无沙箱时的等价方案):`RemoteFilesystemSpec` 用 `userId` 作为 KV 命名空间前缀,所有路由到 `MEMORY.md`、`memory/` 等的读写都落在同一 store key 下,从而实现分布式副本之间的记忆共享,而无需快照。 + +```java +// 沙箱 + USER 隔离:同一用户跨 Pod 共享快照 +HarnessAgent agent = HarnessAgent.builder() + .name("assistant") + .model(model) + .filesystem(new DockerFilesystemSpec() + .image("ubuntu:24.04") + .snapshotSpec(new OssSnapshotSpec(...)) + .isolationScope(IsolationScope.USER)) + .sandboxDistributed(SandboxDistributedOptions.oss(redisSession, ossSnapshotSpec)) + .build(); + +RuntimeContext ctx = RuntimeContext.builder() + .userId("alice") // 相同 userId → 相同 state slot → 可恢复同一工作区 + .sessionId("session-xyz") + .build(); +agent.call(msgs, ctx).block(); +``` + +```java +// Remote 模式 + USER 隔离:轻量级分布式记忆共享(无沙箱) +HarnessAgent agent = HarnessAgent.builder() + .name("assistant") + .model(model) + .filesystem(new RemoteFilesystemSpec(redisStore) + .isolationScope(IsolationScope.USER)) + .build(); +// 同一 userId 的所有副本共享 MEMORY.md / memory/ 目录下的记忆 +``` + +### 3.3 AGENT — Agent 级共享 + +同一个 agent(按名称)的所有用户和会话共享工作区快照或存储命名空间。适合「公共知识库型」agent:全局单一工作区,写入由调用顺序决定,适合工具型、只读型或管理员场景。 + +### 3.4 GLOBAL — 全局共享 + +一个 store/workspace 实例内最大范围的共享,谨慎使用。 + +## 4. 自定义沙箱实例与生命周期管理 + +默认情况下,`SandboxManager` 全权负责沙箱的 create / start / stop / shutdown(**self-managed**)。当你需要**复用已有容器**、**在多个 agent 之间共享一个沙箱**,或**自己管理容器生命周期**时,可通过两种方式将沙箱控制权交还给调用方。 + +### 4.1 传入已有 `Sandbox` 实例(user-managed,最高优先级) + +在每次 `call` 时,通过 `RuntimeContext` 中的 `SandboxContext` 带入一个**已经启动的** `Sandbox` 对象: + +```java +// 提前创建并启动沙箱(容器生命周期由调用方管理) +Sandbox mySandbox = dockerClient.create(workspaceSpec, snapshotSpec, options); +mySandbox.start(); + +// 每次 call 时注入该实例 +SandboxContext callCtx = SandboxContext.builder() + .client(dockerClient) // 同 agent 构建时的 client + .externalSandbox(mySandbox) // ← 明确告知 Manager:这是 user-managed + .build(); + +RuntimeContext ctx = RuntimeContext.builder() + .sessionId("my-session") + .sandboxContext(callCtx) // 覆盖构建时的 defaultSandboxContext + .build(); + +agent.call(msgs, ctx).block(); +// SandboxLifecycleHook 会调用 mySandbox.stop()(持久快照) +// 但 不 会 调用 mySandbox.shutdown(),容器依然运行 +``` + +**行为规则**(`SandboxManager.acquire` 的 4 级优先级): + +| 优先级 | 条件 | 行为 | +|--------|------|------| +| 1(最高) | `SandboxContext.externalSandbox != null` | 直接使用,标记 user-managed;`PostCall` 仅调 `stop()`,不 `shutdown()` | +| 2 | `SandboxContext.externalSandboxState != null` | 从指定 state 恢复,self-managed | +| 3 | `SandboxStateStore` 中有持久化的 state | 按 `IsolationScope` 键恢复,self-managed | +| 4(默认) | 以上均无 | 创建新沙箱,self-managed | + +### 4.2 传入序列化状态(精确恢复特定快照) + +若你已持有某次 `call` 后保存的 `SandboxState` 序列化串,可绕过 `SandboxStateStore` 的自动查找,直接指定要恢复的状态: + +```java +// 从外部获取之前序列化的 state(例如从数据库或请求参数中读取) +String savedStateJson = db.load("checkpoint-2026-04-28"); +SandboxState savedState = dockerClient.deserializeState(savedStateJson); + +SandboxContext callCtx = SandboxContext.builder() + .client(dockerClient) + .externalSandboxState(savedState) // ← 指定 state,SDK 负责 resume + 管理生命周期 + .build(); + +RuntimeContext ctx = RuntimeContext.builder() + .sandboxContext(callCtx) + .build(); + +agent.call(msgs, ctx).block(); +``` + +### 4.3 多 Agent 共享同一沙箱 + +```java +// 主 agent 完成一个 call 后,把沙箱传给下一个 agent 继续使用 +Sandbox sharedSandbox = ...; // 已 start() + +agent1.call(msgs1, RuntimeContext.builder() + .sandboxContext(SandboxContext.builder().externalSandbox(sharedSandbox).client(client).build()) + .build()).block(); + +agent2.call(msgs2, RuntimeContext.builder() + .sandboxContext(SandboxContext.builder().externalSandbox(sharedSandbox).client(client).build()) + .build()).block(); + +// 所有 agent 用完后手动 shutdown +sharedSandbox.shutdown(); +``` + +## 5. 快照与 4-分支恢复 + +`Sandbox.start()` 按 **4 个分支**决定如何初始化工作区,保证在各种「容器是否还在、快照是否可用」的组合下都能正确恢复: + +``` +Branch A: workspaceRootReady=true & 容器内目录仍存在 → 只重新应用 ephemeral 条目(最快,热启动) +Branch B: workspaceRootReady=true & 容器内目录已丢失 → 从快照还原 + 重新应用 ephemeral 条目 +Branch C: workspaceRootReady=false & 快照可用 → 从快照还原 + 重新应用所有条目 +Branch D: workspaceRootReady=false & 无可用快照 → 从 WorkspaceSpec 全量初始化(冷启动) +``` + +`Sandbox.stop()` 执行时若 `SandboxSnapshotSpec` 启用了持久化,则将工作区打成 tar 并存入快照后端(OSS、Redis、本地文件等),同时把 `workspaceRootReady` 置 true。这个 tar 就是下次恢复时供 Branch B/C 使用的**归档**。 + +**`WorkspaceEntry.ephemeral` 标志**:`WorkspaceSpec` 中的每个条目都可以标记为 ephemeral(每次启动都重新写入)或非 ephemeral(进快照一同保存,只在冷启动时写入)。`skills/`、`AGENTS.md` 等宿主侧随时可能更新的文件,以 `WorkspaceProjectionEntry` 的方式处理(下节),而不是 ephemeral flag。 + +**快照 spec 可选类型**: + +| Spec | 存储位置 | +|------|---------| +| `NoopSnapshotSpec`(默认) | 不持久化;容器重建后从 WorkspaceSpec 冷启动 | +| `LocalSnapshotSpec` | 宿主机本地文件(适合单机长期运行) | +| `OssSnapshotSpec` | OSS / S3 兼容存储(适合多副本) | +| `RedisSnapshotSpec` | Redis(适合低延迟、小工作区) | + +## 6. 工作区投影与 Skills 同步 + +**工作区投影**(`WorkspaceProjectionEntry`)是 harness 将宿主机工作区里的特定目录/文件在**每次沙箱启动时**同步进沙箱的机制,是 Skills 等能力在沙箱内运行的基础。 + +### 6.1 投影范围 + +`SandboxFilesystemSpec` 构建 `SandboxContext` 时,默认把以下宿主路径打包进投影: + +``` +AGENTS.md ← agent 身份与指令 +skills/ ← SkillBox 里所有 Skill 的目录(含 SKILL.md 和脚本文件) +subagents/ ← 子 agent 规格文件 +knowledge/ ← 领域知识文件 +``` + +可通过 `SandboxFilesystemSpec#workspaceProjectionRoots(List)` 自定义要投影的根路径,或通过 `workspaceProjectionEnabled(false)` 完全关闭。 + +### 6.2 投影如何工作 + +`WorkspaceProjectionApplier` 在 `Sandbox.start()` 末尾执行: + +1. 遍历所有 `WorkspaceProjectionEntry`,收集宿主侧的文件集合,按路径排序后计算 **SHA-256 内容哈希**。 +2. 将这批文件打包成 tar,通过 `Sandbox.hydrateWorkspace(archive)` 解压到沙箱工作区内对应路径。 +3. 把本次哈希存入 `SandboxState.workspaceProjectionHash`;下次启动时若哈希不变,**跳过投影**(避免重复传输)。 + +这意味着:宿主机上 `skills/` 的内容更新后,下次沙箱 start 时哈希变化,新版文件自动同步进去;沙箱内对 skill 文件的修改不会反向同步回宿主机。 + +### 6.3 Skills 在沙箱内怎么执行 + +Harness 的 `SkillBox` 机制把 `workspace/skills//SKILL.md` 里的说明注入 agent 的 system prompt;model 理解「需要这个 skill」后通过 `ShellExecuteTool` 执行 skill 目录下的脚本或命令。在沙箱模式下,这一切都在沙箱内进行: + +``` +宿主机 workspace/skills/pytest/ +│── SKILL.md # 描述:如何运行 pytest +└── run_tests.sh # 实际脚本 + + ▼ 投影(每次启动时) + +沙箱内 /workspace/skills/pytest/ +│── SKILL.md +└── run_tests.sh + +agent 思考后调用 shell_execute: + "bash /workspace/skills/pytest/run_tests.sh tests/" + ↓ + ExecResult(exitCode=0, stdout="5 passed") +``` + +**优点**:脚本运行在隔离容器内,pip install、apt-get、rm -rf 等操作只影响沙箱工作区,宿主机无感。沙箱被 snapshot 后,已安装的依赖也会随工作区一起被归档,下次恢复时直接可用(Branch A/B/C),无需重新安装。 + +### 6.4 Shell 命令与脚本的状态持久化 + +`ShellExecuteTool` 调用 `AbstractSandboxFilesystem.execute(cmd, timeout)` → `Sandbox.exec(cmd, timeout)`,在沙箱内执行命令。命令对文件系统的所有更改(新建文件、安装包、写日志等)都保留在沙箱的 overlay/容器内。`stop()` 时这些状态随 tar 快照持久化,下次 `start()` 恢复。 + +因此,跨 `call` 的**状态是完整保留的**: + +``` +call 1: shell_execute("pip install pandas") → pandas 装进沙箱 +call 2: shell_execute("python analyze.py") → 直接可用,无需重装 +call 3: shell_execute("cat results.csv") → 读 call 2 产生的文件 +``` + +## 7. 状态:`SandboxStateStore` 与 `Session` + +- **`SandboxStateStore`**:抽象「与某次隔离键绑定的沙箱元数据(sessionId + 快照引用)」的持久化。便于替换为自定义实现。 +- **默认 `SessionSandboxStateStore`**:依赖构建时选定的 `Session`(与 `SessionPersistenceHook` 等共用的**会话抽象**;若你使用 Redis 等分布式 `Session`,沙箱元数据可随之跨进程可见)。 +- **`WorkspaceSession`** 仍负责**工作区布局下的 per-session 配置**;**不要**将 `WorkspaceSession` 的 JSON 与「沙箱 state JSON」混为同一套职责——沙箱的 resume 数据以 **`SandboxStateStore`** 为准。 + +## 8. 分布式与 `sandboxDistributed` + +当多副本或无状态 worker 要共享**同一条逻辑会话**的沙箱恢复能力时,需要: + +- **分布式 `Session`**(如 `RedisSession`),而不仅是默认的 `WorkspaceSession` 文件后端;以及 +- 非 no-op 的 **`SandboxSnapshotSpec`**(将工作区打成可再拉取的归档),在「必须分布式」的校验下才会通过。 + +`HarnessAgent.Builder#sandboxDistributed(SandboxDistributedOptions)` 可统一下发: + +- 覆盖/合并 **`isolationScope`** 与 **`snapshotSpec`**(若提供); +- 在选项中**显式指定**用于沙箱的 `Session`(若与主 `session` 不同); +- 使用 `SandboxDistributedOptions#oss` / `#redis` 等辅助构造常见组合(见类 JavaDoc)。 + +若 `requireDistributed` 为 true 而当前 `effectiveSession` 仍是 `WorkspaceSession` 或快照为 no-op,构建会 **fail-fast**。 + +## 9. 与三种 Filesystem 模式怎么选 + +沙箱是三种**声明式**配置之一。完整对比见 [Filesystem](./filesystem.md#三种声明式模式);此处只给决策要点: + +| 你更需要 | 推荐模式 | +|----------|----------| +| 多实例共享 `MEMORY.md`、会话日志等到 KV,**不要**在宿主跑 shell | `RemoteFilesystemSpec`(见 [Filesystem — 模式一](./filesystem.md)) | +| 单进程/本机、信任 shell、**不要**另起沙箱 | `LocalFilesystemSpec` 或默认本机 + shell(见 [Filesystem — 模式三](./filesystem.md)) | +| **隔离执行**、命令与文件落沙箱、**长会话恢复**、可选**快照 + 集群** | **`SandboxFilesystemSpec`(本文)+ 可选 `sandboxDistributed`** | + +## 10. 子 Agent + +已启用 `SubagentsHook` 时,若主 agent 在沙箱模式下构建,**子 agent 的 filesystem 会复用**同一 `SandboxBackedFilesystem` 的会话绑定策略(以当前实现为准,便于在同一次编排树内共享环境)。子 agent 本身仍是独立 `ReActAgent`;隔离边界与主 agent 的沙箱 spec 一致。 + +## 11. 延伸阅读 + +- [Filesystem](./filesystem.md) — 类层次、三种模式、`abstractFilesystem` 逃生口 +- [工具](./tool.md) — `FilesystemTool`、`ShellExecuteTool` 入参 +- [会话](./session.md) — `Session` 与 `WorkspaceSession` +- [架构](./architecture.md) — Hook 协作与时序 diff --git a/docs/zh/harness/tool.md b/docs/zh/harness/tool.md index a775930f2..42218d2cb 100644 --- a/docs/zh/harness/tool.md +++ b/docs/zh/harness/tool.md @@ -82,7 +82,7 @@ Session mode 下,这三个名会变为 `sessions_spawn` / `sessions_send` / `s ## Shell·`ShellExecuteTool`(条件性装) -仅在后端是 `AbstractSandboxFilesystem`(包含 `LocalFilesystemWithShell`)时才被注册。如果你用的是纯 `LocalFilesystem` 或 `StoreFilesystem`,子工具不出现。 +仅在后端是 `AbstractSandboxFilesystem`(包含 `LocalFilesystemWithShell`)时才被注册。如果你用的是纯 `LocalFilesystem` 或 `RemoteFilesystem`,子工具不出现。 | 工具 | 作用 | 参数 | |------|------|------| diff --git a/docs/zh/openai-agents/sandbox/clients.md b/docs/zh/openai-agents/sandbox/clients.md new file mode 100644 index 000000000..683e8bc47 --- /dev/null +++ b/docs/zh/openai-agents/sandbox/clients.md @@ -0,0 +1,137 @@ +# Sandbox clients + +Use this page to choose where sandbox work should run. In most cases, the `SandboxAgent` definition stays the same while the sandbox client and client-specific options change in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. + +!!! warning "Beta feature" + + Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. + +## Decision guide + +

    + +| Goal | Start with | Why | +| --- | --- | --- | +| Fastest local iteration on macOS or Linux | `UnixLocalSandboxClient` | No extra install, simple local filesystem development. | +| Basic container isolation | `DockerSandboxClient` | Runs work inside Docker with a specific image. | +| Hosted execution or production-style isolation | A hosted sandbox client | Moves the workspace boundary to a provider-managed environment. | + +
    + +## Local clients + +For most users, start with one of these two sandbox clients: + +
    + +| Client | Install | Choose it when | Example | +| --- | --- | --- | --- | +| `UnixLocalSandboxClient` | none | Fastest local iteration on macOS or Linux. Good default for local development. | [Unix-local starter](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/unix_local_runner.py) | +| `DockerSandboxClient` | `openai-agents[docker]` | You want container isolation or a specific image for local parity. | [Docker starter](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py) | + +
    + +Unix-local is the easiest way to start developing against a local filesystem. Move to Docker or a hosted provider when you need stronger environment isolation or production-style parity. + +To switch from Unix-local to Docker, keep the agent definition the same and change only the run config: + +```python +from docker import from_env as docker_from_env + +from agents.run import RunConfig +from agents.sandbox import SandboxRunConfig +from agents.sandbox.sandboxes.docker import DockerSandboxClient, DockerSandboxClientOptions + +run_config = RunConfig( + sandbox=SandboxRunConfig( + client=DockerSandboxClient(docker_from_env()), + options=DockerSandboxClientOptions(image="python:3.14-slim"), + ), +) +``` + +Use this when you want container isolation or image parity. See [examples/sandbox/docker/docker_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py). + +## Mounts and remote storage + +Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. Import the built-in mount entries and generic strategies from `agents.sandbox.entries`. Hosted-provider strategies are available from `agents.extensions.sandbox` or the provider-specific extension package. + +Common mount options: + +- `mount_path`: where the storage appears in the sandbox. Relative paths are resolved under the manifest root; absolute paths are used as-is. +- `read_only`: defaults to `True`. Set `False` only when the sandbox should write back to the mounted storage. +- `mount_strategy`: required. Use a strategy that matches both the mount entry and the sandbox backend. + +Mounts are treated as ephemeral workspace entries. Snapshot and persistence flows detach or skip mounted paths instead of copying mounted remote storage into the saved workspace. + +Generic local/container strategies: + +
    + +| Strategy or pattern | Use it when | Notes | +| --- | --- | --- | +| `InContainerMountStrategy(pattern=RcloneMountPattern(...))` | The sandbox image can run `rclone`. | Supports S3, GCS, R2, and Azure Blob. `RcloneMountPattern` can run in `fuse` mode or `nfs` mode. | +| `InContainerMountStrategy(pattern=MountpointMountPattern(...))` | The image has `mount-s3` and you want Mountpoint-style S3 or S3-compatible access. | Supports `S3Mount` and `GCSMount`. | +| `InContainerMountStrategy(pattern=FuseMountPattern(...))` | The image has `blobfuse2` and FUSE support. | Supports `AzureBlobMount`. | +| `InContainerMountStrategy(pattern=S3FilesMountPattern(...))` | The image has `mount.s3files` and can reach an existing S3 Files mount target. | Supports `S3FilesMount`. | +| `DockerVolumeMountStrategy(driver=...)` | Docker should attach a volume-driver-backed mount before the container starts. | Docker-only. S3, GCS, R2, and Azure Blob support `rclone`; S3 and GCS also support `mountpoint`. | + +
    + +## Supported hosted platforms + +When you need a hosted environment, the same `SandboxAgent` definition usually carries over and only the sandbox client changes in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. + +If you are using the published SDK instead of this repository checkout, install sandbox-client dependencies through the matching package extra. + +For provider-specific setup notes and links for the checked-in extension examples, see [examples/sandbox/extensions/README.md](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/README.md). + +
    + +| Client | Install | Example | +| --- | --- | --- | +| `BlaxelSandboxClient` | `openai-agents[blaxel]` | [Blaxel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/blaxel_runner.py) | +| `CloudflareSandboxClient` | `openai-agents[cloudflare]` | [Cloudflare runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/cloudflare_runner.py) | +| `DaytonaSandboxClient` | `openai-agents[daytona]` | [Daytona runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/daytona/daytona_runner.py) | +| `E2BSandboxClient` | `openai-agents[e2b]` | [E2B runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/e2b_runner.py) | +| `ModalSandboxClient` | `openai-agents[modal]` | [Modal runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/modal_runner.py) | +| `RunloopSandboxClient` | `openai-agents[runloop]` | [Runloop runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/runloop/runner.py) | +| `VercelSandboxClient` | `openai-agents[vercel]` | [Vercel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/vercel_runner.py) | + +
    + +Hosted sandbox clients expose provider-specific mount strategies. Choose the backend and mount strategy that best fit your storage provider: + +
    + +| Backend | Mount notes | +| --- | --- | +| Docker | Supports `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `S3FilesMount` with local strategies such as `InContainerMountStrategy` and `DockerVolumeMountStrategy`. | +| `ModalSandboxClient` | Supports Modal cloud bucket mounts with `ModalCloudBucketMountStrategy` on `S3Mount`, `R2Mount`, and HMAC-authenticated `GCSMount`. You can use inline credentials or a named Modal Secret. | +| `CloudflareSandboxClient` | Supports Cloudflare bucket mounts with `CloudflareBucketMountStrategy` on `S3Mount`, `R2Mount`, and HMAC-authenticated `GCSMount`. | +| `BlaxelSandboxClient` | Supports cloud bucket mounts with `BlaxelCloudBucketMountStrategy` on `S3Mount`, `R2Mount`, and `GCSMount`. Also supports persistent Blaxel Drives with `BlaxelDriveMount` and `BlaxelDriveMountStrategy` from `agents.extensions.sandbox.blaxel`. | +| `DaytonaSandboxClient` | Supports cloud bucket mounts with `DaytonaCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | +| `E2BSandboxClient` | Supports cloud bucket mounts with `E2BCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | +| `RunloopSandboxClient` | Supports cloud bucket mounts with `RunloopCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | +| `VercelSandboxClient` | No hosted-specific mount strategy is currently exposed. Use manifest files, repos, or other workspace inputs instead. | + +
    + +The table below summarizes which remote storage entries each backend can mount directly. + +
    + +| Backend | AWS S3 | Cloudflare R2 | GCS | Azure Blob Storage | S3 Files | +| --- | --- | --- | --- | --- | --- | +| Docker | ✓ | ✓ | ✓ | ✓ | ✓ | +| `ModalSandboxClient` | ✓ | ✓ | ✓ | - | - | +| `CloudflareSandboxClient` | ✓ | ✓ | ✓ | - | - | +| `BlaxelSandboxClient` | ✓ | ✓ | ✓ | - | - | +| `DaytonaSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | +| `E2BSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | +| `RunloopSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | +| `VercelSandboxClient` | - | - | - | - | - | + +
    + +For more runnable examples, browse [examples/sandbox/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox) for local, coding, memory, handoff, and agent-composition patterns, and [examples/sandbox/extensions/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox/extensions) for hosted sandbox clients. diff --git a/docs/zh/openai-agents/sandbox/guide.md b/docs/zh/openai-agents/sandbox/guide.md new file mode 100644 index 000000000..a6f9b31f9 --- /dev/null +++ b/docs/zh/openai-agents/sandbox/guide.md @@ -0,0 +1,832 @@ +# Concepts + +!!! warning "Beta feature" + + Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. + +Modern agents work best when they can operate on real files in a filesystem. **Sandbox Agents** can make use of specialized tools and shell commands to search over and manipulate large document sets, edit files, generate artifacts, and run commands. The sandbox provides the model with a persistent workspace that the agent can use to do work on your behalf. Sandbox Agents in the Agents SDK help you easily run agents paired with a sandbox environment, making it easy to get the right files on the filesystem and orchestrate the sandboxes to make it easy to start, stop, and resume tasks at scale. + +You define the workspace around the data the agent needs. It can start from GitHub repos, local files and directories, synthetic task files, remote filesystems such as S3 or Azure Blob Storage, and other sandbox inputs you provide. + +
    + +![Sandbox agent harness with compute](../assets/images/harness_with_compute.png) + +
    + +`SandboxAgent` is still an `Agent`. It keeps the usual agent surface such as `instructions`, `prompt`, `tools`, `handoffs`, `mcp_servers`, `model_settings`, `output_type`, guardrails, and hooks, and it still runs through the normal `Runner` APIs. What changes is the execution boundary: + +- `SandboxAgent` defines the agent itself: the usual agent configuration plus sandbox-specific defaults like `default_manifest`, `base_instructions`, `run_as`, and capabilities such as filesystem tools, shell access, skills, memory, or compaction. +- `Manifest` declares the desired starting contents and layout for a fresh sandbox workspace, including files, repos, mounts, and environment. +- A sandbox session is the live isolated environment where commands run and files change. +- [`SandboxRunConfig`][agents.run_config.SandboxRunConfig] decides how the run gets that sandbox session, for example by injecting one directly, reconnecting from serialized sandbox session state, or creating a fresh sandbox session through a sandbox client. +- Saved sandbox state and snapshots let later runs reconnect to prior work or seed a fresh sandbox session from saved contents. + +`Manifest` is the fresh-session workspace contract, not the full source of truth for every live sandbox. The effective workspace for a run can instead come from a reused sandbox session, serialized sandbox session state, or a snapshot chosen at run time. + +Throughout this page, "sandbox session" means the live execution environment managed by a sandbox client. It is different from the SDK's conversational [`Session`][agents.memory.session.Session] interfaces described in [Sessions](../sessions/index.md). + +The outer runtime still owns approvals, tracing, handoffs, and resume bookkeeping. The sandbox session owns commands, file changes, and environment isolation. That split is a core part of the model. + +### How the pieces fit together + +A sandbox run combines an agent definition with per-run sandbox configuration. The runner prepares the agent, binds it to a live sandbox session, and can save state for later runs. + +```mermaid +flowchart LR + agent["SandboxAgent
    full Agent + sandbox defaults"] + config["SandboxRunConfig
    client / session / resume inputs"] + runner["Runner
    prepare instructions
    bind capability tools
    "] + sandbox["sandbox session
    workspace where commands run
    and files change
    "] + saved["saved state / snapshot
    for resume or fresh-start later"] + + agent --> runner + config --> runner + runner --> sandbox + sandbox --> saved +``` + +Sandbox-specific defaults stay on `SandboxAgent`. Per-run sandbox-session choices stay in `SandboxRunConfig`. + +Think about the lifecycle in three phases: + +1. Define the agent and the fresh-workspace contract with `SandboxAgent`, `Manifest`, and capabilities. +2. Execute a run by giving `Runner` a `SandboxRunConfig` that injects, resumes, or creates the sandbox session. +3. Continue later from runner-managed `RunState`, explicit sandbox `session_state`, or a saved workspace snapshot. + +If shell access is only one occasional tool, start with hosted shell in the [tools guide](../tools.md). Reach for sandbox agents when workspace isolation, sandbox client choice, or sandbox-session resume behavior are part of the design. + +## When to use them + +Sandbox agents are a good fit for workspace-centric workflows, for example: + +- coding and debugging, for example orchestrating automated fixes for issue reports in a GitHub repo and running targeted tests +- document processing and editing, for example extracting information from a user's financial documents and creating a completed tax-form draft +- file-grounded review or analysis, for example checking onboarding packets, generated reports, or artifact bundles before answering +- isolated multi-agent patterns, for example giving each reviewer or coding sub-agent its own workspace +- multi-step workspace tasks, for example fixing a bug in one run and adding a regression test later, or resuming from snapshot or sandbox session state + +If you do not need access to files or a living filesystem, keep using `Agent`. If shell access is just one occasional capability, add hosted shell; if the workspace boundary itself is part of the feature, use sandbox agents. + +## Choose a sandbox client + +Start with `UnixLocalSandboxClient` for local development. Move to `DockerSandboxClient` when you need container isolation or image parity. Move to a hosted provider when you need provider-managed execution. + +In most cases, the `SandboxAgent` definition stays the same while the sandbox client and its options change in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. See [Sandbox clients](clients.md) for local, Docker, hosted, and remote-mount options. + +## Core pieces + +
    + +| Layer | Main SDK pieces | What it answers | +| --- | --- | --- | +| Agent definition | `SandboxAgent`, `Manifest`, capabilities | What agent will run, and what fresh-session workspace contract should it start from? | +| Sandbox execution | `SandboxRunConfig`, the sandbox client, and the live sandbox session | How does this run get a live sandbox session, and where does the work execute? | +| Saved sandbox state | `RunState` sandbox payload, `session_state`, and snapshots | How does this workflow reconnect to prior sandbox work or seed a fresh sandbox session from saved contents? | + +
    + +The main SDK pieces map onto those layers like this: + +
    + +| Piece | What it owns | Ask this question | +| --- | --- | --- | +| [`SandboxAgent`][agents.sandbox.sandbox_agent.SandboxAgent] | The agent definition | What should this agent do, and which defaults should travel with it? | +| [`Manifest`][agents.sandbox.manifest.Manifest] | Fresh-session workspace files and folders | What files and folder should be present on the filesystem when the run starts? | +| [`Capability`][agents.sandbox.capabilities.capability.Capability] | Sandbox-native behavior | Which tools, instruction fragments, or runtime behavior should attach to this agent? | +| [`SandboxRunConfig`][agents.run_config.SandboxRunConfig] | Per-run sandbox client and sandbox-session source | Should this run inject, resume, or create a sandbox session? | +| [`RunState`][agents.run_state.RunState] | Runner-managed saved sandbox state | Am I resuming a prior runner-managed workflow and carrying its sandbox state forward automatically? | +| [`SandboxRunConfig.session_state`][agents.run_config.SandboxRunConfig.session_state] | Explicit serialized sandbox session state | Do I want to resume from sandbox state I already serialized outside `RunState`? | +| [`SandboxRunConfig.snapshot`][agents.run_config.SandboxRunConfig.snapshot] | Saved workspace contents for fresh sandbox sessions | Should a new sandbox session start from saved files and artifacts? | + +
    + +A practical design order is: + +1. Define the fresh-session workspace contract with `Manifest`. +2. Define the agent with `SandboxAgent`. +3. Add built-in or custom capabilities. +4. Decide how each run should obtain its sandbox session in `RunConfig(sandbox=SandboxRunConfig(...))`. + +## How a sandbox run is prepared + +At run time, the runner turns that definition into a concrete sandbox-backed run: + +1. It resolves the sandbox session from `SandboxRunConfig`. + If you pass `session=...`, it reuses that live sandbox session. + Otherwise it uses `client=...` to create or resume one. +2. It determines the effective workspace inputs for the run. + If the run injects or resumes a sandbox session, that existing sandbox state wins. + Otherwise the runner starts from a one-off manifest override or `agent.default_manifest`. + This is why `Manifest` alone does not define the final live workspace for every run. +3. It lets capabilities process the resulting manifest. + This is how capabilities can add files, mounts, or other workspace-scoped behavior before the final agent is prepared. +4. It builds the final instructions in a fixed order: + the SDK's default sandbox prompt, or `base_instructions` if you explicitly override it, then `instructions`, then capability instruction fragments, then any remote-mount policy text, then a rendered filesystem tree. +5. It binds capability tools to the live sandbox session and runs the prepared agent through the normal `Runner` APIs. + +Sandboxing does not change what a turn means. A turn is still a model step, not a single shell command or sandbox action. There is no fixed 1:1 mapping between sandbox-side operations and turns: some work may stay inside the sandbox execution layer, while other actions return tool results, approvals, or other state that requires another model step. As a practical rule, another turn is consumed only when the agent runtime needs another model response after sandbox work has happened. + +Those preparation steps are why `default_manifest`, `instructions`, `base_instructions`, `capabilities`, and `run_as` are the main sandbox-specific options to think about when designing a `SandboxAgent`. + +## `SandboxAgent` options + +These are the sandbox-specific options on top of the usual `Agent` fields: + +
    + +| Option | Best use | +| --- | --- | +| `default_manifest` | The default workspace for fresh sandbox sessions created by the runner. | +| `instructions` | Additional role, workflow, and success criteria appended after the SDK sandbox prompt. | +| `base_instructions` | Advanced escape hatch that replaces the SDK sandbox prompt. | +| `capabilities` | Sandbox-native tools and behavior that should travel with this agent. | +| `run_as` | User identity for model-facing sandbox tools such as shell commands, file reads, and patches. | + +
    + +Sandbox client choice, sandbox-session reuse, manifest override, and snapshot selection belong in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig], not on the agent. + +### `default_manifest` + +`default_manifest` is the default [`Manifest`][agents.sandbox.manifest.Manifest] used when the runner creates a fresh sandbox session for this agent. Use it for the files, repos, helper material, output directories, and mounts the agent should usually start with. + +This is only the default. A run can override it with `SandboxRunConfig(manifest=...)`, and a reused or resumed sandbox session keeps its existing workspace state. + +### `instructions` and `base_instructions` + +Use `instructions` for short rules that should survive different prompts. In a `SandboxAgent`, these instructions are appended after the SDK's sandbox base prompt, so you keep the built-in sandbox guidance and add your own role, workflow, and success criteria. + +Use `base_instructions` only when you want to replace the SDK sandbox base prompt. Most agents should not set it. + +
    + +| Put it in... | Use it for | Examples | +| --- | --- | --- | +| `instructions` | Stable role, workflow rules, and success criteria for the agent. | "Inspect onboarding documents, then hand off.", "Write final files into `output/`." | +| `base_instructions` | A full replacement for the SDK sandbox base prompt. | Custom low-level sandbox wrapper prompts. | +| the user prompt | The one-off request for this run. | "Summarize this workspace." | +| workspace files in the manifest | Longer task specs, repo-local instructions, or bounded reference material. | `repo/task.md`, document bundles, sample packets. | + +
    + +Good uses for `instructions` include: + +- [examples/sandbox/unix_local_pty.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/unix_local_pty.py) keeps the agent in one interactive process when PTY state matters. +- [examples/sandbox/handoffs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/handoffs.py) forbids the sandbox reviewer from answering the user directly after inspection. +- [examples/sandbox/tax_prep.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/tax_prep.py) requires the final filled files to actually land in `output/`. +- [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) pins the exact verification command and clarifies workspace-root-relative patch paths. + +Avoid copying the user's one-off task into `instructions`, embedding long reference material that belongs in the manifest, restating tool docs that built-in capabilities already inject, or mixing in local installation notes the model does not need at run time. + +If you omit `instructions`, the SDK still includes the default sandbox prompt. That is enough for low-level wrappers, but most user-facing agents should still provide explicit `instructions`. + +### `capabilities` + +Capabilities attach sandbox-native behavior to a `SandboxAgent`. They can shape the workspace before a run starts, append sandbox-specific instructions, expose tools that bind to the live sandbox session, and adjust model behavior or input handling for that agent. + +Built-in capabilities include: + +
    + +| Capability | Add it when | Notes | +| --- | --- | --- | +| `Shell` | The agent needs shell access. | Adds `exec_command`, plus `write_stdin` when the sandbox client supports PTY interaction. | +| `Filesystem` | The agent needs to edit files or inspect local images. | Adds `apply_patch` and `view_image`; patch paths are workspace-root-relative. | +| `Skills` | You want skill discovery and materialization in the sandbox. | Prefer this over mounting `.agents` or `.agents/skills` manually for sandbox-local `SKILL.md` skills. | +| `Memory` | Follow-on runs should read or generate memory artifacts. | Requires `Shell`; live updates also require `Filesystem`. | +| `Compaction` | Long-running flows need context trimming after compaction items. | Adjusts model sampling and input handling. | + +
    + +By default, `SandboxAgent.capabilities` uses `Capabilities.default()`, which includes `Filesystem()`, `Shell()`, and `Compaction()`. If you pass `capabilities=[...]`, that list replaces the default, so include any default capabilities you still want. + +For skills, choose the source based on how you want them materialized: + +- `Skills(lazy_from=LocalDirLazySkillSource(...))` is a good default for larger local skill directories because the model can discover the index first and load only what it needs. +- `Skills(from_=LocalDir(src=...))` is better for a small local bundle you want staged up front. +- `Skills(from_=GitRepo(repo=..., ref=...))` is the right fit when the skills themselves should come from a repository. + +If your skills already live on disk under something like `.agents/skills//SKILL.md`, point `LocalDir(...)` at that source root and still use `Skills(...)` to expose them. Keep the default `skills_path=".agents"` unless you have an existing workspace contract that depends on a different in-sandbox layout. + +Prefer built-in capabilities when they fit. Write a custom capability only when you need a sandbox-specific tool or instruction surface that the built-ins do not cover. + +## Concepts + +### Manifest + +A [`Manifest`][agents.sandbox.manifest.Manifest] describes the workspace for a fresh sandbox session. It can set the workspace `root`, declare files and directories, copy in local files, clone Git repos, attach remote storage mounts, set environment variables, and define users or groups. + +Manifest entry paths are workspace-relative. They cannot be absolute paths or escape the workspace with `..`, which keeps the workspace contract portable across local, Docker, and hosted clients. + +Use manifest entries for the material the agent needs before work begins: + +
    + +| Manifest entry | Use it for | +| --- | --- | +| `File`, `Dir` | Small synthetic inputs, helper files, or output directories. | +| `LocalFile`, `LocalDir` | Host files or directories that should be materialized into the sandbox. | +| `GitRepo` | A repository that should be fetched into the workspace. | +| mounts such as `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, `S3FilesMount` | External storage that should appear inside the sandbox. | + +
    + +Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. See [Sandbox clients](clients.md#mounts-and-remote-storage) for mount options and provider support. + +Good manifest design usually means keeping the workspace contract narrow, putting long task recipes in workspace files such as `repo/task.md`, and using relative workspace paths in instructions, for example `repo/task.md` or `output/report.md`. If the agent edits files with the `Filesystem` capability's `apply_patch` tool, remember that patch paths are relative to the sandbox workspace root, not the shell `workdir`. + +### Permissions + +`Permissions` controls filesystem permissions for manifest entries. It is about the files the sandbox materializes, not model permissions, approval policy, or API credentials. + +By default, manifest entries are owner-readable/writable/executable and readable/executable by group and others. Override this when staged files should be private, read-only, or executable: + +```python +from agents.sandbox import FileMode, Permissions +from agents.sandbox.entries import File + +private_notes = File( + text="internal notes", + permissions=Permissions( + owner=FileMode.READ | FileMode.WRITE, + group=FileMode.NONE, + other=FileMode.NONE, + ), +) +``` + +`Permissions` stores separate owner, group, and other bits, plus whether the entry is a directory. You can build it directly, parse it from a mode string with `Permissions.from_str(...)`, or derive it from an OS mode with `Permissions.from_mode(...)`. + +Users are the sandbox identities that can execute work. Add a `User` to the manifest when you want that identity to exist in the sandbox, then set `SandboxAgent.run_as` when model-facing sandbox tools such as shell commands, file reads, and patches should run as that user. If `run_as` points at a user that is not already in the manifest, the runner adds it to the effective manifest for you. + +```python +from agents import Runner +from agents.run import RunConfig +from agents.sandbox import FileMode, Manifest, Permissions, SandboxAgent, SandboxRunConfig, User +from agents.sandbox.entries import Dir, LocalDir +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +analyst = User(name="analyst") + +agent = SandboxAgent( + name="Dataroom analyst", + instructions="Review the files in `dataroom/` and write findings to `output/`.", + default_manifest=Manifest( + # Declare the sandbox user so manifest entries can grant access to it. + users=[analyst], + entries={ + "dataroom": LocalDir( + src="./dataroom", + # Let the analyst traverse and read the mounted dataroom, but not edit it. + group=analyst, + permissions=Permissions( + owner=FileMode.READ | FileMode.EXEC, + group=FileMode.READ | FileMode.EXEC, + other=FileMode.NONE, + ), + ), + "output": Dir( + # Give the analyst a writable scratch/output directory for artifacts. + group=analyst, + permissions=Permissions( + owner=FileMode.ALL, + group=FileMode.ALL, + other=FileMode.NONE, + ), + ), + }, + ), + # Run model-facing sandbox actions as this user, so those permissions apply. + run_as=analyst, +) + +result = await Runner.run( + agent, + "Summarize the contracts and call out renewal dates.", + run_config=RunConfig( + sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), + ), +) +``` + +If you also need file-level sharing rules, combine users with manifest groups and entry `group` metadata. The `run_as` user controls who executes sandbox-native actions; `Permissions` controls which files that user can read, write, or execute once the sandbox has materialized the workspace. + +### SnapshotSpec + +`SnapshotSpec` tells a fresh sandbox session where saved workspace contents should be restored from and persisted back to. It is the snapshot policy for the sandbox workspace, while `session_state` is the serialized connection state for resuming a specific sandbox backend. + +Use `LocalSnapshotSpec` for local durable snapshots and `RemoteSnapshotSpec` when your app provides a remote snapshot client. A no-op snapshot is used as a fallback when local snapshot setup is unavailable, and advanced callers can use one explicitly when they do not want workspace snapshot persistence. + +```python +from pathlib import Path + +from agents.run import RunConfig +from agents.sandbox import LocalSnapshotSpec, SandboxRunConfig +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +run_config = RunConfig( + sandbox=SandboxRunConfig( + client=UnixLocalSandboxClient(), + snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshots")), + ) +) +``` + +When the runner creates a fresh sandbox session, the sandbox client builds a snapshot instance for that session. On start, if the snapshot is restorable, the sandbox restores saved workspace contents before the run continues. On cleanup, runner-owned sandbox sessions archive the workspace and persist it back through the snapshot. + +If you omit `snapshot`, the runtime tries to use a default local snapshot location when it can. If that cannot be set up, it falls back to a no-op snapshot. Mounted and ephemeral paths are not copied into snapshots as durable workspace contents. + +### Sandbox lifecycle + +There are two lifecycle modes: **SDK-owned** and **developer-owned**. + +
    + +```mermaid +sequenceDiagram + participant App + participant Runner + participant Client + participant Sandbox + + App->>Runner: Runner.run(..., SandboxRunConfig(client=...)) + Runner->>Client: create or resume sandbox + Client-->>Runner: sandbox session + Runner->>Sandbox: start, run tools + Runner->>Sandbox: stop and persist snapshot + Runner->>Client: delete runner-owned resources + + App->>Client: create(...) + Client-->>App: sandbox session + App->>Sandbox: async with sandbox + App->>Runner: Runner.run(..., SandboxRunConfig(session=sandbox)) + Runner->>Sandbox: run tools + App->>Sandbox: cleanup on context exit / aclose() +``` + +
    + +Use SDK-owned lifecycle when the sandbox only needs to live for one run. Pass a `client`, optional `manifest`, optional `snapshot`, and client `options`; the runner creates or resumes the sandbox, starts it, runs the agent, persists snapshot-backed workspace state, shuts the sandbox down, and lets the client clean up runner-owned resources. + +```python +result = await Runner.run( + agent, + "Inspect the workspace and summarize what changed.", + run_config=RunConfig( + sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), + ), +) +``` + +Use developer-owned lifecycle when you want to eagerly create a sandbox, reuse one live sandbox across multiple runs, inspect files after a run, stream over a sandbox you created yourself, or decide exactly when cleanup happens. Passing `session=...` tells the runner to use that live sandbox, but not to close it for you. + +```python +sandbox = await client.create(manifest=agent.default_manifest) + +async with sandbox: + run_config = RunConfig(sandbox=SandboxRunConfig(session=sandbox)) + await Runner.run(agent, "Analyze the files.", run_config=run_config) + await Runner.run(agent, "Write the final report.", run_config=run_config) +``` + +The context manager is the usual shape: it starts the sandbox on entry and runs the session cleanup lifecycle on exit. If your app cannot use a context manager, call the lifecycle methods directly: + +```python +sandbox = await client.create( + manifest=agent.default_manifest, + snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshots")), +) +try: + await sandbox.start() + await Runner.run( + agent, + "Analyze the files.", + run_config=RunConfig(sandbox=SandboxRunConfig(session=sandbox)), + ) + # Persist a checkpoint of the live workspace before doing more work. + # `aclose()` also calls `stop()`, so this is only needed for an explicit mid-lifecycle save. + await sandbox.stop() +finally: + await sandbox.aclose() +``` + +`stop()` only persists snapshot-backed workspace contents; it does not tear down the sandbox. `aclose()` is the full session cleanup path: it runs pre-stop hooks, calls `stop()`, shuts down sandbox resources, and closes session-scoped dependencies. + +## `SandboxRunConfig` options + +[`SandboxRunConfig`][agents.run_config.SandboxRunConfig] holds the per-run options that decide where the sandbox session comes from and how a fresh session should be initialized. + +### Sandbox source + +These options decide whether the runner should reuse, resume, or create the sandbox session: + +
    + +| Option | Use it when | Notes | +| --- | --- | --- | +| `client` | You want the runner to create, resume, and clean up sandbox sessions for you. | Required unless you provide a live sandbox `session`. | +| `session` | You already created a live sandbox session yourself. | The caller owns lifecycle; the runner reuses that live sandbox session. | +| `session_state` | You have serialized sandbox session state but not a live sandbox session object. | Requires `client`; the runner resumes from that explicit state as an owning session. | + +
    + +In practice, the runner resolves the sandbox session in this order: + +1. If you inject `run_config.sandbox.session`, that live sandbox session is reused directly. +2. Otherwise, if the run is resuming from `RunState`, the stored sandbox session state is resumed. +3. Otherwise, if you pass `run_config.sandbox.session_state`, the runner resumes from that explicit serialized sandbox session state. +4. Otherwise, the runner creates a fresh sandbox session. For that fresh session, it uses `run_config.sandbox.manifest` when provided, or `agent.default_manifest` if not. + +### Fresh-session inputs + +These options only matter when the runner is creating a fresh sandbox session: + +
    + +| Option | Use it when | Notes | +| --- | --- | --- | +| `manifest` | You want a one-off fresh-session workspace override. | Falls back to `agent.default_manifest` when omitted. | +| `snapshot` | A fresh sandbox session should be seeded from a snapshot. | Useful for resume-like flows or remote snapshot clients. | +| `options` | The sandbox client needs creation-time options. | Common for Docker images, Modal app names, E2B templates, timeouts, and similar client-specific settings. | + +
    + +### Materialization controls + +`concurrency_limits` controls how much sandbox materialization work can run in parallel. Use `SandboxConcurrencyLimits(manifest_entries=..., local_dir_files=...)` when large manifests or local directory copies need tighter resource control. Set either value to `None` to disable that specific limit. + +A few implications are worth keeping in mind: + +- Fresh sessions: `manifest=` and `snapshot=` only apply when the runner is creating a fresh sandbox session. +- Resume vs snapshot: `session_state=` reconnects to previously serialized sandbox state, whereas `snapshot=` seeds a new sandbox session from saved workspace contents. +- Client-specific options: `options=` depends on the sandbox client; Docker and many hosted clients require it. +- Injected live sessions: if you pass a running sandbox `session`, capability-driven manifest updates can add compatible non-mount entries. They cannot change `manifest.root`, `manifest.environment`, `manifest.users`, or `manifest.groups`; remove existing entries; replace entry types; or add or change mount entries. +- Runner API: `SandboxAgent` execution still uses the normal `Runner.run()`, `Runner.run_sync()`, and `Runner.run_streamed()` APIs. + +## Full example: coding task + +This coding-style example is a good default starting point: + +```python +import asyncio +from pathlib import Path + +from agents import ModelSettings, Runner +from agents.run import RunConfig +from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig +from agents.sandbox.capabilities import ( + Capabilities, + LocalDirLazySkillSource, + Skills, +) +from agents.sandbox.entries import LocalDir +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +EXAMPLE_DIR = Path(__file__).resolve().parent +HOST_REPO_DIR = EXAMPLE_DIR / "repo" +HOST_SKILLS_DIR = EXAMPLE_DIR / "skills" +TARGET_TEST_CMD = "sh tests/test_credit_note.sh" + + +def build_agent(model: str) -> SandboxAgent[None]: + return SandboxAgent( + name="Sandbox engineer", + model=model, + instructions=( + "Inspect the repo, make the smallest correct change, run the most relevant checks, " + "and summarize the file changes and risks. " + "Read `repo/task.md` before editing files. Stay grounded in the repository, preserve " + "existing behavior, and mention the exact verification command you ran. " + "Use the `$credit-note-fixer` skill before editing files. If the repo lives under " + "`repo/`, remember that `apply_patch` paths stay relative to the sandbox workspace " + "root, so edits still target `repo/...`." + ), + # Put repos and task files in the manifest. + default_manifest=Manifest( + entries={ + "repo": LocalDir(src=HOST_REPO_DIR), + } + ), + capabilities=Capabilities.default() + [ + # Let Skills(...) stage and index sandbox-local skills for you. + Skills( + lazy_from=LocalDirLazySkillSource( + source=LocalDir(src=HOST_SKILLS_DIR), + ) + ), + ], + model_settings=ModelSettings(tool_choice="required"), + ) + + +async def main(model: str, prompt: str) -> None: + result = await Runner.run( + build_agent(model), + prompt, + run_config=RunConfig( + sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), + workflow_name="Sandbox coding example", + ), + ) + print(result.final_output) + + +if __name__ == "__main__": + asyncio.run( + main( + model="gpt-5.4", + prompt=( + "Open `repo/task.md`, use the `$credit-note-fixer` skill, fix the bug, " + f"run `{TARGET_TEST_CMD}`, and summarize the change." + ), + ) + ) +``` + +See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py). It uses a tiny shell-based repo so the example can be verified deterministically across Unix-local runs. Your real task repo can of course be Python, JavaScript, or anything else. + +## Common patterns + +Start from the full example above. In many cases, the same `SandboxAgent` can stay intact while only the sandbox client, sandbox-session source, or workspace source changes. + +### Switch sandbox clients + +Keep the agent definition the same and change only the run config. Use Docker when you want container isolation or image parity, or a hosted provider when you want provider-managed execution. See [Sandbox clients](clients.md) for examples and provider options. + +### Override the workspace + +Keep the agent definition the same and swap only the fresh-session manifest: + +```python +from agents.run import RunConfig +from agents.sandbox import Manifest, SandboxRunConfig +from agents.sandbox.entries import GitRepo +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +run_config = RunConfig( + sandbox=SandboxRunConfig( + client=UnixLocalSandboxClient(), + manifest=Manifest( + entries={ + "repo": GitRepo(repo="openai/openai-agents-python", ref="main"), + } + ), + ), +) +``` + +Use this when the same agent role should run against different repos, packets, or task bundles without rebuilding the agent. The validated coding example above shows the same pattern with `default_manifest` instead of a one-off override. + +### Inject a sandbox session + +Inject a live sandbox session when you need explicit lifecycle control, post-run inspection, or output copying: + +```python +from agents import Runner +from agents.run import RunConfig +from agents.sandbox import SandboxRunConfig +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +client = UnixLocalSandboxClient() +sandbox = await client.create(manifest=agent.default_manifest) + +async with sandbox: + result = await Runner.run( + agent, + prompt, + run_config=RunConfig( + sandbox=SandboxRunConfig(session=sandbox), + ), + ) +``` + +Use this when you want to inspect the workspace after the run or stream over an already-started sandbox session. See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) and [examples/sandbox/docker/docker_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py). + +### Resume from session state + +If you already serialized sandbox state outside `RunState`, let the runner reconnect from that state: + +```python +from agents.run import RunConfig +from agents.sandbox import SandboxRunConfig + +serialized = load_saved_payload() +restored_state = client.deserialize_session_state(serialized) + +run_config = RunConfig( + sandbox=SandboxRunConfig( + client=client, + session_state=restored_state, + ), +) +``` + +Use this when sandbox state lives in your own storage or job system and you want `Runner` to resume from it directly. See [examples/sandbox/extensions/blaxel_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/blaxel_runner.py) for the serialize/deserialize flow. + +### Start from a snapshot + +Seed a new sandbox from saved files and artifacts: + +```python +from pathlib import Path + +from agents.run import RunConfig +from agents.sandbox import LocalSnapshotSpec, SandboxRunConfig +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +run_config = RunConfig( + sandbox=SandboxRunConfig( + client=UnixLocalSandboxClient(), + snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshot")), + ), +) +``` + +Use this when a fresh run should start from saved workspace contents rather than only `agent.default_manifest`. See [examples/sandbox/memory.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory.py) for a local snapshot flow and [examples/sandbox/sandbox_agent_with_remote_snapshot.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agent_with_remote_snapshot.py) for a remote snapshot client. + +### Load skills from Git + +Swap the local skill source for a repository-backed one: + +```python +from agents.sandbox.capabilities import Capabilities, Skills +from agents.sandbox.entries import GitRepo + +capabilities = Capabilities.default() + [ + Skills(from_=GitRepo(repo="sdcoffey/tax-prep-skills", ref="main")), +] +``` + +Use this when the skills bundle has its own release cadence or should be shared across sandboxes. See [examples/sandbox/tax_prep.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/tax_prep.py). + +### Expose as tools + +Tool-agents can either get their own sandbox boundary or reuse a live sandbox from the parent run. Reuse is useful for a fast read-only explorer agent: it can inspect the exact workspace the parent is using without paying to create, hydrate, or snapshot another sandbox. + +```python +from agents import Runner +from agents.run import RunConfig +from agents.sandbox import FileMode, Manifest, Permissions, SandboxAgent, SandboxRunConfig, User +from agents.sandbox.entries import Dir, File +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +coordinator = User(name="coordinator") +explorer = User(name="explorer") + +manifest = Manifest( + users=[coordinator, explorer], + entries={ + "pricing_packet": Dir( + group=coordinator, + permissions=Permissions( + owner=FileMode.ALL, + group=FileMode.ALL, + other=FileMode.READ | FileMode.EXEC, + directory=True, + ), + children={ + "pricing.md": File( + content=b"Pricing packet contents...", + group=coordinator, + permissions=Permissions( + owner=FileMode.ALL, + group=FileMode.ALL, + other=FileMode.READ, + ), + ), + }, + ), + "work": Dir( + group=coordinator, + permissions=Permissions( + owner=FileMode.ALL, + group=FileMode.ALL, + other=FileMode.NONE, + directory=True, + ), + ), + }, +) + +pricing_explorer = SandboxAgent( + name="Pricing Explorer", + instructions="Read `pricing_packet/` and summarize commercial risk. Do not edit files.", + run_as=explorer, +) + +client = UnixLocalSandboxClient() +sandbox = await client.create(manifest=manifest) + +async with sandbox: + shared_run_config = RunConfig( + sandbox=SandboxRunConfig(session=sandbox), + ) + + orchestrator = SandboxAgent( + name="Revenue Operations Coordinator", + instructions="Coordinate the review and write final notes to `work/`.", + run_as=coordinator, + tools=[ + pricing_explorer.as_tool( + tool_name="review_pricing_packet", + tool_description="Inspect the pricing packet and summarize commercial risk.", + run_config=shared_run_config, + max_turns=2, + ), + ], + ) + + result = await Runner.run( + orchestrator, + "Review the pricing packet, then write final notes to `work/summary.md`.", + run_config=shared_run_config, + ) +``` + +Here the parent agent runs as `coordinator`, and the explorer tool-agent runs as `explorer` inside the same live sandbox session. The `pricing_packet/` entries are readable by `other` users, so the explorer can inspect them quickly, but it does not have write bits. The `work/` directory is only available to the coordinator's user/group, so the parent can write the final artifact while the explorer stays read-only. + +When a tool-agent needs real isolation instead, give it its own sandbox `RunConfig`: + +```python +from docker import from_env as docker_from_env + +from agents.run import RunConfig +from agents.sandbox import SandboxRunConfig +from agents.sandbox.sandboxes.docker import DockerSandboxClient, DockerSandboxClientOptions + +rollout_agent.as_tool( + tool_name="review_rollout_risk", + tool_description="Inspect the rollout packet and summarize implementation risk.", + run_config=RunConfig( + sandbox=SandboxRunConfig( + client=DockerSandboxClient(docker_from_env()), + options=DockerSandboxClientOptions(image="python:3.14-slim"), + ), + ), +) +``` + +Use a separate sandbox when the tool-agent should mutate freely, run untrusted commands, or use a different backend/image. See [examples/sandbox/sandbox_agents_as_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agents_as_tools.py). + +### Combine with local tools and MCP + +Keep the sandbox workspace while still using ordinary tools on the same agent: + +```python +from agents.sandbox import SandboxAgent +from agents.sandbox.capabilities import Shell + +agent = SandboxAgent( + name="Workspace reviewer", + instructions="Inspect the workspace and call host tools when needed.", + tools=[get_discount_approval_path], + mcp_servers=[server], + capabilities=[Shell()], +) +``` + +Use this when workspace inspection is only one part of the agent's job. See [examples/sandbox/sandbox_agent_with_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agent_with_tools.py). + +## Memory + +Use the `Memory` capability when future sandbox-agent runs should learn from prior runs. Memory is separate from the SDK's conversational `Session` memory: it distills lessons into files inside the sandbox workspace, then later runs can read those files. + +See [Agent memory](memory.md) for setup, read/generate behavior, multi-turn conversations, and layout isolation. + +## Composition patterns + +Once the single-agent pattern is clear, the next design question is where the sandbox boundary belongs in a larger system. + +Sandbox agents still compose with the rest of the SDK: + +- [Handoffs](../handoffs.md): hand document-heavy work from a non-sandbox intake agent into a sandbox reviewer. +- [Agents as tools](../tools.md#agents-as-tools): expose multiple sandbox agents as tools, usually by passing `run_config=RunConfig(sandbox=SandboxRunConfig(...))` on each `Agent.as_tool(...)` call so each tool gets its own sandbox boundary. +- [MCP](../mcp.md) and normal function tools: sandbox capabilities can coexist with `mcp_servers` and ordinary Python tools. +- [Running agents](../running_agents.md): sandbox runs still use the normal `Runner` APIs. + +Two patterns are especially common: + +- a non-sandbox agent hands off into a sandbox agent only for the part of the workflow that needs workspace isolation +- an orchestrator exposes multiple sandbox agents as tools, usually with a separate sandbox `RunConfig` per `Agent.as_tool(...)` call so each tool gets its own isolated workspace + +### Turns and sandbox runs + +It helps to explain handoffs and agent-as-tool calls separately. + +With a handoff, there is still one top-level run and one top-level turn loop. The active agent changes, but the run does not become nested. If a non-sandbox intake agent hands off to a sandbox reviewer, the next model call in that same run is prepared for the sandbox agent, and that sandbox agent becomes the one taking the next turn. In other words, handoffs change which agent owns the next turn of the same run. See [examples/sandbox/handoffs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/handoffs.py). + +With `Agent.as_tool(...)`, the relationship is different. The outer orchestrator uses one outer turn to decide to call the tool, and that tool call starts a nested run for the sandbox agent. The nested run has its own turn loop, `max_turns`, approvals, and usually its own sandbox `RunConfig`. It may finish in one nested turn or take several. From the outer orchestrator's point of view, all of that work still sits behind one tool invocation, so the nested turns do not increment the outer run's turn counter. See [examples/sandbox/sandbox_agents_as_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agents_as_tools.py). + +Approval behavior follows the same split: + +- with handoffs, approvals stay on the same top-level run because the sandbox agent is now the active agent in that run +- with `Agent.as_tool(...)`, approvals raised inside the sandbox tool-agent still surface on the outer run, but they come from stored nested run state and resume the nested sandbox run when the outer run resumes + +## Further reading + +- [Quickstart](quickstart.md): get one sandbox agent running. +- [Sandbox clients](clients.md): choose local, Docker, hosted, and mount options. +- [Agent memory](memory.md): preserve and reuse lessons from prior sandbox runs. +- [examples/sandbox/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox): runnable local, coding, memory, handoff, and agent-composition patterns. diff --git a/docs/zh/openai-agents/sandbox/memory.md b/docs/zh/openai-agents/sandbox/memory.md new file mode 100644 index 000000000..94086fcae --- /dev/null +++ b/docs/zh/openai-agents/sandbox/memory.md @@ -0,0 +1,185 @@ +# Agent memory + +Memory lets future sandbox-agent runs learn from prior runs. It is separate from the SDK's conversational [`Session`](../sessions/index.md) memory, which stores message history. Memory distills lessons from prior runs into files in the sandbox workspace. + +!!! warning "Beta feature" + + Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. + +Memory can reduce three kinds of cost for future runs: + +1. Agent cost: If the agent took a long time to complete a workflow, the next run should need less exploration. This can reduce token usage and time to completion. +2. User cost: If the user corrected the agent or expressed a preference, future runs can remember that feedback. This can reduce human intervention. +3. Context cost: If the agent completed a task before, and the user wants to build on that task, the user should not need to find the previous thread or re-type all the context. This makes task descriptions shorter. + +See [examples/sandbox/memory.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory.py) for a complete two-run example that fixes a bug, generates memory, resumes a snapshot, and uses that memory in a follow-up verifier run. See [examples/sandbox/memory_multi_agent_multiturn.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory_multi_agent_multiturn.py) for a multi-turn, multi-agent example with separate memory layouts. + +## Enable memory + +Add `Memory()` as a capability to the sandbox agent. + +```python +from pathlib import Path +import tempfile + +from agents.sandbox import LocalSnapshotSpec, SandboxAgent +from agents.sandbox.capabilities import Filesystem, Memory, Shell + +agent = SandboxAgent( + name="Memory-enabled reviewer", + instructions="Inspect the workspace and preserve useful lessons for follow-up runs.", + capabilities=[Memory(), Filesystem(), Shell()], +) + +with tempfile.TemporaryDirectory(prefix="sandbox-memory-example-") as snapshot_dir: + sandbox = await client.create( + manifest=manifest, + snapshot=LocalSnapshotSpec(base_path=Path(snapshot_dir)), + ) +``` + +If read is enabled, `Memory()` requires `Shell()`, which lets the agent read and search memory files when the injected summary is not enough. When live memory update is enabled (by default), it also requires `Filesystem()`, which lets the agent update `memories/MEMORY.md` if the agent discovers stale memory or the user asks it to update memory. + +By default, memory artifacts are stored in the sandbox workspace under `memories/`. To reuse them in a later run, preserve and reuse the whole configured memories directory by keeping the same live sandbox session or resuming from a persisted session state or snapshot; a fresh empty sandbox starts with empty memory. + +`Memory()` enables both reading and generating memories. Use `Memory(generate=None)` for agents that should read memory but should not generate new memories: for example, an internal agent, subagent, checker, or one-off tool agent whose run doesn't add much signal. Use `Memory(read=None)` when the run should generate memory for later, but the user doesn't want the run to be influenced by existing memory. + +## Read memory + +Memory reads use progressive disclosure. At the start of a run, the SDK injects a small summary (`memory_summary.md`) of generally useful tips, user preferences, and available memories into the agent's developer prompt. This gives the agent enough context to decide whether prior work may be relevant. + +When prior work looks relevant, the agent searches the configured memory index (`MEMORY.md` under `memories_dir`) for keywords from the current task. It opens the corresponding prior rollout summaries under the configured `rollout_summaries/` directory only when the task needs more detail. + +Memory can become stale. Agents are instructed to treat memories as guidance only and trust the current environment. By default, memory reads have `live_update` enabled, so if the agent discovers stale memory, it can update the configured `MEMORY.md` in the same run. Disable live updates when the agent should read memory but not modify it during the run, for example if the run is latency sensitive. + +## Generate memory + +After a run finishes, the sandbox runtime appends that run segment to a conversation file. Accumulated conversation files are processed when the sandbox session closes. + +Memory generation has two phases: + +1. Phase 1: conversation extraction. A memory-generating model processes one accumulated conversation file and generates a conversation summary. System, developer, and reasoning content are omitted. If the conversation is too long, it is truncated to fit within the context window, with the beginning and end preserved. It also generates a raw memory extract: compact notes from the conversation that Phase 2 can consolidate. +2. Phase 2: layout consolidation. A consolidation agent reads raw memories for one memory layout, opens conversation summaries when more evidence is needed, and extracts patterns into `MEMORY.md` and `memory_summary.md`. + +The default workspace layout is: + +```text +workspace/ +├── sessions/ +│ └── .jsonl +└── memories/ + ├── memory_summary.md + ├── MEMORY.md + ├── raw_memories.md (intermediate) + ├── phase_two_selection.json (intermediate) + ├── raw_memories/ (intermediate) + │ └── .md + ├── rollout_summaries/ + │ └── _.md + └── skills/ +``` + +You can configure memory generation with `MemoryGenerateConfig`: + +```python +from agents.sandbox import MemoryGenerateConfig +from agents.sandbox.capabilities import Memory + +memory = Memory( + generate=MemoryGenerateConfig( + max_raw_memories_for_consolidation=128, + extra_prompt="Pay extra attention to what made the customer more satisfied or annoyed", + ), +) +``` + +Use `extra_prompt` to tell the memory generator which signals matter most for your use case, such as customer and company details for a GTM agent. + +If recent raw memories exceed `max_raw_memories_for_consolidation` (defaults to 256), Phase 2 keeps only memories from the newest conversations and removes older ones. Recency is based on the last time the conversation is updated. This forgetting mechanism helps memories reflect the newest environment. + +## Multi-turn conversations + +For multi-turn sandbox chats, use the normal SDK `Session` together with the same live sandbox session: + +```python +from agents import Runner, SQLiteSession +from agents.run import RunConfig +from agents.sandbox import SandboxRunConfig + +conversation_session = SQLiteSession("gtm-q2-pipeline-review") +sandbox = await client.create(manifest=agent.default_manifest) + +async with sandbox: + run_config = RunConfig( + sandbox=SandboxRunConfig(session=sandbox), + workflow_name="GTM memory example", + ) + await Runner.run( + agent, + "Analyze data/leads.csv and identify one promising GTM segment.", + session=conversation_session, + run_config=run_config, + ) + await Runner.run( + agent, + "Using that analysis, write a short outreach hypothesis.", + session=conversation_session, + run_config=run_config, + ) +``` + +Both runs append to one memory conversation file because they pass the same SDK conversation session (`session=conversation_session`) and therefore share the same `session.session_id`. This is different from the sandbox (`sandbox`), which identifies the live workspace and is not used as the memory conversation ID. Phase 1 sees the accumulated conversation when the sandbox session closes, so it can extract memory from the whole exchange instead of two isolated turns. + +If you want multiple `Runner.run(...)` calls to become one memory conversation, pass a stable identifier across those calls. When memory associates a run with a conversation, it resolves in this order: + +1. `conversation_id`, when you pass one to `Runner.run(...)` +2. `session.session_id`, when you pass an SDK `Session` such as `SQLiteSession` +3. `RunConfig.group_id`, when neither of the above is present +4. A generated per-run ID, when no stable identifier is present + +## Use different layouts to isolate memory for different agents + +Memory isolation is based on `MemoryLayoutConfig`, not on agent name. Agents with the same layout and the same memory conversation ID share one memory conversation and one consolidated memory. Agents with different layouts keep separate rollout files, raw memories, `MEMORY.md`, and `memory_summary.md`, even when they share the same sandbox workspace. + +Use separate layouts when multiple agents share one sandbox but should not share memory: + +```python +from agents import SQLiteSession +from agents.sandbox import MemoryLayoutConfig, SandboxAgent +from agents.sandbox.capabilities import Filesystem, Memory, Shell + +gtm_agent = SandboxAgent( + name="GTM reviewer", + instructions="Analyze GTM workspace data and write concise recommendations.", + capabilities=[ + Memory( + layout=MemoryLayoutConfig( + memories_dir="memories/gtm", + sessions_dir="sessions/gtm", + ) + ), + Filesystem(), + Shell(), + ], +) + +engineering_agent = SandboxAgent( + name="Engineering reviewer", + instructions="Inspect engineering workspaces and summarize fixes and risks.", + capabilities=[ + Memory( + layout=MemoryLayoutConfig( + memories_dir="memories/engineering", + sessions_dir="sessions/engineering", + ) + ), + Filesystem(), + Shell(), + ], +) + +gtm_session = SQLiteSession("gtm-q2-pipeline-review") +engineering_session = SQLiteSession("eng-invoice-test-fix") +``` + +This prevents GTM analysis from being consolidated into engineering bug-fix memory, and vice versa. diff --git a/docs/zh/openai-agents/sandbox_agents.md b/docs/zh/openai-agents/sandbox_agents.md new file mode 100644 index 000000000..e4c91074d --- /dev/null +++ b/docs/zh/openai-agents/sandbox_agents.md @@ -0,0 +1,111 @@ +# Quickstart + +!!! warning "Beta feature" + + Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. + +Modern agents work best when they can operate on real files in a filesystem. **Sandbox Agents** in the Agents SDK give the model a persistent workspace where it can search large document sets, edit files, run commands, generate artifacts, and pick work back up from saved sandbox state. + +The SDK gives you that execution harness without making you wire together file staging, filesystem tools, shell access, sandbox lifecycle, snapshots, and provider-specific glue yourself. You keep the normal `Agent` and `Runner` flow, then add a `Manifest` for the workspace, capabilities for sandbox-native tools, and `SandboxRunConfig` for where the work runs. + +## Prerequisites + +- Python 3.10 or higher +- Basic familiarity with the OpenAI Agents SDK +- A sandbox client. For local development, start with `UnixLocalSandboxClient`. + +## Installation + +If you have not already installed the SDK: + +```bash +pip install openai-agents +``` + +For Docker-backed sandboxes: + +```bash +pip install "openai-agents[docker]" +``` + +## Create a local sandbox agent + +This example stages a local repo under `repo/`, loads local skills lazily, and lets the runner create a Unix-local sandbox session for the run. + +```python +import asyncio +from pathlib import Path + +from agents import Runner +from agents.run import RunConfig +from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig +from agents.sandbox.capabilities import Capabilities, LocalDirLazySkillSource, Skills +from agents.sandbox.entries import LocalDir +from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient + +EXAMPLE_DIR = Path(__file__).resolve().parent +HOST_REPO_DIR = EXAMPLE_DIR / "repo" +HOST_SKILLS_DIR = EXAMPLE_DIR / "skills" + + +def build_agent(model: str) -> SandboxAgent[None]: + return SandboxAgent( + name="Sandbox engineer", + model=model, + instructions=( + "Read `repo/task.md` before editing files. Stay grounded in the repository, preserve " + "existing behavior, and mention the exact verification command you ran. " + "If you edit files with apply_patch, paths are relative to the sandbox workspace root." + ), + default_manifest=Manifest( + entries={ + "repo": LocalDir(src=HOST_REPO_DIR), + } + ), + capabilities=Capabilities.default() + [ + Skills( + lazy_from=LocalDirLazySkillSource( + source=LocalDir(src=HOST_SKILLS_DIR), + ) + ), + ], + ) + + +async def main() -> None: + result = await Runner.run( + build_agent("gpt-5.4"), + "Open `repo/task.md`, fix the issue, run the targeted test, and summarize the change.", + run_config=RunConfig( + sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), + workflow_name="Sandbox coding example", + ), + ) + print(result.final_output) + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py). It uses a tiny shell-based repo so the example can be verified deterministically across Unix-local runs. + +## Key choices + +Once the basic run works, the choices most people reach for next are: + +- `default_manifest`: the files, repos, directories, and mounts for fresh sandbox sessions +- `instructions`: short workflow rules that should apply across prompts +- `base_instructions`: an advanced escape hatch for replacing the SDK sandbox prompt +- `capabilities`: sandbox-native tools such as filesystem editing/image inspection, shell, skills, memory, and compaction +- `run_as`: the sandbox user identity for model-facing tools +- `SandboxRunConfig.client`: the sandbox backend +- `SandboxRunConfig.session`, `session_state`, or `snapshot`: how later runs reconnect to prior work + +## Where to go next + +- [Concepts](sandbox/guide.md): understand manifests, capabilities, permissions, snapshots, run config, and composition patterns. +- [Sandbox clients](sandbox/clients.md): choose Unix-local, Docker, hosted providers, and mount strategies. +- [Agent memory](sandbox/memory.md): preserve and reuse lessons from previous sandbox runs. + +If shell access is only one occasional tool, start with hosted shell in the [tools guide](tools.md). Reach for sandbox agents when workspace isolation, sandbox client choice, or sandbox-session resume behavior are part of the design. From 3ee52eed5fbfeab6cf9a19832c13e6672fd1ed94 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 08:46:18 +0800 Subject: [PATCH 10/28] update docs --- docs/zh/openai-agents/sandbox/clients.md | 137 ---- docs/zh/openai-agents/sandbox/guide.md | 832 ----------------------- docs/zh/openai-agents/sandbox/memory.md | 185 ----- docs/zh/openai-agents/sandbox_agents.md | 111 --- 4 files changed, 1265 deletions(-) delete mode 100644 docs/zh/openai-agents/sandbox/clients.md delete mode 100644 docs/zh/openai-agents/sandbox/guide.md delete mode 100644 docs/zh/openai-agents/sandbox/memory.md delete mode 100644 docs/zh/openai-agents/sandbox_agents.md diff --git a/docs/zh/openai-agents/sandbox/clients.md b/docs/zh/openai-agents/sandbox/clients.md deleted file mode 100644 index 683e8bc47..000000000 --- a/docs/zh/openai-agents/sandbox/clients.md +++ /dev/null @@ -1,137 +0,0 @@ -# Sandbox clients - -Use this page to choose where sandbox work should run. In most cases, the `SandboxAgent` definition stays the same while the sandbox client and client-specific options change in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. - -!!! warning "Beta feature" - - Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. - -## Decision guide - -
    - -| Goal | Start with | Why | -| --- | --- | --- | -| Fastest local iteration on macOS or Linux | `UnixLocalSandboxClient` | No extra install, simple local filesystem development. | -| Basic container isolation | `DockerSandboxClient` | Runs work inside Docker with a specific image. | -| Hosted execution or production-style isolation | A hosted sandbox client | Moves the workspace boundary to a provider-managed environment. | - -
    - -## Local clients - -For most users, start with one of these two sandbox clients: - -
    - -| Client | Install | Choose it when | Example | -| --- | --- | --- | --- | -| `UnixLocalSandboxClient` | none | Fastest local iteration on macOS or Linux. Good default for local development. | [Unix-local starter](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/unix_local_runner.py) | -| `DockerSandboxClient` | `openai-agents[docker]` | You want container isolation or a specific image for local parity. | [Docker starter](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py) | - -
    - -Unix-local is the easiest way to start developing against a local filesystem. Move to Docker or a hosted provider when you need stronger environment isolation or production-style parity. - -To switch from Unix-local to Docker, keep the agent definition the same and change only the run config: - -```python -from docker import from_env as docker_from_env - -from agents.run import RunConfig -from agents.sandbox import SandboxRunConfig -from agents.sandbox.sandboxes.docker import DockerSandboxClient, DockerSandboxClientOptions - -run_config = RunConfig( - sandbox=SandboxRunConfig( - client=DockerSandboxClient(docker_from_env()), - options=DockerSandboxClientOptions(image="python:3.14-slim"), - ), -) -``` - -Use this when you want container isolation or image parity. See [examples/sandbox/docker/docker_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py). - -## Mounts and remote storage - -Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. Import the built-in mount entries and generic strategies from `agents.sandbox.entries`. Hosted-provider strategies are available from `agents.extensions.sandbox` or the provider-specific extension package. - -Common mount options: - -- `mount_path`: where the storage appears in the sandbox. Relative paths are resolved under the manifest root; absolute paths are used as-is. -- `read_only`: defaults to `True`. Set `False` only when the sandbox should write back to the mounted storage. -- `mount_strategy`: required. Use a strategy that matches both the mount entry and the sandbox backend. - -Mounts are treated as ephemeral workspace entries. Snapshot and persistence flows detach or skip mounted paths instead of copying mounted remote storage into the saved workspace. - -Generic local/container strategies: - -
    - -| Strategy or pattern | Use it when | Notes | -| --- | --- | --- | -| `InContainerMountStrategy(pattern=RcloneMountPattern(...))` | The sandbox image can run `rclone`. | Supports S3, GCS, R2, and Azure Blob. `RcloneMountPattern` can run in `fuse` mode or `nfs` mode. | -| `InContainerMountStrategy(pattern=MountpointMountPattern(...))` | The image has `mount-s3` and you want Mountpoint-style S3 or S3-compatible access. | Supports `S3Mount` and `GCSMount`. | -| `InContainerMountStrategy(pattern=FuseMountPattern(...))` | The image has `blobfuse2` and FUSE support. | Supports `AzureBlobMount`. | -| `InContainerMountStrategy(pattern=S3FilesMountPattern(...))` | The image has `mount.s3files` and can reach an existing S3 Files mount target. | Supports `S3FilesMount`. | -| `DockerVolumeMountStrategy(driver=...)` | Docker should attach a volume-driver-backed mount before the container starts. | Docker-only. S3, GCS, R2, and Azure Blob support `rclone`; S3 and GCS also support `mountpoint`. | - -
    - -## Supported hosted platforms - -When you need a hosted environment, the same `SandboxAgent` definition usually carries over and only the sandbox client changes in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. - -If you are using the published SDK instead of this repository checkout, install sandbox-client dependencies through the matching package extra. - -For provider-specific setup notes and links for the checked-in extension examples, see [examples/sandbox/extensions/README.md](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/README.md). - -
    - -| Client | Install | Example | -| --- | --- | --- | -| `BlaxelSandboxClient` | `openai-agents[blaxel]` | [Blaxel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/blaxel_runner.py) | -| `CloudflareSandboxClient` | `openai-agents[cloudflare]` | [Cloudflare runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/cloudflare_runner.py) | -| `DaytonaSandboxClient` | `openai-agents[daytona]` | [Daytona runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/daytona/daytona_runner.py) | -| `E2BSandboxClient` | `openai-agents[e2b]` | [E2B runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/e2b_runner.py) | -| `ModalSandboxClient` | `openai-agents[modal]` | [Modal runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/modal_runner.py) | -| `RunloopSandboxClient` | `openai-agents[runloop]` | [Runloop runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/runloop/runner.py) | -| `VercelSandboxClient` | `openai-agents[vercel]` | [Vercel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/vercel_runner.py) | - -
    - -Hosted sandbox clients expose provider-specific mount strategies. Choose the backend and mount strategy that best fit your storage provider: - -
    - -| Backend | Mount notes | -| --- | --- | -| Docker | Supports `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `S3FilesMount` with local strategies such as `InContainerMountStrategy` and `DockerVolumeMountStrategy`. | -| `ModalSandboxClient` | Supports Modal cloud bucket mounts with `ModalCloudBucketMountStrategy` on `S3Mount`, `R2Mount`, and HMAC-authenticated `GCSMount`. You can use inline credentials or a named Modal Secret. | -| `CloudflareSandboxClient` | Supports Cloudflare bucket mounts with `CloudflareBucketMountStrategy` on `S3Mount`, `R2Mount`, and HMAC-authenticated `GCSMount`. | -| `BlaxelSandboxClient` | Supports cloud bucket mounts with `BlaxelCloudBucketMountStrategy` on `S3Mount`, `R2Mount`, and `GCSMount`. Also supports persistent Blaxel Drives with `BlaxelDriveMount` and `BlaxelDriveMountStrategy` from `agents.extensions.sandbox.blaxel`. | -| `DaytonaSandboxClient` | Supports cloud bucket mounts with `DaytonaCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | -| `E2BSandboxClient` | Supports cloud bucket mounts with `E2BCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | -| `RunloopSandboxClient` | Supports cloud bucket mounts with `RunloopCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, and `AzureBlobMount`. | -| `VercelSandboxClient` | No hosted-specific mount strategy is currently exposed. Use manifest files, repos, or other workspace inputs instead. | - -
    - -The table below summarizes which remote storage entries each backend can mount directly. - -
    - -| Backend | AWS S3 | Cloudflare R2 | GCS | Azure Blob Storage | S3 Files | -| --- | --- | --- | --- | --- | --- | -| Docker | ✓ | ✓ | ✓ | ✓ | ✓ | -| `ModalSandboxClient` | ✓ | ✓ | ✓ | - | - | -| `CloudflareSandboxClient` | ✓ | ✓ | ✓ | - | - | -| `BlaxelSandboxClient` | ✓ | ✓ | ✓ | - | - | -| `DaytonaSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | -| `E2BSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | -| `RunloopSandboxClient` | ✓ | ✓ | ✓ | ✓ | - | -| `VercelSandboxClient` | - | - | - | - | - | - -
    - -For more runnable examples, browse [examples/sandbox/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox) for local, coding, memory, handoff, and agent-composition patterns, and [examples/sandbox/extensions/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox/extensions) for hosted sandbox clients. diff --git a/docs/zh/openai-agents/sandbox/guide.md b/docs/zh/openai-agents/sandbox/guide.md deleted file mode 100644 index a6f9b31f9..000000000 --- a/docs/zh/openai-agents/sandbox/guide.md +++ /dev/null @@ -1,832 +0,0 @@ -# Concepts - -!!! warning "Beta feature" - - Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. - -Modern agents work best when they can operate on real files in a filesystem. **Sandbox Agents** can make use of specialized tools and shell commands to search over and manipulate large document sets, edit files, generate artifacts, and run commands. The sandbox provides the model with a persistent workspace that the agent can use to do work on your behalf. Sandbox Agents in the Agents SDK help you easily run agents paired with a sandbox environment, making it easy to get the right files on the filesystem and orchestrate the sandboxes to make it easy to start, stop, and resume tasks at scale. - -You define the workspace around the data the agent needs. It can start from GitHub repos, local files and directories, synthetic task files, remote filesystems such as S3 or Azure Blob Storage, and other sandbox inputs you provide. - -
    - -![Sandbox agent harness with compute](../assets/images/harness_with_compute.png) - -
    - -`SandboxAgent` is still an `Agent`. It keeps the usual agent surface such as `instructions`, `prompt`, `tools`, `handoffs`, `mcp_servers`, `model_settings`, `output_type`, guardrails, and hooks, and it still runs through the normal `Runner` APIs. What changes is the execution boundary: - -- `SandboxAgent` defines the agent itself: the usual agent configuration plus sandbox-specific defaults like `default_manifest`, `base_instructions`, `run_as`, and capabilities such as filesystem tools, shell access, skills, memory, or compaction. -- `Manifest` declares the desired starting contents and layout for a fresh sandbox workspace, including files, repos, mounts, and environment. -- A sandbox session is the live isolated environment where commands run and files change. -- [`SandboxRunConfig`][agents.run_config.SandboxRunConfig] decides how the run gets that sandbox session, for example by injecting one directly, reconnecting from serialized sandbox session state, or creating a fresh sandbox session through a sandbox client. -- Saved sandbox state and snapshots let later runs reconnect to prior work or seed a fresh sandbox session from saved contents. - -`Manifest` is the fresh-session workspace contract, not the full source of truth for every live sandbox. The effective workspace for a run can instead come from a reused sandbox session, serialized sandbox session state, or a snapshot chosen at run time. - -Throughout this page, "sandbox session" means the live execution environment managed by a sandbox client. It is different from the SDK's conversational [`Session`][agents.memory.session.Session] interfaces described in [Sessions](../sessions/index.md). - -The outer runtime still owns approvals, tracing, handoffs, and resume bookkeeping. The sandbox session owns commands, file changes, and environment isolation. That split is a core part of the model. - -### How the pieces fit together - -A sandbox run combines an agent definition with per-run sandbox configuration. The runner prepares the agent, binds it to a live sandbox session, and can save state for later runs. - -```mermaid -flowchart LR - agent["SandboxAgent
    full Agent + sandbox defaults"] - config["SandboxRunConfig
    client / session / resume inputs"] - runner["Runner
    prepare instructions
    bind capability tools
    "] - sandbox["sandbox session
    workspace where commands run
    and files change
    "] - saved["saved state / snapshot
    for resume or fresh-start later"] - - agent --> runner - config --> runner - runner --> sandbox - sandbox --> saved -``` - -Sandbox-specific defaults stay on `SandboxAgent`. Per-run sandbox-session choices stay in `SandboxRunConfig`. - -Think about the lifecycle in three phases: - -1. Define the agent and the fresh-workspace contract with `SandboxAgent`, `Manifest`, and capabilities. -2. Execute a run by giving `Runner` a `SandboxRunConfig` that injects, resumes, or creates the sandbox session. -3. Continue later from runner-managed `RunState`, explicit sandbox `session_state`, or a saved workspace snapshot. - -If shell access is only one occasional tool, start with hosted shell in the [tools guide](../tools.md). Reach for sandbox agents when workspace isolation, sandbox client choice, or sandbox-session resume behavior are part of the design. - -## When to use them - -Sandbox agents are a good fit for workspace-centric workflows, for example: - -- coding and debugging, for example orchestrating automated fixes for issue reports in a GitHub repo and running targeted tests -- document processing and editing, for example extracting information from a user's financial documents and creating a completed tax-form draft -- file-grounded review or analysis, for example checking onboarding packets, generated reports, or artifact bundles before answering -- isolated multi-agent patterns, for example giving each reviewer or coding sub-agent its own workspace -- multi-step workspace tasks, for example fixing a bug in one run and adding a regression test later, or resuming from snapshot or sandbox session state - -If you do not need access to files or a living filesystem, keep using `Agent`. If shell access is just one occasional capability, add hosted shell; if the workspace boundary itself is part of the feature, use sandbox agents. - -## Choose a sandbox client - -Start with `UnixLocalSandboxClient` for local development. Move to `DockerSandboxClient` when you need container isolation or image parity. Move to a hosted provider when you need provider-managed execution. - -In most cases, the `SandboxAgent` definition stays the same while the sandbox client and its options change in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig]. See [Sandbox clients](clients.md) for local, Docker, hosted, and remote-mount options. - -## Core pieces - -
    - -| Layer | Main SDK pieces | What it answers | -| --- | --- | --- | -| Agent definition | `SandboxAgent`, `Manifest`, capabilities | What agent will run, and what fresh-session workspace contract should it start from? | -| Sandbox execution | `SandboxRunConfig`, the sandbox client, and the live sandbox session | How does this run get a live sandbox session, and where does the work execute? | -| Saved sandbox state | `RunState` sandbox payload, `session_state`, and snapshots | How does this workflow reconnect to prior sandbox work or seed a fresh sandbox session from saved contents? | - -
    - -The main SDK pieces map onto those layers like this: - -
    - -| Piece | What it owns | Ask this question | -| --- | --- | --- | -| [`SandboxAgent`][agents.sandbox.sandbox_agent.SandboxAgent] | The agent definition | What should this agent do, and which defaults should travel with it? | -| [`Manifest`][agents.sandbox.manifest.Manifest] | Fresh-session workspace files and folders | What files and folder should be present on the filesystem when the run starts? | -| [`Capability`][agents.sandbox.capabilities.capability.Capability] | Sandbox-native behavior | Which tools, instruction fragments, or runtime behavior should attach to this agent? | -| [`SandboxRunConfig`][agents.run_config.SandboxRunConfig] | Per-run sandbox client and sandbox-session source | Should this run inject, resume, or create a sandbox session? | -| [`RunState`][agents.run_state.RunState] | Runner-managed saved sandbox state | Am I resuming a prior runner-managed workflow and carrying its sandbox state forward automatically? | -| [`SandboxRunConfig.session_state`][agents.run_config.SandboxRunConfig.session_state] | Explicit serialized sandbox session state | Do I want to resume from sandbox state I already serialized outside `RunState`? | -| [`SandboxRunConfig.snapshot`][agents.run_config.SandboxRunConfig.snapshot] | Saved workspace contents for fresh sandbox sessions | Should a new sandbox session start from saved files and artifacts? | - -
    - -A practical design order is: - -1. Define the fresh-session workspace contract with `Manifest`. -2. Define the agent with `SandboxAgent`. -3. Add built-in or custom capabilities. -4. Decide how each run should obtain its sandbox session in `RunConfig(sandbox=SandboxRunConfig(...))`. - -## How a sandbox run is prepared - -At run time, the runner turns that definition into a concrete sandbox-backed run: - -1. It resolves the sandbox session from `SandboxRunConfig`. - If you pass `session=...`, it reuses that live sandbox session. - Otherwise it uses `client=...` to create or resume one. -2. It determines the effective workspace inputs for the run. - If the run injects or resumes a sandbox session, that existing sandbox state wins. - Otherwise the runner starts from a one-off manifest override or `agent.default_manifest`. - This is why `Manifest` alone does not define the final live workspace for every run. -3. It lets capabilities process the resulting manifest. - This is how capabilities can add files, mounts, or other workspace-scoped behavior before the final agent is prepared. -4. It builds the final instructions in a fixed order: - the SDK's default sandbox prompt, or `base_instructions` if you explicitly override it, then `instructions`, then capability instruction fragments, then any remote-mount policy text, then a rendered filesystem tree. -5. It binds capability tools to the live sandbox session and runs the prepared agent through the normal `Runner` APIs. - -Sandboxing does not change what a turn means. A turn is still a model step, not a single shell command or sandbox action. There is no fixed 1:1 mapping between sandbox-side operations and turns: some work may stay inside the sandbox execution layer, while other actions return tool results, approvals, or other state that requires another model step. As a practical rule, another turn is consumed only when the agent runtime needs another model response after sandbox work has happened. - -Those preparation steps are why `default_manifest`, `instructions`, `base_instructions`, `capabilities`, and `run_as` are the main sandbox-specific options to think about when designing a `SandboxAgent`. - -## `SandboxAgent` options - -These are the sandbox-specific options on top of the usual `Agent` fields: - -
    - -| Option | Best use | -| --- | --- | -| `default_manifest` | The default workspace for fresh sandbox sessions created by the runner. | -| `instructions` | Additional role, workflow, and success criteria appended after the SDK sandbox prompt. | -| `base_instructions` | Advanced escape hatch that replaces the SDK sandbox prompt. | -| `capabilities` | Sandbox-native tools and behavior that should travel with this agent. | -| `run_as` | User identity for model-facing sandbox tools such as shell commands, file reads, and patches. | - -
    - -Sandbox client choice, sandbox-session reuse, manifest override, and snapshot selection belong in [`SandboxRunConfig`][agents.run_config.SandboxRunConfig], not on the agent. - -### `default_manifest` - -`default_manifest` is the default [`Manifest`][agents.sandbox.manifest.Manifest] used when the runner creates a fresh sandbox session for this agent. Use it for the files, repos, helper material, output directories, and mounts the agent should usually start with. - -This is only the default. A run can override it with `SandboxRunConfig(manifest=...)`, and a reused or resumed sandbox session keeps its existing workspace state. - -### `instructions` and `base_instructions` - -Use `instructions` for short rules that should survive different prompts. In a `SandboxAgent`, these instructions are appended after the SDK's sandbox base prompt, so you keep the built-in sandbox guidance and add your own role, workflow, and success criteria. - -Use `base_instructions` only when you want to replace the SDK sandbox base prompt. Most agents should not set it. - -
    - -| Put it in... | Use it for | Examples | -| --- | --- | --- | -| `instructions` | Stable role, workflow rules, and success criteria for the agent. | "Inspect onboarding documents, then hand off.", "Write final files into `output/`." | -| `base_instructions` | A full replacement for the SDK sandbox base prompt. | Custom low-level sandbox wrapper prompts. | -| the user prompt | The one-off request for this run. | "Summarize this workspace." | -| workspace files in the manifest | Longer task specs, repo-local instructions, or bounded reference material. | `repo/task.md`, document bundles, sample packets. | - -
    - -Good uses for `instructions` include: - -- [examples/sandbox/unix_local_pty.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/unix_local_pty.py) keeps the agent in one interactive process when PTY state matters. -- [examples/sandbox/handoffs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/handoffs.py) forbids the sandbox reviewer from answering the user directly after inspection. -- [examples/sandbox/tax_prep.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/tax_prep.py) requires the final filled files to actually land in `output/`. -- [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) pins the exact verification command and clarifies workspace-root-relative patch paths. - -Avoid copying the user's one-off task into `instructions`, embedding long reference material that belongs in the manifest, restating tool docs that built-in capabilities already inject, or mixing in local installation notes the model does not need at run time. - -If you omit `instructions`, the SDK still includes the default sandbox prompt. That is enough for low-level wrappers, but most user-facing agents should still provide explicit `instructions`. - -### `capabilities` - -Capabilities attach sandbox-native behavior to a `SandboxAgent`. They can shape the workspace before a run starts, append sandbox-specific instructions, expose tools that bind to the live sandbox session, and adjust model behavior or input handling for that agent. - -Built-in capabilities include: - -
    - -| Capability | Add it when | Notes | -| --- | --- | --- | -| `Shell` | The agent needs shell access. | Adds `exec_command`, plus `write_stdin` when the sandbox client supports PTY interaction. | -| `Filesystem` | The agent needs to edit files or inspect local images. | Adds `apply_patch` and `view_image`; patch paths are workspace-root-relative. | -| `Skills` | You want skill discovery and materialization in the sandbox. | Prefer this over mounting `.agents` or `.agents/skills` manually for sandbox-local `SKILL.md` skills. | -| `Memory` | Follow-on runs should read or generate memory artifacts. | Requires `Shell`; live updates also require `Filesystem`. | -| `Compaction` | Long-running flows need context trimming after compaction items. | Adjusts model sampling and input handling. | - -
    - -By default, `SandboxAgent.capabilities` uses `Capabilities.default()`, which includes `Filesystem()`, `Shell()`, and `Compaction()`. If you pass `capabilities=[...]`, that list replaces the default, so include any default capabilities you still want. - -For skills, choose the source based on how you want them materialized: - -- `Skills(lazy_from=LocalDirLazySkillSource(...))` is a good default for larger local skill directories because the model can discover the index first and load only what it needs. -- `Skills(from_=LocalDir(src=...))` is better for a small local bundle you want staged up front. -- `Skills(from_=GitRepo(repo=..., ref=...))` is the right fit when the skills themselves should come from a repository. - -If your skills already live on disk under something like `.agents/skills//SKILL.md`, point `LocalDir(...)` at that source root and still use `Skills(...)` to expose them. Keep the default `skills_path=".agents"` unless you have an existing workspace contract that depends on a different in-sandbox layout. - -Prefer built-in capabilities when they fit. Write a custom capability only when you need a sandbox-specific tool or instruction surface that the built-ins do not cover. - -## Concepts - -### Manifest - -A [`Manifest`][agents.sandbox.manifest.Manifest] describes the workspace for a fresh sandbox session. It can set the workspace `root`, declare files and directories, copy in local files, clone Git repos, attach remote storage mounts, set environment variables, and define users or groups. - -Manifest entry paths are workspace-relative. They cannot be absolute paths or escape the workspace with `..`, which keeps the workspace contract portable across local, Docker, and hosted clients. - -Use manifest entries for the material the agent needs before work begins: - -
    - -| Manifest entry | Use it for | -| --- | --- | -| `File`, `Dir` | Small synthetic inputs, helper files, or output directories. | -| `LocalFile`, `LocalDir` | Host files or directories that should be materialized into the sandbox. | -| `GitRepo` | A repository that should be fetched into the workspace. | -| mounts such as `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, `S3FilesMount` | External storage that should appear inside the sandbox. | - -
    - -Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. See [Sandbox clients](clients.md#mounts-and-remote-storage) for mount options and provider support. - -Good manifest design usually means keeping the workspace contract narrow, putting long task recipes in workspace files such as `repo/task.md`, and using relative workspace paths in instructions, for example `repo/task.md` or `output/report.md`. If the agent edits files with the `Filesystem` capability's `apply_patch` tool, remember that patch paths are relative to the sandbox workspace root, not the shell `workdir`. - -### Permissions - -`Permissions` controls filesystem permissions for manifest entries. It is about the files the sandbox materializes, not model permissions, approval policy, or API credentials. - -By default, manifest entries are owner-readable/writable/executable and readable/executable by group and others. Override this when staged files should be private, read-only, or executable: - -```python -from agents.sandbox import FileMode, Permissions -from agents.sandbox.entries import File - -private_notes = File( - text="internal notes", - permissions=Permissions( - owner=FileMode.READ | FileMode.WRITE, - group=FileMode.NONE, - other=FileMode.NONE, - ), -) -``` - -`Permissions` stores separate owner, group, and other bits, plus whether the entry is a directory. You can build it directly, parse it from a mode string with `Permissions.from_str(...)`, or derive it from an OS mode with `Permissions.from_mode(...)`. - -Users are the sandbox identities that can execute work. Add a `User` to the manifest when you want that identity to exist in the sandbox, then set `SandboxAgent.run_as` when model-facing sandbox tools such as shell commands, file reads, and patches should run as that user. If `run_as` points at a user that is not already in the manifest, the runner adds it to the effective manifest for you. - -```python -from agents import Runner -from agents.run import RunConfig -from agents.sandbox import FileMode, Manifest, Permissions, SandboxAgent, SandboxRunConfig, User -from agents.sandbox.entries import Dir, LocalDir -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -analyst = User(name="analyst") - -agent = SandboxAgent( - name="Dataroom analyst", - instructions="Review the files in `dataroom/` and write findings to `output/`.", - default_manifest=Manifest( - # Declare the sandbox user so manifest entries can grant access to it. - users=[analyst], - entries={ - "dataroom": LocalDir( - src="./dataroom", - # Let the analyst traverse and read the mounted dataroom, but not edit it. - group=analyst, - permissions=Permissions( - owner=FileMode.READ | FileMode.EXEC, - group=FileMode.READ | FileMode.EXEC, - other=FileMode.NONE, - ), - ), - "output": Dir( - # Give the analyst a writable scratch/output directory for artifacts. - group=analyst, - permissions=Permissions( - owner=FileMode.ALL, - group=FileMode.ALL, - other=FileMode.NONE, - ), - ), - }, - ), - # Run model-facing sandbox actions as this user, so those permissions apply. - run_as=analyst, -) - -result = await Runner.run( - agent, - "Summarize the contracts and call out renewal dates.", - run_config=RunConfig( - sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), - ), -) -``` - -If you also need file-level sharing rules, combine users with manifest groups and entry `group` metadata. The `run_as` user controls who executes sandbox-native actions; `Permissions` controls which files that user can read, write, or execute once the sandbox has materialized the workspace. - -### SnapshotSpec - -`SnapshotSpec` tells a fresh sandbox session where saved workspace contents should be restored from and persisted back to. It is the snapshot policy for the sandbox workspace, while `session_state` is the serialized connection state for resuming a specific sandbox backend. - -Use `LocalSnapshotSpec` for local durable snapshots and `RemoteSnapshotSpec` when your app provides a remote snapshot client. A no-op snapshot is used as a fallback when local snapshot setup is unavailable, and advanced callers can use one explicitly when they do not want workspace snapshot persistence. - -```python -from pathlib import Path - -from agents.run import RunConfig -from agents.sandbox import LocalSnapshotSpec, SandboxRunConfig -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -run_config = RunConfig( - sandbox=SandboxRunConfig( - client=UnixLocalSandboxClient(), - snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshots")), - ) -) -``` - -When the runner creates a fresh sandbox session, the sandbox client builds a snapshot instance for that session. On start, if the snapshot is restorable, the sandbox restores saved workspace contents before the run continues. On cleanup, runner-owned sandbox sessions archive the workspace and persist it back through the snapshot. - -If you omit `snapshot`, the runtime tries to use a default local snapshot location when it can. If that cannot be set up, it falls back to a no-op snapshot. Mounted and ephemeral paths are not copied into snapshots as durable workspace contents. - -### Sandbox lifecycle - -There are two lifecycle modes: **SDK-owned** and **developer-owned**. - -
    - -```mermaid -sequenceDiagram - participant App - participant Runner - participant Client - participant Sandbox - - App->>Runner: Runner.run(..., SandboxRunConfig(client=...)) - Runner->>Client: create or resume sandbox - Client-->>Runner: sandbox session - Runner->>Sandbox: start, run tools - Runner->>Sandbox: stop and persist snapshot - Runner->>Client: delete runner-owned resources - - App->>Client: create(...) - Client-->>App: sandbox session - App->>Sandbox: async with sandbox - App->>Runner: Runner.run(..., SandboxRunConfig(session=sandbox)) - Runner->>Sandbox: run tools - App->>Sandbox: cleanup on context exit / aclose() -``` - -
    - -Use SDK-owned lifecycle when the sandbox only needs to live for one run. Pass a `client`, optional `manifest`, optional `snapshot`, and client `options`; the runner creates or resumes the sandbox, starts it, runs the agent, persists snapshot-backed workspace state, shuts the sandbox down, and lets the client clean up runner-owned resources. - -```python -result = await Runner.run( - agent, - "Inspect the workspace and summarize what changed.", - run_config=RunConfig( - sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), - ), -) -``` - -Use developer-owned lifecycle when you want to eagerly create a sandbox, reuse one live sandbox across multiple runs, inspect files after a run, stream over a sandbox you created yourself, or decide exactly when cleanup happens. Passing `session=...` tells the runner to use that live sandbox, but not to close it for you. - -```python -sandbox = await client.create(manifest=agent.default_manifest) - -async with sandbox: - run_config = RunConfig(sandbox=SandboxRunConfig(session=sandbox)) - await Runner.run(agent, "Analyze the files.", run_config=run_config) - await Runner.run(agent, "Write the final report.", run_config=run_config) -``` - -The context manager is the usual shape: it starts the sandbox on entry and runs the session cleanup lifecycle on exit. If your app cannot use a context manager, call the lifecycle methods directly: - -```python -sandbox = await client.create( - manifest=agent.default_manifest, - snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshots")), -) -try: - await sandbox.start() - await Runner.run( - agent, - "Analyze the files.", - run_config=RunConfig(sandbox=SandboxRunConfig(session=sandbox)), - ) - # Persist a checkpoint of the live workspace before doing more work. - # `aclose()` also calls `stop()`, so this is only needed for an explicit mid-lifecycle save. - await sandbox.stop() -finally: - await sandbox.aclose() -``` - -`stop()` only persists snapshot-backed workspace contents; it does not tear down the sandbox. `aclose()` is the full session cleanup path: it runs pre-stop hooks, calls `stop()`, shuts down sandbox resources, and closes session-scoped dependencies. - -## `SandboxRunConfig` options - -[`SandboxRunConfig`][agents.run_config.SandboxRunConfig] holds the per-run options that decide where the sandbox session comes from and how a fresh session should be initialized. - -### Sandbox source - -These options decide whether the runner should reuse, resume, or create the sandbox session: - -
    - -| Option | Use it when | Notes | -| --- | --- | --- | -| `client` | You want the runner to create, resume, and clean up sandbox sessions for you. | Required unless you provide a live sandbox `session`. | -| `session` | You already created a live sandbox session yourself. | The caller owns lifecycle; the runner reuses that live sandbox session. | -| `session_state` | You have serialized sandbox session state but not a live sandbox session object. | Requires `client`; the runner resumes from that explicit state as an owning session. | - -
    - -In practice, the runner resolves the sandbox session in this order: - -1. If you inject `run_config.sandbox.session`, that live sandbox session is reused directly. -2. Otherwise, if the run is resuming from `RunState`, the stored sandbox session state is resumed. -3. Otherwise, if you pass `run_config.sandbox.session_state`, the runner resumes from that explicit serialized sandbox session state. -4. Otherwise, the runner creates a fresh sandbox session. For that fresh session, it uses `run_config.sandbox.manifest` when provided, or `agent.default_manifest` if not. - -### Fresh-session inputs - -These options only matter when the runner is creating a fresh sandbox session: - -
    - -| Option | Use it when | Notes | -| --- | --- | --- | -| `manifest` | You want a one-off fresh-session workspace override. | Falls back to `agent.default_manifest` when omitted. | -| `snapshot` | A fresh sandbox session should be seeded from a snapshot. | Useful for resume-like flows or remote snapshot clients. | -| `options` | The sandbox client needs creation-time options. | Common for Docker images, Modal app names, E2B templates, timeouts, and similar client-specific settings. | - -
    - -### Materialization controls - -`concurrency_limits` controls how much sandbox materialization work can run in parallel. Use `SandboxConcurrencyLimits(manifest_entries=..., local_dir_files=...)` when large manifests or local directory copies need tighter resource control. Set either value to `None` to disable that specific limit. - -A few implications are worth keeping in mind: - -- Fresh sessions: `manifest=` and `snapshot=` only apply when the runner is creating a fresh sandbox session. -- Resume vs snapshot: `session_state=` reconnects to previously serialized sandbox state, whereas `snapshot=` seeds a new sandbox session from saved workspace contents. -- Client-specific options: `options=` depends on the sandbox client; Docker and many hosted clients require it. -- Injected live sessions: if you pass a running sandbox `session`, capability-driven manifest updates can add compatible non-mount entries. They cannot change `manifest.root`, `manifest.environment`, `manifest.users`, or `manifest.groups`; remove existing entries; replace entry types; or add or change mount entries. -- Runner API: `SandboxAgent` execution still uses the normal `Runner.run()`, `Runner.run_sync()`, and `Runner.run_streamed()` APIs. - -## Full example: coding task - -This coding-style example is a good default starting point: - -```python -import asyncio -from pathlib import Path - -from agents import ModelSettings, Runner -from agents.run import RunConfig -from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig -from agents.sandbox.capabilities import ( - Capabilities, - LocalDirLazySkillSource, - Skills, -) -from agents.sandbox.entries import LocalDir -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -EXAMPLE_DIR = Path(__file__).resolve().parent -HOST_REPO_DIR = EXAMPLE_DIR / "repo" -HOST_SKILLS_DIR = EXAMPLE_DIR / "skills" -TARGET_TEST_CMD = "sh tests/test_credit_note.sh" - - -def build_agent(model: str) -> SandboxAgent[None]: - return SandboxAgent( - name="Sandbox engineer", - model=model, - instructions=( - "Inspect the repo, make the smallest correct change, run the most relevant checks, " - "and summarize the file changes and risks. " - "Read `repo/task.md` before editing files. Stay grounded in the repository, preserve " - "existing behavior, and mention the exact verification command you ran. " - "Use the `$credit-note-fixer` skill before editing files. If the repo lives under " - "`repo/`, remember that `apply_patch` paths stay relative to the sandbox workspace " - "root, so edits still target `repo/...`." - ), - # Put repos and task files in the manifest. - default_manifest=Manifest( - entries={ - "repo": LocalDir(src=HOST_REPO_DIR), - } - ), - capabilities=Capabilities.default() + [ - # Let Skills(...) stage and index sandbox-local skills for you. - Skills( - lazy_from=LocalDirLazySkillSource( - source=LocalDir(src=HOST_SKILLS_DIR), - ) - ), - ], - model_settings=ModelSettings(tool_choice="required"), - ) - - -async def main(model: str, prompt: str) -> None: - result = await Runner.run( - build_agent(model), - prompt, - run_config=RunConfig( - sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), - workflow_name="Sandbox coding example", - ), - ) - print(result.final_output) - - -if __name__ == "__main__": - asyncio.run( - main( - model="gpt-5.4", - prompt=( - "Open `repo/task.md`, use the `$credit-note-fixer` skill, fix the bug, " - f"run `{TARGET_TEST_CMD}`, and summarize the change." - ), - ) - ) -``` - -See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py). It uses a tiny shell-based repo so the example can be verified deterministically across Unix-local runs. Your real task repo can of course be Python, JavaScript, or anything else. - -## Common patterns - -Start from the full example above. In many cases, the same `SandboxAgent` can stay intact while only the sandbox client, sandbox-session source, or workspace source changes. - -### Switch sandbox clients - -Keep the agent definition the same and change only the run config. Use Docker when you want container isolation or image parity, or a hosted provider when you want provider-managed execution. See [Sandbox clients](clients.md) for examples and provider options. - -### Override the workspace - -Keep the agent definition the same and swap only the fresh-session manifest: - -```python -from agents.run import RunConfig -from agents.sandbox import Manifest, SandboxRunConfig -from agents.sandbox.entries import GitRepo -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -run_config = RunConfig( - sandbox=SandboxRunConfig( - client=UnixLocalSandboxClient(), - manifest=Manifest( - entries={ - "repo": GitRepo(repo="openai/openai-agents-python", ref="main"), - } - ), - ), -) -``` - -Use this when the same agent role should run against different repos, packets, or task bundles without rebuilding the agent. The validated coding example above shows the same pattern with `default_manifest` instead of a one-off override. - -### Inject a sandbox session - -Inject a live sandbox session when you need explicit lifecycle control, post-run inspection, or output copying: - -```python -from agents import Runner -from agents.run import RunConfig -from agents.sandbox import SandboxRunConfig -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -client = UnixLocalSandboxClient() -sandbox = await client.create(manifest=agent.default_manifest) - -async with sandbox: - result = await Runner.run( - agent, - prompt, - run_config=RunConfig( - sandbox=SandboxRunConfig(session=sandbox), - ), - ) -``` - -Use this when you want to inspect the workspace after the run or stream over an already-started sandbox session. See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) and [examples/sandbox/docker/docker_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py). - -### Resume from session state - -If you already serialized sandbox state outside `RunState`, let the runner reconnect from that state: - -```python -from agents.run import RunConfig -from agents.sandbox import SandboxRunConfig - -serialized = load_saved_payload() -restored_state = client.deserialize_session_state(serialized) - -run_config = RunConfig( - sandbox=SandboxRunConfig( - client=client, - session_state=restored_state, - ), -) -``` - -Use this when sandbox state lives in your own storage or job system and you want `Runner` to resume from it directly. See [examples/sandbox/extensions/blaxel_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/blaxel_runner.py) for the serialize/deserialize flow. - -### Start from a snapshot - -Seed a new sandbox from saved files and artifacts: - -```python -from pathlib import Path - -from agents.run import RunConfig -from agents.sandbox import LocalSnapshotSpec, SandboxRunConfig -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -run_config = RunConfig( - sandbox=SandboxRunConfig( - client=UnixLocalSandboxClient(), - snapshot=LocalSnapshotSpec(base_path=Path("/tmp/my-sandbox-snapshot")), - ), -) -``` - -Use this when a fresh run should start from saved workspace contents rather than only `agent.default_manifest`. See [examples/sandbox/memory.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory.py) for a local snapshot flow and [examples/sandbox/sandbox_agent_with_remote_snapshot.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agent_with_remote_snapshot.py) for a remote snapshot client. - -### Load skills from Git - -Swap the local skill source for a repository-backed one: - -```python -from agents.sandbox.capabilities import Capabilities, Skills -from agents.sandbox.entries import GitRepo - -capabilities = Capabilities.default() + [ - Skills(from_=GitRepo(repo="sdcoffey/tax-prep-skills", ref="main")), -] -``` - -Use this when the skills bundle has its own release cadence or should be shared across sandboxes. See [examples/sandbox/tax_prep.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/tax_prep.py). - -### Expose as tools - -Tool-agents can either get their own sandbox boundary or reuse a live sandbox from the parent run. Reuse is useful for a fast read-only explorer agent: it can inspect the exact workspace the parent is using without paying to create, hydrate, or snapshot another sandbox. - -```python -from agents import Runner -from agents.run import RunConfig -from agents.sandbox import FileMode, Manifest, Permissions, SandboxAgent, SandboxRunConfig, User -from agents.sandbox.entries import Dir, File -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -coordinator = User(name="coordinator") -explorer = User(name="explorer") - -manifest = Manifest( - users=[coordinator, explorer], - entries={ - "pricing_packet": Dir( - group=coordinator, - permissions=Permissions( - owner=FileMode.ALL, - group=FileMode.ALL, - other=FileMode.READ | FileMode.EXEC, - directory=True, - ), - children={ - "pricing.md": File( - content=b"Pricing packet contents...", - group=coordinator, - permissions=Permissions( - owner=FileMode.ALL, - group=FileMode.ALL, - other=FileMode.READ, - ), - ), - }, - ), - "work": Dir( - group=coordinator, - permissions=Permissions( - owner=FileMode.ALL, - group=FileMode.ALL, - other=FileMode.NONE, - directory=True, - ), - ), - }, -) - -pricing_explorer = SandboxAgent( - name="Pricing Explorer", - instructions="Read `pricing_packet/` and summarize commercial risk. Do not edit files.", - run_as=explorer, -) - -client = UnixLocalSandboxClient() -sandbox = await client.create(manifest=manifest) - -async with sandbox: - shared_run_config = RunConfig( - sandbox=SandboxRunConfig(session=sandbox), - ) - - orchestrator = SandboxAgent( - name="Revenue Operations Coordinator", - instructions="Coordinate the review and write final notes to `work/`.", - run_as=coordinator, - tools=[ - pricing_explorer.as_tool( - tool_name="review_pricing_packet", - tool_description="Inspect the pricing packet and summarize commercial risk.", - run_config=shared_run_config, - max_turns=2, - ), - ], - ) - - result = await Runner.run( - orchestrator, - "Review the pricing packet, then write final notes to `work/summary.md`.", - run_config=shared_run_config, - ) -``` - -Here the parent agent runs as `coordinator`, and the explorer tool-agent runs as `explorer` inside the same live sandbox session. The `pricing_packet/` entries are readable by `other` users, so the explorer can inspect them quickly, but it does not have write bits. The `work/` directory is only available to the coordinator's user/group, so the parent can write the final artifact while the explorer stays read-only. - -When a tool-agent needs real isolation instead, give it its own sandbox `RunConfig`: - -```python -from docker import from_env as docker_from_env - -from agents.run import RunConfig -from agents.sandbox import SandboxRunConfig -from agents.sandbox.sandboxes.docker import DockerSandboxClient, DockerSandboxClientOptions - -rollout_agent.as_tool( - tool_name="review_rollout_risk", - tool_description="Inspect the rollout packet and summarize implementation risk.", - run_config=RunConfig( - sandbox=SandboxRunConfig( - client=DockerSandboxClient(docker_from_env()), - options=DockerSandboxClientOptions(image="python:3.14-slim"), - ), - ), -) -``` - -Use a separate sandbox when the tool-agent should mutate freely, run untrusted commands, or use a different backend/image. See [examples/sandbox/sandbox_agents_as_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agents_as_tools.py). - -### Combine with local tools and MCP - -Keep the sandbox workspace while still using ordinary tools on the same agent: - -```python -from agents.sandbox import SandboxAgent -from agents.sandbox.capabilities import Shell - -agent = SandboxAgent( - name="Workspace reviewer", - instructions="Inspect the workspace and call host tools when needed.", - tools=[get_discount_approval_path], - mcp_servers=[server], - capabilities=[Shell()], -) -``` - -Use this when workspace inspection is only one part of the agent's job. See [examples/sandbox/sandbox_agent_with_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agent_with_tools.py). - -## Memory - -Use the `Memory` capability when future sandbox-agent runs should learn from prior runs. Memory is separate from the SDK's conversational `Session` memory: it distills lessons into files inside the sandbox workspace, then later runs can read those files. - -See [Agent memory](memory.md) for setup, read/generate behavior, multi-turn conversations, and layout isolation. - -## Composition patterns - -Once the single-agent pattern is clear, the next design question is where the sandbox boundary belongs in a larger system. - -Sandbox agents still compose with the rest of the SDK: - -- [Handoffs](../handoffs.md): hand document-heavy work from a non-sandbox intake agent into a sandbox reviewer. -- [Agents as tools](../tools.md#agents-as-tools): expose multiple sandbox agents as tools, usually by passing `run_config=RunConfig(sandbox=SandboxRunConfig(...))` on each `Agent.as_tool(...)` call so each tool gets its own sandbox boundary. -- [MCP](../mcp.md) and normal function tools: sandbox capabilities can coexist with `mcp_servers` and ordinary Python tools. -- [Running agents](../running_agents.md): sandbox runs still use the normal `Runner` APIs. - -Two patterns are especially common: - -- a non-sandbox agent hands off into a sandbox agent only for the part of the workflow that needs workspace isolation -- an orchestrator exposes multiple sandbox agents as tools, usually with a separate sandbox `RunConfig` per `Agent.as_tool(...)` call so each tool gets its own isolated workspace - -### Turns and sandbox runs - -It helps to explain handoffs and agent-as-tool calls separately. - -With a handoff, there is still one top-level run and one top-level turn loop. The active agent changes, but the run does not become nested. If a non-sandbox intake agent hands off to a sandbox reviewer, the next model call in that same run is prepared for the sandbox agent, and that sandbox agent becomes the one taking the next turn. In other words, handoffs change which agent owns the next turn of the same run. See [examples/sandbox/handoffs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/handoffs.py). - -With `Agent.as_tool(...)`, the relationship is different. The outer orchestrator uses one outer turn to decide to call the tool, and that tool call starts a nested run for the sandbox agent. The nested run has its own turn loop, `max_turns`, approvals, and usually its own sandbox `RunConfig`. It may finish in one nested turn or take several. From the outer orchestrator's point of view, all of that work still sits behind one tool invocation, so the nested turns do not increment the outer run's turn counter. See [examples/sandbox/sandbox_agents_as_tools.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/sandbox_agents_as_tools.py). - -Approval behavior follows the same split: - -- with handoffs, approvals stay on the same top-level run because the sandbox agent is now the active agent in that run -- with `Agent.as_tool(...)`, approvals raised inside the sandbox tool-agent still surface on the outer run, but they come from stored nested run state and resume the nested sandbox run when the outer run resumes - -## Further reading - -- [Quickstart](quickstart.md): get one sandbox agent running. -- [Sandbox clients](clients.md): choose local, Docker, hosted, and mount options. -- [Agent memory](memory.md): preserve and reuse lessons from prior sandbox runs. -- [examples/sandbox/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox): runnable local, coding, memory, handoff, and agent-composition patterns. diff --git a/docs/zh/openai-agents/sandbox/memory.md b/docs/zh/openai-agents/sandbox/memory.md deleted file mode 100644 index 94086fcae..000000000 --- a/docs/zh/openai-agents/sandbox/memory.md +++ /dev/null @@ -1,185 +0,0 @@ -# Agent memory - -Memory lets future sandbox-agent runs learn from prior runs. It is separate from the SDK's conversational [`Session`](../sessions/index.md) memory, which stores message history. Memory distills lessons from prior runs into files in the sandbox workspace. - -!!! warning "Beta feature" - - Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. - -Memory can reduce three kinds of cost for future runs: - -1. Agent cost: If the agent took a long time to complete a workflow, the next run should need less exploration. This can reduce token usage and time to completion. -2. User cost: If the user corrected the agent or expressed a preference, future runs can remember that feedback. This can reduce human intervention. -3. Context cost: If the agent completed a task before, and the user wants to build on that task, the user should not need to find the previous thread or re-type all the context. This makes task descriptions shorter. - -See [examples/sandbox/memory.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory.py) for a complete two-run example that fixes a bug, generates memory, resumes a snapshot, and uses that memory in a follow-up verifier run. See [examples/sandbox/memory_multi_agent_multiturn.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/memory_multi_agent_multiturn.py) for a multi-turn, multi-agent example with separate memory layouts. - -## Enable memory - -Add `Memory()` as a capability to the sandbox agent. - -```python -from pathlib import Path -import tempfile - -from agents.sandbox import LocalSnapshotSpec, SandboxAgent -from agents.sandbox.capabilities import Filesystem, Memory, Shell - -agent = SandboxAgent( - name="Memory-enabled reviewer", - instructions="Inspect the workspace and preserve useful lessons for follow-up runs.", - capabilities=[Memory(), Filesystem(), Shell()], -) - -with tempfile.TemporaryDirectory(prefix="sandbox-memory-example-") as snapshot_dir: - sandbox = await client.create( - manifest=manifest, - snapshot=LocalSnapshotSpec(base_path=Path(snapshot_dir)), - ) -``` - -If read is enabled, `Memory()` requires `Shell()`, which lets the agent read and search memory files when the injected summary is not enough. When live memory update is enabled (by default), it also requires `Filesystem()`, which lets the agent update `memories/MEMORY.md` if the agent discovers stale memory or the user asks it to update memory. - -By default, memory artifacts are stored in the sandbox workspace under `memories/`. To reuse them in a later run, preserve and reuse the whole configured memories directory by keeping the same live sandbox session or resuming from a persisted session state or snapshot; a fresh empty sandbox starts with empty memory. - -`Memory()` enables both reading and generating memories. Use `Memory(generate=None)` for agents that should read memory but should not generate new memories: for example, an internal agent, subagent, checker, or one-off tool agent whose run doesn't add much signal. Use `Memory(read=None)` when the run should generate memory for later, but the user doesn't want the run to be influenced by existing memory. - -## Read memory - -Memory reads use progressive disclosure. At the start of a run, the SDK injects a small summary (`memory_summary.md`) of generally useful tips, user preferences, and available memories into the agent's developer prompt. This gives the agent enough context to decide whether prior work may be relevant. - -When prior work looks relevant, the agent searches the configured memory index (`MEMORY.md` under `memories_dir`) for keywords from the current task. It opens the corresponding prior rollout summaries under the configured `rollout_summaries/` directory only when the task needs more detail. - -Memory can become stale. Agents are instructed to treat memories as guidance only and trust the current environment. By default, memory reads have `live_update` enabled, so if the agent discovers stale memory, it can update the configured `MEMORY.md` in the same run. Disable live updates when the agent should read memory but not modify it during the run, for example if the run is latency sensitive. - -## Generate memory - -After a run finishes, the sandbox runtime appends that run segment to a conversation file. Accumulated conversation files are processed when the sandbox session closes. - -Memory generation has two phases: - -1. Phase 1: conversation extraction. A memory-generating model processes one accumulated conversation file and generates a conversation summary. System, developer, and reasoning content are omitted. If the conversation is too long, it is truncated to fit within the context window, with the beginning and end preserved. It also generates a raw memory extract: compact notes from the conversation that Phase 2 can consolidate. -2. Phase 2: layout consolidation. A consolidation agent reads raw memories for one memory layout, opens conversation summaries when more evidence is needed, and extracts patterns into `MEMORY.md` and `memory_summary.md`. - -The default workspace layout is: - -```text -workspace/ -├── sessions/ -│ └── .jsonl -└── memories/ - ├── memory_summary.md - ├── MEMORY.md - ├── raw_memories.md (intermediate) - ├── phase_two_selection.json (intermediate) - ├── raw_memories/ (intermediate) - │ └── .md - ├── rollout_summaries/ - │ └── _.md - └── skills/ -``` - -You can configure memory generation with `MemoryGenerateConfig`: - -```python -from agents.sandbox import MemoryGenerateConfig -from agents.sandbox.capabilities import Memory - -memory = Memory( - generate=MemoryGenerateConfig( - max_raw_memories_for_consolidation=128, - extra_prompt="Pay extra attention to what made the customer more satisfied or annoyed", - ), -) -``` - -Use `extra_prompt` to tell the memory generator which signals matter most for your use case, such as customer and company details for a GTM agent. - -If recent raw memories exceed `max_raw_memories_for_consolidation` (defaults to 256), Phase 2 keeps only memories from the newest conversations and removes older ones. Recency is based on the last time the conversation is updated. This forgetting mechanism helps memories reflect the newest environment. - -## Multi-turn conversations - -For multi-turn sandbox chats, use the normal SDK `Session` together with the same live sandbox session: - -```python -from agents import Runner, SQLiteSession -from agents.run import RunConfig -from agents.sandbox import SandboxRunConfig - -conversation_session = SQLiteSession("gtm-q2-pipeline-review") -sandbox = await client.create(manifest=agent.default_manifest) - -async with sandbox: - run_config = RunConfig( - sandbox=SandboxRunConfig(session=sandbox), - workflow_name="GTM memory example", - ) - await Runner.run( - agent, - "Analyze data/leads.csv and identify one promising GTM segment.", - session=conversation_session, - run_config=run_config, - ) - await Runner.run( - agent, - "Using that analysis, write a short outreach hypothesis.", - session=conversation_session, - run_config=run_config, - ) -``` - -Both runs append to one memory conversation file because they pass the same SDK conversation session (`session=conversation_session`) and therefore share the same `session.session_id`. This is different from the sandbox (`sandbox`), which identifies the live workspace and is not used as the memory conversation ID. Phase 1 sees the accumulated conversation when the sandbox session closes, so it can extract memory from the whole exchange instead of two isolated turns. - -If you want multiple `Runner.run(...)` calls to become one memory conversation, pass a stable identifier across those calls. When memory associates a run with a conversation, it resolves in this order: - -1. `conversation_id`, when you pass one to `Runner.run(...)` -2. `session.session_id`, when you pass an SDK `Session` such as `SQLiteSession` -3. `RunConfig.group_id`, when neither of the above is present -4. A generated per-run ID, when no stable identifier is present - -## Use different layouts to isolate memory for different agents - -Memory isolation is based on `MemoryLayoutConfig`, not on agent name. Agents with the same layout and the same memory conversation ID share one memory conversation and one consolidated memory. Agents with different layouts keep separate rollout files, raw memories, `MEMORY.md`, and `memory_summary.md`, even when they share the same sandbox workspace. - -Use separate layouts when multiple agents share one sandbox but should not share memory: - -```python -from agents import SQLiteSession -from agents.sandbox import MemoryLayoutConfig, SandboxAgent -from agents.sandbox.capabilities import Filesystem, Memory, Shell - -gtm_agent = SandboxAgent( - name="GTM reviewer", - instructions="Analyze GTM workspace data and write concise recommendations.", - capabilities=[ - Memory( - layout=MemoryLayoutConfig( - memories_dir="memories/gtm", - sessions_dir="sessions/gtm", - ) - ), - Filesystem(), - Shell(), - ], -) - -engineering_agent = SandboxAgent( - name="Engineering reviewer", - instructions="Inspect engineering workspaces and summarize fixes and risks.", - capabilities=[ - Memory( - layout=MemoryLayoutConfig( - memories_dir="memories/engineering", - sessions_dir="sessions/engineering", - ) - ), - Filesystem(), - Shell(), - ], -) - -gtm_session = SQLiteSession("gtm-q2-pipeline-review") -engineering_session = SQLiteSession("eng-invoice-test-fix") -``` - -This prevents GTM analysis from being consolidated into engineering bug-fix memory, and vice versa. diff --git a/docs/zh/openai-agents/sandbox_agents.md b/docs/zh/openai-agents/sandbox_agents.md deleted file mode 100644 index e4c91074d..000000000 --- a/docs/zh/openai-agents/sandbox_agents.md +++ /dev/null @@ -1,111 +0,0 @@ -# Quickstart - -!!! warning "Beta feature" - - Sandbox agents are in beta. Expect details of the API, defaults, and supported capabilities to change before general availability, and expect more advanced features over time. - -Modern agents work best when they can operate on real files in a filesystem. **Sandbox Agents** in the Agents SDK give the model a persistent workspace where it can search large document sets, edit files, run commands, generate artifacts, and pick work back up from saved sandbox state. - -The SDK gives you that execution harness without making you wire together file staging, filesystem tools, shell access, sandbox lifecycle, snapshots, and provider-specific glue yourself. You keep the normal `Agent` and `Runner` flow, then add a `Manifest` for the workspace, capabilities for sandbox-native tools, and `SandboxRunConfig` for where the work runs. - -## Prerequisites - -- Python 3.10 or higher -- Basic familiarity with the OpenAI Agents SDK -- A sandbox client. For local development, start with `UnixLocalSandboxClient`. - -## Installation - -If you have not already installed the SDK: - -```bash -pip install openai-agents -``` - -For Docker-backed sandboxes: - -```bash -pip install "openai-agents[docker]" -``` - -## Create a local sandbox agent - -This example stages a local repo under `repo/`, loads local skills lazily, and lets the runner create a Unix-local sandbox session for the run. - -```python -import asyncio -from pathlib import Path - -from agents import Runner -from agents.run import RunConfig -from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig -from agents.sandbox.capabilities import Capabilities, LocalDirLazySkillSource, Skills -from agents.sandbox.entries import LocalDir -from agents.sandbox.sandboxes.unix_local import UnixLocalSandboxClient - -EXAMPLE_DIR = Path(__file__).resolve().parent -HOST_REPO_DIR = EXAMPLE_DIR / "repo" -HOST_SKILLS_DIR = EXAMPLE_DIR / "skills" - - -def build_agent(model: str) -> SandboxAgent[None]: - return SandboxAgent( - name="Sandbox engineer", - model=model, - instructions=( - "Read `repo/task.md` before editing files. Stay grounded in the repository, preserve " - "existing behavior, and mention the exact verification command you ran. " - "If you edit files with apply_patch, paths are relative to the sandbox workspace root." - ), - default_manifest=Manifest( - entries={ - "repo": LocalDir(src=HOST_REPO_DIR), - } - ), - capabilities=Capabilities.default() + [ - Skills( - lazy_from=LocalDirLazySkillSource( - source=LocalDir(src=HOST_SKILLS_DIR), - ) - ), - ], - ) - - -async def main() -> None: - result = await Runner.run( - build_agent("gpt-5.4"), - "Open `repo/task.md`, fix the issue, run the targeted test, and summarize the change.", - run_config=RunConfig( - sandbox=SandboxRunConfig(client=UnixLocalSandboxClient()), - workflow_name="Sandbox coding example", - ), - ) - print(result.final_output) - - -if __name__ == "__main__": - asyncio.run(main()) -``` - -See [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py). It uses a tiny shell-based repo so the example can be verified deterministically across Unix-local runs. - -## Key choices - -Once the basic run works, the choices most people reach for next are: - -- `default_manifest`: the files, repos, directories, and mounts for fresh sandbox sessions -- `instructions`: short workflow rules that should apply across prompts -- `base_instructions`: an advanced escape hatch for replacing the SDK sandbox prompt -- `capabilities`: sandbox-native tools such as filesystem editing/image inspection, shell, skills, memory, and compaction -- `run_as`: the sandbox user identity for model-facing tools -- `SandboxRunConfig.client`: the sandbox backend -- `SandboxRunConfig.session`, `session_state`, or `snapshot`: how later runs reconnect to prior work - -## Where to go next - -- [Concepts](sandbox/guide.md): understand manifests, capabilities, permissions, snapshots, run config, and composition patterns. -- [Sandbox clients](sandbox/clients.md): choose Unix-local, Docker, hosted providers, and mount strategies. -- [Agent memory](sandbox/memory.md): preserve and reuse lessons from previous sandbox runs. - -If shell access is only one occasional tool, start with hosted shell in the [tools guide](tools.md). Reach for sandbox agents when workspace isolation, sandbox client choice, or sandbox-session resume behavior are part of the design. From 1c82d7dc587f2440e3f5e6e524c8e92f48b1705b Mon Sep 17 00:00:00 2001 From: chickenlj Date: Tue, 28 Apr 2026 08:50:11 +0800 Subject: [PATCH 11/28] skip license check --- .licenserc.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.licenserc.yaml b/.licenserc.yaml index 8ad0920c2..0523beec0 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -17,6 +17,11 @@ header: limitations under the License. paths-ignore: + # Config / example files without license headers + - 'agentscope-examples/harness-example/.env.example' + - 'agentscope-examples/harness-example/src/main/resources/agentscope.json.example' + - 'agentscope-examples/harness-example/src/main/resources/log4j2.xml' + - 'agentscope-harness/src/main/resources/agentscope.json.example' - '**/*.versionsBackup' - '**/.idea/' - '**/*.iml' From 060238c33df3d42a8bbe1aea6cad1604c65fd5b2 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Wed, 6 May 2026 08:18:12 +0800 Subject: [PATCH 12/28] update harness implementation --- .../harness-example-sandbox/pom.xml | 43 +++- .../harness/sandbox/DataAgentController.java | 93 ++++++++ .../harness/sandbox/DataAgentService.java | 163 +++++++++++++ .../sandbox/HarnessSandboxApplication.java | 41 ++++ .../sandbox/HarnessSandboxExampleApp.java | 52 ---- ...calFilesystemPersonalAssistantExample.java | 132 ---------- ...RemoteFilesystemIsolationScopeExample.java | 180 -------------- ...andboxFilesystemIsolationScopeExample.java | 182 -------------- .../WorkspaceClasspathMaterializer.java | 70 ++++++ .../harness/sandbox/data/SqliteTool.java | 225 ++++++++++++++++++ .../sandbox/support/FixedReplyModel.java | 64 ----- .../sandbox/support/InMemorySandbox.java | 56 ++++- .../SharedInMemorySandboxStateStore.java | 52 ++++ .../src/main/resources/application.properties | 2 + .../harness/sandbox/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 + .../workspace/skills/query-writing/SKILL.md | 14 ++ .../harness/agent/HarnessAgent.java | 51 ++-- .../agent/filesystem/AbstractFilesystem.java | 47 +++- .../filesystem/BaseSandboxFilesystem.java | 31 ++- .../agent/filesystem/CompositeFilesystem.java | 87 ++++--- .../agent/filesystem/LocalFilesystem.java | 76 +++++- .../filesystem/LocalFilesystemWithShell.java | 74 ++++++ .../agent/filesystem/RemoteFilesystem.java | 30 ++- .../agent/hook/MemoryMaintenanceHook.java | 11 +- .../agent/hook/SandboxLifecycleHook.java | 20 +- .../agent/hook/ToolResultEvictionHook.java | 5 +- .../agent/memory/MemoryConsolidator.java | 5 +- .../agent/memory/session/SessionTree.java | 7 +- .../sandbox/SandboxBackedFilesystem.java | 7 +- .../filesystem/SandboxFilesystemSpec.java | 20 ++ .../harness/agent/tool/FilesystemTool.java | 20 +- .../harness/agent/tool/MemorySearchTool.java | 2 +- .../harness/agent/tool/ShellExecuteTool.java | 6 + .../agent/workspace/WorkspaceManager.java | 17 +- ...ilesystemPersonalAssistantExampleTest.java | 6 +- ...teFilesystemIsolationScopeExampleTest.java | 10 +- ...oxFilesystemIsolationScopeExampleTest.java | 10 +- .../FilesystemDeleteMoveExistsTest.java | 37 +-- .../filesystem/RemoteFilesystemSpecTest.java | 6 + docs/zh/harness/sandbox.md | 4 +- 41 files changed, 1190 insertions(+), 780 deletions(-) create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java create mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/application.properties create mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite create mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md diff --git a/agentscope-examples/harness-example-sandbox/pom.xml b/agentscope-examples/harness-example-sandbox/pom.xml index a7c825582..88e76a3e4 100644 --- a/agentscope-examples/harness-example-sandbox/pom.xml +++ b/agentscope-examples/harness-example-sandbox/pom.xml @@ -30,37 +30,54 @@ io.agentscope.examples harness-example-sandbox jar - Runnable examples: local filesystem, in-memory sandbox isolation scopes, and store-backed namespaces (no remote LLM required) + Spring Boot app: in-memory sandbox Data Agent (text-to-SQL pattern from harness-example), USER isolation, shared store, projected workspace - - 2.24.3 - + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + io.agentscope agentscope-harness + + + org.xerial + sqlite-jdbc + 3.47.2.0 + com.fasterxml.jackson.dataformat jackson-dataformat-yaml - org.apache.logging.log4j - log4j-slf4j2-impl - ${log4j2.version} + org.springframework.boot + spring-boot-starter-web - org.codehaus.mojo - exec-maven-plugin - 3.6.3 - - io.agentscope.examples.harness.sandbox.HarnessSandboxExampleApp - + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java new file mode 100644 index 000000000..68b834ac0 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * HTTP entry point for the sandbox Data Agent. + * + *
    + * GET  /        — usage hint
    + * POST /query   — ask the data agent a question
    + * 
    + * + *

    Example: + * + *

    {@code
    + * curl -X POST http://localhost:8787/query \
    + *   -H 'Content-Type: application/json' \
    + *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
    + * }
    + */ +@RestController +public class DataAgentController { + + private final DataAgentService agentService; + + public DataAgentController(DataAgentService agentService) { + this.agentService = agentService; + } + + @GetMapping("/") + public String index() { + return "Sandbox Data Agent — POST /query with" + + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; + } + + /** + * Processes a natural-language question about the Chinook database. + * + *

    The agent sandbox and memory are scoped by {@code userId}: the same user always resumes + * the same sandbox (and sees the same {@code MEMORY.md}) regardless of {@code sessionId}. The + * conversation context (messages) is scoped by {@code sessionId}. + */ + @PostMapping("/query") + public ResponseEntity query(@RequestBody QueryRequest request) { + if (blank(request.sessionId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); + } + if (blank(request.userId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); + } + if (blank(request.question())) { + return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); + } + String answer = + agentService.query(request.sessionId(), request.userId(), request.question()); + return ResponseEntity.ok(QueryResponse.ok(answer)); + } + + private static boolean blank(String s) { + return s == null || s.isBlank(); + } + + record QueryRequest(String sessionId, String userId, String question) {} + + record QueryResponse(String answer, String error) { + static QueryResponse ok(String answer) { + return new QueryResponse(answer, null); + } + + static QueryResponse error(String error) { + return new QueryResponse(null, error); + } + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java new file mode 100644 index 000000000..b46cc33c3 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java @@ -0,0 +1,163 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.core.model.Model; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.examples.harness.sandbox.data.SqliteTool; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; +import io.agentscope.examples.harness.sandbox.support.SharedInMemorySandboxStateStore; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.RuntimeContext; +import jakarta.annotation.PostConstruct; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Data Agent service: Chinook text-to-SQL with sandbox isolation. + * + *

    Infrastructure shared across all requests (initialized once on startup): + * + *

      + *
    • {@link InMemorySandboxClient} — local-process sandbox (stands in for Docker in + * production) + *
    • {@link SharedInMemorySandboxStateStore} — shared state store (stands in for Redis) + *
    • {@link InMemorySandboxFilesystemSpec} with {@link IsolationScope#USER} — each unique + * {@code userId} gets its own sandbox; the sandbox persists across sessions for that user + *
    + * + *

    A fresh {@link HarnessAgent} is built per request so concurrent calls with different + * {@code userId} values do not interfere. The heavy shared state (sandbox instance, workspace + * files, memory) lives in the stores above, not in the agent object itself. + * + *

    Required environment variables: + * + *

      + *
    • {@code DASHSCOPE_API_KEY} — DashScope API key + *
    • {@code AGENTSCOPE_MODEL} — model name (default: {@code qwen-max}) + *
    + */ +@Service +public class DataAgentService { + + private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); + + private static final String AGENT_NAME = "data-agent"; + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + private static final String SYS_PROMPT = + "You are a Text-to-SQL agent with access to the Chinook music store database." + + " Use the sql_* tools to explore the schema and run read-only SELECT queries." + + " Follow the query-writing skill and answer clearly in plain language."; + + private Path hostWorkspace; + private Path dbPath; + private Model model; + private InMemorySandboxFilesystemSpec fsSpec; + private SharedInMemorySandboxStateStore stateStore; + + @PostConstruct + void init() throws Exception { + hostWorkspace = WorkspaceClasspathMaterializer.materialize(); + dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); + model = buildModel(); + + stateStore = new SharedInMemorySandboxStateStore(); + fsSpec = new InMemorySandboxFilesystemSpec(new InMemorySandboxClient()); + fsSpec.isolationScope(IsolationScope.USER).sandboxStateStore(stateStore); + + log.info("DataAgentService ready: workspace={} db={}", hostWorkspace, dbPath); + } + + /** + * Processes a user question with the data agent. + * + *
      + *
    • {@code sessionId} — scopes the conversation history (same session = same chat context) + *
    • {@code userId} — scopes the sandbox workspace and memory (same user = shared sandbox + * and MEMORY.md across sessions) + *
    + * + * @param sessionId session identifier + * @param userId user identifier + * @param question natural-language question about the Chinook database + * @return agent answer + */ + public String query(String sessionId, String userId, String question) { + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name(AGENT_NAME) + .model(model) + .workspace(hostWorkspace) + .filesystem(fsSpec) + .sysPrompt(SYS_PROMPT) + .toolkit(toolkit) + .enableAgentTracingLog(true) + .build(); + + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); + Msg reply = agent.call(userMsg, ctx).block(); + return reply != null ? reply.getTextContent() : "(no response)"; + } + + private static Model buildModel() { + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); + } + String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); + log.info("Using model: {}", modelName); + return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) + .build(); + } + + private static Path materialiseChinook(Path target) throws Exception { + if (Files.exists(target)) { + return target.toAbsolutePath(); + } + try (InputStream in = + DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + throw new IllegalStateException( + "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); + } + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + return target.toAbsolutePath(); + } + + private static String envOrDefault(String name, String defaultValue) { + String v = System.getenv(name); + return (v != null && !v.isBlank()) ? v : defaultValue; + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java new file mode 100644 index 000000000..953e784d8 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot entry for the sandbox Data Agent (text-to-SQL) demo. + * + *

    Set {@code DASHSCOPE_API_KEY} before starting. Optionally override the model with + * {@code AGENTSCOPE_MODEL} (default: {@code qwen-max}). + * + *

    Once started, send questions via: + * + *

    + * curl -X POST http://localhost:8787/query \
    + *   -H 'Content-Type: application/json' \
    + *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are there?"}'
    + * 
    + */ +@SpringBootApplication +public class HarnessSandboxApplication { + + public static void main(String[] args) { + SpringApplication.run(HarnessSandboxApplication.class, args); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java deleted file mode 100644 index 0074851dd..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; -import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; - -/** - * Runs harness filesystem examples (local, in-memory sandbox, in-memory store). No LLM API key - * required — uses {@link FixedReplyModel} for a single turn per {@code call}. The - * {@code store} mode is an alias for {@code remote} (shared KV / {@link RemoteFilesystemSpec}). - * - *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|remote|store]} - */ -public final class HarnessSandboxExampleApp { - - public static void main(String[] args) throws Exception { - String mode = args.length == 0 ? "all" : args[0].toLowerCase(); - System.out.println( - "Model: " + FixedReplyModel.done().getModelName() + " (no remote LLM)\n"); - switch (mode) { - case "all" -> { - LocalFilesystemPersonalAssistantExample.main(new String[0]); - System.out.println(); - SandboxFilesystemIsolationScopeExample.main(new String[0]); - System.out.println(); - RemoteFilesystemIsolationScopeExample.main(new String[0]); - } - case "local" -> LocalFilesystemPersonalAssistantExample.main(new String[0]); - case "sandbox" -> SandboxFilesystemIsolationScopeExample.main(new String[0]); - case "remote", "store" -> RemoteFilesystemIsolationScopeExample.main(new String[0]); - default -> { - System.err.println("Unknown mode: " + mode); - System.err.println("Use: all | local | sandbox | remote | store"); - System.exit(1); - } - } - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java deleted file mode 100644 index 359891ec9..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; -import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Example: local personal-assistant mode using {@link LocalFilesystemWithShell} — direct disk I/O - * and {@link ProcessBuilder} shell in one workspace, no container or distributed store. - */ -public final class LocalFilesystemPersonalAssistantExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-local-fs-example-"); - System.out.println("Workspace: " + workspace.toAbsolutePath()); - - demonstrateFilesPersistAcrossCalls(workspace, model); - demonstrateSharedWorkspaceForAllUsersAndSessions(workspace, model); - demonstrateHostWrittenFileVisibleToAgent(workspace, model); - - System.out.println("Local filesystem example finished successfully."); - } - - static void demonstrateFilesPersistAcrossCalls(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - agent.call(userMsg("first call"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "# Notes\n- item 1"); - - Path memoryFile = workspace.resolve("MEMORY.md"); - if (!Files.isRegularFile(memoryFile)) { - throw new IllegalStateException("MEMORY.md should exist on disk after first call"); - } - String content = Files.readString(memoryFile, StandardCharsets.UTF_8); - if (!content.contains("item 1")) { - throw new IllegalStateException("MEMORY.md should contain persisted item"); - } - - agent.call(userMsg("second call"), ctx("session-2", "alice")).block(); - if (!Files.isRegularFile(memoryFile)) { - throw new IllegalStateException("MEMORY.md should still exist after second call"); - } - if (!content.equals(Files.readString(memoryFile, StandardCharsets.UTF_8))) { - throw new IllegalStateException("MEMORY.md content should be unchanged"); - } - System.out.println("[local] files persist across calls: OK"); - } - - static void demonstrateSharedWorkspaceForAllUsersAndSessions(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - agent.call(userMsg("alice here"), ctx("session-alice", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("shared.txt", "alice was here"); - agent.call(userMsg("bob here"), ctx("session-bob", "bob")).block(); - if (!Files.isRegularFile(workspace.resolve("shared.txt"))) { - throw new IllegalStateException( - "local workspace is not partitioned by user or session"); - } - System.out.println("[local] same workspace for all user/session context values: OK"); - } - - static void demonstrateHostWrittenFileVisibleToAgent(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - Path doc = workspace.resolve("document.txt"); - Files.writeString(doc, "Host-written document content"); - agent.call(userMsg("check document"), ctx("s1", "user")).block(); - String read = agent.getWorkspaceManager().readManagedWorkspaceFileUtf8("document.txt"); - if (read == null || !read.contains("Host-written")) { - throw new IllegalStateException("agent should read host-written file"); - } - System.out.println("[local] host file visible to workspace manager: OK"); - } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java deleted file mode 100644 index c243d69f3..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; -import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; -import io.agentscope.harness.agent.store.InMemoryStore; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -/** - * Example: {@link RemoteFilesystemSpec} with in-memory key-value store and different {@link - * IsolationScope} namespaces. - */ -public final class RemoteFilesystemIsolationScopeExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-store-isolation-example-"); - System.out.println("Workspace: " + workspace.toAbsolutePath()); - - sessionScopeIsolated(model, workspace); - sessionScopeSharedWithinSession(model, workspace); - userScopeSharedAcrossSessions(model, workspace); - userScopeIsolatedByUser(model, workspace); - agentScopeSharedByAllCallers(model, workspace); - - System.out.println("Store isolation example finished successfully."); - } - - static void sessionScopeIsolated(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.SESSION)) - .build(); - - agent.call(userMsg("from session-1"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "session-1 notes"); - if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") - == null) { - throw new IllegalStateException("data should exist under session-1"); - } - if (store.get(List.of("agents", "assistant", "sessions", "session-2"), "/MEMORY.md") - != null) { - throw new IllegalStateException("session-2 namespace should be empty"); - } - System.out.println("[store] SESSION: per-session namespace: OK"); - } - - static void sessionScopeSharedWithinSession(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.SESSION)) - .build(); - - agent.call(userMsg("call 1"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared memory"); - agent.call(userMsg("call 2"), ctx("session-1", "alice")).block(); - if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") - == null) { - throw new IllegalStateException("MEMORY under session-1"); - } - System.out.println("[store] SESSION: same session reuses key: OK"); - } - - static void userScopeSharedAcrossSessions(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) - .build(); - - agent.call(userMsg("hi from session-a"), ctx("session-a", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's memory"); - if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { - throw new IllegalStateException("data under user alice"); - } - agent.call(userMsg("hi from session-b"), ctx("session-b", "alice")).block(); - if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { - throw new IllegalStateException("alice's key still present"); - } - System.out.println("[store] USER: one namespace per user: OK"); - } - - static void userScopeIsolatedByUser(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) - .build(); - - agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's data"); - if (store.get(List.of("agents", "assistant", "users", "bob"), "/MEMORY.md") != null) { - throw new IllegalStateException("bob should not see alice's data"); - } - System.out.println("[store] USER: users are isolated: OK"); - } - - static void agentScopeSharedByAllCallers(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("shared-assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.AGENT)) - .build(); - - agent.call(userMsg("alice"), ctx("s1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared knowledge"); - if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { - throw new IllegalStateException("shared namespace"); - } - agent.call(userMsg("bob"), ctx("s2", "bob")).block(); - if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { - throw new IllegalStateException("data still in shared"); - } - System.out.println("[store] AGENT: shared key for all callers: OK"); - } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java deleted file mode 100644 index c309766cf..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Example: sandbox filesystem with {@link IsolationScope} (in-process {@link InMemorySandboxClient} - * simulates create/resume without Docker). - */ -public final class SandboxFilesystemIsolationScopeExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-sandbox-isolation-example-"); - System.out.println("Control workspace: " + workspace.toAbsolutePath()); - - sessionScopeSameSessionResumes(workspace, model); - sessionScopeDifferentSessionCreatesTwo(workspace, model); - userScopeSameUserResumesAcrossSessions(workspace, model); - userScopeDifferentUsersGetTwoSandboxes(workspace, model); - agentScopeEveryoneSharesOneSandbox(workspace, model); - - System.out.println("Sandbox isolation example finished successfully."); - } - - static void sessionScopeSameSessionResumes(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.SESSION); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("hello"), ctx("session-1", null)).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 0) { - throw new IllegalStateException("expected 1 create, 0 resume after first call"); - } - agent.call(userMsg("hello again"), ctx("session-1", null)).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { - throw new IllegalStateException("expected 1 create, 1 resume for same session"); - } - System.out.println("[sandbox] SESSION: same session resumes: OK"); - } - - static void sessionScopeDifferentSessionCreatesTwo(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.SESSION); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call( - userMsg("call from session-DifferentSessionCreatesTwo-1"), - ctx("session-DifferentSessionCreatesTwo-1", "alice")) - .block(); - agent.call( - userMsg("call from session-DifferentSessionCreatesTwo-2"), - ctx("session-DifferentSessionCreatesTwo-2", "alice")) - .block(); - if (client.getCreateCount() != 2 || client.getResumeCount() != 0) { - throw new IllegalStateException("expected 2 creates for distinct sessions"); - } - System.out.println("[sandbox] SESSION: different sessions get new sandboxes: OK"); - } - - static void userScopeSameUserResumesAcrossSessions(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.USER); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("session A"), ctx("session-a", "alice")).block(); - if (client.getCreateCount() != 1) { - throw new IllegalStateException("expected 1 create"); - } - agent.call(userMsg("session B"), ctx("session-b", "alice")).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { - throw new IllegalStateException("same user should resume across sessions"); - } - System.out.println("[sandbox] USER: same user resumes across sessions: OK"); - } - - static void userScopeDifferentUsersGetTwoSandboxes(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.USER); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("hi from alice2"), ctx("s1", "alice2")).block(); - agent.call(userMsg("hi from bob2"), ctx("s2", "bob2")).block(); - if (client.getCreateCount() != 2) { - throw new IllegalStateException("each user should get a new sandbox"); - } - System.out.println("[sandbox] USER: different users are isolated: OK"); - } - - static void agentScopeEveryoneSharesOneSandbox(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.AGENT); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("shared-assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("alice says hi"), ctx("s1", "alice")).block(); - agent.call(userMsg("bob says hi"), ctx("s2", "bob")).block(); - agent.call(userMsg("charlie says hi"), ctx("s3", "charlie")).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 2) { - throw new IllegalStateException("AGENT scope: 1 create, 2 resume"); - } - System.out.println("[sandbox] AGENT: all callers share one sandbox: OK"); - } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java new file mode 100644 index 000000000..7c425ed1d --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +/** + * Copies known {@code classpath:workspace/...} entries into a temp directory so {@link + * io.agentscope.harness.agent.HarnessAgent} can use it as the host workspace root for sandbox + * projection (e.g. {@code skills/query-writing/} for the Data Agent demo). + */ +public final class WorkspaceClasspathMaterializer { + + private static final String[] CLASSPATH_FILES = { + "classpath:workspace/AGENTS.md", + "classpath:workspace/skills/query-writing/SKILL.md", + "classpath:workspace/knowledge/KNOWLEDGE.md", + }; + + private WorkspaceClasspathMaterializer() {} + + /** + * Materializes bundled workspace resources to disk. + * + * @return absolute path to the host workspace directory (contains {@code AGENTS.md}, + * {@code skills/}, …) + */ + public static Path materialize() { + try { + Path dir = Files.createTempDirectory("data-agent-host-workspace-"); + PathMatchingResourcePatternResolver resolver = + new PathMatchingResourcePatternResolver(); + for (String location : CLASSPATH_FILES) { + Resource resource = resolver.getResource(location); + if (!resource.exists()) { + throw new IllegalStateException("Missing required resource: " + location); + } + String pathWithinWorkspace = location.substring("classpath:workspace/".length()); + Path target = dir.resolve(pathWithinWorkspace); + Files.createDirectories(target.getParent()); + try (InputStream in = resource.getInputStream()) { + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + } + return dir.toAbsolutePath().normalize(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to materialize workspace from classpath", e); + } + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java new file mode 100644 index 000000000..9649b157c --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java @@ -0,0 +1,225 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.data; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SQLite helpers for the sandbox Data Agent — same tool names and behaviour as {@code + * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. + * + *

    Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + private static final int MAX_ROWS = 50; + + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + String separator = "-".repeat(header.toString().length()); + + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java deleted file mode 100644 index 573283e7e..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.TextBlock; -import io.agentscope.core.model.ChatResponse; -import io.agentscope.core.model.GenerateOptions; -import io.agentscope.core.model.Model; -import io.agentscope.core.model.ToolSchema; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import reactor.core.publisher.Flux; - -/** - * A minimal, deterministic {@link Model} implementation for examples: one assistant text turn - * with finish reason {@code stop}, so the agent loop can complete without remote LLM calls. - */ -public final class FixedReplyModel implements Model { - - private final String modelName; - private final String replyText; - - public FixedReplyModel(String modelName, String replyText) { - this.modelName = modelName; - this.replyText = replyText; - } - - public static FixedReplyModel done() { - return new FixedReplyModel("fixed-reply", "done"); - } - - @Override - public String getModelName() { - return modelName; - } - - @Override - public Flux stream( - List messages, List tools, GenerateOptions options) { - ChatResponse chunk = - new ChatResponse( - "local-" + UUID.randomUUID(), - List.of(TextBlock.builder().text(replyText).build()), - null, - Map.of(), - "stop"); - return Flux.just(chunk); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java index 4ee8de504..a51409c0b 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java @@ -18,15 +18,25 @@ import io.agentscope.harness.agent.sandbox.ExecResult; import io.agentscope.harness.agent.sandbox.Sandbox; import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceProjectionApplier; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; /** * In-process {@link Sandbox} that uses a local temp directory as the workspace (for examples). + * + *

    Applies {@link WorkspaceProjectionApplier} payloads on {@link #start} and extracts tar + * archives in {@link #hydrateWorkspace} so host-projected skills match production behaviour. */ public class InMemorySandbox implements Sandbox { @@ -46,10 +56,28 @@ public void start() throws Exception { if (!Files.exists(workspaceDir)) { Files.createDirectories(workspaceDir); } + applyWorkspaceProjectionIfChanged(state.getWorkspaceSpec()); state.setWorkspaceRootReady(true); running.set(true); } + private void applyWorkspaceProjectionIfChanged(WorkspaceSpec spec) throws Exception { + WorkspaceProjectionApplier.ProjectionPayload payload = + WorkspaceProjectionApplier.build(spec); + if (payload == null) { + return; + } + if (Objects.equals(payload.hash(), state.getWorkspaceProjectionHash())) { + return; + } + if (payload.fileCount() > 0) { + try (InputStream archive = new ByteArrayInputStream(payload.tarBytes())) { + hydrateWorkspace(archive); + } + } + state.setWorkspaceProjectionHash(payload.hash()); + } + @Override public void stop() throws Exception { state.setWorkspaceRootReady(true); @@ -107,7 +135,33 @@ public InputStream persistWorkspace() throws Exception { @Override public void hydrateWorkspace(InputStream archive) throws Exception { - // no-op + if (archive == null) { + return; + } + Path root = workspaceDir.normalize(); + try (TarArchiveInputStream tar = new TarArchiveInputStream(archive)) { + TarArchiveEntry entry; + while ((entry = tar.getNextEntry()) != null) { + if (entry.isDirectory()) { + continue; + } + String name = entry.getName(); + if (name.startsWith("/")) { + name = name.substring(1); + } + if (name.isBlank()) { + continue; + } + Path dest = root.resolve(name).normalize(); + if (!dest.startsWith(root)) { + throw new IOException("Tar entry escapes workspace: " + name); + } + Files.createDirectories(dest.getParent()); + try (OutputStream out = Files.newOutputStream(dest)) { + tar.transferTo(out); + } + } + } } public Path getWorkspaceDir() { diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java new file mode 100644 index 000000000..59d06f7c8 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxIsolationKey; +import io.agentscope.harness.agent.sandbox.SandboxStateStore; +import java.io.IOException; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +/** + * In-memory {@link SandboxStateStore} for examples: simulates a shared Redis-style slot map so + * multiple {@link io.agentscope.harness.agent.HarnessAgent} instances can resume the same user's + * sandbox metadata. + */ +public final class SharedInMemorySandboxStateStore implements SandboxStateStore { + + private final ConcurrentHashMap store = new ConcurrentHashMap<>(); + + private static String mapKey(SandboxIsolationKey key) { + return key.getScope().name() + ":" + key.getValue(); + } + + @Override + public Optional load(SandboxIsolationKey key) throws IOException { + String v = store.get(mapKey(key)); + return Optional.ofNullable(v); + } + + @Override + public void save(SandboxIsolationKey key, String json) throws IOException { + store.put(mapKey(key), json); + } + + @Override + public void delete(SandboxIsolationKey key) throws IOException { + store.remove(mapKey(key)); + } +} diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties b/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties new file mode 100644 index 000000000..37ad2486c --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=harness-example-sandbox +server.port=8787 diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite b/agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


    i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..1203157cd --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,12 @@ +# Chinook Knowledge (sandbox demo) + +This Data Agent uses the Chinook SQLite sample database. + +Primary entities: +- `Artist` -> `Album` -> `Track` +- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` + +Guidance: +- Always discover schema with `sql_list_tables` and `sql_get_schema`. +- Use read-only `SELECT` statements. +- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..055899406 --- /dev/null +++ b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,14 @@ +--- +name: query-writing +description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). +--- + +# Query writing (sandbox) + +1. Call `sql_list_tables` if you do not yet know table names. +2. Call `sql_get_schema` for each table you join or filter on. +3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). +4. Summarise results in plain language. + +See the full skill in `agentscope-examples/harness-example` under +`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index b889e9edf..a59f6f4c4 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -112,7 +112,7 @@ * .name("MyAgent") * .model(model) * .sysPrompt("You are a helpful assistant.") - * .workspace(Path.of("/path/to/workspace")) + * .workspace("/path/to/workspace") * .build(); * * Msg response = agent.call( @@ -438,7 +438,6 @@ public static class Builder { private String environmentMemory; private AbstractFilesystem abstractFilesystem; private Session session; - private SandboxStateStore sandboxStateStore; private SandboxDistributedOptions sandboxDistributedOptions; /** @@ -552,12 +551,40 @@ public Builder toolExecutionContext(ToolExecutionContext ctx) { return this; } - /** Sets the workspace directory. Defaults to {@code ${cwd}/.agentscope/workspace}. */ + /** + * Sets the workspace directory. Pass {@code null} to use the default + * {@code ${cwd}/.agentscope/workspace}. + * + * @see #workspace(String) + */ public Builder workspace(Path workspace) { this.workspace = workspace; return this; } + /** + * Sets the workspace directory from a filesystem path string (resolved with + * {@link Path#of(String, String...)}). Equivalent to {@link #workspace(Path)} with + * {@code Path.of(path.strip())}. + * + *

    Pass {@code null} for the same default as {@link #workspace(Path)} with a {@code null} + * argument. Blank or whitespace-only strings are rejected. + * + * @param path absolute or relative path string, or {@code null} for the default workspace + */ + public Builder workspace(String path) { + if (path == null) { + this.workspace = null; + return this; + } + String trimmed = path.strip(); + if (trimmed.isEmpty()) { + throw new IllegalArgumentException("workspace path must not be blank"); + } + this.workspace = Path.of(trimmed); + return this; + } + public Builder environmentMemory(String environmentMemory) { this.environmentMemory = environmentMemory; return this; @@ -660,17 +687,6 @@ public Builder session(Session session) { return this; } - /** - * Overrides the store used to persist/resume sandbox session state. - * - *

    When not set, sandbox mode uses a {@link SessionSandboxStateStore} backed by the - * configured {@link #session(Session)} (or the default {@link WorkspaceSession}). - */ - public Builder sandboxStateStore(SandboxStateStore sandboxStateStore) { - this.sandboxStateStore = sandboxStateStore; - return this; - } - /** * Enables high-level distributed sandbox configuration. * @@ -881,8 +897,8 @@ public HarnessAgent build() { } SandboxStateStore stateStore = - sandboxStateStore != null - ? sandboxStateStore + sandboxFilesystemSpec.getSandboxStateStore() != null + ? sandboxFilesystemSpec.getSandboxStateStore() : new SessionSandboxStateStore(effectiveSession, resolvedAgentId); SandboxManager sandboxManager = new SandboxManager( @@ -1093,7 +1109,8 @@ private AbstractFilesystem resolveFilesystem( private void validateDistributedSandboxConfig( Session effectiveSession, SandboxContext sandboxContext) { - if (sandboxStateStore == null && effectiveSession instanceof WorkspaceSession) { + if (sandboxFilesystemSpec.getSandboxStateStore() == null + && effectiveSession instanceof WorkspaceSession) { throw new IllegalStateException( "sandboxDistributed(requireDistributed=true) requires a distributed" + " Session backend (for example RedisSession)." diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java index a22c5fa0a..815bed1f6 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/AbstractFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.filesystem; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.EditResult; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; import io.agentscope.harness.agent.filesystem.model.FileUploadResponse; @@ -30,91 +31,113 @@ * Abstract filesystem API for agents: list, read, write, edit, grep, glob, upload, download. * *

    Implementations may target the local disk, a sandbox, a key-value store, or other storage. + * Host-rooted types {@link LocalFilesystem} and {@link LocalFilesystemWithShell} also expose + * constructors that take the workspace root as a {@link String} path (same semantics as + * {@link java.nio.file.Path}). + * + *

    Every operation accepts a {@link RuntimeContext} so backends can scope work to the current + * session, user, or sandbox. Callers that are not inside a tool/agent call with a merged context + * should pass {@link RuntimeContext#empty()}. */ public interface AbstractFilesystem { /** * List all files in a directory with metadata. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param path absolute path to the directory to list (must start with '/') * @return LsResult with directory entries or error */ - LsResult ls(String path); + LsResult ls(RuntimeContext runtimeContext, String path); /** * Read file content with optional line-based pagination. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param filePath absolute path to the file to read (must start with '/') * @param offset line number to start reading from (0-indexed). Default: 0 * @param limit maximum number of lines to read. Default: 2000 * @return ReadResult with file data on success or error on failure */ - ReadResult read(String filePath, int offset, int limit); + ReadResult read(RuntimeContext runtimeContext, String filePath, int offset, int limit); /** * Write content to a new file, error if file already exists. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param filePath absolute path where the file should be created * @param content string content to write to the file * @return WriteResult with path on success, or error if the file already exists or write fails */ - WriteResult write(String filePath, String content); + WriteResult write(RuntimeContext runtimeContext, String filePath, String content); /** * Perform exact string replacements in an existing file. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param filePath absolute path to the file to edit * @param oldString exact string to search for and replace * @param newString string to replace oldString with (must be different from oldString) * @param replaceAll if true, replace all occurrences; if false, oldString must be unique * @return EditResult with path and occurrence count on success, or error on failure */ - EditResult edit(String filePath, String oldString, String newString, boolean replaceAll); + EditResult edit( + RuntimeContext runtimeContext, + String filePath, + String oldString, + String newString, + boolean replaceAll); /** * Search for a literal text pattern in files. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param pattern literal string to search for (not regex) * @param path optional directory path to search in (null searches current working directory) * @param glob optional glob pattern to filter which files to search (e.g., "*.java") * @return GrepResult with matches or error */ - GrepResult grep(String pattern, String path, String glob); + GrepResult grep(RuntimeContext runtimeContext, String pattern, String path, String glob); /** * Find files matching a glob pattern. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param pattern glob pattern with wildcards to match file paths * @param path base directory to search from (default: "/") * @return GlobResult with matching files or error */ - GlobResult glob(String pattern, String path); + GlobResult glob(RuntimeContext runtimeContext, String pattern, String path); /** * Upload multiple files. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param files list of path-to-content mappings to upload * @return list of FileUploadResponse objects, one per input file (order matches input order) */ - List uploadFiles(List> files); + List uploadFiles( + RuntimeContext runtimeContext, List> files); /** * Download multiple files. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param paths list of file paths to download * @return list of FileDownloadResponse objects, one per input path (order matches input order) */ - List downloadFiles(List paths); + List downloadFiles(RuntimeContext runtimeContext, List paths); /** * Delete a file or directory (recursive for directories). * *

    Idempotent: deleting a path that does not exist is treated as success. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param path absolute path to the file or directory to delete * @return WriteResult success when deleted (or already absent), failure on I/O error */ - WriteResult delete(String path); + WriteResult delete(RuntimeContext runtimeContext, String path); /** * Move (rename) a file or directory from {@code fromPath} to {@code toPath}. @@ -123,11 +146,12 @@ public interface AbstractFilesystem { * fall back to a read + write + delete sequence when source and destination live in * different backend filesystems. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param fromPath absolute source path * @param toPath absolute destination path * @return WriteResult success on completion, failure on I/O error or missing source */ - WriteResult move(String fromPath, String toPath); + WriteResult move(RuntimeContext runtimeContext, String fromPath, String toPath); /** * Check whether a file or directory exists. @@ -135,10 +159,11 @@ public interface AbstractFilesystem { *

    Implementations may approximate this with a lightweight read probe where a dedicated * {@code exists} API is unavailable, but should avoid reading full file content. * + * @param runtimeContext per-call agent runtime; {@link RuntimeContext#empty()} when none * @param path absolute path to check * @return {@code true} if the path exists, {@code false} otherwise */ - boolean exists(String path); + boolean exists(RuntimeContext runtimeContext, String path); // ==================== Path validation utility ==================== diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java index 8b8d0e4de..9e6cdba96 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/BaseSandboxFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.filesystem; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.EditResult; import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; import io.agentscope.harness.agent.filesystem.model.FileData; @@ -85,13 +86,15 @@ protected String namespacedPath(String path) { public abstract ExecuteResponse execute(String command, Integer timeoutSeconds); @Override - public abstract List uploadFiles(List> files); + public abstract List uploadFiles( + RuntimeContext runtimeContext, List> files); @Override - public abstract List downloadFiles(List paths); + public abstract List downloadFiles( + RuntimeContext runtimeContext, List paths); @Override - public LsResult ls(String path) { + public LsResult ls(RuntimeContext runtimeContext, String path) { String escapedPath = FilesystemUtils.shellQuote(namespacedPath(path)); String cmd = "for f in " @@ -118,7 +121,7 @@ public LsResult ls(String path) { } @Override - public ReadResult read(String filePath, int offset, int limit) { + public ReadResult read(RuntimeContext runtimeContext, String filePath, int offset, int limit) { String nsPath = namespacedPath(filePath); String fileType = FilesystemUtils.getFileType(nsPath); String escapedPath = FilesystemUtils.shellQuote(nsPath); @@ -168,7 +171,7 @@ public ReadResult read(String filePath, int offset, int limit) { } @Override - public WriteResult write(String filePath, String content) { + public WriteResult write(RuntimeContext runtimeContext, String filePath, String content) { String nsPath = namespacedPath(filePath); String escapedPath = FilesystemUtils.shellQuote(nsPath); String checkCmd = @@ -193,6 +196,7 @@ public WriteResult write(String filePath, String content) { List responses = uploadFiles( + runtimeContext, List.of( Map.entry( nsPath, @@ -209,7 +213,11 @@ public WriteResult write(String filePath, String content) { @Override public EditResult edit( - String filePath, String oldString, String newString, boolean replaceAll) { + RuntimeContext runtimeContext, + String filePath, + String oldString, + String newString, + boolean replaceAll) { String nsPath = namespacedPath(filePath); String payload = "{\"path\":\"" @@ -292,7 +300,8 @@ public EditResult edit( } @Override - public GrepResult grep(String pattern, String path, String glob) { + public GrepResult grep( + RuntimeContext runtimeContext, String pattern, String path, String glob) { String nsPath = path != null ? namespacedPath(path) : "."; String searchPath = FilesystemUtils.shellQuote(nsPath); String grepOpts = "-rHnF"; @@ -336,7 +345,7 @@ public GrepResult grep(String pattern, String path, String glob) { } @Override - public GlobResult glob(String pattern, String path) { + public GlobResult glob(RuntimeContext runtimeContext, String pattern, String path) { String effectivePath = path != null ? namespacedPath(path) : "/"; String escapedPath = FilesystemUtils.shellQuote(effectivePath); String escapedPattern = FilesystemUtils.shellQuote(pattern); @@ -362,7 +371,7 @@ public GlobResult glob(String pattern, String path) { } @Override - public WriteResult delete(String path) { + public WriteResult delete(RuntimeContext runtimeContext, String path) { AbstractFilesystem.validatePath(path); String effectivePath = namespacedPath(path); String escapedPath = FilesystemUtils.shellQuote(effectivePath); @@ -375,7 +384,7 @@ public WriteResult delete(String path) { } @Override - public WriteResult move(String fromPath, String toPath) { + public WriteResult move(RuntimeContext runtimeContext, String fromPath, String toPath) { AbstractFilesystem.validatePath(fromPath); AbstractFilesystem.validatePath(toPath); String from = namespacedPath(fromPath); @@ -392,7 +401,7 @@ public WriteResult move(String fromPath, String toPath) { } @Override - public boolean exists(String path) { + public boolean exists(RuntimeContext runtimeContext, String path) { if (path == null || path.isBlank()) { return false; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java index 29a21c3e3..3e57391a3 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/CompositeFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.filesystem; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.EditResult; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; import io.agentscope.harness.agent.filesystem.model.FileInfo; @@ -51,8 +52,8 @@ * localFs, * Map.of("/memories/", storeFs, "/cache/", inMemoryFs) * ); - * fs.read("/memories/notes.md", 0, 100); // → storeFs.read("/notes.md", ...) - * fs.read("/src/Main.java", 0, 100); // → localFs.read("/src/Main.java", ...) + * fs.read(RuntimeContext.empty(), "/memories/notes.md", 0, 100); // → storeFs.read(...) + * fs.read(RuntimeContext.empty(), "/src/Main.java", 0, 100); // → localFs.read(...) * } */ public class CompositeFilesystem implements AbstractFilesystem { @@ -146,11 +147,11 @@ private static String stripRouteFromPattern(String pattern, String routePrefix) // ==================== AbstractFilesystem ==================== @Override - public LsResult ls(String path) { + public LsResult ls(RuntimeContext runtimeContext, String path) { RouteResult route = routeForPath(path); if (route.routePrefix() != null) { - LsResult result = route.backend().ls(route.backendPath()); + LsResult result = route.backend().ls(runtimeContext, route.backendPath()); if (!result.isSuccess()) { return result; } @@ -163,7 +164,7 @@ public LsResult ls(String path) { if ("/".equals(path)) { List results = new ArrayList<>(); - LsResult defaultResult = defaultBackend.ls(path); + LsResult defaultResult = defaultBackend.ls(runtimeContext, path); if (defaultResult.isSuccess() && defaultResult.entries() != null) { results.addAll(defaultResult.entries()); } @@ -179,19 +180,19 @@ public LsResult ls(String path) { return LsResult.success(results); } - return defaultBackend.ls(path); + return defaultBackend.ls(runtimeContext, path); } @Override - public ReadResult read(String filePath, int offset, int limit) { + public ReadResult read(RuntimeContext runtimeContext, String filePath, int offset, int limit) { RouteResult route = routeForPath(filePath); - return route.backend().read(route.backendPath(), offset, limit); + return route.backend().read(runtimeContext, route.backendPath(), offset, limit); } @Override - public WriteResult write(String filePath, String content) { + public WriteResult write(RuntimeContext runtimeContext, String filePath, String content) { RouteResult route = routeForPath(filePath); - WriteResult result = route.backend().write(route.backendPath(), content); + WriteResult result = route.backend().write(runtimeContext, route.backendPath(), content); if (result.isSuccess() && route.routePrefix() != null) { return WriteResult.ok(filePath); } @@ -200,10 +201,20 @@ public WriteResult write(String filePath, String content) { @Override public EditResult edit( - String filePath, String oldString, String newString, boolean replaceAll) { + RuntimeContext runtimeContext, + String filePath, + String oldString, + String newString, + boolean replaceAll) { RouteResult route = routeForPath(filePath); EditResult result = - route.backend().edit(route.backendPath(), oldString, newString, replaceAll); + route.backend() + .edit( + runtimeContext, + route.backendPath(), + oldString, + newString, + replaceAll); if (result.isSuccess() && route.routePrefix() != null) { return EditResult.ok(filePath, result.occurrences()); } @@ -211,11 +222,13 @@ public EditResult edit( } @Override - public GrepResult grep(String pattern, String path, String glob) { + public GrepResult grep( + RuntimeContext runtimeContext, String pattern, String path, String glob) { if (path != null) { RouteResult route = routeForPath(path); if (route.routePrefix() != null) { - GrepResult result = route.backend().grep(pattern, route.backendPath(), glob); + GrepResult result = + route.backend().grep(runtimeContext, pattern, route.backendPath(), glob); if (!result.isSuccess()) { return result; } @@ -229,7 +242,7 @@ public GrepResult grep(String pattern, String path, String glob) { if (path == null || "/".equals(path)) { List allMatches = new ArrayList<>(); - GrepResult defaultResult = defaultBackend.grep(pattern, path, glob); + GrepResult defaultResult = defaultBackend.grep(runtimeContext, pattern, path, glob); if (!defaultResult.isSuccess()) { return defaultResult; } @@ -237,7 +250,7 @@ public GrepResult grep(String pattern, String path, String glob) { allMatches.addAll(defaultResult.matches()); } for (RouteEntry entry : sortedRoutes) { - GrepResult routeResult = entry.backend().grep(pattern, "/", glob); + GrepResult routeResult = entry.backend().grep(runtimeContext, pattern, "/", glob); if (!routeResult.isSuccess()) { return routeResult; } @@ -250,15 +263,15 @@ public GrepResult grep(String pattern, String path, String glob) { return GrepResult.success(allMatches); } - return defaultBackend.grep(pattern, path, glob); + return defaultBackend.grep(runtimeContext, pattern, path, glob); } @Override - public GlobResult glob(String pattern, String path) { + public GlobResult glob(RuntimeContext runtimeContext, String pattern, String path) { RouteResult route = routeForPath(path); if (route.routePrefix() != null) { - GlobResult result = route.backend().glob(pattern, route.backendPath()); + GlobResult result = route.backend().glob(runtimeContext, pattern, route.backendPath()); if (!result.isSuccess()) { return result; } @@ -270,13 +283,13 @@ public GlobResult glob(String pattern, String path) { } List results = new ArrayList<>(); - GlobResult defaultResult = defaultBackend.glob(pattern, path); + GlobResult defaultResult = defaultBackend.glob(runtimeContext, pattern, path); if (defaultResult.isSuccess() && defaultResult.matches() != null) { results.addAll(defaultResult.matches()); } for (RouteEntry entry : sortedRoutes) { String routePattern = stripRouteFromPattern(pattern, entry.prefix()); - GlobResult routeResult = entry.backend().glob(routePattern, "/"); + GlobResult routeResult = entry.backend().glob(runtimeContext, routePattern, "/"); if (routeResult.isSuccess() && routeResult.matches() != null) { for (FileInfo fi : routeResult.matches()) { results.add(remapFileInfo(fi, entry.prefix())); @@ -288,7 +301,8 @@ public GlobResult glob(String pattern, String path) { } @Override - public List uploadFiles(List> files) { + public List uploadFiles( + RuntimeContext runtimeContext, List> files) { FileUploadResponse[] results = new FileUploadResponse[files.size()]; Map> batches = new HashMap<>(); @@ -304,7 +318,8 @@ public List uploadFiles(List> file for (IndexedFile f : batch.getValue()) { batchFiles.add(Map.entry(f.backendPath(), f.content())); } - List responses = batch.getKey().uploadFiles(batchFiles); + List responses = + batch.getKey().uploadFiles(runtimeContext, batchFiles); List indexed = batch.getValue(); for (int i = 0; i < responses.size() && i < indexed.size(); i++) { results[indexed.get(i).originalIndex()] = @@ -316,7 +331,8 @@ public List uploadFiles(List> file } @Override - public List downloadFiles(List paths) { + public List downloadFiles( + RuntimeContext runtimeContext, List paths) { FileDownloadResponse[] results = new FileDownloadResponse[paths.size()]; Map> batches = new HashMap<>(); Map> batchPaths = new HashMap<>(); @@ -330,7 +346,8 @@ public List downloadFiles(List paths) { } for (Map.Entry> batch : batchPaths.entrySet()) { - List responses = batch.getKey().downloadFiles(batch.getValue()); + List responses = + batch.getKey().downloadFiles(runtimeContext, batch.getValue()); List indices = batches.get(batch.getKey()); for (int i = 0; i < responses.size() && i < indices.size(); i++) { FileDownloadResponse resp = responses.get(i); @@ -346,10 +363,10 @@ public List downloadFiles(List paths) { } @Override - public WriteResult delete(String path) { + public WriteResult delete(RuntimeContext runtimeContext, String path) { AbstractFilesystem.validatePath(path); RouteResult route = routeForPath(path); - WriteResult result = route.backend().delete(route.backendPath()); + WriteResult result = route.backend().delete(runtimeContext, route.backendPath()); if (result.isSuccess() && route.routePrefix() != null) { return WriteResult.ok(path); } @@ -357,7 +374,7 @@ public WriteResult delete(String path) { } @Override - public WriteResult move(String fromPath, String toPath) { + public WriteResult move(RuntimeContext runtimeContext, String fromPath, String toPath) { AbstractFilesystem.validatePath(fromPath); AbstractFilesystem.validatePath(toPath); RouteResult srcRoute = routeForPath(fromPath); @@ -365,7 +382,8 @@ public WriteResult move(String fromPath, String toPath) { if (srcRoute.backend() == dstRoute.backend()) { WriteResult result = - srcRoute.backend().move(srcRoute.backendPath(), dstRoute.backendPath()); + srcRoute.backend() + .move(runtimeContext, srcRoute.backendPath(), dstRoute.backendPath()); if (result.isSuccess()) { return WriteResult.ok(toPath); } @@ -373,7 +391,7 @@ public WriteResult move(String fromPath, String toPath) { } // Cross-backend move: read → write → delete - var readResult = srcRoute.backend().read(srcRoute.backendPath(), 0, 0); + var readResult = srcRoute.backend().read(runtimeContext, srcRoute.backendPath(), 0, 0); if (!readResult.isSuccess() || readResult.fileData() == null) { return WriteResult.fail("Cannot read source for cross-backend move: " + fromPath); } @@ -381,22 +399,23 @@ public WriteResult move(String fromPath, String toPath) { if (content == null) { content = ""; } - WriteResult writeResult = dstRoute.backend().write(dstRoute.backendPath(), content); + WriteResult writeResult = + dstRoute.backend().write(runtimeContext, dstRoute.backendPath(), content); if (!writeResult.isSuccess()) { return WriteResult.fail( "Cross-backend move write failed for '" + toPath + "': " + writeResult.error()); } - srcRoute.backend().delete(srcRoute.backendPath()); + srcRoute.backend().delete(runtimeContext, srcRoute.backendPath()); return WriteResult.ok(toPath); } @Override - public boolean exists(String path) { + public boolean exists(RuntimeContext runtimeContext, String path) { if (path == null || path.isBlank()) { return false; } RouteResult route = routeForPath(path); - return route.backend().exists(route.backendPath()); + return route.backend().exists(runtimeContext, route.backendPath()); } /** Returns the default backend. */ diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java index d149f21ad..3df13e4cf 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.filesystem; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.EditResult; import io.agentscope.harness.agent.filesystem.model.FileData; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; @@ -70,6 +71,17 @@ public class LocalFilesystem implements AbstractFilesystem { private final long maxFileSizeBytes; private final NamespaceFactory namespaceFactory; + /** + * Same as {@link #LocalFilesystem(Path)} with {@link Path#of(String, String...) Path.of(path)} + * after {@link String#strip()}. Pass {@code null} for the same CWD semantics as a {@code null} + * {@link Path}. Blank strings are rejected. + * + * @param rootDir filesystem root as a path string, or {@code null} for process working directory + */ + public LocalFilesystem(String rootDir) { + this(rootDirFromString(rootDir), false, DEFAULT_MAX_FILE_SIZE_MB, null); + } + /** * Creates a abstract filesystem rooted at the given directory. * @@ -90,6 +102,14 @@ public LocalFilesystem(Path rootDir, boolean virtualMode, int maxFileSizeMb) { this(rootDir, virtualMode, maxFileSizeMb, null); } + /** + * Same as {@link #LocalFilesystem(Path, boolean, int)} with a path string; see + * {@link #LocalFilesystem(String)} for {@code null} / blank rules. + */ + public LocalFilesystem(String rootDir, boolean virtualMode, int maxFileSizeMb) { + this(rootDirFromString(rootDir), virtualMode, maxFileSizeMb, null); + } + /** * Creates a abstract filesystem with explicit configuration and namespace support. * @@ -116,6 +136,33 @@ public LocalFilesystem( this.namespaceFactory = namespaceFactory; } + /** + * Same as {@link #LocalFilesystem(Path, boolean, int, NamespaceFactory)} with a path string; + * see {@link #LocalFilesystem(String)} for {@code null} / blank rules. + */ + public LocalFilesystem( + String rootDir, + boolean virtualMode, + int maxFileSizeMb, + NamespaceFactory namespaceFactory) { + this(rootDirFromString(rootDir), virtualMode, maxFileSizeMb, namespaceFactory); + } + + /** + * Converts a root path string to {@link Path}. {@code null} yields {@code null} (CWD). Non-null + * values must be non-blank after {@link String#strip()}. + */ + static Path rootDirFromString(String rootDir) { + if (rootDir == null) { + return null; + } + String trimmed = rootDir.strip(); + if (trimmed.isEmpty()) { + throw new IllegalArgumentException("root directory path must not be blank"); + } + return Path.of(trimmed); + } + /** * Returns the root directory for this filesystem. */ @@ -124,7 +171,7 @@ public Path getCwd() { } @Override - public LsResult ls(String path) { + public LsResult ls(RuntimeContext runtimeContext, String path) { Path dirPath = resolvePath(path); if (!Files.exists(dirPath) || !Files.isDirectory(dirPath)) { return LsResult.success(List.of()); @@ -159,7 +206,7 @@ public LsResult ls(String path) { } @Override - public ReadResult read(String filePath, int offset, int limit) { + public ReadResult read(RuntimeContext runtimeContext, String filePath, int offset, int limit) { Path resolved = resolvePath(filePath); if (!Files.exists(resolved) || !Files.isRegularFile(resolved)) { @@ -209,7 +256,7 @@ public ReadResult read(String filePath, int offset, int limit) { } @Override - public WriteResult write(String filePath, String content) { + public WriteResult write(RuntimeContext runtimeContext, String filePath, String content) { Path resolved = resolvePath(filePath); if (Files.exists(resolved)) { @@ -233,7 +280,11 @@ public WriteResult write(String filePath, String content) { @Override public EditResult edit( - String filePath, String oldString, String newString, boolean replaceAll) { + RuntimeContext runtimeContext, + String filePath, + String oldString, + String newString, + boolean replaceAll) { Path resolved = resolvePath(filePath); if (!Files.exists(resolved) || !Files.isRegularFile(resolved)) { @@ -264,7 +315,8 @@ public EditResult edit( } @Override - public GrepResult grep(String pattern, String path, String glob) { + public GrepResult grep( + RuntimeContext runtimeContext, String pattern, String path, String glob) { Path basePath; try { basePath = resolvePath(path != null ? path : "."); @@ -284,7 +336,7 @@ public GrepResult grep(String pattern, String path, String glob) { } @Override - public GlobResult glob(String pattern, String path) { + public GlobResult glob(RuntimeContext runtimeContext, String pattern, String path) { String effectivePattern = pattern; if (effectivePattern.startsWith("/")) { effectivePattern = effectivePattern.substring(1); @@ -341,7 +393,8 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) { } @Override - public List uploadFiles(List> files) { + public List uploadFiles( + RuntimeContext runtimeContext, List> files) { List responses = new ArrayList<>(); for (Map.Entry entry : files) { String filePath = entry.getKey(); @@ -363,7 +416,8 @@ public List uploadFiles(List> file } @Override - public List downloadFiles(List paths) { + public List downloadFiles( + RuntimeContext runtimeContext, List paths) { List responses = new ArrayList<>(); for (String filePath : paths) { try { @@ -388,7 +442,7 @@ public List downloadFiles(List paths) { } @Override - public WriteResult delete(String path) { + public WriteResult delete(RuntimeContext runtimeContext, String path) { AbstractFilesystem.validatePath(path); Path resolved = resolvePath(path); if (!Files.exists(resolved)) { @@ -417,7 +471,7 @@ public WriteResult delete(String path) { } @Override - public WriteResult move(String fromPath, String toPath) { + public WriteResult move(RuntimeContext runtimeContext, String fromPath, String toPath) { AbstractFilesystem.validatePath(fromPath); AbstractFilesystem.validatePath(toPath); Path from = resolvePath(fromPath); @@ -438,7 +492,7 @@ public WriteResult move(String fromPath, String toPath) { } @Override - public boolean exists(String path) { + public boolean exists(RuntimeContext runtimeContext, String path) { if (path == null || path.isBlank()) { return false; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java index b5d04b372..a70a1e80f 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/LocalFilesystemWithShell.java @@ -60,6 +60,21 @@ public LocalFilesystemWithShell(Path rootDir) { this(rootDir, false, DEFAULT_EXECUTE_TIMEOUT, 100_000, null, false, null); } + /** + * Same as {@link #LocalFilesystemWithShell(Path)} with a path string; see + * {@link LocalFilesystem#LocalFilesystem(String)} for {@code null} / blank rules. + */ + public LocalFilesystemWithShell(String rootDir) { + this( + LocalFilesystem.rootDirFromString(rootDir), + false, + DEFAULT_EXECUTE_TIMEOUT, + 100_000, + null, + false, + null); + } + /** * Creates an abstract filesystem with default settings and namespace support. * @@ -70,6 +85,21 @@ public LocalFilesystemWithShell(Path rootDir, NamespaceFactory namespaceFactory) this(rootDir, false, DEFAULT_EXECUTE_TIMEOUT, 100_000, null, false, namespaceFactory); } + /** + * Same as {@link #LocalFilesystemWithShell(Path, NamespaceFactory)} with a path string; see + * {@link LocalFilesystem#LocalFilesystem(String)} for {@code null} / blank rules. + */ + public LocalFilesystemWithShell(String rootDir, NamespaceFactory namespaceFactory) { + this( + LocalFilesystem.rootDirFromString(rootDir), + false, + DEFAULT_EXECUTE_TIMEOUT, + 100_000, + null, + false, + namespaceFactory); + } + /** * Creates a abstract filesystem with full configuration. * @@ -90,6 +120,27 @@ public LocalFilesystemWithShell( this(rootDir, virtualMode, timeout, maxOutputBytes, env, inheritEnv, null); } + /** + * Same as {@link #LocalFilesystemWithShell(Path, boolean, int, int, Map, boolean)} with a path + * string; see {@link LocalFilesystem#LocalFilesystem(String)} for {@code null} / blank rules. + */ + public LocalFilesystemWithShell( + String rootDir, + boolean virtualMode, + int timeout, + int maxOutputBytes, + Map env, + boolean inheritEnv) { + this( + LocalFilesystem.rootDirFromString(rootDir), + virtualMode, + timeout, + maxOutputBytes, + env, + inheritEnv, + null); + } + /** * Creates a abstract filesystem with full configuration and namespace support. * @@ -130,6 +181,29 @@ public LocalFilesystemWithShell( } } + /** + * Same as {@link #LocalFilesystemWithShell(Path, boolean, int, int, Map, boolean, + * NamespaceFactory)} with a path string; see {@link LocalFilesystem#LocalFilesystem(String)} + * for {@code null} / blank rules. + */ + public LocalFilesystemWithShell( + String rootDir, + boolean virtualMode, + int timeout, + int maxOutputBytes, + Map env, + boolean inheritEnv, + NamespaceFactory namespaceFactory) { + this( + LocalFilesystem.rootDirFromString(rootDir), + virtualMode, + timeout, + maxOutputBytes, + env, + inheritEnv, + namespaceFactory); + } + @Override public String id() { return sandboxId; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java index fc0cafb79..42d93248e 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/filesystem/RemoteFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.filesystem; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.EditResult; import io.agentscope.harness.agent.filesystem.model.FileData; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; @@ -115,7 +116,7 @@ private List getNamespace() { } @Override - public LsResult ls(String path) { + public LsResult ls(RuntimeContext runtimeContext, String path) { List items = searchAllItems(); List infos = new ArrayList<>(); Set subdirs = new LinkedHashSet<>(); @@ -154,7 +155,7 @@ public LsResult ls(String path) { } @Override - public ReadResult read(String filePath, int offset, int limit) { + public ReadResult read(RuntimeContext runtimeContext, String filePath, int offset, int limit) { StoreItem item = store.get(getNamespace(), filePath); if (item == null) { return ReadResult.fail("File '" + filePath + "' not found"); @@ -200,7 +201,7 @@ public ReadResult read(String filePath, int offset, int limit) { } @Override - public WriteResult write(String filePath, String content) { + public WriteResult write(RuntimeContext runtimeContext, String filePath, String content) { List ns = getNamespace(); StoreItem existing = store.get(ns, filePath); if (existing != null) { @@ -218,7 +219,11 @@ public WriteResult write(String filePath, String content) { @Override public EditResult edit( - String filePath, String oldString, String newString, boolean replaceAll) { + RuntimeContext runtimeContext, + String filePath, + String oldString, + String newString, + boolean replaceAll) { List ns = getNamespace(); StoreItem item = store.get(ns, filePath); if (item == null) { @@ -247,7 +252,8 @@ public EditResult edit( } @Override - public GrepResult grep(String pattern, String path, String glob) { + public GrepResult grep( + RuntimeContext runtimeContext, String pattern, String path, String glob) { List items = searchAllItems(); String normalizedPath = normalizePath(path); @@ -288,7 +294,7 @@ public GrepResult grep(String pattern, String path, String glob) { } @Override - public GlobResult glob(String pattern, String path) { + public GlobResult glob(RuntimeContext runtimeContext, String pattern, String path) { List items = searchAllItems(); String normalizedPath = normalizePath(path); String effectivePattern = pattern.startsWith("/") ? pattern.substring(1) : pattern; @@ -328,7 +334,8 @@ public GlobResult glob(String pattern, String path) { } @Override - public List uploadFiles(List> files) { + public List uploadFiles( + RuntimeContext runtimeContext, List> files) { List ns = getNamespace(); List responses = new ArrayList<>(); for (Map.Entry entry : files) { @@ -353,7 +360,8 @@ public List uploadFiles(List> file } @Override - public List downloadFiles(List paths) { + public List downloadFiles( + RuntimeContext runtimeContext, List paths) { List ns = getNamespace(); List responses = new ArrayList<>(); for (String filePath : paths) { @@ -381,7 +389,7 @@ public List downloadFiles(List paths) { } @Override - public WriteResult delete(String path) { + public WriteResult delete(RuntimeContext runtimeContext, String path) { AbstractFilesystem.validatePath(path); List ns = getNamespace(); List items = searchAllItems(); @@ -398,7 +406,7 @@ public WriteResult delete(String path) { } @Override - public WriteResult move(String fromPath, String toPath) { + public WriteResult move(RuntimeContext runtimeContext, String fromPath, String toPath) { AbstractFilesystem.validatePath(fromPath); AbstractFilesystem.validatePath(toPath); List ns = getNamespace(); @@ -422,7 +430,7 @@ public WriteResult move(String fromPath, String toPath) { } @Override - public boolean exists(String path) { + public boolean exists(RuntimeContext runtimeContext, String path) { if (path == null || path.isBlank()) { return false; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java index e2915aa1f..9c13c11ce 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryMaintenanceHook.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.hook; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PostCallEvent; @@ -55,6 +56,8 @@ */ public class MemoryMaintenanceHook implements Hook { + private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); + private static final Logger log = LoggerFactory.getLogger(MemoryMaintenanceHook.class); /** Default minimum gap between two maintenance runs. */ @@ -126,7 +129,7 @@ private void expireDailyFiles() { if (fs == null) { return; } - GlobResult glob = fs.glob("*.md", WorkspaceConstants.MEMORY_DIR); + GlobResult glob = fs.glob(DEFAULT_FS_RUNTIME, "*.md", WorkspaceConstants.MEMORY_DIR); if (glob == null || glob.matches() == null) { return; } @@ -149,7 +152,7 @@ private void expireDailyFiles() { if (fileDate.isBefore(cutoff)) { String fromPath = WorkspaceConstants.MEMORY_DIR + "/" + fileName; String toPath = WorkspaceConstants.MEMORY_DIR + "/archive/" + fileName; - fs.move(fromPath, toPath); + fs.move(DEFAULT_FS_RUNTIME, fromPath, toPath); log.debug("Archived expired daily file: {}", fileName); } } catch (Exception e) { @@ -174,7 +177,7 @@ private void pruneOldSessions() { if (fs == null) { return; } - GlobResult glob = fs.glob("*.log.jsonl", WorkspaceConstants.AGENTS_DIR); + GlobResult glob = fs.glob(DEFAULT_FS_RUNTIME, "*.log.jsonl", WorkspaceConstants.AGENTS_DIR); if (glob == null || glob.matches() == null) { return; } @@ -191,7 +194,7 @@ private void pruneOldSessions() { try { Instant modified = Instant.parse(modifiedAt); if (modified.isBefore(cutoff)) { - fs.delete(fi.path()); + fs.delete(DEFAULT_FS_RUNTIME, fi.path()); log.debug("Pruned old session file: {}", fi.path()); } } catch (Exception e) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java index 72d71a2ab..6d746da6e 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SandboxLifecycleHook.java @@ -27,6 +27,7 @@ import io.agentscope.harness.agent.sandbox.SandboxBackedFilesystem; import io.agentscope.harness.agent.sandbox.SandboxContext; import io.agentscope.harness.agent.sandbox.SandboxManager; +import java.util.concurrent.atomic.AtomicReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; @@ -64,11 +65,15 @@ public class SandboxLifecycleHook implements Hook, RuntimeContextAware { private RuntimeContext runtimeContext; /** - * Thread-local acquire result to track the session acquired for the current call. - * Using ThreadLocal allows concurrent calls on different threads to have independent - * session state. + * Holds the acquire result between {@link PreCallEvent} and {@link PostCallEvent}. + * + *

    Not {@link ThreadLocal}: Reactor may resume hook stages on different threads, so a + * thread-local would drop the handle and skip persist/release. A typical {@link + * io.agentscope.harness.agent.HarnessAgent} rejects concurrent calls per agent, so a single + * {@link AtomicReference} is sufficient. */ - private final ThreadLocal currentAcquireResult = new ThreadLocal<>(); + private final AtomicReference currentAcquireResult = + new AtomicReference<>(); /** * Creates the hook. @@ -157,10 +162,13 @@ private Mono handlePreCall(T event) { private Mono handlePost(T event) { return Mono.fromCallable( () -> { - SandboxAcquireResult result = currentAcquireResult.get(); - currentAcquireResult.remove(); + SandboxAcquireResult result = currentAcquireResult.getAndSet(null); if (result == null) { + log.warn( + "[sandbox-hook] PostCall/ErrorEvent: no in-flight acquire result" + + " (persist/release skipped — was PreCall skipped or ref" + + " already consumed?)"); return event; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java index 455478bd3..f7c6e463f 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/ToolResultEvictionHook.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.hook; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PostActingEvent; @@ -64,6 +65,8 @@ */ public class ToolResultEvictionHook implements Hook { + private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); + private static final Logger log = LoggerFactory.getLogger(ToolResultEvictionHook.class); private final AbstractFilesystem filesystem; @@ -108,7 +111,7 @@ public Mono onEvent(T event) { String evictionPath = buildEvictionPath(agentName, toolCallId); try { - WriteResult writeResult = filesystem.write(evictionPath, fullText); + WriteResult writeResult = filesystem.write(DEFAULT_FS_RUNTIME, evictionPath, fullText); if (!writeResult.isSuccess()) { log.warn( "[{}] Failed to evict tool result [tool={}, id={}]: {}", diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java index 4e290c9b2..324d6726a 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryConsolidator.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.memory; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; @@ -55,6 +56,8 @@ */ public class MemoryConsolidator { + private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); + private static final Logger log = LoggerFactory.getLogger(MemoryConsolidator.class); /** Hidden state file inside {@code memory/} tracking the last consolidation Instant. */ @@ -186,7 +189,7 @@ private String readDailyEntries(Instant watermark) { return ""; } - GlobResult glob = fs.glob("*.md", "memory"); + GlobResult glob = fs.glob(DEFAULT_FS_RUNTIME, "*.md", "memory"); if (!glob.isSuccess() || glob.matches() == null || glob.matches().isEmpty()) { return ""; } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java index e333e691e..84580428d 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.memory.session; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.util.JsonUtils; import io.agentscope.harness.agent.filesystem.AbstractFilesystem; import io.agentscope.harness.agent.filesystem.model.ReadResult; @@ -53,6 +54,8 @@ */ public class SessionTree { + private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); + private static final Logger log = LoggerFactory.getLogger(SessionTree.class); private static final int SESSION_FORMAT_VERSION = 1; @@ -318,7 +321,7 @@ private void restoreFromMirror(Path file) { if (relativePath == null || relativePath.isBlank()) { return; } - ReadResult read = filesystem.read(relativePath, 0, 0); + ReadResult read = filesystem.read(DEFAULT_FS_RUNTIME, relativePath, 0, 0); if (!read.isSuccess() || read.fileData() == null || read.fileData().content() == null) { return; } @@ -351,7 +354,7 @@ private void mirrorToFilesystem(Path file) { } try { byte[] bytes = Files.readAllBytes(file); - filesystem.uploadFiles(List.of(Map.entry(relativePath, bytes))); + filesystem.uploadFiles(DEFAULT_FS_RUNTIME, List.of(Map.entry(relativePath, bytes))); } catch (IOException e) { log.warn("Failed to mirror session file {} to filesystem: {}", file, e.getMessage()); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java index 401f72448..3e19b1669 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxBackedFilesystem.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.sandbox; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.BaseSandboxFilesystem; import io.agentscope.harness.agent.filesystem.model.ExecuteResponse; import io.agentscope.harness.agent.filesystem.model.FileDownloadResponse; @@ -89,7 +90,8 @@ public ExecuteResponse execute(String command, Integer timeoutSeconds) { } @Override - public List uploadFiles(List> files) { + public List uploadFiles( + RuntimeContext runtimeContext, List> files) { Sandbox active = requireSandbox(); List results = new ArrayList<>(files.size()); @@ -132,7 +134,8 @@ public List uploadFiles(List> file } @Override - public List downloadFiles(List paths) { + public List downloadFiles( + RuntimeContext runtimeContext, List paths) { Sandbox active = requireSandbox(); List results = new ArrayList<>(paths.size()); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java index 9299f00fe..50f4aa287 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/SandboxFilesystemSpec.java @@ -19,6 +19,7 @@ import io.agentscope.harness.agent.sandbox.SandboxClient; import io.agentscope.harness.agent.sandbox.SandboxClientOptions; import io.agentscope.harness.agent.sandbox.SandboxContext; +import io.agentscope.harness.agent.sandbox.SandboxStateStore; import io.agentscope.harness.agent.sandbox.WorkspaceSpec; import io.agentscope.harness.agent.sandbox.layout.WorkspaceEntry; import io.agentscope.harness.agent.sandbox.layout.WorkspaceProjectionEntry; @@ -42,6 +43,7 @@ public abstract class SandboxFilesystemSpec { private IsolationScope isolationScope; private SandboxSnapshotSpec snapshotSpecOverride; + private SandboxStateStore sandboxStateStore; private boolean workspaceProjectionEnabled = true; private List workspaceProjectionRoots = DEFAULT_WORKSPACE_PROJECTION_ROOTS; @@ -71,6 +73,24 @@ public SandboxSnapshotSpec getSnapshotSpecOverride() { return snapshotSpecOverride; } + /** + * Overrides the {@link SandboxStateStore} used to persist and resume sandbox metadata across + * calls. When {@code null} (default), {@link io.agentscope.harness.agent.HarnessAgent} uses + * {@link io.agentscope.harness.agent.sandbox.SessionSandboxStateStore} with the effective + * {@link io.agentscope.core.session.Session} and agent id at build time. + * + * @param sandboxStateStore custom store, or {@code null} for the default session-backed store + * @return this spec + */ + public SandboxFilesystemSpec sandboxStateStore(SandboxStateStore sandboxStateStore) { + this.sandboxStateStore = sandboxStateStore; + return this; + } + + public SandboxStateStore getSandboxStateStore() { + return sandboxStateStore; + } + public SandboxFilesystemSpec workspaceProjectionEnabled(boolean enabled) { this.workspaceProjectionEnabled = enabled; return this; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java index 13467fe10..f002fa2c3 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/FilesystemTool.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.tool; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.tool.Tool; import io.agentscope.core.tool.ToolParam; import io.agentscope.harness.agent.filesystem.AbstractFilesystem; @@ -47,6 +48,7 @@ public FilesystemTool(AbstractFilesystem abstractFilesystem) { "Read file content with line numbers. Supports pagination via offset and" + " limit.") public String readFile( + RuntimeContext runtimeContext, @ToolParam(name = "path", description = "File path to read") String path, @ToolParam( name = "offset", @@ -54,7 +56,7 @@ public String readFile( int offset, @ToolParam(name = "limit", description = "Max lines to return. Default: 0 (all lines)") int limit) { - ReadResult r = abstractFilesystem.read(path, offset, limit); + ReadResult r = abstractFilesystem.read(runtimeContext, path, offset, limit); if (!r.isSuccess()) { return "Error: " + r.error(); } @@ -65,9 +67,10 @@ public String readFile( name = "write_file", description = "Write content to a new file, creating parent directories if needed.") public String writeFile( + RuntimeContext runtimeContext, @ToolParam(name = "path", description = "Target file path") String path, @ToolParam(name = "content", description = "File content to write") String content) { - WriteResult r = abstractFilesystem.write(path, content); + WriteResult r = abstractFilesystem.write(runtimeContext, path, content); return r.isSuccess() ? "Written to " + r.path() : "Error: " + r.error(); } @@ -77,6 +80,7 @@ public String writeFile( "Perform exact string replacement in a file. The old_string must be unique" + " unless replace_all is true.") public String editFile( + RuntimeContext runtimeContext, @ToolParam(name = "path", description = "File to edit") String path, @ToolParam(name = "old_string", description = "Text to find") String oldString, @ToolParam(name = "new_string", description = "Replacement text") String newString, @@ -84,7 +88,8 @@ public String editFile( name = "replace_all", description = "Replace all occurrences (default: false)") boolean replaceAll) { - EditResult r = abstractFilesystem.edit(path, oldString, newString, replaceAll); + EditResult r = + abstractFilesystem.edit(runtimeContext, path, oldString, newString, replaceAll); return r.isSuccess() ? "Edited " + r.path() + " (" + r.occurrences() + " replacement(s))" : "Error: " + r.error(); @@ -92,12 +97,13 @@ public String editFile( @Tool(name = "grep_files", description = "Search file contents for a literal text pattern.") public String grepFiles( + RuntimeContext runtimeContext, @ToolParam(name = "pattern", description = "Literal text pattern to search for") String pattern, @ToolParam(name = "path", description = "Directory or file to search") String path, @ToolParam(name = "glob", description = "Optional file glob filter (e.g., *.java)") String glob) { - GrepResult r = abstractFilesystem.grep(pattern, path, glob); + GrepResult r = abstractFilesystem.grep(runtimeContext, pattern, path, glob); if (!r.isSuccess()) { return "Error: " + r.error(); } @@ -112,10 +118,11 @@ public String grepFiles( @Tool(name = "glob_files", description = "Find files matching a glob pattern.") public String globFiles( + RuntimeContext runtimeContext, @ToolParam(name = "pattern", description = "Glob pattern (e.g., **/*.java)") String pattern, @ToolParam(name = "path", description = "Base directory to search from") String path) { - GlobResult r = abstractFilesystem.glob(pattern, path); + GlobResult r = abstractFilesystem.glob(runtimeContext, pattern, path); if (!r.isSuccess()) { return "Error: " + r.error(); } @@ -130,8 +137,9 @@ public String globFiles( @Tool(name = "list_files", description = "List files and directories at the given path.") public String listFiles( + RuntimeContext runtimeContext, @ToolParam(name = "path", description = "Directory path to list") String path) { - LsResult r = abstractFilesystem.ls(path); + LsResult r = abstractFilesystem.ls(runtimeContext, path); if (!r.isSuccess()) { return "Error: " + r.error(); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java index b97ab1e5a..d792f7360 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/MemorySearchTool.java @@ -29,7 +29,7 @@ * *

    Uses keyword-based search through all memory files visible via the configured * {@link io.agentscope.harness.agent.filesystem.AbstractFilesystem} (works across Local, - * Sandbox, and Store backends without any local SQLite dependency). + * Sandbox, and Store backends). */ public class MemorySearchTool { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java index 74f6e2659..698271e09 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/ShellExecuteTool.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.agent.tool; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.tool.Tool; import io.agentscope.core.tool.ToolParam; import io.agentscope.harness.agent.filesystem.AbstractSandboxFilesystem; @@ -31,11 +32,16 @@ public ShellExecuteTool(AbstractSandboxFilesystem sandbox) { this.sandbox = sandbox; } + /** + * @param runtimeContext per-call agent runtime injected by the framework (not an LLM argument); + * may be {@code null} when no merged context is available + */ @Tool( description = "Execute a shell command. Use for git, npm, build, test, and other terminal" + " operations. Returns combined output and exit code.") public String execute( + RuntimeContext runtimeContext, @ToolParam(name = "command", description = "Shell command to execute") String command, @ToolParam( name = "working_directory", diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java index aef74b460..fb7f78b22 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/workspace/WorkspaceManager.java @@ -28,6 +28,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.AbstractFilesystem; import io.agentscope.harness.agent.filesystem.model.FileInfo; import io.agentscope.harness.agent.filesystem.model.GlobResult; @@ -78,6 +79,8 @@ */ public class WorkspaceManager { + private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); + private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class); private static final ObjectMapper SESSION_STORE_JSON = new ObjectMapper(); @@ -177,7 +180,7 @@ public List listKnowledgeFiles() { Set relativePaths = new LinkedHashSet<>(); if (filesystem != null) { - GlobResult glob = filesystem.glob("*", KNOWLEDGE_DIR); + GlobResult glob = filesystem.glob(DEFAULT_FS_RUNTIME, "*", KNOWLEDGE_DIR); if (glob.isSuccess() && glob.matches() != null) { for (FileInfo fi : glob.matches()) { if (fi.path() != null && !fi.path().isBlank()) { @@ -252,13 +255,14 @@ public void appendUtf8WorkspaceRelative(String relativePath, String content) { appendLocalFile(normalized, content); return; } - ReadResult rr = filesystem.read(normalized, 0, 0); + ReadResult rr = filesystem.read(DEFAULT_FS_RUNTIME, normalized, 0, 0); String existing = ""; if (rr.isSuccess() && rr.fileData() != null && rr.fileData().content() != null) { existing = rr.fileData().content(); } String merged = existing + content; filesystem.uploadFiles( + DEFAULT_FS_RUNTIME, List.of(Map.entry(normalized, merged.getBytes(StandardCharsets.UTF_8)))); } @@ -337,6 +341,7 @@ public void writeUtf8WorkspaceRelative(String relativePath, String content) { return; } filesystem.uploadFiles( + DEFAULT_FS_RUNTIME, List.of(Map.entry(normalized, content.getBytes(StandardCharsets.UTF_8)))); } @@ -370,7 +375,7 @@ private String readTextThroughFilesystem(String filePath) { if (filesystem == null) { return ""; } - ReadResult r = filesystem.read(filePath, 0, 0); + ReadResult r = filesystem.read(DEFAULT_FS_RUNTIME, filePath, 0, 0); if (!r.isSuccess() || r.fileData() == null) { return ""; } @@ -441,11 +446,11 @@ public List listMemoryFilePaths() { Set paths = new LinkedHashSet<>(); if (filesystem != null) { - ReadResult memMd = filesystem.read(MEMORY_MD, 0, 1); + ReadResult memMd = filesystem.read(DEFAULT_FS_RUNTIME, MEMORY_MD, 0, 1); if (memMd.isSuccess()) { paths.add(MEMORY_MD); } - GlobResult glob = filesystem.glob("*.md", MEMORY_DIR); + GlobResult glob = filesystem.glob(DEFAULT_FS_RUNTIME, "*.md", MEMORY_DIR); if (glob.isSuccess() && glob.matches() != null) { for (FileInfo fi : glob.matches()) { if (fi.path() != null && !fi.path().isBlank()) { @@ -482,7 +487,7 @@ public List listSessionLogFiles() { Set paths = new LinkedHashSet<>(); if (filesystem != null) { - GlobResult glob = filesystem.glob("*.log.jsonl", AGENTS_DIR); + GlobResult glob = filesystem.glob(DEFAULT_FS_RUNTIME, "*.log.jsonl", AGENTS_DIR); if (glob.isSuccess() && glob.matches() != null) { for (FileInfo fi : glob.matches()) { if (fi.path() != null && !fi.path().isBlank()) { diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java index f9ecedea1..4c25b57ea 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java @@ -83,7 +83,7 @@ void localFilesystem_filesPersistAcrossCalls() throws Exception { HarnessAgent.builder() .name("my-local-assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .abstractFilesystem(new LocalFilesystemWithShell(workspace)) .build(); @@ -122,7 +122,7 @@ void localFilesystem_workspaceIsNotPartitionedByUserOrSession() throws Exception HarnessAgent.builder() .name("my-local-assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .abstractFilesystem(new LocalFilesystemWithShell(workspace)) .build(); @@ -151,7 +151,7 @@ void localFilesystem_directDiskAccessFromHostProcess() throws Exception { HarnessAgent.builder() .name("my-local-assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .abstractFilesystem(new LocalFilesystemWithShell(workspace)) .build(); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java index a3f6c3ea6..dd89b5956 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java @@ -95,7 +95,7 @@ void sessionScope_differentSessions_isolatedNamespaces() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) @@ -128,7 +128,7 @@ void sessionScope_sameSession_sharedNamespace() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) @@ -165,7 +165,7 @@ void userScope_sameUser_sharedAcrossSessions() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); @@ -198,7 +198,7 @@ void userScope_differentUsers_isolatedNamespaces() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) .build(); @@ -231,7 +231,7 @@ void agentScope_allCallersShareOneNamespace() throws Exception { HarnessAgent.builder() .name("shared-assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.AGENT)) diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java index 40191f8fc..dbec25950 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -89,7 +89,7 @@ void sessionScope_sameSession_resumesSandbox() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) .build(); @@ -119,7 +119,7 @@ void sessionScope_differentSession_createsFreshSandbox() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) .build(); @@ -153,7 +153,7 @@ void userScope_sameUser_differentSessions_resumesSandbox() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) .build(); @@ -182,7 +182,7 @@ void userScope_differentUsers_createsFreshSandbox() throws Exception { HarnessAgent.builder() .name("assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) .build(); @@ -215,7 +215,7 @@ void agentScope_allCallsShareOneSandbox() throws Exception { HarnessAgent.builder() .name("shared-assistant") .model(stubModel("done")) - .workspace(workspace) + .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) .build(); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java index 86111d29e..60a9ef6ce 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/FilesystemDeleteMoveExistsTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.model.WriteResult; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; @@ -37,6 +38,8 @@ */ class FilesystemDeleteMoveExistsTest { + private static final RuntimeContext RT = RuntimeContext.empty(); + // ================================================================ // LocalFilesystem — non-virtual mode, relative paths (no leading '/') // ================================================================ @@ -46,13 +49,13 @@ void local_exists_true(@TempDir Path tmp) throws Exception { LocalFilesystem fs = new LocalFilesystem(tmp); Files.writeString(tmp.resolve("file.txt"), "hello"); - assertTrue(fs.exists("file.txt")); + assertTrue(fs.exists(RT, "file.txt")); } @Test void local_exists_false(@TempDir Path tmp) { LocalFilesystem fs = new LocalFilesystem(tmp); - assertFalse(fs.exists("nonexistent.txt")); + assertFalse(fs.exists(RT, "nonexistent.txt")); } @Test @@ -60,7 +63,7 @@ void local_delete_file(@TempDir Path tmp) throws Exception { LocalFilesystem fs = new LocalFilesystem(tmp); Path f = Files.writeString(tmp.resolve("del.txt"), "data"); - WriteResult result = fs.delete("del.txt"); + WriteResult result = fs.delete(RT, "del.txt"); assertTrue(result.isSuccess()); assertFalse(Files.exists(f)); } @@ -68,7 +71,7 @@ void local_delete_file(@TempDir Path tmp) throws Exception { @Test void local_delete_idempotent(@TempDir Path tmp) { LocalFilesystem fs = new LocalFilesystem(tmp); - WriteResult result = fs.delete("ghost.txt"); + WriteResult result = fs.delete(RT, "ghost.txt"); assertTrue(result.isSuccess(), "deleting nonexistent should succeed (idempotent)"); } @@ -80,7 +83,7 @@ void local_delete_directory_recursive(@TempDir Path tmp) throws Exception { Files.writeString(dir.resolve("a.txt"), "a"); Files.writeString(dir.resolve("b.txt"), "b"); - WriteResult result = fs.delete("subdir"); + WriteResult result = fs.delete(RT, "subdir"); assertTrue(result.isSuccess()); assertFalse(Files.exists(dir)); } @@ -90,7 +93,7 @@ void local_move_file(@TempDir Path tmp) throws Exception { LocalFilesystem fs = new LocalFilesystem(tmp); Files.writeString(tmp.resolve("src.txt"), "content"); - WriteResult result = fs.move("src.txt", "dst.txt"); + WriteResult result = fs.move(RT, "src.txt", "dst.txt"); assertTrue(result.isSuccess()); assertFalse(Files.exists(tmp.resolve("src.txt"))); assertTrue(Files.exists(tmp.resolve("dst.txt"))); @@ -99,7 +102,7 @@ void local_move_file(@TempDir Path tmp) throws Exception { @Test void local_move_missingSource(@TempDir Path tmp) { LocalFilesystem fs = new LocalFilesystem(tmp); - WriteResult result = fs.move("missing.txt", "dst.txt"); + WriteResult result = fs.move(RT, "missing.txt", "dst.txt"); assertFalse(result.isSuccess()); } @@ -118,13 +121,13 @@ void store_exists_true() { InMemoryStore s = storeWith("/file.txt", "hello"); RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); - assertTrue(fs.exists("/file.txt")); + assertTrue(fs.exists(RT, "/file.txt")); } @Test void store_exists_false() { RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); - assertFalse(fs.exists("/nope.txt")); + assertFalse(fs.exists(RT, "/nope.txt")); } @Test @@ -132,7 +135,7 @@ void store_delete_file() { InMemoryStore s = storeWith("/file.txt", "hello"); RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); - WriteResult result = fs.delete("/file.txt"); + WriteResult result = fs.delete(RT, "/file.txt"); assertTrue(result.isSuccess()); assertNull(s.get(List.of("ns"), "/file.txt")); } @@ -140,7 +143,7 @@ void store_delete_file() { @Test void store_delete_idempotent() { RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); - WriteResult result = fs.delete("/ghost.txt"); + WriteResult result = fs.delete(RT, "/ghost.txt"); assertTrue(result.isSuccess()); } @@ -149,7 +152,7 @@ void store_move_file() { InMemoryStore s = storeWith("/src.txt", "data"); RemoteFilesystem fs = new RemoteFilesystem(s, List.of("ns")); - WriteResult result = fs.move("/src.txt", "/dst.txt"); + WriteResult result = fs.move(RT, "/src.txt", "/dst.txt"); assertTrue(result.isSuccess()); assertNull(s.get(List.of("ns"), "/src.txt")); assertNotNull(s.get(List.of("ns"), "/dst.txt")); @@ -158,7 +161,7 @@ void store_move_file() { @Test void store_move_missingSource() { RemoteFilesystem fs = new RemoteFilesystem(new InMemoryStore(), List.of("ns")); - WriteResult result = fs.move("/missing.txt", "/dst.txt"); + WriteResult result = fs.move(RT, "/missing.txt", "/dst.txt"); assertFalse(result.isSuccess()); } @@ -174,8 +177,8 @@ void composite_exists_routedToStore(@TempDir Path tmp) { CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); - assertTrue(fs.exists("MEMORY.md")); - assertFalse(fs.exists("notExist.txt")); + assertTrue(fs.exists(RT, "MEMORY.md")); + assertFalse(fs.exists(RT, "notExist.txt")); } @Test @@ -186,7 +189,7 @@ void composite_delete_routedToStore(@TempDir Path tmp) { CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("MEMORY.md", storeFsys)); - WriteResult result = fs.delete("MEMORY.md"); + WriteResult result = fs.delete(RT, "MEMORY.md"); assertTrue(result.isSuccess()); assertNull(s.get(List.of("ns"), "/MEMORY.md")); } @@ -206,7 +209,7 @@ void composite_move_crossBackend_storeToLocal(@TempDir Path tmp) throws Exceptio CompositeFilesystem fs = new CompositeFilesystem(local, Map.of("memory/", storeFsys)); // Move from store-routed path to a local-only path - WriteResult result = fs.move("memory/2025-01-01.md", "archive/2025-01-01.md"); + WriteResult result = fs.move(RT, "memory/2025-01-01.md", "archive/2025-01-01.md"); assertTrue(result.isSuccess(), "cross-backend move should succeed"); // Source removed from store assertNull(s.get(ns, "/2025-01-01.md"), "source should be deleted from store"); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java index 77340c056..478315677 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/filesystem/RemoteFilesystemSpecTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.harness.agent.store.InMemoryStore; import io.agentscope.harness.agent.store.NamespaceFactory; import java.nio.charset.StandardCharsets; @@ -31,6 +32,8 @@ class RemoteFilesystemSpecTest { + private static final RuntimeContext RT = RuntimeContext.empty(); + @TempDir Path workspace; @Test @@ -45,12 +48,14 @@ void routesSharedPathsToStoreAndOthersToLocal() throws Exception { .toFilesystem(workspace, "agent-a", localNs, userRef::get); fs.uploadFiles( + RT, List.of( java.util.Map.entry( "MEMORY.md", "hello".getBytes(StandardCharsets.UTF_8)))); assertNotNull(store.get(List.of("agents", "agent-a", "users", "anon"), "/MEMORY.md")); fs.uploadFiles( + RT, List.of( java.util.Map.entry( "knowledge/notes.md", "local".getBytes(StandardCharsets.UTF_8)))); @@ -67,6 +72,7 @@ void resolvesNamespaceByRuntimeUserId() { .toFilesystem(workspace, "agent-a", List::of, userRef::get); fs.uploadFiles( + RT, List.of(java.util.Map.entry("MEMORY.md", "v1".getBytes(StandardCharsets.UTF_8)))); assertNotNull(store.get(List.of("agents", "agent-a", "users", "user-1"), "/MEMORY.md")); } diff --git a/docs/zh/harness/sandbox.md b/docs/zh/harness/sandbox.md index d99545c04..c5ddd2295 100644 --- a/docs/zh/harness/sandbox.md +++ b/docs/zh/harness/sandbox.md @@ -14,7 +14,7 @@ 1. 用 **`SandboxFilesystemSpec#toSandboxContext(hostWorkspaceRoot)`** 得到 **`SandboxContext`**(内含 `SandboxClient`、隔离范围、快照 spec、`WorkspaceSpec` 等),并同时把宿主侧需要投影进沙箱的目录(`AGENTS.md`、`skills/`、`subagents/`、`knowledge/`)装入一个 `WorkspaceProjectionEntry`(见 [§6 工作区投影](#6-工作区投影与-skills-同步))。 2. 使用 **`SandboxBackedFilesystem`** 作为 agent 的 `AbstractFilesystem` 实现(对上层透明)。 -3. 构造 **`SandboxManager(client, stateStore, agentId)`**;未显式配置 `sandboxStateStore` 时,默认使用 **`SessionSandboxStateStore(effectiveSession, agentId)`**,将沙箱元数据与当前 `Session` 关联。 +3. 构造 **`SandboxManager(client, stateStore, agentId)`**;未在 **`SandboxFilesystemSpec#sandboxStateStore`** 上显式配置时,默认使用 **`SessionSandboxStateStore(effectiveSession, agentId)`**,将沙箱元数据与当前 `Session` 关联。 4. 注册 **`SandboxLifecycleHook(sandboxManager, filesystemProxy)`**(优先级 `50`):在每次 `PreCall` 中 **acquire → `start()`**(含 4-分支工作区初始化,见 [§5 快照与 4-分支恢复](#5-快照与-4-分支恢复)),在 **`PostCall` / `Error`** 中 **`stop()`(持久快照)→ 持久化 state → release** 并清空代理上的活动会话。 只有后端实现 **`AbstractSandboxFilesystem`** 时,`HarnessAgent` 才会注册 **`ShellExecuteTool`**;沙箱模式下文件与 shell 命令都走沙箱内部,宿主机不受影响。 @@ -261,7 +261,7 @@ call 3: shell_execute("cat results.csv") → 读 call 2 产生的文件 ## 7. 状态:`SandboxStateStore` 与 `Session` -- **`SandboxStateStore`**:抽象「与某次隔离键绑定的沙箱元数据(sessionId + 快照引用)」的持久化。便于替换为自定义实现。 +- **`SandboxStateStore`**:抽象「与某次隔离键绑定的沙箱元数据(sessionId + 快照引用)」的持久化。便于替换为自定义实现;在 **`SandboxFilesystemSpec#sandboxStateStore`** 上配置(未设置则走默认)。 - **默认 `SessionSandboxStateStore`**:依赖构建时选定的 `Session`(与 `SessionPersistenceHook` 等共用的**会话抽象**;若你使用 Redis 等分布式 `Session`,沙箱元数据可随之跨进程可见)。 - **`WorkspaceSession`** 仍负责**工作区布局下的 per-session 配置**;**不要**将 `WorkspaceSession` 的 JSON 与「沙箱 state JSON」混为同一套职责——沙箱的 resume 数据以 **`SandboxStateStore`** 为准。 From 9f2be712b328a4c4abf401e1b6b18d45728f859c Mon Sep 17 00:00:00 2001 From: chickenlj Date: Wed, 6 May 2026 10:27:14 +0800 Subject: [PATCH 13/28] RuntimeContext refactor --- .../harness/sandbox/DataAgentService.java | 2 +- .../harness/example/QuickstartExample.java | 2 +- .../harness/example/TextToSqlExample.java | 2 +- .../harness/agent/HarnessAgent.java | 13 +- .../harness/agent/IsolationScope.java | 4 +- .../harness/agent/RuntimeContext.java | 119 ------------------ .../harness/agent/sandbox/SandboxContext.java | 2 +- .../agent/subagent/DefaultAgentManager.java | 2 +- .../HarnessAgentIntegrationExampleTest.java | 1 + .../harness/agent/HarnessAgentTest.java | 1 + ...ilesystemPersonalAssistantExampleTest.java | 2 +- ...teFilesystemIsolationScopeExampleTest.java | 2 +- ...oxFilesystemIsolationScopeExampleTest.java | 2 +- .../sandbox/SandboxIsolationKeyTest.java | 20 +-- .../sandbox/SandboxManagerIsolationTest.java | 18 +-- .../sandbox/SessionSandboxStateStoreTest.java | 4 +- .../WorkspaceSandboxStateStoreTest.java | 8 +- 17 files changed, 45 insertions(+), 159 deletions(-) delete mode 100644 agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java index b46cc33c3..5fdd1f5dc 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java +++ b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java @@ -15,6 +15,7 @@ */ package io.agentscope.examples.harness.sandbox; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.model.DashScopeChatModel; @@ -26,7 +27,6 @@ import io.agentscope.examples.harness.sandbox.support.SharedInMemorySandboxStateStore; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import jakarta.annotation.PostConstruct; import java.io.InputStream; import java.nio.file.Files; diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java index 8adfe0dc2..bf5dc547b 100644 --- a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java @@ -15,12 +15,12 @@ */ package io.agentscope.harness.example; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.compaction.CompactionConfig; import java.nio.file.Files; import java.nio.file.Path; diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java index b337c4cb3..c34ad5651 100644 --- a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java +++ b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java @@ -15,6 +15,7 @@ */ package io.agentscope.harness.example; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; @@ -22,7 +23,6 @@ import io.agentscope.core.model.Model; import io.agentscope.core.tool.Toolkit; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index a59f6f4c4..aff1b1397 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -19,6 +19,7 @@ import io.agentscope.core.ReActAgent; import io.agentscope.core.agent.Agent; import io.agentscope.core.agent.Event; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.agent.StreamOptions; import io.agentscope.core.hook.Hook; import io.agentscope.core.memory.InMemoryMemory; @@ -177,7 +178,7 @@ public Flux stream(List msgs, StreamOptions options, RuntimeContext private io.agentscope.core.agent.RuntimeContext coreForDelegate() { return runtimeContext != null - ? runtimeContext.toCore() + ? runtimeContext : io.agentscope.core.agent.RuntimeContext.empty(); } @@ -231,7 +232,7 @@ private Mono forceCompactAndRetry(Memory memory, List msgs) { private io.agentscope.core.agent.RuntimeContext coreRuntimeForRecovery() { return runtimeContext != null - ? runtimeContext.toCore() + ? runtimeContext : io.agentscope.core.agent.RuntimeContext.empty(); } @@ -295,11 +296,13 @@ private RuntimeContext ensureSessionDefaults(RuntimeContext ctx) { } // Inject default sandbox context if the call doesn't provide one SandboxContext sandboxCtx = - ctx.getSandboxContext() != null ? ctx.getSandboxContext() : defaultSandboxContext; + ctx.get(SandboxContext.class) != null + ? ctx.get(SandboxContext.class) + : defaultSandboxContext; if (session == ctx.getSession() && sessionKey == ctx.getSessionKey() - && sandboxCtx == ctx.getSandboxContext()) { + && sandboxCtx == ctx.get(SandboxContext.class)) { return ctx; } return RuntimeContext.builder() @@ -308,7 +311,7 @@ private RuntimeContext ensureSessionDefaults(RuntimeContext ctx) { .session(session) .sessionKey(sessionKey) .putAll(ctx.getExtra()) - .sandboxContext(sandboxCtx) + .put(SandboxContext.class, sandboxCtx) .build(); } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java index e572bf2dd..6df694a26 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/IsolationScope.java @@ -51,14 +51,14 @@ public enum IsolationScope { * *

    This is the default behavior. Each distinct session gets its own sandbox state / * store namespace. If no session key is present in the - * {@link io.agentscope.harness.agent.RuntimeContext}, state lookup is skipped and a fresh + * {@link io.agentscope.core.agent.RuntimeContext}, state lookup is skipped and a fresh * sandbox is created (or a default store namespace is used). */ SESSION, /** * Share across all sessions belonging to the same - * {@link io.agentscope.harness.agent.RuntimeContext#getUserId() userId}. + * {@link io.agentscope.core.agent.RuntimeContext#getUserId() userId}. * *

    If {@code userId} is blank, a warning is logged and state lookup / namespace resolution * degrades to the default (fresh sandbox create, or an anonymous-user namespace). diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java deleted file mode 100644 index 624c6bd05..000000000 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/RuntimeContext.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.agent; - -import io.agentscope.core.session.Session; -import io.agentscope.core.state.SessionKey; -import io.agentscope.harness.agent.sandbox.SandboxContext; -import java.util.Map; - -/** - * Harness-facing runtime context: wraps {@link io.agentscope.core.agent.RuntimeContext} and adds - * a typed {@link #getSandboxContext() sandbox} view (stored as a typed attribute on the core - * object). - * - *

    Pass {@link #toCore()} to {@link io.agentscope.core.ReActAgent#call} when calling the - * delegate directly. - */ -public final class RuntimeContext { - - private final io.agentscope.core.agent.RuntimeContext core; - - private RuntimeContext(io.agentscope.core.agent.RuntimeContext core) { - this.core = core; - } - - public io.agentscope.core.agent.RuntimeContext toCore() { - return core; - } - - public String getSessionId() { - return core.getSessionId(); - } - - public String getUserId() { - return core.getUserId(); - } - - public Session getSession() { - return core.getSession(); - } - - public SessionKey getSessionKey() { - return core.getSessionKey(); - } - - @SuppressWarnings("unchecked") - public T get(String key) { - return (T) core.get(key); - } - - public Map getExtra() { - return core.getExtra(); - } - - public SandboxContext getSandboxContext() { - return core.get(SandboxContext.class); - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private final io.agentscope.core.agent.RuntimeContext.Builder b = - io.agentscope.core.agent.RuntimeContext.builder(); - - public Builder sessionId(String sessionId) { - b.sessionId(sessionId); - return this; - } - - public Builder userId(String userId) { - b.userId(userId); - return this; - } - - public Builder session(Session session) { - b.session(session); - return this; - } - - public Builder sessionKey(SessionKey sessionKey) { - b.sessionKey(sessionKey); - return this; - } - - public Builder put(String key, Object value) { - b.put(key, value); - return this; - } - - public Builder putAll(Map extras) { - b.putAll(extras); - return this; - } - - public Builder sandboxContext(SandboxContext sandboxContext) { - b.put(SandboxContext.class, sandboxContext); - return this; - } - - public RuntimeContext build() { - return new RuntimeContext(b.build()); - } - } -} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java index 429998f37..f1ce071e8 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxContext.java @@ -21,7 +21,7 @@ /** * Immutable configuration for sandbox behavior. * - *

    Built with the agent and attached to {@link io.agentscope.harness.agent.RuntimeContext} for + *

    Built with the agent and attached to {@link io.agentscope.core.agent.RuntimeContext} for * each call. */ public final class SandboxContext { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java index 74e77f0d6..50c6e32ca 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java @@ -16,10 +16,10 @@ package io.agentscope.harness.agent.subagent; import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.tool.AgentSpawnTool; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.util.List; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java index eb9ec4c95..dc4a3585a 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentIntegrationExampleTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.when; import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java index 83097f8a3..899cfbb8b 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java index 4c25b57ea..85eb3b137 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/LocalFilesystemPersonalAssistantExampleTest.java @@ -23,13 +23,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; import io.agentscope.core.model.ChatResponse; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; import java.nio.charset.StandardCharsets; import java.nio.file.Files; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java index dd89b5956..5109e40e0 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; @@ -29,7 +30,6 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java index dbec25950..a3527705d 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; @@ -28,7 +29,6 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.example.support.InMemorySandboxClient; import io.agentscope.harness.agent.example.support.InMemorySandboxFilesystemSpec; import java.nio.file.Files; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java index 96e0a8c7b..e13ddcfcf 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxIsolationKeyTest.java @@ -19,9 +19,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.state.SimpleSessionKey; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import java.util.Optional; import org.junit.jupiter.api.Test; @@ -34,7 +34,7 @@ void sessionScope_withSessionKey_resolvesCorrectly() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-abc")).build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.SESSION, key.get().getScope()); assertEquals("sess-abc", key.get().getValue()); @@ -44,7 +44,7 @@ void sessionScope_withSessionKey_resolvesCorrectly() { void sessionScope_missingSessionKey_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); assertFalse(key.isPresent()); } @@ -60,7 +60,7 @@ void nullScope_treatedAsSession_withSessionKey() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("sess-def")).build(); Optional key = - SandboxIsolationKey.resolve((IsolationScope) null, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve((IsolationScope) null, ctx, AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.SESSION, key.get().getScope()); assertEquals("sess-def", key.get().getValue()); @@ -70,7 +70,7 @@ void nullScope_treatedAsSession_withSessionKey() { void userScope_withUserId_resolvesCorrectly() { RuntimeContext ctx = RuntimeContext.builder().userId("user-123").build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); assertTrue(key.isPresent()); assertEquals(IsolationScope.USER, key.get().getScope()); assertEquals("user-123", key.get().getValue()); @@ -80,7 +80,7 @@ void userScope_withUserId_resolvesCorrectly() { void userScope_blankUserId_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().userId(" ").build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); assertFalse(key.isPresent()); } @@ -88,7 +88,7 @@ void userScope_blankUserId_returnsEmpty() { void userScope_nullUserId_returnsEmpty() { RuntimeContext ctx = RuntimeContext.builder().build(); Optional key = - SandboxIsolationKey.resolve(IsolationScope.USER, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.USER, ctx, AGENT_ID); assertFalse(key.isPresent()); } @@ -103,7 +103,7 @@ void userScope_nullContext_returnsEmpty() { void agentScope_alwaysResolvesToAgentId() { Optional keyWithCtx = SandboxIsolationKey.resolve( - IsolationScope.AGENT, RuntimeContext.builder().build().toCore(), AGENT_ID); + IsolationScope.AGENT, RuntimeContext.builder().build(), AGENT_ID); Optional keyNullCtx = SandboxIsolationKey.resolve(IsolationScope.AGENT, null, AGENT_ID); @@ -128,9 +128,9 @@ void globalScope_alwaysResolvesToGlobalValue() { void equalsAndHashCode_sameValues_areEqual() { RuntimeContext ctx = RuntimeContext.builder().sessionKey(SimpleSessionKey.of("s1")).build(); Optional k1 = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); Optional k2 = - SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx.toCore(), AGENT_ID); + SandboxIsolationKey.resolve(IsolationScope.SESSION, ctx, AGENT_ID); assertTrue(k1.isPresent() && k2.isPresent()); assertEquals(k1.get(), k2.get()); assertEquals(k1.get().hashCode(), k2.get().hashCode()); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java index 8ddaf1818..f97233394 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SandboxManagerIsolationTest.java @@ -24,9 +24,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.state.SimpleSessionKey; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; @@ -99,7 +99,7 @@ void priority3_stateStoreHit_resumesSession() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); + SandboxAcquireResult result = manager.acquire(sCtx, rtx); assertSame(resumedSandbox, result.getSandbox()); assertEquals(true, result.isSelfManaged()); @@ -121,7 +121,7 @@ void priority3_stateStoreMiss_createsFreshSession() throws Exception { .snapshotSpec(snapshotSpec) .build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); + SandboxAcquireResult result = manager.acquire(sCtx, rtx); assertSame(freshSandbox, result.getSandbox()); verify(client).create(any(), any(), any()); @@ -136,7 +136,7 @@ void noScopeKey_createsFreshSession() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no sessionKey SandboxContext sCtx = SandboxContext.builder().build(); // scope = SESSION (default) - SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); + SandboxAcquireResult result = manager.acquire(sCtx, rtx); assertSame(freshSandbox, result.getSandbox()); verify(stateStore, never()).load(any()); @@ -153,7 +153,7 @@ void userScope_withUserId_loadsFromStore() throws Exception { RuntimeContext rtx = RuntimeContext.builder().userId("user-42").build(); SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); + SandboxAcquireResult result = manager.acquire(sCtx, rtx); assertSame(resumedSandbox, result.getSandbox()); } @@ -165,7 +165,7 @@ void userScope_missingUserId_createsFreshSession() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no userId SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.USER).build(); - SandboxAcquireResult result = manager.acquire(sCtx, rtx.toCore()); + SandboxAcquireResult result = manager.acquire(sCtx, rtx); assertSame(freshSandbox, result.getSandbox()); verify(stateStore, never()).load(any()); @@ -218,7 +218,7 @@ void persistState_savesJsonForResolvedScopeKey() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - manager.persistState(result, sCtx, rtx.toCore()); + manager.persistState(result, sCtx, rtx); verify(stateStore).save(any(), any()); } @@ -232,7 +232,7 @@ void persistState_missingScopeKey_skipped() throws Exception { RuntimeContext rtx = RuntimeContext.builder().build(); // no session key SandboxContext sCtx = SandboxContext.builder().build(); // SESSION scope by default - manager.persistState(result, sCtx, rtx.toCore()); + manager.persistState(result, sCtx, rtx); verify(stateStore, never()).save(any(), any()); } @@ -246,7 +246,7 @@ void clearState_deletesFromStore() throws Exception { SandboxContext sCtx = SandboxContext.builder().isolationScope(IsolationScope.SESSION).build(); - manager.clearState(sCtx, rtx.toCore()); + manager.clearState(sCtx, rtx); verify(stateStore).delete(any()); } diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java index 5b8615cb6..0578a9b2c 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/SessionSandboxStateStoreTest.java @@ -19,10 +19,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.session.InMemorySession; import io.agentscope.core.state.SimpleSessionKey; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -86,7 +86,7 @@ void deleteUsesTombstone_evenWhenSessionDeleteUnsupported() throws Exception { } private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { - return SandboxIsolationKey.resolve(scope, runtimeContext(scope, value).toCore(), AGENT_ID) + return SandboxIsolationKey.resolve(scope, runtimeContext(scope, value), AGENT_ID) .orElseThrow(); } diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java index 4a54cbe79..c82d38092 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/sandbox/WorkspaceSandboxStateStoreTest.java @@ -211,17 +211,17 @@ void sessionScope_usesDirectFileIo() throws Exception { private static SandboxIsolationKey isolationKey(IsolationScope scope, String value) { return SandboxIsolationKey.resolve( scope, - buildCtxForScope(scope, value).toCore(), + buildCtxForScope(scope, value), value.startsWith("user") || scope == IsolationScope.GLOBAL ? "test-agent" : value) .orElseThrow(() -> new IllegalStateException("Key could not be resolved")); } - private static io.agentscope.harness.agent.RuntimeContext buildCtxForScope( + private static io.agentscope.core.agent.RuntimeContext buildCtxForScope( IsolationScope scope, String value) { - io.agentscope.harness.agent.RuntimeContext.Builder b = - io.agentscope.harness.agent.RuntimeContext.builder(); + io.agentscope.core.agent.RuntimeContext.Builder b = + io.agentscope.core.agent.RuntimeContext.builder(); switch (scope) { case SESSION -> b.sessionKey(SimpleSessionKey.of(value)); case USER -> b.userId(value); From b582c061a3cd81f962fc452607d1542b4bdf3219 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Wed, 6 May 2026 12:18:16 +0800 Subject: [PATCH 14/28] WorkspaceSession check --- .../.env.example | 0 .../README.md | 0 .../pom.xml | 2 +- .../harness/example/SqliteTool.java | 0 .../harness/example/TextToSqlExample.java | 0 .../harness/example/WorkspaceInitializer.java | 0 .../main/resources/agentscope.json.example | 0 .../harness/example/chinook-default.sqlite | Bin .../resources/log4j2.component.properties | 0 .../src/main/resources/log4j2.xml | 0 .../workspace/knowledge/KNOWLEDGE.md | 0 .../workspace/skills/query-writing/SKILL.md | 0 .../skills/schema-exploration/SKILL.md | 0 .../workspace/subagents/query-optimizer.md | 0 .../workspace/subagents/schema-analyst.md | 0 .../harness-example-remote/pom.xml | 83 +++++++ .../harness/remote/DataAgentController.java | 79 ++++++ .../harness/remote/DataAgentService.java | 151 ++++++++++++ .../remote/HarnessRemoteApplication.java | 36 +++ .../WorkspaceClasspathMaterializer.java | 68 ++++++ .../harness/remote/data/SqliteTool.java | 225 ++++++++++++++++++ .../src/main/resources/application.properties | 2 + .../harness/remote/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 + .../workspace/skills/query-writing/SKILL.md | 14 ++ .../harness/example/QuickstartExample.java | 141 ----------- agentscope-examples/pom.xml | 3 +- .../harness/agent/HarnessAgent.java | 37 ++- .../main/resources/agentscope.json.example | 24 -- .../HarnessAgentDistributedSandboxTest.java | 63 ++++- 30 files changed, 763 insertions(+), 177 deletions(-) rename agentscope-examples/{harness-example => harness-example-local}/.env.example (100%) rename agentscope-examples/{harness-example => harness-example-local}/README.md (100%) rename agentscope-examples/{harness-example => harness-example-local}/pom.xml (97%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/java/io/agentscope/harness/example/SqliteTool.java (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/java/io/agentscope/harness/example/TextToSqlExample.java (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/agentscope.json.example (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/log4j2.component.properties (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/log4j2.xml (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/workspace/knowledge/KNOWLEDGE.md (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/workspace/skills/query-writing/SKILL.md (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/workspace/skills/schema-exploration/SKILL.md (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/workspace/subagents/query-optimizer.md (100%) rename agentscope-examples/{harness-example => harness-example-local}/src/main/resources/workspace/subagents/schema-analyst.md (100%) create mode 100644 agentscope-examples/harness-example-remote/pom.xml create mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java create mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java create mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java create mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java create mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java create mode 100644 agentscope-examples/harness-example-remote/src/main/resources/application.properties create mode 100644 agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite create mode 100644 agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md delete mode 100644 agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java delete mode 100644 agentscope-harness/src/main/resources/agentscope.json.example diff --git a/agentscope-examples/harness-example/.env.example b/agentscope-examples/harness-example-local/.env.example similarity index 100% rename from agentscope-examples/harness-example/.env.example rename to agentscope-examples/harness-example-local/.env.example diff --git a/agentscope-examples/harness-example/README.md b/agentscope-examples/harness-example-local/README.md similarity index 100% rename from agentscope-examples/harness-example/README.md rename to agentscope-examples/harness-example-local/README.md diff --git a/agentscope-examples/harness-example/pom.xml b/agentscope-examples/harness-example-local/pom.xml similarity index 97% rename from agentscope-examples/harness-example/pom.xml rename to agentscope-examples/harness-example-local/pom.xml index 24a4eaf00..8a27d35a0 100644 --- a/agentscope-examples/harness-example/pom.xml +++ b/agentscope-examples/harness-example-local/pom.xml @@ -27,7 +27,7 @@ AgentScope Java - Harness Example - harness-example + harness-example-local AgentScope Harness Example - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java similarity index 100% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java rename to agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java similarity index 100% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java rename to agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java similarity index 100% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java rename to agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java diff --git a/agentscope-examples/harness-example/src/main/resources/agentscope.json.example b/agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/agentscope.json.example rename to agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example diff --git a/agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite b/agentscope-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite rename to agentscope-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.component.properties b/agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/log4j2.component.properties rename to agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.xml b/agentscope-examples/harness-example-local/src/main/resources/log4j2.xml similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/log4j2.xml rename to agentscope-examples/harness-example-local/src/main/resources/log4j2.xml diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md rename to agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md rename to agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md rename to agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md rename to agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md rename to agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md diff --git a/agentscope-examples/harness-example-remote/pom.xml b/agentscope-examples/harness-example-remote/pom.xml new file mode 100644 index 000000000..cf763acfd --- /dev/null +++ b/agentscope-examples/harness-example-remote/pom.xml @@ -0,0 +1,83 @@ + + + + + 4.0.0 + + io.agentscope + agentscope-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Remote Filesystem Example + io.agentscope.examples + harness-example-remote + jar + Spring Boot Data Agent using RemoteFilesystemSpec (composite + shared store; docs/zh/harness/filesystem.md 模式一). For sandbox (模式二) see harness-example-sandbox. + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + io.agentscope + agentscope-harness + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + + diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java new file mode 100644 index 000000000..698bc1fbb --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java @@ -0,0 +1,79 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * HTTP API for the remote-store Data Agent ({@code RemoteFilesystemSpec} / filesystem.md 模式一). + * + *

    {@code
    + * curl -X POST http://localhost:8788/query \
    + *   -H 'Content-Type: application/json' \
    + *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
    + * }
    + */ +@RestController +public class DataAgentController { + + private final DataAgentService agentService; + + public DataAgentController(DataAgentService agentService) { + this.agentService = agentService; + } + + @GetMapping("/") + public String index() { + return "Remote-store Data Agent (RemoteFilesystemSpec) — POST /query with" + + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; + } + + @PostMapping("/query") + public ResponseEntity query(@RequestBody QueryRequest request) { + if (blank(request.sessionId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); + } + if (blank(request.userId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); + } + if (blank(request.question())) { + return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); + } + String answer = + agentService.query(request.sessionId(), request.userId(), request.question()); + return ResponseEntity.ok(QueryResponse.ok(answer)); + } + + private static boolean blank(String s) { + return s == null || s.isBlank(); + } + + record QueryRequest(String sessionId, String userId, String question) {} + + record QueryResponse(String answer, String error) { + static QueryResponse ok(String answer) { + return new QueryResponse(answer, null); + } + + static QueryResponse error(String error) { + return new QueryResponse(null, error); + } + } +} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java new file mode 100644 index 000000000..6f0612e7c --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java @@ -0,0 +1,151 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import io.agentscope.core.agent.RuntimeContext; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.core.model.Model; +import io.agentscope.core.session.InMemorySession; +import io.agentscope.core.session.Session; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.examples.harness.remote.data.SqliteTool; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; +import io.agentscope.harness.agent.store.InMemoryStore; +import jakarta.annotation.PostConstruct; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Data Agent using {@link RemoteFilesystemSpec} — the composite + shared-store mode described in + * {@code docs/zh/harness/filesystem.md} as 模式一 (and in {@link + * io.agentscope.harness.agent.HarnessAgent.Builder#filesystem(RemoteFilesystemSpec)} as + * Mode 1). + * + *

    Not sandbox mode: there is no {@code ShellExecuteTool}. For 模式二 + * / Mode 2 (sandbox + shell in isolation), use {@code harness-example-sandbox}. + * + *

    Shared components (simulate Redis + multi-replica in one JVM): + * + *

      + *
    • {@link InMemoryStore} — {@link io.agentscope.harness.agent.store.BaseStore} for + * MEMORY.md, memory/, session paths, and {@code knowledge/} + *
    • {@link InMemorySession} — non-local {@link Session} required by Harness when using remote + * filesystem spec (production would use RedisSession, etc.) + *
    + */ +@Service +public class DataAgentService { + + private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); + + private static final String AGENT_NAME = "data-agent"; + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + private static final String SYS_PROMPT = + "You are a Text-to-SQL agent with access to the Chinook music store database." + + " Use the sql_* tools. This deployment has no shell tool — use read_file," + + " write_file, grep_files for workspace files. Answer clearly."; + + private Path hostWorkspace; + private Path dbPath; + private Model model; + private RemoteFilesystemSpec remoteSpec; + private Session appSession; + + @PostConstruct + void init() throws Exception { + hostWorkspace = WorkspaceClasspathMaterializer.materialize(); + dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); + model = buildModel(); + + InMemoryStore store = new InMemoryStore(); + remoteSpec = + new RemoteFilesystemSpec(store) + .isolationScope(IsolationScope.USER) + .addSharedPrefix("knowledge/"); + appSession = new InMemorySession(); + + log.info( + "DataAgentService ready (RemoteFilesystemSpec): workspace={} db={}", + hostWorkspace, + dbPath); + } + + public String query(String sessionId, String userId, String question) { + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name(AGENT_NAME) + .model(model) + .workspace(hostWorkspace) + .filesystem(remoteSpec) + .session(appSession) + .sysPrompt(SYS_PROMPT) + .toolkit(toolkit) + .enableAgentTracingLog(true) + .build(); + + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); + Msg reply = agent.call(userMsg, ctx).block(); + return reply != null ? reply.getTextContent() : "(no response)"; + } + + private static Model buildModel() { + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); + } + String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); + log.info("Using model: {}", modelName); + return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) + .build(); + } + + private static Path materialiseChinook(Path target) throws Exception { + if (Files.exists(target)) { + return target.toAbsolutePath(); + } + try (InputStream in = + DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + throw new IllegalStateException( + "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); + } + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + return target.toAbsolutePath(); + } + + private static String envOrDefault(String name, String defaultValue) { + String v = System.getenv(name); + return (v != null && !v.isBlank()) ? v : defaultValue; + } +} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java new file mode 100644 index 000000000..9ab7754fe --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot entry for the remote-store Data Agent example. + * + *

    Set {@code DASHSCOPE_API_KEY}. Default port {@code 8788} (see {@code application.properties}). + * + *

    This module demonstrates {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec} + * ({@code docs/zh/harness/filesystem.md} 模式一). Sandbox (模式二) + * is {@code harness-example-sandbox}. + */ +@SpringBootApplication +public class HarnessRemoteApplication { + + public static void main(String[] args) { + SpringApplication.run(HarnessRemoteApplication.class, args); + } +} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java new file mode 100644 index 000000000..04710d7fa --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +/** + * Copies {@code classpath:workspace/...} into a temp directory used as the local side of the + * composite workspace for {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec}. + */ +public final class WorkspaceClasspathMaterializer { + + private static final String[] CLASSPATH_FILES = { + "classpath:workspace/AGENTS.md", + "classpath:workspace/skills/query-writing/SKILL.md", + "classpath:workspace/knowledge/KNOWLEDGE.md", + }; + + private WorkspaceClasspathMaterializer() {} + + /** + * Materializes bundled workspace resources to disk. + * + * @return absolute path to the host workspace directory + */ + public static Path materialize() { + try { + Path dir = Files.createTempDirectory("remote-data-agent-host-workspace-"); + PathMatchingResourcePatternResolver resolver = + new PathMatchingResourcePatternResolver(); + for (String location : CLASSPATH_FILES) { + Resource resource = resolver.getResource(location); + if (!resource.exists()) { + throw new IllegalStateException("Missing required resource: " + location); + } + String pathWithinWorkspace = location.substring("classpath:workspace/".length()); + Path target = dir.resolve(pathWithinWorkspace); + Files.createDirectories(target.getParent()); + try (InputStream in = resource.getInputStream()) { + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + } + return dir.toAbsolutePath().normalize(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to materialize workspace from classpath", e); + } + } +} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java new file mode 100644 index 000000000..c9b5e5d3b --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java @@ -0,0 +1,225 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote.data; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SQLite helpers for the remote-store Data Agent — same tool names and behaviour as {@code + * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. + * + *

    Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + private static final int MAX_ROWS = 50; + + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + String separator = "-".repeat(header.toString().length()); + + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-example-remote/src/main/resources/application.properties b/agentscope-examples/harness-example-remote/src/main/resources/application.properties new file mode 100644 index 000000000..a0192ca20 --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=harness-example-remote +server.port=8788 diff --git a/agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite b/agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


    i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..2f30165e6 --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,12 @@ +# Chinook Knowledge (remote-store demo) + +This Data Agent uses the Chinook SQLite sample database. + +Primary entities: +- `Artist` -> `Album` -> `Track` +- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` + +Guidance: +- Always discover schema with `sql_list_tables` and `sql_get_schema`. +- Use read-only `SELECT` statements. +- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..c8315594c --- /dev/null +++ b/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,14 @@ +--- +name: query-writing +description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). +--- + +# Query writing (remote-store) + +1. Call `sql_list_tables` if you do not yet know table names. +2. Call `sql_get_schema` for each table you join or filter on. +3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). +4. Summarise results in plain language. + +See the full skill in `agentscope-examples/harness-example` under +`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java b/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java deleted file mode 100644 index bf5dc547b..000000000 --- a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.example; - -import io.agentscope.core.agent.RuntimeContext; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.model.DashScopeChatModel; -import io.agentscope.core.model.Model; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.memory.compaction.CompactionConfig; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * Minimal quickstart example for the AgentScope Harness module. - * - *

    This example demonstrates the three core values of the harness layer: - * - *

      - *
    • Workspace-driven persona — agent identity comes from {@code AGENTS.md} in the - * workspace and is injected into every reasoning step - *
    • Session persistence — calls sharing the same {@code sessionId} automatically - * resume from the previous state - *
    • Conversation compaction — long histories are summarised in place; on the way, - * useful facts are flushed to a daily memory journal - *
    - * - *

    Run

    - * - *
    - * export DASHSCOPE_API_KEY=your_key_here
    - * mvn -pl agentscope-examples/harness-example -am compile \
    - *     org.codehaus.mojo:exec-maven-plugin:3.6.3:java \
    - *     -Dexec.mainClass=io.agentscope.harness.example.QuickstartExample
    - * 
    - * - *

    The first run creates {@code .agentscope/workspace/AGENTS.md} under the current working - * directory. Subsequent runs reuse it; remove the workspace folder to start clean. - */ -public class QuickstartExample { - - public static void main(String[] args) throws Exception { - // 1. Workspace: created on first run, reused afterwards - Path workspace = Paths.get(".agentscope/workspace"); - initWorkspaceIfAbsent(workspace); - - // 2. Model - String apiKey = System.getenv("DASHSCOPE_API_KEY"); - if (apiKey == null || apiKey.isBlank()) { - System.err.println("Required environment variable DASHSCOPE_API_KEY is not set."); - System.exit(1); - } - Model model = - DashScopeChatModel.builder().apiKey(apiKey).modelName("qwen-max").stream(true) - .build(); - - // 3. HarnessAgent — workspace injection / session persistence / agent tracing are - // enabled by default. Compaction is opt-in and shown here for completeness. - HarnessAgent agent = - HarnessAgent.builder() - .name("quickstart-agent") - .sysPrompt("你是一个帮助用户做笔记的助手。") - .model(model) - .workspace(workspace) - .compaction( - CompactionConfig.builder() - .triggerMessages(30) - .keepMessages(10) - .flushBeforeCompact(true) - .build()) - .build(); - - // 4. Two turns sharing the same RuntimeContext. - // Same sessionId → the second call automatically resumes the first turn's state. - RuntimeContext ctx = - RuntimeContext.builder().sessionId("demo-session").userId("alice").build(); - - Msg turn1 = - agent.call( - Msg.builder() - .role(MsgRole.USER) - .textContent("我叫天宇,今天准备一个关于 ReAct 的技术分享。") - .build(), - ctx) - .block(); - System.out.println("\n[turn1] " + textOf(turn1)); - - Msg turn2 = - agent.call( - Msg.builder() - .role(MsgRole.USER) - .textContent("我叫什么?我今天要干什么?") - .build(), - ctx) - .block(); - System.out.println("\n[turn2] " + textOf(turn2)); - } - - /** - * Creates a minimal {@code AGENTS.md} on the first run. The file defines the agent's persona - * and is automatically injected into the system prompt by {@code WorkspaceContextHook}. - */ - private static void initWorkspaceIfAbsent(Path workspace) throws Exception { - Files.createDirectories(workspace); - Path agentsMd = workspace.resolve("AGENTS.md"); - if (Files.exists(agentsMd)) { - return; - } - Files.writeString( - agentsMd, - """ - # 笔记助手 - - 你是一个帮助用户整理笔记和知识的助手。 - - ## 行为约定 - - 主动记录用户提到的关键事实(姓名、计划、偏好等) - - 回答用简洁中文,必要时给出要点列表 - - 对不确定的内容要主动说明,不要臆造 - """); - } - - private static String textOf(Msg msg) { - return msg != null ? msg.getTextContent() : "(no response)"; - } -} diff --git a/agentscope-examples/pom.xml b/agentscope-examples/pom.xml index ca8d3c0bd..4fdc23175 100644 --- a/agentscope-examples/pom.xml +++ b/agentscope-examples/pom.xml @@ -55,8 +55,9 @@ multiagent-patterns/pipeline multiagent-patterns/skills a2a-rocketmq - harness-example + harness-example-local harness-example-sandbox + harness-example-remote diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index aff1b1397..04793cd2b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -869,6 +869,16 @@ public HarnessAgent build() { effectiveSession = new WorkspaceSession(resolvedWorkspace, resolvedAgentId); } + // Mode 1 (RemoteFilesystemSpec) is inherently distributed: automatically require a + // distributed Session so that conversation state is also shared across replicas. + if (remoteFilesystemSpec != null && effectiveSession instanceof WorkspaceSession) { + throw new IllegalStateException( + "filesystem(RemoteFilesystemSpec) is designed for distributed / multi-replica" + + " deployments, but the effective Session is a local" + + " WorkspaceSession. Configure a distributed Session backend" + + " (for example RedisSession) via .session(...)."); + } + AtomicReference userIdRef = new AtomicReference<>(); AtomicReference sessionIdRef = new AtomicReference<>(); AbstractFilesystem filesystem = @@ -894,8 +904,12 @@ public HarnessAgent build() { filesystem = capturedSandboxFs; defaultSandboxContext = sandboxFilesystemSpec.toSandboxContext(resolvedWorkspace); - if (sandboxDistributedOptions != null - && sandboxDistributedOptions.isRequireDistributed()) { + // Mode 2 (SandboxFilesystemSpec) always validates distributed prerequisites unless + // the caller explicitly opts out via sandboxDistributed(requireDistributed=false). + boolean skipDistributedValidation = + sandboxDistributedOptions != null + && !sandboxDistributedOptions.isRequireDistributed(); + if (!skipDistributedValidation) { validateDistributedSandboxConfig(effectiveSession, defaultSandboxContext); } @@ -1115,17 +1129,24 @@ private void validateDistributedSandboxConfig( if (sandboxFilesystemSpec.getSandboxStateStore() == null && effectiveSession instanceof WorkspaceSession) { throw new IllegalStateException( - "sandboxDistributed(requireDistributed=true) requires a distributed" - + " Session backend (for example RedisSession)." - + " Current effective session is WorkspaceSession."); + "filesystem(SandboxFilesystemSpec) requires a distributed Session backend" + + " (for example RedisSession) to persist and restore sandbox" + + " state across distributed instances." + + " Configure one via .session(...)." + + " For single-node use, opt out via" + + " .sandboxDistributed(SandboxDistributedOptions.builder()" + + ".requireDistributed(false).build())."); } if (sandboxContext == null || sandboxContext.getSnapshotSpec() == null || sandboxContext.getSnapshotSpec() instanceof NoopSnapshotSpec) { throw new IllegalStateException( - "sandboxDistributed(requireDistributed=true) requires a non-noop" - + " snapshotSpec to restore workspace archives across" - + " distributed instances."); + "filesystem(SandboxFilesystemSpec) requires a non-noop snapshotSpec to" + + " restore workspace archives across distributed instances." + + " Configure one via SandboxFilesystemSpec.snapshotSpec(...)." + + " For single-node use, opt out via" + + " .sandboxDistributed(SandboxDistributedOptions.builder()" + + ".requireDistributed(false).build())."); } } diff --git a/agentscope-harness/src/main/resources/agentscope.json.example b/agentscope-harness/src/main/resources/agentscope.json.example deleted file mode 100644 index 76b2bb6d0..000000000 --- a/agentscope-harness/src/main/resources/agentscope.json.example +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://agentscope.io/schema/agentscope.json", - "main": "default", - "agents": { - "default": { - "name": "Main", - "description": "Primary harness agent", - "workspace": ".agentscope/workspace", - "maxIters": 15 - }, - "worker": { - "name": "Worker", - "description": "Secondary agent with its own workspace", - "workspace": ".agentscope/worker-workspace", - "maxIters": 10 - } - }, - "channels": { - "chatui": { - "defaultAgentId": "default", - "dmScope": "MAIN" - } - } -} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java index 6ed16fa8c..afdf85474 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java @@ -28,9 +28,11 @@ import io.agentscope.core.model.Model; import io.agentscope.core.session.Session; import io.agentscope.harness.agent.filesystem.LocalFilesystemSpec; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; import io.agentscope.harness.agent.sandbox.filesystem.DockerFilesystemSpec; import io.agentscope.harness.agent.sandbox.snapshot.LocalSnapshotSpec; +import io.agentscope.harness.agent.store.BaseStore; import java.nio.file.Path; import java.util.List; import java.util.Map; @@ -63,7 +65,27 @@ void sandboxDistributed_requiresSandboxFilesystemMode() { } @Test - void sandboxDistributed_requireDistributed_failsOnLocalDefaults() { + void sandboxMode_withLocalSession_failsFastByDefault() { + // Mode 2 (SandboxFilesystemSpec) now validates automatically — no sandboxDistributed() needed. + IllegalStateException ex = + assertThrows( + IllegalStateException.class, + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new DockerFilesystemSpec()) + .build()); + assertEquals( + true, + ex.getMessage().contains("distributed Session backend"), + "sandbox mode should fail-fast when effective session remains local WorkspaceSession"); + } + + @Test + void sandboxMode_explicitSandboxDistributed_alsoFailsOnLocalSession() { + // Explicit sandboxDistributed() with default requireDistributed=true still fails. IllegalStateException ex = assertThrows( IllegalStateException.class, @@ -110,7 +132,8 @@ void sandboxDistributed_appliesIsolationAndSnapshotOverride() { } @Test - void sandboxDistributed_requireDistributedCanBeDisabled() { + void sandboxMode_requireDistributedFalse_allowsLocalSession() { + // Single-node sandbox use: opt out of distributed validation explicitly. assertDoesNotThrow( () -> HarnessAgent.builder() @@ -125,6 +148,42 @@ void sandboxDistributed_requireDistributedCanBeDisabled() { .build()); } + @Test + void remoteFilesystemMode_withLocalSession_failsFast() { + // Mode 1 (RemoteFilesystemSpec) always requires a distributed Session. + BaseStore store = mock(BaseStore.class); + IllegalStateException ex = + assertThrows( + IllegalStateException.class, + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new RemoteFilesystemSpec(store)) + .build()); + assertEquals( + true, + ex.getMessage().contains("RemoteFilesystemSpec"), + "Mode 1 should fail-fast when effective session is local WorkspaceSession"); + } + + @Test + void remoteFilesystemMode_withDistributedSession_succeeds() { + // Mode 1 with a distributed Session should build successfully. + BaseStore store = mock(BaseStore.class); + Session distributedSession = mock(Session.class); + assertDoesNotThrow( + () -> + HarnessAgent.builder() + .name("agent") + .model(stubModel("ok")) + .workspace(workspace) + .filesystem(new RemoteFilesystemSpec(store)) + .session(distributedSession) + .build()); + } + private static Model stubModel(String assistantText) { Model model = mock(Model.class); when(model.getModelName()).thenReturn("stub-model"); From 9c0e197e248114522766e53bf6012d25430abe18 Mon Sep 17 00:00:00 2001 From: fang-tech Date: Wed, 6 May 2026 22:21:13 +0800 Subject: [PATCH 15/28] refactor harness examples module structure and using interactive chat replaces solid fixed chat --- .../harness-example-common}/pom.xml | 32 +- .../common/model}/FixedReplyModel.java | 2 +- .../harness/common/util/ExampleUtils.java | 490 ++++++++++++++++++ .../harness/common/util/MsgUtils.java | 176 +++++++ .../harness-quickstart}/.env.example | 0 .../harness-quickstart}/README.md | 8 +- .../harness-quickstart/pom.xml | 48 ++ .../harness/example/QuickstartExample.java | 51 +- .../harness/example/SqliteTool.java | 0 .../harness/example/TextToSqlExample.java | 62 +-- .../harness/example/WorkspaceInitializer.java | 0 .../main/resources/agentscope.json.example | 0 .../harness/example/chinook-default.sqlite | Bin .../resources/log4j2.component.properties | 0 .../src/main/resources/log4j2.xml | 0 .../workspace/knowledge/KNOWLEDGE.md | 0 .../workspace/skills/query-writing/SKILL.md | 0 .../skills/schema-exploration/SKILL.md | 0 .../workspace/subagents/query-optimizer.md | 0 .../workspace/subagents/schema-analyst.md | 0 .../harness-sandbox}/pom.xml | 20 +- .../sandbox/HarnessSandboxExampleApp.java | 2 +- ...calFilesystemPersonalAssistantExample.java | 20 +- ...RemoteFilesystemIsolationScopeExample.java | 20 +- ...andboxFilesystemIsolationScopeExample.java | 20 +- .../sandbox/support/InMemorySandbox.java | 0 .../support/InMemorySandboxClient.java | 0 .../InMemorySandboxFilesystemSpec.java | 0 .../sandbox/support/InMemorySandboxState.java | 0 agentscope-examples/harness-examples/pom.xml | 27 + agentscope-examples/pom.xml | 3 +- .../impl/docker/DockerSandboxClient.java | 4 +- 32 files changed, 800 insertions(+), 185 deletions(-) rename agentscope-examples/{harness-example => harness-examples/harness-example-common}/pom.xml (67%) rename agentscope-examples/{harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support => harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/model}/FixedReplyModel.java (97%) create mode 100644 agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java create mode 100644 agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/MsgUtils.java rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/.env.example (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/README.md (97%) create mode 100644 agentscope-examples/harness-examples/harness-quickstart/pom.xml rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/java/io/agentscope/harness/example/QuickstartExample.java (72%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/java/io/agentscope/harness/example/SqliteTool.java (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/java/io/agentscope/harness/example/TextToSqlExample.java (85%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/agentscope.json.example (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/log4j2.component.properties (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/log4j2.xml (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/workspace/knowledge/KNOWLEDGE.md (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/workspace/skills/query-writing/SKILL.md (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/workspace/skills/schema-exploration/SKILL.md (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/workspace/subagents/query-optimizer.md (100%) rename agentscope-examples/{harness-example => harness-examples/harness-quickstart}/src/main/resources/workspace/subagents/schema-analyst.md (100%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/pom.xml (76%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java (96%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java (89%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java (92%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java (92%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java (100%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java (100%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java (100%) rename agentscope-examples/{harness-example-sandbox => harness-examples/harness-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java (100%) create mode 100644 agentscope-examples/harness-examples/pom.xml diff --git a/agentscope-examples/harness-example/pom.xml b/agentscope-examples/harness-examples/harness-example-common/pom.xml similarity index 67% rename from agentscope-examples/harness-example/pom.xml rename to agentscope-examples/harness-examples/harness-example-common/pom.xml index 24a4eaf00..575d19d57 100644 --- a/agentscope-examples/harness-example/pom.xml +++ b/agentscope-examples/harness-examples/harness-example-common/pom.xml @@ -6,14 +6,14 @@ ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. ---> + --> 4.0.0 io.agentscope - agentscope-examples + harness-examples ${revision} ../pom.xml - AgentScope Java - Harness Example - harness-example - AgentScope Harness Example - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction - - - 2.24.3 - + harness-example-common + io.agentscope.examples + AgentScope Java - Harness Example Common + jar io.agentscope agentscope-harness - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml + com.fasterxml.jackson.core + jackson-databind - - - org.xerial - sqlite-jdbc - 3.47.2.0 + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml - - org.apache.logging.log4j log4j-slf4j2-impl diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/model/FixedReplyModel.java similarity index 97% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java rename to agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/model/FixedReplyModel.java index 573283e7e..53a327e6c 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/FixedReplyModel.java +++ b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/model/FixedReplyModel.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.agentscope.examples.harness.sandbox.support; +package io.agentscope.examples.harness.common.model; import io.agentscope.core.message.Msg; import io.agentscope.core.message.TextBlock; diff --git a/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java new file mode 100644 index 000000000..fef614000 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java @@ -0,0 +1,490 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.common.util; + +import io.agentscope.core.agent.Agent; +import io.agentscope.core.agent.EventType; +import io.agentscope.core.agent.StreamOptions; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ThinkingBlock; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * Utility class providing common functionality for examples. + * + *

    + * Features: + * + *

      + *
    • Interactive API key configuration + *
    • Chat loop implementation + *
    • Helper methods for user interaction + *
    + */ +public class ExampleUtils { + + private static final BufferedReader reader = + new BufferedReader(new InputStreamReader(System.in)); + + /** + * Get DashScope API key from environment variable or interactive input. + * + * @return API key + * @throws IOException if input fails + */ + public static String getDashScopeApiKey() throws IOException { + return getApiKey( + "DASHSCOPE_API_KEY", "DashScope", "https://dashscope.console.aliyun.com/apiKey"); + } + + /** + * Get OpenAI API key from environment variable or interactive input. + * + * @return API key + * @throws IOException if input fails + */ + public static String getOpenAIApiKey() throws IOException { + return getApiKey("OPENAI_API_KEY", "OpenAI", "https://platform.openai.com/api-keys"); + } + + /** + * Get API key from environment variable or interactive input. + * + * @param envVarName environment variable name + * @param serviceName service name for display + * @param helpUrl URL to get API key + * @return API key + * @throws IOException if input fails + */ + public static String getApiKey(String envVarName, String serviceName, String helpUrl) + throws IOException { + + // 1. Try environment variable + String apiKey = System.getenv(envVarName); + + if (apiKey != null && !apiKey.isEmpty()) { + System.out.println("✓ Using API key from environment variable " + envVarName + "\n"); + return apiKey; + } + + // 2. Interactive input + System.out.println(envVarName + " environment variable not found.\n"); + System.out.println("Please enter your " + serviceName + " API Key:"); + System.out.println("(Get one at: " + helpUrl + ")"); + System.out.print("\nAPI Key: "); + + apiKey = reader.readLine().trim(); + + if (apiKey.isEmpty()) { + System.err.println("Error: API Key cannot be empty"); + System.exit(1); + } + + System.out.println("\n✓ API Key configured"); + System.out.println("Tip: Set environment variable to skip this step:"); + System.out.println(" export " + envVarName + "=" + maskApiKey(apiKey) + "\n"); + + return apiKey; + } + + /** + * Mask API key for display (show first 4 and last 4 characters). + * + * @param apiKey API key to mask + * @return masked API key + */ + public static String maskApiKey(String apiKey) { + if (apiKey == null || apiKey.length() <= 8) { + return "***"; + } + return apiKey.substring(0, 4) + "****" + apiKey.substring(apiKey.length() - 4); + } + + /** + * Start an interactive chat loop with an agent. + * + * @param agent the agent to chat with + * @throws IOException if input fails + */ + public static void startChat(Agent agent) throws IOException { + System.out.println("=== Chat Started ==="); + System.out.println("Type 'exit' to quit\n"); + + while (true) { + System.out.print("You> "); + String input = reader.readLine(); + + if (input == null || "exit".equalsIgnoreCase(input.trim())) { + System.out.println("Goodbye!"); + break; + } + + if (input.trim().isEmpty()) { + continue; + } + + try { + Msg userMsg = + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(input).build()) + .build(); + + System.out.print("Agent> "); + + try { + // Try to use stream() first for real-time output + AtomicBoolean hasPrintedThinkingHeader = new AtomicBoolean(false); + AtomicBoolean hasPrintedTextHeader = new AtomicBoolean(false); + AtomicBoolean hasPrintedTextSeparator = new AtomicBoolean(false); + AtomicReference lastThinkingContent = new AtomicReference<>(""); + AtomicReference lastTextContent = new AtomicReference<>(""); + + StreamOptions streamOptions = + StreamOptions.builder() + .eventTypes(EventType.REASONING, EventType.TOOL_RESULT) + .incremental(true) + .includeReasoningResult(false) + .build(); + + agent.stream(userMsg, streamOptions) + .doOnNext( + event -> { + Msg msg = event.getMessage(); + for (ContentBlock block : msg.getContent()) { + if (block instanceof ThinkingBlock) { + printStreamContent( + ((ThinkingBlock) block).getThinking(), + lastThinkingContent, + hasPrintedThinkingHeader, + "> Thinking: ", + null); + } else if (block instanceof TextBlock) { + printStreamContent( + ((TextBlock) block).getText(), + lastTextContent, + hasPrintedTextHeader, + "Text: ", + () -> { + if (hasPrintedThinkingHeader.get() + && !hasPrintedTextSeparator + .get()) { + System.out.print("\n\n"); + hasPrintedTextSeparator.set(true); + } + }); + } + } + }) + .blockLast(); + } catch (Exception e) { + // Fallback to call() if streaming is not supported or fails + if (e instanceof UnsupportedOperationException) { + System.err.println( + "\n[Info] Streaming not supported by this agent. Falling back to" + + " call()."); + } else { + System.err.println( + "\n[Warning] Exception during streaming: " + e.getMessage()); + e.printStackTrace(); + System.err.println("[Info] Falling back to call()."); + } + + Msg response = agent.call(userMsg).block(); + if (response != null) { + // Extract thinking and text separately to match streaming format + String thinking = + response.getContent().stream() + .filter(block -> block instanceof ThinkingBlock) + .map(block -> ((ThinkingBlock) block).getThinking()) + .collect(Collectors.joining("\n")); + + String text = + response.getContent().stream() + .filter(block -> block instanceof TextBlock) + .map(block -> ((TextBlock) block).getText()) + .collect(Collectors.joining("\n")); + + boolean hasContent = false; + if (!thinking.isEmpty()) { + System.out.print("> Thinking: " + thinking); + hasContent = true; + } + if (!text.isEmpty()) { + if (hasContent) { + System.out.print("\n\n"); + } + System.out.print("Text: " + text); + hasContent = true; + } + if (!hasContent) { + System.out.print("[No response]"); + } + } + } + + System.out.println("\n"); + + } catch (Exception e) { + System.err.println("\nError: " + e.getMessage()); + e.printStackTrace(); + } + } + } + + /** + * Read a line from user input. + * + * @return user input + * @throws IOException if input fails + */ + public static String readLine() throws IOException { + return reader.readLine(); + } + + /** + * Print a welcome banner. + * + * @param title example title + * @param description example description + */ + public static void printWelcome(String title, String description) { + System.out.println("=== " + title + " ===\n"); + System.out.println(description); + System.out.println(); + } + + /** + * Extract text content from a message. + * + * @param msg message to extract text from + * @return extracted text + */ + public static String textOf(Msg msg) { + return MsgUtils.getTextContent(msg); + } + + public static Msg userMsg(String text) { + return MsgUtils.textMsg(null, MsgRole.USER, text); + } + + public static RuntimeContext ctx(String sessionId, String userId) { + return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + } + + public static RuntimeContext ctx(String sessionId) { + return RuntimeContext.builder().sessionId(sessionId).build(); + } + + public static void startChat(HarnessAgent agent, RuntimeContext ctx) throws IOException { + startHarnessChat(agent, ctx); + } + + public static void startHarnessChat(HarnessAgent agent, RuntimeContext ctx) throws IOException { + System.out.println("=== Chat Started ==="); + System.out.println("Type 'exit', 'quit', or 'q' to quit\n"); + + while (true) { + System.out.print("You> "); + String input = reader.readLine(); + + if (input == null) { + System.out.println("\n(end of input)"); + break; + } + + String question = input.trim(); + if (question.isEmpty()) { + System.out.println("Goodbye!"); + break; + } + + if (isQuitCommand(question)) { + System.out.println("Goodbye!"); + break; + } + + try { + runHarnessTurn(agent, ctx, question); + System.out.println(); + } catch (Exception e) { + System.err.println("\nError: " + e.getMessage()); + e.printStackTrace(); + } + } + } + + public static void runHarnessTurn(HarnessAgent agent, RuntimeContext ctx, String question) { + Msg userMsg = userMsg(question); + System.out.print("Agent> "); + try { + streamHarnessTurn(agent, ctx, userMsg); + } catch (Exception e) { + if (e instanceof UnsupportedOperationException) { + System.err.println( + "\n[Info] Streaming not supported by this agent. Falling back to call()."); + } else { + System.err.println("\n[Warning] Exception during streaming: " + e.getMessage()); + e.printStackTrace(); + System.err.println("[Info] Falling back to call()."); + } + Msg response = agent.call(userMsg, ctx).block(); + printResponseContent(response); + } + System.out.println("\n"); + } + + private static void streamHarnessTurn(HarnessAgent agent, RuntimeContext ctx, Msg userMsg) { + AtomicBoolean hasPrintedThinkingHeader = new AtomicBoolean(false); + AtomicBoolean hasPrintedTextHeader = new AtomicBoolean(false); + AtomicBoolean hasPrintedTextSeparator = new AtomicBoolean(false); + AtomicReference lastThinkingContent = new AtomicReference<>(""); + AtomicReference lastTextContent = new AtomicReference<>(""); + + StreamOptions streamOptions = + StreamOptions.builder() + .eventTypes(EventType.REASONING, EventType.TOOL_RESULT) + .incremental(true) + .includeReasoningResult(false) + .build(); + + agent.stream(List.of(userMsg), streamOptions, ctx) + .doOnNext( + event -> { + Msg msg = event.getMessage(); + for (ContentBlock block : msg.getContent()) { + if (block instanceof ThinkingBlock) { + printStreamContent( + ((ThinkingBlock) block).getThinking(), + lastThinkingContent, + hasPrintedThinkingHeader, + "> Thinking: ", + null); + } else if (block instanceof TextBlock) { + printStreamContent( + ((TextBlock) block).getText(), + lastTextContent, + hasPrintedTextHeader, + "Text: ", + () -> { + if (hasPrintedThinkingHeader.get() + && !hasPrintedTextSeparator.get()) { + System.out.print("\n\n"); + hasPrintedTextSeparator.set(true); + } + }); + } + } + }) + .blockLast(); + } + + private static void printResponseContent(Msg response) { + if (response == null) { + System.out.print("[No response]"); + return; + } + String thinking = + response.getContent().stream() + .filter(block -> block instanceof ThinkingBlock) + .map(block -> ((ThinkingBlock) block).getThinking()) + .collect(Collectors.joining("\n")); + + String text = + response.getContent().stream() + .filter(block -> block instanceof TextBlock) + .map(block -> ((TextBlock) block).getText()) + .collect(Collectors.joining("\n")); + + boolean hasContent = false; + if (!thinking.isEmpty()) { + System.out.print("> Thinking: " + thinking); + hasContent = true; + } + if (!text.isEmpty()) { + if (hasContent) { + System.out.print("\n\n"); + } + System.out.print("Text: " + text); + hasContent = true; + } + if (!hasContent) { + System.out.print("[No response]"); + } + } + + private static boolean isQuitCommand(String line) { + return line.equalsIgnoreCase("quit") + || line.equalsIgnoreCase("exit") + || line.equalsIgnoreCase("q"); + } + + /** + * Helper method to print streaming content. + * + * @param content content to print + * @param lastContentRef reference to the last content for delta + * calculation + * @param hasPrintedHeaderRef reference to whether the header has been printed + * @param header header to print + * @param prePrintAction action to run before printing (e.g., adding + * separators) + */ + private static void printStreamContent( + String content, + AtomicReference lastContentRef, + AtomicBoolean hasPrintedHeaderRef, + String header, + Runnable prePrintAction) { + String lastContent = lastContentRef.get(); + String toPrint; + + // Detect if cumulative or incremental + if (content.startsWith(lastContent)) { + // Cumulative: print only new part + toPrint = content.substring(lastContent.length()); + lastContentRef.set(content); + } else { + // Incremental: print as-is and append + toPrint = content; + lastContentRef.set(lastContent + content); + } + + if (!toPrint.isEmpty()) { + if (prePrintAction != null) { + prePrintAction.run(); + } + + if (!hasPrintedHeaderRef.get()) { + System.out.print(header); + hasPrintedHeaderRef.set(true); + } + System.out.print(toPrint); + System.out.flush(); + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/MsgUtils.java b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/MsgUtils.java new file mode 100644 index 000000000..a9d7377aa --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/MsgUtils.java @@ -0,0 +1,176 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.common.util; + +import io.agentscope.core.message.AudioBlock; +import io.agentscope.core.message.ImageBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.Source; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.message.ThinkingBlock; +import io.agentscope.core.message.VideoBlock; +import java.util.stream.Collectors; + +/** + * Utility methods for working with Msg in examples. These are convenience + * methods for common + * operations. + */ +public class MsgUtils { + + /** + * Extract text content from a message. Concatenates text from all + * text-containing blocks + * (TextBlock and ThinkingBlock). + * + * @param msg The message to extract text from + * @return Concatenated text content or empty string if not available + */ + public static String getTextContent(Msg msg) { + String thinking = + msg.getContent().stream() + .filter(block -> block instanceof ThinkingBlock) + .map(block -> ((ThinkingBlock) block).getThinking()) + .collect(Collectors.joining("\n")); + + String text = + msg.getContent().stream() + .filter(block -> block instanceof TextBlock) + .map(block -> ((TextBlock) block).getText()) + .collect(Collectors.joining("\n")); + + if (!thinking.isEmpty() && !text.isEmpty()) { + return thinking + "\n\n" + text; + } else if (!thinking.isEmpty()) { + return thinking; + } else if (!text.isEmpty()) { + return text; + } else { + return "[No response]"; + } + } + + /** + * Check if a message has text content. + * + * @param msg The message to check + * @return true if the message contains text content + */ + public static boolean hasTextContent(Msg msg) { + return msg.getContent().stream() + .anyMatch(block -> block instanceof TextBlock || block instanceof ThinkingBlock); + } + + /** + * Check if a message has media content. + * + * @param msg The message to check + * @return true if the message contains media content + */ + public static boolean hasMediaContent(Msg msg) { + return msg.getContent().stream() + .anyMatch( + block -> + block instanceof ImageBlock + || block instanceof AudioBlock + || block instanceof VideoBlock); + } + + /** + * Create a message with text content (convenience method). + * + * @param name Sender name + * @param role Message role + * @param text Text content + * @return Message with text content + */ + public static Msg textMsg(String name, MsgRole role, String text) { + return Msg.builder() + .name(name) + .role(role) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + /** + * Create a message with image content (convenience method). + * + * @param name Sender name + * @param role Message role + * @param source Image source + * @return Message with image content + */ + public static Msg imageMsg(String name, MsgRole role, Source source) { + return Msg.builder() + .name(name) + .role(role) + .content(ImageBlock.builder().source(source).build()) + .build(); + } + + /** + * Create a message with audio content (convenience method). + * + * @param name Sender name + * @param role Message role + * @param source Audio source + * @return Message with audio content + */ + public static Msg audioMsg(String name, MsgRole role, Source source) { + return Msg.builder() + .name(name) + .role(role) + .content(AudioBlock.builder().source(source).build()) + .build(); + } + + /** + * Create a message with video content (convenience method). + * + * @param name Sender name + * @param role Message role + * @param source Video source + * @return Message with video content + */ + public static Msg videoMsg(String name, MsgRole role, Source source) { + return Msg.builder() + .name(name) + .role(role) + .content(VideoBlock.builder().source(source).build()) + .build(); + } + + /** + * Create a message with thinking content (convenience method). + * + * @param name Sender name + * @param role Message role + * @param thinking Thinking content + * @return Message with thinking content + */ + public static Msg thinkingMsg(String name, MsgRole role, String thinking) { + return Msg.builder() + .name(name) + .role(role) + .content(ThinkingBlock.builder().thinking(thinking).build()) + .build(); + } + + private MsgUtils() { + // Utility class + } +} diff --git a/agentscope-examples/harness-example/.env.example b/agentscope-examples/harness-examples/harness-quickstart/.env.example similarity index 100% rename from agentscope-examples/harness-example/.env.example rename to agentscope-examples/harness-examples/harness-quickstart/.env.example diff --git a/agentscope-examples/harness-example/README.md b/agentscope-examples/harness-examples/harness-quickstart/README.md similarity index 97% rename from agentscope-examples/harness-example/README.md rename to agentscope-examples/harness-examples/harness-quickstart/README.md index 291e45d06..e3023651a 100644 --- a/agentscope-examples/harness-example/README.md +++ b/agentscope-examples/harness-examples/harness-quickstart/README.md @@ -20,7 +20,7 @@ framework. The scenario: translate natural-language questions into SQL queries a ## Project Layout ``` -harness-example/ +harness-examples/harness-quickstart/ ├── pom.xml ├── .env.example # Environment variable template ├── README.md # This file @@ -56,7 +56,7 @@ harness-example/ ```bash cd agentscope-java -mvn -pl agentscope-examples/agents/harness-example package -am -DskipTests +mvn -pl agentscope-examples/harness-examples/harness-quickstart package -am -DskipTests ``` ### 2. Chinook database (optional) @@ -90,14 +90,14 @@ Interactive (no arguments — type questions at the `>` prompt; `quit`, empty li exit): ```bash -java -cp target/harness-example-*.jar \ +java -cp target/harness-quickstart-*.jar \ io.agentscope.harness.example.TextToSqlExample ``` One-shot (single question, then exit — useful for scripts): ```bash -java -cp target/harness-example-*.jar \ +java -cp target/harness-quickstart-*.jar \ io.agentscope.harness.example.TextToSqlExample \ "What are the top 5 best-selling artists?" ``` diff --git a/agentscope-examples/harness-examples/harness-quickstart/pom.xml b/agentscope-examples/harness-examples/harness-quickstart/pom.xml new file mode 100644 index 000000000..c08a28d4d --- /dev/null +++ b/agentscope-examples/harness-examples/harness-quickstart/pom.xml @@ -0,0 +1,48 @@ + + + + + 4.0.0 + + io.agentscope + harness-examples + ${revision} + ../pom.xml + + io.agentscope.examples + + AgentScope Java - Harness quickstart + harness-quickstart + AgentScope Harness quickstart - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction + + + + io.agentscope.examples + harness-example-common + ${revision} + + + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java similarity index 72% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java rename to agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java index 8adfe0dc2..4a7e46411 100644 --- a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/QuickstartExample.java +++ b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java @@ -15,8 +15,11 @@ */ package io.agentscope.harness.example; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.getDashScopeApiKey; +import static io.agentscope.examples.harness.common.util.ExampleUtils.printWelcome; +import static io.agentscope.examples.harness.common.util.ExampleUtils.startChat; + import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; @@ -55,16 +58,17 @@ public class QuickstartExample { public static void main(String[] args) throws Exception { + printWelcome( + "AgentScope Harness Quickstart", + "Interactive note assistant with workspace context, session persistence, and" + + " compaction."); + // 1. Workspace: created on first run, reused afterwards Path workspace = Paths.get(".agentscope/workspace"); initWorkspaceIfAbsent(workspace); // 2. Model - String apiKey = System.getenv("DASHSCOPE_API_KEY"); - if (apiKey == null || apiKey.isBlank()) { - System.err.println("Required environment variable DASHSCOPE_API_KEY is not set."); - System.exit(1); - } + String apiKey = getDashScopeApiKey(); Model model = DashScopeChatModel.builder().apiKey(apiKey).modelName("qwen-max").stream(true) .build(); @@ -83,32 +87,13 @@ public static void main(String[] args) throws Exception { .keepMessages(10) .flushBeforeCompact(true) .build()) + // .enableAgentTracingLog(false) .build(); - // 4. Two turns sharing the same RuntimeContext. - // Same sessionId → the second call automatically resumes the first turn's state. - RuntimeContext ctx = - RuntimeContext.builder().sessionId("demo-session").userId("alice").build(); - - Msg turn1 = - agent.call( - Msg.builder() - .role(MsgRole.USER) - .textContent("我叫天宇,今天准备一个关于 ReAct 的技术分享。") - .build(), - ctx) - .block(); - System.out.println("\n[turn1] " + textOf(turn1)); - - Msg turn2 = - agent.call( - Msg.builder() - .role(MsgRole.USER) - .textContent("我叫什么?我今天要干什么?") - .build(), - ctx) - .block(); - System.out.println("\n[turn2] " + textOf(turn2)); + // 4. Interactive turns sharing the same RuntimeContext. + // Same sessionId → each call automatically resumes the previous turn's state. + RuntimeContext ctx = ctx("demo-session", "alice"); + startChat(agent, ctx); } /** @@ -134,8 +119,4 @@ private static void initWorkspaceIfAbsent(Path workspace) throws Exception { - 对不确定的内容要主动说明,不要臆造 """); } - - private static String textOf(Msg msg) { - return msg != null ? msg.getTextContent() : "(no response)"; - } } diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/SqliteTool.java similarity index 100% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/SqliteTool.java rename to agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/SqliteTool.java diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java similarity index 85% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java rename to agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java index b337c4cb3..51baf24d5 100644 --- a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/TextToSqlExample.java +++ b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java @@ -15,19 +15,17 @@ */ package io.agentscope.harness.example; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.runHarnessTurn; +import static io.agentscope.examples.harness.common.util.ExampleUtils.startHarnessChat; + import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.core.tool.Toolkit; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.RuntimeContext; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -179,10 +177,10 @@ public static void main(String[] args) throws IOException { ? "text-to-sql-" + UUID.randomUUID().toString().substring(0, 8) : DEFAULT_SHARED_SESSION_ID; System.out.println("Session ID: " + sessionId); - RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); + RuntimeContext ctx = ctx(sessionId); if (parsedArgs.question() != null) { - runOneTurn(agent, ctx, parsedArgs.question()); + runHarnessTurn(agent, ctx, parsedArgs.question()); return; } @@ -191,35 +189,7 @@ public static void main(String[] args) throws IOException { + " Same session for all turns (memory tools share context)."); System.out.println("Tip: add --new-session to generate a UUID-based fresh session."); System.out.println("Leave: empty line, quit, exit, q, or EOF (Ctrl-D).\n"); - - BufferedReader stdin = - new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); - while (true) { - System.out.print("> "); - System.out.flush(); - String line = stdin.readLine(); - if (line == null) { - System.out.println("\n(end of input)"); - break; - } - String question = line.strip(); - if (question.isEmpty()) { - System.out.println("Goodbye."); - break; - } - if (isQuitCommand(question)) { - System.out.println("Goodbye."); - break; - } - runOneTurn(agent, ctx, question); - System.out.println(); - } - } - - private static boolean isQuitCommand(String line) { - return line.equalsIgnoreCase("quit") - || line.equalsIgnoreCase("exit") - || line.equalsIgnoreCase("q"); + startHarnessChat(agent, ctx); } private static ParsedArgs parseArgs(String[] args) { @@ -239,24 +209,6 @@ private static ParsedArgs parseArgs(String[] args) { return new ParsedArgs(newSession, question); } - private static void runOneTurn(HarnessAgent agent, RuntimeContext ctx, String question) { - System.out.println("─".repeat(50)); - System.out.println("Question: " + question); - System.out.println(); - - Msg userMsg = - Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(question).build()) - .build(); - Msg reply = agent.call(userMsg, ctx).block(); - - System.out.println("─".repeat(50)); - System.out.println("\nAnswer:\n"); - System.out.println(reply != null ? reply.getTextContent() : "(no response)"); - System.out.println(); - } - // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- diff --git a/agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java similarity index 100% rename from agentscope-examples/harness-example/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java rename to agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java diff --git a/agentscope-examples/harness-example/src/main/resources/agentscope.json.example b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/agentscope.json.example similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/agentscope.json.example rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/agentscope.json.example diff --git a/agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.component.properties b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/log4j2.component.properties similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/log4j2.component.properties rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/log4j2.component.properties diff --git a/agentscope-examples/harness-example/src/main/resources/log4j2.xml b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/log4j2.xml similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/log4j2.xml rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/log4j2.xml diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/knowledge/KNOWLEDGE.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/knowledge/KNOWLEDGE.md rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/knowledge/KNOWLEDGE.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/skills/query-writing/SKILL.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/skills/query-writing/SKILL.md rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/skills/query-writing/SKILL.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/skills/schema-exploration/SKILL.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/skills/schema-exploration/SKILL.md rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/skills/schema-exploration/SKILL.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/subagents/query-optimizer.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/subagents/query-optimizer.md rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/subagents/query-optimizer.md diff --git a/agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md b/agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/subagents/schema-analyst.md similarity index 100% rename from agentscope-examples/harness-example/src/main/resources/workspace/subagents/schema-analyst.md rename to agentscope-examples/harness-examples/harness-quickstart/src/main/resources/workspace/subagents/schema-analyst.md diff --git a/agentscope-examples/harness-example-sandbox/pom.xml b/agentscope-examples/harness-examples/harness-sandbox/pom.xml similarity index 76% rename from agentscope-examples/harness-example-sandbox/pom.xml rename to agentscope-examples/harness-examples/harness-sandbox/pom.xml index a7c825582..714aed98c 100644 --- a/agentscope-examples/harness-example-sandbox/pom.xml +++ b/agentscope-examples/harness-examples/harness-sandbox/pom.xml @@ -21,7 +21,7 @@ 4.0.0 io.agentscope - agentscope-examples + harness-examples ${revision} ../pom.xml @@ -32,23 +32,11 @@ jar Runnable examples: local filesystem, in-memory sandbox isolation scopes, and store-backed namespaces (no remote LLM required) - - 2.24.3 - - - io.agentscope - agentscope-harness - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - org.apache.logging.log4j - log4j-slf4j2-impl - ${log4j2.version} + io.agentscope.examples + harness-example-common + ${revision} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java similarity index 96% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java index 0074851dd..47ac18aa0 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java @@ -15,7 +15,7 @@ */ package io.agentscope.examples.harness.sandbox; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.examples.harness.common.model.FixedReplyModel; import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; /** diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java similarity index 89% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java index 359891ec9..3d5fbb2b5 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java @@ -15,13 +15,12 @@ */ package io.agentscope.examples.harness.sandbox; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; + import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.examples.harness.common.model.FixedReplyModel; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -118,15 +117,4 @@ static void demonstrateHostWrittenFileVisibleToAgent(Path workspace, Model model } System.out.println("[local] host file visible to workspace manager: OK"); } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } } diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java similarity index 92% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java index c243d69f3..bacf72614 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java @@ -15,14 +15,13 @@ */ package io.agentscope.examples.harness.sandbox; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; + import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.examples.harness.common.model.FixedReplyModel; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.store.InMemoryStore; import java.nio.file.Files; @@ -166,15 +165,4 @@ static void agentScopeSharedByAllCallers(Model model, Path workspace) throws Exc } System.out.println("[store] AGENT: shared key for all callers: OK"); } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } } diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java similarity index 92% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java index c309766cf..ed41f9d5c 100644 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java @@ -15,16 +15,15 @@ */ package io.agentscope.examples.harness.sandbox; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; + import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.sandbox.support.FixedReplyModel; +import io.agentscope.examples.harness.common.model.FixedReplyModel; import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.RuntimeContext; import java.nio.file.Files; import java.nio.file.Path; @@ -168,15 +167,4 @@ static void agentScopeEveryoneSharesOneSandbox(Path workspace, Model model) thro } System.out.println("[sandbox] AGENT: all callers share one sandbox: OK"); } - - private static RuntimeContext ctx(String sessionId, String userId) { - return RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - } - - private static Msg userMsg(String text) { - return Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(text).build()) - .build(); - } } diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java similarity index 100% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java similarity index 100% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java similarity index 100% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java similarity index 100% rename from agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java rename to agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java diff --git a/agentscope-examples/harness-examples/pom.xml b/agentscope-examples/harness-examples/pom.xml new file mode 100644 index 000000000..b98fb7361 --- /dev/null +++ b/agentscope-examples/harness-examples/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + io.agentscope + agentscope-examples + ${revision} + ../pom.xml + + + harness-examples + pom + + harness-examples + http://maven.apache.org + + + 2.24.3 + UTF-8 + + + + harness-example-common + harness-quickstart + harness-sandbox + + diff --git a/agentscope-examples/pom.xml b/agentscope-examples/pom.xml index ca8d3c0bd..9fa78b59b 100644 --- a/agentscope-examples/pom.xml +++ b/agentscope-examples/pom.xml @@ -55,8 +55,7 @@ multiagent-patterns/pipeline multiagent-patterns/skills a2a-rocketmq - harness-example - harness-example-sandbox + harness-examples diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java index 33f9175c2..0f1285e1f 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java @@ -16,6 +16,7 @@ package io.agentscope.harness.agent.sandbox.impl.docker; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; import io.agentscope.harness.agent.sandbox.Sandbox; import io.agentscope.harness.agent.sandbox.SandboxClient; import io.agentscope.harness.agent.sandbox.SandboxException; @@ -43,8 +44,7 @@ public DockerSandboxClient() { new ObjectMapper() .findAndRegisterModules() .activateDefaultTyping( - com.fasterxml.jackson.databind.jsontype - .BasicPolymorphicTypeValidator.builder() + BasicPolymorphicTypeValidator.builder() .allowIfSubType("io.agentscope.harness") .build(), ObjectMapper.DefaultTyping.NON_FINAL); From 9906a0600d3f2260236cd31dbd234d00d64a673e Mon Sep 17 00:00:00 2001 From: fang-tech Date: Thu, 7 May 2026 00:00:07 +0800 Subject: [PATCH 16/28] example: Add python docker image for python env sandbox example --- .../harness-examples/harness-sandbox/pom.xml | 5 + .../src/main/docker/python-sandbox/Dockerfile | 48 +++++ .../sandbox/DockerPythonSandboxExample.java | 169 ++++++++++++++++++ .../sandbox/DockerPythonSandboxImage.java | 158 ++++++++++++++++ .../sandbox/HarnessSandboxExampleApp.java | 5 +- .../sandbox/DockerPythonSandboxImageTest.java | 45 +++++ 6 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile create mode 100644 agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java create mode 100644 agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java create mode 100644 agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/pom.xml b/agentscope-examples/harness-examples/harness-sandbox/pom.xml index 714aed98c..28ef753fc 100644 --- a/agentscope-examples/harness-examples/harness-sandbox/pom.xml +++ b/agentscope-examples/harness-examples/harness-sandbox/pom.xml @@ -38,6 +38,11 @@ harness-example-common ${revision} + + org.junit.jupiter + junit-jupiter + test + diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile b/agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile new file mode 100644 index 000000000..d6c291f15 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile @@ -0,0 +1,48 @@ +FROM python:3.11-slim-bookworm + +ENV DEBIAN_FRONTEND=noninteractive \ + PIP_NO_CACHE_DIR=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + fonts-dejavu-core \ + poppler-utils \ + unzip \ + unrar-free \ + p7zip-full \ + bc \ + ripgrep \ + fd-find \ + sqlite3 \ + && ln -sf /usr/local/bin/python3 /usr/local/bin/python \ + && ln -sf /usr/bin/fdfind /usr/local/bin/fd \ + && python -m pip install --upgrade pip setuptools wheel \ + && python -m pip install --prefer-binary \ + pandas \ + numpy \ + openpyxl \ + xlsxwriter \ + xlrd \ + pillow \ + python-pptx \ + python-docx \ + pypdf \ + pdfplumber \ + pypdfium2 \ + pdf2image \ + img2pdf \ + sympy \ + mpmath \ + tqdm \ + python-dateutil \ + pytz \ + joblib \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +WORKDIR /workspace + +CMD ["sleep", "infinity"] diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java new file mode 100644 index 000000000..110119ab1 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java @@ -0,0 +1,169 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; +import static io.agentscope.examples.harness.common.util.ExampleUtils.getDashScopeApiKey; +import static io.agentscope.examples.harness.common.util.ExampleUtils.printWelcome; +import static io.agentscope.examples.harness.common.util.ExampleUtils.startChat; +import static io.agentscope.examples.harness.sandbox.DockerPythonSandboxImage.ensureImage; + +import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.core.model.Model; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.RuntimeContext; +import io.agentscope.harness.agent.sandbox.filesystem.DockerFilesystemSpec; +import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +public final class DockerPythonSandboxExample { + + public static void main(String[] args) throws Exception { + printWelcome( + "AgentScope Harness Docker Python Sandbox", + "Interactive assistant that can execute Python scripts inside a Docker sandbox."); + + ensureImage(); + + Path workspace = Paths.get(".agentscope/python-sandbox-workspace"); + initWorkspaceIfAbsent(workspace); + + String apiKey = getDashScopeApiKey(); + Model model = + DashScopeChatModel.builder().apiKey(apiKey).modelName("qwen-max").stream(true) + .build(); + + SandboxFilesystemSpec sandboxSpec = + new DockerFilesystemSpec() + .image(DockerPythonSandboxImage.IMAGE) + .workspaceRoot("/workspace") + .workspaceProjectionRoots(List.of("AGENTS.md", "examples")); + + HarnessAgent agent = + HarnessAgent.builder() + .name("docker-python-sandbox-agent") + .sysPrompt("你是一个 Python 数据分析助手。需要运行代码时,使用 shell 执行工具在 sandbox 中运行命令。") + .model(model) + .workspace(workspace) + .filesystem(sandboxSpec) + .maxIters(20) + .build(); + + RuntimeContext ctx = ctx("docker-python-demo-session", "alice"); + System.out.println("Workspace: " + workspace.toAbsolutePath()); + System.out.println("Try: 请运行 examples/check_libs.py 检查 sandbox 里的 Python 环境。\n"); + startChat(agent, ctx); + } + + private static void initWorkspaceIfAbsent(Path workspace) throws Exception { + Files.createDirectories(workspace.resolve("examples")); + writeIfAbsent( + workspace.resolve("AGENTS.md"), + """ + # Docker Python Sandbox Assistant + + 你运行在一个 Docker sandbox 工作区中。 + + ## 可用能力 + - 使用 shell 执行工具运行 Python 代码和命令 + - 优先在 `/workspace` 下读写文件 + - 可以执行 `python examples/check_libs.py` 检查预装库 + - 可以执行 `python examples/analyze_sales.py` 运行示例数据分析脚本 + + ## 行为约定 + - 执行代码前先简要说明计划 + - 执行失败时读取错误输出并修复脚本 + - 不要声称已运行代码,除非确实调用了 shell 执行工具 + """); + writeIfAbsent( + workspace.resolve("examples/check_libs.py"), + """ + import importlib + import sqlite3 + import subprocess + import sys + + modules = [ + "pandas", + "numpy", + "openpyxl", + "xlsxwriter", + "xlrd", + "PIL", + "pptx", + "docx", + "pypdf", + "pdfplumber", + "pypdfium2", + "pdf2image", + "img2pdf", + "sympy", + "mpmath", + "tqdm", + "dateutil", + "pytz", + "joblib", + ] + + print(sys.version) + print("sqlite", sqlite3.sqlite_version) + missing = [] + for module in modules: + try: + importlib.import_module(module) + except Exception as exc: + missing.append((module, str(exc))) + for command in ["rg", "fd", "unzip", "unrar", "7z", "bc"]: + completed = subprocess.run(["sh", "-lc", f"command -v {command}"], capture_output=True, text=True) + if completed.returncode != 0: + missing.append((command, "command not found")) + if missing: + print("Missing dependencies:") + for name, reason in missing: + print(f"- {name}: {reason}") + raise SystemExit(1) + print("All expected Python modules and utility commands are available.") + """); + writeIfAbsent( + workspace.resolve("examples/analyze_sales.py"), + """ + import pandas as pd + + data = pd.DataFrame( + [ + {"region": "north", "product": "notebook", "revenue": 1200}, + {"region": "north", "product": "pen", "revenue": 300}, + {"region": "south", "product": "notebook", "revenue": 900}, + {"region": "south", "product": "pen", "revenue": 450}, + ] + ) + + summary = data.groupby("region", as_index=False)["revenue"].sum() + print(summary.to_string(index=False)) + """); + } + + private static void writeIfAbsent(Path path, String content) throws Exception { + if (Files.exists(path)) { + return; + } + Files.createDirectories(path.getParent()); + Files.writeString(path, content); + } +} diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java new file mode 100644 index 000000000..81b4cb2fe --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java @@ -0,0 +1,158 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.TimeUnit; + +final class DockerPythonSandboxImage { + + static final String IMAGE = "agentscope/python-sandbox:py311-slim"; + + private DockerPythonSandboxImage() {} + + static void ensureImage() throws Exception { + Path dockerfile = findDockerfile(); + CommandResult dockerInfo = runAllowFailure(dockerInfoCommand(), 30); + if (dockerInfo.exitCode() != 0) { + throw new IllegalStateException(dockerAvailabilityErrorMessage(dockerInfo.output())); + } + if (runAllowFailure(inspectCommand(IMAGE), 30).exitCode() == 0) { + System.out.println("✓ Docker image exists: " + IMAGE); + return; + } + System.out.println("Docker image not found. Building: " + IMAGE); + runStreaming( + buildCommand(IMAGE, dockerfile), + 1800, + "Failed to build Docker image: " + IMAGE, + System.out, + System.err); + } + + static List dockerInfoCommand() { + return List.of("docker", "info"); + } + + static List inspectCommand(String image) { + return List.of("docker", "image", "inspect", image); + } + + static List buildCommand(String image, Path dockerfile) { + return List.of( + "docker", + "build", + "-t", + image, + "-f", + dockerfile.toString(), + dockerfile.getParent().toString()); + } + + static String dockerAvailabilityErrorMessage(String output) { + String details = output != null ? output.strip() : ""; + if (details.contains("Cannot connect to the Docker daemon")) { + return "Docker CLI is available, but the Docker daemon is not reachable." + + " Please start Docker Desktop or verify the active Docker context/socket.\n" + + details; + } + return "Docker is not available or not usable. Please install Docker and ensure the" + + " Docker daemon is running.\n" + + details; + } + + private static Path findDockerfile() { + String relative = "src/main/docker/python-sandbox/Dockerfile"; + String moduleRelative = "agentscope-examples/harness-examples/harness-sandbox/" + relative; + Path cwd = Path.of(System.getProperty("user.dir")); + for (Path candidate : List.of(cwd.resolve(relative), cwd.resolve(moduleRelative))) { + if (Files.isRegularFile(candidate)) { + return candidate.toAbsolutePath().normalize(); + } + } + throw new IllegalStateException( + "Cannot find Dockerfile. Run from repository root or harness-sandbox module."); + } + + private static void run(List command, int timeoutSeconds, String errorMessage) + throws Exception { + CommandResult result = runAllowFailure(command, timeoutSeconds); + if (result.exitCode() != 0) { + throw new IllegalStateException(errorMessage + "\n" + result.output()); + } + } + + static void runStreaming( + List command, + int timeoutSeconds, + String errorMessage, + PrintStream stdout, + PrintStream stderr) + throws Exception { + Process process = new ProcessBuilder(command).start(); + Thread stdoutForwarder = pipe(process.getInputStream(), stdout, "docker-build-stdout"); + Thread stderrForwarder = pipe(process.getErrorStream(), stderr, "docker-build-stderr"); + boolean finished = process.waitFor(timeoutSeconds, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + stdoutForwarder.join(); + stderrForwarder.join(); + stderr.println("Command timed out: " + String.join(" ", command)); + throw new IllegalStateException(errorMessage); + } + stdoutForwarder.join(); + stderrForwarder.join(); + if (process.exitValue() != 0) { + throw new IllegalStateException(errorMessage); + } + } + + private static Thread pipe(java.io.InputStream source, PrintStream target, String name) { + Thread thread = + new Thread( + () -> { + try (source) { + source.transferTo(target); + target.flush(); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }, + name); + thread.start(); + return thread; + } + + private static CommandResult runAllowFailure(List command, int timeoutSeconds) + throws IOException, InterruptedException { + Process process = new ProcessBuilder(command).redirectErrorStream(true).start(); + boolean finished = process.waitFor(timeoutSeconds, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + return new CommandResult(124, "Command timed out: " + String.join(" ", command)); + } + String output = new String(process.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + return new CommandResult(process.exitValue(), output); + } + + private record CommandResult(int exitCode, String output) {} +} diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java index 47ac18aa0..b29ef11b2 100644 --- a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java +++ b/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java @@ -23,7 +23,7 @@ * required — uses {@link FixedReplyModel} for a single turn per {@code call}. The * {@code store} mode is an alias for {@code remote} (shared KV / {@link RemoteFilesystemSpec}). * - *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|remote|store]} + *

    Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|remote|store|docker-python]} */ public final class HarnessSandboxExampleApp { @@ -42,9 +42,10 @@ public static void main(String[] args) throws Exception { case "local" -> LocalFilesystemPersonalAssistantExample.main(new String[0]); case "sandbox" -> SandboxFilesystemIsolationScopeExample.main(new String[0]); case "remote", "store" -> RemoteFilesystemIsolationScopeExample.main(new String[0]); + case "docker-python" -> DockerPythonSandboxExample.main(new String[0]); default -> { System.err.println("Unknown mode: " + mode); - System.err.println("Use: all | local | sandbox | remote | store"); + System.err.println("Use: all | local | sandbox | remote | store | docker-python"); System.exit(1); } } diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java b/agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java new file mode 100644 index 000000000..8b7caee91 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.junit.jupiter.api.Test; + +class DockerPythonSandboxImageTest { + + @Test + void runStreamingPrintsCommandOutput() throws Exception { + ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); + ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); + try (PrintStream stdout = new PrintStream(stdoutBuffer, true, StandardCharsets.UTF_8); + PrintStream stderr = new PrintStream(stderrBuffer, true, StandardCharsets.UTF_8)) { + DockerPythonSandboxImage.runStreaming( + List.of("sh", "-c", "printf 'build-log\\n'; printf 'warn-log\\n' >&2"), + 5, + "failed", + stdout, + stderr); + } + + assertTrue(stdoutBuffer.toString(StandardCharsets.UTF_8).contains("build-log")); + assertTrue(stderrBuffer.toString(StandardCharsets.UTF_8).contains("warn-log")); + } +} From 136ccd513553a03b88ed12a85e41913467569550 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 17:37:34 +0800 Subject: [PATCH 17/28] Refactor system message handling in PreCallEvent and related hooks --- .../java/io/agentscope/core/ReActAgent.java | 81 +++-- .../io/agentscope/core/agent/AgentBase.java | 101 +++++- .../io/agentscope/core/hook/HookEvent.java | 104 ++++++ .../io/agentscope/core/hook/PreCallEvent.java | 13 +- .../core/memory/StaticLongTermMemoryHook.java | 33 +- .../agentscope/core/model/ModelRegistry.java | 259 ++++++++++++++ .../io/agentscope/core/skill/SkillHook.java | 52 +-- .../agentscope/core/hook/HookEventTest.java | 77 ++++ .../core/hook/ReActAgentSystemMsgTest.java | 330 ++++++++++++++++++ .../memory/StaticLongTermMemoryHookTest.java | 12 +- .../core/model/ModelRegistryTest.java | 139 ++++++++ .../agentscope/core/skill/SkillHookTest.java | 99 ++---- .../skill/SkillRuntimeIntegrationTest.java | 11 +- .../harness/agent/HarnessAgent.java | 88 +++-- .../harness/agent/hook/AgentTraceHook.java | 5 +- .../harness/agent/hook/CompactionHook.java | 54 +-- .../harness/agent/hook/SubagentsHook.java | 50 +-- .../agent/hook/WorkspaceContextHook.java | 60 +--- .../agent/memory/MemoryFlushManager.java | 3 + .../agent/memory/session/SessionTree.java | 299 +++++++++++++--- .../harness/agent/tool/SessionSearchTool.java | 112 +++--- .../HarnessAgentDistributedSandboxTest.java | 6 +- .../agent/HarnessAgentModelStringTest.java | 125 +++++++ .../memory/session/SessionTreeMirrorTest.java | 166 ++++++++- 24 files changed, 1838 insertions(+), 441 deletions(-) create mode 100644 agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java create mode 100644 agentscope-core/src/test/java/io/agentscope/core/hook/ReActAgentSystemMsgTest.java create mode 100644 agentscope-core/src/test/java/io/agentscope/core/model/ModelRegistryTest.java create mode 100644 agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentModelStringTest.java diff --git a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java index 0e7513615..d65fd2dd0 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java @@ -157,6 +157,16 @@ public class ReActAgent extends StructuredOutputCapableAgent { private final StatePersistence statePersistence; private RuntimeContext pendingRuntimeContext; + /** + * Per-call system message, propagated across PreCallEvent → PreReasoningEvent / + * PreSummaryEvent. It is safe to use an {@link java.util.concurrent.atomic.AtomicReference} + * here because {@code AgentBase.acquireExecution()} guarantees that only one {@code call()} + * runs concurrently per agent instance, so this reference is effectively owned by a single + * logical execution at any time. + */ + private final java.util.concurrent.atomic.AtomicReference currentSystemMsg = + new java.util.concurrent.atomic.AtomicReference<>(); + // ==================== Constructor ==================== private ReActAgent(Builder builder, Toolkit agentToolkit) { @@ -193,6 +203,25 @@ protected void beforeAgentExecution(List msgs) { ctx = RuntimeContext.empty(); } bindRuntimeContextToHooks(ctx); + // Reset per-call system message; will be initialised by consumeSystemMsgAfterPreCall + currentSystemMsg.set(null); + } + + @Override + protected Msg seedSystemMsg() { + if (sysPrompt != null && !sysPrompt.trim().isEmpty()) { + return Msg.builder() + .name("system") + .role(MsgRole.SYSTEM) + .content(TextBlock.builder().text(sysPrompt).build()) + .build(); + } + return null; + } + + @Override + protected void consumeSystemMsgAfterPreCall(Msg systemMsg) { + currentSystemMsg.set(systemMsg); } @Override @@ -537,17 +566,17 @@ private Mono reasoning(int iter, boolean ignoreMaxIters) { ReasoningContext context = new ReasoningContext(getName()); return checkInterruptedAsync() - .then(notifyPreReasoningEvent(prepareMessages())) + .then(notifyPreReasoningEvent(memory.getMessages())) .flatMapMany( event -> { GenerateOptions options = event.getEffectiveGenerateOptions() != null ? event.getEffectiveGenerateOptions() : buildGenerateOptions(); - return model.stream( - event.getInputMessages(), - toolkit.getToolSchemas(), - options) + List modelInput = + prependSystemMsg( + event.getInputMessages(), event.getSystemMessage()); + return model.stream(modelInput, toolkit.getToolSchemas(), options) .concatMap(chunk -> checkInterruptedAsync().thenReturn(chunk)); }) .doOnNext( @@ -805,7 +834,10 @@ protected Mono summarizing() { return notifyPreSummaryHook(messageList, generateOptions) .flatMap( preSummaryEvent -> { - List effectiveMessages = preSummaryEvent.getInputMessages(); + List effectiveMessages = + prependSystemMsg( + preSummaryEvent.getInputMessages(), + preSummaryEvent.getSystemMessage()); GenerateOptions effectiveOptions = preSummaryEvent.getEffectiveGenerateOptions(); @@ -846,7 +878,7 @@ private Mono streamAndAccumulateSummary( } private List prepareSummaryMessages() { - List messageList = prepareMessages(); + List messageList = new ArrayList<>(memory.getMessages()); messageList.add( Msg.builder() .name("user") @@ -887,20 +919,21 @@ private Mono handleSummaryError(Throwable error) { // ==================== Helper Methods ==================== /** - * Prepare messages for model input. + * Prepends the system message to {@code msgs} if non-null. + * + *

    Called immediately before each {@code model.stream()} invocation to build the final + * LLM input without contaminating the in-memory message list. */ - private List prepareMessages() { - List messages = new ArrayList<>(); - if (sysPrompt != null && !sysPrompt.trim().isEmpty()) { - messages.add( - Msg.builder() - .name("system") - .role(MsgRole.SYSTEM) - .content(TextBlock.builder().text(sysPrompt).build()) - .build()); + private static List prependSystemMsg(List msgs, Msg systemMsg) { + if (systemMsg == null) { + return msgs != null ? msgs : List.of(); + } + List result = new ArrayList<>(); + result.add(systemMsg); + if (msgs != null) { + result.addAll(msgs); } - messages.addAll(memory.getMessages()); - return messages; + return result; } /** @@ -982,7 +1015,9 @@ private Mono notifyHooks(T event) { } private Mono notifyPreReasoningEvent(List msgs) { - return notifyHooks(new PreReasoningEvent(this, model.getModelName(), null, msgs)); + PreReasoningEvent event = new PreReasoningEvent(this, model.getModelName(), null, msgs); + event.setSystemMessage(currentSystemMsg.get()); + return notifyHooks(event); } private Mono notifyPostReasoning(Msg msg) { @@ -1052,9 +1087,11 @@ private Mono notifyReasoningChunk(Msg chunkMsg, ReasoningContext context) private Mono notifyPreSummaryHook( List msgs, GenerateOptions generateOptions) { - return notifyHooks( + PreSummaryEvent event = new PreSummaryEvent( - this, model.getModelName(), generateOptions, msgs, maxIters, maxIters)); + this, model.getModelName(), generateOptions, msgs, maxIters, maxIters); + event.setSystemMessage(currentSystemMsg.get()); + return notifyHooks(event); } private Mono notifyPostSummaryHook(Msg msg, GenerateOptions generateOptions) { diff --git a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java index a1c568c68..dbd9988b2 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java +++ b/agentscope-core/src/main/java/io/agentscope/core/agent/AgentBase.java @@ -23,7 +23,9 @@ import io.agentscope.core.hook.RuntimeContextAware; import io.agentscope.core.interruption.InterruptContext; import io.agentscope.core.interruption.InterruptSource; +import io.agentscope.core.memory.Memory; import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; import io.agentscope.core.shutdown.GracefulShutdownHook; import io.agentscope.core.shutdown.GracefulShutdownManager; import io.agentscope.core.state.StateModule; @@ -617,21 +619,104 @@ protected List getSortedHooks() { } /** - * Notify all hooks that agent is starting (preCall hook). + * Returns the initial system message to seed into {@link PreCallEvent} before hooks run. * - *

    Hooks may modify the input messages via {@link PreCallEvent#setInputMessages(List)}. - * Hooks are executed sequentially, with each hook receiving the event modified by previous hooks. + *

    The default implementation returns {@code null}. Subclasses (e.g. {@code ReActAgent}) + * override this to build a system message from their configured {@code sysPrompt}. * - * @param msgs Input messages - * @return Mono containing the messages after all hooks have processed them (may be modified) + * @return the seed system message, or {@code null} if none + */ + protected Msg seedSystemMsg() { + return null; + } + + /** + * Called after {@link PreCallEvent} hooks have run, with the final system message value. + * + *

    The default implementation is a no-op. Subclasses (e.g. {@code ReActAgent}) override + * this to persist the system message into a per-call {@code AtomicReference} so it is + * available to subsequent events ({@code PreReasoningEvent}, {@code PreSummaryEvent}). + * + * @param systemMsg the system message produced by all PreCall hooks (may be null) */ - private Mono> notifyPreCall(List msgs) { - PreCallEvent event = new PreCallEvent(this, msgs); + protected void consumeSystemMsgAfterPreCall(Msg systemMsg) {} + + /** + * Notify all hooks that agent is starting (preCall hook). + * + *

    The event's {@code inputMessages} contains the full message view: + * a snapshot of the agent's current memory followed by the {@code callArgs} passed to + * {@code call()}. Hooks may append non-SYSTEM messages to the tail. Injecting + * {@link MsgRole#SYSTEM} messages via {@code setInputMessages} is forbidden and + * detected at the end of this method — use {@link PreCallEvent#setSystemMessage} or + * {@link PreCallEvent#appendSystemContent} instead. + * + *

    After hooks run the system message is handed off via + * {@link #consumeSystemMsgAfterPreCall(Msg)}, and only the tail (messages beyond the + * snapshot boundary) is returned for {@code doCall} to add to memory. + * + * @param callArgs messages passed by the caller to {@code call()} + * @return Mono containing the new tail messages that {@code doCall} should add to memory + */ + private Mono> notifyPreCall(List callArgs) { + // Take a memory snapshot before hooks run (pre-hook view) + List snapshot = List.of(); + if (this instanceof io.agentscope.core.ReActAgent reactAgent) { + Memory mem = reactAgent.getMemory(); + if (mem != null) { + snapshot = mem.getMessages(); + } + } + final int snapshotSize = snapshot.size(); + + // Build full input for hooks: snapshot + callArgs + List fullInput = new ArrayList<>(snapshot); + if (callArgs != null) { + fullInput.addAll(callArgs); + } + + PreCallEvent event = new PreCallEvent(this, fullInput); + event.setSystemMessage(seedSystemMsg()); + Mono result = Mono.just(event); for (Hook hook : getSortedHooks()) { result = result.flatMap(hook::onEvent); } - return result.map(PreCallEvent::getInputMessages); + + return result.map( + e -> { + // Hand off the system message to the per-call state + consumeSystemMsgAfterPreCall(e.getSystemMessage()); + + // Extract the tail: messages appended beyond the snapshot boundary + List currentInput = e.getInputMessages(); + List tail; + if (currentInput == null || currentInput.size() <= snapshotSize) { + tail = List.of(); + } else { + tail = + new ArrayList<>( + currentInput.subList(snapshotSize, currentInput.size())); + } + + // Guard (ReActAgent only): hooks must not inject SYSTEM messages into the + // tail, since the tail is persisted to memory and SYSTEM messages would + // accumulate. Agents without memory (e.g. UserAgent) may legitimately + // pass SYSTEM messages as call arguments. + if (AgentBase.this instanceof io.agentscope.core.ReActAgent) { + for (Msg msg : tail) { + if (msg != null && msg.getRole() == MsgRole.SYSTEM) { + throw new IllegalStateException( + "Hooks must not inject SYSTEM messages into" + + " PreCallEvent.inputMessages. Use" + + " event.setSystemMessage() or" + + " event.appendSystemContent() instead."); + } + } + } + + return tail; + }); } /** diff --git a/agentscope-core/src/main/java/io/agentscope/core/hook/HookEvent.java b/agentscope-core/src/main/java/io/agentscope/core/hook/HookEvent.java index c3f8c2974..eca862c1b 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/hook/HookEvent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/hook/HookEvent.java @@ -18,6 +18,12 @@ import io.agentscope.core.ReActAgent; import io.agentscope.core.agent.Agent; import io.agentscope.core.memory.Memory; +import io.agentscope.core.message.ContentBlock; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -34,6 +40,31 @@ *

  13. {@link #getTimestamp()} - When the event occurred
  14. * * + *

    System message lifecycle: Every event carries a unified {@code systemMsg} field + * that holds the single {@link MsgRole#SYSTEM} message visible to the LLM. {@code ReActAgent} + * manages this field across the event lifecycle as follows: + *

      + *
    1. Seeded from {@code sysPrompt} at the start of each {@code call()} before + * {@link PreCallEvent} hooks run.
    2. + *
    3. After {@link PreCallEvent} hooks complete, the resulting system message is + * frozen as the base for the entire call.
    4. + *
    5. Before each {@link PreReasoningEvent} (and {@link PreSummaryEvent}), the frozen base + * is injected fresh into the event — hooks that run on these events always start from + * the same clean baseline and may append per-iteration content.
    6. + *
    7. Before {@code model.stream(...)} is called: the event's final system message is + * prepended to {@link PreReasoningEvent#getInputMessages()} as the first element.
    8. + *
    + * + *

    Because each {@link PreReasoningEvent} starts from a fresh copy of the frozen base, + * hooks that fire per-iteration (e.g. subagent guidance) can safely use + * {@link #appendSystemContent(String)} — content is added to that iteration's copy and never + * accumulates across iterations. + * + *

    Hooks should modify the system message exclusively via {@link #setSystemMessage(Msg)}, + * {@link #appendSystemContent(String)}, or {@link #appendSystemContent(ContentBlock)}. + * Injecting {@link MsgRole#SYSTEM} messages into {@code inputMessages} directly is forbidden + * and results in an {@link IllegalStateException} at runtime. + * *

    Modifiability: Whether an event allows modification is determined by * the presence of setter methods in the concrete event class. * @@ -47,6 +78,13 @@ public abstract sealed class HookEvent private final Agent agent; private final long timestamp; + /** + * The unified system message for this event. Hooks read and write this field via the + * helper methods below; {@code ReActAgent} propagates it between events and prepends it + * to the LLM input before every reasoning call. + */ + private Msg systemMsg; + /** * Constructor for HookEvent. * @@ -98,4 +136,70 @@ public final Memory getMemory() { } return null; } + + // ==================== System message API ==================== + + /** + * Returns the current unified system message, or {@code null} if none has been set. + * + *

    On {@link PreCallEvent} and {@link PreReasoningEvent}, modifications made by earlier + * hooks in the chain are already reflected here. + * + * @return the system message, may be null + */ + public final Msg getSystemMessage() { + return systemMsg; + } + + /** + * Replaces the entire system message with the given one. + * + *

    Prefer {@link #appendSystemContent} when you only need to add a portion of the system + * message; use this method only when you need to set a completely custom system message. + * + * @param systemMsg the new system message (may be null to clear) + */ + public final void setSystemMessage(Msg systemMsg) { + this.systemMsg = systemMsg; + } + + /** + * Appends the given text as a new {@link TextBlock} at the end of the system message. + * + *

    If no system message exists yet, one is created automatically with + * {@link MsgRole#SYSTEM} and name {@code "system"}. + * + * @param text the text to append (must not be null) + */ + public final void appendSystemContent(String text) { + Objects.requireNonNull(text, "text cannot be null"); + appendSystemContent(TextBlock.builder().text(text).build()); + } + + /** + * Appends a {@link ContentBlock} at the end of the system message. + * + *

    If no system message exists yet, one is created automatically with + * {@link MsgRole#SYSTEM} and name {@code "system"}. + * + * @param block the content block to append (must not be null) + */ + public final void appendSystemContent(ContentBlock block) { + Objects.requireNonNull(block, "block cannot be null"); + if (systemMsg == null) { + systemMsg = Msg.builder().name("system").role(MsgRole.SYSTEM).content(block).build(); + } else { + List merged = new ArrayList<>(systemMsg.getContent()); + merged.add(block); + systemMsg = + Msg.builder() + .id(systemMsg.getId()) + .name(systemMsg.getName()) + .role(MsgRole.SYSTEM) + .content(merged) + .metadata(systemMsg.getMetadata()) + .timestamp(systemMsg.getTimestamp()) + .build(); + } + } } diff --git a/agentscope-core/src/main/java/io/agentscope/core/hook/PreCallEvent.java b/agentscope-core/src/main/java/io/agentscope/core/hook/PreCallEvent.java index a81bf978a..d704f746a 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/hook/PreCallEvent.java +++ b/agentscope-core/src/main/java/io/agentscope/core/hook/PreCallEvent.java @@ -22,16 +22,25 @@ /** * Event fired before agent starts processing. * - *

    Modifiable: No (notification-only) + *

    Modifiable: Yes — {@link #setInputMessages(List)} and the inherited + * {@link HookEvent#setSystemMessage}, {@link HookEvent#appendSystemContent(String)} methods. * *

    Context: *

      *
    • {@link #getAgent()} - The agent instance
    • - *
    • {@link #getMemory()} - Agent's memory (includes input messages already added)
    • + *
    • {@link #getMemory()} - Agent's current (live) memory
    • + *
    • {@link #getInputMessages()} - Full message view: memory snapshot + this call's + * arguments. Hooks may append non-SYSTEM messages to the tail. Injecting + * {@link io.agentscope.core.message.MsgRole#SYSTEM} messages here is + * forbidden; use {@link HookEvent#setSystemMessage} instead.
    • + *
    • {@link #getSystemMessage()} - The unified system message seeded from + * {@code sysPrompt}; modify via the helper methods on {@link HookEvent}.
    • *
    * *

    Use Cases: *

      + *
    • Inject workspace context, skill prompts, or other static guidance into + * the system message via {@link HookEvent#appendSystemContent(String)}
    • *
    • Log the start of agent execution
    • *
    • Initialize execution-specific resources
    • *
    • Track agent invocation metrics
    • diff --git a/agentscope-core/src/main/java/io/agentscope/core/memory/StaticLongTermMemoryHook.java b/agentscope-core/src/main/java/io/agentscope/core/memory/StaticLongTermMemoryHook.java index b57bb5433..c662fbe72 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/memory/StaticLongTermMemoryHook.java +++ b/agentscope-core/src/main/java/io/agentscope/core/memory/StaticLongTermMemoryHook.java @@ -23,8 +23,6 @@ import io.agentscope.core.hook.PreCallEvent; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,13 +114,15 @@ public int priority() { } /** - * Handles PreReasoningEvent by retrieving relevant memories and injecting them. + * Handles PreCallEvent by retrieving relevant memories and injecting them into the system + * message via {@link PreCallEvent#appendSystemContent}. * - *

      Retrieves memories relevant to the user's query and injects them as a system - * message at the beginning of the message list. The memories are wrapped in - * {@code } tags for clear identification. + *

      Retrieves memories relevant to the last user message and appends them to the unified + * system message. The memories are wrapped in {@code } tags for clear + * identification. Since this hook fires only on {@link PreCallEvent} (once per call), there + * is no risk of accumulation across reasoning iterations. * - * @param event the PreReasoningEvent + * @param event the PreCallEvent * @return Mono containing the potentially modified event */ private Mono handlePreCall(PreCallEvent event) { @@ -142,24 +142,7 @@ private Mono handlePreCall(PreCallEvent event) { .filter(memoryText -> memoryText != null && !memoryText.isEmpty()) .flatMap( memoryText -> { - // Wrap memory content in tags - String wrappedMemory = wrap(memoryText); - - // Create system message with retrieved memories - Msg memoryMsg = - Msg.builder() - .role(MsgRole.SYSTEM) - .name("long_term_memory") - .content( - TextBlock.builder().text(wrappedMemory).build()) - .build(); - - // Inject memory message at the beginning - List enhancedMessages = new ArrayList<>(); - enhancedMessages.addAll(inputMessages); - enhancedMessages.add(memoryMsg); - event.setInputMessages(enhancedMessages); - + event.appendSystemContent(wrap(memoryText)); return Mono.just(event); }) .defaultIfEmpty(event) diff --git a/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java b/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java new file mode 100644 index 000000000..e6d5637a7 --- /dev/null +++ b/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java @@ -0,0 +1,259 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.regex.Pattern; + +/** + * Registry for resolving {@link Model} instances from string identifiers (named instances or + * {@code provider:model} patterns). User-registered factories take precedence over built-in + * providers. + * + *

      Built-in providers read API keys from standard environment variables when auto-creating + * models: {@code OPENAI_API_KEY}, {@code DASHSCOPE_API_KEY}, {@code GEMINI_API_KEY}, {@code + * ANTHROPIC_API_KEY} (optional for Anthropic SDK), {@code OLLAMA_BASE_URL} (optional, defaults to + * {@code http://localhost:11434}). + */ +public final class ModelRegistry { + + private static final ConcurrentHashMap namedModels = new ConcurrentHashMap<>(); + private static final CopyOnWriteArrayList userFactories = + new CopyOnWriteArrayList<>(); + private static final List builtinFactories = new ArrayList<>(); + private static final ConcurrentHashMap resolvedCache = new ConcurrentHashMap<>(); + + static { + registerBuiltin( + "openai:(.+)", + modelId -> { + String modelName = modelId.substring("openai:".length()); + String apiKey = env("OPENAI_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException( + "Environment variable OPENAI_API_KEY is required to auto-create" + + " model: " + + modelId); + } + return OpenAIChatModel.builder().apiKey(apiKey).modelName(modelName).stream( + true) + .build(); + }); + registerBuiltin( + "dashscope:(.+)", + modelId -> { + String modelName = modelId.substring("dashscope:".length()); + String apiKey = requireApiKey("DASHSCOPE_API_KEY", modelId); + return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream( + true) + .build(); + }); + registerBuiltin( + "qwen-.+", + modelId -> { + String apiKey = requireApiKey("DASHSCOPE_API_KEY", modelId); + return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelId).stream( + true) + .build(); + }); + registerBuiltin( + "anthropic:(.+)", + modelId -> { + String modelName = modelId.substring("anthropic:".length()); + String apiKey = env("ANTHROPIC_API_KEY"); + return AnthropicChatModel.builder().apiKey(apiKey).modelName(modelName).stream( + true) + .build(); + }); + registerBuiltin( + "gemini:(.+)", + modelId -> { + String modelName = modelId.substring("gemini:".length()); + String apiKey = requireApiKey("GEMINI_API_KEY", modelId); + return GeminiChatModel.builder() + .apiKey(apiKey) + .modelName(modelName) + .streamEnabled(true) + .build(); + }); + registerBuiltin( + "ollama:(.+)", + modelId -> { + String modelName = modelId.substring("ollama:".length()); + String baseUrl = env("OLLAMA_BASE_URL"); + if (baseUrl == null || baseUrl.isBlank()) { + baseUrl = "http://localhost:11434"; + } + return OllamaChatModel.builder().modelName(modelName).baseUrl(baseUrl).build(); + }); + } + + private ModelRegistry() {} + + /** + * Registers a named {@link Model} instance. {@link #resolve(String)} returns this instance for + * an exact {@code name} match (no caching of factory-created instances applies). + */ + public static void register(String name, Model model) { + Objects.requireNonNull(name, "name"); + Objects.requireNonNull(model, "model"); + namedModels.put(name, model); + } + + /** + * Registers a factory matched against the full {@code modelId} string using {@link + * Pattern#matches}. Newly registered factories are consulted before older user registrations + * and before built-in providers. + * + * @param modelNameRegex regex with semantics of {@link Pattern#matches(CharSequence)} on the + * full model id + * @param factory creates a {@link Model} from the full model id + */ + public static void registerFactory(String modelNameRegex, ModelFactory factory) { + Objects.requireNonNull(modelNameRegex, "modelNameRegex"); + Objects.requireNonNull(factory, "factory"); + Pattern pattern = Pattern.compile(modelNameRegex); + userFactories.add(0, new ProviderEntry(pattern, factory)); + } + + /** + * Resolves a {@link Model} for the given id: named registration first, then cached + * factory-created instance, then user factories (newest first), then built-in factories. + * + * @throws IllegalArgumentException if the id cannot be resolved or creation fails + */ + public static Model resolve(String modelId) { + Objects.requireNonNull(modelId, "modelId"); + String trimmed = modelId.trim(); + if (trimmed.isEmpty()) { + throw new IllegalArgumentException("modelId must not be blank"); + } + + Model named = namedModels.get(trimmed); + if (named != null) { + return named; + } + + Model cached = resolvedCache.get(trimmed); + if (cached != null) { + return cached; + } + + ProviderEntry entry = findMatchingEntry(trimmed); + if (entry == null) { + throw new IllegalArgumentException(buildNotFoundMessage(trimmed)); + } + + try { + Model created = entry.factory().create(trimmed); + Objects.requireNonNull(created, "ModelFactory returned null for: " + trimmed); + resolvedCache.put(trimmed, created); + return created; + } catch (RuntimeException e) { + throw new IllegalArgumentException( + "Failed to create model for id: " + trimmed + ": " + e.getMessage(), e); + } + } + + /** + * Returns {@code true} if {@link #resolve(String)} can find a named model or a matching factory + * pattern (without creating an instance). + */ + public static boolean canResolve(String modelId) { + if (modelId == null) { + return false; + } + String trimmed = modelId.trim(); + if (trimmed.isEmpty()) { + return false; + } + if (namedModels.containsKey(trimmed)) { + return true; + } + return findMatchingEntry(trimmed) != null; + } + + /** + * Clears named models, user-registered factories, and the factory-resolution cache. Built-in + * provider rules are preserved. Intended for tests. + */ + public static void reset() { + namedModels.clear(); + userFactories.clear(); + resolvedCache.clear(); + } + + @FunctionalInterface + public interface ModelFactory { + Model create(String modelId); + } + + private record ProviderEntry(Pattern pattern, ModelFactory factory) {} + + private static void registerBuiltin(String regex, ModelFactory factory) { + builtinFactories.add(new ProviderEntry(Pattern.compile(regex), factory)); + } + + private static ProviderEntry findMatchingEntry(String modelId) { + for (ProviderEntry e : userFactories) { + if (e.pattern().matcher(modelId).matches()) { + return e; + } + } + for (ProviderEntry e : builtinFactories) { + if (e.pattern().matcher(modelId).matches()) { + return e; + } + } + return null; + } + + private static String env(String key) { + return System.getenv(key); + } + + private static String requireApiKey(String envKey, String modelId) { + String v = env(envKey); + if (v == null || v.isBlank()) { + throw new IllegalStateException( + "Environment variable " + + envKey + + " is required to auto-create model: " + + modelId); + } + return v; + } + + private static String buildNotFoundMessage(String modelId) { + return "Cannot resolve model: \"" + + modelId + + "\".\n\nPossible causes:\n" + + " - No named model registered with this name. Use ModelRegistry.register(\"" + + modelId + + "\", instance).\n" + + " - No matching provider factory. Built-in providers: openai, dashscope," + + " gemini, anthropic, ollama.\n" + + " Format: \":\", e.g. \"openai:gpt-5.5\"," + + " \"dashscope:qwen-max\".\n" + + " - DashScope short form: \"qwen-*\" model ids (requires DASHSCOPE_API_KEY).\n" + + " - Missing API key environment variable (e.g., OPENAI_API_KEY," + + " DASHSCOPE_API_KEY)."; + } +} diff --git a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java index eab1cb015..b5dbf7b07 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java +++ b/agentscope-core/src/main/java/io/agentscope/core/skill/SkillHook.java @@ -18,20 +18,18 @@ import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PreCallEvent; -import io.agentscope.core.message.ContentBlock; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import java.util.ArrayList; -import java.util.List; import reactor.core.publisher.Mono; /** - * Injects the skill catalog prompt into the first system message on {@link PreCallEvent}. + * Injects the skill catalog prompt into the unified system message on {@link PreCallEvent} via + * {@link PreCallEvent#appendSystemContent(String)}. * *

      Uses priority {@link #SKILL_HOOK_PRIORITY} so that, in typical {@code HarnessAgent} wiring, * this hook runs after {@code SubagentsHook} (80) and before {@code WorkspaceContextHook} (900), * yielding append order: base prompt → subagents → skills → workspace context. + * + *

      The skill prompt is appended to the transient system message and is never stored in + * the agent's persistent {@code Memory}. */ public class SkillHook implements Hook { @@ -52,50 +50,12 @@ public Mono onEvent(T event) { if (event instanceof PreCallEvent preCallEvent) { String skillPrompt = skillBox.getSkillPrompt(); if (skillPrompt != null && !skillPrompt.isEmpty()) { - List inputMessages = preCallEvent.getInputMessages(); - int systemIndex = findFirstSystemMessageIndex(inputMessages); - if (systemIndex >= 0) { - // Merge skill prompt into existing system message in-place (structural) - Msg existingSystem = inputMessages.get(systemIndex); - List mergedContent = new ArrayList<>(existingSystem.getContent()); - mergedContent.add(TextBlock.builder().text(skillPrompt).build()); - Msg mergedMsg = - Msg.builder() - .id(existingSystem.getId()) - .role(MsgRole.SYSTEM) - .name(existingSystem.getName()) - .content(mergedContent) - .metadata(existingSystem.getMetadata()) - .timestamp(existingSystem.getTimestamp()) - .build(); - List newMessages = new ArrayList<>(inputMessages); - newMessages.set(systemIndex, mergedMsg); - preCallEvent.setInputMessages(newMessages); - } else { - // No existing system message, add one at the beginning - List newMessages = new ArrayList<>(inputMessages.size() + 1); - newMessages.add( - Msg.builder() - .role(MsgRole.SYSTEM) - .content(TextBlock.builder().text(skillPrompt).build()) - .build()); - newMessages.addAll(inputMessages); - preCallEvent.setInputMessages(newMessages); - } + preCallEvent.appendSystemContent(skillPrompt); } } return Mono.just(event); } - private int findFirstSystemMessageIndex(List messages) { - for (int i = 0; i < messages.size(); i++) { - if (messages.get(i).getRole() == MsgRole.SYSTEM) { - return i; - } - } - return -1; - } - @Override public int priority() { return SKILL_HOOK_PRIORITY; diff --git a/agentscope-core/src/test/java/io/agentscope/core/hook/HookEventTest.java b/agentscope-core/src/test/java/io/agentscope/core/hook/HookEventTest.java index b229f612d..259660dd5 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/hook/HookEventTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/hook/HookEventTest.java @@ -23,6 +23,7 @@ import io.agentscope.core.agent.Agent; import io.agentscope.core.agent.AgentBase; import io.agentscope.core.interruption.InterruptContext; +import io.agentscope.core.message.ContentBlock; import io.agentscope.core.message.Msg; import io.agentscope.core.message.MsgRole; import io.agentscope.core.message.TextBlock; @@ -357,4 +358,80 @@ void testNullValidation() { assertThrows(NullPointerException.class, () -> new ErrorEvent(testAgent, null)); } } + + @Nested + @DisplayName("System message API Tests") + class SystemMessageApiTests { + + private PreCallEvent event; + + @org.junit.jupiter.api.BeforeEach + void setup() { + event = new PreCallEvent(testAgent, List.of()); + } + + @Test + @DisplayName("getSystemMessage returns null by default") + void getSystemMessage_nullByDefault() { + assertNull(event.getSystemMessage()); + } + + @Test + @DisplayName("setSystemMessage stores and retrieves value") + void setSystemMessage_storesValue() { + Msg sys = + Msg.builder() + .role(MsgRole.SYSTEM) + .content(TextBlock.builder().text("hello").build()) + .build(); + event.setSystemMessage(sys); + assertEquals(sys, event.getSystemMessage()); + } + + @Test + @DisplayName("setSystemMessage(null) clears value") + void setSystemMessage_null_clears() { + event.appendSystemContent("init"); + event.setSystemMessage(null); + assertNull(event.getSystemMessage()); + } + + @Test + @DisplayName("appendSystemContent(String) creates SYSTEM msg when null") + void appendSystemContent_string_createsWhenNull() { + event.appendSystemContent("Hello system"); + + Msg sys = event.getSystemMessage(); + assertNotNull(sys); + assertEquals(MsgRole.SYSTEM, sys.getRole()); + assertEquals("Hello system", sys.getTextContent()); + } + + @Test + @DisplayName("appendSystemContent(String) appends to existing message") + void appendSystemContent_string_appendsToExisting() { + event.appendSystemContent("Part 1"); + event.appendSystemContent("Part 2"); + + Msg sys = event.getSystemMessage(); + assertNotNull(sys); + assertEquals(2, sys.getContent().size()); + assertEquals("Part 1\nPart 2", sys.getTextContent()); + } + + @Test + @DisplayName("appendSystemContent(ContentBlock) rejects null") + void appendSystemContent_block_rejectsNull() { + assertThrows( + NullPointerException.class, + () -> event.appendSystemContent((ContentBlock) null)); + } + + @Test + @DisplayName("appendSystemContent(String) rejects null") + void appendSystemContent_string_rejectsNull() { + assertThrows( + NullPointerException.class, () -> event.appendSystemContent((String) null)); + } + } } diff --git a/agentscope-core/src/test/java/io/agentscope/core/hook/ReActAgentSystemMsgTest.java b/agentscope-core/src/test/java/io/agentscope/core/hook/ReActAgentSystemMsgTest.java new file mode 100644 index 000000000..9bdec58be --- /dev/null +++ b/agentscope-core/src/test/java/io/agentscope/core/hook/ReActAgentSystemMsgTest.java @@ -0,0 +1,330 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.hook; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.ReActAgent; +import io.agentscope.core.memory.InMemoryMemory; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Tests for the unified system-message propagation introduced by the HookEvent.systemMsg + * refactoring. + * + *

      Key scenarios verified: + *

        + *
      • sysPrompt is seeded as systemMsg before PreCallEvent hooks run
      • + *
      • systemMsg modified by a PreCallEvent hook is propagated to PreReasoningEvent
      • + *
      • systemMsg is prepended to the model.stream() input as the first message
      • + *
      • PreCallEvent.inputMessages now contains memory snapshot + callArgs (full view)
      • + *
      • Hooks that inject SYSTEM into inputMessages.tail throw IllegalStateException
      • + *
      + */ +@DisplayName("ReActAgent system-message propagation tests") +class ReActAgentSystemMsgTest { + + private static final Duration TIMEOUT = Duration.ofSeconds(5); + + private Model mockModel; + private InMemoryMemory memory; + + @BeforeEach + void setUp() { + mockModel = mock(Model.class); + memory = new InMemoryMemory(); + } + + /** Stubs the model to emit a single text response. */ + private void stubModelText(String text) { + ChatResponse response = + ChatResponse.builder() + .content(List.of(TextBlock.builder().text(text).build())) + .build(); + when(mockModel.stream(anyList(), any(), any())).thenReturn(Flux.just(response)); + when(mockModel.getModelName()).thenReturn("stub"); + } + + private Msg userMsg(String text) { + return Msg.builder() + .name("user") + .role(MsgRole.USER) + .content(TextBlock.builder().text(text).build()) + .build(); + } + + // ========================================================================= + + @Nested + @DisplayName("sysPrompt seeded as systemMsg") + class SysPromptSeeding { + + @Test + @DisplayName("sysPrompt becomes systemMsg before PreCallEvent hooks run") + void sysPrompt_isSeededIntoSystemMsg() { + AtomicReference capturedSysMsg = new AtomicReference<>(); + + stubModelText("done"); + ReActAgent agent = + ReActAgent.builder() + .name("agent") + .model(mockModel) + .memory(memory) + .sysPrompt("You are a helpful assistant.") + .maxIters(1) + .hook( + new Hook() { + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent) { + capturedSysMsg.set(event.getSystemMessage()); + } + return Mono.just(event); + } + }) + .build(); + + agent.call(List.of(userMsg("hello"))).block(TIMEOUT); + + Msg sys = capturedSysMsg.get(); + assertNotNull(sys); + assertEquals(MsgRole.SYSTEM, sys.getRole()); + assertTrue( + sys.getTextContent().contains("You are a helpful assistant."), + "systemMsg should contain sysPrompt text"); + } + + @Test + @DisplayName("agent with empty sysPrompt seeds null systemMsg") + void emptySysPrompt_seedsNullSystemMsg() { + AtomicReference capturedSysMsg = + new AtomicReference<>( + Msg.builder() + .role(MsgRole.SYSTEM) + .content(TextBlock.builder().text("marker").build()) + .build()); + + stubModelText("done"); + ReActAgent agent = + ReActAgent.builder() + .name("agent") + .model(mockModel) + .memory(memory) + .maxIters(1) + .hook( + new Hook() { + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent) { + capturedSysMsg.set(event.getSystemMessage()); + } + return Mono.just(event); + } + }) + .build(); + + agent.call(List.of(userMsg("hello"))).block(TIMEOUT); + + // Without sysPrompt, the seed is null + assertTrue( + capturedSysMsg.get() == null || capturedSysMsg.get().getTextContent().isBlank(), + "Expected null or blank systemMsg when sysPrompt is empty"); + } + } + + // ========================================================================= + + @Nested + @DisplayName("systemMsg propagated to reasoning") + class SystemMsgPropagation { + + @Test + @DisplayName("systemMsg set by PreCallEvent hook appears as first message in model input") + void preCallHook_systemMsg_prependedToModelInput() { + List> modelInputCapture = new ArrayList<>(); + + when(mockModel.getModelName()).thenReturn("stub"); + when(mockModel.stream(anyList(), any(), any())) + .thenAnswer( + invocation -> { + @SuppressWarnings("unchecked") + List msgs = invocation.getArgument(0); + modelInputCapture.add(new ArrayList<>(msgs)); + ChatResponse resp = + ChatResponse.builder() + .content( + List.of( + TextBlock.builder() + .text("ok") + .build())) + .build(); + return Flux.just(resp); + }); + + ReActAgent agent = + ReActAgent.builder() + .name("agent") + .model(mockModel) + .memory(memory) + .sysPrompt("base prompt") + .maxIters(1) + .hook( + new Hook() { + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent) { + event.appendSystemContent(" extra context"); + } + return Mono.just(event); + } + }) + .build(); + + agent.call(List.of(userMsg("hi"))).block(TIMEOUT); + + assertEquals(1, modelInputCapture.size(), "model.stream should be called once"); + List input = modelInputCapture.get(0); + assertTrue(input.size() >= 1, "model should receive at least one message"); + + Msg firstMsg = input.get(0); + assertEquals(MsgRole.SYSTEM, firstMsg.getRole(), "first message must be SYSTEM"); + String sysText = firstMsg.getTextContent(); + assertTrue(sysText.contains("base prompt"), "systemMsg should contain sysPrompt"); + assertTrue( + sysText.contains("extra context"), + "systemMsg should include text appended by hook"); + } + } + + // ========================================================================= + + @Nested + @DisplayName("PreCallEvent full message view") + class PreCallFullMessageView { + + @Test + @DisplayName("PreCallEvent inputMessages contains memory snapshot + callArgs") + void preCallEvent_containsMemoryPlusCallArgs() { + // Seed memory with one prior message + Msg priorMsg = userMsg("prior turn"); + memory.addMessage(priorMsg); + + AtomicReference> capturedInput = new AtomicReference<>(); + + stubModelText("done"); + ReActAgent agent = + ReActAgent.builder() + .name("agent") + .model(mockModel) + .memory(memory) + .maxIters(1) + .hook( + new Hook() { + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent pre) { + capturedInput.set( + new ArrayList<>(pre.getInputMessages())); + } + return Mono.just(event); + } + }) + .build(); + + Msg callArg = userMsg("new message"); + agent.call(List.of(callArg)).block(TIMEOUT); + + List input = capturedInput.get(); + assertNotNull(input); + assertEquals(2, input.size(), "inputMessages should be [prior, callArg]"); + assertEquals( + "prior turn", + input.get(0).getTextContent(), + "first message should be the memory snapshot"); + assertEquals( + "new message", + input.get(1).getTextContent(), + "second message should be the call argument"); + } + } + + // ========================================================================= + + @Nested + @DisplayName("SYSTEM-in-tail guard") + class SystemInTailGuard { + + @Test + @DisplayName("Hook injecting SYSTEM into inputMessages tail throws IllegalStateException") + void hook_injectingSystemIntoTail_throws() { + stubModelText("done"); + ReActAgent agent = + ReActAgent.builder() + .name("agent") + .model(mockModel) + .memory(memory) + .maxIters(1) + .hook( + new Hook() { + @Override + public Mono onEvent(T event) { + if (event instanceof PreCallEvent pre) { + // Forbidden: append SYSTEM to inputMessages + List msgs = + new ArrayList<>(pre.getInputMessages()); + msgs.add( + Msg.builder() + .role(MsgRole.SYSTEM) + .content( + TextBlock.builder() + .text("bad") + .build()) + .build()); + pre.setInputMessages(msgs); + } + return Mono.just(event); + } + }) + .build(); + + assertThrows( + Exception.class, + () -> agent.call(List.of(userMsg("hello"))).block(TIMEOUT), + "Should throw when SYSTEM message appears in inputMessages tail"); + } + } +} diff --git a/agentscope-core/src/test/java/io/agentscope/core/memory/StaticLongTermMemoryHookTest.java b/agentscope-core/src/test/java/io/agentscope/core/memory/StaticLongTermMemoryHookTest.java index 37417ee26..9645db2e6 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/memory/StaticLongTermMemoryHookTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/memory/StaticLongTermMemoryHookTest.java @@ -136,15 +136,19 @@ void testOnEventWithPreReasoningEventAndRetrievedMemories() { StepVerifier.create(hook.onEvent(event)) .assertNext( resultEvent -> { + // Memory is now injected into systemMsg, not inputMessages List messages = resultEvent.getInputMessages(); - assertEquals(2, messages.size()); - assertEquals(MsgRole.SYSTEM, messages.get(1).getRole()); + assertEquals(1, messages.size(), "inputMessages should be unchanged"); + assertNotNull( + resultEvent.getSystemMessage(), "systemMsg should be set"); assertTrue( - messages.get(1) + resultEvent + .getSystemMessage() .getTextContent() .contains("")); assertTrue( - messages.get(1) + resultEvent + .getSystemMessage() .getTextContent() .contains("User prefers dark mode")); }) diff --git a/agentscope-core/src/test/java/io/agentscope/core/model/ModelRegistryTest.java b/agentscope-core/src/test/java/io/agentscope/core/model/ModelRegistryTest.java new file mode 100644 index 000000000..7d0bd52df --- /dev/null +++ b/agentscope-core/src/test/java/io/agentscope/core/model/ModelRegistryTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.core.model; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.agentscope.core.message.Msg; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import reactor.core.publisher.Flux; + +class ModelRegistryTest { + + @BeforeEach + void setUp() { + ModelRegistry.reset(); + } + + @AfterEach + void tearDown() { + ModelRegistry.reset(); + } + + @Test + void resolve_namedInstance_returnsRegistered() { + Model m = new StubModel("x"); + ModelRegistry.register("my-model", m); + assertSame(m, ModelRegistry.resolve("my-model")); + } + + @Test + void resolve_namedInstance_precedesFactory() { + Model named = new StubModel("named"); + ModelRegistry.register("openai:fake", named); + AtomicInteger factoryCalls = new AtomicInteger(); + ModelRegistry.registerFactory( + "openai:(.+)", + id -> { + factoryCalls.incrementAndGet(); + return new StubModel("factory"); + }); + assertSame(named, ModelRegistry.resolve("openai:fake")); + assertSame(named, ModelRegistry.resolve("openai:fake")); + assertTrue(factoryCalls.get() == 0); + } + + @Test + @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") + void resolve_openaiFormat_createsOpenAIChatModel() { + Model m = ModelRegistry.resolve("openai:gpt-4o-mini"); + assertInstanceOf(OpenAIChatModel.class, m); + } + + @Test + @EnabledIfEnvironmentVariable(named = "DASHSCOPE_API_KEY", matches = ".+") + void resolve_dashscopeShortFormat_createsDashScopeChatModel() { + Model m = ModelRegistry.resolve("qwen-max"); + assertInstanceOf(DashScopeChatModel.class, m); + } + + @Test + void resolve_unknownModel_throwsWithHelpMessage() { + IllegalArgumentException ex = + assertThrows( + IllegalArgumentException.class, + () -> ModelRegistry.resolve("totally-unknown-id")); + assertTrue(ex.getMessage().contains("Cannot resolve model")); + assertTrue(ex.getMessage().contains("OPENAI_API_KEY")); + } + + @Test + void resolve_caching_returnsSameInstance() { + Model a = ModelRegistry.resolve("ollama:llama3"); + Model b = ModelRegistry.resolve("ollama:llama3"); + assertSame(a, b); + } + + @Test + void registerFactory_userFactory_takesPriorityOverBuiltin() { + Model custom = new StubModel("custom-openai"); + ModelRegistry.registerFactory("openai:(.+)", id -> custom); + assertSame(custom, ModelRegistry.resolve("openai:anything")); + } + + @Test + void canResolve_knownOpenAiPattern_returnsTrue() { + assertTrue(ModelRegistry.canResolve("openai:gpt-5.5")); + } + + @Test + void canResolve_unknownPattern_returnsFalse() { + org.junit.jupiter.api.Assertions.assertFalse( + ModelRegistry.canResolve("unknown-provider:x")); + } + + @Test + void resolve_blankModelId_throws() { + assertThrows(IllegalArgumentException.class, () -> ModelRegistry.resolve(" ")); + } + + private static final class StubModel implements Model { + private final String name; + + StubModel(String name) { + this.name = name; + } + + @Override + public Flux stream( + List messages, List tools, GenerateOptions options) { + return Flux.empty(); + } + + @Override + public String getModelName() { + return name; + } + } +} diff --git a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java index c51f81982..3df4f3822 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillHookTest.java @@ -97,16 +97,14 @@ void testInjectSkillPromptWhenSkillsActive() { // Act: Process event through hook PreCallEvent result = skillHook.onEvent(event).block(); - // Assert: Skill prompt should be injected + // Assert: Skill prompt should be injected into systemMsg, not inputMessages assertNotNull(result, "Event should be processed"); - assertEquals(2, result.getInputMessages().size(), "Should add skill prompt message"); - assertEquals( - MsgRole.SYSTEM, - result.getInputMessages().get(0).getRole(), - "Skill prompt should be SYSTEM message"); + assertEquals(1, result.getInputMessages().size(), "Should not add SYSTEM to inputMessages"); + assertNotNull(result.getSystemMessage(), "systemMsg should be set by SkillHook"); + assertEquals(MsgRole.SYSTEM, result.getSystemMessage().getRole()); assertTrue( - result.getInputMessages().get(0).getContent().toString().contains("test_skill"), - "Skill prompt should contain skill information"); + result.getSystemMessage().getTextContent().contains("test_skill"), + "systemMsg should contain skill information"); } /** @@ -153,16 +151,11 @@ void testInjectPromptForRegisteredSkills() { // Act: Process event through hook PreCallEvent result = skillHook.onEvent(event).block(); - // Assert: Skill prompt should be added for registered skills + // Assert: Skill prompt should be in systemMsg, not inputMessages assertNotNull(result, "Event should be processed"); - assertEquals( - 2, - result.getInputMessages().size(), - "Should add skill prompt for registered skills"); - assertEquals( - MsgRole.SYSTEM, - result.getInputMessages().get(0).getRole(), - "Skill prompt should be SYSTEM message"); + assertEquals(1, result.getInputMessages().size(), "Should not add SYSTEM to inputMessages"); + assertNotNull(result.getSystemMessage(), "systemMsg should be set for registered skills"); + assertEquals(MsgRole.SYSTEM, result.getSystemMessage().getRole()); } @Test @@ -271,29 +264,26 @@ void testInjectSkillPromptAtFirst() { // Act: Process event through hook PreCallEvent result = skillHook.onEvent(event).block(); - // Assert: Skill prompt should be injected at the FIRST position + // Assert: Skill prompt should be in systemMsg; inputMessages unchanged assertNotNull(result, "Event should be processed"); - assertEquals(3, result.getInputMessages().size(), "Should add skill prompt message"); - - // Verify the first message is the skill prompt (SYSTEM role) - Msg firstMsg = result.getInputMessages().get(0); assertEquals( - MsgRole.SYSTEM, - firstMsg.getRole(), - "First message should be SYSTEM message with skill prompt"); + 2, + result.getInputMessages().size(), + "inputMessages should not gain a SYSTEM entry"); + assertNotNull(result.getSystemMessage(), "systemMsg should be set"); assertTrue( - firstMsg.getTextContent().contains("test_skill"), - "First message should contain skill information"); + result.getSystemMessage().getTextContent().contains("test_skill"), + "systemMsg should contain skill information"); - // Verify original messages are preserved in order after skill prompt + // Verify original messages are preserved in order assertEquals( "User query", - result.getInputMessages().get(1).getTextContent(), - "Second message should be original user query"); + result.getInputMessages().get(0).getTextContent(), + "First message should be original user query"); assertEquals( "Assistant response", - result.getInputMessages().get(2).getTextContent(), - "Third message should be original assistant response"); + result.getInputMessages().get(1).getTextContent(), + "Second message should be original assistant response"); } @Test @@ -334,42 +324,23 @@ void testMergeSkillPromptIntoExistingSystemMessage() { // Act: Process event through hook PreCallEvent result = skillHook.onEvent(event).block(); - // Assert: Should still have exactly 3 messages (merged, not added) + // Assert: SkillHook uses systemMsg API now; inputMessages are NOT modified. + // The pre-existing SYSTEM message in inputMessages stays there (it's in the caller's list), + // and the skill prompt is appended to event.getSystemMessage(). assertNotNull(result, "Event should be processed"); + + // inputMessages still has 3 items (unchanged by SkillHook) assertEquals( - 3, - result.getInputMessages().size(), - "Should merge into existing SYSTEM message, not add a new one"); - - // Verify there is exactly one SYSTEM message - long systemCount = - result.getInputMessages().stream() - .filter(m -> m.getRole() == MsgRole.SYSTEM) - .count(); - assertEquals(1, systemCount, "There should be exactly one SYSTEM message"); - - // Verify the merged SYSTEM message is at index 0 - Msg systemMsg = result.getInputMessages().get(0); - assertEquals(MsgRole.SYSTEM, systemMsg.getRole()); - - // Verify structural merge: content blocks are preserved, not flattened - // First content block should be the original system instruction TextBlock, - // second should be the skill prompt TextBlock - assertEquals( - 2, - systemMsg.getContent().size(), - "Merged SYSTEM message should have 2 content blocks (structural merge)"); - assertInstanceOf(TextBlock.class, systemMsg.getContent().get(0)); - assertInstanceOf(TextBlock.class, systemMsg.getContent().get(1)); - assertEquals( - "System instruction", - ((TextBlock) systemMsg.getContent().get(0)).getText(), - "First content block should be the original system instruction"); + 3, result.getInputMessages().size(), "SkillHook should not modify inputMessages"); + + // systemMsg should contain the skill prompt + assertNotNull(result.getSystemMessage(), "systemMsg should be set by SkillHook"); + assertEquals(MsgRole.SYSTEM, result.getSystemMessage().getRole()); assertTrue( - ((TextBlock) systemMsg.getContent().get(1)).getText().contains("test_skill"), - "Second content block should be the skill prompt"); + result.getSystemMessage().getTextContent().contains("test_skill"), + "systemMsg should contain skill information"); - // Verify other messages are preserved + // Verify original messages are preserved in order assertEquals("User query", result.getInputMessages().get(1).getTextContent()); assertEquals("Assistant response", result.getInputMessages().get(2).getTextContent()); } diff --git a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java index d9ad4ef11..0fa36d793 100644 --- a/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java +++ b/agentscope-core/src/test/java/io/agentscope/core/skill/SkillRuntimeIntegrationTest.java @@ -144,14 +144,17 @@ void testCompleteSkillActivationFlow() { PreCallEvent preCallEvent = new PreCallEvent(testAgent, messages); PreCallEvent result = skillHook.onEvent(preCallEvent).block(); - // Step 7: Verify skill prompt was injected + // Step 7: Verify skill prompt was injected into systemMsg assertNotNull(result, "PreCallEvent should be processed"); assertEquals( - 2, result.getInputMessages().size(), "Should add skill prompt to input messages"); + 1, + result.getInputMessages().size(), + "inputMessages should not gain a SYSTEM entry"); + assertNotNull(result.getSystemMessage(), "systemMsg should be set by SkillHook"); assertEquals( MsgRole.SYSTEM, - result.getInputMessages().get(0).getRole(), - "Skill prompt should be SYSTEM message"); + result.getSystemMessage().getRole(), + "systemMsg should be SYSTEM role"); // Step 8: Verify skill and tool group remain active assertTrue(skillBox.isSkillActive(skillId), "Skill should remain active"); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 04793cd2b..cc678146b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -28,6 +28,7 @@ import io.agentscope.core.model.ExecutionConfig; import io.agentscope.core.model.GenerateOptions; import io.agentscope.core.model.Model; +import io.agentscope.core.model.ModelRegistry; import io.agentscope.core.session.JsonSession; import io.agentscope.core.session.Session; import io.agentscope.core.skill.AgentSkill; @@ -111,7 +112,7 @@ *
      {@code
        * HarnessAgent agent = HarnessAgent.builder()
        *     .name("MyAgent")
      - *     .model(model)
      + *     .model(model) // or .model("openai:gpt-5.5") via {@link ModelRegistry}
        *     .sysPrompt("You are a helpful assistant.")
        *     .workspace("/path/to/workspace")
        *     .build();
      @@ -176,10 +177,20 @@ public Flux stream(List msgs, StreamOptions options, RuntimeContext
               return delegate.stream(msgs, options, coreForDelegate());
           }
       
      -    private io.agentscope.core.agent.RuntimeContext coreForDelegate() {
      +    /** Streams with default {@link StreamOptions} and a runtime context. */
      +    public Flux stream(List msgs, RuntimeContext ctx) {
      +        return stream(msgs, StreamOptions.defaults(), ctx);
      +    }
      +
      +    /** Streams a single message with default {@link StreamOptions} and a runtime context. */
      +    public Flux stream(Msg msg, RuntimeContext ctx) {
      +        return stream(List.of(msg), ctx);
      +    }
      +
      +    private RuntimeContext coreForDelegate() {
               return runtimeContext != null
                       ? runtimeContext
      -                : io.agentscope.core.agent.RuntimeContext.empty();
      +                : RuntimeContext.empty();
           }
       
           private Mono recoverFromOverflow(List msgs) {
      @@ -503,6 +514,23 @@ public Builder model(Model model) {
                   return this;
               }
       
      +        /**
      +         * Configures the model from a string id resolved via {@link ModelRegistry}: a named
      +         * registration ({@link ModelRegistry#register(String, Model)}) or a built-in pattern such
      +         * as {@code openai:gpt-5.5}, {@code dashscope:qwen-max}, {@code anthropic:claude-sonnet-4-5},
      +         * {@code gemini:gemini-2.0-flash}, or {@code ollama:llama3}. API keys for auto-created models
      +         * come from standard environment variables ({@code OPENAI_API_KEY}, {@code DASHSCOPE_API_KEY},
      +         * etc.).
      +         *
      +         * @param modelId registry id or {@code provider:model} string
      +         * @return this builder
      +         * @throws IllegalArgumentException if the id cannot be resolved
      +         */
      +        public Builder model(String modelId) {
      +            this.model = ModelRegistry.resolve(modelId);
      +            return this;
      +        }
      +
               public Builder toolkit(Toolkit toolkit) {
                   this.toolkit = toolkit;
                   return this;
      @@ -768,7 +796,9 @@ public Builder externalSubagentTool(Object tool) {
       
               /**
                * Sets a resolver for model name strings to {@link Model} instances. Used when spec-based
      -         * subagents specify a {@code model} override (e.g. {@code "openai:gpt-4o-mini"}).
      +         * subagents specify a {@code model} override (e.g. {@code "openai:gpt-4o-mini"}). When unset,
      +         * {@link ModelRegistry#resolve(String)} is used so subagent specs can use the same string ids
      +         * as {@link #model(String)}.
                */
               public Builder modelResolver(Function resolver) {
                   this.modelResolver = resolver;
      @@ -873,10 +903,10 @@ public HarnessAgent build() {
                   // distributed Session so that conversation state is also shared across replicas.
                   if (remoteFilesystemSpec != null && effectiveSession instanceof WorkspaceSession) {
                       throw new IllegalStateException(
      -                        "filesystem(RemoteFilesystemSpec) is designed for distributed / multi-replica"
      -                                + " deployments, but the effective Session is a local"
      -                                + " WorkspaceSession. Configure a distributed Session backend"
      -                                + " (for example RedisSession) via .session(...).");
      +                        "filesystem(RemoteFilesystemSpec) is designed for distributed /"
      +                                + " multi-replica deployments, but the effective Session is a local"
      +                                + " WorkspaceSession. Configure a distributed Session backend (for"
      +                                + " example RedisSession) via .session(...).");
                   }
       
                   AtomicReference userIdRef = new AtomicReference<>();
      @@ -1234,8 +1264,8 @@ private SubagentFactory buildGeneralPurposeFactory(
               /**
                * Builds a factory for a spec-based subagent. The resulting HarnessAgent is fully
                * independent from the main agent — it uses the spec's own system prompt, workspace,
      -         * and configuration. Supports per-subagent model override when a {@code modelResolver}
      -         * is configured.
      +         * and configuration. Supports per-subagent {@code model} override via an explicit {@code
      +         * modelResolver}, or by default {@link ModelRegistry#resolve(String)}.
                */
               private SubagentFactory buildSpecFactory(SubagentSpec spec, Path defaultWorkspace) {
                   final Model capturedModel = this.model;
      @@ -1249,26 +1279,30 @@ private SubagentFactory buildSpecFactory(SubagentSpec spec, Path defaultWorkspac
                                       ? Path.of(spec.getWorkspace())
                                       : defaultWorkspace;
       
      +                Function effectiveResolver =
      +                        capturedResolver != null ? capturedResolver : ModelRegistry::resolve;
      +
                       Model effectiveModel = capturedModel;
      -                if (spec.getModel() != null
      -                        && !spec.getModel().isBlank()
      -                        && capturedResolver != null) {
      -                    try {
      -                        Model resolved = capturedResolver.apply(spec.getModel());
      -                        if (resolved != null) {
      -                            effectiveModel = resolved;
      -                            log.debug(
      -                                    "Subagent '{}' using overridden model: {}",
      +                if (spec.getModel() != null && !spec.getModel().isBlank()) {
      +                    String specModel = spec.getModel().trim();
      +                    if (ModelRegistry.canResolve(specModel) || capturedResolver != null) {
      +                        try {
      +                            Model resolved = effectiveResolver.apply(specModel);
      +                            if (resolved != null) {
      +                                effectiveModel = resolved;
      +                                log.debug(
      +                                        "Subagent '{}' using overridden model: {}",
      +                                        spec.getName(),
      +                                        spec.getModel());
      +                            }
      +                        } catch (Exception e) {
      +                            log.warn(
      +                                    "Failed to resolve model '{}' for subagent '{}', falling back"
      +                                            + " to parent model: {}",
      +                                    spec.getModel(),
                                           spec.getName(),
      -                                    spec.getModel());
      +                                    e.getMessage());
                               }
      -                    } catch (Exception e) {
      -                        log.warn(
      -                                "Failed to resolve model '{}' for subagent '{}', falling back to"
      -                                        + " parent model: {}",
      -                                spec.getModel(),
      -                                spec.getName(),
      -                                e.getMessage());
                           }
                       }
       
      diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java
      index 595075ceb..5f3c05567 100644
      --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java
      +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/AgentTraceHook.java
      @@ -196,7 +196,10 @@ private static String truncate(String s, int max) {
               if (s == null || s.isEmpty()) {
                   return "";
               }
      -        return s.length() <= max ? s : s.substring(0, max) + "...";
      +        if (s.length() <= max) {
      +            return s;
      +        }
      +        return s.substring(0, max) + "...[truncated, limit=" + max + " chars]";
           }
       
           private static String mapToJson(Map map) {
      diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java
      index 2b5e89987..3a13f1fe2 100644
      --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java
      +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/CompactionHook.java
      @@ -23,13 +23,11 @@
       import io.agentscope.core.hook.RuntimeContextAware;
       import io.agentscope.core.memory.Memory;
       import io.agentscope.core.message.Msg;
      -import io.agentscope.core.message.MsgRole;
       import io.agentscope.core.model.Model;
       import io.agentscope.harness.agent.memory.MemoryFlushManager;
       import io.agentscope.harness.agent.memory.compaction.CompactionConfig;
       import io.agentscope.harness.agent.memory.compaction.ConversationCompactor;
       import io.agentscope.harness.agent.workspace.WorkspaceManager;
      -import java.util.ArrayList;
       import java.util.List;
       import org.slf4j.Logger;
       import org.slf4j.LoggerFactory;
      @@ -45,13 +43,17 @@
        *   
    • The prefix is distilled into a structured summary via one LLM call.
    • *
    • The agent's working {@link Memory} is replaced with * {@code [summaryMsg] + preservedTail}.
    • - *
    • {@link PreReasoningEvent#setInputMessages} is updated so the LLM sees the - * compacted view: {@code systemMsgs + [summaryMsg] + preservedTail}.
    • + *
    • {@link PreReasoningEvent#setInputMessages} is updated to the compacted conversation + * ({@code [summaryMsg] + preservedTail}). The system message is managed separately in + * {@link PreReasoningEvent#getSystemMessage()} and prepended by {@code ReActAgent} + * just before {@code model.stream()}, so this hook no longer splits or re-merges + * SYSTEM messages.
    • *
* - *

This hook runs at priority 10 — before {@link io.agentscope.harness.agent.hook.WorkspaceContextHook} - * (priority 900): compaction runs on the conversation portion first; workspace files are merged into - * the system message afterwards on the same {@link PreReasoningEvent} chain. + *

This hook runs at priority 10 — before + * {@link io.agentscope.harness.agent.hook.WorkspaceContextHook} (priority 900): compaction + * runs on the conversation first; the workspace context is then appended to the system message + * by {@code WorkspaceContextHook} on the same {@link PreReasoningEvent} chain. * *

{@link RuntimeContext} is bound on each call by {@link io.agentscope.core.ReActAgent}. */ @@ -101,17 +103,9 @@ private Mono handlePreReasoning(PreReasoningEvent event) { return Mono.just(event); } - // Separate system messages (injected by WorkspaceContextHook etc.) from conversation - List inputMessages = event.getInputMessages(); - List systemMsgs = new ArrayList<>(); - List conversationMsgs = new ArrayList<>(); - for (Msg m : inputMessages) { - if (m.getRole() == MsgRole.SYSTEM) { - systemMsgs.add(m); - } else { - conversationMsgs.add(m); - } - } + // inputMessages contains only conversation messages — SYSTEM is managed separately + // via event.getSystemMessage() / event.setSystemMessage() + List conversationMsgs = event.getInputMessages(); String agentId = event.getAgent().getName(); String sessionId = sessionId(); @@ -128,7 +122,10 @@ private Mono handlePreReasoning(PreReasoningEvent event) { } List compacted = optResult.get(); applyToMemory(reActAgent.getMemory(), compacted); - applyToEvent(event, systemMsgs, compacted); + event.setInputMessages(compacted); + log.debug( + "Updated PreReasoningEvent to {} compacted messages", + compacted.size()); return Mono.just(event); }) .onErrorResume( @@ -158,25 +155,6 @@ private static void applyToMemory(Memory memory, List compacted) { } } - /** - * Updates the event's input message list so the LLM sees the compacted view. - * - *

System messages are always placed at the front, followed by the compacted - * conversation (summary + preserved tail). - */ - private static void applyToEvent( - PreReasoningEvent event, List systemMsgs, List compacted) { - List rebuilt = new ArrayList<>(systemMsgs.size() + compacted.size()); - rebuilt.addAll(systemMsgs); - rebuilt.addAll(compacted); - event.setInputMessages(rebuilt); - log.debug( - "Updated PreReasoningEvent: {} system + {} conversation = {} total messages", - systemMsgs.size(), - compacted.size(), - rebuilt.size()); - } - // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java index f8f61e5b0..b11519ed8 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/SubagentsHook.java @@ -18,10 +18,6 @@ import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; import io.agentscope.core.hook.PreReasoningEvent; -import io.agentscope.core.message.ContentBlock; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; import io.agentscope.harness.agent.subagent.DefaultAgentManager; import io.agentscope.harness.agent.subagent.SubagentFactory; import io.agentscope.harness.agent.subagent.task.DefaultTaskRepository; @@ -29,7 +25,6 @@ import io.agentscope.harness.agent.tool.AgentSpawnTool; import io.agentscope.harness.agent.tool.TaskTool; import io.agentscope.harness.agent.workspace.WorkspaceManager; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -48,10 +43,11 @@ * *

    *
  1. Registers the subagent tool and {@link TaskTool} as agent tools - *
  2. Injects rich subagent usage guidance into the leading system message at - * {@link PreReasoningEvent} time. The injection is per-iteration only — it never enters - * the persistent {@code Memory} / {@code Session}, so SYSTEM context cannot accumulate - * across calls. + *
  3. Injects rich subagent usage guidance into the unified system message at + * {@link PreReasoningEvent} time via {@link PreReasoningEvent#appendSystemContent}. + * Because each {@link PreReasoningEvent} starts from a fresh copy of the frozen base + * system message, calling {@code appendSystemContent} on every iteration is safe — + * content never accumulates across iterations. *
*/ public class SubagentsHook implements Hook { @@ -205,41 +201,7 @@ private void injectSubagentPrompt(PreReasoningEvent event) { String section = String.format(SUBAGENT_SECTION_TEMPLATE, spawnName, sendName, listName, agentList); - List msgs = new ArrayList<>(event.getInputMessages()); - int systemIndex = findFirstSystemMessageIndex(msgs); - if (systemIndex >= 0) { - Msg existing = msgs.get(systemIndex); - List mergedContent = new ArrayList<>(existing.getContent()); - mergedContent.add(TextBlock.builder().text(section).build()); - Msg merged = - Msg.builder() - .id(existing.getId()) - .role(MsgRole.SYSTEM) - .name(existing.getName()) - .content(mergedContent) - .metadata(existing.getMetadata()) - .timestamp(existing.getTimestamp()) - .build(); - msgs.set(systemIndex, merged); - } else { - msgs.add( - 0, - Msg.builder() - .role(MsgRole.SYSTEM) - .name("subagent_context") - .content(TextBlock.builder().text(section).build()) - .build()); - } - event.setInputMessages(msgs); - } - - private static int findFirstSystemMessageIndex(List messages) { - for (int i = 0; i < messages.size(); i++) { - if (messages.get(i).getRole() == MsgRole.SYSTEM) { - return i; - } - } - return -1; + event.appendSystemContent(section); } private static Map buildFactories(List entries) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java index 86321bdbd..581efb6d0 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/WorkspaceContextHook.java @@ -18,12 +18,8 @@ import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.hook.Hook; import io.agentscope.core.hook.HookEvent; -import io.agentscope.core.hook.PreReasoningEvent; +import io.agentscope.core.hook.PreCallEvent; import io.agentscope.core.hook.RuntimeContextAware; -import io.agentscope.core.message.ContentBlock; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; import io.agentscope.harness.agent.workspace.WorkspaceManager; import java.nio.file.Path; import java.time.LocalDate; @@ -34,11 +30,15 @@ import reactor.core.publisher.Mono; /** - * A side-by-side variant of {@link WorkspaceContextHook} for A/B testing prompt layout. + * Injects workspace context (session info, AGENTS.md, MEMORY.md, knowledge) into the unified + * system message on {@link PreCallEvent}. * - *

It keeps the same runtime/session/token-budget behavior as the current hook, but renders - * workspace files using XML-style {@code } blocks to compare against markdown - * sectioning. + *

Workspace content is added via {@link PreCallEvent#appendSystemContent}. + * Because this hook fires only on {@link PreCallEvent} (once per {@code call()}), there + * is no risk of accumulation across reasoning iterations. + * + *

Runs at priority 900 — after all other pre-call hooks so that workspace context is + * appended after skill and subagent guidance. */ public class WorkspaceContextHook implements Hook, RuntimeContextAware { @@ -125,8 +125,8 @@ public void setRuntimeContext(RuntimeContext runtimeContext) { @Override public Mono onEvent(T event) { - if (event instanceof PreReasoningEvent preReasoning) { - injectWorkspaceContext(preReasoning); + if (event instanceof PreCallEvent preCallEvent) { + injectWorkspaceContext(preCallEvent); } return Mono.just(event); } @@ -136,7 +136,7 @@ public int priority() { return 900; } - private void injectWorkspaceContext(PreReasoningEvent event) { + private void injectWorkspaceContext(PreCallEvent event) { String agentsContent = workspaceManager.readAgentsMd().strip(); String memoryContent = workspaceManager.readMemoryMd().strip(); String knowledgeContent = workspaceManager.readKnowledgeMd().strip(); @@ -163,32 +163,7 @@ private void injectWorkspaceContext(PreReasoningEvent event) { agentsContent, memoryContent, knowledgeBlock, additionalBlock); String section = buildWorkspaceSection(sessionContext, guidance, loadedContext); - List msgs = new ArrayList<>(event.getInputMessages()); - int systemIndex = findFirstSystemMessageIndex(msgs); - if (systemIndex >= 0) { - Msg existing = msgs.get(systemIndex); - List mergedContent = new ArrayList<>(existing.getContent()); - mergedContent.add(TextBlock.builder().text(section).build()); - Msg merged = - Msg.builder() - .id(existing.getId()) - .role(MsgRole.SYSTEM) - .name(existing.getName()) - .content(mergedContent) - .metadata(existing.getMetadata()) - .timestamp(existing.getTimestamp()) - .build(); - msgs.set(systemIndex, merged); - } else { - msgs.add( - 0, - Msg.builder() - .role(MsgRole.SYSTEM) - .name("workspace_context") - .content(TextBlock.builder().text(section).build()) - .build()); - } - event.setInputMessages(msgs); + event.appendSystemContent(section); } private String buildWorkspaceSection( @@ -229,15 +204,6 @@ private String buildSessionDynamicPart() { return parts.isEmpty() ? "" : String.join("\n", parts); } - private static int findFirstSystemMessageIndex(List messages) { - for (int i = 0; i < messages.size(); i++) { - if (messages.get(i).getRole() == MsgRole.SYSTEM) { - return i; - } - } - return -1; - } - /** * Builds XML-style loaded context blocks for AGENTS/MEMORY/KNOWLEDGE and extra files. */ diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java index 29d2c942e..697f1f2e0 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/MemoryFlushManager.java @@ -210,6 +210,9 @@ private void offloadToSessionTree(List messages, String agentId, String ses workspaceManager.getWorkspace(), workspaceManager.getFilesystem()); tree.load(); + // Sync from remote before appending so that entries written by a previous replica + // (cross-machine handoff) are included in the merged file pushed to remote. + tree.syncFromRemote(); String lastId = null; for (Msg msg : messages) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java index 84580428d..b0e5676f9 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/memory/session/SessionTree.java @@ -29,8 +29,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +52,13 @@ * agents/{agentId}/sessions/{sessionId}.log.jsonl — full history (append-only, never compacted) * * + *

Persistence model

+ * The local file is the working copy; the remote {@link AbstractFilesystem} (when configured) is + * the cross-replica mirror. On every {@link #load()}, remote content is fetched and union-merged + * with the local file so that entries written on another machine are visible to the current one. + * On every {@link #flush()}, pending entries are appended to the local files synchronously and + * then mirrored to the remote filesystem asynchronously (fire-and-forget, best-effort). + * *

Deferred persistence

* Entries are buffered in memory and only flushed to disk on the first call to {@link #flush()} * (typically after the first assistant message). This avoids partial session files from @@ -57,7 +69,18 @@ public class SessionTree { private static final RuntimeContext DEFAULT_FS_RUNTIME = RuntimeContext.empty(); private static final Logger log = LoggerFactory.getLogger(SessionTree.class); - private static final int SESSION_FORMAT_VERSION = 1; + + /** + * Daemon executor used for fire-and-forget remote mirrors so that flush() never blocks callers + * on remote I/O. A single thread is intentional: serialises uploads for the same session. + */ + private static final ExecutorService MIRROR_EXECUTOR = + Executors.newSingleThreadExecutor( + r -> { + Thread t = new Thread(r, "session-tree-mirror"); + t.setDaemon(true); + return t; + }); private final Path contextFile; private final Path logFile; @@ -73,10 +96,14 @@ public class SessionTree { private boolean loaded = false; private boolean flushed = false; - public SessionTree(Path contextFile) { - this(contextFile, null, null); - } - + /** + * Creates a SessionTree backed by the given filesystem for remote mirroring. + * + * @param contextFile path to the {@code .jsonl} context file (LLM-facing, compacted) + * @param workspaceRoot root of the agent workspace; used to derive workspace-relative paths + * @param filesystem {@link AbstractFilesystem} used for remote read/write; may be + * {@code null} to disable remote mirroring (local-only mode) + */ public SessionTree(Path contextFile, Path workspaceRoot, AbstractFilesystem filesystem) { this.contextFile = contextFile; String name = contextFile.getFileName().toString(); @@ -87,8 +114,14 @@ public SessionTree(Path contextFile, Path workspaceRoot, AbstractFilesystem file } /** - * Loads existing entries from the context JSONL file (if it exists). - * Safe to call multiple times; only loads once. + * Loads existing entries from the local context file into the in-memory tree. + * + *

This is a local-only, zero-network operation. If the local file is absent, the + * tree starts empty. To additionally pull and union-merge entries from the remote filesystem + * (e.g., before a write that may follow a cross-machine handoff), call + * {@link #syncFromRemote()} after this method. + * + *

Safe to call multiple times; only loads once. */ public void load() { if (loaded) { @@ -96,35 +129,93 @@ public void load() { } loaded = true; - restoreFromMirror(contextFile); + // Cold-start restore: if local file is absent but remote has a copy, pull it down once. if (!Files.isRegularFile(contextFile)) { + restoreFromMirror(contextFile); + } + + List localEntries = readLocalEntries(contextFile); + for (SessionEntry entry : localEntries) { + entriesById.put(entry.getId(), entry); + appendOrder.add(entry); + + if (entry instanceof SessionEntry.CompactionEntry ce) { + lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); + lastSummaryEntryId = ce.getSummaryEntryId(); + } + } + } + + /** + * Pulls the remote context file and union-merges any entries not yet present locally. + * + *

Remote is treated as the authoritative base: remote entries come first, followed by any + * local-only entries (written but not yet mirrored). If the remote has entries the local file + * does not, the local file is overwritten with the merged content and the new entries are + * appended to the local log file. + * + *

This is a network operation — call it only when cross-machine consistency is + * required (typically in write paths such as + * {@link io.agentscope.harness.agent.memory.MemoryFlushManager}). Read-only tools should use + * {@link #load()} alone to keep queries fast and local. + * + *

No-op if no filesystem is configured or the remote read fails (failures are logged as + * warnings). + * + *

{@link #load()} must be called before this method. + */ + public void syncFromRemote() { + if (filesystem == null || workspaceRoot == null) { return; } - try (BufferedReader reader = Files.newBufferedReader(contextFile, StandardCharsets.UTF_8)) { - String line; - while ((line = reader.readLine()) != null) { - line = line.strip(); - if (line.isEmpty()) { - continue; - } - try { - SessionEntry entry = - JsonUtils.getJsonCodec().fromJson(line, SessionEntry.class); - entriesById.put(entry.getId(), entry); - appendOrder.add(entry); + List remoteEntries = pullRemoteEntries(contextFile); + if (remoteEntries.isEmpty()) { + return; + } - if (entry instanceof SessionEntry.CompactionEntry ce) { - lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); - lastSummaryEntryId = ce.getSummaryEntryId(); - } - } catch (Exception e) { - log.warn("Skipping malformed session entry: {}", e.getMessage()); - } + Set localIds = + appendOrder.stream().map(SessionEntry::getId).collect(Collectors.toSet()); + + List remoteNewEntries = + remoteEntries.stream().filter(re -> !localIds.contains(re.getId())).toList(); + if (remoteNewEntries.isEmpty()) { + return; + } + + // Rebuild merged list: remote base + local-only extras at the end. + Set remoteIds = + remoteEntries.stream() + .map(SessionEntry::getId) + .collect(Collectors.toCollection(LinkedHashSet::new)); + List merged = new ArrayList<>(remoteEntries); + for (SessionEntry e : appendOrder) { + if (!remoteIds.contains(e.getId())) { + merged.add(e); } - } catch (IOException e) { - log.warn("Failed to load session file {}: {}", contextFile, e.getMessage()); } + + overwriteFile(contextFile, merged); + appendToFile(logFile, remoteNewEntries); + + // Update in-memory state with the newly discovered remote entries. + for (SessionEntry entry : remoteNewEntries) { + entriesById.put(entry.getId(), entry); + } + // Re-build appendOrder to match the merged order (remote base first). + appendOrder.clear(); + appendOrder.addAll(merged); + for (SessionEntry entry : remoteNewEntries) { + if (entry instanceof SessionEntry.CompactionEntry ce) { + lastCompactionFirstKeptId = ce.getFirstKeptEntryId(); + lastSummaryEntryId = ce.getSummaryEntryId(); + } + } + + log.info( + "syncFromRemote: merged {} new remote entries into local session file {}", + remoteNewEntries.size(), + contextFile.getFileName()); } /** @@ -147,8 +238,11 @@ public SessionEntry append(SessionEntry entry) { } /** - * Flushes all pending entries to both the context file and the log file. - * Creates parent directories as needed. Marks the session as flushed. + * Flushes all pending entries to both the local context file and the local log file + * synchronously, then schedules an asynchronous best-effort mirror to the remote filesystem. + * + *

The remote mirror is fire-and-forget: failures are logged as warnings and do not affect + * the return of this method. The local write is always the primary guarantee. */ public void flush() { if (pendingWrites.isEmpty()) { @@ -161,8 +255,7 @@ public void flush() { appendToFile(contextFile, toWrite); appendToFile(logFile, toWrite); - mirrorToFilesystem(contextFile); - mirrorToFilesystem(logFile); + scheduleMirror(); } /** @@ -291,6 +384,106 @@ public int syncFromLog() { return syncCount; } + // ------------------------------------------------------------------------- + // Private helpers + // ------------------------------------------------------------------------- + + /** + * Schedules an asynchronous, best-effort mirror of both session files to the remote + * filesystem. Uses a daemon single-thread executor to serialise uploads and avoid + * blocking the caller on remote I/O. + */ + private void scheduleMirror() { + if (filesystem == null || workspaceRoot == null) { + return; + } + MIRROR_EXECUTOR.execute( + () -> { + mirrorToFilesystem(contextFile); + mirrorToFilesystem(logFile); + }); + } + + /** + * Fetches the remote copy of {@code file} and parses it as JSONL session entries. + * Returns an empty list if no filesystem is configured or the remote read fails. + */ + private List pullRemoteEntries(Path file) { + if (filesystem == null || workspaceRoot == null) { + return List.of(); + } + String relativePath = toWorkspaceRelative(file); + if (relativePath == null || relativePath.isBlank()) { + return List.of(); + } + ReadResult read = filesystem.read(DEFAULT_FS_RUNTIME, relativePath, 0, 0); + if (!read.isSuccess() || read.fileData() == null || read.fileData().content() == null) { + return List.of(); + } + return parseJsonlEntries(read.fileData().content()); + } + + /** + * Reads and parses the local copy of {@code file} as JSONL session entries. + * Returns an empty list if the file does not exist or cannot be read. + */ + private List readLocalEntries(Path file) { + if (!Files.isRegularFile(file)) { + return List.of(); + } + try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append('\n'); + } + return parseJsonlEntries(sb.toString()); + } catch (IOException e) { + log.warn("Failed to read local session file {}: {}", file, e.getMessage()); + return List.of(); + } + } + + /** Parses a JSONL string into a list of {@link SessionEntry} objects, skipping bad lines. */ + private List parseJsonlEntries(String content) { + List result = new ArrayList<>(); + for (String line : content.split("\n", -1)) { + line = line.strip(); + if (line.isEmpty()) { + continue; + } + try { + result.add(JsonUtils.getJsonCodec().fromJson(line, SessionEntry.class)); + } catch (Exception e) { + log.warn("Skipping malformed session entry: {}", e.getMessage()); + } + } + return result; + } + + /** Overwrites {@code file} with the serialised form of {@code entries} (TRUNCATE + WRITE). */ + private void overwriteFile(Path file, List entries) { + try { + if (file.getParent() != null) { + Files.createDirectories(file.getParent()); + } + try (BufferedWriter writer = + Files.newBufferedWriter( + file, + StandardCharsets.UTF_8, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE)) { + for (SessionEntry entry : entries) { + writer.write(JsonUtils.getJsonCodec().toJson(entry)); + writer.newLine(); + } + } + } catch (IOException e) { + log.warn("Failed to overwrite session file {}: {}", file, e.getMessage()); + } + } + private void appendToFile(Path file, List entries) { try { if (file.getParent() != null) { @@ -313,6 +506,30 @@ private void appendToFile(Path file, List entries) { } } + /** + * Uploads {@code file} to the remote filesystem (full-file upload). Only called from the + * mirror executor thread; failures are logged as warnings. + */ + private void mirrorToFilesystem(Path file) { + if (filesystem == null || workspaceRoot == null || !Files.isRegularFile(file)) { + return; + } + String relativePath = toWorkspaceRelative(file); + if (relativePath == null || relativePath.isBlank()) { + return; + } + try { + byte[] bytes = Files.readAllBytes(file); + filesystem.uploadFiles(DEFAULT_FS_RUNTIME, List.of(Map.entry(relativePath, bytes))); + } catch (IOException e) { + log.warn("Failed to mirror session file {} to filesystem: {}", file, e.getMessage()); + } + } + + /** + * Restores {@code file} from the remote filesystem mirror when the local file is absent. + * Used by {@link #syncFromLog()} to ensure the log file is available locally before reading. + */ private void restoreFromMirror(Path file) { if (filesystem == null || workspaceRoot == null || Files.isRegularFile(file)) { return; @@ -344,22 +561,6 @@ private void restoreFromMirror(Path file) { } } - private void mirrorToFilesystem(Path file) { - if (filesystem == null || workspaceRoot == null || !Files.isRegularFile(file)) { - return; - } - String relativePath = toWorkspaceRelative(file); - if (relativePath == null || relativePath.isBlank()) { - return; - } - try { - byte[] bytes = Files.readAllBytes(file); - filesystem.uploadFiles(DEFAULT_FS_RUNTIME, List.of(Map.entry(relativePath, bytes))); - } catch (IOException e) { - log.warn("Failed to mirror session file {} to filesystem: {}", file, e.getMessage()); - } - } - private String toWorkspaceRelative(Path file) { Path root = workspaceRoot.toAbsolutePath().normalize(); Path candidate = file.toAbsolutePath().normalize(); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java index bce5aca30..7e5b8eafb 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java @@ -32,6 +32,11 @@ /** * Tool for searching past session transcripts and viewing session history. + * + *

Operates exclusively on the local session cache. Remote synchronisation is handled by + * {@link io.agentscope.harness.agent.memory.session.SessionTree#load()} in write paths + * (e.g. {@link io.agentscope.harness.agent.memory.MemoryFlushManager}), keeping this tool + * lightweight and fast for in-process search. */ public class SessionSearchTool { @@ -71,15 +76,12 @@ public String sessionSearch( List results = new ArrayList<>(); - List sessionDirs = listSessionDirs(effectiveAgentId); - for (Path sessionDir : sessionDirs) { - List sessionFiles = listJsonlFiles(sessionDir); - for (Path file : sessionFiles) { - if (results.size() >= limit) { - break; - } - searchInSessionFile(file, lowerQuery, results, limit); + List sessionFiles = listLogFiles(effectiveAgentId); + for (Path file : sessionFiles) { + if (results.size() >= limit) { + break; } + searchInSessionFile(file, lowerQuery, results, limit); } if (results.isEmpty()) { @@ -104,11 +106,7 @@ public String sessionList( return "Error: agentId is required"; } - Path sessionDir = workspaceManager.getSessionDir(agentId); - if (!Files.isDirectory(sessionDir)) { - return "No sessions found for agent: " + agentId; - } - + // Prefer the structured session-store index (already two-layer: remote then local). String storeContent = workspaceManager.readManagedWorkspaceFileUtf8( WorkspaceConstants.AGENTS_DIR @@ -118,12 +116,25 @@ public String sessionList( + WorkspaceConstants.SESSIONS_DIR + "/" + WorkspaceConstants.SESSIONS_STORE); - if (!storeContent.isBlank()) { return storeContent; } - List sessionFiles = listJsonlFiles(sessionDir); + // List sessions from local cache only — remote sync is handled at write time. + Path sessionDir = workspaceManager.getSessionDir(agentId); + if (!Files.isDirectory(sessionDir)) { + return "No sessions found for agent: " + agentId; + } + + List sessionFiles = new ArrayList<>(); + try (Stream walk = Files.list(sessionDir)) { + walk.filter(Files::isRegularFile) + .filter(p -> p.getFileName().toString().endsWith(WorkspaceConstants.SESSION_CONTEXT_EXT)) + .forEach(sessionFiles::add); + } catch (IOException e) { + log.debug("Could not list local session dir for agent {}: {}", agentId, e.getMessage()); + } + if (sessionFiles.isEmpty()) { return "No sessions found for agent: " + agentId; } @@ -132,10 +143,7 @@ public String sessionList( sb.append("Sessions for agent ").append(agentId).append(":\n"); for (Path file : sessionFiles) { String name = file.getFileName().toString(); - String sessionId = - name.replace(WorkspaceConstants.SESSION_CONTEXT_EXT, "") - .replace(WorkspaceConstants.SESSION_LOG_EXT, "") - .replace(".json", ""); + String sessionId = name.replace(WorkspaceConstants.SESSION_CONTEXT_EXT, ""); sb.append(" - ").append(sessionId).append("\n"); } return sb.toString(); @@ -171,7 +179,7 @@ public String sessionHistory( return "Session not found: " + sessionId; } - SessionTree tree = new SessionTree(contextFile); + SessionTree tree = new SessionTree(contextFile, workspaceManager.getWorkspace(), null); tree.load(); List messages = tree.getMessageEntries(); @@ -193,61 +201,67 @@ public String sessionHistory( return sb.toString(); } - private List listSessionDirs(String agentId) { - List dirs = new ArrayList<>(); + // ------------------------------------------------------------------------- + // Private helpers + // ------------------------------------------------------------------------- + + /** + * Collects all {@code .log.jsonl} files under the sessions directory for the given agent + * (or all agents when {@code agentId} is {@code null}). + * Only scans the local disk; remote-only sessions are handled via sessionList / sessionHistory. + */ + private List listLogFiles(String agentId) { + List files = new ArrayList<>(); Path agentsDir = workspaceManager.getWorkspace().resolve(WorkspaceConstants.AGENTS_DIR); if (!Files.isDirectory(agentsDir)) { - return dirs; + return files; } if (agentId != null) { - Path dir = agentsDir.resolve(agentId).resolve(WorkspaceConstants.SESSIONS_DIR); - if (Files.isDirectory(dir)) { - dirs.add(dir); - } - return dirs; + Path sessionDir = + agentsDir.resolve(agentId).resolve(WorkspaceConstants.SESSIONS_DIR); + collectLogFiles(sessionDir, files); + return files; } try (Stream walk = Files.list(agentsDir)) { walk.filter(Files::isDirectory) .forEach( - agentDir -> { - Path sessDir = agentDir.resolve(WorkspaceConstants.SESSIONS_DIR); - if (Files.isDirectory(sessDir)) { - dirs.add(sessDir); - } - }); + agentDir -> + collectLogFiles( + agentDir.resolve(WorkspaceConstants.SESSIONS_DIR), + files)); } catch (IOException e) { // ignore } - return dirs; + return files; } - private List listJsonlFiles(Path dir) { - List files = new ArrayList<>(); - if (!Files.isDirectory(dir)) { - return files; + private void collectLogFiles(Path sessionDir, List collector) { + if (!Files.isDirectory(sessionDir)) { + return; } - try (Stream walk = Files.list(dir)) { - walk.filter(p -> p.toString().endsWith(".log.jsonl")) + try (Stream walk = Files.list(sessionDir)) { + walk.filter(p -> p.toString().endsWith(WorkspaceConstants.SESSION_LOG_EXT)) .filter(Files::isRegularFile) - .forEach(files::add); + .forEach(collector::add); } catch (IOException e) { // ignore } - return files; } private void searchInSessionFile( - Path file, String lowerQuery, List results, int limit) { + Path logFile, String lowerQuery, List results, int limit) { try { - SessionTree tree = - new SessionTree( - file.resolveSibling( - file.getFileName().toString().replace(".log.jsonl", ".jsonl"))); + Path contextFile = + logFile.resolveSibling( + logFile.getFileName() + .toString() + .replace(WorkspaceConstants.SESSION_LOG_EXT, WorkspaceConstants.SESSION_CONTEXT_EXT)); + SessionTree tree = new SessionTree(contextFile, workspaceManager.getWorkspace(), null); tree.load(); - String relPath = workspaceManager.getWorkspace().relativize(file).toString(); + String relPath = workspaceManager.getWorkspace().relativize(logFile).toString(); for (SessionEntry.MessageEntry msg : tree.getMessageEntries()) { if (results.size() >= limit) { break; diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java index afdf85474..bf26c5c31 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java @@ -66,7 +66,8 @@ void sandboxDistributed_requiresSandboxFilesystemMode() { @Test void sandboxMode_withLocalSession_failsFastByDefault() { - // Mode 2 (SandboxFilesystemSpec) now validates automatically — no sandboxDistributed() needed. + // Mode 2 (SandboxFilesystemSpec) now validates automatically — no sandboxDistributed() + // needed. IllegalStateException ex = assertThrows( IllegalStateException.class, @@ -80,7 +81,8 @@ void sandboxMode_withLocalSession_failsFastByDefault() { assertEquals( true, ex.getMessage().contains("distributed Session backend"), - "sandbox mode should fail-fast when effective session remains local WorkspaceSession"); + "sandbox mode should fail-fast when effective session remains local" + + " WorkspaceSession"); } @Test diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentModelStringTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentModelStringTest.java new file mode 100644 index 000000000..be7836e9e --- /dev/null +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentModelStringTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.agent; + +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.model.ChatResponse; +import io.agentscope.core.model.Model; +import io.agentscope.core.model.ModelRegistry; +import io.agentscope.harness.agent.filesystem.LocalFilesystem; +import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; +import io.agentscope.harness.agent.subagent.SubagentSpec; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import reactor.core.publisher.Flux; + +class HarnessAgentModelStringTest { + + @TempDir Path workspace; + + @BeforeEach + void setUp() throws Exception { + ModelRegistry.reset(); + Files.createDirectories(workspace); + } + + @AfterEach + void tearDown() { + ModelRegistry.reset(); + } + + @Test + void builder_modelString_resolvesViaRegistry() { + Model registered = stubModel("ok"); + ModelRegistry.register("reg-main", registered); + + HarnessAgent agent = + HarnessAgent.builder() + .name("t") + .model("reg-main") + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .build(); + + assertSame(registered, agent.getDelegate().getModel()); + } + + @Test + void builder_modelString_unknownId_throws() { + assertThrows( + IllegalArgumentException.class, + () -> + HarnessAgent.builder() + .name("t") + .model("no-such-registry-model") + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .build()); + } + + @Test + void subagentSpec_model_resolvedByDefaultResolver() { + Model main = stubModel("main-reply"); + Model sub = stubModel("sub-reply"); + ModelRegistry.register("reg-sub", sub); + + SubagentSpec spec = new SubagentSpec("sa", "subagent"); + spec.setSysPrompt("You are a test subagent."); + spec.setModel("reg-sub"); + + List entries = + HarnessAgent.builder() + .name("main") + .model(main) + .workspace(workspace) + .abstractFilesystem(new LocalFilesystem(workspace)) + .subagent(spec) + .buildSubagentEntries(workspace); + + SubagentEntry entry = + entries.stream().filter(e -> "sa".equals(e.name())).findFirst().orElseThrow(); + + HarnessAgent subAgent = (HarnessAgent) entry.factory().create(); + assertSame(sub, subAgent.getDelegate().getModel()); + } + + private static Model stubModel(String assistantText) { + Model model = mock(Model.class); + when(model.getModelName()).thenReturn("stub-model"); + ChatResponse chunk = + new ChatResponse( + "stub-id", + List.of(TextBlock.builder().text(assistantText).build()), + null, + Map.of(), + "stop"); + when(model.stream(anyList(), any(), any())).thenReturn(Flux.just(chunk)); + return model; + } +} diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java index 35118e161..727990e50 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java @@ -24,6 +24,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -31,27 +32,174 @@ class SessionTreeMirrorTest { @TempDir Path workspace; + private AbstractFilesystem buildFs(InMemoryStore store) { + return new RemoteFilesystemSpec(store) + .toFilesystem(workspace, "agent-a", List::of, () -> "user-1"); + } + + // ----------------------------------------------------------------------- + // load(): local-only, cold-start restore when local file is absent + // ----------------------------------------------------------------------- + @Test - void mirrorsToFilesystemAndCanRestoreWhenLocalFilesMissing() throws Exception { + void load_restoresFromRemote_whenLocalFilesMissing() throws Exception { InMemoryStore store = new InMemoryStore(); - AbstractFilesystem fs = - new RemoteFilesystemSpec(store) - .toFilesystem(workspace, "agent-a", List::of, () -> "user-1"); - + AbstractFilesystem fs = buildFs(store); Path context = workspace.resolve("agents/agent-a/sessions/s1.jsonl"); + + // Machine A writes and flushes (mirrors to remote) SessionTree writer = new SessionTree(context, workspace, fs); writer.append(new SessionEntry.MessageEntry(null, null, null, "USER", "hello", null)); writer.flush(); + awaitMirror(); - assertTrue(Files.isRegularFile(context)); - assertTrue(Files.isRegularFile(writer.getLogFile())); - + // Delete local files — simulate cold-start on a new machine Files.deleteIfExists(context); Files.deleteIfExists(writer.getLogFile()); + // Machine B: load() alone should restore from remote (cold-start path) SessionTree reader = new SessionTree(context, workspace, fs); reader.load(); + + assertEquals(1, reader.size(), "load() should restore from remote when local is absent"); + assertTrue(Files.isRegularFile(context), "local file should be recreated"); + } + + @Test + void load_readsLocalOnly_whenLocalFileExists() throws Exception { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = buildFs(store); + Path context = workspace.resolve("agents/agent-a/sessions/s1b.jsonl"); + + // Write two entries; mirror first entry to remote, keep second local-only + SessionTree t1 = new SessionTree(context, workspace, fs); + t1.append(new SessionEntry.MessageEntry(null, null, null, "USER", "entry-1", null)); + t1.flush(); + awaitMirror(); // remote has entry-1 + + SessionTree t2 = new SessionTree(context, workspace, fs); + t2.load(); // local has entry-1 + t2.append(new SessionEntry.MessageEntry(null, null, null, "ASSISTANT", "entry-2", null)); + t2.flush(); // local has entry-1+2; async mirror not awaited + + // A new SessionTree.load() on the same local file should see both entries immediately + // (local has them) WITHOUT touching remote. + SessionTree t3 = new SessionTree(context, workspace, fs); + t3.load(); + assertEquals(2, t3.size(), "load() should read both entries from local cache"); + } + + // ----------------------------------------------------------------------- + // syncFromRemote(): cross-machine handoff + // ----------------------------------------------------------------------- + + @Test + void syncFromRemote_mergesRemoteAheadEntries_intoStaleLocal() throws Exception { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = buildFs(store); + Path context = workspace.resolve("agents/agent-a/sessions/s2.jsonl"); + + // Round 1 — Machine A: write, flush, mirror to remote + SessionTree machineA = new SessionTree(context, workspace, fs); + machineA.append(new SessionEntry.MessageEntry(null, null, null, "USER", "round-1", null)); + machineA.flush(); + awaitMirror(); // remote: round-1 + + // Simulate machine B having a stale local: only round-1 on disk. + // Machine A then writes round-2 and mirrors. + SessionTree machineA2 = new SessionTree(context, workspace, fs); + machineA2.load(); + machineA2.append( + new SessionEntry.MessageEntry(null, null, null, "ASSISTANT", "round-2", null)); + machineA2.flush(); + awaitMirror(); // remote: round-1 + round-2 + + // Truncate local to only round-1 (simulate stale machine B) + List lines = Files.readAllLines(context); + Files.writeString(context, lines.get(0) + "\n"); + + // Machine B: load() sees local (stale, round-1 only) + SessionTree machineB = new SessionTree(context, workspace, fs); + machineB.load(); + assertEquals(1, machineB.size(), "load() should only see local (stale) content"); + + // syncFromRemote() picks up round-2 from remote + machineB.syncFromRemote(); + assertEquals(2, machineB.size(), "syncFromRemote() should union-merge round-2 from remote"); + } + + @Test + void syncFromRemote_preservesLocalOnlyEntries_notYetPushed() throws Exception { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = buildFs(store); + Path context = workspace.resolve("agents/agent-a/sessions/s3.jsonl"); + + // Write entry-1 and mirror + SessionTree t1 = new SessionTree(context, workspace, fs); + t1.append(new SessionEntry.MessageEntry(null, null, null, "USER", "entry-1", null)); + t1.flush(); + awaitMirror(); // remote: entry-1 + + // Write entry-2 locally but don't wait for mirror (still in-flight) + SessionTree t2 = new SessionTree(context, workspace, fs); + t2.load(); + t2.append( + new SessionEntry.MessageEntry(null, null, null, "ASSISTANT", "entry-2", null)); + t2.flush(); // local: entry-1+2; remote may still only have entry-1 + + // Load a fresh tree — local has entry-1+2 + SessionTree t3 = new SessionTree(context, workspace, fs); + t3.load(); + assertEquals(2, t3.size()); + + // syncFromRemote() — remote has entry-1 only; local-only entry-2 must survive + t3.syncFromRemote(); + assertEquals(2, t3.size(), "local-only entry-2 must survive union-merge"); + assertTrue( + t3.getMessageEntries().stream().anyMatch(m -> "entry-2".equals(m.getContent())), + "entry-2 must be present after sync"); + } + + @Test + void syncFromRemote_isNoOp_whenFilesystemIsNull() throws Exception { + Path context = workspace.resolve("agents/agent-a/sessions/s4.jsonl"); + SessionTree tree = new SessionTree(context, workspace, null); + tree.append(new SessionEntry.MessageEntry(null, null, null, "USER", "local", null)); + tree.flush(); + + SessionTree reader = new SessionTree(context, workspace, null); + reader.load(); + reader.syncFromRemote(); // must not throw assertEquals(1, reader.size()); - assertTrue(Files.isRegularFile(context)); + } + + // ----------------------------------------------------------------------- + // flush(): local write is synchronous, remote mirror is async + // ----------------------------------------------------------------------- + + @Test + void flush_localWriteCompletesImmediately() throws Exception { + InMemoryStore store = new InMemoryStore(); + AbstractFilesystem fs = buildFs(store); + Path context = workspace.resolve("agents/agent-a/sessions/s5.jsonl"); + + SessionTree tree = new SessionTree(context, workspace, fs); + tree.append(new SessionEntry.MessageEntry(null, null, null, "USER", "hi", null)); + tree.flush(); + + assertTrue( + Files.isRegularFile(context), + "local context file must exist immediately after flush()"); + assertTrue( + Files.isRegularFile(tree.getLogFile()), + "local log file must exist immediately after flush()"); + } + + // ----------------------------------------------------------------------- + // Helper + // ----------------------------------------------------------------------- + + private static void awaitMirror() throws InterruptedException { + TimeUnit.MILLISECONDS.sleep(300); } } From 9f5f09de7cec778467d0c0324c2796f02ec86266 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 17:38:08 +0800 Subject: [PATCH 18/28] Add ModelRegistry documentation and usage examples --- docs/en/task/model.md | 81 ++++++++++++++++++++++++++++++++++++++++++- docs/zh/task/model.md | 80 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/docs/en/task/model.md b/docs/en/task/model.md index 0a5c71c04..0e0bf9c07 100644 --- a/docs/en/task/model.md +++ b/docs/en/task/model.md @@ -1,4 +1,3 @@ -model.md # Model This guide introduces the LLM models supported by AgentScope Java and how to configure them. @@ -27,6 +26,86 @@ This guide introduces the LLM models supported by AgentScope Java and how to con | Gemini | [Google AI Studio](https://aistudio.google.com/apikey) | `GEMINI_API_KEY` | | DeepSeek | [DeepSeek Platform](https://platform.deepseek.com/api_keys) | - | +## ModelRegistry + +[`ModelRegistry`](https://github.com/agentscope-ai/agentscope-java/blob/main/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java) (`io.agentscope.core.model.ModelRegistry`) resolves a `Model` from a **string id**, so you do not have to call each vendor’s `*ChatModel.builder()` for simple setups. With Harness, use `HarnessAgent.builder().model(String)`; anywhere else that needs a `Model`, call `ModelRegistry.resolve(...)` and pass the result into `ReActAgent` or other builders. + +### API summary + +| Method | Description | +|--------|-------------| +| `register(String name, Model model)` | Registers a **named** model; `resolve(name)` returns that instance. | +| `registerFactory(String regex, ModelFactory factory)` | Registers a custom factory for ids matching the regex; **later** registrations take precedence over earlier user factories and over built-in rules. | +| `resolve(String modelId)` | Returns a `Model`; throws `IllegalArgumentException` if the id cannot be resolved or creation fails. | +| `canResolve(String modelId)` | Returns whether the id can be resolved (does not create a model). | +| `reset()` | Clears named registrations, user factories, and the resolve cache; built-in rules stay. Intended for tests or in-process reset. | + +`ModelFactory` is a functional interface: `Model create(String modelId)` with the full id string. + +### Built-in id formats and environment variables + +With the right environment variables set, you can use these id forms (with `resolve` or `HarnessAgent.Builder.model(String)`, for example): + +| Example id | Environment variable | Notes | +|------------|----------------------|-------| +| `openai:gpt-4o-mini` | `OPENAI_API_KEY` | OpenAI-compatible HTTP model | +| `dashscope:qwen-max` | `DASHSCOPE_API_KEY` | Alibaba DashScope / Bailian | +| Any id starting with `qwen-`, e.g. `qwen-max` | `DASHSCOPE_API_KEY` | Uses the whole string as the DashScope `modelName` | +| `anthropic:claude-sonnet-4-5-20250929` | `ANTHROPIC_API_KEY` (optional; SDK may read from the environment) | Anthropic Claude | +| `gemini:gemini-2.5-flash` | `GEMINI_API_KEY` | Google Gemini API | +| `ollama:llama3` | `OLLAMA_BASE_URL` (optional, default `http://localhost:11434`) | Local Ollama | + +Within one process, repeated `resolve` of the **same** factory-based id returns a **cached** `Model` instance. **Named** registrations are not cached that way. + +### Example: named registration (reuse a tuned model) + +Build once with full control, then register under a name: + +```java +import io.agentscope.core.model.GenerateOptions; +import io.agentscope.core.model.ModelRegistry; +import io.agentscope.core.model.OpenAIChatModel; +import io.agentscope.harness.agent.HarnessAgent; + +Model tuned = OpenAIChatModel.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .modelName("gpt-4o") + .generateOptions(GenerateOptions.builder().temperature(0.2).build()) + .build(); +ModelRegistry.register("my-gpt4o", tuned); + +HarnessAgent agent = HarnessAgent.builder() + .name("demo") + .model("my-gpt4o") + .workspace(workspace) + .build(); +``` + +### Example: built-in prefix (default connection settings) + +```java +import io.agentscope.harness.agent.HarnessAgent; + +HarnessAgent agent = HarnessAgent.builder() + .name("demo") + .model("dashscope:qwen-max") + .workspace(workspace) + .build(); +``` + +### Example: custom factory + +```java +import io.agentscope.core.model.Model; +import io.agentscope.core.model.ModelRegistry; + +ModelRegistry.registerFactory( + "my-llm:.+", + id -> myModelFactory(id.substring("my-llm:".length()))); + +Model m = ModelRegistry.resolve("my-llm:prod"); +``` + ## DashScope Alibaba Cloud LLM platform, providing Qwen series models. diff --git a/docs/zh/task/model.md b/docs/zh/task/model.md index 6c5195653..6bcda6c27 100644 --- a/docs/zh/task/model.md +++ b/docs/zh/task/model.md @@ -26,6 +26,86 @@ | Gemini | [Google AI Studio](https://aistudio.google.com/apikey) | `GEMINI_API_KEY` | | DeepSeek | [DeepSeek 开放平台](https://platform.deepseek.com/api_keys) | - | +## ModelRegistry + +[`ModelRegistry`](https://github.com/agentscope-ai/agentscope-java/blob/main/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java)(`io.agentscope.core.model.ModelRegistry`)用**字符串 id**得到 `Model` 实例,适合不想手写各厂商 `*ChatModel.builder()` 的场景。例如 Harness 场景下可使用 `HarnessAgent.builder().model(String)`;任意需要 `Model` 的地方可先调用 `ModelRegistry.resolve(...)` 再传入 `ReActAgent` 等构建器。 + +### API 一览 + +| 方法 | 说明 | +|------|------| +| `register(String name, Model model)` | 注册**具名**模型;之后对同名 id 调用 `resolve` 直接返回该实例。 | +| `registerFactory(String regex, ModelFactory factory)` | 为匹配正则的 id 注册自定义工厂;**后注册的工厂优先**于更早注册的用户工厂,且优先于内置规则。 | +| `resolve(String modelId)` | 解析并返回 `Model`;无法解析或创建失败时抛出 `IllegalArgumentException`。 | +| `canResolve(String modelId)` | 仅判断是否可解析(不创建实例)。 | +| `reset()` | 清空具名注册、用户工厂与解析缓存;内置规则保留。一般仅在测试或进程内重置时使用。 | + +`ModelFactory` 为函数式接口:`Model create(String modelId)`,参数为完整模型 id 字符串。 + +### 内置 id 格式与环境变量 + +在已配置对应环境变量的前提下,可使用下列 id 形式(适用于 `resolve` 以及 `HarnessAgent.Builder.model(String)` 等): + +| id 示例 | 所需环境变量 | 说明 | +|---------|--------------|------| +| `openai:gpt-4o-mini` | `OPENAI_API_KEY` | OpenAI 兼容 HTTP 模型 | +| `dashscope:qwen-max` | `DASHSCOPE_API_KEY` | 阿里云 DashScope / 百炼 | +| `qwen-max` 等以 `qwen-` 开头的 id | `DASHSCOPE_API_KEY` | 将整个字符串作为 DashScope 的 `modelName` | +| `anthropic:claude-sonnet-4-5-20250929` | `ANTHROPIC_API_KEY`(可选;未设置时可依赖 SDK 从环境读取) | Anthropic Claude | +| `gemini:gemini-2.5-flash` | `GEMINI_API_KEY` | Google Gemini API | +| `ollama:llama3` | `OLLAMA_BASE_URL`(可选,默认 `http://localhost:11434`) | 本地 Ollama | + +同一进程内,对**相同**工厂解析 id 多次时,返回的 `Model` 实例会被缓存复用;**具名**注册不走该缓存。 + +### 示例:具名注册(自定义配置后复用) + +需要先精细配置(温度、超时等)时,用 Builder 构建一次,再注册成名字: + +```java +import io.agentscope.core.model.GenerateOptions; +import io.agentscope.core.model.ModelRegistry; +import io.agentscope.core.model.OpenAIChatModel; +import io.agentscope.harness.agent.HarnessAgent; + +Model tuned = OpenAIChatModel.builder() + .apiKey(System.getenv("OPENAI_API_KEY")) + .modelName("gpt-4o") + .generateOptions(GenerateOptions.builder().temperature(0.2).build()) + .build(); +ModelRegistry.register("my-gpt4o", tuned); + +HarnessAgent agent = HarnessAgent.builder() + .name("demo") + .model("my-gpt4o") + .workspace(workspace) + .build(); +``` + +### 示例:内置前缀(默认连接参数) + +```java +import io.agentscope.harness.agent.HarnessAgent; + +HarnessAgent agent = HarnessAgent.builder() + .name("demo") + .model("dashscope:qwen-max") + .workspace(workspace) + .build(); +``` + +### 示例:自定义工厂 + +```java +import io.agentscope.core.model.Model; +import io.agentscope.core.model.ModelRegistry; + +ModelRegistry.registerFactory( + "my-llm:.+", + id -> myModelFactory(id.substring("my-llm:".length()))); + +Model m = ModelRegistry.resolve("my-llm:prod"); +``` + ## DashScope 阿里云 LLM 平台,提供通义千问系列模型。 From 13cfe4270a087f998b3e5c94187b1767add75755 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 17:41:12 +0800 Subject: [PATCH 19/28] delete examples --- .../harness-example-local/.env.example | 22 -- .../harness-example-local/README.md | 201 ----------- .../harness-example-local/pom.xml | 63 ---- .../harness/example/SqliteTool.java | 247 -------------- .../harness/example/TextToSqlExample.java | 316 ------------------ .../harness/example/WorkspaceInitializer.java | 126 ------- .../main/resources/agentscope.json.example | 24 -- .../harness/example/chinook-default.sqlite | Bin 1007616 -> 0 bytes .../resources/log4j2.component.properties | 2 - .../src/main/resources/log4j2.xml | 34 -- .../workspace/knowledge/KNOWLEDGE.md | 187 ----------- .../workspace/skills/query-writing/SKILL.md | 148 -------- .../skills/schema-exploration/SKILL.md | 136 -------- .../workspace/subagents/query-optimizer.md | 53 --- .../workspace/subagents/schema-analyst.md | 50 --- .../harness-example-remote/pom.xml | 83 ----- .../harness/remote/DataAgentController.java | 79 ----- .../harness/remote/DataAgentService.java | 151 --------- .../remote/HarnessRemoteApplication.java | 36 -- .../WorkspaceClasspathMaterializer.java | 68 ---- .../harness/remote/data/SqliteTool.java | 225 ------------- .../src/main/resources/application.properties | 2 - .../harness/remote/chinook-default.sqlite | Bin 1007616 -> 0 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 - .../workspace/skills/query-writing/SKILL.md | 14 - .../harness-example-sandbox/pom.xml | 84 ----- .../harness/sandbox/DataAgentController.java | 93 ------ .../harness/sandbox/DataAgentService.java | 163 --------- .../sandbox/HarnessSandboxApplication.java | 41 --- .../WorkspaceClasspathMaterializer.java | 70 ---- .../harness/sandbox/data/SqliteTool.java | 225 ------------- .../sandbox/support/InMemorySandbox.java | 170 ---------- .../support/InMemorySandboxClient.java | 122 ------- .../InMemorySandboxFilesystemSpec.java | 81 ----- .../sandbox/support/InMemorySandboxState.java | 41 --- .../SharedInMemorySandboxStateStore.java | 52 --- .../src/main/resources/application.properties | 2 - .../harness/sandbox/chinook-default.sqlite | Bin 1007616 -> 0 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 - .../workspace/skills/query-writing/SKILL.md | 14 - 40 files changed, 3449 deletions(-) delete mode 100644 agentscope-examples/harness-example-local/.env.example delete mode 100644 agentscope-examples/harness-example-local/README.md delete mode 100644 agentscope-examples/harness-example-local/pom.xml delete mode 100644 agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java delete mode 100644 agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java delete mode 100644 agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/log4j2.xml delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md delete mode 100644 agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md delete mode 100644 agentscope-examples/harness-example-remote/pom.xml delete mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java delete mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java delete mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java delete mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java delete mode 100644 agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java delete mode 100644 agentscope-examples/harness-example-remote/src/main/resources/application.properties delete mode 100644 agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite delete mode 100644 agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md delete mode 100644 agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md delete mode 100644 agentscope-examples/harness-example-sandbox/pom.xml delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/application.properties delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md delete mode 100644 agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md diff --git a/agentscope-examples/harness-example-local/.env.example b/agentscope-examples/harness-example-local/.env.example deleted file mode 100644 index 3a20c5633..000000000 --- a/agentscope-examples/harness-example-local/.env.example +++ /dev/null @@ -1,22 +0,0 @@ -# ───────────────────────────────────────────────────────────── -# AgentScope Harness Example — Environment Variables -# Copy this file to .env and fill in your values. -# ───────────────────────────────────────────────────────────── - -# Required: DashScope API key (https://dashscope.aliyun.com/) -DASHSCOPE_API_KEY=your_api_key_here - -# Optional: LLM model to use (default: qwen-max) -# Other options: qwen-plus, qwen-turbo, qwen-long -AGENTSCOPE_MODEL=qwen-max - -# Optional: path to the Chinook SQLite database (default: chinook.db). -# If this file does not exist, the example copies the bundled sample from the JAR (no curl needed). -AGENTSCOPE_DB_PATH=chinook.db - -# Optional: workspace directory (default: .agentscope/workspace) -# Modify the files here to customise agent behaviour without recompiling. -AGENTSCOPE_WORKSPACE=.agentscope/workspace - -# Optional: Log4j2 level for io.agentscope loggers (default: INFO). Example: DEBUG, TRACE -# AGENTSCOPE_LOG_LEVEL=DEBUG diff --git a/agentscope-examples/harness-example-local/README.md b/agentscope-examples/harness-example-local/README.md deleted file mode 100644 index 291e45d06..000000000 --- a/agentscope-examples/harness-example-local/README.md +++ /dev/null @@ -1,201 +0,0 @@ -# AgentScope Harness Example — Text-to-SQL Agent - -A practical example showing how to build a domain-specific agent with the **AgentScope Harness** -framework. The scenario: translate natural-language questions into SQL queries against the -[Chinook](https://github.com/lerocha/chinook-database) SQLite sample database. - -## What This Example Covers - -| Feature | How it is demonstrated | -|---------|------------------------| -| **Workspace** | Pre-populated from bundled resources by `WorkspaceInitializer` | -| **AGENTS.md** | Agent persona, principles, and workflow loaded automatically | -| **skills/** | `query-writing` and `schema-exploration` loaded on demand | -| **knowledge/** | Chinook schema reference injected as domain knowledge | -| **subagents/** | `schema-analyst` and `query-optimizer` available for delegation | -| **Custom tool** | `SqliteTool` registered via `Toolkit` alongside harness defaults | -| **Memory tools** | `memory_search` / `memory_get` enabled for cross-session recall | -| **RuntimeContext** | Session ID bound per invocation for stateful multi-turn use | - -## Project Layout - -``` -harness-example/ -├── pom.xml -├── .env.example # Environment variable template -├── README.md # This file -└── src/main/ - ├── java/io/agentscope/harness/example/ - │ ├── TextToSqlExample.java # Main entry point (CLI) - │ ├── SqliteTool.java # Custom @Tool: list_tables, get_schema, execute_query - │ └── WorkspaceInitializer.java # Copies bundled workspace to disk on first run - └── resources/ - ├── log4j2.xml # Log4j2 console layout and logger levels - ├── log4j2.component.properties # Log4j2 component flags (e.g. disable JMX) - ├── agentscope.json.example # Agent configuration template - ├── io/agentscope/harness/example/ - │ └── chinook-default.sqlite # Bundled Chinook DB (copied to AGENTSCOPE_DB_PATH if missing) - └── workspace/ # Bundled workspace template (extracted at runtime) - ├── AGENTS.md # Agent identity and core rules - ├── MEMORY.md # Persistent notes (pre-seeded) - ├── knowledge/ - │ └── KNOWLEDGE.md # Full Chinook schema reference - ├── skills/ - │ ├── query-writing/ - │ │ └── SKILL.md # SQL query writing workflow - │ └── schema-exploration/ - │ └── SKILL.md # Database structure discovery workflow - └── subagents/ - ├── schema-analyst.md # Schema documentation specialist - └── query-optimizer.md # Query optimisation specialist -``` - -## Quick Start - -### 1. Build - -```bash -cd agentscope-java -mvn -pl agentscope-examples/agents/harness-example package -am -DskipTests -``` - -### 2. Chinook database (optional) - -The example ships a bundled Chinook SQLite file in the JAR. On first run, if `chinook.db` (or -`AGENTSCOPE_DB_PATH`) is missing, it is copied from the classpath automatically. Use your own file -only when you want a different path or a refreshed copy from upstream: - -```bash -curl -L -o chinook.db \ - https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite -``` - -### 3. Set your API key - -```bash -export DASHSCOPE_API_KEY=your_key_here -``` - -Or copy `.env.example` → `.env` and fill in your values, then load it: - -```bash -cp .env.example .env -# edit .env, then: -source <(grep -v '^#' .env | sed 's/^/export /') -``` - -### 4. Run - -Interactive (no arguments — type questions at the `>` prompt; `quit`, empty line, or Ctrl-D to -exit): - -```bash -java -cp target/harness-example-*.jar \ - io.agentscope.harness.example.TextToSqlExample -``` - -One-shot (single question, then exit — useful for scripts): - -```bash -java -cp target/harness-example-*.jar \ - io.agentscope.harness.example.TextToSqlExample \ - "What are the top 5 best-selling artists?" -``` - -Example prompts you can paste at `>`: - -- Which customers are from Brazil? -- Show me the monthly revenue trend for 2013 -- Which employee has the most customers? -- What are the top genres by number of tracks? -- How many tracks are longer than 5 minutes? - -## Logging (Log4j2) - -This module uses **Log4j2** with `log4j-slf4j2-impl` as the SLF4J binding. Configuration lives in -[`src/main/resources/log4j2.xml`](src/main/resources/log4j2.xml) (console appender, tuned levels -for Netty / Reactor / OkHttp). - -Set **`AGENTSCOPE_LOG_LEVEL`** (for example `DEBUG`) to change verbosity for `io.agentscope.*` -without editing the XML. To use a different file at runtime: - -```bash -java -Dlog4j.configurationFile=/path/to/log4j2-custom.xml ... -``` - -## How It Works - -### Workspace Initialisation - -On first run `WorkspaceInitializer.init(workspace)` extracts the bundled template files from the -JAR into `.agentscope/workspace/`. On subsequent runs existing files are preserved so the agent's -accumulated notes survive across restarts. - -``` -.agentscope/workspace/ -├── AGENTS.md ← always loaded into system prompt -├── MEMORY.md ← loaded into -├── knowledge/KNOWLEDGE.md ← loaded into -├── skills/ ← skill descriptions shown; full content loaded on demand -└── subagents/ ← subagent specs registered as callable agents -``` - -### Agent Construction - -```java -HarnessAgent agent = HarnessAgent.builder() - .name("text-to-sql") - .model(model) - .workspace(workspace) // ← harness reads all workspace files from here - .toolkit(toolkit) // ← includes our custom SqliteTool - .maxIters(20) - .build(); -``` - -### Custom Tool Registration - -```java -Toolkit toolkit = new Toolkit(); -toolkit.registerTool(new SqliteTool(dbPath)); // adds sql_list_tables, sql_get_schema, sql_execute_query -``` - -`SqliteTool` uses `@Tool` / `@ToolParam` annotations — the same mechanism used by all harness -built-in tools. Methods are discovered at runtime via reflection and exposed to the LLM as JSON -schemas. - -### Calling the Agent - -```java -RuntimeContext ctx = RuntimeContext.builder() - .sessionId("my-session-id") - .build(); - -Msg reply = agent.call(Msg.userMsg("Top 5 artists?"), ctx).block(); -``` - -The `RuntimeContext` carries the session ID used by hooks (WorkspaceContextHook, MemoryFlushHook) to -isolate per-session state and persist memory between turns in the same session. - -## Customising the Agent - -All behaviour can be tuned by editing files in `.agentscope/workspace/` — no recompilation needed: - -| File | What to change | -|------|----------------| -| `AGENTS.md` | Persona, rules, communication style | -| `MEMORY.md` | Pre-seed knowledge the agent should know from turn one | -| `knowledge/KNOWLEDGE.md` | Domain knowledge (schema details, business rules) | -| `skills/*/SKILL.md` | Step-by-step workflows for specific task types | -| `subagents/*.md` | Add / remove / reconfigure specialist subagents | - -## Dependencies - -| Dependency | Purpose | -|------------|---------| -| `agentscope-harness` | Core framework (HarnessAgent, tools, hooks, workspace) | -| `jackson-dataformat-yaml` | YAML front-matter parsing in skill/subagent files | -| `sqlite-jdbc` | SQLite JDBC driver used by `SqliteTool` | - -## License - -Apache 2.0 — see the root `LICENSE` file. diff --git a/agentscope-examples/harness-example-local/pom.xml b/agentscope-examples/harness-example-local/pom.xml deleted file mode 100644 index 8a27d35a0..000000000 --- a/agentscope-examples/harness-example-local/pom.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - 4.0.0 - - io.agentscope - agentscope-examples - ${revision} - ../pom.xml - - - AgentScope Java - Harness Example - harness-example-local - AgentScope Harness Example - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction - - - 2.24.3 - - - - - io.agentscope - agentscope-harness - - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - - - org.xerial - sqlite-jdbc - 3.47.2.0 - - - - - org.apache.logging.log4j - log4j-slf4j2-impl - ${log4j2.version} - - - diff --git a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java deleted file mode 100644 index 84650c783..000000000 --- a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.example; - -import io.agentscope.core.tool.Tool; -import io.agentscope.core.tool.ToolParam; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.StringJoiner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Custom tool that exposes SQLite database operations to the agent. - * - *

Provides three tools the agent can call: - * - *

    - *
  • {@code sql_list_tables} — list all tables in the database - *
  • {@code sql_get_schema} — describe a table's columns, types, and sample rows - *
  • {@code sql_execute_query} — run a read-only SELECT query and return formatted results - *
- * - *

This class demonstrates how to wire a domain-specific tool into a {@link - * io.agentscope.harness.agent.HarnessAgent}. Register it via the agent's {@code Toolkit} before - * calling {@link io.agentscope.harness.agent.HarnessAgent.Builder#build()}. - */ -public class SqliteTool { - - private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); - - /** Maximum rows returned by {@code sql_execute_query} to prevent context overflow. */ - private static final int MAX_ROWS = 50; - - /** Number of sample rows shown by {@code sql_get_schema}. */ - private static final int SAMPLE_ROWS = 3; - - private final String jdbcUrl; - - public SqliteTool(Path dbPath) { - this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); - } - - @Tool( - name = "sql_list_tables", - description = - "Lists all tables in the SQLite database. Use this first to discover what data" - + " is available before writing queries.") - public String listTables() { - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - List tables = new ArrayList<>(); - try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { - while (rs.next()) { - tables.add(rs.getString("TABLE_NAME")); - } - } - if (tables.isEmpty()) { - return "No tables found in the database."; - } - return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); - } catch (SQLException e) { - log.warn("sql_list_tables failed", e); - return "Error listing tables: " + e.getMessage(); - } - } - - @Tool( - name = "sql_get_schema", - description = - "Returns the schema (column names, types, keys) and sample rows for one or more" - + " tables. Pass a comma-separated list of table names to inspect" - + " multiple tables at once.") - public String getSchema( - @ToolParam( - name = "tables", - description = - "Comma-separated table names, e.g. \"Artist,Album,Track\"") - String tables) { - StringBuilder sb = new StringBuilder(); - for (String table : tables.split(",")) { - table = table.strip(); - if (table.isEmpty()) continue; - sb.append(describeTable(table)).append("\n\n"); - } - return sb.toString().strip(); - } - - @Tool( - name = "sql_execute_query", - description = - "Executes a read-only SELECT query against the SQLite database and returns the" - + " results as a formatted table. Never use DML statements" - + " (INSERT / UPDATE / DELETE / DROP).") - public String executeQuery( - @ToolParam(name = "query", description = "A valid SQLite SELECT statement") - String query) { - String trimmed = query.strip(); - if (!trimmed.toUpperCase().startsWith("SELECT")) { - return "Error: only SELECT statements are allowed. Received: " + trimmed; - } - try (Connection conn = DriverManager.getConnection(jdbcUrl); - Statement stmt = conn.createStatement()) { - stmt.setMaxRows(MAX_ROWS); - try (ResultSet rs = stmt.executeQuery(trimmed)) { - return formatResultSet(rs); - } - } catch (SQLException e) { - log.warn("sql_execute_query failed for: {}", trimmed, e); - return "Error executing query: " + e.getMessage(); - } - } - - // ------------------------------------------------------------------------- - // Private helpers - // ------------------------------------------------------------------------- - - private String describeTable(String tableName) { - StringBuilder sb = new StringBuilder(); - sb.append("## ").append(tableName).append("\n\n"); - - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - - // Primary keys - List pks = new ArrayList<>(); - try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { - while (rs.next()) { - pks.add(rs.getString("COLUMN_NAME")); - } - } - - // Foreign keys - List fks = new ArrayList<>(); - try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { - while (rs.next()) { - fks.add( - rs.getString("FKCOLUMN_NAME") - + " → " - + rs.getString("PKTABLE_NAME") - + "." - + rs.getString("PKCOLUMN_NAME")); - } - } - - // Columns - sb.append("### Columns\n"); - try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { - while (rs.next()) { - String col = rs.getString("COLUMN_NAME"); - String type = rs.getString("TYPE_NAME"); - String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; - String pk = pks.contains(col) ? " [PK]" : ""; - sb.append("- ") - .append(col) - .append(" (") - .append(type) - .append(nullable) - .append(pk) - .append(")\n"); - } - } - - if (!fks.isEmpty()) { - sb.append("\n### Foreign Keys\n"); - fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); - } - - // Sample rows - sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); - try (Statement stmt = conn.createStatement()) { - stmt.setMaxRows(SAMPLE_ROWS); - try (ResultSet rs = - stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { - sb.append(formatResultSet(rs)); - } - } - - } catch (SQLException e) { - sb.append("Error describing table '") - .append(tableName) - .append("': ") - .append(e.getMessage()); - } - return sb.toString(); - } - - private static String formatResultSet(ResultSet rs) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int cols = meta.getColumnCount(); - - // Header - StringJoiner header = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - header.add(meta.getColumnName(i)); - } - - // Separator - String separator = "-".repeat(header.toString().length()); - - // Rows - List rows = new ArrayList<>(); - int count = 0; - while (rs.next()) { - StringJoiner row = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - Object val = rs.getObject(i); - row.add(val == null ? "NULL" : val.toString()); - } - rows.add(row.toString()); - count++; - } - - if (rows.isEmpty()) { - return "(no rows returned)"; - } - - StringBuilder sb = new StringBuilder(); - sb.append(header).append("\n").append(separator).append("\n"); - rows.forEach(r -> sb.append(r).append("\n")); - if (count >= MAX_ROWS) { - sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); - } - return sb.toString(); - } -} diff --git a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java deleted file mode 100644 index c34ad5651..000000000 --- a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.example; - -import io.agentscope.core.agent.RuntimeContext; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.message.TextBlock; -import io.agentscope.core.model.DashScopeChatModel; -import io.agentscope.core.model.Model; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.harness.agent.HarnessAgent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.UUID; - -/** - * Text-to-SQL example using the AgentScope Harness framework. - * - *

What this example demonstrates

- * - *
    - *
  • Setting up a workspace directory with the standard harness layout - * (AGENTS.md, skills/, knowledge/, subagents/) - *
  • Wiring a custom tool ({@link SqliteTool}) into the agent's toolkit - *
  • Building a {@link HarnessAgent} with skills auto-loading, memory tools, and subagents - *
  • Calling the agent with a {@link RuntimeContext} (session id, user id) - *
  • Reading questions from the console in a loop (optional one-shot mode if you pass a - * question as program arguments) - *
- * - *

Prerequisites

- * - *
    - *
  1. The Chinook sample database is bundled in the JAR under the same package - * as this class. If {@code AGENTSCOPE_DB_PATH} (default {@code chinook.db}) does not exist - * yet, it is copied there automatically — no manual download is required. - *
  2. Set the environment variable {@code DASHSCOPE_API_KEY} (or {@code OPENAI_API_KEY} for - * OpenAI-compatible endpoints). - *
  3. Optionally override defaults via the variables listed in {@code .env.example}. - *
- * - *

Usage

- * - *

Run with no arguments to start an interactive session: type a question at - * the {@code >} prompt after startup. Empty line, {@code quit}, {@code exit}, or {@code q} ends - * the session; EOF (Ctrl-D) also exits. - * - *

Pass a question as arguments for a single non-interactive run (exits after - * the answer), e.g. for scripts: - * - *

- * java -jar harness-example.jar
- * java -jar harness-example.jar "What are the top 5 best-selling artists?"
- * java -jar harness-example.jar --new-session "What are the top 5 best-selling artists?"
- * 
- * - *

The workspace is initialised under {@code .agentscope/workspace/} relative to the current - * working directory. Modify the files there to customise the agent's behaviour without recompiling. - */ -public class TextToSqlExample { - - // ------------------------------------------------------------------------- - // Environment variable names - // ------------------------------------------------------------------------- - - /** DashScope API key (required). */ - public static final String ENV_API_KEY = "DASHSCOPE_API_KEY"; - - /** LLM model name. Defaults to {@code qwen-max}. */ - public static final String ENV_MODEL_NAME = "AGENTSCOPE_MODEL"; - - /** Path to the Chinook SQLite database file. Defaults to {@code chinook.db}. */ - public static final String ENV_DB_PATH = "AGENTSCOPE_DB_PATH"; - - /** Workspace directory. Defaults to {@code .agentscope/workspace}. */ - public static final String ENV_WORKSPACE = "AGENTSCOPE_WORKSPACE"; - - // ------------------------------------------------------------------------- - // Defaults - // ------------------------------------------------------------------------- - - private static final String DEFAULT_MODEL = "qwen-max"; - private static final String DEFAULT_DB_PATH = "chinook.db"; - private static final String DEFAULT_WORKSPACE = ".agentscope/workspace"; - private static final String DEFAULT_SHARED_SESSION_ID = "text-to-sql-shared-default"; - private static final String NEW_SESSION_FLAG = "--new-session"; - - /** - * Bundled Chinook SQLite file (same package on the classpath). Materialised to disk when - * {@link #ENV_DB_PATH} points to a path that does not exist yet. - */ - private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; - - // ------------------------------------------------------------------------- - // Entry point - // ------------------------------------------------------------------------- - - public static void main(String[] args) throws IOException { - System.out.println("\n═══════════════════════════════════════════════"); - System.out.println(" AgentScope Harness — Text-to-SQL Example"); - System.out.println("═══════════════════════════════════════════════\n"); - - // ------------------------------------------------------------------ - // 1. Resolve configuration from environment variables - // ------------------------------------------------------------------ - - String apiKey = requireEnv(ENV_API_KEY); - String modelName = env(ENV_MODEL_NAME, DEFAULT_MODEL); - Path workspace = Paths.get(env(ENV_WORKSPACE, DEFAULT_WORKSPACE)); - Path dbPath = resolveDatabasePath(Paths.get(env(ENV_DB_PATH, DEFAULT_DB_PATH))); - - // ------------------------------------------------------------------ - // 2. Initialise workspace from bundled template files - // (skips files that already exist — safe to call every run) - // ------------------------------------------------------------------ - - System.out.println("[1/3] Initialising workspace at: " + workspace.toAbsolutePath()); - WorkspaceInitializer.init(workspace); - - // ------------------------------------------------------------------ - // 3. Build the LLM model - // ------------------------------------------------------------------ - - System.out.println("[2/3] Connecting to model: " + modelName); - Model model = - DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) - .build(); - - // ------------------------------------------------------------------ - // 4. Build the agent - // - workspace: loads AGENTS.md, MEMORY.md, knowledge/, subagents/, skills/ - // - harness: memory tools, session_search, optional subagent tools - // - custom toolkit: SqliteTool is registered alongside harness defaults - // ------------------------------------------------------------------ - - System.out.println("[3/3] Building HarnessAgent ..."); - - Toolkit toolkit = new Toolkit(); - toolkit.registerTool(new SqliteTool(dbPath)); - - HarnessAgent agent = - HarnessAgent.builder() - .name("text-to-sql") - .sysPrompt( - "You are a Text-to-SQL agent with access to the Chinook music" - + " store database. When asked a question, explore the" - + " database schema, write a correct SQL query, execute it," - + " and present the results in a clear, formatted answer.") - .model(model) - .workspace(workspace) - .enableAgentTracingLog(true) - .toolkit(toolkit) - .build(); - - ParsedArgs parsedArgs = parseArgs(args); - String sessionId = - parsedArgs.newSession() - ? "text-to-sql-" + UUID.randomUUID().toString().substring(0, 8) - : DEFAULT_SHARED_SESSION_ID; - System.out.println("Session ID: " + sessionId); - RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); - - if (parsedArgs.question() != null) { - runOneTurn(agent, ctx, parsedArgs.question()); - return; - } - - System.out.println( - "Ask questions in natural language about the Chinook database." - + " Same session for all turns (memory tools share context)."); - System.out.println("Tip: add --new-session to generate a UUID-based fresh session."); - System.out.println("Leave: empty line, quit, exit, q, or EOF (Ctrl-D).\n"); - - BufferedReader stdin = - new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); - while (true) { - System.out.print("> "); - System.out.flush(); - String line = stdin.readLine(); - if (line == null) { - System.out.println("\n(end of input)"); - break; - } - String question = line.strip(); - if (question.isEmpty()) { - System.out.println("Goodbye."); - break; - } - if (isQuitCommand(question)) { - System.out.println("Goodbye."); - break; - } - runOneTurn(agent, ctx, question); - System.out.println(); - } - } - - private static boolean isQuitCommand(String line) { - return line.equalsIgnoreCase("quit") - || line.equalsIgnoreCase("exit") - || line.equalsIgnoreCase("q"); - } - - private static ParsedArgs parseArgs(String[] args) { - boolean newSession = false; - StringBuilder questionBuilder = new StringBuilder(); - for (String arg : args) { - if (NEW_SESSION_FLAG.equals(arg)) { - newSession = true; - continue; - } - if (questionBuilder.length() > 0) { - questionBuilder.append(' '); - } - questionBuilder.append(arg); - } - String question = questionBuilder.length() == 0 ? null : questionBuilder.toString(); - return new ParsedArgs(newSession, question); - } - - private static void runOneTurn(HarnessAgent agent, RuntimeContext ctx, String question) { - System.out.println("─".repeat(50)); - System.out.println("Question: " + question); - System.out.println(); - - Msg userMsg = - Msg.builder() - .role(MsgRole.USER) - .content(TextBlock.builder().text(question).build()) - .build(); - Msg reply = agent.call(userMsg, ctx).block(); - - System.out.println("─".repeat(50)); - System.out.println("\nAnswer:\n"); - System.out.println(reply != null ? reply.getTextContent() : "(no response)"); - System.out.println(); - } - - // ------------------------------------------------------------------------- - // Helpers - // ------------------------------------------------------------------------- - - /** - * Uses an existing file at {@code configuredPath}, or copies the bundled Chinook database from - * the classpath to that path (SQLite itself has no built-in sample data; shipping a small - * .sqlite in resources gives the same “works out of the box” experience). - */ - private static Path resolveDatabasePath(Path configuredPath) throws IOException { - if (Files.exists(configuredPath)) { - return configuredPath.toAbsolutePath(); - } - try (InputStream in = - TextToSqlExample.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { - if (in == null) { - System.err.println( - "Database file not found: " - + configuredPath.toAbsolutePath() - + "\n\nBuilt-in sample missing from classpath (packaging issue)." - + " Download manually:\n" - + " curl -L -o chinook.db \\\n" - + " https://github.com/lerocha/chinook-database/raw/master/" - + "ChinookDatabase/DataSources/Chinook_Sqlite.sqlite"); - System.exit(1); - } - Path parent = configuredPath.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - Files.copy(in, configuredPath, StandardCopyOption.REPLACE_EXISTING); - System.out.println( - "Materialised bundled Chinook database to: " + configuredPath.toAbsolutePath()); - return configuredPath.toAbsolutePath(); - } - } - - private static String requireEnv(String name) { - String value = System.getenv(name); - if (value == null || value.isBlank()) { - System.err.println( - "Required environment variable '" - + name - + "' is not set.\n" - + "Copy .env.example → .env and fill in your API key."); - System.exit(1); - } - return value; - } - - private static String env(String name, String defaultValue) { - String value = System.getenv(name); - return (value != null && !value.isBlank()) ? value : defaultValue; - } - - private record ParsedArgs(boolean newSession, String question) {} -} diff --git a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java deleted file mode 100644 index 1fec9b2f7..000000000 --- a/agentscope-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.harness.example; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.Collections; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Initializes the agent workspace by copying bundled template files from the classpath into a - * target directory on disk. - * - *

The template files live under {@code src/main/resources/workspace/} and are packaged inside - * the JAR. When the example is run for the first time, {@link #init(Path)} extracts them into the - * given workspace directory so the agent can read and modify them at runtime. - * - *

Workspace structure

- * - *
- * <workspace>/
- * ├── AGENTS.md              # Agent persona and core rules (always loaded)
- * ├── MEMORY.md              # Persistent notes accumulated across sessions
- * ├── knowledge/
- * │   └── KNOWLEDGE.md       # Chinook database schema reference
- * ├── skills/
- * │   ├── schema-exploration/
- * │   │   └── SKILL.md       # How to discover database structure
- * │   └── query-writing/
- * │       └── SKILL.md       # How to write and execute SQL queries
- * └── subagents/
- *     ├── schema-analyst.md  # Specialised subagent for deep schema analysis
- *     └── query-optimizer.md # Specialised subagent for query optimisation
- * 
- */ -public class WorkspaceInitializer { - - private static final Logger log = LoggerFactory.getLogger(WorkspaceInitializer.class); - private static final String CLASSPATH_PREFIX = "workspace"; - - /** - * Copies all bundled workspace template files into {@code targetDir}. - * - *

Existing files are left unchanged so that previously accumulated notes survive restarts. - * New template files are copied with {@link StandardCopyOption#REPLACE_EXISTING} disabled. - * - * @param targetDir directory to initialise; created if it does not exist - * @throws IOException if a file cannot be read or written - */ - public static void init(Path targetDir) throws IOException { - Files.createDirectories(targetDir); - - URL resourceUrl = WorkspaceInitializer.class.getClassLoader().getResource(CLASSPATH_PREFIX); - if (resourceUrl == null) { - log.warn( - "Classpath resource '{}' not found — workspace will not be pre-populated.", - CLASSPATH_PREFIX); - return; - } - - URI resourceUri; - try { - resourceUri = resourceUrl.toURI(); - } catch (URISyntaxException e) { - throw new IOException("Cannot convert resource URL to URI: " + resourceUrl, e); - } - - if ("jar".equals(resourceUri.getScheme())) { - // Running from a JAR: open the embedded filesystem - try (FileSystem fs = FileSystems.newFileSystem(resourceUri, Collections.emptyMap())) { - Path source = fs.getPath(CLASSPATH_PREFIX); - copyTree(source, targetDir); - } - } else { - // Running from an exploded directory (IDE / Maven test run) - Path source = Path.of(resourceUri); - copyTree(source, targetDir); - } - - log.info("Workspace initialised at {}", targetDir); - } - - private static void copyTree(Path source, Path targetDir) throws IOException { - try (Stream walk = Files.walk(source)) { - for (Path srcPath : (Iterable) walk::iterator) { - Path relative = source.relativize(srcPath); - Path target = targetDir.resolve(relative.toString()); - - if (Files.isDirectory(srcPath)) { - Files.createDirectories(target); - } else if (!Files.exists(target)) { - Files.createDirectories(target.getParent()); - try (InputStream in = Files.newInputStream(srcPath)) { - Files.copy(in, target); - } - log.debug("Copied workspace file: {}", relative); - } else { - log.debug("Skipped (already exists): {}", relative); - } - } - } - } -} diff --git a/agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example b/agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example deleted file mode 100644 index a09a7c4eb..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/agentscope.json.example +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://agentscope.io/schema/agentscope.json", - "main": "text-to-sql", - "agents": { - "text-to-sql": { - "name": "Text-to-SQL", - "description": "Answers natural-language questions about the Chinook music store database by translating them into SQL and executing the queries.", - "workspace": ".agentscope/workspace", - "maxIters": 20 - }, - "schema-analyst": { - "name": "Schema Analyst", - "description": "Deep schema analysis and documentation specialist. Loaded on-demand from workspace/subagents/schema-analyst.md.", - "workspace": ".agentscope/workspace", - "maxIters": 10 - } - }, - "channels": { - "chatui": { - "defaultAgentId": "text-to-sql", - "dmScope": "MAIN" - } - } -} diff --git a/agentscope-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite b/agentscope-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite deleted file mode 100644 index f385c2651f80914c3b93c62431b0b000465a921b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D diff --git a/agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties b/agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties deleted file mode 100644 index 6745cfa94..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/log4j2.component.properties +++ /dev/null @@ -1,2 +0,0 @@ -# Log4j2 component settings for the harness-example module -log4j2.disable.jmx=true diff --git a/agentscope-examples/harness-example-local/src/main/resources/log4j2.xml b/agentscope-examples/harness-example-local/src/main/resources/log4j2.xml deleted file mode 100644 index b6ecbb49f..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/log4j2.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - ${env:AGENTSCOPE_LOG_LEVEL:-INFO} - %d{HH:mm:ss.SSS} %-5level %-36.36c{1.} : %m%n%throwable - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md deleted file mode 100644 index ad6c7c40d..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md +++ /dev/null @@ -1,187 +0,0 @@ -# Chinook Database — Schema Reference - -The Chinook database represents a digital music store. It was originally created to demonstrate -data modelling in SQLite and is widely used as a sample database for tutorials. - -## Entity Relationship Overview - -``` -Artist (ArtistId, Name) - └─ 1:many ─► Album (AlbumId, Title, ArtistId) - └─ 1:many ─► Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, - Composer, Milliseconds, Bytes, UnitPrice) - └─ 1:many ─► InvoiceLine (InvoiceLineId, InvoiceId, - TrackId, UnitPrice, Quantity) - └─ many:1 ─► Invoice (InvoiceId, CustomerId, - InvoiceDate, BillingAddress, - BillingCity, BillingState, - BillingCountry, BillingPostalCode, - Total) - └─ many:1 ─► Customer (CustomerId, - FirstName, LastName, - Company, Address, - City, State, Country, - PostalCode, Phone, - Fax, Email, - SupportRepId) - └─ many:1 ─► Employee - -Genre (GenreId, Name) -MediaType (MediaTypeId, Name) -Playlist (PlaylistId, Name) - └─ many:many via PlaylistTrack (PlaylistId, TrackId) ─► Track - -Employee (EmployeeId, LastName, FirstName, Title, ReportsTo [→ Employee.EmployeeId], - BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email) -``` - -## Table Descriptions - -### Artist -| Column | Type | Notes | -|----------|---------|-------| -| ArtistId | INTEGER | PK | -| Name | TEXT | | - -275 rows — music artists (AC/DC, Aerosmith, Alanis Morissette, …). - -### Album -| Column | Type | Notes | -|----------|---------|----------------| -| AlbumId | INTEGER | PK | -| Title | TEXT | | -| ArtistId | INTEGER | FK → Artist | - -347 rows — one or many albums per artist. - -### Track -| Column | Type | Notes | -|---------------|---------|--------------------| -| TrackId | INTEGER | PK | -| Name | TEXT | | -| AlbumId | INTEGER | FK → Album | -| MediaTypeId | INTEGER | FK → MediaType | -| GenreId | INTEGER | FK → Genre | -| Composer | TEXT | nullable | -| Milliseconds | INTEGER | duration | -| Bytes | INTEGER | file size | -| UnitPrice | REAL | default 0.99 | - -3,503 rows — the central music catalog table. - -### Genre -| Column | Type | Notes | -|---------|---------|-------| -| GenreId | INTEGER | PK | -| Name | TEXT | | - -25 rows — Rock, Jazz, Metal, Alternative & Punk, … - -### MediaType -| Column | Type | Notes | -|-------------|---------|-------| -| MediaTypeId | INTEGER | PK | -| Name | TEXT | | - -5 rows — MPEG audio file, AAC audio file, Protected AAC, … - -### Customer -| Column | Type | Notes | -|--------------|---------|-------------------| -| CustomerId | INTEGER | PK | -| FirstName | TEXT | | -| LastName | TEXT | | -| Company | TEXT | nullable | -| Address | TEXT | | -| City | TEXT | | -| State | TEXT | nullable | -| Country | TEXT | | -| PostalCode | TEXT | nullable | -| Phone | TEXT | nullable | -| Fax | TEXT | nullable | -| Email | TEXT | unique | -| SupportRepId | INTEGER | FK → Employee | - -59 rows — customers from 24 countries. - -### Employee -| Column | Type | Notes | -|-------------|---------|----------------------------| -| EmployeeId | INTEGER | PK | -| LastName | TEXT | | -| FirstName | TEXT | | -| Title | TEXT | | -| ReportsTo | INTEGER | FK → Employee (nullable) | -| BirthDate | TEXT | ISO-8601 | -| HireDate | TEXT | ISO-8601 | -| Address | TEXT | | -| City | TEXT | | -| State | TEXT | | -| Country | TEXT | | -| PostalCode | TEXT | | -| Phone | TEXT | | -| Fax | TEXT | | -| Email | TEXT | | - -8 rows — Sales Support Agents + manager hierarchy. - -### Invoice -| Column | Type | Notes | -|-----------------|---------|------------------| -| InvoiceId | INTEGER | PK | -| CustomerId | INTEGER | FK → Customer | -| InvoiceDate | TEXT | ISO-8601 | -| BillingAddress | TEXT | | -| BillingCity | TEXT | | -| BillingState | TEXT | nullable | -| BillingCountry | TEXT | | -| BillingPostalCode | TEXT | nullable | -| Total | REAL | invoice total | - -412 rows — one invoice per purchase, covering 2009–2013. - -### InvoiceLine -| Column | Type | Notes | -|---------------|---------|------------------| -| InvoiceLineId | INTEGER | PK | -| InvoiceId | INTEGER | FK → Invoice | -| TrackId | INTEGER | FK → Track | -| UnitPrice | REAL | | -| Quantity | INTEGER | | - -2,240 rows — line items; revenue = UnitPrice × Quantity. - -### Playlist -| Column | Type | Notes | -|------------|---------|-------| -| PlaylistId | INTEGER | PK | -| Name | TEXT | | - -18 rows — Music, Movies, TV Shows, Classical, … - -### PlaylistTrack -| Column | Type | Notes | -|------------|---------|---------------------| -| PlaylistId | INTEGER | FK → Playlist (PK) | -| TrackId | INTEGER | FK → Track (PK) | - -8,715 rows — composite PK, no surrogate key. - -## Common JOIN Paths - -```sql --- Revenue by artist -Artist - JOIN Album ON Album.ArtistId = Artist.ArtistId - JOIN Track ON Track.AlbumId = Album.AlbumId - JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId - --- Revenue by country -Invoice - JOIN Customer ON Customer.CustomerId = Invoice.CustomerId - GROUP BY Customer.Country - --- Employee support load -Employee - LEFT JOIN Customer ON Customer.SupportRepId = Employee.EmployeeId -``` diff --git a/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md deleted file mode 100644 index 648c5fcd7..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -name: query-writing -description: Writes and executes SQL queries ranging from simple single-table SELECTs to complex multi-table JOINs, aggregations, window functions, and subqueries. Use when the user asks to query the database, retrieve data, filter records, rank results, or generate reports. ---- - -# Query Writing Skill - -## When to Use This Skill - -Use query-writing when the user: - -- Asks "how many …?" / "what are the top …?" / "list all …" -- Needs data aggregated (SUM, COUNT, AVG, MAX, MIN) -- Wants results sorted, filtered, or grouped -- Asks for trend analysis, ranking, or comparison across dimensions - ---- - -## Workflow for Simple Queries (single table) - -1. **Identify the table** — which table contains the answer? -2. **Check the schema** — call `sql_get_schema` to confirm column names. -3. **Write a SELECT** — include WHERE / ORDER BY / LIMIT as needed. -4. **Execute** — call `sql_execute_query`. -5. **Present** — show the SQL and the result in plain language. - -### Example — "How many customers are from Canada?" - -```sql -SELECT COUNT(*) AS canadian_customers -FROM Customer -WHERE Country = 'Canada'; -``` - ---- - -## Workflow for Complex Queries (multiple tables) - -### Step 1 — Plan with todos - -Break the query into subtasks: - -``` -- [ ] Identify all required tables -- [ ] Inspect schemas to find join columns -- [ ] Draft the JOIN structure -- [ ] Add aggregations and grouping -- [ ] Validate and run -``` - -### Step 2 — Inspect schemas - -Call `sql_get_schema` for EACH table involved to find the exact foreign key column names. - -### Step 3 — Build the query - -```sql -SELECT - , - -FROM -[INNER | LEFT] JOIN ON = -[JOIN ...] -WHERE -GROUP BY -HAVING -- optional -ORDER BY [DESC] -LIMIT 10; -- always limit unless all rows requested -``` - -### Step 4 — Validate - -Before executing, verify: -- Every JOIN has an ON clause -- Every non-aggregate SELECT column appears in GROUP BY -- Table aliases are consistent -- No DML statements (INSERT / UPDATE / DELETE / DROP) - -### Step 5 — Execute and present - -Call `sql_execute_query`, then show: -1. The SQL query in a fenced code block -2. The result table -3. A brief plain-language summary - ---- - -## Templates for Common Patterns - -### Top-N ranking - -```sql -SELECT - Artist.Name AS artist, - SUM(InvoiceLine.UnitPrice * InvoiceLine.Quantity) AS total_revenue -FROM Artist -JOIN Album ON Album.ArtistId = Artist.ArtistId -JOIN Track ON Track.AlbumId = Album.AlbumId -JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId -GROUP BY Artist.ArtistId, Artist.Name -ORDER BY total_revenue DESC -LIMIT 10; -``` - -### Revenue by time period - -```sql -SELECT - strftime('%Y-%m', InvoiceDate) AS month, - ROUND(SUM(Total), 2) AS monthly_revenue -FROM Invoice -WHERE strftime('%Y', InvoiceDate) = '2013' -GROUP BY month -ORDER BY month; -``` - -### Entity counts with left join - -```sql -SELECT - e.FirstName || ' ' || e.LastName AS employee, - COUNT(c.CustomerId) AS customer_count -FROM Employee e -LEFT JOIN Customer c ON c.SupportRepId = e.EmployeeId -GROUP BY e.EmployeeId -ORDER BY customer_count DESC; -``` - ---- - -## Error Recovery - -| Symptom | Action | -|----------------------|--------| -| Empty result | Check WHERE condition values (case-sensitive strings). Verify column exists. | -| Syntax error | Re-read schema. Check GROUP BY includes all non-aggregate SELECT columns. | -| Wrong row count | Look for duplicate rows caused by missing JOIN conditions. | -| Result seems too high | Check for fan-out from multiple JOINs; may need DISTINCT or subquery. | - ---- - -## Quality Rules - -- Always apply `LIMIT` (default 10) unless the user explicitly asks for all rows. -- Use table aliases (`e`, `c`, `inv`) for readability in multi-table queries. -- Never use `SELECT *` — name the columns you need. -- Round monetary values to 2 decimal places: `ROUND(SUM(Total), 2)`. -- Always show the executed SQL so users can learn from it. diff --git a/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md deleted file mode 100644 index 4972a88d2..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -name: schema-exploration -description: Lists tables, describes columns and data types, identifies foreign key relationships, and maps entity relationships in the database. Use when the user asks about database structure, table layout, column types, what tables exist, foreign keys, or how entities relate to each other. ---- - -# Schema Exploration Skill - -## When to Use This Skill - -Use schema-exploration when the user: - -- Asks "what tables are in the database?" -- Asks "what columns does the X table have?" -- Asks about relationships between tables -- Needs to understand data types before writing a query -- Wants an entity-relationship overview - -## Workflow - -### Step 1 — List All Tables - -Use `sql_list_tables` to see everything available. - -``` -Tool: sql_list_tables -(no parameters) -``` - -### Step 2 — Inspect Relevant Tables - -Use `sql_get_schema` with the table name(s) you need to understand: - -``` -Tool: sql_get_schema -tables: "Customer" # single table -tables: "Invoice,Customer" # multiple tables at once -``` - -This returns: -- **Columns** — names, types, NOT NULL constraints, primary keys -- **Foreign keys** — links to other tables -- **Sample data** — 3 example rows to understand content - -### Step 3 — Map Relationships - -Look for columns ending in `Id` — they are almost always foreign keys. - -Example for the Chinook database: -``` -Customer.SupportRepId → Employee.EmployeeId -Invoice.CustomerId → Customer.CustomerId -Track.AlbumId → Album.AlbumId -Track.GenreId → Genre.GenreId -``` - -### Step 4 — Present the Findings - -Provide: -- A list of all tables with a one-line purpose summary -- Column names and types for any tables the user asked about -- The relationship chain (which table links to which) -- Sample data to illustrate what the table holds - ---- - -## Examples - -### "What tables are available?" - -1. Call `sql_list_tables` -2. Return a formatted list with brief descriptions: - -``` -The Chinook database has 11 tables: - -Music Catalog: - - Artist — 275 music artists - - Album — 347 albums (linked to Artist) - - Track — 3,503 tracks (linked to Album, Genre, MediaType) - - Genre — 25 music genres - - MediaType — 5 file formats (MP3, AAC, …) - -Commerce: - - Customer — 59 customers from 24 countries - - Invoice — 412 purchase invoices - - InvoiceLine — 2,240 line items (linked to Invoice and Track) - -Staff: - - Employee — 8 employees with reporting hierarchy - -Playlists: - - Playlist — 18 playlists - - PlaylistTrack — join table linking Playlist ↔ Track -``` - -### "What does the Customer table look like?" - -1. Call `sql_get_schema` with `tables: "Customer"` -2. Present columns with types and notes: - -``` -Customer table: - CustomerId INTEGER PK - FirstName TEXT - LastName TEXT - Company TEXT (nullable) - Address TEXT - City TEXT - State TEXT (nullable) - Country TEXT - PostalCode TEXT (nullable) - Phone TEXT (nullable) - Fax TEXT (nullable) - Email TEXT - SupportRepId INTEGER FK → Employee.EmployeeId - -Sample rows show customers from Brazil, Germany, and Canada. -``` - -### "How are artists connected to sales?" - -Map the full JOIN path: - -``` -Artist (ArtistId) - ↓ 1:many -Album (ArtistId, AlbumId) - ↓ 1:many -Track (AlbumId, TrackId) - ↓ 1:many -InvoiceLine (TrackId, UnitPrice, Quantity) - ↓ many:1 -Invoice (InvoiceId, Total) -``` - -Then suggest using the **query-writing** skill to write the aggregation query. diff --git a/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md deleted file mode 100644 index 2bacd0c95..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -name: query-optimizer -description: > - SQL query optimisation specialist. Reviews existing queries for correctness, clarity, and performance. Suggests index strategies, rewrites inefficient JOINs, and explains query plans. Delegate to this agent when a query returns unexpected results, runs slowly, or when the user asks for query optimisation or a second opinion on complex SQL. -maxIters: 8 ---- - -You are an expert SQL query optimiser for SQLite databases. - -## Your Responsibilities - -1. **Understand the question** — ask the user to provide the original query and the problem - (wrong results, slow execution, hard to read). -2. **Inspect the schema** — use `sql_get_schema` to verify table structures involved in the query. -3. **Analyse the query**: - - Check JOIN conditions for correctness - - Look for missing GROUP BY columns - - Identify Cartesian products (missing ON clause) - - Spot opportunities to push filters earlier (WHERE vs HAVING) - - Detect fan-out caused by 1:many JOINs before aggregation -4. **Rewrite the query** — produce a corrected and/or optimised version. -5. **Explain the changes** — list what was wrong and why each change helps. -6. **Validate** — run both the original and optimised queries if possible and compare results. - -## Output Format - -``` -## Original Query - - -## Issues Found -1. -2. ... - -## Optimised Query - - -## Explanation - - -## Validation -Original: -Optimised: -``` - -## Rules - -- Never modify the user's data — SELECT only. -- Confirm correctness first; performance is secondary. -- For SQLite specifically: - - Prefer covering indexes over table scans for large tables. - - Use `WITH` (CTEs) to make complex queries readable. - - Avoid correlated subqueries in WHERE clauses; rewrite as JOINs. diff --git a/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md b/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md deleted file mode 100644 index 869208134..000000000 --- a/agentscope-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: schema-analyst -description: Deep schema analysis specialist. Produces comprehensive documentation of the database schema including entity-relationship diagrams (text), table purposes, column semantics, foreign key chains, and index recommendations. Delegate to this agent when the user requests a full data model overview, wants to understand how tables relate, or needs schema documentation generated. -maxIters: 10 ---- - -You are a database schema analyst specialised in documenting and explaining relational data models. - -## Your Responsibilities - -1. **Discover** all tables using `sql_list_tables`. -2. **Inspect** every table with `sql_get_schema` to record columns, types, and foreign keys. -3. **Map relationships** — identify 1:many and many:many (via join tables) relationships. -4. **Describe purpose** — explain what each table represents in business terms. -5. **Produce documentation** — write a clear, structured schema reference the user can save. - -## Output Format - -Structure your analysis as: - -``` -# Database Schema Analysis - -## Summary - - -## Tables - -### -**Purpose:** -**Rows:** - -| Column | Type | Notes | -|--------|------|-------| -| ... | ... | ... | - -**Relationships:** -- - ---- -``` - -Repeat for every table, then close with an Entity Relationship Diagram in text format. - -## Rules - -- Be thorough — inspect every table, not just the ones that seem important. -- Do not guess column types; verify them with `sql_get_schema`. -- Keep explanations accessible to non-technical stakeholders. -- If asked to save the output, write it to `knowledge/SCHEMA_ANALYSIS.md` in the workspace. diff --git a/agentscope-examples/harness-example-remote/pom.xml b/agentscope-examples/harness-example-remote/pom.xml deleted file mode 100644 index cf763acfd..000000000 --- a/agentscope-examples/harness-example-remote/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - 4.0.0 - - io.agentscope - agentscope-examples - ${revision} - ../pom.xml - - - AgentScope Java - Harness Remote Filesystem Example - io.agentscope.examples - harness-example-remote - jar - Spring Boot Data Agent using RemoteFilesystemSpec (composite + shared store; docs/zh/harness/filesystem.md 模式一). For sandbox (模式二) see harness-example-sandbox. - - - - - org.springframework.boot - spring-boot-dependencies - ${spring.boot.version} - pom - import - - - - - - - io.agentscope - agentscope-harness - - - org.xerial - sqlite-jdbc - 3.47.2.0 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - org.springframework.boot - spring-boot-starter-web - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring.boot.version} - - - - repackage - - - - - - - diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java deleted file mode 100644 index 698bc1fbb..000000000 --- a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.remote; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -/** - * HTTP API for the remote-store Data Agent ({@code RemoteFilesystemSpec} / filesystem.md 模式一). - * - *
{@code
- * curl -X POST http://localhost:8788/query \
- *   -H 'Content-Type: application/json' \
- *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
- * }
- */ -@RestController -public class DataAgentController { - - private final DataAgentService agentService; - - public DataAgentController(DataAgentService agentService) { - this.agentService = agentService; - } - - @GetMapping("/") - public String index() { - return "Remote-store Data Agent (RemoteFilesystemSpec) — POST /query with" - + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; - } - - @PostMapping("/query") - public ResponseEntity query(@RequestBody QueryRequest request) { - if (blank(request.sessionId())) { - return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); - } - if (blank(request.userId())) { - return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); - } - if (blank(request.question())) { - return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); - } - String answer = - agentService.query(request.sessionId(), request.userId(), request.question()); - return ResponseEntity.ok(QueryResponse.ok(answer)); - } - - private static boolean blank(String s) { - return s == null || s.isBlank(); - } - - record QueryRequest(String sessionId, String userId, String question) {} - - record QueryResponse(String answer, String error) { - static QueryResponse ok(String answer) { - return new QueryResponse(answer, null); - } - - static QueryResponse error(String error) { - return new QueryResponse(null, error); - } - } -} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java deleted file mode 100644 index 6f0612e7c..000000000 --- a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.remote; - -import io.agentscope.core.agent.RuntimeContext; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.model.DashScopeChatModel; -import io.agentscope.core.model.Model; -import io.agentscope.core.session.InMemorySession; -import io.agentscope.core.session.Session; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.examples.harness.remote.data.SqliteTool; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; -import io.agentscope.harness.agent.store.InMemoryStore; -import jakarta.annotation.PostConstruct; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -/** - * Data Agent using {@link RemoteFilesystemSpec} — the composite + shared-store mode described in - * {@code docs/zh/harness/filesystem.md} as 模式一 (and in {@link - * io.agentscope.harness.agent.HarnessAgent.Builder#filesystem(RemoteFilesystemSpec)} as - * Mode 1). - * - *

Not sandbox mode: there is no {@code ShellExecuteTool}. For 模式二 - * / Mode 2 (sandbox + shell in isolation), use {@code harness-example-sandbox}. - * - *

Shared components (simulate Redis + multi-replica in one JVM): - * - *

    - *
  • {@link InMemoryStore} — {@link io.agentscope.harness.agent.store.BaseStore} for - * MEMORY.md, memory/, session paths, and {@code knowledge/} - *
  • {@link InMemorySession} — non-local {@link Session} required by Harness when using remote - * filesystem spec (production would use RedisSession, etc.) - *
- */ -@Service -public class DataAgentService { - - private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); - - private static final String AGENT_NAME = "data-agent"; - private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; - private static final String SYS_PROMPT = - "You are a Text-to-SQL agent with access to the Chinook music store database." - + " Use the sql_* tools. This deployment has no shell tool — use read_file," - + " write_file, grep_files for workspace files. Answer clearly."; - - private Path hostWorkspace; - private Path dbPath; - private Model model; - private RemoteFilesystemSpec remoteSpec; - private Session appSession; - - @PostConstruct - void init() throws Exception { - hostWorkspace = WorkspaceClasspathMaterializer.materialize(); - dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); - model = buildModel(); - - InMemoryStore store = new InMemoryStore(); - remoteSpec = - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.USER) - .addSharedPrefix("knowledge/"); - appSession = new InMemorySession(); - - log.info( - "DataAgentService ready (RemoteFilesystemSpec): workspace={} db={}", - hostWorkspace, - dbPath); - } - - public String query(String sessionId, String userId, String question) { - Toolkit toolkit = new Toolkit(); - toolkit.registerTool(new SqliteTool(dbPath)); - - HarnessAgent agent = - HarnessAgent.builder() - .name(AGENT_NAME) - .model(model) - .workspace(hostWorkspace) - .filesystem(remoteSpec) - .session(appSession) - .sysPrompt(SYS_PROMPT) - .toolkit(toolkit) - .enableAgentTracingLog(true) - .build(); - - RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); - Msg reply = agent.call(userMsg, ctx).block(); - return reply != null ? reply.getTextContent() : "(no response)"; - } - - private static Model buildModel() { - String apiKey = System.getenv("DASHSCOPE_API_KEY"); - if (apiKey == null || apiKey.isBlank()) { - throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); - } - String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); - log.info("Using model: {}", modelName); - return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) - .build(); - } - - private static Path materialiseChinook(Path target) throws Exception { - if (Files.exists(target)) { - return target.toAbsolutePath(); - } - try (InputStream in = - DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { - if (in == null) { - throw new IllegalStateException( - "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); - } - Path parent = target.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); - } - return target.toAbsolutePath(); - } - - private static String envOrDefault(String name, String defaultValue) { - String v = System.getenv(name); - return (v != null && !v.isBlank()) ? v : defaultValue; - } -} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java deleted file mode 100644 index 9ab7754fe..000000000 --- a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.remote; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Spring Boot entry for the remote-store Data Agent example. - * - *

Set {@code DASHSCOPE_API_KEY}. Default port {@code 8788} (see {@code application.properties}). - * - *

This module demonstrates {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec} - * ({@code docs/zh/harness/filesystem.md} 模式一). Sandbox (模式二) - * is {@code harness-example-sandbox}. - */ -@SpringBootApplication -public class HarnessRemoteApplication { - - public static void main(String[] args) { - SpringApplication.run(HarnessRemoteApplication.class, args); - } -} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java deleted file mode 100644 index 04710d7fa..000000000 --- a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.remote; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; - -/** - * Copies {@code classpath:workspace/...} into a temp directory used as the local side of the - * composite workspace for {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec}. - */ -public final class WorkspaceClasspathMaterializer { - - private static final String[] CLASSPATH_FILES = { - "classpath:workspace/AGENTS.md", - "classpath:workspace/skills/query-writing/SKILL.md", - "classpath:workspace/knowledge/KNOWLEDGE.md", - }; - - private WorkspaceClasspathMaterializer() {} - - /** - * Materializes bundled workspace resources to disk. - * - * @return absolute path to the host workspace directory - */ - public static Path materialize() { - try { - Path dir = Files.createTempDirectory("remote-data-agent-host-workspace-"); - PathMatchingResourcePatternResolver resolver = - new PathMatchingResourcePatternResolver(); - for (String location : CLASSPATH_FILES) { - Resource resource = resolver.getResource(location); - if (!resource.exists()) { - throw new IllegalStateException("Missing required resource: " + location); - } - String pathWithinWorkspace = location.substring("classpath:workspace/".length()); - Path target = dir.resolve(pathWithinWorkspace); - Files.createDirectories(target.getParent()); - try (InputStream in = resource.getInputStream()) { - Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); - } - } - return dir.toAbsolutePath().normalize(); - } catch (IOException e) { - throw new UncheckedIOException("Failed to materialize workspace from classpath", e); - } - } -} diff --git a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java b/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java deleted file mode 100644 index c9b5e5d3b..000000000 --- a/agentscope-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.remote.data; - -import io.agentscope.core.tool.Tool; -import io.agentscope.core.tool.ToolParam; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.StringJoiner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * SQLite helpers for the remote-store Data Agent — same tool names and behaviour as {@code - * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. - * - *

Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. - */ -public class SqliteTool { - - private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); - - private static final int MAX_ROWS = 50; - - private static final int SAMPLE_ROWS = 3; - - private final String jdbcUrl; - - public SqliteTool(Path dbPath) { - this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); - } - - @Tool( - name = "sql_list_tables", - description = - "Lists all tables in the SQLite database. Use this first to discover what data" - + " is available before writing queries.") - public String listTables() { - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - List tables = new ArrayList<>(); - try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { - while (rs.next()) { - tables.add(rs.getString("TABLE_NAME")); - } - } - if (tables.isEmpty()) { - return "No tables found in the database."; - } - return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); - } catch (SQLException e) { - log.warn("sql_list_tables failed", e); - return "Error listing tables: " + e.getMessage(); - } - } - - @Tool( - name = "sql_get_schema", - description = - "Returns the schema (column names, types, keys) and sample rows for one or more" - + " tables. Pass a comma-separated list of table names to inspect" - + " multiple tables at once.") - public String getSchema( - @ToolParam( - name = "tables", - description = - "Comma-separated table names, e.g. \"Artist,Album,Track\"") - String tables) { - StringBuilder sb = new StringBuilder(); - for (String table : tables.split(",")) { - table = table.strip(); - if (table.isEmpty()) continue; - sb.append(describeTable(table)).append("\n\n"); - } - return sb.toString().strip(); - } - - @Tool( - name = "sql_execute_query", - description = - "Executes a read-only SELECT query against the SQLite database and returns the" - + " results as a formatted table. Never use DML statements" - + " (INSERT / UPDATE / DELETE / DROP).") - public String executeQuery( - @ToolParam(name = "query", description = "A valid SQLite SELECT statement") - String query) { - String trimmed = query.strip(); - if (!trimmed.toUpperCase().startsWith("SELECT")) { - return "Error: only SELECT statements are allowed. Received: " + trimmed; - } - try (Connection conn = DriverManager.getConnection(jdbcUrl); - Statement stmt = conn.createStatement()) { - stmt.setMaxRows(MAX_ROWS); - try (ResultSet rs = stmt.executeQuery(trimmed)) { - return formatResultSet(rs); - } - } catch (SQLException e) { - log.warn("sql_execute_query failed for: {}", trimmed, e); - return "Error executing query: " + e.getMessage(); - } - } - - private String describeTable(String tableName) { - StringBuilder sb = new StringBuilder(); - sb.append("## ").append(tableName).append("\n\n"); - - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - - List pks = new ArrayList<>(); - try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { - while (rs.next()) { - pks.add(rs.getString("COLUMN_NAME")); - } - } - - List fks = new ArrayList<>(); - try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { - while (rs.next()) { - fks.add( - rs.getString("FKCOLUMN_NAME") - + " → " - + rs.getString("PKTABLE_NAME") - + "." - + rs.getString("PKCOLUMN_NAME")); - } - } - - sb.append("### Columns\n"); - try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { - while (rs.next()) { - String col = rs.getString("COLUMN_NAME"); - String type = rs.getString("TYPE_NAME"); - String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; - String pk = pks.contains(col) ? " [PK]" : ""; - sb.append("- ") - .append(col) - .append(" (") - .append(type) - .append(nullable) - .append(pk) - .append(")\n"); - } - } - - if (!fks.isEmpty()) { - sb.append("\n### Foreign Keys\n"); - fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); - } - - sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); - try (Statement stmt = conn.createStatement()) { - stmt.setMaxRows(SAMPLE_ROWS); - try (ResultSet rs = - stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { - sb.append(formatResultSet(rs)); - } - } - - } catch (SQLException e) { - sb.append("Error describing table '") - .append(tableName) - .append("': ") - .append(e.getMessage()); - } - return sb.toString(); - } - - private static String formatResultSet(ResultSet rs) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int cols = meta.getColumnCount(); - - StringJoiner header = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - header.add(meta.getColumnName(i)); - } - - String separator = "-".repeat(header.toString().length()); - - List rows = new ArrayList<>(); - int count = 0; - while (rs.next()) { - StringJoiner row = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - Object val = rs.getObject(i); - row.add(val == null ? "NULL" : val.toString()); - } - rows.add(row.toString()); - count++; - } - - if (rows.isEmpty()) { - return "(no rows returned)"; - } - - StringBuilder sb = new StringBuilder(); - sb.append(header).append("\n").append(separator).append("\n"); - rows.forEach(r -> sb.append(r).append("\n")); - if (count >= MAX_ROWS) { - sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); - } - return sb.toString(); - } -} diff --git a/agentscope-examples/harness-example-remote/src/main/resources/application.properties b/agentscope-examples/harness-example-remote/src/main/resources/application.properties deleted file mode 100644 index a0192ca20..000000000 --- a/agentscope-examples/harness-example-remote/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.application.name=harness-example-remote -server.port=8788 diff --git a/agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite b/agentscope-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite deleted file mode 100644 index f385c2651f80914c3b93c62431b0b000465a921b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D diff --git a/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md deleted file mode 100644 index 2f30165e6..000000000 --- a/agentscope-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Chinook Knowledge (remote-store demo) - -This Data Agent uses the Chinook SQLite sample database. - -Primary entities: -- `Artist` -> `Album` -> `Track` -- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` - -Guidance: -- Always discover schema with `sql_list_tables` and `sql_get_schema`. -- Use read-only `SELECT` statements. -- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md deleted file mode 100644 index c8315594c..000000000 --- a/agentscope-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: query-writing -description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). ---- - -# Query writing (remote-store) - -1. Call `sql_list_tables` if you do not yet know table names. -2. Call `sql_get_schema` for each table you join or filter on. -3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). -4. Summarise results in plain language. - -See the full skill in `agentscope-examples/harness-example` under -`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. diff --git a/agentscope-examples/harness-example-sandbox/pom.xml b/agentscope-examples/harness-example-sandbox/pom.xml deleted file mode 100644 index 88e76a3e4..000000000 --- a/agentscope-examples/harness-example-sandbox/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - 4.0.0 - - io.agentscope - agentscope-examples - ${revision} - ../pom.xml - - - AgentScope Java - Harness Sandbox Example - io.agentscope.examples - harness-example-sandbox - jar - Spring Boot app: in-memory sandbox Data Agent (text-to-SQL pattern from harness-example), USER isolation, shared store, projected workspace - - - - - org.springframework.boot - spring-boot-dependencies - ${spring.boot.version} - pom - import - - - - - - - io.agentscope - agentscope-harness - - - - org.xerial - sqlite-jdbc - 3.47.2.0 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - org.springframework.boot - spring-boot-starter-web - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring.boot.version} - - - - repackage - - - - - - - diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java deleted file mode 100644 index 68b834ac0..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -/** - * HTTP entry point for the sandbox Data Agent. - * - *
- * GET  /        — usage hint
- * POST /query   — ask the data agent a question
- * 
- * - *

Example: - * - *

{@code
- * curl -X POST http://localhost:8787/query \
- *   -H 'Content-Type: application/json' \
- *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
- * }
- */ -@RestController -public class DataAgentController { - - private final DataAgentService agentService; - - public DataAgentController(DataAgentService agentService) { - this.agentService = agentService; - } - - @GetMapping("/") - public String index() { - return "Sandbox Data Agent — POST /query with" - + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; - } - - /** - * Processes a natural-language question about the Chinook database. - * - *

The agent sandbox and memory are scoped by {@code userId}: the same user always resumes - * the same sandbox (and sees the same {@code MEMORY.md}) regardless of {@code sessionId}. The - * conversation context (messages) is scoped by {@code sessionId}. - */ - @PostMapping("/query") - public ResponseEntity query(@RequestBody QueryRequest request) { - if (blank(request.sessionId())) { - return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); - } - if (blank(request.userId())) { - return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); - } - if (blank(request.question())) { - return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); - } - String answer = - agentService.query(request.sessionId(), request.userId(), request.question()); - return ResponseEntity.ok(QueryResponse.ok(answer)); - } - - private static boolean blank(String s) { - return s == null || s.isBlank(); - } - - record QueryRequest(String sessionId, String userId, String question) {} - - record QueryResponse(String answer, String error) { - static QueryResponse ok(String answer) { - return new QueryResponse(answer, null); - } - - static QueryResponse error(String error) { - return new QueryResponse(null, error); - } - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java deleted file mode 100644 index 5fdd1f5dc..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import io.agentscope.core.agent.RuntimeContext; -import io.agentscope.core.message.Msg; -import io.agentscope.core.message.MsgRole; -import io.agentscope.core.model.DashScopeChatModel; -import io.agentscope.core.model.Model; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.examples.harness.sandbox.data.SqliteTool; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; -import io.agentscope.examples.harness.sandbox.support.SharedInMemorySandboxStateStore; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import jakarta.annotation.PostConstruct; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -/** - * Data Agent service: Chinook text-to-SQL with sandbox isolation. - * - *

Infrastructure shared across all requests (initialized once on startup): - * - *

    - *
  • {@link InMemorySandboxClient} — local-process sandbox (stands in for Docker in - * production) - *
  • {@link SharedInMemorySandboxStateStore} — shared state store (stands in for Redis) - *
  • {@link InMemorySandboxFilesystemSpec} with {@link IsolationScope#USER} — each unique - * {@code userId} gets its own sandbox; the sandbox persists across sessions for that user - *
- * - *

A fresh {@link HarnessAgent} is built per request so concurrent calls with different - * {@code userId} values do not interfere. The heavy shared state (sandbox instance, workspace - * files, memory) lives in the stores above, not in the agent object itself. - * - *

Required environment variables: - * - *

    - *
  • {@code DASHSCOPE_API_KEY} — DashScope API key - *
  • {@code AGENTSCOPE_MODEL} — model name (default: {@code qwen-max}) - *
- */ -@Service -public class DataAgentService { - - private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); - - private static final String AGENT_NAME = "data-agent"; - private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; - private static final String SYS_PROMPT = - "You are a Text-to-SQL agent with access to the Chinook music store database." - + " Use the sql_* tools to explore the schema and run read-only SELECT queries." - + " Follow the query-writing skill and answer clearly in plain language."; - - private Path hostWorkspace; - private Path dbPath; - private Model model; - private InMemorySandboxFilesystemSpec fsSpec; - private SharedInMemorySandboxStateStore stateStore; - - @PostConstruct - void init() throws Exception { - hostWorkspace = WorkspaceClasspathMaterializer.materialize(); - dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); - model = buildModel(); - - stateStore = new SharedInMemorySandboxStateStore(); - fsSpec = new InMemorySandboxFilesystemSpec(new InMemorySandboxClient()); - fsSpec.isolationScope(IsolationScope.USER).sandboxStateStore(stateStore); - - log.info("DataAgentService ready: workspace={} db={}", hostWorkspace, dbPath); - } - - /** - * Processes a user question with the data agent. - * - *
    - *
  • {@code sessionId} — scopes the conversation history (same session = same chat context) - *
  • {@code userId} — scopes the sandbox workspace and memory (same user = shared sandbox - * and MEMORY.md across sessions) - *
- * - * @param sessionId session identifier - * @param userId user identifier - * @param question natural-language question about the Chinook database - * @return agent answer - */ - public String query(String sessionId, String userId, String question) { - Toolkit toolkit = new Toolkit(); - toolkit.registerTool(new SqliteTool(dbPath)); - - HarnessAgent agent = - HarnessAgent.builder() - .name(AGENT_NAME) - .model(model) - .workspace(hostWorkspace) - .filesystem(fsSpec) - .sysPrompt(SYS_PROMPT) - .toolkit(toolkit) - .enableAgentTracingLog(true) - .build(); - - RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); - Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); - Msg reply = agent.call(userMsg, ctx).block(); - return reply != null ? reply.getTextContent() : "(no response)"; - } - - private static Model buildModel() { - String apiKey = System.getenv("DASHSCOPE_API_KEY"); - if (apiKey == null || apiKey.isBlank()) { - throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); - } - String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); - log.info("Using model: {}", modelName); - return DashScopeChatModel.builder().apiKey(apiKey).modelName(modelName).stream(true) - .build(); - } - - private static Path materialiseChinook(Path target) throws Exception { - if (Files.exists(target)) { - return target.toAbsolutePath(); - } - try (InputStream in = - DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { - if (in == null) { - throw new IllegalStateException( - "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); - } - Path parent = target.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); - } - return target.toAbsolutePath(); - } - - private static String envOrDefault(String name, String defaultValue) { - String v = System.getenv(name); - return (v != null && !v.isBlank()) ? v : defaultValue; - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java deleted file mode 100644 index 953e784d8..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Spring Boot entry for the sandbox Data Agent (text-to-SQL) demo. - * - *

Set {@code DASHSCOPE_API_KEY} before starting. Optionally override the model with - * {@code AGENTSCOPE_MODEL} (default: {@code qwen-max}). - * - *

Once started, send questions via: - * - *

- * curl -X POST http://localhost:8787/query \
- *   -H 'Content-Type: application/json' \
- *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are there?"}'
- * 
- */ -@SpringBootApplication -public class HarnessSandboxApplication { - - public static void main(String[] args) { - SpringApplication.run(HarnessSandboxApplication.class, args); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java deleted file mode 100644 index 7c425ed1d..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; - -/** - * Copies known {@code classpath:workspace/...} entries into a temp directory so {@link - * io.agentscope.harness.agent.HarnessAgent} can use it as the host workspace root for sandbox - * projection (e.g. {@code skills/query-writing/} for the Data Agent demo). - */ -public final class WorkspaceClasspathMaterializer { - - private static final String[] CLASSPATH_FILES = { - "classpath:workspace/AGENTS.md", - "classpath:workspace/skills/query-writing/SKILL.md", - "classpath:workspace/knowledge/KNOWLEDGE.md", - }; - - private WorkspaceClasspathMaterializer() {} - - /** - * Materializes bundled workspace resources to disk. - * - * @return absolute path to the host workspace directory (contains {@code AGENTS.md}, - * {@code skills/}, …) - */ - public static Path materialize() { - try { - Path dir = Files.createTempDirectory("data-agent-host-workspace-"); - PathMatchingResourcePatternResolver resolver = - new PathMatchingResourcePatternResolver(); - for (String location : CLASSPATH_FILES) { - Resource resource = resolver.getResource(location); - if (!resource.exists()) { - throw new IllegalStateException("Missing required resource: " + location); - } - String pathWithinWorkspace = location.substring("classpath:workspace/".length()); - Path target = dir.resolve(pathWithinWorkspace); - Files.createDirectories(target.getParent()); - try (InputStream in = resource.getInputStream()) { - Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); - } - } - return dir.toAbsolutePath().normalize(); - } catch (IOException e) { - throw new UncheckedIOException("Failed to materialize workspace from classpath", e); - } - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java deleted file mode 100644 index 9649b157c..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.data; - -import io.agentscope.core.tool.Tool; -import io.agentscope.core.tool.ToolParam; -import java.nio.file.Path; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.StringJoiner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * SQLite helpers for the sandbox Data Agent — same tool names and behaviour as {@code - * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. - * - *

Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. - */ -public class SqliteTool { - - private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); - - private static final int MAX_ROWS = 50; - - private static final int SAMPLE_ROWS = 3; - - private final String jdbcUrl; - - public SqliteTool(Path dbPath) { - this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); - } - - @Tool( - name = "sql_list_tables", - description = - "Lists all tables in the SQLite database. Use this first to discover what data" - + " is available before writing queries.") - public String listTables() { - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - List tables = new ArrayList<>(); - try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { - while (rs.next()) { - tables.add(rs.getString("TABLE_NAME")); - } - } - if (tables.isEmpty()) { - return "No tables found in the database."; - } - return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); - } catch (SQLException e) { - log.warn("sql_list_tables failed", e); - return "Error listing tables: " + e.getMessage(); - } - } - - @Tool( - name = "sql_get_schema", - description = - "Returns the schema (column names, types, keys) and sample rows for one or more" - + " tables. Pass a comma-separated list of table names to inspect" - + " multiple tables at once.") - public String getSchema( - @ToolParam( - name = "tables", - description = - "Comma-separated table names, e.g. \"Artist,Album,Track\"") - String tables) { - StringBuilder sb = new StringBuilder(); - for (String table : tables.split(",")) { - table = table.strip(); - if (table.isEmpty()) continue; - sb.append(describeTable(table)).append("\n\n"); - } - return sb.toString().strip(); - } - - @Tool( - name = "sql_execute_query", - description = - "Executes a read-only SELECT query against the SQLite database and returns the" - + " results as a formatted table. Never use DML statements" - + " (INSERT / UPDATE / DELETE / DROP).") - public String executeQuery( - @ToolParam(name = "query", description = "A valid SQLite SELECT statement") - String query) { - String trimmed = query.strip(); - if (!trimmed.toUpperCase().startsWith("SELECT")) { - return "Error: only SELECT statements are allowed. Received: " + trimmed; - } - try (Connection conn = DriverManager.getConnection(jdbcUrl); - Statement stmt = conn.createStatement()) { - stmt.setMaxRows(MAX_ROWS); - try (ResultSet rs = stmt.executeQuery(trimmed)) { - return formatResultSet(rs); - } - } catch (SQLException e) { - log.warn("sql_execute_query failed for: {}", trimmed, e); - return "Error executing query: " + e.getMessage(); - } - } - - private String describeTable(String tableName) { - StringBuilder sb = new StringBuilder(); - sb.append("## ").append(tableName).append("\n\n"); - - try (Connection conn = DriverManager.getConnection(jdbcUrl)) { - DatabaseMetaData meta = conn.getMetaData(); - - List pks = new ArrayList<>(); - try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { - while (rs.next()) { - pks.add(rs.getString("COLUMN_NAME")); - } - } - - List fks = new ArrayList<>(); - try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { - while (rs.next()) { - fks.add( - rs.getString("FKCOLUMN_NAME") - + " → " - + rs.getString("PKTABLE_NAME") - + "." - + rs.getString("PKCOLUMN_NAME")); - } - } - - sb.append("### Columns\n"); - try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { - while (rs.next()) { - String col = rs.getString("COLUMN_NAME"); - String type = rs.getString("TYPE_NAME"); - String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; - String pk = pks.contains(col) ? " [PK]" : ""; - sb.append("- ") - .append(col) - .append(" (") - .append(type) - .append(nullable) - .append(pk) - .append(")\n"); - } - } - - if (!fks.isEmpty()) { - sb.append("\n### Foreign Keys\n"); - fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); - } - - sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); - try (Statement stmt = conn.createStatement()) { - stmt.setMaxRows(SAMPLE_ROWS); - try (ResultSet rs = - stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { - sb.append(formatResultSet(rs)); - } - } - - } catch (SQLException e) { - sb.append("Error describing table '") - .append(tableName) - .append("': ") - .append(e.getMessage()); - } - return sb.toString(); - } - - private static String formatResultSet(ResultSet rs) throws SQLException { - ResultSetMetaData meta = rs.getMetaData(); - int cols = meta.getColumnCount(); - - StringJoiner header = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - header.add(meta.getColumnName(i)); - } - - String separator = "-".repeat(header.toString().length()); - - List rows = new ArrayList<>(); - int count = 0; - while (rs.next()) { - StringJoiner row = new StringJoiner(" | "); - for (int i = 1; i <= cols; i++) { - Object val = rs.getObject(i); - row.add(val == null ? "NULL" : val.toString()); - } - rows.add(row.toString()); - count++; - } - - if (rows.isEmpty()) { - return "(no rows returned)"; - } - - StringBuilder sb = new StringBuilder(); - sb.append(header).append("\n").append(separator).append("\n"); - rows.forEach(r -> sb.append(r).append("\n")); - if (count >= MAX_ROWS) { - sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); - } - return sb.toString(); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java deleted file mode 100644 index a51409c0b..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.ExecResult; -import io.agentscope.harness.agent.sandbox.Sandbox; -import io.agentscope.harness.agent.sandbox.SandboxState; -import io.agentscope.harness.agent.sandbox.WorkspaceProjectionApplier; -import io.agentscope.harness.agent.sandbox.WorkspaceSpec; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; - -/** - * In-process {@link Sandbox} that uses a local temp directory as the workspace (for examples). - * - *

Applies {@link WorkspaceProjectionApplier} payloads on {@link #start} and extracts tar - * archives in {@link #hydrateWorkspace} so host-projected skills match production behaviour. - */ -public class InMemorySandbox implements Sandbox { - - private final InMemorySandboxState state; - private final Path workspaceDir; - private final AtomicBoolean running = new AtomicBoolean(false); - private final int defaultTimeoutSeconds; - - public InMemorySandbox(InMemorySandboxState state, int defaultTimeoutSeconds) { - this.state = state; - this.workspaceDir = Path.of(state.getWorkspaceRoot()); - this.defaultTimeoutSeconds = defaultTimeoutSeconds; - } - - @Override - public void start() throws Exception { - if (!Files.exists(workspaceDir)) { - Files.createDirectories(workspaceDir); - } - applyWorkspaceProjectionIfChanged(state.getWorkspaceSpec()); - state.setWorkspaceRootReady(true); - running.set(true); - } - - private void applyWorkspaceProjectionIfChanged(WorkspaceSpec spec) throws Exception { - WorkspaceProjectionApplier.ProjectionPayload payload = - WorkspaceProjectionApplier.build(spec); - if (payload == null) { - return; - } - if (Objects.equals(payload.hash(), state.getWorkspaceProjectionHash())) { - return; - } - if (payload.fileCount() > 0) { - try (InputStream archive = new ByteArrayInputStream(payload.tarBytes())) { - hydrateWorkspace(archive); - } - } - state.setWorkspaceProjectionHash(payload.hash()); - } - - @Override - public void stop() throws Exception { - state.setWorkspaceRootReady(true); - running.set(false); - } - - @Override - public void shutdown() throws Exception { - // Leave workspace dir in place for resume in tests - } - - @Override - public void close() throws Exception { - try { - stop(); - } catch (Exception e) { - // best-effort - } - shutdown(); - } - - @Override - public boolean isRunning() { - return running.get(); - } - - @Override - public SandboxState getState() { - return state; - } - - @Override - public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { - int timeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeoutSeconds; - ProcessBuilder pb = new ProcessBuilder("sh", "-c", command); - pb.directory(workspaceDir.toFile()); - pb.redirectErrorStream(false); - Process process = pb.start(); - - boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); - if (!finished) { - process.destroyForcibly(); - return new ExecResult(124, "", "Command timed out after " + timeout + "s", false); - } - - String stdout = new String(process.getInputStream().readAllBytes()); - String stderr = new String(process.getErrorStream().readAllBytes()); - return new ExecResult(process.exitValue(), stdout, stderr, false); - } - - @Override - public InputStream persistWorkspace() throws Exception { - return new ByteArrayInputStream(new byte[1024]); - } - - @Override - public void hydrateWorkspace(InputStream archive) throws Exception { - if (archive == null) { - return; - } - Path root = workspaceDir.normalize(); - try (TarArchiveInputStream tar = new TarArchiveInputStream(archive)) { - TarArchiveEntry entry; - while ((entry = tar.getNextEntry()) != null) { - if (entry.isDirectory()) { - continue; - } - String name = entry.getName(); - if (name.startsWith("/")) { - name = name.substring(1); - } - if (name.isBlank()) { - continue; - } - Path dest = root.resolve(name).normalize(); - if (!dest.startsWith(root)) { - throw new IOException("Tar entry escapes workspace: " + name); - } - Files.createDirectories(dest.getParent()); - try (OutputStream out = Files.newOutputStream(dest)) { - tar.transferTo(out); - } - } - } - } - - public Path getWorkspaceDir() { - return workspaceDir; - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java deleted file mode 100644 index 88b9c6c16..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.agentscope.harness.agent.sandbox.Sandbox; -import io.agentscope.harness.agent.sandbox.SandboxClient; -import io.agentscope.harness.agent.sandbox.SandboxClientOptions; -import io.agentscope.harness.agent.sandbox.SandboxState; -import io.agentscope.harness.agent.sandbox.WorkspaceSpec; -import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; - -/** In-process {@link SandboxClient} that allocates local temp directories as sandboxes. */ -public class InMemorySandboxClient implements SandboxClient { - - private static final ObjectMapper MAPPER = new ObjectMapper(); - private static final int DEFAULT_TIMEOUT_SECONDS = 30; - - private final AtomicInteger createCount = new AtomicInteger(0); - private final AtomicInteger resumeCount = new AtomicInteger(0); - private final Path baseDir; - - public InMemorySandboxClient() { - try { - this.baseDir = Files.createTempDirectory("agentscope-inmemory-sandbox-"); - } catch (IOException e) { - throw new UncheckedIOException( - "Failed to create base temp dir for InMemorySandboxClient", e); - } - } - - @Override - public Sandbox create( - WorkspaceSpec workspaceSpec, - SandboxSnapshotSpec snapshotSpec, - SandboxClientOptions options) { - createCount.incrementAndGet(); - String sessionId = UUID.randomUUID().toString(); - Path workspaceDir = baseDir.resolve(sessionId); - try { - Files.createDirectories(workspaceDir); - } catch (IOException e) { - throw new UncheckedIOException("Failed to create workspace dir", e); - } - - InMemorySandboxState state = new InMemorySandboxState(sessionId, workspaceDir.toString()); - WorkspaceSpec spec = workspaceSpec != null ? workspaceSpec.copy() : new WorkspaceSpec(); - spec.setRoot(workspaceDir.toString()); - state.setWorkspaceSpec(spec); - - return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); - } - - @Override - public Sandbox resume(SandboxState sessionState) { - resumeCount.incrementAndGet(); - InMemorySandboxState state = (InMemorySandboxState) sessionState; - return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); - } - - @Override - public void delete(Sandbox session) { - // no-op - } - - @Override - public String serializeState(SandboxState state) { - try { - InMemorySandboxState s = (InMemorySandboxState) state; - return MAPPER.writeValueAsString(new StateDto(s.getSessionId(), s.getWorkspaceRoot())); - } catch (IOException e) { - throw new UncheckedIOException("Failed to serialize sandbox state", e); - } - } - - @Override - public SandboxState deserializeState(String json) { - try { - StateDto dto = MAPPER.readValue(json, StateDto.class); - InMemorySandboxState state = - new InMemorySandboxState(dto.sessionId(), dto.workspaceRoot()); - state.setWorkspaceRootReady(true); - return state; - } catch (IOException e) { - throw new UncheckedIOException("Failed to deserialize sandbox state", e); - } - } - - public int getCreateCount() { - return createCount.get(); - } - - public int getResumeCount() { - return resumeCount.get(); - } - - public void resetCounts() { - createCount.set(0); - resumeCount.set(0); - } - - record StateDto(String sessionId, String workspaceRoot) {} -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java deleted file mode 100644 index b34b7e5fb..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.SandboxClient; -import io.agentscope.harness.agent.sandbox.SandboxClientOptions; -import io.agentscope.harness.agent.sandbox.WorkspaceSpec; -import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; -import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; - -/** - * {@link SandboxFilesystemSpec} backed by an {@link InMemorySandboxClient}. - * - *

Uses a local temp directory as the sandbox workspace. No Docker or external services are - * required. The {@link InMemorySandboxClient} exposes create/resume counters to illustrate - * {@link io.agentscope.harness.agent.IsolationScope} behaviour. - */ -public class InMemorySandboxFilesystemSpec extends SandboxFilesystemSpec { - - private final InMemorySandboxClient client; - - /** - * Creates a spec backed by the given in-memory sandbox client. - * - * @param client the in-memory client to use for session create/resume - */ - public InMemorySandboxFilesystemSpec(InMemorySandboxClient client) { - this.client = client; - } - - /** - * Creates a spec with a new default {@link InMemorySandboxClient}. - */ - public InMemorySandboxFilesystemSpec() { - this(new InMemorySandboxClient()); - } - - /** - * Returns the underlying {@link InMemorySandboxClient}. - * - * @return the client - */ - public InMemorySandboxClient getClient() { - return client; - } - - @Override - protected SandboxClient createClient() { - return client; - } - - @Override - protected SandboxClientOptions clientOptions() { - return null; - } - - @Override - protected SandboxSnapshotSpec snapshotSpec() { - return null; - } - - @Override - protected WorkspaceSpec workspaceSpec() { - WorkspaceSpec s = new WorkspaceSpec(); - s.setRoot("/workspace"); - return s; - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java deleted file mode 100644 index d2be8fc79..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.SandboxState; - -/** - * In-memory {@link SandboxState} for {@link InMemorySandboxClient}. - */ -public class InMemorySandboxState extends SandboxState { - - private String workspaceRoot; - - public InMemorySandboxState() {} - - public InMemorySandboxState(String sessionId, String workspaceRoot) { - setSessionId(sessionId); - this.workspaceRoot = workspaceRoot; - } - - public String getWorkspaceRoot() { - return workspaceRoot; - } - - public void setWorkspaceRoot(String workspaceRoot) { - this.workspaceRoot = workspaceRoot; - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java b/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java deleted file mode 100644 index 59d06f7c8..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.SandboxIsolationKey; -import io.agentscope.harness.agent.sandbox.SandboxStateStore; -import java.io.IOException; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; - -/** - * In-memory {@link SandboxStateStore} for examples: simulates a shared Redis-style slot map so - * multiple {@link io.agentscope.harness.agent.HarnessAgent} instances can resume the same user's - * sandbox metadata. - */ -public final class SharedInMemorySandboxStateStore implements SandboxStateStore { - - private final ConcurrentHashMap store = new ConcurrentHashMap<>(); - - private static String mapKey(SandboxIsolationKey key) { - return key.getScope().name() + ":" + key.getValue(); - } - - @Override - public Optional load(SandboxIsolationKey key) throws IOException { - String v = store.get(mapKey(key)); - return Optional.ofNullable(v); - } - - @Override - public void save(SandboxIsolationKey key, String json) throws IOException { - store.put(mapKey(key), json); - } - - @Override - public void delete(SandboxIsolationKey key) throws IOException { - store.remove(mapKey(key)); - } -} diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties b/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties deleted file mode 100644 index 37ad2486c..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.application.name=harness-example-sandbox -server.port=8787 diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite b/agentscope-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite deleted file mode 100644 index f385c2651f80914c3b93c62431b0b000465a921b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md deleted file mode 100644 index 1203157cd..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Chinook Knowledge (sandbox demo) - -This Data Agent uses the Chinook SQLite sample database. - -Primary entities: -- `Artist` -> `Album` -> `Track` -- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` - -Guidance: -- Always discover schema with `sql_list_tables` and `sql_get_schema`. -- Use read-only `SELECT` statements. -- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md deleted file mode 100644 index 055899406..000000000 --- a/agentscope-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: query-writing -description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). ---- - -# Query writing (sandbox) - -1. Call `sql_list_tables` if you do not yet know table names. -2. Call `sql_get_schema` for each table you join or filter on. -3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). -4. Summarise results in plain language. - -See the full skill in `agentscope-examples/harness-example` under -`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. From 216a407ba8dd92ea5d6cfa95e41bb956be85eed2 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 18:27:14 +0800 Subject: [PATCH 20/28] code format --- .../io/agentscope/harness/agent/HarnessAgent.java | 4 +--- .../harness/agent/tool/SessionSearchTool.java | 13 +++++++++---- .../agent/memory/session/SessionTreeMirrorTest.java | 3 +-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index cc678146b..9626fe4e8 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -188,9 +188,7 @@ public Flux stream(Msg msg, RuntimeContext ctx) { } private RuntimeContext coreForDelegate() { - return runtimeContext != null - ? runtimeContext - : RuntimeContext.empty(); + return runtimeContext != null ? runtimeContext : RuntimeContext.empty(); } private Mono recoverFromOverflow(List msgs) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java index 7e5b8eafb..f37597afe 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/SessionSearchTool.java @@ -129,7 +129,11 @@ public String sessionList( List sessionFiles = new ArrayList<>(); try (Stream walk = Files.list(sessionDir)) { walk.filter(Files::isRegularFile) - .filter(p -> p.getFileName().toString().endsWith(WorkspaceConstants.SESSION_CONTEXT_EXT)) + .filter( + p -> + p.getFileName() + .toString() + .endsWith(WorkspaceConstants.SESSION_CONTEXT_EXT)) .forEach(sessionFiles::add); } catch (IOException e) { log.debug("Could not list local session dir for agent {}: {}", agentId, e.getMessage()); @@ -218,8 +222,7 @@ private List listLogFiles(String agentId) { } if (agentId != null) { - Path sessionDir = - agentsDir.resolve(agentId).resolve(WorkspaceConstants.SESSIONS_DIR); + Path sessionDir = agentsDir.resolve(agentId).resolve(WorkspaceConstants.SESSIONS_DIR); collectLogFiles(sessionDir, files); return files; } @@ -257,7 +260,9 @@ private void searchInSessionFile( logFile.resolveSibling( logFile.getFileName() .toString() - .replace(WorkspaceConstants.SESSION_LOG_EXT, WorkspaceConstants.SESSION_CONTEXT_EXT)); + .replace( + WorkspaceConstants.SESSION_LOG_EXT, + WorkspaceConstants.SESSION_CONTEXT_EXT)); SessionTree tree = new SessionTree(contextFile, workspaceManager.getWorkspace(), null); tree.load(); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java index 727990e50..c2af8c2ba 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/memory/session/SessionTreeMirrorTest.java @@ -143,8 +143,7 @@ void syncFromRemote_preservesLocalOnlyEntries_notYetPushed() throws Exception { // Write entry-2 locally but don't wait for mirror (still in-flight) SessionTree t2 = new SessionTree(context, workspace, fs); t2.load(); - t2.append( - new SessionEntry.MessageEntry(null, null, null, "ASSISTANT", "entry-2", null)); + t2.append(new SessionEntry.MessageEntry(null, null, null, "ASSISTANT", "entry-2", null)); t2.flush(); // local: entry-1+2; remote may still only have entry-1 // Load a fresh tree — local has entry-1+2 From 787640075522fb008514822c4af0634eb1939028 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 18:27:36 +0800 Subject: [PATCH 21/28] update harness example --- .../harness/common/util/ExampleUtils.java | 2 +- .../harness-example-local/.env.example | 22 ++ .../harness-example-local/README.md | 169 ++++++++++ .../harness-example-local/pom.xml | 63 ++++ .../harness/example/SqliteTool.java | 247 ++++++++++++++ .../harness/example/TextToSqlExample.java | 312 ++++++++++++++++++ .../harness/example/WorkspaceInitializer.java | 126 +++++++ .../main/resources/agentscope.json.example | 24 ++ .../harness/example/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../resources/log4j2.component.properties | 2 + .../src/main/resources/log4j2.xml | 34 ++ .../workspace/knowledge/KNOWLEDGE.md | 187 +++++++++++ .../workspace/skills/query-writing/SKILL.md | 148 +++++++++ .../skills/schema-exploration/SKILL.md | 136 ++++++++ .../workspace/subagents/query-optimizer.md | 53 +++ .../workspace/subagents/schema-analyst.md | 50 +++ .../harness-example-remote/README.md | 92 ++++++ .../harness-example-remote/pom.xml | 83 +++++ .../harness/remote/DataAgentController.java | 79 +++++ .../harness/remote/DataAgentService.java | 149 +++++++++ .../remote/HarnessRemoteApplication.java | 36 ++ .../WorkspaceClasspathMaterializer.java | 68 ++++ .../harness/remote/data/SqliteTool.java | 225 +++++++++++++ .../src/main/resources/application.properties | 2 + .../harness/remote/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 + .../workspace/skills/query-writing/SKILL.md | 14 + .../harness-example-sandbox/README.md | 76 +++++ .../harness-example-sandbox/pom.xml | 84 +++++ .../harness/sandbox/DataAgentController.java | 93 ++++++ .../harness/sandbox/DataAgentService.java | 166 ++++++++++ .../sandbox/HarnessSandboxApplication.java | 41 +++ .../WorkspaceClasspathMaterializer.java | 70 ++++ .../harness/sandbox/data/SqliteTool.java | 225 +++++++++++++ .../sandbox/support/InMemorySandbox.java | 170 ++++++++++ .../support/InMemorySandboxClient.java | 0 .../InMemorySandboxFilesystemSpec.java | 0 .../sandbox/support/InMemorySandboxState.java | 0 .../SharedInMemorySandboxStateStore.java | 52 +++ .../src/main/resources/application.properties | 2 + .../harness/sandbox/chinook-default.sqlite | Bin 0 -> 1007616 bytes .../workspace/knowledge/KNOWLEDGE.md | 12 + .../workspace/skills/query-writing/SKILL.md | 14 + .../harness/example/QuickstartExample.java | 2 +- .../harness/example/TextToSqlExample.java | 2 +- .../pom.xml | 2 +- .../src/main/docker/python-sandbox/Dockerfile | 0 .../sandbox/DockerPythonSandboxExample.java | 2 +- .../sandbox/DockerPythonSandboxImage.java | 0 .../sandbox/HarnessSandboxExampleApp.java | 0 ...calFilesystemPersonalAssistantExample.java | 0 ...RemoteFilesystemIsolationScopeExample.java | 0 ...andboxFilesystemIsolationScopeExample.java | 0 .../sandbox/support/InMemorySandbox.java | 0 .../support/InMemorySandboxClient.java | 122 +++++++ .../InMemorySandboxFilesystemSpec.java | 81 +++++ .../sandbox/support/InMemorySandboxState.java | 41 +++ .../sandbox/DockerPythonSandboxImageTest.java | 0 agentscope-examples/harness-examples/pom.xml | 5 +- 59 files changed, 3591 insertions(+), 6 deletions(-) create mode 100644 agentscope-examples/harness-examples/harness-example-local/.env.example create mode 100644 agentscope-examples/harness-examples/harness-example-local/README.md create mode 100644 agentscope-examples/harness-examples/harness-example-local/pom.xml create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.component.properties create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md create mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md create mode 100644 agentscope-examples/harness-examples/harness-example-remote/README.md create mode 100644 agentscope-examples/harness-examples/harness-example-remote/pom.xml create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/resources/application.properties create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/README.md create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/pom.xml create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java rename agentscope-examples/harness-examples/{harness-sandbox => harness-example-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-example-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-example-sandbox}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java (100%) create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/application.properties create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md create mode 100644 agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/pom.xml (97%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/docker/python-sandbox/Dockerfile (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java (99%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java (100%) rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java (100%) create mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java create mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java create mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java rename agentscope-examples/harness-examples/{harness-sandbox => harness-sandbox-docker}/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java (100%) diff --git a/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java index fef614000..a2c62e025 100644 --- a/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java +++ b/agentscope-examples/harness-examples/harness-example-common/src/main/java/io/agentscope/examples/harness/common/util/ExampleUtils.java @@ -17,6 +17,7 @@ import io.agentscope.core.agent.Agent; import io.agentscope.core.agent.EventType; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.agent.StreamOptions; import io.agentscope.core.message.ContentBlock; import io.agentscope.core.message.Msg; @@ -24,7 +25,6 @@ import io.agentscope.core.message.TextBlock; import io.agentscope.core.message.ThinkingBlock; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/agentscope-examples/harness-examples/harness-example-local/.env.example b/agentscope-examples/harness-examples/harness-example-local/.env.example new file mode 100644 index 000000000..3a20c5633 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/.env.example @@ -0,0 +1,22 @@ +# ───────────────────────────────────────────────────────────── +# AgentScope Harness Example — Environment Variables +# Copy this file to .env and fill in your values. +# ───────────────────────────────────────────────────────────── + +# Required: DashScope API key (https://dashscope.aliyun.com/) +DASHSCOPE_API_KEY=your_api_key_here + +# Optional: LLM model to use (default: qwen-max) +# Other options: qwen-plus, qwen-turbo, qwen-long +AGENTSCOPE_MODEL=qwen-max + +# Optional: path to the Chinook SQLite database (default: chinook.db). +# If this file does not exist, the example copies the bundled sample from the JAR (no curl needed). +AGENTSCOPE_DB_PATH=chinook.db + +# Optional: workspace directory (default: .agentscope/workspace) +# Modify the files here to customise agent behaviour without recompiling. +AGENTSCOPE_WORKSPACE=.agentscope/workspace + +# Optional: Log4j2 level for io.agentscope loggers (default: INFO). Example: DEBUG, TRACE +# AGENTSCOPE_LOG_LEVEL=DEBUG diff --git a/agentscope-examples/harness-examples/harness-example-local/README.md b/agentscope-examples/harness-examples/harness-example-local/README.md new file mode 100644 index 000000000..342fa42e0 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/README.md @@ -0,0 +1,169 @@ +# harness-example-local — Filesystem **模式三(本机 + 宿主 Shell)** + +本模块是 **CLI 版 Chinook Text-to-SQL** 示例(`TextToSqlExample`),演示 **`HarnessAgent` 不显式配置 `filesystem(...)`** 时的默认行为:与 [`docs/zh/harness/filesystem.md`](../../docs/zh/harness/filesystem.md) 中的 **模式三**(以及 `HarnessAgent.Builder#filesystem(LocalFilesystemSpec)` / 源码注释 **Mode 3**)一致。 + +--- + +## 三种 Filesystem 示例对照 + +| 模式 | 文档(中文) | 典型 `HarnessAgent` 配置 | 本仓库模块 | +|------|----------------|---------------------------|------------| +| **模式一** | 复合 + 共享存储 | `.filesystem(new RemoteFilesystemSpec(store)...)` + 分布式 `Session` | [`harness-example-remote`](../harness-example-remote/README.md) | +| **模式二** | 沙箱 | `.filesystem(sandboxFilesystemSpec)` + `SandboxStateStore` 等 | [`harness-example-sandbox`](../harness-example-sandbox/README.md) | +| **模式三** | 本机 + shell | **不写** `filesystem(...)`,或 `.filesystem(new LocalFilesystemSpec())` | **本模块** | + +--- + +## 模式三在本示例里如何体现 + +`TextToSqlExample` 构建 Agent 时**没有**调用 `.filesystem(...)`: + +```java +HarnessAgent agent = + HarnessAgent.builder() + .name("text-to-sql") + .sysPrompt("...") + .model(modelId) // 例如 "dashscope:qwen-max",经 ModelRegistry 解析 + .workspace(workspace) + .enableAgentTracingLog(true) + .toolkit(toolkit) + .build(); +``` + +`HarnessAgent` 内部 `resolveFilesystem(...)` 在三种 Spec 都未配置时,**直接**返回 **`LocalFilesystemWithShell(workspace, namespaceFactory)`** —— 工作区根在本地目录,**`ShellExecuteTool` 在宿主上执行 `sh -c`**。这与「显式 `new LocalFilesystemSpec().toFilesystem(...)` 且保持默认参数」在能力上等价(显式 Spec 用于调节超时、`virtualMode`、环境变量等)。 + +**后果(设计上的取舍)**: + +- 适合 **单机 / 信任环境 / 本地开发**。 +- **不适合**把不受信 shell 暴露给多租户;也不自带跨副本的 `MEMORY.md` 共享(与模式一不同)。 + +--- + +## 业务与仓库布局(CLI) + +- **入口**:`io.agentscope.harness.example.TextToSqlExample` +- **工作区**:`WorkspaceInitializer` 将 `src/main/resources/workspace/` 解压到磁盘(默认 `.agentscope/workspace`)。 +- **工具**:`SqliteTool`(`sql_list_tables` / `sql_get_schema` / `sql_execute_query`)通过 `Toolkit` 注册。 +- **Chinook**:classpath 自带 `chinook-default.sqlite`,首次运行可复制到 `AGENTSCOPE_DB_PATH`(默认 `chinook.db`)。 + +详细目录树与自定义方式见下文「项目布局」与「自定义 Agent」。 + +--- + +## 快速开始 + +### 1. 构建 + +```bash +cd agentscope-java +mvn -pl agentscope-examples/harness-example-local -am package -DskipTests +``` + +### 2. 环境变量 + +```bash +export DASHSCOPE_API_KEY=your_key_here +# 可选:AGENTSCOPE_MODEL(默认 qwen-max)、AGENTSCOPE_WORKSPACE、AGENTSCOPE_DB_PATH +``` + +或复制 `.env.example` → `.env` 后自行 `export`。 + +### 3. 运行 + +本模块为**普通 JAR**(非 Spring Boot fat jar),需把 **`target/classes` + 依赖 classpath** 一并传给 `java`。 + +在 **`agentscope-examples/harness-example-local`** 目录下: + +```bash +mvn package -DskipTests +export CP="target/classes:$(mvn -q -DincludeScope=runtime dependency:build-classpath -Dmdep.outputFile=/dev/stdout)" +java -cp "$CP" io.agentscope.harness.example.TextToSqlExample +``` + +交互(无参数);单次问答可在末尾追加问题字符串,例如: + +```bash +java -cp "$CP" io.agentscope.harness.example.TextToSqlExample "What are the top 5 best-selling artists?" +``` + +从仓库根目录构建时: + +```bash +cd agentscope-java +mvn -pl agentscope-examples/harness-example-local -am package -DskipTests +cd agentscope-examples/harness-example-local +export CP="target/classes:$(mvn -q -DincludeScope=runtime dependency:build-classpath -Dmdep.outputFile=/dev/stdout)" +java -cp "$CP" io.agentscope.harness.example.TextToSqlExample +``` + +--- + +## 项目布局(节选) + +``` +agentscope-examples/harness-example-local/ +├── pom.xml +├── .env.example +├── README.md +└── src/main/ + ├── java/io/agentscope/harness/example/ + │ ├── TextToSqlExample.java + │ ├── SqliteTool.java + │ └── WorkspaceInitializer.java + └── resources/ + ├── log4j2.xml + ├── io/agentscope/harness/example/chinook-default.sqlite + └── workspace/ + ├── AGENTS.md + ├── MEMORY.md + ├── knowledge/KNOWLEDGE.md + ├── skills/... + └── subagents/... +``` + +--- + +## 调用与 `RuntimeContext` + +```java +RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); +Msg reply = agent.call(Msg.builder().role(MsgRole.USER).textContent(question).build(), ctx).block(); +``` + +`sessionId` 用于会话级状态与 memory hooks;本 CLI 默认可复用同一 session 以做多轮。 + +--- + +## 日志(Log4j2) + +模块使用 **Log4j2**(`log4j-slf4j2-impl`)。配置见 `src/main/resources/log4j2.xml`。可通过环境变量 **`AGENTSCOPE_LOG_LEVEL`**(如 `DEBUG`)调整 `io.agentscope.*` 日志级别。 + +--- + +## 自定义 Agent + +无需重新编译:直接编辑工作区目录下文件即可。 + +| 文件 | 作用 | +|------|------| +| `AGENTS.md` | 人设与规则 | +| `MEMORY.md` | 预置长期记忆 | +| `knowledge/KNOWLEDGE.md` | 领域知识(如 Chinook schema) | +| `skills/*/SKILL.md` | 技能流程 | +| `subagents/*.md` | 子 Agent 规格 | + +--- + +## 依赖 + +| 依赖 | 用途 | +|------|------| +| `agentscope-harness` | HarnessAgent、工具、Hook、工作区 | +| `jackson-dataformat-yaml` | Skill / subagent 的 YAML front matter | +| `sqlite-jdbc` | `SqliteTool` | + +--- + +## License + +Apache 2.0 — 见仓库根目录 `LICENSE`。 diff --git a/agentscope-examples/harness-examples/harness-example-local/pom.xml b/agentscope-examples/harness-examples/harness-example-local/pom.xml new file mode 100644 index 000000000..0b2e4fc26 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/pom.xml @@ -0,0 +1,63 @@ + + + + + 4.0.0 + + io.agentscope + harness-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Example + harness-example-local + AgentScope Harness Example - Enhanced agent runtime with workspace context, subagent orchestration, memory management, and backend abstraction + + + 2.24.3 + + + + + io.agentscope + agentscope-harness + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + + + org.apache.logging.log4j + log4j-slf4j2-impl + ${log4j2.version} + + + diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java new file mode 100644 index 000000000..84650c783 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/SqliteTool.java @@ -0,0 +1,247 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Custom tool that exposes SQLite database operations to the agent. + * + *

Provides three tools the agent can call: + * + *

    + *
  • {@code sql_list_tables} — list all tables in the database + *
  • {@code sql_get_schema} — describe a table's columns, types, and sample rows + *
  • {@code sql_execute_query} — run a read-only SELECT query and return formatted results + *
+ * + *

This class demonstrates how to wire a domain-specific tool into a {@link + * io.agentscope.harness.agent.HarnessAgent}. Register it via the agent's {@code Toolkit} before + * calling {@link io.agentscope.harness.agent.HarnessAgent.Builder#build()}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + /** Maximum rows returned by {@code sql_execute_query} to prevent context overflow. */ + private static final int MAX_ROWS = 50; + + /** Number of sample rows shown by {@code sql_get_schema}. */ + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + // ------------------------------------------------------------------------- + // Private helpers + // ------------------------------------------------------------------------- + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + // Primary keys + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + // Foreign keys + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + // Columns + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + // Sample rows + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + // Header + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + // Separator + String separator = "-".repeat(header.toString().length()); + + // Rows + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java new file mode 100644 index 000000000..a100520eb --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/TextToSqlExample.java @@ -0,0 +1,312 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import io.agentscope.core.agent.RuntimeContext; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.message.TextBlock; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.harness.agent.HarnessAgent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.UUID; + +/** + * Text-to-SQL example using the AgentScope Harness framework. + * + *

What this example demonstrates

+ * + *
    + *
  • Setting up a workspace directory with the standard harness layout + * (AGENTS.md, skills/, knowledge/, subagents/) + *
  • Wiring a custom tool ({@link SqliteTool}) into the agent's toolkit + *
  • Building a {@link HarnessAgent} with skills auto-loading, memory tools, and subagents + *
  • Calling the agent with a {@link RuntimeContext} (session id, user id) + *
  • Reading questions from the console in a loop (optional one-shot mode if you pass a + * question as program arguments) + *
+ * + *

Prerequisites

+ * + *
    + *
  1. The Chinook sample database is bundled in the JAR under the same package + * as this class. If {@code AGENTSCOPE_DB_PATH} (default {@code chinook.db}) does not exist + * yet, it is copied there automatically — no manual download is required. + *
  2. Set the environment variable {@code DASHSCOPE_API_KEY} (or {@code OPENAI_API_KEY} for + * OpenAI-compatible endpoints). + *
  3. Optionally override defaults via the variables listed in {@code .env.example}. + *
+ * + *

Usage

+ * + *

Run with no arguments to start an interactive session: type a question at + * the {@code >} prompt after startup. Empty line, {@code quit}, {@code exit}, or {@code q} ends + * the session; EOF (Ctrl-D) also exits. + * + *

Pass a question as arguments for a single non-interactive run (exits after + * the answer), e.g. for scripts: + * + *

+ * java -jar harness-example.jar
+ * java -jar harness-example.jar "What are the top 5 best-selling artists?"
+ * java -jar harness-example.jar --new-session "What are the top 5 best-selling artists?"
+ * 
+ * + *

The workspace is initialised under {@code .agentscope/workspace/} relative to the current + * working directory. Modify the files there to customise the agent's behaviour without recompiling. + */ +public class TextToSqlExample { + + // ------------------------------------------------------------------------- + // Environment variable names + // ------------------------------------------------------------------------- + + /** DashScope API key (required). */ + public static final String ENV_API_KEY = "DASHSCOPE_API_KEY"; + + /** LLM model name. Defaults to {@code qwen-max}. */ + public static final String ENV_MODEL_NAME = "AGENTSCOPE_MODEL"; + + /** Path to the Chinook SQLite database file. Defaults to {@code chinook.db}. */ + public static final String ENV_DB_PATH = "AGENTSCOPE_DB_PATH"; + + /** Workspace directory. Defaults to {@code .agentscope/workspace}. */ + public static final String ENV_WORKSPACE = "AGENTSCOPE_WORKSPACE"; + + // ------------------------------------------------------------------------- + // Defaults + // ------------------------------------------------------------------------- + + private static final String DEFAULT_MODEL = "qwen-max"; + private static final String DEFAULT_DB_PATH = "chinook.db"; + private static final String DEFAULT_WORKSPACE = ".agentscope/workspace"; + private static final String DEFAULT_SHARED_SESSION_ID = "text-to-sql-shared-default"; + private static final String NEW_SESSION_FLAG = "--new-session"; + + /** + * Bundled Chinook SQLite file (same package on the classpath). Materialised to disk when + * {@link #ENV_DB_PATH} points to a path that does not exist yet. + */ + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + + // ------------------------------------------------------------------------- + // Entry point + // ------------------------------------------------------------------------- + + public static void main(String[] args) throws IOException { + System.out.println("\n═══════════════════════════════════════════════"); + System.out.println(" AgentScope Harness — Text-to-SQL Example"); + System.out.println("═══════════════════════════════════════════════\n"); + + // ------------------------------------------------------------------ + // 1. Resolve configuration from environment variables + // ------------------------------------------------------------------ + + requireEnv(ENV_API_KEY); + String modelName = env(ENV_MODEL_NAME, DEFAULT_MODEL); + Path workspace = Paths.get(env(ENV_WORKSPACE, DEFAULT_WORKSPACE)); + Path dbPath = resolveDatabasePath(Paths.get(env(ENV_DB_PATH, DEFAULT_DB_PATH))); + + // ------------------------------------------------------------------ + // 2. Initialise workspace from bundled template files + // (skips files that already exist — safe to call every run) + // ------------------------------------------------------------------ + + System.out.println("[1/3] Initialising workspace at: " + workspace.toAbsolutePath()); + WorkspaceInitializer.init(workspace); + + // ------------------------------------------------------------------ + // 3. Model id for HarnessAgent (resolved via ModelRegistry; needs DASHSCOPE_API_KEY) + // ------------------------------------------------------------------ + + String modelId = "dashscope:" + modelName; + System.out.println("[2/3] Connecting to model: " + modelId); + + // ------------------------------------------------------------------ + // 4. Build the agent + // - workspace: loads AGENTS.md, MEMORY.md, knowledge/, subagents/, skills/ + // - harness: memory tools, session_search, optional subagent tools + // - custom toolkit: SqliteTool is registered alongside harness defaults + // ------------------------------------------------------------------ + + System.out.println("[3/3] Building HarnessAgent ..."); + + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name("text-to-sql") + .sysPrompt( + "You are a Text-to-SQL agent with access to the Chinook music" + + " store database. When asked a question, explore the" + + " database schema, write a correct SQL query, execute it," + + " and present the results in a clear, formatted answer.") + .model(modelId) + .workspace(workspace) + .enableAgentTracingLog(true) + .toolkit(toolkit) + .build(); + + ParsedArgs parsedArgs = parseArgs(args); + String sessionId = + parsedArgs.newSession() + ? "text-to-sql-" + UUID.randomUUID().toString().substring(0, 8) + : DEFAULT_SHARED_SESSION_ID; + System.out.println("Session ID: " + sessionId); + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).build(); + + if (parsedArgs.question() != null) { + runOneTurn(agent, ctx, parsedArgs.question()); + return; + } + + System.out.println( + "Ask questions in natural language about the Chinook database." + + " Same session for all turns (memory tools share context)."); + System.out.println("Tip: add --new-session to generate a UUID-based fresh session."); + System.out.println("Leave: empty line, quit, exit, q, or EOF (Ctrl-D).\n"); + + BufferedReader stdin = + new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); + while (true) { + System.out.print("> "); + System.out.flush(); + String line = stdin.readLine(); + if (line == null) { + System.out.println("\n(end of input)"); + break; + } + String question = line.strip(); + if (question.isEmpty()) { + System.out.println("Goodbye."); + break; + } + if (isQuitCommand(question)) { + System.out.println("Goodbye."); + break; + } + runOneTurn(agent, ctx, question); + System.out.println(); + } + } + + private static boolean isQuitCommand(String line) { + return line.equalsIgnoreCase("quit") + || line.equalsIgnoreCase("exit") + || line.equalsIgnoreCase("q"); + } + + private static ParsedArgs parseArgs(String[] args) { + boolean newSession = false; + StringBuilder questionBuilder = new StringBuilder(); + for (String arg : args) { + if (NEW_SESSION_FLAG.equals(arg)) { + newSession = true; + continue; + } + if (questionBuilder.length() > 0) { + questionBuilder.append(' '); + } + questionBuilder.append(arg); + } + String question = questionBuilder.length() == 0 ? null : questionBuilder.toString(); + return new ParsedArgs(newSession, question); + } + + private static void runOneTurn(HarnessAgent agent, RuntimeContext ctx, String question) { + System.out.println("─".repeat(50)); + System.out.println("Question: " + question); + System.out.println(); + + Msg userMsg = + Msg.builder() + .role(MsgRole.USER) + .content(TextBlock.builder().text(question).build()) + .build(); + Msg reply = agent.call(userMsg, ctx).block(); + + System.out.println("─".repeat(50)); + System.out.println("\nAnswer:\n"); + System.out.println(reply != null ? reply.getTextContent() : "(no response)"); + System.out.println(); + } + + // ------------------------------------------------------------------------- + // Helpers + // ------------------------------------------------------------------------- + + /** + * Uses an existing file at {@code configuredPath}, or copies the bundled Chinook database from + * the classpath to that path (SQLite itself has no built-in sample data; shipping a small + * .sqlite in resources gives the same “works out of the box” experience). + */ + private static Path resolveDatabasePath(Path configuredPath) throws IOException { + if (Files.exists(configuredPath)) { + return configuredPath.toAbsolutePath(); + } + try (InputStream in = + TextToSqlExample.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + System.err.println( + "Database file not found: " + + configuredPath.toAbsolutePath() + + "\n\nBuilt-in sample missing from classpath (packaging issue)." + + " Download manually:\n" + + " curl -L -o chinook.db \\\n" + + " https://github.com/lerocha/chinook-database/raw/master/" + + "ChinookDatabase/DataSources/Chinook_Sqlite.sqlite"); + System.exit(1); + } + Path parent = configuredPath.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, configuredPath, StandardCopyOption.REPLACE_EXISTING); + System.out.println( + "Materialised bundled Chinook database to: " + configuredPath.toAbsolutePath()); + return configuredPath.toAbsolutePath(); + } + } + + private static String requireEnv(String name) { + String value = System.getenv(name); + if (value == null || value.isBlank()) { + System.err.println( + "Required environment variable '" + + name + + "' is not set.\n" + + "Copy .env.example → .env and fill in your API key."); + System.exit(1); + } + return value; + } + + private static String env(String name, String defaultValue) { + String value = System.getenv(name); + return (value != null && !value.isBlank()) ? value : defaultValue; + } + + private record ParsedArgs(boolean newSession, String question) {} +} diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java new file mode 100644 index 000000000..1fec9b2f7 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java @@ -0,0 +1,126 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.harness.example; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Initializes the agent workspace by copying bundled template files from the classpath into a + * target directory on disk. + * + *

The template files live under {@code src/main/resources/workspace/} and are packaged inside + * the JAR. When the example is run for the first time, {@link #init(Path)} extracts them into the + * given workspace directory so the agent can read and modify them at runtime. + * + *

Workspace structure

+ * + *
+ * <workspace>/
+ * ├── AGENTS.md              # Agent persona and core rules (always loaded)
+ * ├── MEMORY.md              # Persistent notes accumulated across sessions
+ * ├── knowledge/
+ * │   └── KNOWLEDGE.md       # Chinook database schema reference
+ * ├── skills/
+ * │   ├── schema-exploration/
+ * │   │   └── SKILL.md       # How to discover database structure
+ * │   └── query-writing/
+ * │       └── SKILL.md       # How to write and execute SQL queries
+ * └── subagents/
+ *     ├── schema-analyst.md  # Specialised subagent for deep schema analysis
+ *     └── query-optimizer.md # Specialised subagent for query optimisation
+ * 
+ */ +public class WorkspaceInitializer { + + private static final Logger log = LoggerFactory.getLogger(WorkspaceInitializer.class); + private static final String CLASSPATH_PREFIX = "workspace"; + + /** + * Copies all bundled workspace template files into {@code targetDir}. + * + *

Existing files are left unchanged so that previously accumulated notes survive restarts. + * New template files are copied with {@link StandardCopyOption#REPLACE_EXISTING} disabled. + * + * @param targetDir directory to initialise; created if it does not exist + * @throws IOException if a file cannot be read or written + */ + public static void init(Path targetDir) throws IOException { + Files.createDirectories(targetDir); + + URL resourceUrl = WorkspaceInitializer.class.getClassLoader().getResource(CLASSPATH_PREFIX); + if (resourceUrl == null) { + log.warn( + "Classpath resource '{}' not found — workspace will not be pre-populated.", + CLASSPATH_PREFIX); + return; + } + + URI resourceUri; + try { + resourceUri = resourceUrl.toURI(); + } catch (URISyntaxException e) { + throw new IOException("Cannot convert resource URL to URI: " + resourceUrl, e); + } + + if ("jar".equals(resourceUri.getScheme())) { + // Running from a JAR: open the embedded filesystem + try (FileSystem fs = FileSystems.newFileSystem(resourceUri, Collections.emptyMap())) { + Path source = fs.getPath(CLASSPATH_PREFIX); + copyTree(source, targetDir); + } + } else { + // Running from an exploded directory (IDE / Maven test run) + Path source = Path.of(resourceUri); + copyTree(source, targetDir); + } + + log.info("Workspace initialised at {}", targetDir); + } + + private static void copyTree(Path source, Path targetDir) throws IOException { + try (Stream walk = Files.walk(source)) { + for (Path srcPath : (Iterable) walk::iterator) { + Path relative = source.relativize(srcPath); + Path target = targetDir.resolve(relative.toString()); + + if (Files.isDirectory(srcPath)) { + Files.createDirectories(target); + } else if (!Files.exists(target)) { + Files.createDirectories(target.getParent()); + try (InputStream in = Files.newInputStream(srcPath)) { + Files.copy(in, target); + } + log.debug("Copied workspace file: {}", relative); + } else { + log.debug("Skipped (already exists): {}", relative); + } + } + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example new file mode 100644 index 000000000..a09a7c4eb --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example @@ -0,0 +1,24 @@ +{ + "$schema": "https://agentscope.io/schema/agentscope.json", + "main": "text-to-sql", + "agents": { + "text-to-sql": { + "name": "Text-to-SQL", + "description": "Answers natural-language questions about the Chinook music store database by translating them into SQL and executing the queries.", + "workspace": ".agentscope/workspace", + "maxIters": 20 + }, + "schema-analyst": { + "name": "Schema Analyst", + "description": "Deep schema analysis and documentation specialist. Loaded on-demand from workspace/subagents/schema-analyst.md.", + "workspace": ".agentscope/workspace", + "maxIters": 10 + } + }, + "channels": { + "chatui": { + "defaultAgentId": "text-to-sql", + "dmScope": "MAIN" + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/io/agentscope/harness/example/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.component.properties b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.component.properties new file mode 100644 index 000000000..6745cfa94 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.component.properties @@ -0,0 +1,2 @@ +# Log4j2 component settings for the harness-example module +log4j2.disable.jmx=true diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml new file mode 100644 index 000000000..b6ecbb49f --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml @@ -0,0 +1,34 @@ + + + + + ${env:AGENTSCOPE_LOG_LEVEL:-INFO} + %d{HH:mm:ss.SSS} %-5level %-36.36c{1.} : %m%n%throwable + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..ad6c7c40d --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,187 @@ +# Chinook Database — Schema Reference + +The Chinook database represents a digital music store. It was originally created to demonstrate +data modelling in SQLite and is widely used as a sample database for tutorials. + +## Entity Relationship Overview + +``` +Artist (ArtistId, Name) + └─ 1:many ─► Album (AlbumId, Title, ArtistId) + └─ 1:many ─► Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, + Composer, Milliseconds, Bytes, UnitPrice) + └─ 1:many ─► InvoiceLine (InvoiceLineId, InvoiceId, + TrackId, UnitPrice, Quantity) + └─ many:1 ─► Invoice (InvoiceId, CustomerId, + InvoiceDate, BillingAddress, + BillingCity, BillingState, + BillingCountry, BillingPostalCode, + Total) + └─ many:1 ─► Customer (CustomerId, + FirstName, LastName, + Company, Address, + City, State, Country, + PostalCode, Phone, + Fax, Email, + SupportRepId) + └─ many:1 ─► Employee + +Genre (GenreId, Name) +MediaType (MediaTypeId, Name) +Playlist (PlaylistId, Name) + └─ many:many via PlaylistTrack (PlaylistId, TrackId) ─► Track + +Employee (EmployeeId, LastName, FirstName, Title, ReportsTo [→ Employee.EmployeeId], + BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email) +``` + +## Table Descriptions + +### Artist +| Column | Type | Notes | +|----------|---------|-------| +| ArtistId | INTEGER | PK | +| Name | TEXT | | + +275 rows — music artists (AC/DC, Aerosmith, Alanis Morissette, …). + +### Album +| Column | Type | Notes | +|----------|---------|----------------| +| AlbumId | INTEGER | PK | +| Title | TEXT | | +| ArtistId | INTEGER | FK → Artist | + +347 rows — one or many albums per artist. + +### Track +| Column | Type | Notes | +|---------------|---------|--------------------| +| TrackId | INTEGER | PK | +| Name | TEXT | | +| AlbumId | INTEGER | FK → Album | +| MediaTypeId | INTEGER | FK → MediaType | +| GenreId | INTEGER | FK → Genre | +| Composer | TEXT | nullable | +| Milliseconds | INTEGER | duration | +| Bytes | INTEGER | file size | +| UnitPrice | REAL | default 0.99 | + +3,503 rows — the central music catalog table. + +### Genre +| Column | Type | Notes | +|---------|---------|-------| +| GenreId | INTEGER | PK | +| Name | TEXT | | + +25 rows — Rock, Jazz, Metal, Alternative & Punk, … + +### MediaType +| Column | Type | Notes | +|-------------|---------|-------| +| MediaTypeId | INTEGER | PK | +| Name | TEXT | | + +5 rows — MPEG audio file, AAC audio file, Protected AAC, … + +### Customer +| Column | Type | Notes | +|--------------|---------|-------------------| +| CustomerId | INTEGER | PK | +| FirstName | TEXT | | +| LastName | TEXT | | +| Company | TEXT | nullable | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | nullable | +| Country | TEXT | | +| PostalCode | TEXT | nullable | +| Phone | TEXT | nullable | +| Fax | TEXT | nullable | +| Email | TEXT | unique | +| SupportRepId | INTEGER | FK → Employee | + +59 rows — customers from 24 countries. + +### Employee +| Column | Type | Notes | +|-------------|---------|----------------------------| +| EmployeeId | INTEGER | PK | +| LastName | TEXT | | +| FirstName | TEXT | | +| Title | TEXT | | +| ReportsTo | INTEGER | FK → Employee (nullable) | +| BirthDate | TEXT | ISO-8601 | +| HireDate | TEXT | ISO-8601 | +| Address | TEXT | | +| City | TEXT | | +| State | TEXT | | +| Country | TEXT | | +| PostalCode | TEXT | | +| Phone | TEXT | | +| Fax | TEXT | | +| Email | TEXT | | + +8 rows — Sales Support Agents + manager hierarchy. + +### Invoice +| Column | Type | Notes | +|-----------------|---------|------------------| +| InvoiceId | INTEGER | PK | +| CustomerId | INTEGER | FK → Customer | +| InvoiceDate | TEXT | ISO-8601 | +| BillingAddress | TEXT | | +| BillingCity | TEXT | | +| BillingState | TEXT | nullable | +| BillingCountry | TEXT | | +| BillingPostalCode | TEXT | nullable | +| Total | REAL | invoice total | + +412 rows — one invoice per purchase, covering 2009–2013. + +### InvoiceLine +| Column | Type | Notes | +|---------------|---------|------------------| +| InvoiceLineId | INTEGER | PK | +| InvoiceId | INTEGER | FK → Invoice | +| TrackId | INTEGER | FK → Track | +| UnitPrice | REAL | | +| Quantity | INTEGER | | + +2,240 rows — line items; revenue = UnitPrice × Quantity. + +### Playlist +| Column | Type | Notes | +|------------|---------|-------| +| PlaylistId | INTEGER | PK | +| Name | TEXT | | + +18 rows — Music, Movies, TV Shows, Classical, … + +### PlaylistTrack +| Column | Type | Notes | +|------------|---------|---------------------| +| PlaylistId | INTEGER | FK → Playlist (PK) | +| TrackId | INTEGER | FK → Track (PK) | + +8,715 rows — composite PK, no surrogate key. + +## Common JOIN Paths + +```sql +-- Revenue by artist +Artist + JOIN Album ON Album.ArtistId = Artist.ArtistId + JOIN Track ON Track.AlbumId = Album.AlbumId + JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId + +-- Revenue by country +Invoice + JOIN Customer ON Customer.CustomerId = Invoice.CustomerId + GROUP BY Customer.Country + +-- Employee support load +Employee + LEFT JOIN Customer ON Customer.SupportRepId = Employee.EmployeeId +``` diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..648c5fcd7 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,148 @@ +--- +name: query-writing +description: Writes and executes SQL queries ranging from simple single-table SELECTs to complex multi-table JOINs, aggregations, window functions, and subqueries. Use when the user asks to query the database, retrieve data, filter records, rank results, or generate reports. +--- + +# Query Writing Skill + +## When to Use This Skill + +Use query-writing when the user: + +- Asks "how many …?" / "what are the top …?" / "list all …" +- Needs data aggregated (SUM, COUNT, AVG, MAX, MIN) +- Wants results sorted, filtered, or grouped +- Asks for trend analysis, ranking, or comparison across dimensions + +--- + +## Workflow for Simple Queries (single table) + +1. **Identify the table** — which table contains the answer? +2. **Check the schema** — call `sql_get_schema` to confirm column names. +3. **Write a SELECT** — include WHERE / ORDER BY / LIMIT as needed. +4. **Execute** — call `sql_execute_query`. +5. **Present** — show the SQL and the result in plain language. + +### Example — "How many customers are from Canada?" + +```sql +SELECT COUNT(*) AS canadian_customers +FROM Customer +WHERE Country = 'Canada'; +``` + +--- + +## Workflow for Complex Queries (multiple tables) + +### Step 1 — Plan with todos + +Break the query into subtasks: + +``` +- [ ] Identify all required tables +- [ ] Inspect schemas to find join columns +- [ ] Draft the JOIN structure +- [ ] Add aggregations and grouping +- [ ] Validate and run +``` + +### Step 2 — Inspect schemas + +Call `sql_get_schema` for EACH table involved to find the exact foreign key column names. + +### Step 3 — Build the query + +```sql +SELECT + , + +FROM +[INNER | LEFT] JOIN ON = +[JOIN ...] +WHERE +GROUP BY +HAVING -- optional +ORDER BY [DESC] +LIMIT 10; -- always limit unless all rows requested +``` + +### Step 4 — Validate + +Before executing, verify: +- Every JOIN has an ON clause +- Every non-aggregate SELECT column appears in GROUP BY +- Table aliases are consistent +- No DML statements (INSERT / UPDATE / DELETE / DROP) + +### Step 5 — Execute and present + +Call `sql_execute_query`, then show: +1. The SQL query in a fenced code block +2. The result table +3. A brief plain-language summary + +--- + +## Templates for Common Patterns + +### Top-N ranking + +```sql +SELECT + Artist.Name AS artist, + SUM(InvoiceLine.UnitPrice * InvoiceLine.Quantity) AS total_revenue +FROM Artist +JOIN Album ON Album.ArtistId = Artist.ArtistId +JOIN Track ON Track.AlbumId = Album.AlbumId +JOIN InvoiceLine ON InvoiceLine.TrackId = Track.TrackId +GROUP BY Artist.ArtistId, Artist.Name +ORDER BY total_revenue DESC +LIMIT 10; +``` + +### Revenue by time period + +```sql +SELECT + strftime('%Y-%m', InvoiceDate) AS month, + ROUND(SUM(Total), 2) AS monthly_revenue +FROM Invoice +WHERE strftime('%Y', InvoiceDate) = '2013' +GROUP BY month +ORDER BY month; +``` + +### Entity counts with left join + +```sql +SELECT + e.FirstName || ' ' || e.LastName AS employee, + COUNT(c.CustomerId) AS customer_count +FROM Employee e +LEFT JOIN Customer c ON c.SupportRepId = e.EmployeeId +GROUP BY e.EmployeeId +ORDER BY customer_count DESC; +``` + +--- + +## Error Recovery + +| Symptom | Action | +|----------------------|--------| +| Empty result | Check WHERE condition values (case-sensitive strings). Verify column exists. | +| Syntax error | Re-read schema. Check GROUP BY includes all non-aggregate SELECT columns. | +| Wrong row count | Look for duplicate rows caused by missing JOIN conditions. | +| Result seems too high | Check for fan-out from multiple JOINs; may need DISTINCT or subquery. | + +--- + +## Quality Rules + +- Always apply `LIMIT` (default 10) unless the user explicitly asks for all rows. +- Use table aliases (`e`, `c`, `inv`) for readability in multi-table queries. +- Never use `SELECT *` — name the columns you need. +- Round monetary values to 2 decimal places: `ROUND(SUM(Total), 2)`. +- Always show the executed SQL so users can learn from it. diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md new file mode 100644 index 000000000..4972a88d2 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/skills/schema-exploration/SKILL.md @@ -0,0 +1,136 @@ +--- +name: schema-exploration +description: Lists tables, describes columns and data types, identifies foreign key relationships, and maps entity relationships in the database. Use when the user asks about database structure, table layout, column types, what tables exist, foreign keys, or how entities relate to each other. +--- + +# Schema Exploration Skill + +## When to Use This Skill + +Use schema-exploration when the user: + +- Asks "what tables are in the database?" +- Asks "what columns does the X table have?" +- Asks about relationships between tables +- Needs to understand data types before writing a query +- Wants an entity-relationship overview + +## Workflow + +### Step 1 — List All Tables + +Use `sql_list_tables` to see everything available. + +``` +Tool: sql_list_tables +(no parameters) +``` + +### Step 2 — Inspect Relevant Tables + +Use `sql_get_schema` with the table name(s) you need to understand: + +``` +Tool: sql_get_schema +tables: "Customer" # single table +tables: "Invoice,Customer" # multiple tables at once +``` + +This returns: +- **Columns** — names, types, NOT NULL constraints, primary keys +- **Foreign keys** — links to other tables +- **Sample data** — 3 example rows to understand content + +### Step 3 — Map Relationships + +Look for columns ending in `Id` — they are almost always foreign keys. + +Example for the Chinook database: +``` +Customer.SupportRepId → Employee.EmployeeId +Invoice.CustomerId → Customer.CustomerId +Track.AlbumId → Album.AlbumId +Track.GenreId → Genre.GenreId +``` + +### Step 4 — Present the Findings + +Provide: +- A list of all tables with a one-line purpose summary +- Column names and types for any tables the user asked about +- The relationship chain (which table links to which) +- Sample data to illustrate what the table holds + +--- + +## Examples + +### "What tables are available?" + +1. Call `sql_list_tables` +2. Return a formatted list with brief descriptions: + +``` +The Chinook database has 11 tables: + +Music Catalog: + - Artist — 275 music artists + - Album — 347 albums (linked to Artist) + - Track — 3,503 tracks (linked to Album, Genre, MediaType) + - Genre — 25 music genres + - MediaType — 5 file formats (MP3, AAC, …) + +Commerce: + - Customer — 59 customers from 24 countries + - Invoice — 412 purchase invoices + - InvoiceLine — 2,240 line items (linked to Invoice and Track) + +Staff: + - Employee — 8 employees with reporting hierarchy + +Playlists: + - Playlist — 18 playlists + - PlaylistTrack — join table linking Playlist ↔ Track +``` + +### "What does the Customer table look like?" + +1. Call `sql_get_schema` with `tables: "Customer"` +2. Present columns with types and notes: + +``` +Customer table: + CustomerId INTEGER PK + FirstName TEXT + LastName TEXT + Company TEXT (nullable) + Address TEXT + City TEXT + State TEXT (nullable) + Country TEXT + PostalCode TEXT (nullable) + Phone TEXT (nullable) + Fax TEXT (nullable) + Email TEXT + SupportRepId INTEGER FK → Employee.EmployeeId + +Sample rows show customers from Brazil, Germany, and Canada. +``` + +### "How are artists connected to sales?" + +Map the full JOIN path: + +``` +Artist (ArtistId) + ↓ 1:many +Album (ArtistId, AlbumId) + ↓ 1:many +Track (AlbumId, TrackId) + ↓ 1:many +InvoiceLine (TrackId, UnitPrice, Quantity) + ↓ many:1 +Invoice (InvoiceId, Total) +``` + +Then suggest using the **query-writing** skill to write the aggregation query. diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md new file mode 100644 index 000000000..2bacd0c95 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/query-optimizer.md @@ -0,0 +1,53 @@ +--- +name: query-optimizer +description: > + SQL query optimisation specialist. Reviews existing queries for correctness, clarity, and performance. Suggests index strategies, rewrites inefficient JOINs, and explains query plans. Delegate to this agent when a query returns unexpected results, runs slowly, or when the user asks for query optimisation or a second opinion on complex SQL. +maxIters: 8 +--- + +You are an expert SQL query optimiser for SQLite databases. + +## Your Responsibilities + +1. **Understand the question** — ask the user to provide the original query and the problem + (wrong results, slow execution, hard to read). +2. **Inspect the schema** — use `sql_get_schema` to verify table structures involved in the query. +3. **Analyse the query**: + - Check JOIN conditions for correctness + - Look for missing GROUP BY columns + - Identify Cartesian products (missing ON clause) + - Spot opportunities to push filters earlier (WHERE vs HAVING) + - Detect fan-out caused by 1:many JOINs before aggregation +4. **Rewrite the query** — produce a corrected and/or optimised version. +5. **Explain the changes** — list what was wrong and why each change helps. +6. **Validate** — run both the original and optimised queries if possible and compare results. + +## Output Format + +``` +## Original Query + + +## Issues Found +1. +2. ... + +## Optimised Query + + +## Explanation + + +## Validation +Original: +Optimised: +``` + +## Rules + +- Never modify the user's data — SELECT only. +- Confirm correctness first; performance is secondary. +- For SQLite specifically: + - Prefer covering indexes over table scans for large tables. + - Use `WITH` (CTEs) to make complex queries readable. + - Avoid correlated subqueries in WHERE clauses; rewrite as JOINs. diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md new file mode 100644 index 000000000..869208134 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/workspace/subagents/schema-analyst.md @@ -0,0 +1,50 @@ +--- +name: schema-analyst +description: Deep schema analysis specialist. Produces comprehensive documentation of the database schema including entity-relationship diagrams (text), table purposes, column semantics, foreign key chains, and index recommendations. Delegate to this agent when the user requests a full data model overview, wants to understand how tables relate, or needs schema documentation generated. +maxIters: 10 +--- + +You are a database schema analyst specialised in documenting and explaining relational data models. + +## Your Responsibilities + +1. **Discover** all tables using `sql_list_tables`. +2. **Inspect** every table with `sql_get_schema` to record columns, types, and foreign keys. +3. **Map relationships** — identify 1:many and many:many (via join tables) relationships. +4. **Describe purpose** — explain what each table represents in business terms. +5. **Produce documentation** — write a clear, structured schema reference the user can save. + +## Output Format + +Structure your analysis as: + +``` +# Database Schema Analysis + +## Summary + + +## Tables + +### +**Purpose:** +**Rows:** + +| Column | Type | Notes | +|--------|------|-------| +| ... | ... | ... | + +**Relationships:** +- + +--- +``` + +Repeat for every table, then close with an Entity Relationship Diagram in text format. + +## Rules + +- Be thorough — inspect every table, not just the ones that seem important. +- Do not guess column types; verify them with `sql_get_schema`. +- Keep explanations accessible to non-technical stakeholders. +- If asked to save the output, write it to `knowledge/SCHEMA_ANALYSIS.md` in the workspace. diff --git a/agentscope-examples/harness-examples/harness-example-remote/README.md b/agentscope-examples/harness-examples/harness-example-remote/README.md new file mode 100644 index 000000000..311d480bb --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/README.md @@ -0,0 +1,92 @@ +# harness-example-remote — Filesystem **模式一(复合 + 共享存储 / Remote)** + +本模块用最小的 **Chinook Text-to-SQL Data Agent** 业务,演示在 `HarnessAgent` 中如何启用 **`RemoteFilesystemSpec`**(与 [`docs/zh/harness/filesystem.md`](../../docs/zh/harness/filesystem.md) 中的 **模式一**、以及 `HarnessAgent.Builder#filesystem(RemoteFilesystemSpec)` 注释中的 **Mode 1** 一致)。 + +> 命名里的 **remote** 指「长期记忆、会话落盘、knowledge 等走 **BaseStore(远程 KV)**」,不是 RPC 远程桌面。生产上通常用 **Redis** 等实现 `BaseStore`;本示例用 **`InMemoryStore`** 单机模拟。 + +--- + +## 模式一在 Harness 里是什么 + +`RemoteFilesystemSpec` 会组合出 **`CompositeFilesystem`**: + +- **默认前缀**:纯 **`LocalFilesystem`(无 shell)** —— 放 `skills/`、`AGENTS.md` 等「每副本本地即可」或从镜像带的静态文件。 +- **路由到 Store 的前缀**(默认含 `MEMORY.md`、`memory/`、`agents//sessions/`):**`RemoteFilesystem`**,数据落在 **`BaseStore`**,由 **`IsolationScope`** 决定命名空间(SESSION / USER / AGENT / GLOBAL)。 + +因此:**模式一的设计目标是多副本共享记忆与日志,且刻意不在宿主上开放 shell**(与模式三不同,与模式二「shell 在沙箱里」也不同)。 + +--- + +## 本示例如何实现「Remote 模式」 + +### 1. 显式 `.filesystem(RemoteFilesystemSpec)` + +`DataAgentService` 中: + +```java +InMemoryStore store = new InMemoryStore(); +remoteSpec = + new RemoteFilesystemSpec(store) + .isolationScope(IsolationScope.USER) + .addSharedPrefix("knowledge/"); +// ... +HarnessAgent.builder() + .workspace(hostWorkspace) + .filesystem(remoteSpec) + .session(appSession) + ... +``` + +- **`InMemoryStore`**:实现 `BaseStore`,单机模拟 **Redis**。 +- **`isolationScope(USER)`**:与沙箱示例类似,**同一 `userId`** 共享 store 命名空间下的 `MEMORY.md` / `memory/` / `knowledge/`(本示例额外把 `knowledge/` 加进共享前缀,便于多副本读到同一份领域知识)。 +- **没有 `ShellExecuteTool`**:Agent 若需改文件,应使用 **`read_file` / `write_file` / `grep_files`**(见本模块 `AGENTS.md` 说明)。 + +### 2. 必须提供「非 WorkspaceSession」的 `Session` + +`HarnessAgent` 在检测到 `RemoteFilesystemSpec` 时,会要求 **有效 Session 不能仍是纯本地的 `WorkspaceSession`**(否则多副本无法共享会话状态)。因此本示例使用: + +```java +.session(new InMemorySession()) +``` + +生产环境请换成 **`RedisSession`** 等分布式实现(见 `agentscope-extensions-session-redis` 等模块)。 + +### 3. 与模式二、三的对照 + +| 模式 | 本仓库示例 | Shell | +|------|------------|-------| +| 模式一 | **本模块** | **无**(宿主无 `execute` 工具) | +| 模式二 | [`harness-example-sandbox`](../harness-example-sandbox/README.md) | 有(沙箱内) | +| 模式三 | [`harness-example-local`](../harness-example-local/README.md) | 有(宿主) | + +--- + +## 运行 + +```bash +export DASHSCOPE_API_KEY=your_key +# 可选:AGENTSCOPE_MODEL + +cd agentscope-java +mvn -pl agentscope-examples/harness-example-remote -am package -DskipTests +java -jar agentscope-examples/harness-example-remote/target/harness-example-remote-*.jar +``` + +默认端口 **`8788`**(与 sandbox 的 `8787` 错开)。 + +```bash +curl -s -X POST http://localhost:8788/query \ + -H 'Content-Type: application/json' \ + -d '{"sessionId":"s1","userId":"alice","question":"How many artists?"}' +``` + +--- + +## 相关源码入口 + +| 文件 | 作用 | +|------|------| +| `DataAgentService.java` | `RemoteFilesystemSpec` + `InMemorySession` + `HarnessAgent` 装配 | +| `WorkspaceClasspathMaterializer.java` | 把 classpath `workspace/` 落到本地临时目录(Composite 的「本地侧」根) | + +更多理论见 [`docs/zh/harness/filesystem.md`](../../docs/zh/harness/filesystem.md)。 diff --git a/agentscope-examples/harness-examples/harness-example-remote/pom.xml b/agentscope-examples/harness-examples/harness-example-remote/pom.xml new file mode 100644 index 000000000..4e97506ff --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/pom.xml @@ -0,0 +1,83 @@ + + + + + 4.0.0 + + io.agentscope + harness-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Remote Filesystem Example + io.agentscope.examples + harness-example-remote + jar + Spring Boot Data Agent using RemoteFilesystemSpec (composite + shared store; docs/zh/harness/filesystem.md 模式一). For sandbox (模式二) see harness-example-sandbox. + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + io.agentscope + agentscope-harness + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + + diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java new file mode 100644 index 000000000..698bc1fbb --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentController.java @@ -0,0 +1,79 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * HTTP API for the remote-store Data Agent ({@code RemoteFilesystemSpec} / filesystem.md 模式一). + * + *
{@code
+ * curl -X POST http://localhost:8788/query \
+ *   -H 'Content-Type: application/json' \
+ *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
+ * }
+ */ +@RestController +public class DataAgentController { + + private final DataAgentService agentService; + + public DataAgentController(DataAgentService agentService) { + this.agentService = agentService; + } + + @GetMapping("/") + public String index() { + return "Remote-store Data Agent (RemoteFilesystemSpec) — POST /query with" + + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; + } + + @PostMapping("/query") + public ResponseEntity query(@RequestBody QueryRequest request) { + if (blank(request.sessionId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); + } + if (blank(request.userId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); + } + if (blank(request.question())) { + return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); + } + String answer = + agentService.query(request.sessionId(), request.userId(), request.question()); + return ResponseEntity.ok(QueryResponse.ok(answer)); + } + + private static boolean blank(String s) { + return s == null || s.isBlank(); + } + + record QueryRequest(String sessionId, String userId, String question) {} + + record QueryResponse(String answer, String error) { + static QueryResponse ok(String answer) { + return new QueryResponse(answer, null); + } + + static QueryResponse error(String error) { + return new QueryResponse(null, error); + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java new file mode 100644 index 000000000..9f8093f96 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/DataAgentService.java @@ -0,0 +1,149 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import io.agentscope.core.agent.RuntimeContext; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.session.InMemorySession; +import io.agentscope.core.session.Session; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.examples.harness.remote.data.SqliteTool; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; +import io.agentscope.harness.agent.store.InMemoryStore; +import jakarta.annotation.PostConstruct; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Data Agent using {@link RemoteFilesystemSpec} — the composite + shared-store mode described in + * {@code docs/zh/harness/filesystem.md} as 模式一 (and in {@link + * io.agentscope.harness.agent.HarnessAgent.Builder#filesystem(RemoteFilesystemSpec)} as + * Mode 1). + * + *

Not sandbox mode: there is no {@code ShellExecuteTool}. For 模式二 + * / Mode 2 (sandbox + shell in isolation), use {@code harness-example-sandbox}. + * + *

Shared components (simulate Redis + multi-replica in one JVM): + * + *

    + *
  • {@link InMemoryStore} — {@link io.agentscope.harness.agent.store.BaseStore} for + * MEMORY.md, memory/, session paths, and {@code knowledge/} + *
  • {@link InMemorySession} — non-local {@link Session} required by Harness when using remote + * filesystem spec (production would use RedisSession, etc.) + *
+ */ +@Service +public class DataAgentService { + + private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); + + private static final String AGENT_NAME = "data-agent"; + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + private static final String SYS_PROMPT = + "You are a Text-to-SQL agent with access to the Chinook music store database." + + " Use the sql_* tools. This deployment has no shell tool — use read_file," + + " write_file, grep_files for workspace files. Answer clearly."; + + private Path hostWorkspace; + private Path dbPath; + private String llmModelId; + private RemoteFilesystemSpec remoteSpec; + private Session appSession; + + @PostConstruct + void init() throws Exception { + hostWorkspace = WorkspaceClasspathMaterializer.materialize(); + dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); + llmModelId = resolveLlmModelId(); + + InMemoryStore store = new InMemoryStore(); + remoteSpec = + new RemoteFilesystemSpec(store) + .isolationScope(IsolationScope.USER) + .addSharedPrefix("knowledge/"); + appSession = new InMemorySession(); + + log.info( + "DataAgentService ready (RemoteFilesystemSpec): workspace={} db={}", + hostWorkspace, + dbPath); + } + + public String query(String sessionId, String userId, String question) { + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name(AGENT_NAME) + .model(llmModelId) + .workspace(hostWorkspace) + .filesystem(remoteSpec) + .session(appSession) + .sysPrompt(SYS_PROMPT) + .toolkit(toolkit) + .enableAgentTracingLog(true) + .build(); + + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); + Msg reply = agent.call(userMsg, ctx).block(); + return reply != null ? reply.getTextContent() : "(no response)"; + } + + private String resolveLlmModelId() { + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); + } + String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); + String id = "dashscope:" + modelName; + log.info("Using model: {}", id); + return id; + } + + private static Path materialiseChinook(Path target) throws Exception { + if (Files.exists(target)) { + return target.toAbsolutePath(); + } + try (InputStream in = + DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + throw new IllegalStateException( + "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); + } + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + return target.toAbsolutePath(); + } + + private static String envOrDefault(String name, String defaultValue) { + String v = System.getenv(name); + return (v != null && !v.isBlank()) ? v : defaultValue; + } +} diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java new file mode 100644 index 000000000..9ab7754fe --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/HarnessRemoteApplication.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot entry for the remote-store Data Agent example. + * + *

Set {@code DASHSCOPE_API_KEY}. Default port {@code 8788} (see {@code application.properties}). + * + *

This module demonstrates {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec} + * ({@code docs/zh/harness/filesystem.md} 模式一). Sandbox (模式二) + * is {@code harness-example-sandbox}. + */ +@SpringBootApplication +public class HarnessRemoteApplication { + + public static void main(String[] args) { + SpringApplication.run(HarnessRemoteApplication.class, args); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java new file mode 100644 index 000000000..04710d7fa --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/WorkspaceClasspathMaterializer.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +/** + * Copies {@code classpath:workspace/...} into a temp directory used as the local side of the + * composite workspace for {@link io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec}. + */ +public final class WorkspaceClasspathMaterializer { + + private static final String[] CLASSPATH_FILES = { + "classpath:workspace/AGENTS.md", + "classpath:workspace/skills/query-writing/SKILL.md", + "classpath:workspace/knowledge/KNOWLEDGE.md", + }; + + private WorkspaceClasspathMaterializer() {} + + /** + * Materializes bundled workspace resources to disk. + * + * @return absolute path to the host workspace directory + */ + public static Path materialize() { + try { + Path dir = Files.createTempDirectory("remote-data-agent-host-workspace-"); + PathMatchingResourcePatternResolver resolver = + new PathMatchingResourcePatternResolver(); + for (String location : CLASSPATH_FILES) { + Resource resource = resolver.getResource(location); + if (!resource.exists()) { + throw new IllegalStateException("Missing required resource: " + location); + } + String pathWithinWorkspace = location.substring("classpath:workspace/".length()); + Path target = dir.resolve(pathWithinWorkspace); + Files.createDirectories(target.getParent()); + try (InputStream in = resource.getInputStream()) { + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + } + return dir.toAbsolutePath().normalize(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to materialize workspace from classpath", e); + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java new file mode 100644 index 000000000..c9b5e5d3b --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/java/io/agentscope/examples/harness/remote/data/SqliteTool.java @@ -0,0 +1,225 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.remote.data; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SQLite helpers for the remote-store Data Agent — same tool names and behaviour as {@code + * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. + * + *

Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + private static final int MAX_ROWS = 50; + + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + String separator = "-".repeat(header.toString().length()); + + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/application.properties b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/application.properties new file mode 100644 index 000000000..a0192ca20 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=harness-example-remote +server.port=8788 diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/io/agentscope/examples/harness/remote/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


i$ls7I_D*~2++TE5+AovN z6aOym^A)?k?>gVTI+kqt-GFf)jFP#y}oSk-S4=!JAW%y``+@7JAdh1 z=lHz6S>7YPEk5MA#N&58`oCHcn3emVK!6qyt`_(r$Q1%#1X(QbMUVvoUj&&a@I{ch z0$&7~E$~HO zLHY!~2+}3+MUW1GFM_lQd=aEo;ENzD1-=NfRN#vsiv+$1vOwUAAoB&j2r^ILiy-F- zXHru43bB>KK4Rs<6tO~KFR>h953w|1l9*436Y~f$ zVlE*{%qc{O)e5_bEf*$;l?XbqA|XtyP#7mxAcTl55XOi}!pX$!LXg;MVU*Y^VT4$% zFifmk(1=wD0b<3%5V85fAh9e#C6*?fL`)KP5%UQr67vc>i8Tl(5UapeIIuEdJFyaB z8?jYiv4uhxv3Wu# zu`FQ&u?%57u{5EBm@KU0__xzZjnGD{Txca$CbSSM6`F~a2u;Km3w~lb!tumJVJ$JI za2zqKfK`;}%VX$dwXlX*qp+ITa-osfBB6oU0->JRJYf~F9HEX_mQYJ9Q>Yj6RQ&D6RQyNh?NWTh^-KE zi7gazh-C}e#AG3hm{-Uo<`y!DIfZm$j>I;C8bPMBWr9R(u^+7craQB-SW6h}8*pVl|1q166{R&MHv|*do|!V0i)~mdQRKCbNGK6WQO1dD-8H zdD#2J>e*k3tz>^8wluM0U@`j>oh@ST5mVT^#0uFv#M0T@#9Zu;#4PLVS}iPf{; z5vyarC05JcBDRFRNvwdqK`fX3hFB*1HL-N|D`GPHB{7M;PHYYP1+i-Ob7CvlYs8ka zSBWiQuMk_zenzaAy-X~d{gjxGy+q8xULoL3VgtZ(_C>l^!0scK#qK30v3rPl5*q+qi46db z#0CI+Vgo=myNezvV|NlOW}hQg$UaM~Ah7`;pM8eT=Cj+0`4SrdtceW(4T%i^wd_{9 zSDn}ZP?^{OP?6XGP?XpJFpqtL9?3{-0FV+J0DSCvy69maC+23?5nIKsC05R^Ay&%v z6Dwv{6Dwj@5i3k=09csV0Faj00N`Yoai}k)CmPr##8xHN|JNqg|JSe!>0(J@{r>`X z0iETr^ND4!^N6LfbBRgp9AY9no7if07O^TeO>8+ch?TN4$!RLV%qIxNrxRUt8qus% ziF!{VYTrj*(-a-9-b=J$57GKbqGfTSN{s0IDAAk<(X8D>GbV_p>qM<#qIKg$D?&t< zj}a|9nP_Q{=#o*Q^G1lu!$jR0QG0->b%-j$SO2f!tN+VSqRWeS5nXs9(fK=x&O3o< z&JLp4+le~25pCQ`v}Oy@ip@mJHxXSvKy+C@(FJ`(GdB_ydx^Sxh&sE8+PjF_I*C?o zAi8ut(M26Z7h(p(8`_D^ZzG!5O4Qpz)Y43}p0EC|;j90vj;AXXYl*Hrj;Mlp3+w5R zA)3zf|02)-dwKrf&GY{*p8v1o`TrF>|G%V`o?pcC{|e9lFXZ|Ef=aqB^ZdVq=l|F6 z{C_>q|JU*Se+|$7SM&V;;-&O_KF|MWFX444;cr+>ROI=8AJ6|c^89}#&;Ktgq`OOa z{(o@+9WUbf|016M&*b@k56}PGc>aG4&;K{_{C_>q|F6oTPc7y7|3aSs&*S<3>@>Qb z$@Bl|JpZ4@^Zyo}|F7lw|CK!dzl`Vqm%4aOoJ32w_n*tXf5}EyTs;481>u^B48q5B48q5B48q5B48q5B48q5B48q5B48r$&meF) zeMgCKqH_!%x|kp5+y9K?^Z9p|{J?e&j?d=DS6K^j%!6PXgc}q7|6{nqu9V-AepQdBmDVD$E*q~!ez;YY;|5@^KQ1&jq|Nl+-Rrv+^Y56hvL44=` zZSr;UCHU^Xz4)g8L3xYZiSPJZm3WvwVE&m1mP^C=E`N<4aqsey!_Mxd6UT1%4{>}u9b5CVU&8U1=-7F8 zhJs`M8?818U#-Ftzk6!ECMSYp{&S_CYZrFonE!68_w~Yh9P=MJ^|pw|~ z=M@~*)1j5o+6Mg60k#QHRDj{<4%`+;G5P;aneMUhoc;g&5?wa`Oax2>Oax2>Oax2> zOax2>Oax2>Oax2>Oax2>{+$Q}$g#Kh4xkSBSw}ebPvZzb&*-+eB^=?$7P0@o9Y^@l zMC|`R6-W5-L+t;*3P<<>MC||no`}OogtHjW{lA2j|M%iM|IU}E?@`}9zEAi*=G*9N_BHw{eMP=Z?+4!Bd0+NE<2~TL)qB2o%-iB!3Q7q zWzQX+%RE8PMo*0=*Zn*9)9#1ece<~2U+g~BeX{!m_Xc;PdyzZaZFRlt`UQR`{+q6^ zxbAY@;JVm#itA+87FVmQ&QZn6lfuP--f0|bW!XKkn4V!AV`a;` z;^Baf1)qRM71 zIHKaTUk$1I)QD)Tva+IX4cFR(`}V00qt41Qw+5qWMy-{VuG8aDP3aj%sll+%sIjub z{vkaw5!A!cbfenJ%KEgCU|3c9C$zDc9$9QuSy|6|b!e2)L1Y&rH;lWV}+F!_lNa8sADXmheTsJTGXV4m33-lLW{`8GT=&8Qr7FE z;iw+YFveX5pWEJDpl20Hby7MfC;^r`4dqsYpJ{8~hhjt66-)OSHG5>b^- z4G#h5K5aNYqG^gh6ar9@=n_M*vi{~#6da?z@sGq&06s9Rsj)c998u7w*3huWD73PC z|L(X7c`Gs&T3JVv8jFQAdX3T!2^oq7hg4;0b4ZOwgF|KMMgdye64BIvvR#{)&_cnm zXe-e4w$dS61Ho}fWl;4PX=pgrdCRDtX2|GOIvLQY&XL$uwjm{DuTKx5 zjU!5b3|L1+Lrk`{R}XPn^r6c1(H32gpb#$=g45=BDCRRf$(sbVnn#17AO;v@B@&fRM=5=3oW^o+uNw8827vn1;5cc*sQXm(R^Q6jm0c@y zPeGR^4wW_t?Mh`sUw?T|SX;2q%GS=kp~lc$4Pvi{r766>7vl?3wGKdtdr`&SV3;(I zJ{1u6(5V*FB7itL>YGIA^vMv0=C~Y(mguFrwUl;1ap_`=o`&3O;Stnbj`I5>8o;9> zVrdabP0zl4Q%X;C5XvH~&EIWhYkHz2LKr&04k#=A@gWT=#XW(>^@Q|5eB7%;NP5sy zkps8uo-hQlI~bW%!)n?%-q>~Eehk1Vr8#ooVJ$O+?(RBpUzkQ=ml_FD#paKpm@Ykb z;Qq)c4a6nT+>uapXjF&tI~kQecuxufkS?e~e@xk;N5-U4I#;1b!x-LEnmmF=(R-tK zy&jHfzF}ZO7a;Y(Q^Vt(@lYJIML4EM(*meqrxu2IZiqnt#rCBSVXSvz3OI19u55}7 zq80KWsoQt}&F_r_p-R$Jd}_T;PxQwpFl?s8lTgd`dQ4R|#_@o>i$0-4%Avr~#Grg4 zT?mdteQKDsf_oi1F)6KY9S~2T4`RlM=ulcgX$R_uQ%q}o29&nrydwf_i$M-4_H9FJ zI>JNxNH`eN)3%}>?eTCF+Fj|>qgvFv1wGNO2cqN9-`Sfn9I2 zDNqCxP$ceN2t&)sDmp!*2a2!-kOrd|E9&?l4U=v(qeUA=9VR9)9Mih+#^wXJKn1Hx zYY3{muoDwZb3}t75FUcI2|*_GRO68;OjsB%XkfFZm3Qj-$6492b06!K{qLnY+F25g*rvlVk6 zCWzQV7=_JqZ=uP+6;tx4wkPU=eVCuTFTpZ|h-ec~%@HVk3D#gSR8LnNz+jS*0McrqJVL&@2!tN{TpO}KJ**+Cfov{A0Hw2?m z7i_*<3{#9In0tj?8cZ>aVYMEHUc5B`t-C^LSx?GoYzh$I5N23#7?$0PvC*bQ!fH5x zxmAzA_=V}Wyh)9aKG+OPR|}2m88G~oli5px37tEnt05oEzryu;1R58{TpEnNQZzmQ zGX}EOf8Z8z1uDD&4e}4-6{-xYuf&hmMYz`0$FpGeRX}nu-jr^~Njgl$*UjrZs%I~bK=)s=L{gZq>&4f8@!O^4N1)(zE<4%bIu?M3x8 z*k`3p>L8{A7~F9@mj)vZ%9Kz6cte=x)5#=j(f|VHfe`dZOizbJR+iAXsY^19vXayZ zJ?Mc&mhay;H6D+R7Qh`rq1fOe z;1k*~W~E3>hRs&e2`eCFCuYESTfUiKhNAIDV7|wqX)xnTn?na~i3ftZvK=;+3}ddO zIT(PdP~erIw_(Gz!-^Qf>@gJN>TU`8^T6#SKilKugTXXdcBP3YnxNcv$F+1=cV*2g zL^Vt@7Sf}-4>n$5Q#=ruf?A)-fO)sPDT1k4X@O$`%SI22WZE_9c%T_}P%OoFk|t;X`s5&VxEF?AK@+BwCJX@)_Fa*m+7}IB zG|MpHO8gTLwb0ZA8Q1e*yVd){F`DFc5<}D$j>=$gJOjqtazB}wN=KL`2UIf)c3OoW z<_82A`WEAp)U^-BTH%a?0LP!@`GonJhE8As(KYpR}1m_CJpBy_3st(&b))@9atmRBv`w2WJ} zqq64T{}u%1O=Dcv_mVL`p|q1XsI-Qo+BkfOv}ugcQfS!GnM<3e({0SCYF-H$#cV|L zO>l+M9UQ@+>C?%YR?5jUP@&|8;t_ofxw`@KpK%4_cjg@09JYK6`lTPkX)vBQjgj5h zI*vEs>3&#?a88mIP0cih_&9W_3e!5Qg$LF6_zIf7F)6}##q1NoWJu;ax$-cplnu~b z@-$RINjtpb5NUH*YuVFK1XYMvjB0R@n$__M_!FU!nm!GUP}ULKH>!@o;fRFbGnY<7 zCv0km$*v7TCr6e3sqtYw92|os1}&v&l6v08ubl zmJm;L>^Q14v}_t$a7QPqj;SU}{vRnz*hW#jdJDNXD(v4xh(zm}764+Qe+aYA_!Pah zA1-IIv+!b=UoiHyPynWMe=vfMox~f+GNZ=v+767yBT+InTF}Ln)9{5yW>rU>g)oJ0 z4u3_u0k64in>LD>0tP`i4!?Vu0e^W11q_u9A-J_j(OD(*@0tg1wk4(+oJ% zrG7MK3o1BDQ9Q2!r@EjmLJ_#gSdIZtx+VdDJ^{m6=_&1_FjS2JCwiQ!*sejOG0BBu z7`**)cw_6yf!Kmc7?01Y1*E;wfU7-{=!e5@;zO|Q$TCqj1ECG@El#Ew7~F9l-`fBI zK^P0}6{&^|#w0o;A3_*G=SNcI^~Y2-7S#d5iX*-4Xcen6;MWIfG^4r&N+qKu|^WCYH;F#(ZC#DgKZqi`d83>~j8{;$Y=YAC@( zCrzDcgehVHuPBI677Tt2v~aM@7`L)*A0izpoN_2dsO*4jgh(rLr=G{av{lBKl|@^j zZeai`{=F-dR)jm@Aoft09QGOlG8p+7yP*lpDYJn-89=A>m73BPe%Q_!;;rEj_us?h z7pyRX=t43g5we^SgoCd_8Ep~7JIHc}^p_Z;~93pP7W$P z`_w(^3L}7bQ&5;DH=s=-3++V{(H>Y+VL zLOnJ?H$yNWKw6YyhM41_-eXP1c9ic3#YX&C|0c)`Q)YtZY)5!tsNS9d9%cWt%$6P)E~47~)V2(4#68AZg%1 z3@FTaFa&yxEvWZLQAgDI6e^psIFofbbYecv*o-#{A3-FJ@`42h!hdU_dG!z?%qjbH zrdY3mSYW|6y?h(2Of}u;$IyXBgylG{Y`}~?Jlt#ap#~-Epr0W7>(o)$LF={Q;Rw2G zgNj(ZM*1993g$iva-|xU>OAtTVP+sIk3K_^<76$;Y;43Uy?!X%@_x+Si0vcngW2hy zniz|XUZe+G!y~YyMrX$05@ZCBj=}Vf%#=Pfw#Gnw^0bt}jEaPiXTw7Ga)%jkrLN@g@r5Sd{u`p80K0|I5;uyPIfbr2Osj%pn|b!r*%jfh)|1|pe7FjfH12AEaz zjW)ze*Fjzfq0Nz0x`P|bP3pKBP<=)#x!`~j;i$b2vPp7MR!cfId)-;l4<*WfGk35W{3 z;QhMyI`3ZZ3EmFxO0V7XqUS-+XFP@{?Ah!&&f{_a%>7Md_HT4=b~n2#+&ReT|JwDa z>u%Q-u9&OORgWyb?EHuG`_4z5cR4R}MxBGsW@m=u1IJGt4>>M$oaz{HtaGe%WFmU- ziv3CZ7wtFMKZcCGYVWrnW6wbp;k&l4*zU4jZ95G)`X<|ATe^)|e`|f(`mpsH>-pAk zYqPb~nvV4ozpy-Q`JCk@%Q==|%L$e?ONAv@cvtv^@Q`r1uuE7EXb%6&Fhm*dKh6CUcofFS!6T(7uJrIkzmAT?r-Ev9 zsMPS-*hYcmtzU;1+oz3FfQJvQepo-s(iRw{N_AOIsp0-8Pga%Xh=$9?3IsAsDNvSE zXgF=mFZ7O1kpqnQU_?cV7S`#G#JhLqWE&0}D;H+R>6DI+j+`vRZez<2y`Gb4*leuq zkjptv!)jycLdWKu1%}1O)(9PBVk5ISGRm9N6OW;fS*+*@I?htGOelg>-5l6 zj@w{1mMt{v0X3)S3>#||$TH|h=8RSv%+y!ef#nh!s(m`udQ*5J6dxHuj4^S!cK&HL zRxjWY3Jds$$zbma2Et_K4N9llSfS9Y4r}`;6QX9FLJd5agetFUY^*zJ{yuucOw^f1 zp;BE3?W{*vE}gQmexW}e8K&3op#%?UBt+;iGcTq7BTb|Q%68@LwXr(EkBJuR36$2o za9VieGO+eUaS!!SJ1KK0xt+!Ebvn2Z^l3=Vhf|>RPpFjF(f17MQzxXwZLC=6p9+t` zYz*$x0w*kt+1Ofv;vg`Dhme7UF9KT&w;N{A@oCM?t#0g zDX=V&PS>^$8p?b$>0F{DA@TPJ`-Y+!7A<{%BB7C4=}Es1w!!N6WFAbf-RlC=&aITYBQbrN0m zLpPw$cw3MH-=4K=)>V8Q5h7eIgz@Xgvy?4LbX_N9VaUNq6d~^(Pl=k2hunj_uXS^(4XSiz5UJ|-+p83yPr(02%>lXbZ@ za~n0z55a`O!K+~F#a4-1N#-GBWZ^`&tb~=fOF+~P4l{xb2oNGh51Bxiu)Mqpad1rP zEfje})(EN0{36(Jtw(qs`443&p;DG#xQREO(l}wvfnUT-3BR{B4x0mJtrpEsA0TPR zx+tDKqAc&`ihk1AU2sU$sntn2hmJ>A&B^vAbx+mKO$D&zj^)DxmJT822eu?}{i6t3 z4age_Uv!1iL<3SA$nUkWM$&~G-gSBySfv#2Kz`5BZdUCaNbjcFw$K_0n3_mANBT3n z2v{nO3&Q{{%jhfZq=|vTCtUjdl*hx74*wrz`5`jH=%#V4Pu@Uv<2EMDlW43jXFZKP zSY~m)j)dO34T9Pyb&!^vQLG#D){%_RZDgAfF#|fu9QH<~-Nu@QS*f&g3`>|l>kyec za4&4SvIT84LKAsz#g9x(5DU@D5d#XXRH}LlS_#f0->t0f6pHRgznFyJu6l+?YdpylY z{gjv?6C4p>uEV3NGuCp2gWM_>AOwfvu-;dvA4i{0DpbUv)WGW2W9`iF3LD5&re08E ziO#0v51;bp3f8QIEve5KD%nt38eJ_O!v_dFvq7ZSR?k~QO_=>KX-yQddfsZfgY^km zxkEKgh%LtW>ZOe|In7xl0I2)1OsEsdu^1N4j3snO;XwZPxeEK!n}f+mu~WYhzuQfKp2hFv1fH2If?= zEv<&s=%xwuMkzG6KHjQSlblh9wqgB6DCMd|XSDe0(yEkw)Jm&$VnIALYstXOpld0u z{3s7r?QF@bNQr$D*?l^qMaf)mN%~4IMRCmOSPc?K-eArAaxxlVv<=ddALyMhtN>l9 zuB@!eE?hyH>1Y;M)y|yKB zdjHH2qZI+Q*^6mno4H0-F=}6vS4^NG20=azR^6;j_E1$>b^apKc8GgGx+zJq4+|($ z_N^no=x8^q%I0M#RDNnMNMI@#@|g@)GuGf>{Y7rkLYg6tU@=zhOj(Rs1$@%n3$Lw7 zr6?iq9dQ8-yl&)%ptRJidHH;J&CWiTL!ZT>nR)Z6ZT_JH55k{<7uz+kIr-+ytUP*i zi;6Wf<5+7+Ib1!OkvWe~gu@Z!h+#@0HW^eiGIQzT!7e1vH+_B%mmZy)rQ`-6)SFb6 zY3bP{Y_R8P@d5u_T3wcnjVJUQi6#{COja8siG~S8AIm3$(CpkJ=M%G>ok@L$6)@x6 z6WF2!kPRA<#VI^MGj-9-SoD@lAN}#Fo!$a5HTm)pNzFzxQyF*9Josca0;yffxs!h% z4q)CK8gr+62|{u~@R`=VNO8DicwU$dXL9ncVmMeG0%fBxic$+)Xc}*$X`Zr8deoT- z->OX50;>deN75&7h|U?)CO90k=faz+60m}qoRUt&>_U7gX2>Sm={Z_S49g&D&9*^r zx;tU7qr+fJH(^?be$Rm)1v?r2N`?}*-4IO*SaRT1RiJfP->YCy)9BoS6HA$3V_Vz_ z!x!t>5LMIB&H_Y2?CzR&p1_3iO(^{w_T_SwDfcz^Ew zk@sou-QF|3L2s}3SZ}2_-SaEY^PWdNw|Xx3>_Y@#m1mJha=+((*8Ms6_3m@ARv_r! z;;wNQxSg)IT|aQ0=?c5L5Ch0`{@wYe^M}q)JI_W0px1efQ*^xU_>SX#$4!p&9Z|;y zN0q~E|GWKl`{VY9?RVM@d)U6tzRIrHMcdn0um6bcX4_e|-L~UxmDbm-Pgzf~YFJ6| zuH~m#m;a#UvsjmZx<$8awA5RcSTcp@gf9vEg_y7jfE@j=a2lg;tp!3gx>`xak+1*; zgO>DXls&&-8iTPh`NZZRmakA$pGULxDEn^VGzQ&T3(OuQmxBpYfJ;O#pCW4!yrL@@g}g*G_RQL8jKMQ3{s30p zp^ICz_&92r3a24D2lHBi`Wffqf*b`@JxydJJQOoxPp3^|#1=!`CXqAeEpkcI7?lMU zs9OXpd&2BHxziYT6_&$daO|o4X$-k~3n`q`9ElKcY!s`@!t6=kG=^QCg}X6P_JlZ% zA(wAKWQ=AC_U*iBjJO(0D@=ZbLE+6&&G_Vf=Rp3l)$YT4DwG{%`9%^A}$?UeUpO=x0N z^`R4Ei1D$<)=yhu!etA6DutynHAQJ^>cNZ073kdcXwEqLJWP8M0%{pIRzlj)kjk@n zSe_c;A$0$^8qpVLPGg{!S`wQk&?4G2!S3sx7EnaKrMeRSaWkf9Oj#*IbB@YBL}$;k z9r3Q2Z5Qm`+-b(m)(IHKsV;4ylys!sI0HqA77F`O|08-it|s2&ABWuVSB&4GOqeHigR( zTq9r2LB=9bLUW zeFHn$^|{6#f(a%kUj<8+S;FF6mqsb(A`6Bp<_N4=4zTMojW~53dRpPT4{{7~ zQ6pxqvTKWtsExHB6#JfGl8(e@l4dbJmu5t$fEG-7v>b6ym|eS+Qn?!~w4Z^`(y3{T z`$KUu==UHjvT4Ikc8zFE5cb;;KrL9af+_LmrAnBgI#duXCS9FWpLn5O)+NL+_?fWXxFAlsj7 zoJ=D>HEL!RQep(@4bVwwNW$YGwN)B}Pevltq`^52u>BdvD5hSEe`quohi^p77^#LM ze54|!In({s?CLCI_^``WbXhy>at*sW#|TiDBOi(VA2YA1VplCT5Oe7`qLj`&R>Q7b zVGP>Xwj(~47%b!@BA)>B5}03^PU+8L3w$2xrxraJWmm`sVl#zkT+$+BR}>nE%dE8^ zDICPad(iPp*}3fULP}5`^@*x7cKJ#JL7JTw1SMz%G!#3Fk~H~9>tg2$ zyDWoJjU|==tYN_BARaAcmr4f0HwBgfXf0@)D7!S15`qwJgnh7Vy%WaKh{i5SHxR5T zwjhGmuVEDyY&3RBv4L1kJEVgWgxJ%x0@Agr7SdH;HDk@QOBPb1?pQtu68m80`rzzh zneuLh`~ki(hF#QeY=UMgv0%9}VhP-fpP4!!!*onnm8E3OP|=8~t$^>20R-MjYnCbd zffNsLiIycs%7ycd0a6T28dgFDFh}cH4UB_U=t6cO(s9&2dNnOAfl0+amPzTjQVWlz zrD8Gcf=tS&&AD2&lU-0`^uqJB?7+~f-C+Q?GoS*0+%8R)Jx1x72G-KlHkia*NZLZ!NyE#?jhcB%}N7dmt8^+LX-z?MM0e^R%!91H(+C;lNWI7lbK^gS8-JxQn$NKm8878;0};H8J|kVpj|mZcepnH19lkXJu# zHEYQ?5HM*JPyngf^@t?X>U17#4uz^E1M!nWL|9is3nRQ*oogU$QU!s8_)<%`_9V?$ z?KKcJ$%F6FsjGqN90Spk3WQcEfku9MZ=4bg(Q3DmOKCy=P`Z&r*iyblDaGa`*dNt- zMmF^S5n@i&Wz}g0oU`I&kb+0Ls}~q>$PyW@)J%${mXsjE*c}V5GT@ErNM&hbd>TPq zA7vpP7l7kM@|v8e_-CQxR@IP>t183R&U6|$kh^#Ywh#7M!G;={XTU?N0e(@e^BO`x zfZ|^P?9vMiuQFsRY1Y;{%<_HBex<6i5=B#v7$Y5~1ymaD958sGzOou?;iUhY4_0a9 z|F>BWF!>ev%ZLCBV$Z)K{aJbmdH)-vkhD%(EWRt=CtfBtii>=I^F5E<{5SgIzV*Ih zpVRxS_dM?g?;_6wo>M*BJ$}!8_g~yEx%a#K+?8(G^*z^}uKlj_UE5ttogX-#b$-gJ z!-KDIN{(MSzT&vf(P)3${)GM0_F;RK?dP@|v7f%dw!r!iRL1->5ik+>s0cJn!>r$J z*?=W^wEt%}mO}@Xr3a_ugV7#L6y!Mc28YP1DHAgDr{Mt9Te@`2mdKx_7Mbyl5kf}Z zG#r5%+)eG(Sgp`9|6xrR(wnEZ!fv-)uwE;UI5s}a6*+~R=5D{>)_H0}Mi6g;EnlNF zx0FW9gtP_Ia2Oh4Cq^fbRS2%e>N3nJnBHj#7JId2dNT@fS~{^UDn@JjQN>gkji;Cs zu{F4GynsXuhrIV-IF9}DJQ-CZ$m^%c$H=sB+Y6EOA*?jTWWx(0TObvCL0&A?7&L1S z)=glxio#o3q10lI!dAVAAXQJpwb0-xMEAv@g0bu1zy+~51&~@wTld0Y;t+GkYly=0 zXt5w3I}MlPl>e*(t6_0qcL(AU$X-_0!u*>+x?GD2zM^TkC(V{_>@`3lE9r~U((mL> z3q0dpGQH8px-9+Jx`$Zd|6%XF3VTb}owttkS-ONSVgCHAjcTv^5x@##!_@(9VNIjW#GF_qLQ*gpW4 zsce7;d@`AfOL59&Hvv*XU$DBaLHS{xQ3x*S>cqsNMCkBj3&r$-9zn>(q9$@J!s?kr z-icZu5Ftwe7!Zj3TVM&aIl!|45ysFBhF5?haA0tu(;F7eT8p!v0evY)of#CqA(~tQ zIf4T)PzL)xG`9weBi4W(RY=MsFa)rYiis;`27Ol%oeDXzzS&}rHlSg#eP%iW7piHZ zPJ=6A1?$p64zSpI8+DK7X35> z`d7M&)d!=ViFW|52SDs*i=9v8q?Qkk%BT=JZDgu9 zSkyQpmuy5l$|eF7A~y{)!qx#oiW-8+m}0REHlVG|hT>TR*AgN{7h|>n{83TX&{Pdo zl)ZPDUX-h&+M*0FpvdKeGonK)N5B&=Y}EtA4}q4&ru?2{K%-j#jXGk=ZP)X(s91#O zLa+@~#YW{cmL@8{4KkqL%@j6cEFCf=62c%VF0+<^99ST5h0lP_jvXmp`PFSe?dzrr zh=uY?X9FrA`vPF>i=YT#OZusg z0rhZfqzwR8SK$TY1JxY63jCh(V}>yb3&VoNUJ)$E5)5M0bDLpwjeIRKR=}i>uzLE> zswzZAH4yMRfA7tJ+@dW(<%euzBzV}>3H0k9<~4(_#{(9yoK`l>(ozSDjAzu4VJYeH z%7N|%lu?+|(N6;NP74C%O~Fp3LFN122K3RmwDZFt42gFFcHt`W?=~pk#Td{` zVKbu`s@j$2_l6N`JT^6aY%*{w$4)VZkE45Y{zK@O-!xc8M0`WVnf$EvM%8QRnd z=u4q(!A9lS2m>l=6TBQyBxnPtZ$<6HW>FV_oQud}+VoL_cZJq|j&BzkDHx(jYH=w7 zU@L2vHB@4+8ZsRF@py0}*Gg0&tt%XKgQE)T5>wI%fJ_@|DGd5~aLPVrDVa3(89 zQw(V36)o#Das&W=7r-|oeWjM;ThJo8VuQ*T-3_Sg$!g2Ygmyz~qavVu9%DdP&x28@ z0YNY|bOysHfo&T8t|;Vnp?|*9R?*pJJ8+3#l`@9vDnBLn-Z*t5eu^c$2C3@_EQK&m_?X1<(O{hT~r~CBr;*5 z5QYpNA8>lHeWRijV3hy#HDD>o!kUPL-GE0SJaod`0R%~)p;`HGi~-BR8W>}d)`{mL zgFG=kG0~%vhyK}Yqoq06fTdwJj!mou`k*kS1b|V<6wv~UaJmw@!Q2Vn?`y!!kR=SJ zldirL8_#ue_UJ!1gd#9girmy*H1*b_7dH z5V5#q&BZ21eXgN6TrpA&$~%1xm?g5{-#|VstSA~WGDkz-jx6j3t&W`Zbd1uF(^Hf;PBUQ5NH>oq1XfZq4e9NDJ>GyxqXS+edBhnX5 z#du@l!$=YN|I(BlivLo7Pv0ZHJn!$`9p33))pM_>+|%3rl)Kv9$MwDIS=W`WN<{Z} zalY=n(U}h~{hf}0!wz)*3i~MA*T|$-X^XMGZry5~sQ;qx(rfg-+AG?H+C=qt^+9#H znqc`9c=|Ierzr2@Wheh9EzJeHp3@nxY4%KHi(`N#V#@-R_K6}%7CcP|g|4d7cJ)~P zXw29zZ|}15{oLDAQ(Z94Q9a!b|1Vi;iV%5RyS!a3>x}iv&Yg>8wd@oZ>^4qk4yxs2 zi--A_hAy*qMZ0=%K?IsHX^U{41e^5*yOaw$jFViFlU*=OaieEKe#X%W$Y)J?J09w^ zE|X&Kl9gr*bph7qbQa>(gc2_VS|0lspoGh#;xek(NgIr}Wng=5lk5TWH5d3E3YJIQ zU45B7RIPlQbFbu^Im88nEAyQR$9L59y1(Y3udG%!`yZ7&CY;X0Qi!im0An(ZNp>xr zlYh-hYffr(HcL+9l3XzJQEN0iVWTTbPk=*cPs2BzB!}!o7i@~$9}@ASCSvpWYbN@H zKFWD7XG<=539?7JosgSiYk>q2Y&-#0T@EYjuKPi<${H*iq=^p)r)Pc5UvtrJDq0?V z!elbY1xr2m3g**ts0Js%L%%dj+5FN?lF6ijE?7-@aHo+phY!V37no3g-6HjlW3z%I zOlI*d%xJfvwE#aPTt<~AGDup$s2O>mWR?*pC!uDiBNLvX6KKynhvz-9TC&KC<(+_L zPP_H-*Q~VXHm&KLB3VryAiJj9Az{KnMc@(~e>1U{{53Ou)*DNy_e*;w8rs zF)mo;oz5(9B*S@CJ0<|wBicM-Kh}3`Q!cN1S=OBx&3n&G3{wt#9@GvB*K5b3RXdPZ z4KgaW4xC)tD_hU(xJB~H>BsGujdo-~3~N3RwU<3P9u8rY#vMBryAhZn(}shXvDGW15X>U*6mPs zjomBjj_<`AAde|RQ)1gyZS`f^G(msBuUyd-E&1e}#&b9WZNLs#L3uxO$kq~>J9B!d8o+FGcVlaaCnyx^5=jz4|_+kSP| z7Uk@EU2@Lv!6z_ro=LEfJWNKMKMg0!?veS*mHXe6?520;4YC33fZ)gRQ`LT1v>LhA za~e^wC<|Dbi2Kr=KPhJ~>?ql0pX!23#_1dhwgf7mT@J_>#E2{l;CMS;TlG(4lx^xa zlFQ6)+}CRAD?FdH0nCJ@>A3Z=5s--k_6QZvhp>CMv6Cf7Bs6pp!}7C*gXOP~LMh~*bpFCU}aU*nZE z;ybwD*yBDU9vIpZMR=7*x;SBLWqye)I>66Mm)Ziz0zt7NEWJCG?dw*_a+7^7rLWWJ zT!3;&Wn5JSByCL@He;Buge*tyG@2kbDS?k&ME6Kfm&i4Hrmmv%Oelf*a%~ zaWF$3rL7P-4a#X^BHZMJd27)t78TzrSr>b7`a~K^IfI1PU2OVIu&$giQ(a%7gcD3T zIMzZe4*^pag^Cr7m#*t7sWG1RSiDp^zlyLAi$!(HTa?|XT z;hCaif+zk}wC?lE?p7qTsScNt5b0xHjmYUp<2EB$Q(JxFy&bk`@kPH#mQ(CFrXnmc zb!kh6fe#zs^tu!0c=5i*e@vAeXV_fIun5N~gylvHVWNREo%R?^y%XmfJ%3SMrQ|!o z>Vlu#;-mwWjQcoIO}9vPV0n$E!rs1U5#>^umY9(kRYaMl6QId7KpJ^y<$_;kOHTE= z8$zeWi44w~{SQ!eO&w2O0;n(8=KjD54g+NJ4Kyu+ZDerN^hBsiuxpmq1R)!cpI~Mp z_U=XWzuN1UWOmo&JI~Na9I!YW@XGOInaF?(i1yF=$~G@NVeV%i8g6v2_eON6%)8yHftq^goAr3x%LWw0iw zO{KAmyGs^HOT~$05f%_WJw4XRoH++BGNdhQuspHiw2Cieg@twe&Q*A)IA4mfOVX67 zqCu;vg~go`N{Y<)Ns*Wol2>6mkbUcyiTvIT{n-CP*?BG3Z0+HhEZ;DuR_FzmNq7T3 zN)UX}7pUSGu`*~jxOX5)$fRW7ErXe}OdYpAru);f{`eXpiCd=PaHS0`3#rnAZatFa z1Lk^&L&C0FhEo5>Ercydcf#~^LOc^nm2*~_ znnvCdA!vaoMjGNpAq5%3iCJ|bytE6BG@N?1Y+iPS5bgvk8g$qht51l_wVRr5nj*PO zTr3+T>?Y7`ambNt_C#3e!w)DMstP2pN##6IsdL%l!is!sZAd6n)qEn{w2KZk_M9V` z4)?W6cJ$2?#* zt%Q|7u{&W(2qQm%FX0@3Tq@9cu9mPk+%7^}M`W4muctH?z9w0X3a|)HtRhZt@+}^} z_NIdB$0y3#qZhK#f@(9On#1sqUwzw=+To_ymA!zKII51V9LWQrj|d-fMioTs<8rau z$E6S060R0fMNj!NQF)KqhP z9;3Idd8w~##>hDkts~7SVxbj5ImfN6>+=^jm<<>`yY=^jX3OB`1{w&-aQv!z*0x0@X0Nknw9K5M#TYm2 zKokiB>;XZbkJ|u!v=MyabUAjzr?XN?<4^JkV)Bk#Q!Cp!b(N{#k1KWoa_hA8$C&{y zbSaiG-j7EdAohUG)FWy)-l=7@$`5Uwc}%(8W6r!0MWP4HfnrA?Aip$xlGzt)9=nwuAE?6c9N&^jz*0xB8i0blKQ4# zyGp?W%7tgQylYC!yXg3tj>L6r=5AN*^J?W9#~reXBMMu(Hv#ulh;y~Yo71+g^?tvy z`*|_*gJRVfK5atlfxH#lGX{?QRsMgDmDGxN~ z$)eE{SwKWDzw%m?i}as1*nTb*SoPG1EIH$P)3nd}7l}=za@IT@PS#2ILzs zo8zy#HCGnR9q&R`32sjj*_>cZ0x+DwPEmOXp2R_t0c2X~-dm#LC_1qop;VMG6|GYJ zFTcp_K)q6&1u^27dd9hb>c zeX>|~C3ZM!sDSo*-kNjF0)sR8kfj2+p8(&m3CI-mQZyE=+p@EGrFpuK%Wx^PWj94k z4N6XjPaSSDY=V3521o~PLi|Qr8)9y#f2XGBq*TZT4IbArZE^!hxhYrhf2HzPxU;b(CVsplf9mAVB=}qL?fFg;d-Ol~k)`h7(u%o%R zxuIu{b}1P+4aj|($393(^wbD81mwbk#}*ymj-mE@mJ+&Uwd`2IC_Yb1X+6}|EE36t z+EsykPnrkPxYCq_f26fn)jFJ zSpTPdv_(g1t1pvmNdKRp+^P8Y`7iO8`iBAgzsGlxufY40_et*-MEOT~KJq;1InOi4 zGt{Fas{bl?J?`u4?mB{K{_|V`*9ccf=LgQ)oQ89bv%k~gcoV4qa~vJ*yX>>=cH3>X zBI}RVe_BWBPXOT$Q>@-y`&xTkyG*Oo^0j#NXZ3M)o4QKPS5Lv6c=uYumYJ3)M@GQ<ByjV} z4Cty5LaRIJ>bX6N=ASEH5*-3Qg2srpSYZ^VJ2yJ%+V-8xn>NT&y+Z&*zzb?oR2+MN z@u0Qck7!lqLQM+|5r_%VRtz=#fw@rpgo(5Oml`fc27U^zL2G9oQf|M>FF6ki0nPxC zTULZ=fr3b}5&<4U>0ibudw({+Qr}RLJQj63N6cc_F59JCwyWjj3;~n?ScB+Mw%F}E z>6WIS5}!47t>_RC2eQ+XCQU-Rl1BOf>h%X^_8BXi79ScMX&O3B(?{&y5f@7*9f|Zm zjgn;(Lck2bcO_n$NtY;@;bJ2A9|Kx`w06(ivV2Sk@Bp|;#DD@C)d&PMf%rP1$akIRv*o zPpH;21G5SIRo3bsf`?u-6*Hu$y0#LyADqRQBgzAZyItQ&mTL^b z_fE$zc?GA#bi*0{p!FmPLm|MDlo5vR1B0w0rbkB&lNebKFt?G#o^r;(B~cGUQ*JQ0 z67?a>3P*jLi`=ZUeo}6m^^tt-86i06X&I9JnWEcfAXh8QAml;+Tm01tTPAM!RI;BN zf)5`kB*A_%?x+Cz5M6@q{WrPa&}YVm=Oy=3AGj6&Ap00ilVzr|LcpQW5{F_-VW5Re13YteU;CPgy7 z!Rc51w_c!rd33>|SlRBz5D*1&EzMjUjBF>SY<-rb`^VLI^%%EvA zjR^rNAT}lp6#E?%!yxm7yUx_5qLJ zEmowl5Q6|GCQ#-$MX4=dJoRvOnQ5@^AA-}K-_PdlnH3b1+(FY_Yn1R&)3p~Df~%e+ z3_5Fp1OOf&aujd=N#K7 zD-908OD~Up4x*3jxzv0VpK(CB;6Q^cJ|F})J@2`MV-oO>%!>Ll6dazSoOh~I7K{nO zLC+^yt7Y!jY>V$xULM{gi^YcEmFMme5&=#b8Zks+%XY_wJS~hVCoiNPf-9^H`ZOIDg^d}enP5-|ZgR;uBe4K(@@a6E7sFvXClRGP z^iYh~dbBWxFPye@5_`ayu&i(nP{_Ma)AsdQ?HeeICWf5yXeVU>ZX?)3Gm*(32Nbf= zECTQ8K%72i3Mt7UIJ0@80+9hYGqTA;JOy54JV8DQ2vUo;=!5qu8$!qAYX*hjua@l> zx&P1{fMiLiu1D#2H!9awe~gF?ETsG5C9awMSyO%_Dbps(7$_pcuKoNUIxkZ}I; zvO#)*`r0H&Zp(!#2-ZhSmFt49%EH4!DzlEp8bdJuasnbj;fz9%UroTP3f~?@xK#%A z#3RavttKEdH3VNQo$+J?!kss@2~z^dW?BOWUA-64GcCF1v_0$BY_ZBWjtVL41|q8y zEmdUe2q5&PF$$OJh#%V4*59mGu1md3R!>~ZyP>eHVXK8)(YCzf{e70`+pm@7hn&fK zjj(Yc#3KsGfa-Qt^wm3+&7(}ceA*h95|kZ-nSmmNs$rN(=$8@IKq!|e66CPUH}*?F zbd>r3ZQG$e-DOSC^h}If-D1bY$zNO7jFYJWQ@eC=!Zb|u5*RjW+A^>mTd#cNG^N?3 zRqURkjvy56QOh+wdT0mbTL-RSrGz}m@Nd*s zd8}EBo3M2Y2dFyaV06-lvTWjV{x*G47Pi>3`X*8{;46jEtfEYKdQU$R9o1i!AF_=1 zRcac!!Ninq@9S09?1}y2Qdwnq6E8Jt4s|^$R$OI^#VLZ{+BR-rX}?GAku^#G&r$xZ z_+Rl~<6q(*;qTyk(s!cN*x=c;B{9<{`QeqjT{D7vM^q(OH)+n8{GzZ`wMJ#C}3__-;$wsAzu#D++kHvxklsJHBCpb-TZ6s25)wZju&seNnvhikFHzkDS zDm%oPfUq|L>)F1Zw)|K_XH$h87s47PU5>_KdNqZSHBg>zI(@Ni2$xBHu-&U^C||i= zzIkv6tCo~{{$izj?`dEB1!c`wU&!J)A*|NCNO731tB{Ed*U{G35>j(+YqRmZc6`*S z{>fjN8vo!>WZBYda~g4BPW$3TNAgFS3vomUE0<0%Dqa{RZXcyYJQyU=(RP)!4u=
gn*Kv7m{272rx`Fv3s|{#NN%W&RCIO?UnBs5^9igmS&$3 zz`azI?2c~81OB@_P(t4jb^2_|y~Y%?5<)<*NFxJ8rcz<^N4AyxioFlPq>u8K9V?pt zmVC#c5a23Oq(IKH3Pgez(v`13RaAGg>#rNiRWD4FrQ<`us<23eNsLQQXiJ4Vp`siO z(SF#btov%WEE^jF>VyS8h)?ywCHNkQRIYDYiK5v>HDAq>C5MJ;q%cJ56`5f$k`I-l zn>k{!WgrPUb@a9#vr})8mEuAGlSt_dvFnk<<&cGF9G^UThNVIl?Hj6UQCSFBi)eq8 zv2M(qUnAIgJ1_*42ag%yX^`AkxB%dS!G$(p z{Kl?8=3rTPc&LJx1Tik8@N~q-kITMcPcNQw)@qw2;L(>s`&X}=J_8wfHH zZ7Rlg0qqIjM7?&_jQ;B-|F{rP8FCylAO?_KgN!eY)Rg}mnYY=*5Dp9hbHROt0@Dmz zHXf0bnfTOjOkVVjsg1;jfT)n4FS6$#6rjGU8EjXsnf5`VY(f7J5ED{=qG?L|OrRd~ z{)SRz_oY9|azjFZL$KO_MNQ$u`L%m@pz~y_Tm*9<9CtJXS;aq$k#+io0C|u@AkJ_2 zPf%#}(P>t5lS&H(S`3RtkvzT2rY0alf*ZI@O*q0`4uZr*LL$( z<*l77Wba0X=5y~xV-uNytkuw40$t&$L$EHkX>6YeU8LxEc+rrQNS|yd7hd_4tR3=( z=DC%ncz4K+`uO&Hw~3EG14yQXoCILb*`pj&|&03!Zojaqj3?i(vLH!O4pPepRx zAQqu%B`u+1gpi|CZEthdUYoCk4y4JhB!uSjF+-wMVHr-x_7&9FgSk&GmgR9l8m~YR z1|Swc_IkQQ71?y#S4FG&k^=o=WcJ)1Et!l8&2}O2n$wbp=HlAf|4|Q$H}tXqjxii3 z`dVb-JflWd9}=3?BK~1I0~Yr`+O3tZuj%uVtP>ZS$vaU`^fNMBx+1^|mVw0q^^-LV zmRux@CWU73+@Lc}&U`dcNJ^1wvekVlbAqNVdT3}muR|e^2AZ(jBRObo`);Yp`zAy^ zAzw2n1VjTJ@T4|n)1B^J?X7PaS4$S>PkvUG9umSPK`JGc&ctMb;Tk6qhP+K3M@nW? zk*qT=1k?hly40-V;0ny_el$Y^WtbbtkBX@Ds($SoX_>Gh{x{R5oE8Ftf%Z6JkyDB* zj4|4UxYVKX553b$j@I31q7f29KrvA7Xhw=nw*8CjXRJ}at~Wt<<3hkMPzST{CZIb3 z=@6%SSF+#%go#_dF`bY!kglSk+#R%osX6Hr$BdT!9TI}kfsS{Q@mptp2M?etk;;}* z_gl`6A2O_qtdkZ3fPqf!KB&W&7tvW6K-RatcjJD?u91JlC7tR$$7c68D^3YbW-)|z z5a31;O%NLuD;&NvVMYf4v1A$D*Iw1!#RjiGF2Jk8)&}=~Fv-k1@A&PIB_?3PBF2V* zbRembzHu?qjY3ctcdQ_PMN3#~7n{J*Qn2ib+8WirG23e%&9g!PK%|00fCdqeNq2UF)*dmzRT#?0|9C{QDi|D)hq#`8JrkkX3XK)QXq~+>Uhvt4{8d~Os@?1(O zSQB(-5{!8wN(pUjCbSm@3|HA2hNXI)zqE9g7im=Ve!9}oMi^`cvgwMuY&#pwCMagaUprIwBN{9Q=QL9mKYoqf}XWd)w5#%E_qMzNs`-XF;sOI|mmSSgcE*lP|g z_k1Z!CWOYZBtxEPdIPRFAm?pEW2CtKiNne-%bR8Sp`o#I6iHKqO#*-rto62jWNX?M z<>qfq`Eh7y48u^wOX}hBKjCnbpPI4T6AW{ttq?0Uy)Wqr`Jzs4K*5>kDDZ=Ow-aUI5yr?CF)%9tNe=q9q;VNh z1p&MXCmy7yc+`C-MLFx)XJqC6#t7LY%}!bYY-xz^3D8SYRxdDx;ekeai~L@I8!RcP zAGx^#u>PW-kEJVDO+7<0ooNhbX`8}l=^`zFnfBgXO)?-UjyjVzFa zQ!E#Dm!!$a2~(>NT(6vGTp{_S8fn}evh^12-BtqO4STHUSWic*)S7yiQf2)^0a-86 zNadAJ`wsz%$cEI@A+&xVw~&=Apxsoxa;b@S$TNU;AiZZ2UR1z09n;uhKFvUzk@u`^ zJCmkCiIQE>D-SB0emCO`(~V^ILX8zK$BmyD#WpMmb0LCDD#~ir`;W|d?i1PYNd^!S zWCF^MY+1ZoB6s?=VIzkusWmt4mYu7jO|@&Z0XPMzUDOhYkPQI>4K>dYR%06Wp zKwHq*QY#2zNY|D{#JfLfinjaU>TgYB$`~V&_dyDd&Y%lnu~q^-9c^Y$o1xGP#wZtD z`gThz0M?+hm!Ly{O2F&{H3il4ad8KhT??z$s$HcugBfrUA$YSqex`DFogjf}o_OHnyh&W>WkS;wBd~lvM zkU0T7F#lnEr_HkUGC=jDX{1of5zy*V>T`-EvuQ>g&*iybM#pcPx%{VGTYm!eryZrE zswLBG1K<;~IpkotU{ouuK)95Uzk9Tv3x90d7e$J3mg%^gYygcyGn+cvvNHZxqj;UQ zXGj>I`%FDM(*S7YcptIH@jjyVNe?CT$SB#h2?ii2bT-j=kqSP(w&H&^NNknVp4OwJ z1s2ymGE}lkF#tEAd727V_&PAuwG2<2Y6I`9xZK=*CK|wzkg!25Fc;a0x8YgWnd9G( zZJ1>A3^-f<4n{xz5eI?6)w~K zHrVJR^;;d09@toVI9ltf`VH?XS3FrF`&DW5c8jSaqGMZj#sA$gx;;kjl-LT|f40`U zr`$YC_tbrRoqSuG(Tn9Fp|Qi$PA4Fi@RY#H9*zk?N=?>?qm*2q>UTR!*2c+-sm5t7 zM<;~_l4_HP!x~?rhohB)OZ#Ap5_-neQ8J94a-XC*@P~c!IP>TquBL_p`R-z)2X7-w z@v)%Zz_M0b^}oj_GA2`kxNHIDpo)gJv-*VtYdiiT*$y?jOY0!5{pz|V+`$Y{1R!+C zH?RrUHwL@gZG%dc7f&%U5OKz-Jb)x5PKG8*0ul68nBBYE)vphi-ZNbCk2bpT^rxcJ zDjI4RLH-PMw_CQ>r~Y8-m(j*4Eu}Ib!&1s9@Y0@1S##8M`owh15glBr>U&z_kjpoT!BH!!WV|LRf~4ajTxL{`U&HW&Mj}ij3DQg zyqXSgIJjf&!53xE;tT*m*is8QN?_Xa1C?+Pqjwa2mH|{q4w}f0t9I_TsJX@U6?MQe*0uLTX@QiwYm#M?vkd@7a*xjiiA~CJ zepjsc1Dlj1ORh9^nTZCFBvS>O|Ka2wXMrXYMsUE=gJcb9c!j#eh;oQ-($-q6EQJh6@kcIla`Khi5-xLODhl zz@LzqC2W$EKZES|n9JE{KfE99Dr*VzmuxoYRhj`f3Q3Ao88{FeT$I0N4sNQhXjjqF zZGX&Trh{&*0elM0HmaCY10!z@l)%D>4>JN(xuJ$ePb@g89 zo$UF^bERjZ`)Bt)_e%E&`2DYUEdkR166pJHI;xP<|5^Ka_6fFEY}eZ6+dAR?y-Td6 z*1`H``a}9f`V!o@*IoNmyI(s85&yC3_v*9iWoo%PQgv7kA`{?TOIN(~|Cv992K>>a z{*%zKHw2F-@}WY$#4*ZoHAGj_^R%`)JgCQ}s2 z{WFoBGAeEcj8GU=NRJ3miT~ex_5OX7b5pxYF3CnS%LvKfl0m0$U+9&{!&;lvMpV%K zO89J3X~{I;qb36dS+ZvAy@$4cpcA5Mv8@1*MH^yY`^3chLTP>piw>&7UTA2wy@!3Lbu5`+kg zBRra{Qp@6#dnlXsnWuKL(a>@d;0xhM!)cWT+>}rPgR<7F7-jRMpJX563^=LfiIs;$ zpIDN7p=*>&d-||qxEIKx2?qSr(!`We-b8sFVEc!~NV1-RL*`c#DiLSELoHbsH{n{W zrezhfXc>Y4o_|uZPB!46mZumDwsa*FF-OYbr7)7n2I)gqC>N!hJHlWC&T2V8S@^E) zyIM2`_JTw5B}oR{)HFlssLaP*vcm6?LAle-!6{s!Y+AKP)<`hmt(H9|A0B*q?RtEl zvbos&1Th9Y*EAvM4Fx2yL_RFSq%Qf~6og|9IIU@>QL)?ryaG6{BPFMlDw`frWCNlN zc&tfJq>{4|(q*Yc1vxWK*)`T!+`4^MJc?R6x#EDO}>XuQW$Y`9$xNS>8t{Z?M7koqjexGgkqrADG9#8kG;3&X-7o7JMY&sP zlC2qHz!A=a0jnHkXGWr+vH)o7O4{c1#s@Eyb(R|Q-6T&qL!B`-D2^K+8`wU2BY6cH zdLzn8Tq%TP&NXmnBq2{+HF8?Qa*;%85BxcBoL2MCLz)s8qgR>35J9KHF3#k z&I$EaeR<~@i3zfC83tVA*z857C>aBaRR6e-qIYI(2@XcizeCBFu!7*@LN4uQ%QtJr zUernQs5EA~NnUb>yyzkBDKzugk)P)To7Ltcv>8t8U7M7L-D~CB<`{6K^Ju_7gZnH1 zex}(w4O#>QVjTUM9)0!#c z-;um08*tHQVVGzti984hlEyJYQ>v+|4Cf{~fD^nm^VUt(enR~1j<+PckZw$OD?u7| zC*}ohcfxy^$KEyaMpD8^ks=6g+|o(}LM>~?BCV)z{f0lR3z$=}B*Z@-XNjoK_L;l- zM%j)u1CRh5K+eACRyLGxzIXu=6+(i8Wv$+2>!&FDJ~<{U&M<%upl$n4rgf{@f3||v zqZ=1|d4*&=(g1`2UfJU>xHhXzw{2C7uLj84qYa=3aPo=I)Oy7qZ@KF)B`I4MnV^k4 z10VuAkaO`>CI@h54X|dImC)Un1(yVRIXS$PoGS2sz{uN>l!M#@_2TAL%!~lgzRV2+Jhs)l(;c)43xO`T=tTfq(APQ()rv;&MVtWKA zzNVKm3tC79?ygD7Mo9LwAaXh39zjwf(F8*00mzQT0$S{tioIt^cKJrW3m3gJKwo3=Yl5{oiEfmj>(y|?Q~;ZpR9wIJHb~mIH}STp?8UX!i*fM<%OGc$@QvY?55#Iw`(Wuq zR7s$uwi>^cEw8}+MHm=Fen7(Ed#RK1DF^>;bQ8vm3hI^y!@}YRWk+(22|P5@@n%YJ z218LJhGsmxX#(hrXz5aDF&Gz^sW36~APYs>rNwTnoMmDpM;Smb(8MI*3j!l?ff4wy z4uUoTOH`XQ1?D20%!M`RR)e-~{jzj(&&V-=VZhQCHtFI(9gI~=n-H&wln13kD?(zQ zUe1;gOhTr>X^{GZRqA^O7oKm5`@;+%82W-wGMWJ!O-XJ0iQd9P{cclf{_S!oCK$jm zPzQuX8fZeeZ?H6Rmjq$y$e9qV5UvDdMXD&R3JM*OvJPR%1~i8?INvT=EiwRb$OEei z8jFf@q*26|feEf8m>`~*B=kL&)nbxhjUkyo=2;e8WPzkC%r@vK`4F%JH4st~$0v#} zO=+0$|60Et6@&gGUleZu3_&IlGPNOp4F(rRIpRzXU2S|;RoGN@N&nAMo>%;L`Rfq< z|D*4A-&)@w@5kO7y%pZBo_9Src^W*~9+&$SME(ce$!?eHCD&G0(3RrSoClp-oEc7+ z<3-0dSOhY~eE{oV6ZqM-*Y*$FG~5XAiS=LBuywYzhkjJwtDmpW0s8+n?K*9_mZJWq zK8ZYllhrnf((aCFjy1j3DPeZ{i&v9=LBA$b3jHH zVK-U0EW1rjV4)))RGX<(yIZ0Q!|?ZGLlXI!3o(UeRM7Dn17kHTGk5Q3?s=_jgS|tQb9Sl9lqq@Zw|Rbdqo}9`SQEWeozM25ABlMf@Iv z2_q6*<_GIx(4ZWzLYhN#UTJNO_Ux=xFPdpWP7lMYPZO97O2{EjSBVvqf48bChO=fO z)0B3`)|z{(WD}CYaN*M^5t53e&b*ps=p>Rv)6pO4>Gn-4-h5xyND0GV57U>Zkr!Ky z{t0zcgmh7GR-i0W?WyMqbk@i2gY4yApWRr%6;Xo&~Xb?)~QMTX=p(5iwi-PSxlJP*);#DJ2fRJ1)tlR@Q3a8VJ|w&pE6#Wd@rhT*s- zvkWcb49dELYdjWVwv<G0t`c#(ks$4ff%<4oAbja!$v~C9qgvVW zz-;;6>@XbBB*o@a=YepkMcV4-Xe}cVXk7^NNai}R<;S8#ap^ZUMO%kM%9HcXmu!ZI zdy7wONdOz#51JRj>MP`s5w~Wch znRH;U5e7Rl)kJGWLCh%YmfgyId1kagS{Qz0`Vj2LDk*{FLx?%hXpOh{NO-;Vx%-qy zR+~`ElrTKS^dho*iDiiF|E0*1TNSt{YFS5?tTusvMPc}gN23}Y?X-|0 zIdz20L9+_Md?hC^pVS30`HfTL_ZSt1TN(BROHT|cr4K7+q#(JCk&6tVagm0sA3Oxx zpz<_Wzji54-nvy*9~h4Kn|q>BWh(M%-J>)ep*{iFz z7Cje~+!Mp_Jmu?XpH{7%pnrq{12;Wf`2WgBCd)-DW-OEnAg`JSP4uCG3?0K)D#m zKmg&<^aGjIDAnx7bGyseC5Jt-8ueuFJ=m)8pzf1OVOG#;J&DQgW2!zoRUC+a`6 z^cjdrz*ou)EQaEdAPzmVrdknG;4=eb2Z!N@ChRNKWGrnlE{Sb2!wR^8OU!gy}Sh?!;L9%rzVYrrg2=NXyjsDWij{I!a)5aaE z`rQ@uHI;xzv+Ef>(hT&6&1rC5QS`kRs2W6}}Dz0ov zR2>X8i-J)I7e?e2+<;Xjw7qatQxfbEWT_F@0~iM~x74h=T6SPW81818HFU(`Q(#cX zH&w$Z0w+X{|;QL07f7xiU#wMk3m}dO(@K@*K%(q_LJK6oI5N=%eLR5HlB_okFUpEzjWukEAcF`Y+~9Sn zr!KQiWCo627>Z!SMEovh3FVroRd*jaBg;%ZFv(cWQ<`AMVscXd;n2lYD#hy&@Pb&6 zDU=AT>VJ5;^@3T-Mcx}^d)WVfhvL7(-|Wxu{pNej*XYak`MlS8>%EhZ{qHBwE1ugt zXL}ZS(mXczyYBnl6>h)lU#=3D&w01A9MS)GI~F4P{~r5%yUn)MHqrVS^8HQHf7Z9@ zi}j(}589*JDs8O#oq8+$|2-|QTDDjg;vT^Flso>0vY!}+cbv8Xaw2lrD@={%4`bu) z+P8<4@b9LsmK=sB98$cnh2Y#IKm@J5V#Kk*-wWU#JjyHM?dtD)O7`6?M$Q`%^6h^%WN`#btHgCqG0drPVb%(1 zV7cJ9h)0-q%}NBiQKo#Y>*3O;%-v#S82)nfQ|JT;-r;<{WHx}F1*tMlhFC(}DuW4* zZjtL?YVBEJxX(!SiU&vsD)O&i-9%bW$xw7eb;d&Oz zg?ua{wnU{#W%_%5rUdoLpmvaZfk?n(WZSE&~-LSAm*iqs#flI4s--cFQv;Me7*?X#~ql^#3 zM^CnUVwDBemvY#U?E06C^c7o_i+?tS#`G}U_GBNSkuIu&%=>5kX-rWreDU;_F{y4D z6JajNqd+>SFMqwdY}-v{kwF*k|(P!@_Xy(-ff- zMfiY7sYS>YGD)?ss=c{>ZA%1qau^b66x&y_-E&Ym)bl?1zO*pB|Mc;M zk_(Yci1En0ySTA^P0K)k|Ek+$#hGCM0_X$}qMiz@zY8U)_EpKeg$E`4M?#PJ;w=y-J|*B7^;_)7B@|o4CjUcL?9`G z7#2Xljmm9m21WpB{sHu(^jas${qp_O*O{<|!Z2V9q=^!DB>O=c3CQaw$5FF&Df!sc zZOg;JG!#ZSiX=VLkS|A|F5<|KPg*`^J60}4viOsGlR8VuUur6G)5E|#&@N4FN1#3h z=fy%u$NNrlim6xkn10XCa>R?m3t3DczD13~BuSW){FCL{u{7(dUnSSMVPGQUcSI~X z!Z*dW**MG)2TW#ylN^fzV^Wq+a-S5Q&w3EGc_P+W*~xLUEIgE;n~Lm|FmMs%c_D6) z4FS?AY78zvIhN|zYZeYO8#przoP^vFkggNDCzdW!F9GAwxcDSFcRG+Y-V_#Qh5?`; zxu32gnTYgl(-NcNCI%>^7ZPH9a5;RTRm%dHYWb8H54Tjoiguj6M*Zip8T}uYgPIox ze4=w?7_i-*WGg*gveucl-C5z;ECkb#iojlgMIhN=|D&{BC&~JO-LrdS%4SXt12aLI zocLM+*r6IBwl|z?bDvl<=fDq==jcZs|1HpP2A8-ju1_ z#Hb>moMH4wvGQZeMYrV1VhLej8OT6G#l)0C-dxHnDJ=XAD1ZJI<+89%mLCuXc7f&z zmCt}@0d^_Mfr)~z?oqCZHkFlr;RrB++liBUSrCOD`ANB|+C+&B2m^>9xsmT3zRsH3 zSbFW*yOqnvn+}4QaDGc~;4ngN7l@xIR=P>K@TmgXy67;F12ik>r9kgAH{!5Bslhvy zb1R}+O2PjxOG%Lwr8?Cs>wS%~R9qN7eNuYG$Y7wCBNzr6c5Mxc8vB(?wOeG-m~dW8 z>mcM$MtnunN)&scNV#^cM;1#6!?`ZU8XgG5;?yn@x3q}s8BjhUPdWFMZnAtu7%uc& zNKQ-9n_RpcD9a$bnpr>wnS}^~U&_>r992$S|Dh^lsu+glt)q9P`g= ze|dCascB#v7lx<2D{2>^HWF(t?hg+xLi_3~%E~E^ksK!6;Rnw?46m>PH>l^2nY!Q9 zY*ND+?7g8O18#;a*)Z-U3U#9Gpw*?+9eh&`LUMRq%TUv2g)mdR82fj-=4&4(o%ysW z!WD$aiv0<yLhyZ!h3zw;mU|JVN?|1STn{_V&Qcm?hV*yvyH5BXR5oBXx@3fvel z&p*>Y)j!Ff;~(o!_b2-k{IUMN{+|A>e!t)8*L=VFzW06QJK{U+d)N1d?`7X}$S=6Z z_pt9?-yOc2eb@W0@@?^5>^sl54!DD6UxTmOSMCe==K7}l3VnILEZ=C~Fy9d0AYXr9 zA76K0XP?(+_gTC@dyjd)^nU975H}UR=6%t--}{93QSXD^yS=x0cOY-!KfRZFFT@Ro zVecC6a_>@ar8nqZ;GOL)^5)}K!wm08Z>l%R8}E(w_VRY~cJ#Wun&%hKG0zvCk3H{s z-oTxQ`#t~mJmR^}a|aL*+YkwH3GyJU^PK5f?x{mQgc8qOPq8Q8Gu|`SGu$)8Gtd+5 zInC46U+v!FzR117ZMavt8{O5& zrm(<0%RSXS(VgWUKf#VarJVY;_|y3E{pRg z=QqyJoQIw7IA3!fa6avP-1)Hc9_MY&8=coUFGm)~bDd%5YG;$P1{R%#&e_Q7ILVpq z9PLbVCOPAreVsj=ot+-1)$yC-d&g17r;ZOCha9gso^$MTJnDGBvCDA_GC*#1T#7sp z>m6q~njQ6yN=KPvo@0ii&@lnIAx1co9fKYH9lagh9331^hid=X{;mCU`$zV7?XTNk zv_E6tYu|0Z*M7Twhy7an74}VtEjio1#=gv6YhP>+*yq@b?33*|_A&Nh_S5b0_I~!B z_AYiWEKa}Mez1LI`>*Xo+gr9*ZO_}Dv^{2f&~}&YR@)7>t8AAc7sWZYkZq-{!B%Ap zB2s0hZHg_=mT4PlOR*)`2H5)8PPKKkxon#C7wa+W7uJuh?^)llzGU5R{kQcI>wVTc ztT$P=S+7KN%lX!I)-$ckt#!E3vcx*qT5Qd?j<=4r4z~`m4zxyFPqTKl`mA=VqW`FW ztsl|*)T5BH|U1GN^jJw^+oyueU?5|pQvZ)qx4ig zQIFN5^zM2m-L31|uiAIom)a-V``Vk@%i6Qr6WYJD`~Qa3?Eh5xe`^G6nnmqrxsb^P zOg1t(pUHVl&SkQJ$vI5c6X|RD2a|P7&Sny3VlW9YIg80!CTB8P!(=s+RZLbgX=bv5 z$#N#kh(uYMm^3nJU{cRyDU&)TwM=T5R5Ph!QpscqlL{t_iS)6QGg-tW$fS%(DU%W= z0VWHXEFjX`GM~vjCTB32%VZ9d*-U0JnaN}Zlj%%~nG`XZ#$+myUY03L3Yioz$!9W| z$s{HdndC8>)fr+1qkBOJasTL0tHxm~V zCldz~I};ldD-)fG#zbXeVWJ44{LbVzCciTIg~`uMeq!gm9UnZY2`Gm>GOg>_An8|;be8}VjBBv1CI^_jz~p%*&k^aOJj-N1 zlV_Mb&EzR2PcqrZ4@(_~;nLNPcej=Te z`Gr5b&E+%&}xr52=Om1VclgX`2ZeemWlbe|AU~(goj>>i>H!!)L$#qP& zF}aq>HB7E%aut)UL^>${WO5~wE0|o)WDAqam|RN4uWV*=36o7sE@pBO5ub7)lM9$^ zWO6=}^O&5=WCN3Pn5<{=4<_rFoXsRm#H$!gLQKxGY8H!kt$3a(o@>N&wRo&vXDK~hCE^(n&xPW-Ks@J*=REN|LpFJm(o|D9LqIl+s=LGT070>bFnIoRr;+Z9$nc|rtp5w%GEIsXG z#B;QGjuOw2;yFS*)5UYRcn%ZKH1SLo&lK@Yrl)PFcn%TI)5SAMJQKw;K|BYG=OFPM zD4y}+87H2x;yHkx*8budBc9RX*-t$Cif5E~_7TtC;@L|)PZQ6c;@LwyyNlvSnx<kVIf46@pECN^ixA-seZ}1zi2Q>Pt{fqny{Ig&UnCQ>)kMgJb6JZO8@^|-l^1J;y zECJv7zVvr_`qmkW^uzc`OMzi@u+e9!rY^Cjng=f9ngIPY`b z;k?PY&3Pqq4xH~?=RDK7+*#+WaF#gdI*Xn8&hgH%&f(4>&VkNo=V{KaPM_26R2)A# zzIGgO{0Dau9CW_5ypZeVjerKGZ(Q z9%JuiKgI61JM0$QPquGtpVY{Vp6wr#X6&6Z?~v-P$0uywY1Y*y=U*6*!Ht)E&yupY9$VtvlK&-y5C zP}pU?#d^JUtMyXr1=jV}v#ib5dTXV%%sS6H!&+#aV9l_OuqImvV`}!ccC&V{I;|@3 z7vJii>mTXw>aXiB>dzqhVz+*;e!IRyzgE9O-=v?XpRKRam+7@YX#^0LQKV1SbM!I# zF#U8rUhk*()Vt_j-KPBx1jkp}f3**_x3pKa=d~xb$Fv8vyR=)i8?>t&TO1cTHaHB& zDo3NE+Of#7z%k1))iKeLWxW~AMxleb;yZgC&y1Tf&Zky|O*AK3*T>o`_=z7cbs_S{zlepLNLDyZb zTU|G}u5w-Gy3qHm?+M?(eE0kAguUuI-#>kueH(rMfVFCcZ>evIuhe%2Y*humT;Dif zx^E~fRWZI^zEgaDp96NPpS<6AKl2{;z5^@O0q@h^$Gs1G?}3f#M(;J=%e@zS&xM6* zH8O41c+0&DVV|1joupl6DywuP4O4}LFiaH^!Z1}x2x+R25Ykj3A*887LP%4Egpj5R z2_a1t5<;3PB!o0oNC;`FkPy;TAt9uxLPAJWg@ll%3JD=i6%s<4DkOw7RY(YFs*n)U zR3RaxsX{_XQ-y?(stO4qRTUCKswyOeR8>d_sj83=QdJ=#q^d$fNL7V|kg5s^AypL; zLaHhxgj7{X2&t-&5K>hkA*856LP$}Cgpi^N2_Z!l5<-e9B!m=INC+vakPuQ-At9uw zLPAJUg@llz3JD=a6%s;1u$$r()MGMU3{+ ziAhHy!_+64>|^o-lYcYW%j9t;dzd`N4@(_`DRb^sfq6lL7oyl)Z zer56tlb@OV#NGWmkZ=S)6ha)il$nS4ql z*76CHkC}YL)}F!_+l2Ta~)@*b0SnY_c~Z6l`)S++2_jLD@; zHZ!?|$tETj6UorTddSekddSekddSekddSekdKjmP^)OBo>tUQG*26eWtcP)$SP$bg zu^z^0Vm*x0#CjN~iS;m6>qRdbtDVNACzBpb#CjO3iS;m66YF8DCf37PO{|Bpnph8G zHL)JXYGOT%(ZqTfqjexIV>CY#9}_PV4-+?$(VB~ilZk_gor#T!m5I(oVtUoS*24%@tcMY*SPvsqu^vXKVm*vd#d;W_iuEu;73*PyD%QgYRjh|}Rjh|} zRjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|}Rjh|} zRjh~Ms#p)hRk0q1t71J2SH*f5u8Q?ATovnKxGL7ea8;~_;i^~hheH%55v@_;7JXcqTB!Z;s5&)pw*F~4JI2(36z-8gnJXl zdeWi0CU{~!eLX#a5b#5L)!e_jzjuEHjKE>&uWz_tc0cES5-5R(p~2pPdls)pu7xe` zi=o4=bFXzbyBmNMD2En1*FD``=*|OHU^MjDA?`u${_Z|N3v`AiYj;~*Kf8_rFYqaJ z*|%Muc2ztUw<99lpn&VgC2)=@y=CI>k z#~Y59fh2emmYRnh_d4!y+zc!MSr#sKoab2QSPL{k18fWBj(}sXV><8zd9W^wb_{b2 zaSQ^YpbxA$ogH3>-C+Ty;27*VpV~jPziodFsDk~l=saqF(0;f5HsA`j!KQPm{X+W& zdl<-q<*@2h+Jp85_SwJ|*3)WINFeER%f?7atkR8{)_f9Kviy;-mqMnp(} zB=ioF1|)<~5~{RGGD$`znJ|+OLKT>qD2fFY8y0LRVnJEkvNjZ5D>ih+g54E$UE8{> z<@b3$H+Mo%_v`-ny}tk7|MmO&+I{PBoO91P&vTx~dYtu0s~2_$7M%HftN%^^ ztNuPL4_?Em&olZH`osDIusygP=RO1^(nYU&z%j8Ssi{viy1@d|FIr3TZ8S-iJ&*W3&ljIHL z_2fqKI`Ufb8uDs#19=sBC7C1>QoWGk5>DMdP^NT(F(lp>u{q*ID?N|8<}(kVqc zrAVg~>5G|`WImZk=8~hx)5($K2y!?%j2uc1AqSI#$bsYl zvOn36>`V3`dy_e2Hkn0o%xWC78po`b$-mDayOZ6>)5xymsbm-O6f!_|CQl|$B2Oew zAde@HBabDIA&(}HB0G^sl1Gq-lZTOh(noqp59uadq?4qSYLrrqQYz{x$RVXv)A(nV zw2+EW{h9oU{E?)Ts{i7j_mlr5zbF4een);wenWmuentMBq@1gibCq(gQqEP%xk@=# zDd#HXTz#6U{!BhaK1uE*pCBJ6Dak4&S*0Yalw_5XtWuIyO0r5xRw>CUC0V5;tCVDw zlB`maRZ6nDjrre0-c4>L?;`Ic?;vj{w~)7yo5@?rTgXl1&E!qwjpPkvl&mM~$Ot)_ zEF=rae3D~F<=9a^D*SMpSn za;{R&Rm!`)>}w1A+QPoJu&*ubYYY3@!oIe!XD#em3wzeW zp0%)NE$mqfd)C69wXkO`>{$zY*212(uxBmoSqppC!k)FTXD#em3wzeWp0%)NE$mqf zd)C69wXkO`>{$zY*212(uxBmoSqppC!k)FTXD#em3wzeWp0%)NEj7}HmTEFYR*{ut z1sNpgk#os87ENI2|8Z*duKu9nf876&|9*G@+~U94f1UqI|0USvpAF6aQp5#p z@So|g^3Q>8f3m;CKiWUaKNS1>Y=4Hoi~mII?ho_3px^%qd;70^pCN|8UhM2&@jdT* z%J&%d_4h(^y4iOlcJ-J0*7?qZ?({6*Vt5&-_tp9;pgo=Ho9HWs&w-J?!O)-f@^$kC ze8>Ab`Fzlzs@@;G-+90Ee(L=II@H&_FL|H!?({z5eGppIJG{5ROTh;3dhdnMqb9t| zy^G+pAmXitCUvH_+*|4$>&^2HhYq^8w}-c@_hj#}-Xoxews{qJHTVX${+~b({ibKP zXP4(`So=Q&P4wNKEuNb_*TLTZ66m7O_N?+O^(=(N|C!K6&+$z6O!kz(=6@9Q(fvKy zo(xYHSp6RjjkL?7yMJ%Pmq*?l8y|1XDL`aE~a zeHJ1rG`j1dnXYipa!++ng#CX3bkl>~ecip>-Eafocxb16Ziib%+=cI4UqV0qf$MG8 z>+rq!tZOGU)DOD0x$bb?f_nfPprgLfwZ@fjEyqoO80`L5x|}-h27C|Oi_aV% zIrbt##4C>H9ZxwPb8L6q>$nT|18#)<#pRB5j`JKT+z?m{dx3gKt)s#*3wH!2!eXGn zG14*E(HFM_y1_!@ct;7aZ}(WSZVCEKVp9n{wD6Q-vT?0 z4fgf+3+-!gTVOdXHDdONz1ltx_XWyft1;G|XCH1Kh#LbvV6Abo{aE`Ec8}d=S75L4 zjqMBDC${%+YhX7lHlDUUZhOdfKkf}|fz8HswkvIy*v`kzfmN{DSZHgoooTDW-GS+_ z+bFS(wvDn4#qEJ?SZ;K&ooGASb{Ost=&;@R-ue~1Uwnic1aH84<9Woyc+9#TcL?r+ z{l<;fYpj=B*WngH3KkrTt&P@tYc1{(%z_QaL~F5szyBNm7dU-;&;KUuY+g zhPb#4ad8>q;xfd=Wr&N*5EqvrE-ph{Lzs3jIfxuc4j}uJ{m8y#AJQ#!en);waslGx z0>sG$h?5HtCl?@2Eda^M4^+#t$!Ex? zNiGDOTnIS15O8uK;N(KUc|D)mNM1)?OI|}>O>Q8sBCjN`ATK8`BiECcl9!Mdlk3Qf z$P38}$n(jy$Z=#bSwxN{Io6y5 z_~-s)Ke8{`hwM$}klADw*^BH+_8>FK4AM&Kq(-Wwg;a!&pUI!dAITrcf06sif0Eym ze!OSn^(w}$(P6% z$z9|Ne+4x2_zL9Mk zbGV1Ro7_s?Mczr?LEcVoA#Wo$ledz$kekSx$rPC+6Xa@g6}gf;i(El2Czp{+$tC1s zvV~kkHj@jmA?K54l3}uztRbt(5Lrc5k`-i- zEuXq1UZ}>Mh+#1kb}uVN8G1hhZq0_-eYke{tkEmoZ%VdITAYSN1&Zrnki{chZK&W0`dRxPF-r9PpSTmE6W&QhR!jiP_` zpXmvBW*28#E#kui&Q%dOBFm1LQw!mwF%LfWV+b6<$QikCR0$`&;V7Il*VMyFLoUL0 z#1ZtQQXKWcMMzZNyGXgA@p9AiLTLi-+r@XvTydxY7mIMh2*-_C@ZP{68FYagN5};f zksk>*RiQ+9&p@P#nLBQUOONnk{jUDXhDh3n;*12Gxr@u;I%GJdJ}l833xaU1S&J$c zz~x^~!I{AbBCU=NMk<5R9QhBuP|Z4cjx7l0jE4(fiNql;hIZU)^*pNFT6wrx+44kR z!>Nemo%WcUWzP#QMxYPWZ^u3GsvelQW3vPm6i-DGE(RXG5aJ^y{yYo1GrXO?wp6+N zl67XbGZXL+FV4E8c@e{dj(E`oZLTtN^5Lne2H{(35YDZ#3GS~eE8*=u9I1`wlm+2= ztyf?sBGnk}RS?u~Qvw9Gx@j#9N3HW&Oq{_It2I$!bkPuECg+=fh+}M2#_KTRwAKya>@|`O#W?RELx4f zh{mkFK2&b+@sXKZuLPXjW0=u(%eY{?7Bbn3p5ToTX!ggpD?eTRjrsWS1f1F%ZYdd4 ztF9q}FiwWU_R-O3qmh*1H5f6?dTM`VbN{rX;JgGp-NW?_LMFk@S`=ZQ;)dIk5S$uE zT6!H2EvrL7t9wSa+?;mOH8ugC_fm&^X@GihAZ|K?D`@7PaCjC6%=85bc+8ik9D(#@ zb#P84zA)t-rom}@tS3Yi4(xNrMC6SQ$i`WpW9j>FdZ=b4;5#4E#2^RaP*;4Yg{sJ?W6hybecc2nJ>Cpo+ufs7f=Jjv{$@7CD#0Wx2CVV8~QT45L z^L%NEo}Pf)e{o_SMkZ6kRYB>-{9t9R1gq_#o9}{LennKw7c`|u-5(3Syw-fl;skvE zi+{r+NN;{ER}<(S8JqZO_RuFFGKNG&&kM#X5XUvEY{%^pSrx(gR8=spPhYEC@Kq-> zv!Vnd0f@ITdD)2wz!eV^!lz$2hHoyW-yV9$mqdLJYy`_Edq=iAo9&T6pa5BuorH?z z1_~i5GkfUco6tz8kNvM3ES81or~vE-v3reP(X))t5+2% z7vBH6nRh_~VFkoRsE8gMsRgCWA@qo{f&TuLPBukAyM1Hxi|NU%M*>j>L~bNDSFXhC zm5@_ye>ldjUTQ7d`>0uFAc05&;xka3&y^!eTJRXVt@9@3&rda*k7OheTEO&A2QS8` z6h<%xecds3YxN%Go)KwhXQw5+hTKch6EIb^Erw9)uF~0_^qSz51i}X#*H$WKhVUX3 ztFPOjT=rht*InlXf&~~ggCDYBT>~CbU)nSK?aSILhM)klD3;PDH3cIJ5d0Wk6cN}M zkAA%>IDC@%X!isH0vPWA7r%xxbu=y3+Z9dCQz z7UiMIX@MG^up7=}rR@;@LL#C^5sI);dhxFAuRknD*i88Lgph+rN1CEHk$r3ApMvB?La{gIV}GAkRh#m4SyV*Dm-x?L&H4 z0zUaAXv3+Iut%~v2=}!L-ovMwd=>3 zxn!<}=Y1K6(vF4jKwgK<1wtZ}V4lFURXgKU}dwlMT-^=Os`c(u7;caDP}oMf!qePCF6*Q`*`_aPK_e)-)1|SeRPut<$atufF6ajVpw`IFiW?J$8_k#8M zU-$oaxBqtkE&dyD&;JUX4qV`0<4^j}!d?G`{ssPszs6qy?|;+%W&Tosk-q@`|Ayku ze{X+Je>ZplJkfs)?)`iH4)_5432_C#!QKB);RSH7Z;x-c??v3IeiGIJfAZb$y9Y4` zZ-srpwZ1ETm-;S*FTj*PM_}m8Mm#!g{{Co??>Kuy>H^i^-JF8yia*|cprjiz-`_;y_>x^d9QijeF}|yeE2(_8tcBfI4oj zfA9Iq^O@%(_y>Fgch{fyJmq=JvmG7+@51f%8$H)}F88d1kH8e}uP^pAdg?v3@Dex+ zH`ph7iV;C^B>V*S#U1u;o`C0gPbYW^bl?{I5AN^WU%EequfVr)kNqY0v+kWZUwP2I z4L8|uabNG=;9d`ZfopJ=eYty)JLZnSW8gg8W-oV_y2rZn;4^R_?z8uBcXglaJ{DdB zJ#L#@aqV|~suBTm(!*k&MxYfSJb+hX_*Ol-ccs@>VR=JkC7P=bX zJ+KNsAEvt|yGmT6;XiOFqB~~0GF)9;C&Gi^VJ?^H3DTuIe{z2B{0hDVKf<}s8_rjp z&pV%jH^J@j)^L||v-3vhHSj064*nWa&a<40osIA)SPPF0vz$|%6P?BIDL4{78~QqX zIlDOn@G95|UK2R4t@nch2Ms^9j`lHay$#qf{(y+!#12M-Qu_&z6ICA)4&=> z!m-@32;K!F@HH^cG1F1*D20E)JjZayKu2#!4@Xyc7(5o<9Xt-3L$U9NkHIhC-{C#` zoA%xIT{xY393CF-x8H5wV!s)F2CsyVhx6@c+gI6_!qZ>_ygXDPip6yMWcV5!4L=V< z?fvc9_6&F%JQ1EA4zs)Ly6q?U8~h5s9zL?|wY_0`1s(^VvOQ+oZoAiZmu)kA4qgL) z59@5_A^zoA@H*HCj}NuB3fnB(RQMe%hR=tQw!yZ(wqEc&7=YJ@PBx#-VN>CI@H_Z@ z_|*D=^=)hzUa~$5&kv7SAGB_>-U0uE*TeV2dh3POHP!??5H5oEhlsV>I?p;2J_t+U z{~^yh+&a+O8)n^IVUm5U^$4rSYJ(rb{qOGzOW_HkK|fQk(&xY*;bi!N7_E=ehwA;|kuc*|59t2qFaMibK+b6` zFOx5kFOs{+7s%(y=g4QtXUM0?Ka)?9Pm(*yC&mynCe7IG2UOfDpw z$VM_w#>fR^0~saj$vQGZ&L__#!(=U4LspX^vWl!EE65-@kDN=+A!n1b$TP^9`ms7*<=>ki|k4EAT!AfvOC$0JdNy1o=SEhPay+j zXYyq7B=SV^1oC+DIPzHXNb(5saPlzHPx?qN=^@>ui*%9>(oWh)E2)zjsgf2_5h_2E zKaoF@Kal?-_mlr5zbF4een);wenWmuentMB{F3||`33no`5C#7{FMAF`3dmlDvYvoV<)& zPhLu1LS9U+BQGK^BrhP(C)bkak>`?Y$aBcE$yPE&CdmZ3np{P$B+n94>=lCLf@OlG zf+d2*f)>FdL9<|?ph?guhznwZ1%d`aR8TLd6GQ~_1!oGvf?7e1pjr?TR0%2t|7Wc6 z%O$Ha!DPWC!9>9XL8)N8phPfEP%J1Cj1`O#j209M3IzFrJVCBtl;Cv1|JeTjrvE>z zAdeAgvm8wxMRub9KhGDIhhYHh{G#3R_`m-y!2ejH|KDSY{vX?&Z-ZCCTlDMo4f=Zc zwqFCkg0MvYeRk)jz54&#H!=RdzX>Drf#xTDq?h!NZqh|MNe5{sZKRddNsUxV3&}O! z|3%j~KapCgACn)EACe!C@00J5?~+{Osa)f!T;r)+JnYdn=}Je6xam1{he zYdn=}Je6xam1{heYdn=}Je6xam1{heYdomcq{q3&Q@O@dxyDnu##6b*Q@O@dxyDnu z##6b*Q@O@dxyDnu##6b*Q@O@dxyDnu##6b*Q@O@dxyDnu##7H?=_|S8^|bGPu7tUaz1$`876DV8nT)UkyT_RSwRNLdE{Jj4mq2g zMV>*?3k5IK+>K=vp5k$uTNWN$Ku%qFwQUSvH@5c?uaIJCi4qCy^(TCy>XJ$C1a9$B;*pN0FU`mRE%ue~t35QT{c`zef4jDE}JeU!(kM zlz)x#uTlQBCf1qquTlOr%D+bW*C_uQe~t35QT{c`zef4jDE}JeU!(kMQ&@k>zef4jDE}Je zU!(kMlz)x#uTlOr%D+bW*C_x0f2|Xg zooD?w9ozp;F~8CR90eB()g#Fx$ivCQNI&T#y`+b9lP=OpI!HTdBdw%PYNSe9NJVJ* znf!_Tk^F)D7rCGOC;2`35Ar+mTk;$7Yw|1d@8p-{-^ee>&&kioedMR)U&&9%kI9e7 z56KV6_sRFjcgelvJLKEsTjZPM9`X(HFXZdwYvgXB#x~d3<{H~vJ522VM=Q4|@bTB| zKf(8a?`+(|x4}Po*xMKW*;_pm;b;91?xnb!egu5WJ?^>~y5ga(qoD!b2|e#D_;u3} z4Q>nWbdPr&2j6R3;aRP~ek8o5ZN=T`!O&|y3BUCdtRCneH|Q05PwfZoP7MKe)tl5s z>R7~~`pWW@<$6ntWt`6(Bwg_u2yO+-nk4u z59V_{5{uexaSFomN*G>N&JVQ&iks@B?5~#1J-gg|xM!l-u-lU=j*T`4#v-~oO>!k% zXg^guVt3`n7tE)-B^I{Z0~xhM@b{)r91otfsp`>-%m+_RG#S<%lI?^Bgz+qmX7@qi z4^5xZ|2Xrh?ukazGD_Mfh!CMu;$q_^)%^3$nQGcFs%IkJUd<8&_(jn73DwnsDGiO$ zW>iys^V?aSel+tvEfH&Pse)KjU3-gumOrQBM)SF>!~(~k~w=0$>)^I>EY%K0@@YWFRjEK44~)y#cdqMnAo&VIYp*)Z zzP(@Ww>)`fj+uLLB0{q?=OpA_))0hQTX_s&#SyOjfS3N2%$eB{qeiOJvQ9EH>y?;q z82X)x%;ereIM_!WACAD(tpN9I;?^fGQyzAuBc1k7oM~8Ii9r)h?sKcr^0dD1kWQO3 zGFo_=S<0Y9xZMt_I25cGBYD_(1u{y)3qzS5Q{HE7sYn|c_DR$lvM2Rpy9COD2o2mJ ziT@$w^chLtb(z4OPP?IoufT@Y?nvmnolR-)*Mom8fj*%EIij?1|YO z9=E!;E4Lo@p!xXei3$oStBDH~Fl?`Hfi0a8dihto#`_n=^2l4`%^Y$QK_gVURIv<} zd{vNaFd50AGh+WD# zSKeYK8I(Yzd9m@9x5#UO4ZHkbX03{Ftg1swdw!+zd4Ae}ct8S?XsdVpalCfLMzu?=mC#4#UtD8`!qsB+tb>Dy452}E!gGjS=V zI23E@@G$Iz=X{kO7X1=a44Yhewlvz@-58oO6?I6ZX=Oos`m@|Q(H3}JL8@Gg=wOar z+xSe2C4C_s+fRIkSiX6 z+)CWii8kff^)J>c8_RZ?iTWiFRec2BO}>dR`;;%&SotzfXv94X28fQIj#Ml2m38NB zHBtcn=SPLX;%uB70~gM>y$nz41txzFUAX--Wb%({rIyklN4yolD* zcnRyG%GD+2Q{5AYvu@g1mxXW@0Jh@gxV99+lQ-109CM}lt=3-8E!$ae#fR@47tVEH4aO+Z?6O*t;-#Rw%m$kO%TIWAr|!E zI39l>b8+<)v+(Q$LavL|ZrkJeFigfJH(YRl1#dy9NfI1m4dtg>EF*!y>!wvWEWGh; z!QF%=R0Rz+XO42gxb!8TKmx(n&926E%BD~RxvgH-)a_%l_)`;O+S{@$8bLm|f`O-Y zwl29ceSa%AF`C~dXCZn?u3fc-{?0z&5@`^Y#@zzA6Ifo0v4Fdo?%I8pMPH|fBLh4=>{)hE~nxq7b4e}^D+Z!V*E|Vw?qEzucuFZM!E2HyP5xh z#Bh#KUa^~qX!4k2|=X1XznVf+|zVJ?$|T<63p zpd?%!`lUQ#Q5iyiG-CE^j$2E&C|gq-&786mLpg@osu`GHYi#D#ptv>9t zapgpBLJIdW|sYb#V_)^z0$T|P5&lKp>?@{j_5|9ARR@a~rhFMdz>Ho*G6*mpc^ z=^yr9g4kq3yhp)T-hJ?MUkm?t$GZRO{u6A{hr;LlbMQbn!_^b^;I}wquM->r9B7g)3Oz3@a{qh}$m+%|2wR-oC{7u2y)xy|pVMEL z{z*)Ja`E;weA*zY@;rpCTK2&m(y3jyjJ{`{*-k@}nAh-8VzRtYHTIVLp66Cp;u`b8 zX|zl+> zh3_d-P^2o}vB>+aGbep-Rx~$>DXOq7QK`%v#&F! zs~n4`I4Y0#t;N@;V}ohalzJt-z8jjv^fRa}-5BikaJ4@Y!Hy;z#|BRR*sIuk2Q?Iq`tr#S|l7VySLf)8cR_Yf`Vk#K!DE z-ww&N2iCQ`^_*GW&?F`gL!Qi~e2rNoZ+~}4s~7K7)_%FbOgtossY5A8Do?lpJ8ZDAP8FaCkH}+*nzgH5T8$SjUv=?W?8@OcJEd~01he_d}!n$UTZklEmHaH1C73NFInTuILzorI4G`8rBE zcmQca%3!SJpd|0jnd_TsCK;0KYIL!j5)=hwDTo=kA%vcuP%qFgb4VM&6@i6=f3~YNet0dGMj%Ve?qQRH=xQOAX-*HbMV|=hB9?TqIS9{lv-aV+j-lw>facz6XG1v~l zl>n~!7BvLxL-0zFQ4q$+!ZxWs)FNqb?L6Jm*G$_h8ED_0PLp{i1NY9cq6CxunBa)rltBUbI8F%n;CQttmxE5X)$jA#d)=K(?Si(gm{ZpNXu6fr?-!FNx zarP$L+sRn$%Pu8jGFFaQ_m$(ewcPVXDsB6a#p`FAsfHy_GOsg3EO9j#AGDafB5wKy zGRk&r#PWVj6Fl=&v>2&xur3_^h?zPsd7?|1-PSxZ&C50&#g;c!!Q)61w%38Fp~cd; z^0zpKZ(7VMWUQ-Qlm5*0OrFrLIKWawY8`EAklVBi`SiUTTK@L4S>&kX@h)XXy2zMu zn>c{-a%cL3` zS~R@l!AdyQkWE<~v_}}>HksxUE#OT~eV;;2YgUNl}Q zqNJs|F1jSWYROE($AX*%iYP(gAoRJAArv&Ie}A{SM422&&p5r3aIjz=!r;a}UahbW zXE12`2XS4!zgru*A$;SDW}SK_;YvXcC?)HO(Z;Na*onl#fzs^99t`xw)5E&fesh`m zbmt_TBbe?03dCaoihn3JGnE#HE=l-3Fz?92MO7FTXu?CEJTq@g`XY1pB>Wv12RTw` zjAv}vaP8QLCtK!B`tA&~z>Fl^9+=(*41Xr2xCxGp6iU_}EL!yawdSL}lW=>0@1@a5 zQS8ljoD(R3KPPBTf)%pMiXlmSQT*@+%p|8IJ?+O|_~_t@xxCPEuENXyYCh952@eRr z)j$J~V0w#!O1Gv4AXDfGX#s+wctkL2Eb5+)T?%=z z{_w5xR8jgHnw5kH1VdnO4oQJQE%J73#u*<(vcKDwTcZGEtz0ZL7EU)P{(r}=P~q~0zLWwp^}%(T$bYDZ45?%U0Ls9RENSCJYk8z_C7 z>O@8Aex~xh3(N<5C)M^Yo*0A|sP3{R!D%7(`Dv}HeM99#yUiroNlW|OQq&#(2cmUy zv;}WpHSnGm?5FCZE0yzF-!~HklF9)mhvBN4P$Q}_;nDhs(hJr>i52EJmXjgbtCa_F zFk~F2$mz)F7{=y!yr^EfM_KDjuX4I2mK*zdnS_e!f~W!%U7|GB&pcka@WfNhT69S) zYj3v+_$Z1l1C6_M_vH7}Q(9(XX}eHh#e=C@GBXwCcg>k;TWn@1`~MNjD~kV7?Ea_w zPxXBa|9{JUXZTLT-v0sIkuO9Hygl&$x5P8vbGZ98_f?2SSLAlNK1PJ}Ww?h4o0>K91>LZId=Y-KoyA{Ajtv z(icVlAOGi!6#5pb3uiN0Q`SqljnJPpRfR@O#yJU=B~-MCdbn4h2y1sym%<51FMP^z zVh}KVX5pw1O(x!=^t&HbuIT)k*q;p|Jdni?xd{99&nVy5j5dp?OfGZtsG3E{Mgd-^4*f;+PyNdEG~4p^pPO;>-& zMQTs9W(5Jk!ct)z!xN4*!AL2#My}W!n0jcsl2i-ZS+%; zY&OQbc|o&ST`P}7qz zGr}U>nS;8N*Fxnfjbt8rz}r+>YfC?^S9BPdpxs2~;=1DbL#h3;hgc{6k5s^eIz5@}7>&}d<;YFYD1DR2$DA%gd|*cb*C?=gX?Gbz0|I-Hr}+|Ok0wKNzj6}#XJsYp{^6J zOeJujinTmeTCm!J!@lssXeJJhTkvV82fvJR%+S$z<`BEOcgUPI=bPD$Pr_Qr$POP` z*=Wh;1xMvDG?E?CczE-}ia=ZeLScvp9JTN;iK+@#Aw%u6N@ZnHdMVH)S!M1- z#2BDbybI!?uZ~w%H6Cte**#g=zHKUuK+lP-6As)fTJXLf96v8B{lU*kR`7TSdm-$o ztKjT)$3`5)1;*esLALS8ThH08oSS;b%sVF;Z8gvjp^jwld$M9_pXqi zP>nbkgAhhg(CZ(r=;Jl(a#|7=Jdl4j>3AF&!S8dhCRB&#p6t4G{r%>1Lz1xADdKaw zy%;YD*T>l4Vb@w8Ul_(tx4kxl?fR%W%6VNznP~?lv0}m5IXjvQ5>xdvEgHkuBHblO zdBG;-l6ikOQw~W^Yj0%^30R6?K!~|ZVUzq|=PcV%wDMrPIw`YcOL}DYOipd@&xv@m zg<`uRy^p#_2ivs~AI@Lk2!wF zgK<%WPl;8CrA1%V=AUK3ng%of?#VK9`>5OdJa!kxHtcqBHiLKWe6MoO<>}Aqh$O6g zU|(wV2<&X=91fp+PEW$nXIfi&?!9?>1KS0( zST0nv0jL;oANb2_NZw0_INPp3~8`X*sBB-=^R zN>aU7jxzBH?vTbhtdnxv%jqvm&m^pf@Fn2q6beLa=sP^FF55IYcaK@U!AV#XiBe8J zzD14Lx)j5qG%5#c5ZS_XNUB{sa^YQmGwJXojEG>F#-tfy%_ADAXj7yr6Uw=&P!J}^ z9g{DOEtr3VnOye&nM$?dZ}Pi+*ZYdRA9`1N=O8xTD$hx<`!9hPxnW5>i~d=v&+;eBY0C4+@_>IrsUB`FdsZHa zHiWNlY?SJA3$o2sQqGv{HZRa)V1im7X#1C3J*1Ir2hMnS*Gw(|xhwf1&1+m)SC8E!W6O0m1eg9iE+bRWTuGBlF0kc?>S%0J ztnuG8x&GWU$_6d{87)r*jH!+LOYBm)6%=(Yj#Onc^V?PF(0TflB4urOj#;lsDX6)m zjU-#y0Ovy&NOSlC?7)6!p4OpzmCa97n0e-=p!$-zTi#Xngt90pK+Dzro7c6fk199( z`4}^gNb01vp@=A^tk}e+m?#Rva0U*mQkXVlQDz?N{kv1KvPM`v$Pz!^b`HoXMxWA2 zS^GhH;TTE5srm?1d8I|h7*uB!FoP4dH!c=HWk03~JB-*Nl&3vkx%8#9g~6QE32ttu zP#h*o7)s>h)=~5j^0(GxDqEGS&E^ZHj(2m)U;+5Rz<+gZAQvBrLnuQZRH>|aHPIn!OO)e9N`EKrHBvrD%Wj$)qIgy>S(vD&_vk8t`F^01qH^? zfG8+r(oAa-4yn-cOei+en&rmSQEpM48-dZWdIZI>JrUHFn+9;KC?&3qzpCtqh`xUvz(yNqxnuFemo9R2!@%4H{~w+o?^$IY`k76gl! z3Vif2MdZSeHF`+p)L*7t`18GHqgABb=|;oX2#0~@{l!Bm#CqK-<-Tz@nuUZ@t~Nmy zB~%ANuK7=tXzdES0~KEV5l!pfw4Hlh%GoAxEbA9xa}K#Y`%(Lqk8kW_zFU_R)bnEI zbqs`VY*V~;1h&qNwc4nW;qTL;IX4BpysRTdU6~JsOZun==lcJ9HPV;tQP!QX!mLIx z1y#PRpxN_wDY5h)#d9 z>mTqVzs6PT%6FaO{M`AB^D5~4`#7EO*?zlYnd3xwS>J4Lv}f8rMHKb9h>-5L?z28_ zy#i6r3$2|IwfrUci8~wq#rx@2?M>|-?QCtP2Bn7j7xi+rK`l@_S>CeTYFTC}w49*) z16BGD{>e^3e}&^69#G{*c5IW7Dnc9$;jFqoI>xTu@$J$c>Cf6JDd?!o3vO*jcz9;p zx|Yk*=d|5ZP(7I^x>$?_1NCyR0}(IA*ww4Lme)RN_UC{Uv`jDwK=ESuA!-R&)G=s7 z`rq<*Y#d|PwV0Af%r(>$cmvupAPJI!bNq@X#%IS*fP z0*pwYs|sZybRUexaOj5@4aJe>wb-1}k!G6yDd>)jdP&3=*zQ!wL4OD*7KN~(i-ZwK z3n%7y@tU&el55RmSt;m_aI9cC4zGjTf4MM~fGKD!I@*pvh6{uB`j3w)*FU)5d_FS; z)sfhC$@96DAqZ}?DgEq}50wkXr;P|tOF>_R8IjMHVS%204w{tKkJGlRBU4ZkNe2~5 zo@jP7iTNnT#F!we9*XqB!89~LalBQ`TC!2Ob6(nfDI*0yG3d$X$S@2jL_L?vx6AQ}p<3l&j|8l;W zYtIxEJ#x%{9OnMfP*BPFb4fU!e)_8XW@p+sDMPeN>$B5`G~H5A z_lU6_n;XZu z!fpzkj*G44!`5zoW%Jc3^XZHf6g=sc4c0XwR%H57&$r4=AHQrq+C2pYk2IMKi~}X9 z&~8;~l^c#s%f+cFD0d9|z;+obwChv0Di>6wcY3F!(rO&h^hYpY@JxUgl?!gX$b96~6m&Ia zwF={6cp8)G#~Ang4zW- zSmvD<6@%PxV+c*$Ghf-#Yq|N@DJke%j9Oxyfv__5QtHk9l`Ar0<}(>7C|Jx=<;HPd zs4h!%KA{*&{b~$&79< zAD5;VaRX9N!kF(p5ys7OGZW_D^&xrh11fI4Zl7|$7B@>9l!6*YB(F0{8xxC07s4*t zi1F0a(AX3|pb7MMaDRPgdig&mHI92f%Sxv-S!1x}pcWR3ISH5tdy23`a)r+fG+cWV zNGHP>AE#uPB4izCTlk^!`h+sGYFR1hazt>YYLjux3iEs*6-V4(SY{}i-1 z_?|gM2C1$cNDJXEz^Gr6jMcOzV%(tHTrLuL# zWb>iZQc&1n+Q36%mXAfItiftR@qF#++NHCz&F4m>psInc(8x?~3y4(;ZzYLs2KM`M zgu+W_(A)*9^7VJ7E7!DJ;dW0!UxRLB`rH_7JwsJhXtbine0|?#%5~?b73o>20^?v; zYBXL9NqJPw1DRY=Y~*VnZCU=zTV~BVr}8PGe1qIdG5O5bW^a!?pPoMZr1FfrN0Q^T zT3P!*-4fM!;uaZ z&_2IcIcx5nX4?L#0qt*!yA<(S?BC?*JXqf$nf3TO<)*(4GL!X9^*2VNyeUn#pmQAu zJKc_n&KRQHp106U)IZg)-GoU#Hi6sNuGmfUm)uJom{+Ky{Q&r1Jk_`>6sVJ-Y6 zgkt{<71EC$q9pe;r<=x>>gA>Z;Yv4}My7fw7GT(45DmZ_$hg%Etvj@Kjp$Js%JPg% ztC_!}w*Ou=d&0iz;5f4;<*A%22@0sCoyI*mybI*2XxxRKi?7GM`$#s(RRp$oh z1ZOA5%Z{rMm93ZkJNte13VS!(9@~0EJabs@vKH(A(s$^y^lsWd?IG=QEuxLrPE_}) zJJc)GsG6r9Yx&ahxa9`R8J5FQk>B~x)K*Mv@=b4opcKN%1H2@JO2&)57ECl?J<I%Bc>3tG{JwF2;UP?{Fm|=6l-M-v8Esr>5F$O>)uPRyT`O*vXhLbA!FPZh*s8y z8h>BL`iY1lAC8z!TiA-J56e8{M2kwfX!rXvlAA{EEoMF^w_+}o?WufU3*k&}oUXpQ zZ`S6!%m*@Cjd_m`q3*yZtZ0(gyq#`!3GC~SVH2vI~m)$ zP!%%nwO=`B`G@TZFyzcV8{Z4lZLVxw@*59KIVO-&y!pV->Nr5xV&c9W-~0=2H_ zfVBEMvlZ4U#^y?#+*C#2B?Xr)agR5Svh{pr_2#fy_NlEI#%@I_n;)#M4xx&8>gbJ1 zvZcm+sz)mfKumi$7=iKrK^c73;l9r`LQ{tzCJtZ=p^M zgRhp#5E%5wS~`@=?MqV?%&?3q7$f+=>g2#}3)Jp;P!BfMX`g+lob_OOc|V{P)*R9Z zQn@kEl9t0I9F>>o-44}LyY(Oam#fV7C}}n9H!SkeE5qz9v$ib4WJlVeeg{k|2Ube! z_e}WMMP_!Dt*4~l7Ux58#I%QY9UcPkhYq>@r*AtcCo&>^rZc5AVDv-{Dm`A52~r6E z@E;bUEnORHO$$e1E6hDaIQZcWMd%`_Lyo`E2>Sja<;G4?vla4NVd7EL))}SPwD4vE z?!DEgosWn`WfQ*U9lFNy-M6C_r40`AT2C_W9*U@zVA%@m6IlIMV_^*g=;mM6%b3}< z*Zj+3>Ball))S3+L0(A|z726~5i4tp_5ZpD^v=gCtpgr5-)cxJu0G2~RqDfil59bK znNeFcPWFe^rSAz(ZpB4tIh!s+HDr@3dsdl6%HbqX{-ww^z7i8$1m7eWqtt}zd3u4X z!%ZUcbm$S!)LvVpoK-Z;tkCdQT#c6Q;$a5N=|pymY=xpRfDa_Na>Zw^ZF7#B3oM;IY_~9)W+|M6g_9A8qs=;aRg0oC0MME zhIR)x^($qgi@_=0Ym02f5)7Hf9-)|ad}Z|&e=yVcYCYOG_mF{_8%vJDi ziA#zRL~mYj;@`~22eck#d@H1qZ5|8FLJq2C==Q zAeL!TKln8Zl(fLiP`p%zu_v)URjWK)ls>f_+mYT2=65MuXDx?7J2sX#LEaa9O>%;Ca(xO+2Zn7pomBMv(u=I&8 z($3k?}z(;(a zU~AqnVK2i|XR(}J!5%{Ilc}8Z%4##8KCOPE!?N%;VvL0U7uoW{HC$WC!B@0?af|wM ztn&30W||SLK11B);>oW$NEH(4)L`}*@CCKo9TPDdX2`XkcDgN4-#wj z>wOi^rL9Q%w0exbJ^`iC6ARYnaIlNvRn$1v);1Kh7gjAFoL-j=YIPf9NA91%Ek<29 z9*U=*%^95yQ^dMpJ^X{!*Q<|gJ>#Y|X5F${UB<9EK{^D73)u4EM6EfUSUII;j)2NbROYWero^6v2c|-#6)0+Pr6?&pu-&I=vM-<6#gXIp1u%Un-{vM)!#; z$Y?B`G^YU4S+6_xD9M}CrXl@Xp-`5uHMgc1nUpoCiXtuT2}?o?TeNffFTD0=v*2;9 z&=O0*xu|Vfvy7S&c(KM+ZoDauHQ^7Vy-9Oq*k_D{a*;>QU`ch%KnZBTb% zz7%uVw5h^xG}n6+aOgtCx(j#)+juT-|%Jl{8b~uxz zYpLH{t6a7-y<6_vYB5&O(m&!bD1?bNS~u2~2S?25lJqP6%K97MHj5h7su-(TwymKR z$M^}giwChwbCW();M-exK` z8oqB1N~GTU<+R!9^NXC+Qe$k(e1fyl8tEQGcye$P6id=*y}Eqwq`?oF#bl?J7%4Jk z#K~0Lp2C=bZR^%5uT}0c6J(_p8PK?4nfnZ+peh= zb3Y_sLUDg0282+FuC0u}G1$zuOKOoZXUM)~d=O6haPJK2*6L>_YDMNly;IHYw;6I_ zOWY8Q8JDGSt)U+JmS7$7-C4G{IPCx|GqundB~sn8Ae4zvGvk8{;YC$P)+uX-PdBsg zmTEG0L{KQgI1tNsUg1DJ9vd>fc9Z#FW~$NLk)g7p{(?geTxNo)r@Yvhobd5;%x7KB zy_WN}^$K+SQFpC7h}iOF?h<#Qd!&01BFksGySPtqcXE5(HrLOt?_Ga)ed>B2QRQEC zJ@0zb^@!^M#FW3yb))NQ*Lv3lh$z3(wb&JRMO-1olb`0A=qhsMxrQN{e3q-5tF!A^ z*WoUgOLP9<{MNU^x5&4^cc!n>H_JE0SLz$%8|53~>+9?3>*_nnceKy%bNDRY{ob#= zpW#lz+uql_yS#t)KIZ+ScN=UJZuVa5z1(||cMWbUEcG^d>v2vo&pX3A**nf#;2q%| z=*{tFcu(;j?>*A%fd_-15c_cm4@6 z?C*pZ!;Q`>ofjj5ebTwy+3aj^hMg78Go0nl@y^lC(-FPCkF$sKROgA#qY%5^?o=HA zbbRI52P=rT9J?JaIG%Dmin#UnAR@v|j%ys3A!_|Oj#Z8&jz&ivV%E=fOm|Fj6g%<} zv3`If+tJ+-a2$tt^=^l5{}E>=e?zqTckOT3U$#GMe*&@U@3Y@!ztw)d{VGJNUu#d< zSJ)TX7a&f3rG1utioMi622tvV*!$Xh+Pm6MLX3L9-C?)b_S?Qjg!&I{Z`)q8?XvwD z@#+6)+h)7ncC+nTM5n*Vw#K#^u^E~Wo4&?2&o;w0*)|T5=||WG+H!0ewo?$7{z#k0 zX0`rg{Ri%O{MGuNb&vHG>vM=n|FHFb>sIS#>kWuVf2s9+YpeAvYYXDh&$m`tXIrNt z&cj%1u63xjpS73uG{mAm#(J35X;pCo^o{7wdtQ4|dqjIcyIZ?WyHUGZTd%*PzplUN`G@CA&tKt> za*yW~#HiTmdDwHmXRBwk=LXLP&!wL85w+qhPm3q!neVCc%=S$6Oz@2Lpb$e4qH<^}XSH+4n4bZ9e3?&v%#aR@}b1 z%6AEDa8in5(=6&t{Vd~Wh4Hi8_*rKBEH!?X7(a{UXNKNl{46qlnvI`@#!r*+(`fv} zjh~qDv%vUiFn*%OPrdO|CqL8mi19Pu_&L+~2^&AP#!rp$Q*Hc&jGrpwr_%VTFn)sa zQ>4!`e&!lKbBv$a#?LI{=M3X#rtvew_?d3}Of!C_8b4EvpK|$`sjoJERvAAlNt)A7VL@*3l{8M85Ik*@4D~%?0s^AFh0KXy}$R5 zhd-_>345)*_G)|Wy9$jE8ZI>M7Ji=y;*-L?wE6QPfVJ|ZgCJ{0;u=zXF0 zgx(c;M`)MO+d^*%y-74pdqZfa(Cb343B4-xiqHFq34CR3q40vq&+M2 zjL_3UPYFFK^n}pkLXQb;6M9tW5u&Nu!$J=UZ57%g^e>?Yh5jk@fY3jL?ic#I(0xMp z3f&|0H=-%p-9mQ>-6?d3(CtFE3Ee7mi_m7Fn}u!?x>4u`q3ekzYu5=~D|C&})k0SZ zZ4$at=nA3Bg)S4?D0C^_CcdOfh5oo$=ZDVIg7jOSRv}a_R3;P7 z&;p_PLi2>?3e6FkEi_B0RH%d~N1G`$Luk5CvCuT3BB7~5Q-mfHWov~(1w#2kc|y5D zIYQY&lZ3K_CJIdu8ZR_XXspl}q0vN>v{6DMg+>Ss7aArsRA`9MV4*=m1BtS- z#X3*E#X3*E#X3*E#X3*E#X3*E#X3*E#X3*E#X3*E#X3*E#X3*EMLJKuMLJKuMLJKu zMLJKuMLJKuMLJKuMLJKuMLJKuMLJKuMLJKuMLJKuMLJKuMLJKug*s2Zg*s2Zg*s2Z zg*s2Zg*s2Zg*s2Zg*s2Zg*s2Zh5DuRd<*qUgf14kNN9u5g+vSV3xv)WI!|c5&|ihl z6*@=gY@xG+&J=1FiVMYrqCyd&bwu;^zX+W{RH*Y*EYx`_7V10|3pH+ap~kH))VS4! z8n?Po<5m}H-0DJ&TV1Ges|z)5b)m+sF4VZyg&McIP~%n?YTW7qjayxyajOe7Zgqji ztuD~G)dd>2xkDklt3oio6t(B^YQYf))2qpGNj@MI<}Ie`Z&a ztz}77Xc^*wG-c)$7pLbH<`z82*#XLmJk7mS1wfgI=wix8=} zye9Zxc`R*6m#S}0H1AUrsp{}pl;bPCa2Z@ubLuDjSMH`?v0mA5M!tEwib!Q55F+(r zNfY!!|DD@Bwph9BjF-*ZEQ*K+0jF`vrMW>95_n;Q|A1%8^D!Ein7m;Y?ddgV^#oLemW z$hi@?IFRYgNf-_iD`PSK>8dAgR^q=|@fH?E;1ogjw`L!)dKo@fm4EgIn!CKb`-f() zlt$o70c#zupW@T}*=p0Cm^(V}d$Zb-$WoVbXrkJj;;cVgtM=N_t1r9ItaU*I{uvZ} zf;wXo%@k1p{OQ_1+;z%jmL_XK1U?;R?Fd+jNFq=a{~t_0B|GrbMP}O}eNC!8P;zZ=7X?FeiT}rHcxmj7C2;4|WWyVT|UdhWE9)0272O&=3+z)HAHIv8ru5;v;6p>*c)_Sy`Ih%nuLyie#M+EBcd&p+M47{5 zmG4>cie=;8D*}HK^TL^&f9c^vM0>@_m99!1n#KlOWi(~GRaVAEZ8^% z$lwfJf9xJ5@`z-!xIp}W{=7l38aPy!hkcuo9$}U=5v@3H6wj!PF5nyXXRv$s_`8}&|vYgjuN8sy0 zb1#h6&w&;B^iXBENQdIMHN6lyDMDi1h!sV#ck+Y5HoQkBHIscFT;kf=TGNZeFnvaV z9{Uk%m5;x-%st0O;0!{>D6G6hpq&PUNkv&0=pZmP3Qg$>GO$#va7k}K<)+ML@ED(`eB{p1#9{dW`1TaAvuMT9IAsZ)6jak8aphV)Q4 z2kz6cM|7+B%Oz&vDG~UK&<0BOsaa)sf5R#(eLkEw|DcuXw$J9bTEkQrfo}=9N|4=b zB6=B&{Qp>0MvtSF8)oh>TUH!_&k1?NQ(ZLV{Ej9M0GQJJu^QQqd%DA{u^=+hY#n*N z;5eC;o)c*OV|A&^vx|e)3w~h)o-CM;YJu#Xnn)g9{??ypdkU8v%Ju5VsN0 z7Xxtg{bSX2>SgVYd)iK4W43r<1RgusjL^xb9RX_*oQy^>J5V0@bJZ`qr{RI;&Fb?b zaPNV+Aa@9*`%cfw$jSI)6>G+?>2L5a_gDBALyI{R9szm&iT=_4 zq0nRY@gMI$)_=JFAioQm%wLfy@N3`az7Ku7pv!#8_pI-6-$T9!eD^?`d6VxN-{p`d ztoNPiTjx8~*XC>T)%mJ?WzhD|_Dx4_!5rUs-$>~D`}=zN(tSt!y7+w1_^aNZz2A9v zdq4HQ51s$3-WR-2d$)PFc<+bS|5on}-mAPDy%&1Vh2H-R?;3B5x6xbUT?Wnnd~d0D znzz6^$vYOh|AF2Uy*<5My+?Wvf%f0#RXlq=-y){r$IuzS;o0HY?s?Mli046Qjqmhq z_FU(=(sPODeCUm%h0akP)!pW9a@WDW zqRhR}J=;CqJsA-d#=A$l2fO>bd%4ryN5jU#=XSVN*Uzr+T)Saq@xJRV*Q>4hB z)fM&@hqyd0n@e%-b$;vo()qFTUFRFl9nS5}Ct>gKpz}WGozBh9>zr4@;^BPf+0LkQ zt@C8(O4vLscUCwTJLfuQI;X>dtx9^`a6b!2<^0hSM+J3e&m z(%#my^fCG{Jrmme9=cz5I$n3YxffTmyTEiyZ46XF_Ups-q1S z5p|AA$5O{U$4uml%yEo!40mKY`Z&5fj&>aC@Hh00BPBYr{WA(#y)o3#65dEUeSP09A>BeLu+ZbyMGct_cM!Ip7afsnIbp03oJN+yD zWBncdb^S&CY5h_CLH%C+cKt^EDrCt#Uq4Gq%X^IP zGQPvOi}7v7x3~=o>n=1nYg3C9Rw8H$D-kq>l?a-`N(4<|C4#1~5sg zB4~;{kRlJH$O9=Xj@J|x$7>3U<28lF@tVTocuiq(yr!@?UQ<{cuPH2!*Ay1VYYL0w zHHF3Tn!@6EO<{4orm#3(Q&=3YDJ+iH6c)#83X9`4g~joj!s2*MVR5{soNj1oX<8{` z3FA!08I02ziy5ae7IE)7-xGRQ=pCV5LT?Lk=c-N~XVv+J{Bb9forU?TorU?TorU?T zorU?TorU?TorU?TorU?TorU?TorU?TorU?TorU?TorU?TorU?TorU?T=#^B_E2*Ma zQbn(%ie5<-y^<<=B~|oFs_2ze(JQH5fi6?+U-FXl(lr!k2_P}OG0Z_|b3 z5-o9wbe%R;{%?xVWG0mdMOArFRF!oks>(VNRb?HCs&j~#% z^o-EcLQe@jDfEQU<4lV5ydpiXoJuoaJ%w=%<7&o}8Bb!I$~c8_GGifQ0b@R69%C+J z4r4asB*rYpiHs9?dwPR$C*$jkuQ9&L_zL3=#+MmiVtkSD1;*zYw=+J+_$=cyj88LO z%-El?ALEIPeHr^O_GawGcmiWj#vY8vGj?Z8XY9tVO+=f7sfLfPiI`qcpBrW zjHfWJVO-64GUG{%ZH%pqEsU!eS28v;HZg`78yQzHHZayR))BgRlwCZ^E*@nUkFtwL z*~O#m;!$?-D7$!+T|CMz9%UDgvWrLA#iQ)vQFietyLgmcJjyN}WfzaKi+j?=J?Y|} zba79*xF=oQlP>N_7x$!#d(y={>EfPraZkFqCtci=F78Pe_oRz^(#1XL;+}MIPrA4# zUEGr{?nxK-q>Fpf#Xafbo^)|fy0|A@+> zVyt9b#u#L*U@T`WV+=4ZWn99zm~j!~LdFG*^BLzc&Sjj#IGb@6V<}?^<4ndGjMEv5 z8K*H8F-~Qi!Z?|+5C`^@82bA?!2cip2kHOEC~?Jqp8o`7{+sMO%=@wTE^n)M46No~ z!IyC@zJ2ZZwms9G=hj`1yJD`Xu7jL!;ft}xITYW27dQslzqH?G58DU9=l?8Q7QT=! zH|7|}={xmv^kUtvZAF|vzxuLzx|*N%R@zNz>(cVmj#OSzZo_Rm{5w7hUuIL^lGj`Z z_u}T-QoDBl2PZA~$&{>|5bb5^TOiY=96js-QEJyO8l_z9^O)C-kDg#=^nlu*^RdFe z2AN<%vvH%Ma37{@B;Dyg5b0Ck9>f94hl+t6l!GOnM*LV? zUfmq5(~f;0xUAVMTO5VUFbVkQLE>3Nkp@W6HKh*T@g*K|5=}>+l~*-oRwFKc`l=w5 z^VHb#ba>A;wIP~Qs7`PCO!?~tR`7xmQMeD2mV>-7;b#PG39>*=g=8BFNQ%}~;#m$4 z&hp0k@}Rn5bLmYdm~APD!e^KS>e(ns&EQBI=re@9X+-G95)UR(u&yl~?r=?+@U{h4 zq~pmDvnQ-Rm$_hJf3vEJD13&gOI9VS$`3Wxh@vHtmKp<)$na7QcQ#DS<&+*c6BxB@9zw{jieNedodtqn1aApEf2Vny>?queDa>FY-zGqDkEU|hA@@gJ zdNp*eO;zx?hHF)3HPq3q>6Prbs=mHjI-nf;Ixg%2`m zyQn{LBj^b@Hbbd7`S#nLyGj-XJ~OMC6NM*oF{;Ux?tqgpN1sXP1xSrS5t&7MhmNTX zk^^}v-d#&)z zg;6*u(~6-ck_^2VF;z$bfTxyuh=fz5cuq&4NciF*&=fqqu@hh!2OHIm>r0>MZa(gm zDEyXbF3&?c!`KD_6;0K_%qpz-w)EN{q8}krQdJ$4qPVggwcWga z_S>V)+DfAEUZy!s(UMr_1FaZ0i>stHmmUuB-d7o7Z*=U1Cwbs9cDRZA^h?}sqNC7uD}M%Gj>!I9?sM*@{s0u z`xJ%*Udzo5p$eYdSgYyf8HfedSRGcYHx#cu)O@C~QTRK{`XaYW3UHQ%$%Q>Lq4>k} zPMOf^_p6s)d6ZdvVic~=G@*y#*3*Kkuo@bxVeXdrsl>Ca5s?6bWo6ucY#y{ww4Qe? zTVPcYh{6Y&w4?RZdhuix|8iOu9GF>l?JCOhQymD_HY~#)o=H1p4PFajJS*kXs>?*& zJ7{FXb*;FEx^#U}j|pZo=SSf;O|ceFp*I4>K)}nYyaq!POkakW1BjOy3TI-_s6qsB zK`QZ@rp)Dma^!Fcr#A*y2AW$k8}LVjnXC@z!>(7N<2IX>Pl&?5ngab%=mdIlGE1RI zCNs$h3u+^_1r!^=gz=v-a))x$&*^3j!=mu7CJkD5)F6QgkN}ucInwUJ)sS0wRgHet zZe@ep3h37_3Q;^xI4B2$08E-1m=|=oTzhf#njx00MOM@h4H&gEFIa|XMVMctO$zV7 zrIarE>E&)@i#=HA{?&iVrn<2g3`)EAxqdw`0_C zizi=LYnB}yg+Db}ZBdIcYzU=UzyGFcKN!ks`2)=;So4klkpj~BL@!U`!AT5*RAhZ>$p2G0zYdCa6+Lb`2A0YS~GOyghm=X zP68UX_uH;~diK-iGY^cw)7mUD3AQHuE=nz;pS4jrZ}X4IB5<}gixgu4R5W7m>{KLu zhqA7Jxmjdr1di8a#L*!J23)H#D?1e%y;X^Aw%$tpB5=hf`zR__5U8o|boDJR<)U9s zH*Yc|0xxW`Dx#}P5mJ%g)%)IK%P8d%#|E?1m6A&Oa$qBZfucNoIB6o&O`xo` z(>?pQDA6M=lhY9qIBC;cK<-JQZzbC#!Uc8il7rSNr(ZI}yzk&hSl*KIYMUzy%|1KS2%8B63Mj(c|G#s$Q>Ha8u;ShZ!zQ zEjv9ITraj5rz-xv{%`$X+P<`XY^7{Kt>C9cw$>c96|w)8Pm3gYmWTx$&W~ z%Xl3=G6Kj^>Dey6aLpW;m_M9{6R~EDo2@Pp<}jVI-)b=IL13hItDxXJ9;5L!_kf|4xht; z+?PKiLc?zRr}p>lZ^7f`1;l9BX5V7J-+s6KR{ITz(y-Bfq5WKY+*icNj_4L^ zU^mdH*XYairHHvu3d?~4eUd&_AC9OCC+a=*uKJPsA-YGmbr8e-?~ngidw^uU2Ft~@ zm*{8hMaCBxpJ&|8_#ET2jL$GW&G;1KlZ;O=KF;_U<2J@e86RPMnDHUTt&Ce3|Ha69 z361p0#+w*#WW0g#ddBM*uVuW3@oL7a7&kFq$#@0h<&2jxZe+Za@e;<1880HldLv{l zguz+}gS8L_YatBQLSRMGHLQg|j1&5qwGaktAq>_+z`}?A&RPhAwGfDfLVsZ`guz+} z*Z|RASPNmW7Q$dH1Y)Mp-^&?U3t_Mp!dS|GVJ(EgS_s5ep(|MnVXzj$U@e5fS_p%+ z5RkdkHLQg&SPNmW7Q$dHguz+}gS8N_MWQQN3t_Mp!eA|g!CDA|wGgmYqH78n3mEem z^B8j(a~QK3CoyI*PGp?GIG%AF<5%YK$sl8lys}|Hk+$<1dUq zGycT5m+?o&9~i%9{El%CUon2k_yyzVjGr-n%J>Q6$BZ8_e#rO% zGrq?7D&s4RI~ZSPe2MWz#upf$XWY*C9OJW$ z&oDmC_!Q%lj88B=&iEMPHpWL8A7Ol$@gc^oj9VE0#rPoOKN%ljyq)nj##AWXxpDU>v~M zpRpg~iHv<2`!M!q?8SHjV^78&jK?!}XG~}8#@LndIL2cck6}ET@hHY48INE*obfQm zE{umV9>RDq<3WsmMjxY>(ZlFwbTK*^9gKEH8>7LfGir<~V;ZAEsQt$HE8{PWKQsQs zxR>!q#vd5JXZ((F597Ct-!Oj7_;1GDj9)Q+$@m51=Zv2*e#-a>#$4|IbV7rTCvl46|BT z`X39M{wH9!zsT3$`}Ks^~RDp2W6RJr7_VOv3Q_3!zFOnstYx> z&ecjFJ#0nf&bq)DXd9v2LVm(BxNPc!)+_DbTiS#{(Q1*5l5C%JFHi+mql&u9j#Z>B zdMaaj*t}z(=yDN@Qkg;|_Um}5cKyax2d^_P9TE+R29qvDo~sI05JG#7d!&@wF@E(Z zOFuO-S|u`3Dm4?C00X4&VU1}{uoel-Qi|@JyQc7b^M=Etm7<%Hw&lSqhl+A)B8XyB z3O>5FZLj57I3T)Ax{=f|GlK)NY7jLz17%lAX>H23<#$@T(@|0Qos%@0dV%zEB(*oSf(T`t+RSgy zQcip4FJ{+Ij4l;TIR(xwdH5DYF;4=G!J7I)d%oyN>(lXrRQgOMfLHUl(TQM0-N@a!cUy?@KM?6ftvD8 zchaE}h#z5TiiSnu_)YdAba@t3e&i1Y-7vI*oo-_vrL3E8sdm`5>5}2)A;b!oqPD=vy=^I z-fA{zP!#Urq#LKpbHnvb58sHLvU8c&N|Y;a{lF|UAPPru()Cgqa_ub-c50HduM$x# z@7l~LT*c*~X@^-BXoF zP!#UtW|=Iw(;~x6pmQ1h+s(=~xt3bEM-)EfV!(!J+!#c9jjF&LRrid7|Hye}%^6X+ zkCVLwIi^ny)WV;S{rutMSclxIH7KxVt#ZLjXPN~@MBzrBn<$V2izPBGGp~j%8+7!o zr2gqUM}rHt?z8RcEQe7mskcoy`yjt zr$s`BZ28!-DniLCEA}>?xY(?{e>C9>&fx;AF0!uHcl1@RoNcMI`$ysbO$H})d3HUN z(19{+49Ux@Bg%P~K5o|DFAA@3QjgK)#kjhvzVYF^t*f;?+mzG$U1?rDEDBfe>_n@x zG3%f%$D_i|0EJ*bRi7*veQMQFH<;xzqj2@6O_T02J&0VooEWhVW))`l=ticpZtftn zMBiwhY(7*X7cYA%WL-OdwQ|nSma$@=D4e;aFLnD2BpYfsZ)-j-O6kgo4*HB4X4=X#iNZYuf_0@~b#`llH zN820&M7e1s%^`H{R{M+lD(fp7&C4^QaKkpIDr~UW5t(g;tOBPkRxa3KS&{XMPE3YI z;Emj>TD$7Aw$@+Gng>MTLoGGq973jx70qnOXANd zfj08+`fZ!#>iAAt)6M^e70*65Dvr*aBg0&2IA$R`0J?LQD+iJP(Y2_nKAhRH7VW2U z<+Q!)&6|&m!o68uZ8-cPw{x%(0l+B`KW9cxZGkp$cPQ6NXf`?uFJ@5@Qv&8J81O+` z2{TGr!{I<`VKryt=T?b8>wc{hg1Dym&9dI2Nmx zY`^L?-=5%<_skk6Mu*BvftoeB8E-2DOZksaR*~J%%Q{ofiw=>+QqEgWLl9#xmcNrR zlWQ=DMS(hmcF&v{2-PC)7fonPP9)4k4guI%l?F&(jWb()MW|N$=?>+LUNN(ICq@UG zy9XuH4dD$>Qw%w^t5C1@IFimBY(*u>hz>G$OZ3ip(10VoG7exooAHXob7}L&uh@IN zS^MDVK=TCz6DAl~A{9lTm6DNQ<7}o^U!Vq-*DKFb){p5oW7jUH&~~ziT-?j;EbSoVejYw z^Fq$w5GH^6lBW8GQp8Rln&ysMudMFT{z3u5}(Zm=gE$!KqojC{gTgY`*Va4vruCH9APA1E08WNnPnsL0SHnwIf4_<7&I48z1 zh3TC<3RO^Mu{oTBXA;F;TcqaWo3?Rfur+fg%nloZ1H|Caaq!V;o|ld^TRbv`=}aFv zG!G^R%InL>t~*cxTS?r%8EK2^kU9=u2(Y9yHg;3)&p62}Iwgh)PBx-shKF}{9e+pn zo>Y&}Fs1c)1;GM-k(w81Z4I_W7DD_a zB)$kW*Dg|v0xh^TJ_L~rC>RV=_NvKsjTy!h-INDEeb_8LFoxwpXJU$H1LK_Xs!&Y@ zx}Y(DG}(!M(7uOxQ&%g}*~AzY3BC3*X~*OsMr7WDw+YJQ)4r)o6+$R%7UR<;M4| z&yjI4IGs#DRozfkBGVP8bC*>HtqojdZ5rcZa6O^vOtWjy zP~;Ko-ufqbmuD)a@m6V#&B?fs(m>z+tbyosAmkGBj#n~ z{gl-}DIFK6`jHcI@4DQ)tat1Xnga4Nl{J|YsD<+eD%9Wn+sq8>%097!X=2Ki`8eai zyQ_X#dM4)fkLH{^2E_~|J#f3Ys>6N7(-+#81Y@X4T$hIAZa zQK4hVBTBUIt!9k_VsN?`Vl}h53`aIf@J*={Cu3dV>5pk1_V>l+^?hRAWMj#a8BJY= zq;*Z@RcOVgsnZr^n3wjBdCXR@uUL9<8PdT~ddCH-q0TQo#cJ<>m^;}B+J3Td`zFr& zoEK^gH=!HKYEHD*C2MviYo3nOZ^3f-4>pEs(Oh-VVZA=_nOA1SoOI;qI11Pq)B6-R zhH!EZ)bvH8=N1(H>oc>!i7^MAI;8-~ap34c4sOUx9irNw-9GT0@#e+7V{lin#<&^N ze_C(E6N5t^sy%C6(Q#H^42s#3M=Qx~JuTQm$*%F;iWe}2Gezx>4;r}AYJ0C3+!Rho zG-YNzq6s#o&uGT#ny(u74_jQ8oooht5zJ;F%{u%xAl}cf4~FNfTCa&iZ~n%-vR4c~ z2xgV&XbQWBvrbzpE>!)4%Sy}(2gKCmh?sfmaKK0}?#-_RG@+qj-aSLi>-)ywV_+Tw z`DB#H5RaRn?&zzdKeDbpA*RqvT)G%wa z3Qf*@)iz|xGUs{bm3^Xc5-?X#5%T7-D`FU@D5`YL*wJH7H!tlSWlsR9lstP%5myu) zTZAih+sl*Qv<_H3qOkbymS`q>-{3nQeXk$+V~%F^eXl6Y`^_FLBo{%v!zh(BZhU0H zkSE?VZ=4y0QU8cUb#sCc#lsa4Bj1EoJh_=XcTjczb8{zJV~`PrO+OuWx?vM0FRL)Q zy4D8g>G_D;TZfOAR_(QotDm)ArKk0awz!qG8j1|VPD!3OxC_mN%!HmOfTXqvZdTHS z?11cem`QDIN*^>B|3QDvgtW1&9%4_jn3vR=nK*D@nP*`cP>xlcOB-vJNdWFl9KU%A z$zAA%$UBW*nkT7?SxJX{h6x>=W1TCl%adEo9+?+~CqW?^TZG2Wfrbr(Kr%DVYV(7=y^Mq%Q2SMS*G~|qwqDL7d@53_Xx&63rY;Qmv$(U zwqyI4h@~hP8ikVqowcY)KJ74gY;4jH+v4ccp_tY)v(jN5Kl?`;G6%531D7xO;bPK= zf-*e^=bzd?Fd*9Ay~=5=s@cI)qxEvkE5}n8;0%oO#Q#XatDV&)yvI6{oz^W1$AQ!4 zpd0B>fXuj%tv`49|M7;OJQ`6M`{pMy`i_x)YciKT)o#qqM_x~6L_WzIiFY~YPPx7nK{$Jr+ zI{nuZ>rKRKaJ3#@WEv1%zt_s&BnlXE-`#FSv`0dIfYQ_9n~Th&a6 zE$3q_-#!cei6M4*$AKE|#`Il-kBi1|N<(b(cPqaZSYJkCVj=$I(T7p`;cYMhHL zfvf^jN^7NikoNQ~a|rWeRV*Jw7g7*!ynU&kis8aWs-i%}fgVNcy6fauttXilg9@JZ zqa`$3<8U8f=2CKrH7*zA5#UW8dmP9}eZ3Cq6nTh(nn-3vOf(hm_PJzjJ2irgm(d z@%>ii%g66FtDO*oQlDO3)Vk?Ns0kNd%Iw*x#*Q`Ew>*_LypQ#KGh$HilVCl78pxLv zgICuC@8M2WbZ*o%j1b~JV`Q+K>esGT{+{%}ERB`P&btV8=0kA6E8P^_>^l}6)*45W#0YOVSl%8+L(~t?69e^rLwzI(~9t< z;b0{;vVEq<{;D(Pbx~g4Z8d2~3^oI%+g&0KHeTt$aGAGbpWFUYxH?=)h+lS^CeSK80DS}`e>Feji{fQ;Z3^nobvk4~f5u~FJth057ST9uT> zU|Ud}aDAmMgie=u7NohJ6l_8UW&DE8JG~cnqNZSAziqSsAitarA#kuM(0O+4xBK5Ul+TitkBz}f0UZfvQHioV4d0s;`)`|LR(4uZ zvUqk3whCC3R&fe-jpxk5c2^TfS(7Opw|SbfJ~;;_#bCogweYm0w>C{nBo=AJS8ZT_ zPvSV&l{PzSb<>0xtQv5>;Yz4~iYOdF9nMAjtwAqtQ8qVNH4Kfx&;hH1ci>4i6siL6 z)Fueq!hw#hw{3EzIR{$BX2xLf0AYxe<{}m|MwmUyNfNftu5FUwW)**mf%eO;FYS(IK~G?NIhkx7s@+2IC2OOlmLHI0qXMg~EU)K4ru@ z*Wa-Z^r0on4aq(j9-AqfGZ_!@ThuzvG*&OwI+nDZ|3PS}_1+p5o57t2fuk6(LAn`2 z=$lrkFjLFvT{E*jR?J;!SZsQ-oQR5WQmW%aV`@3utK(~LJYPUB*CIb*zc>qQ=>+0F2B;M zVNR?_v<*uVosdg{qf&}c4g)HDc`w!e_`v+ww>a6hiLt5jGS8)&1ECs7_v(U;`#e#~ zOGA5h_1N83z~SADmMAUi<#&2`yIXf>;3`oYMAla5~^qYH67RkF=^9 z9ZMLJP($EvUQ@pcCv_aaN~>D2Y-@u{QWk=JNZ;^CtMH&$o~bW@H3Uu&SdUOS)uoov zzx5XvSY@WfU|T|35*ppXB<(=(ew}-<|lN(qUJ+? zX0C&RP)#_T+6?WAJ)<2~!3i-~pU^9Of)wOr5PA6UU!t*oEGN`E3+KJmIku*7#K%?* zg|SKUI_H=#IF~e0oQow|%5J&ey7bny`N_pJA_jvM`e>!czy~_c(76G~EFeh6msIL= z=*y?&-C(sMCpJ+^@^b`h<)hv_bRFPfjKI#>$%E?P80=c)M1wVllYh9i22qnjfll}K zt)G}&Ap>GCZZUNW)1jP0+?mwtwGY>iZ?M`rC2{pLP%4?iIW+ZGWK%Zq3#jB3hT7psm9hbw1y`^vnocMO&* zrqFOIq#Y!4o=VdjH9o$r;rXk~D~HEmjgrkRWLpCkS>dafG;feH;)RZqFoD1=F277U z`>S-b;J6qJP)ZVyMqLBzPT1B!hy^oPmT^xC)-4Y}LWLtiFj$EjKe)G{W~5oZe+-5v zgA(QGjE4I(p_-Da02DCc#j4R$nceR(^YXqin3yDGkccn_b8$X$2Jray9%U<^u~g9~ z#9%yP${?v})3J*~fV^1M?}$zN%u+p!jKM-AKk@97AT+L`hsH~!E6Biz3rJ9-p( z0J|bC{oRN>KNZ&hA3C=<*Epv;yE@)=+~_#Xk?-&$cm1vQRrVbFQMT7@YY-FQVB;-h zjE}$*vA;+<#vJ%xVH{6u zMx3I}DsdX7A1UEksPj8JW%tpCY|ox(t);b)l5Spnbi4!a%Fg z#P}c)r_pAS$6sjB^w8E9O5L_Pt|#rq55^T+hKEIQ7#Yxdr0sh;^cm3gQWl3m`n1Ht ztPAe@93A&WZP%Xh=~tV>I4%y019N@jQ))Us%rONh9v977q- zLH9&^AozkpwicHD`!=Ct722sKBa^R!iE)@6m{lat8~>q-4;PQGvO2a`9JU4+4VZS| z(+KlXA-qVe@g1kHf5hK3&L02tojPX;kTNWH$ZHvOek=hamy>Nxq1B zA+b+ZX=m=5l{ek2Db?mXX+~B zUlD}Uw_0~%9A*IY#Ye5{{Jl_VyWk$>@}q0a<_(EM<&Oh4U%cM~cBO4ft+JuVMP{jt zczSY3Y2-T}sw?eNwko&v3z-Fa#G&5D+{JA=o|P-L$L7x8YAJ9|h(oC_(=+urTxs+i zb<)af&DsXWp~J^wk=ibGlWHwI)}OICS@B zi{~^3nyT2erc%A(=m{_0WmY>d4rRUB66y$ZcM*XzzxFGUQ>yv_%M!VN97=iYuH2H} zktSAZXWuic(URbgi9-i37Os$?QT!tu!V@2W#bm0uELE2Ck8EYrg>Rben-_=9o$PMt z;{d8li8#q$Ws@L1h2*Pl*&i40=}(OhAHKw_du$x~c&eKYgDe$>&6n9U5w)kb4PGh1 zkE{jPCk{gu&_g_FOZZx$OEhq|85=|@Si4(Ifmuvt`# zK2^HYGP39whu)q}i&Uh;Ze?BlTlSLgtN|Gohw7e&^C;Rne&;*JEM|Lev2yJ^YZDz2 zhc2JqKXjMG{~oVgcbzqy!{bot zXD64ooYDgS50do8zYbO{eS0cAx2{hs< zw=r&AtwfieYTjo+9QFanBILrh{^i4A$p?+ve&uxJa zHR#O=J#;sJqRP6{&di=Q!dec4<1iR7kB9lex=KpLHU+y}>h08>M$Wlb^9IM2WFb>S zN1;$t3u#C7ot%882{D)v& z1_MW>4@mE@wN%(rPKi_Y77x2=iXgQF?W#C{`W1XNY zY#l!_GWRQXQGb0PKRJyC$6#Jyu9AU+sB=V$k=h^HC1=e()#}mVv9KHiNom{p7+BtM z0@-fbo#uMnQkG`LU}8WgR?-;E2?pVhTtSw0jiLI+@(yCil&?M`v#0W0gQZZ+i^1*y zW5GxB$;}n;=D|@1Rz7ftsR-_)FzwhW>N}0$iPlq0jKL6r1nSfnT0to zC0epFn9`g2$-9)hlByH>{vW5DulWDr5Bf8GdwdW2Rv-t!JKjzB{_lzJ|E-==Jd-_# zAjjP%cY}M7+mBpyi(L-q%g%MqY0g6(+Z~r8YFc+hLOaVo58wT7*v_@hv2`(a8Ydg+ z$Z2+wo~3=K-L0LX6(9@1)9N|u4Alu6fHTs@D8DMt;MV*68y-ienwtxK>m&@2AdRdE zH>7@;ujw-Idn@W^MjTy9CY-bd7S^o{&@S4kz)_p~wO(efsL^qBnVepKUu>IN*cM;C z;MxUd;k-CZ7wB%YaJPJD`65FNEKWjbmn&mH)-wXVm;YkudXn%G$6 zq?+0eJ@bLlw^)8|*>RXLPVxAjK`^&Y(y%~lKr!;s#~oz@`W>|mw^&E!32|5*Kr76R%w|m$ z&P=sIPWemETZ-dxr`A4GqFi0L$b8I#IBX2)xIPB0Ev|#OhkKZ$r1TYr53st*y3S&> zF{Tww;rL~r)SFe6#$i{0?KrI*Rne}~L5o+H@(^PnKW!%WW#}B)q-P9w?@wFO}dvb!0s# z5?xG)fVo> z;D1!THnO~^)Y_kh$6=E|BSUk!5INOhNQB;J%ed5MHa68Nk^TeBc1?`K>VVGi`Dhmf zxn%%(KNwyiMDuULi0#bHx`!Li<^zau(HDX(9! zUb%OL)%%0uvqehCy`Pj4rj#)juU2*>&!@xVFefm3t@D{ErJ&uuA?>K-8Def6CId7} zO}&2SSz4R25)Wu3r59{cZeD8j!{B&H>ZtP^ zzeAei#V%=q&19#EZ?Z1WZB1k})L>*^Tw#aO&NiA8kxKGdT{!;?vBx0PI0h%t%tp*{+3T z>Q$@NQ{%7#5N+;$>hFCDrZz!+dHae6t4K*4s(#ume#erf zrt_O1Gi5n;91Y{5t;*ZGEepGOaVY;u2Db=9`1__T`&PccVX}?wruu$iBeMBRh<+l*+%)53zn@l3yh6J(NEegwpt-q z7QEo;ZOuNwmB9`rGg+3Uzu&XDVVzk#GY-u@9mi-9(pSZhP&wV^UT}!jZc)96-gc~0hrnQ`msC9wpx0Dp>e3^ z%|jZQ`oJ&)mhf~aT%OV;wx`N#9>3kZMRpttdJ+Za;ug@NLNE($YEv*+v;2UoQtQ=i zaJba0WoR5~d-LY-kbzkjsps;LZXosM+S1j-4^qrx{M6w62Sv!68$fWvqXdFs^dN^7f9ptmiJMUQ7JIWuo+AtyxmA@$m+Q&{L zwP%d0*UwMha7cW(Oa(gTBP0N9Od!UA!Z?tsFg6Y?oRKu}DTzbpA4oKFKbkXW$~qgL z?V~z{KWuJtlqSVt9Y70?da|ItzM2JwIJ<`qJS(^D7@IUEq4@vpMpxzkuT1EOo?L@y z$BW_rKOND8CmCamp~e7MAN}b6+W(pVegB(?`Tv~%asO8T{rjlQdVm-^24o#k8SJH^)msm5|&xo@FwmT#Ib-#5`W$~V~8&)3s;obPa- z-{%3JWh}5{>lBV`wPTh zc-#G|`*~PkJnVkJ{Wtfm?(5xGx-WLGceleIW3_vwyWU;p4!GyTK4Ypo*FD}n!adO4 z*L}SE7^2uuA5!gxGr;D=sL$0b)DvF zbA??st{|j4b6nG1g|11iF|MJm0j^%IZmuI;2fJJ@&H1x)kMm3CN6uZ&*PJgnpK?Cp z{3oJ7+~&N&xd|B|&vTxMh!AU>tDFtakh2W2AxfP^&OGM?=Sb%u=ZVf9&SRa2IekvM zQ*r!=+>xI--gmr-*b&b;9(QbY+z(HZ&5mmwmpe8%&UM5bYvEVYmX*=@F8ZQmjH#fP@Hkon?S+cxCA zxW{&@(bYH{G52lyuZXz+rT!t}?eEZ^MYR0~^?ML&|2qA0MA|=FUxzsREA=`=*=o6ujiOTek zggzAdK3&o%6si)j1FRQl0a_FV#5@{8F9sz%SJ~5Bw7SF)F@9 z-zM~^&?7<*3q2&XRcMRQzl0tX`e$N1@)Dez;G6_!GoNOgl;ErcPfYNH1dmVfxCD<) z@EB(JuO)a?f=4EJM1qGWcvymmCU^)n^Ay`)p+Q0eg))UQga!!p7wRW;qEKI=HAtkx z)LW>R&YX7I{xGk9gU8N9OF3|`r-2CwW^gI9K|!7IDf;FaBK@XBsA zcxAU5ys}#jUfHb%uk2QXS9XiRE4#(umEB_S%5E`uWw#i-vRe#Z*)0aI>=uJpc8kF) zyT#y@-D2>{ZZUXew-~&#TMS;=Ee5ab7K2xIi@_^aXOeiW85n4yoX#7R! z458D7)(V{_bgIxPLTiXt7^{U&7CK3&O{i6thCKME^5Gp6CGs=VlLQ92~2rU*`B(zXy0a2|nUud4tT%kEa zvxQ~}l?s&z%_OQZW(Z9eDi)e1R3tQ2Xo}Eep+cboqG}^wC{HL?C`Tw;Xp&Ht&_tr; z#ss19LgR$S3XKsOEi_7Kq|gYWkTG0nn9xw6Awq+N1_=!m$`r~F8bDNK^cU(UbfQpS zp*}*rg?b5{Ak6ebh;f+J6as0>^tpYdxq_O+Xh><@riMoFXAQ zG@rUvZC6Xxd)^|uAY=;%EM-~!(5x>p(P~HgcL2*1kb1R!kU_93fdEH_T?aXGkL%xFc&hlhk}S4 zz!hbd)|Zi8JG{h=fqRu(w^-qHhPK0^n}no;NG1hWIq1DBtp;=`r`12zc^P;_!7<*Gux+N5j6m0_b z;Z0Ui2=Td^o0=vyQ>xQIU4IzfptHhiaP#!( z51Y3c+71hEve2POWRS|$*EF*$&7e`EhBR^iBP0sO!WmkfHty<=&0<5^Ve5_V{tOhm9M`xo+#kM%lPTU29u?6vD8^@# zITtXokfax}X&$|2^)Abrd0ac}z+s(+CLq8Hf^AkJP(drKkQ1)fa3^bQs_NJp?Lq%Z zJKr@QVR$<%#L2FRp1cSX5)u4Fc1|gYJC-wE9i=={W?8pRXotx-DS zXMK6ESzuT@EXYaONCirf=a;qqWKj$gfR5#i^Y<$M?DDx;uCN_83ia)wOMQ9f zbBt<-?Kv%a3es8FyB5ZDff|%W2uu>pm(#vs6*Z39sN8gIz${zPez>$d7iAHDi+mwq zteJ%wgE;?TAKNs-kizuEgu<+jtS6eFH`Qk-$~j*gZB`X*hn+de+E?L0I5ZQDMP74V zH7B(tf7Y-MuI11;R0SGBjrE!NLD+(lVNH28#YI6#OT=2nt;h~G6YG(Dzi{m;?b=tPE45Q*@%g8?rzQz=;pfZfD6Pp4>mqz43#Lo*=Af>?MAO#Q& zXU+@M!aYgG;>Ge)PQAcH|=*oD28&dp$cuU4Qo>t z*IsdeoPdg_@c=4wp7_ZQZqQv$Fhl zn81@piz?&f9SD0aJuLI(05z$95#`EE>qW7k-RDx4;6CHf*b>T-+yrOC<_c^n z=umm%kS2?MgLO@FMWSD`5I76#Czm$%j<-_J+EsF)73pbgJM8i4wN15i8fFAwL-a4- zev5BvnSIPNW>3y&hgE(dij!K4r+pR;ErRxRL=Gv6N9Qn@h^!EXl~YQS{@SzjZ0j{X zwjI{`WKYwB>csqO;;qT-Tbhr3Q}z^kq7@^}Cgrrlbbm^s`1C+S0F9wKvM}kPA>_yo zlLD2AUh1$pr2YH)33pn0zJcwq=_j=e z)uZn)>mASzvwzZNla~p{y9@h}`x~1OM=wSZwY{XY+YjdTdF?h?$uy?ZDR~d}ZQ%4-}^L zPTFRSXouGTy_-#Q5;?44NU%rMq?EJ`=%##skkyPi?eHHUQy{WQ;<#_6tLnwt9HW6~ zbFdjseWd-{M{M1td^p{zd2qY<7g%jFjcZbx;~3jFt+3Uy8Jyg%NOLCe%Lg-y{Up%` z91X8@Rj54JxZf7&b%n|u6Rj3Zh>PEW)dCLR!WwSg!vnR5wb_``9H+Y~EwtULVRRgR z2Y8Pn4h#;@%}vcPFsn)Jj*g?E-nywe*#Q&d@Iat5pJ}c$s}51=D63NAiVpK4MW1Xx z>7KNHbFKU5#^H)^6snkm?tt}cMp4F!{mrkGdW>Fsm1q0jW=^(}I6M>Z8smEC*>fu- zU=_sxCo|YTR;%rZ50r1VSgo5Fhqpo&YNc5x7D0*EBkyh4VhXUggjaOzBBS|w<@KbY z%cwZK7RV!ys(`V2C5-;z?}US;_;#k0)gRfYJea)w)HwVWC^8Op4n0&BIq}p6nyUWT z(-_Y+DjzpkPctJ99|l_2R2?rx)5Ey5vH6eIssCe#^3SDKox|erYM`$LdOTFu)Qrxi zr-My@%A<8M(94R$je*M1)S**BqF-s)_WN+!n;$5b+-}`FI}XnU+7qY_4lj^6uEQ`P z7~by;)UPU0{+@h-5plROm^;fp24gAD;F{Z#c3INyYeF2p4D_x@TDii!8eVJ%Fxxgx zFDaV1*PONE;_zhn4`zxD9VeIG)=jzVNUH~2?y+g-Xcw#AZr&rk2YX#!&GWNokLOFz zN1k1t*E}zHp7K26Q0zb2zqWsdyytJ)ci5k^KW^WOtmk*xH`}kZUvA%koaZt7TKh@% zCVMS1o-eV_wa-BO|7`nM7(@_dVl={Xi1OI z57M2ws{N#Wt9_w;sDF?A=AYP}Ml8VxZTH%4x7}#F%66&keA`*Jb+%J%{~vqr9bZ+o z#EHhh6-YD z7aJGb6$^@D!GhQB`_8Prb_z}J?|t6qeLnB;#|#JdnpOAOYt4LTX0|cIxXj2mCK#jL zueqN`6oNg-A&yM z-KV=fZq@a>>!|A+*XOPSu6JB-xL$TW<9foi!*#FgcGniyI@c;!%yo_HO4lscbmTRh z;<^Oc4RTxqT>X$4zN70R*9ER~U1uRLys55LH>+D=&)um$q`t1cr0(%V)DPAD$deHF zEb?6CnT>df4}0$O+~K*&v)=QQ=UdMq&qtnjJ#Ttm@jUD4>*?<4;7Rs0_cZY|@c2E3 z`!Dy;?(f`RBEQ1>?zg>Nz3siNyh+|h-ZQ*jujcu~Q-tV?7kly$gCR@%SbI-8GG`*{-INJysF2kY!s{f#Wr5{8@hJWjO^%wQ0^~d!G z^}F@k^c(dX^lSBH`ql8+sM5=jsd_RpOOHe*=uEwj-c3)@TkFk`f&NV0r|a6E{~Wtv zHbS<0uc;Y-z|Q`yame@x@gd$cyTS(F%1rWy{S*CT{lop){&asYe;0o{f6L&IU{OqWhk^Zp*8?vF_5^kY9tzwO*c#XzSc}Y+ z(ZIsM+`!C0Bv2Fx1uhQc1%?K)0(}GB104d%f#!iGfd&D8z(97(pZ(wYzx03Nf8YPM z|26;f{$2h@{rCIt^55d$=)c~-+`q&>-#^D+;V+TvS+@A^tj+&r?TeMKe&*T3T0Rvy zG@#d0O;#YPCaV)wla-6A$r?x1WR0V0vQkntSt+TStdvwuR$rDV)(CdJV5NeU2sTZy%LFSHtVl4nZ>T2QH&in${;@!?e8Hv&77}c-V3P!!DA=Wf zO%Uu7!7dhTykO%58!Olt!A1)0EoxG^d5qB7p$9LT?OkR7#j>!y_5LWQ7|?b zs5%=ARGke5s@_igA8X)MT`YE8EOuQic3r#=x_BQvtU^~kDwp#(1!EODt^xeZ%_?-& z%_?-&%_?*toW%dJ3SD)x3SIT}iRstG z^lM`JH8K5~n0`%6zb58g6Z5W#dDq0eYhvCtG4Gm~cTLQ@Cgxoe^R9_`*TlR##AWvR5VdA@gnHrMbO2Ipo`@#40ftMTs%2Uuw21%1RE;Y5W&P2q-Tp? z))q8S{2CxwmSCBJWeAooSejt{1ruvf7i&-#Yfu+!Q12xk=_yz$GgG{Org;BM@&1|O z{WHb;XNvdF6z`uY-aoU0D4rr%d%?u}XSNl;+6Z=$V9A1sj+vrkrs$X{I%bNFnWAIn znTjHcG#0FpU}C``Z!~}N#DX)E#IL4;oiEsVf}JZ^6Tw;w)=IFJf?X(B3&AcBthr## z1QWw-ieWazFq>kSO)<=-7-mxpvnhrd$z>JClK+kxabvYY=;*(KOhf;}nN6N2p&>~X;!W9Ad@u}{3mKC#?=V!8Xoa`%bl?i0)1CziWU zEHEE0FiqV;!ZdZWU^fc3Nign%rg9%NmHVJMdChCi^Y{_xxq>wjj9(zl$uE%Rk+b`I^1=}as+k(BtOxYpWLxMdh*aL#yFW7d$?i1`@!R`_4 zZo#$*c9&px3U-HJw+psau-kOi;n2#MmNG42I*sXNOpBQoF)d^|m1&r10n>aEr@DBq zRhQUITz$nq_7SYNV7&zEDOjptJp>bbwyT@?CH8EW*t1>Mo-G!!xr-k$#UeJJ6u+Jj zY^Pw43nmt^`Kb8yh+q$s{eQ6Xuo8Se7!BqI8vsSWB~TjZ8F2dF@UO?>3;!lMw;%X52p;A_Bk$cbU77TX($$%y!t-#{9v29%$<^W@F<^;}PQ;BgZ&H z|3JS}U!qUaF90fFx3*C$)Vgb4^?mhWAfKnG$<9B34Os0gb*4MdaeU@@%(2RGnWL-2 zuN*|9PW-1$6p9-dFF9(^pgmg<^qxXbC2@Z4%T4Y4mzAaA9a2ehVH64)vQsvo2%^KQ3|5*J3Hj*-uefmIV>^pNET^48=kYm3H6d7Yvnd<6S|AtP*N1nT*u z0>oZL`pwAY=Ai150_ft&-k+(-LM@|+YCuYUYQ#vG@(N&HM2=Oo;+iaU)ioab?!q_c&E{=GHJB!YVo}DR0l+$h?{#Nk(t>ZBw>9dAcl^9JL|?h_Nq$ z^E#Pt029G9>3w!8+iuI0&$f&r9DrOSIV2e|@6a3w9kD}M@%&EtVDo6c2!TXG(~zd8 zD1s*I)3z!PXM7_cY8#y*tkm>S7NU%DVpvKFK^d1J^YK(={a)KHnH+^DKjj`H^H~-W zZdW@8!_*XlT>%yvz2!}#Lw1O}cG1bC^cT-cD|eme9VE@0*|$Ev<~=@_a0WYNy)a-fkBzmCtmG!ihe`l1vdo zWVDLBX|Uwi5$@Q!>bz}sz}S{ixW~(!Na$sL5iH4(!s2kX)A?h=PBj_AQloH(A7Zs4 ztz;HuupJ8!QBqF0EtXr&Z{Q%%y0bcWDYel`Eu-**mz887;27EI2;Ecd)LvaNY~T5^ z8%?9|dq2mjBpXo@QX%U0;y%~Ul23Gq!kazSdLpk1Iou&>7PX_2^!iX(mqDn}BxBkO zvPh>WeAr3*Pu^-27YuF1+km)Nvtd{)hW(%nsWWD)eGV2k_RB&&qHtUn<_6&~NYE9^ zTZWeq8%%ZGqQPMPs}p6>u2I{6T{XLQ1o8%vwGaRWLG{zi~qi{AS;14w}2P*;-(-uV9+F#tRQFwjVj0nup*dwRon@)(rI?YoHCPq>pkk-&jSC z&Ukt#^4}pmRavdaQ*!NsxqX#b8+$qRkHYDjKKGq5Y@;Y=8K55+a=^1N_Suyz180?d zSl?|K&i2Uz-nH|8^^0bRZwJ*43qE!jKt!++aOSk*3eb|aD2qdH%hnHwri-sQVPzN~ z0ss_Z;!_gF+MPh}>o-N+kvsb@j}+853LkN-9`23Eg2y1l5C{9OEvlw3_pKZ|ZLk!O z9_=rVbpz3tks%~Sr#LW$wM!nS5n9Wm%HoNmrI4;s_>N=y;K|70HGKTJP=5_7^Z$HQ zmKzj>^EkDhhJjj77)4&kxxh1>q7CZvTj%UNDn<2(!h@VZQB5I=t*=s6D@-fi$M7u8 z9s+ey-|`36%c4D_@FJ)49IXgSkcSQ+^F{l??Q6H7rm!+Gw7W_c&Wgf?9J>=2mOG&U z{8>@ckbI8i95ay_3ohIKjFi(O3b%4P-B2Tjh6tDm6lp$MZNC92_Cz>#9O%*61`2kK z!fTuirIZ#oZ#t!b%81OG5~-dU#2E!(PM}B_+G8-&77U6d5To zuq0A`Y{B;zC{O=n+f@fg;UZ3BP1#^&7HVK4)5^<=!lej-QZO@EgC{1~9new;^p(%J zSnco{<<^<@KG8M`uW{_oA`5nYsB~s9kJ21eCS8m#aJbxGKxh&l-+C`LZhL+Q(V@Pp9MeW9Fj~!MvZcmfXca3%y zS1EcPc60<6z|1hRx(uUK(@FiUqss2c6j`oAw3C=kD#s!DMdYeFMT!;WfxjBaA|0b0 z#Vk@01mqFWSkzg&j8@WDS=r)WvP`#V2l4(;8IFHISPTx0i6~dK3#wmbD_4K^v@F;? znj%ntRFGl7G8QL3tu+5NJ#(Gaz~LKgqjBhu=?xogdw8Y+r>YahH)qiqFzjnLU+DR~8ezetEU5O7eL z+Qdd`YcDodHV^!dthigWjksA6C_EhqZ3MzCsezE!s#9y+MOm_FgDgn*|8!-C5_~@x z4~`FZfk*xOfd>L}0vUmT|2_Y${z?91-~smd7W#60O}vNTdp-+3=BInU@Z9NH;2DoR z06)MBJOOX-RJR6C?ps_1uJ-1a=0-DOwlH=Z^NqpC0^dsv&Vbx=Q0*Q=w| z#?B9&w>!SVoxjr2L-_@b_}hQ_$M8b6athprfV=`pgTG8u<_XB$@K7O6=N2}WQ1X>p zv)#(V@9ao#y<>RExeCI8x_{y*WKJrCOQCa867^@oe1YkIYu)J#m>Fx6~ND zWhhSgoYEMEUM_xfEKz}r#Xbx)eo+-ktKHm`+T-n8 z6Lj1Vv~ST}V%P@6NsxO>Ic#Zj8yl*w(`CKSV&$%z2g)w@h+z|umzjYPdLyxkXM{?M zr_#qDRHrNgb5`DCJ4^J4iCusfNFLCO<#c;OX@R<`Q_|JoSBKWd{$OUruno{jxfg~x z6BijAo9GV3C*E+uRW(Z#kWSjsr%$I)i>G_~I$NH1j%<6s81@62;4FHl*+C>TQg{`Q zbgj{>J%ZZ)9mS~DjTXL(ct7M26GCdQfD^UxjqS?%QQ5MWon!Flkw^UOQs6@Y<;3#90jJn=ukYsdU$iIl+rS))8MZNBVDmss-PK0Hl?wpXI-}_9-8Xx|3|XvC3|>Dt6f%62XEGf-Qlzv_RnW6w?c#!8gt=6M zD+|uG!#qxoC5e>~!7QW+R4%J$B1pvp?+N4=uP3VZjMkc$wzwVz#{D%^ zHgQl4UO}{pWT6UZUT~x;gLe{z+@!TqSWmtj-r)$GSR7J6T6xvW*Go}tVsH>5uqrLJ zOiD-{sWUceWp;V`Q}XG-F?a>hyFs26I1JE;@=l#oe|6id3#+BL6sHa(k*aq7m^b;w z=cTZ;7#xIXp!p(#tq@7zvFQ}lsh^fDJTmb8$%r6kVYoyc*`;*i1yV-m7<`80%Ze`> zU0Si5600Ld)wktuvX5|mV(=J}Q;fSLRZXdi>y2BjDRypdF($N2*4jD-FCnRn9#zfz zLu*nzB+pf~+_)0!ZEJKp#o!hMI3#O>#}wyRVlV*dqEQw*L! zbiW}rV}>87*EAA7AGl&?!fggkLPX1JUnrE) zlVfM`nDK)-NY_~c?L|o?azoLxks@XJ;BNBS&anm}%s91#))#$js4ZA?;)pv&%FkN?0N#KC8@aR?Y@s_bOYFa)D`CDnH!_F~R z)z9Cd+I@lq?$~q0b5k4SdLQ%`@9_0qDZ%r+yiL*X+C95Qy z4>dA!994(W`uwA1W9=!sFcy@}5&FhKVcex67#!v1Z4I`hN`bv&0e1A`ain3P%E`Y1 zJ2jmIq<&LQveq3oplQ#^;upsJHPw*A80|G!iD-^Y)mT zhGyAo!Pz-u(1kl>nUt7UTo$RXmOB^&t!)P|)RLAwt;PqaT@1b^q@ke_BwXa@#@3Ic z36#Wm{(=Kj<7del`o`c?LhG88msw>qgtcoJj;5icT(WVD371}R+TaNN6+W~`CsnOZ ze6MWnUMZkM%q1=eBp@R+H9V&n)_{6NoKNqZU=EN)QevjKNK%n>YzKvrg8C)Y_Sq#x z_D0zy2LBOyQKt6ap(#Fe=;QeLkjwegz5NiAhXy<_kep}RJ>4PApJEvt&JPVh^D zZmg7DM-6Hu zZA-(-il-orOJquM2xi(hvXvX(zCrfp!YF(%#DmyP!==z1BRMx2Xw^3+Ub)yOpKBKt z4i@|}S_T~`w&)-^l1?v|n~ooI)7IN}=H^j2Rgfx>8jyx4lE~J9%Fo!UEPBgcFCC+B zl@MPdybGk}LV`Ezz1?$%G*qis9;|qzyKKnN=uEMZ55qiXmE|MDHteWqNMY5UJ4!Ey zcBVWZn_U&QN9;!BA>5wG(H2vSe6>hg7g49>&bTrn#Wjmo@nM78IcCq@SmR_G&sG+% zx6i&5{|}dQ#rW0u5fRW186P8p|2|`{@sjZj(D#oR_Z!=c+lW~JUe(=&;vcj zpMjqP-v_<|Qv3i=4Q~Zr3%n3`8d&iihz@vX;FiFqzzsl)#}FTI9`qfRfimF5ryxS$ zn85JB;6Nr2<2?`~ux+4aASuuonDGFj1Umh{`+xEu0c!kH#0lIFjKnMc=YSi343Prw z@!#&h$-e=}@fH4M{)PT4{j>e${u2LGL<_vwKgyr$9|U}RZ^R4i;J?Vf174Tc>G>TV3`YEL=$`rSt0N7+zt9YDcIZ74gL-nd0KeRM^wQxJU$P;8SY=*KO(N+A@|4d zdD!RP>wXD3r6=8wz^`MQ`!@Gx#1>o)9n%u`0{0c}nTRfUnY#eK9pey%VkqJZ_ILM$ zcSn17Yj<-*7(Cm38vHvn*PpJR5o7Qx*JtqXco!Iz*IX~So_6hokH>wkJE5oAqOJ&M$eh_yPlESF z1H>Y9=}zr;L?b++eW`tlc!c}4H?&va{jp1XOnVS932)bKg5SaQ+6rx%wh%EmX2a{I z1d$0RYZq&y5Swt2mag?ibixkWMOq7Z-Za$C(0rQlw-s;y|AYTGkASYao#p_d@Wvtf z7}H0YKEm{2raPEE#PmU?4=}x->2{{~F};`RJxuRrx{c{wOz&iR2h-b`Zen#Qz0 z(|%0*GVQ~(H`88BdooRB+Jk9#rrnr!W!i;lXQrK)c4XRtX$sT!OxrPS%d`#CiGd+*#xlEfdZOpV0(}qmXVR|;xvzRtudM48| zn4Zq`G^RnO0j7SYKBiu#9;R-lE~X|^gQ?C`W2!QBGIcOjh#G$}{gde*On+zk8`EEz z{=)QUrvGL76Vszie`NXt)9;yn$Mgu(Z<&6>^lPSHF+I%mOQv5iJ;d~Lrk^oA$n;aD zpD_KH=|@ZtF#V9}f0%y2^nIr9F@2ZmJ52X8{WsHnOy6eu7SlJGzQOc$rhA$Gi|K1j zUuF6V)0dgP#Pmg`FED+c>2pk-$Jxrfwx|``PrcW__lIasncQSpP>0?YEW%>xy zhnenR`Vi9xnLfbuex}=*-pBM_ruQ(to9Q;DcQL(_=^adOXS$W?ZA@=vdJEH=ncl>7 z3)9U^Z)CcO=|-j-n678Kj_F#aH!xkp^m?Y(F2jtCrg5e*rctKL zm@Z|ygy~|YiDpXofNS24Yk>0G8)Fuk1V9H!MwXEU9}bSBd(rj<-9 zn3gl0!E`#)2-7mArA$khPGfo*(_*GYObeM#Wg2E$z%-xf6s94jlbKFpI+5w6OeZkC zgz3dh$1@$rbS%>`Oh+>v#WauUNTws04re-yX)ed5_ z(+sBROw*Y5XWEZxU#5MS_Ga3PX-}r9OnWfx&a@lTu1vcy?aZ_j(~e9#Fim0Fo@qO# zZJD-VdJ)rPrmdN_V%n1Fg-ly8y?|+Rrp=fpF>T89e5U6yJ(p<{rj404V%m`DIZV%H zdKS|LOwVL`2Gi4-p2jrDG{Dr))W_7z)Wg)x)Wy_fYB1HAYD`t8PNoi~3Q_$prhhX1 zgX!-~e`ES9(_fhW%=EuZe`0!+>5oi*VER4N@0cE8`YqFMn10RlE2f8;e#!I;riYk* z&h#^;2bq4#^b@8ZGyONyeN5kG`WDkSnZCjFb*6in{)_2rOkZXC3e%UFzQpuJrY|sk zp6PQ;pJn+X|X1bf{E~Za0eUj-DOm~v~zmu|9LHzxx!FGX916Kr+{5$-W{>Hwy zeVcp}e1`WC?_}=Rs%Y80@l70RL-gK1rx zK0>(F*qzngP3Qdaq*Q)Pi~-x728om&=ESzoQ_8NfVj9n_QQrUkTv@@$*i_iNxB}J8 zfHrUnGCxCaO<<3IAXV)&yJ)|y3QdgxEZzh{`(PXf5Yn{ZB;8k6jH@b)$p-b00X&{; zm91+@J#l-ST@PowZJT#S46t&VhCUcHk*I=@gNR)QTZD4WiKapQ?*e81rl@Sl&=_#% zO(Eq{NXem~iOw>pAqZGQDf$hovZ-elXnF)KF0%S&i}BQ#Qk8zbu@-Xb7( z$RJsvTwSv`kNZKaS)bPHEO0q(F<7P33GI)ds%6DtW6=)ftwC+%=w!v&cv~0+j7`zz>AV=Ts9Qbn4 zn`tf9L6PYvmUGPJrKM#n%bv6W6nAoM>4l zwG;=nnsuq0Ta}yl+kR4+u|Z-GvLTiXZ}8G2P=d0cHoWaPVj?@0`-l7~TQ@QWhYZ4n zQtL88fa_Mk%diwDGqjDqvNa9BnAryo$gN$C`<@I(->jFV(4MgY;!H+Cx(GP{6khGF z)+?<#bMqg!(b%J7@Zq3u8MTN44Ki{WD`q5i-r7>?zQ@Pu>3#c@ozH$D8#N>b7Y}+x zXuuFT7XYzz_Rq)*0iZPJnC{kZg)5#zH3e$UkYLk@1}J z%1j#;(JuxM5L$Z~Xd}HP!}1YdR+)d2tx#+JtFq|#Yh=5+#NhhT3=-Nv0!-NO@+}9} z$P!UAnZ{*tWpBv-#-zvki!TLLoY`tTjvom7+R83?e3YW5wotDAIz`q!HU@_e`rHt( zj10JRV#L|L0=3&KC#B}E^+vePmqRT)QnuN42j~}rO9=If;?dH$0B8$%(n$wKRhv#( z)kU_gFa}SM3~n1t;B>qqF`OTraZ3ZpY7DsQ|Ik#eG+DWJ&l9qy@iB57v1+19Xx)k< z>lqM(---CH z5wJc45GKOw;?OZl{Jl18yY6eqf`-^9kZv(}q0q}r;i|ES=0tFD$RR6zxC*e3TI*W< zp;TG0YO!p=xES0}=vqf7TEvqq0T}hfwbt3rkJ;?C`x+~2pFb)^_m06)g%%Tiw1>?h zM@Ru)uUVOO`=kz8Sz_2AR=WT9QLa;hF9+8L#|D+aF4)2c1-$+@{R#gVWU<@ko9*l1 z{l>z%vF7XmG}!nxeqR($EkzmqH$hfB<`zQW$}7y|T`So*TE%J`}Z&0~XuJ zsx=#N0C)gu*G1kVSBLJGb#;vc5laI{&E%c}DPCRxY*M{?v<;%^1#^|9JFk{yd&U8c#V*MG8yGGR@p{C?D?ii@?wR#VJ6p#G zTxVaG$HW1Vr3M$%8wu2KCY%dVg^sdl&p6<=a!4qG2yHBp{5^MqmQ;qy>y>tH%^ugSn=G6fC)BMqhglVH665m2 z2{l(-TCb@3XA5P~4`ErhOB@hfoGp0%J3jpw-0h%%!i!U{m{$6$vhsQRs?aVDKrRgy zEt{d?VoX}y{%KzyQMUZY27q;r69$)`ho?8fRSXXoVA`=d>lRZRXNMP)<&xUrC_X=_ zAiea7;nmP8Z6*%vh`xPH2l^gSqVK&ZOQpmK)yt*e>=LTnvjrIo>a|f7xpG>xQ`%1@x zr|efbH4YFk-G^u}j&rkLR{MhIG2@P`cLK8Zv^e0vbcD)6*;=;@QGLxVqfU3cGqN3( zIS)x0-Q$1O-^TC-vR2h%;Cd|K*TFP7H3E7$3`x?pAbxwb!8 zPK*%4kaH>I)Ye`I8OOhA)s^>vXZBV0y|zybU}BO-8akZM83jHJr{yIz16ZfH>(&E~ zMqk(w7P4YM72}oS^0=%cl6V=*$c?}&0&1BP$sv$&BECqDPkIa>V_Njo4n&?n<`Hrm z#{CCw11A)s?q8$KYi{qq*)af+Nu5hVa&cBIsK$k1K&Yyu65bhaolh*j_zGLY*DnU-G6|suk!v#Rb19$v z3A?0!uvppktZksmiUHOv$2SeBNsx7>0(&3)WXR#I;DmDA(TR?peeCXZi~;IQ?;O9c z!uY@yUs;?DXT7}2@GR&T#1Nif<>r)Ev%O)qu2sP1ig#aqA2a_O;hp>v?OQX~RFBzi#5mBlB0B}cqmnlVrc z=^C3MlsPm^qu|Ol9@kvf)`#nkkp9;O<>^}!vRu#D^qS!%S0*HzVZA~g5`mD3piaZJ zHybOP`oAFyr^F)Sy=D6XT*umtFK?GtRgQ++$`Z#n+xv}vSC+_#mC3$BlPGjf97f>e zeRa8aJJip|NGW|{r9z`mfu#l^{|t1n2rCdtYK?a!8Bv7FaWGRB;fq>OOxD>@i8}5` zSxJ&CKPpxt-gDNEa=WS7^s<*uKe5^Lm|MAebepnp!Yfj2T5Ot_15z|ohNT*Jj-hy@?- zI^EZ;|Myy8Szx69S42Rc;BSQ3f17b=~X?QMw&^sjnWd5VGMZs7jf{S>g-Gl9T9$Mq#5=&yE7bM<#MF%O!Ln$?J&`VC_D z7wBK>i}V!jeXXDRy?VP^srFP|&X=4kotHX(ciihJa5PiiMHA$o%s33|bZQ-lev7-t z&@gnk5#?I!#BiW1BX_5g2waQcH&t9hv6~|F7j?|`GS|1VXPI%B(xsSz@D{`=P3V+Q zCFWmy=bm<0is>JRRh`aD)EZ=Fx(t3QRi|u;b3^_l`-U?Yy{*w#SS*SF0 zN>Lq3r#U*w)(norw2os2i$cmXx^lyj7opLxApt3Iimo}o&6`|&p%gYT9`f?Fb-qr0 zLy&}g8spmM^OWfksN<3fNOxO_*n$z*$Hn5l#b~mDFIE>{m$Kg1P6V0AG$^pp0<+vnVSRRp9;=EZI z`}t%!7AbLID@RC2lrE~83BNk1hRVa2@sL2-f-HwUo*UeBi!9MS4%;`~AVlX1F_$Gc zwj*lPae6o;qjaOKTk05xeH+?9E}4eZPScCU+O9Jy&IWxm_id834UEHHO<(RDw2y-? zAYoXj5=R_!2X1FKaq;W{$z$uhN zs|2<1w=5|IiwL2$poEoqn=0^cIn~g`;lHrU!LJ%BZ3^dse;8GSAw{T)f>SrnwY|vE za=E3y6w$id74x{)aYY-VnLZ(E7<|snw#hy5(-~~&MRAV$SwrsOU z2#br{P=3$ic5b^|*1+Y&T#!Kt~I8foAQ&2n3bYsKe zX}}=iXL<=#Vw@c6Z&W)yt~~Ii9q%MP4y!xGO5u6HilkUNr}=J&4D})Yr7PJ zfKMf1oQqB^1Tj6TcHSxnU}$`VxTR4`hF65Euy^GZW0}EeK2jDrwK!)WFTI&!0JsQ~Dr-2D7cB6Z23MS0ARlcRhbfv=yd-ZF z4SjZD6%<6vO|4so5-a>#KG-e}8#8_6NG8P=qzfFrLXeyW(>fZVRv#?Sw^2wJ#9=(9 zPc%PIg44sLGzfp{q3`YE)J1XFhUvRPPmPSUgNnCZUbtOms9kOtZE*GpW{-BuCbW#h z=1aO2dYIfsp;k&7Ud5flVf%--)w1~q_3jGB)A-%i`>j|BwNgBGnY>|DAY88jkla6ED zQec`YrV0%-J=u15@v!Z(`tETUH?yoK;o=^y$d62+bg~Foha*ECJ`SWq#CH}$R^GS# zj7(XwT^z4<_6v3K6C@y_D>LM4YH z3?j!d8CiwfN!@aK&)Lehuzg1D9q%M8r)gB9NDZjO5x5qY{z1j%75PO7p;WutdG9H! z${N=+xMNL&v#~Ffkck=BL&AC0tyujkUzvZY4e#wA?;tL;WTeL@8DA{~<0zS~#9=!@ z<(c6z;ZW7=lu`T(pHF;E%bcIDocNtjR^B(B!n$HN#XGe8%At*-Eq!EF{qai4D?t`d zHI`BFfvr@$INn|eC`RX5y+T)VKx2fu!y1Mm7=~lUAtkRpow5+rI1TX;%ZulP%G96o zm3g0CE?YM`-cDRm!w{Y(G8dOg$w1R(R3R7>k^-j;gd{qURUp}LPJ2M@hCuz1G7^xx zP<|1Xiuz|=$9K@Or9!upn!Sx#Yq>yP-=+p8RvvOQ_>HbSXMD+C%h z1ec|7nFREsD?NG*by-0@5n8)7%94psN*NjPi+Jnc7{5R+xoex3|>B9oRrcwp3GJVmLk+r^_I$&bIXTplaKd~w-%UB>M*N7({N%U2v-u&ut=#~ zztQS>Tf^V{EQ_baTZw}W6(3N7oWca$s8?aWC-Ue)St2{$Qm7TlrM4`^d@_oA!FX@UbpWB-!Ayk-{-p>nv5HKE8s&v4~T~8z9RKeb-Q|p zx&`_Bu2q++^VMo~hFYwK)bZ*FH9L49xF2x{UI^|AJ`%hycspVc+z?!W2n6$jv%L<_ zFP`rZ0r4ZxJD%4)FM4)+9`$TTe!nfAwVrD|OFi>F)t(v9kc1E)afBz^ljceFbVQE7 zW}Zf#(>-pF!~F{~{C(m6$o-D{b@z+z-N<0L-F=69i+ip6TK7`qFRXUYa2LBn?(yys z$X=L+*oqz9$?j(EM#x?0b~{|ZxW03J;ra-f3txA==-Tai)V1Ap2l5uKbzSRP>YDGW zcFjQ6!jNmcYlJJ?mF7xC&cb9@Ggl+m=`Od+fqahNnO~S6neUjdn=c}pm#`gi&l`bYXZ z`s;v{@75pHx9fN4TlBU1wfa(hzFw`*(2MmDvJj5Yv-LDRRqv=LBL`t4{dC=}JG5W4 z@3b$pk9?C617Wyt5F#M-@O41^gCt)=L_cu(6vRF_f@qZoy!*X-5%*vhyjbq@-j2u- zMZw9zalzriL5LdBBiI2kBa(s*5i!CA?90!ABY{JR7O_9D7qKFC1s*}9h})4>@P@#O zz!F4>m>rmo7!i}zG&NO~+A7IS)#+5??iCitCzpTY3(7oh@tDP<7GGxZr50ae@x>Nj zWbtb(zR==VTYLfYMMjCmr&;_mix*qG$l`?-pK9^2#S55UW8_o4#`@?zl(WThcFf5x0r`@rkIDd*aqm| z*P3D;)|z4-)*`5d_;)c6YfUi^YfUi^Ymo+4{J)rowFrSBeh;+x0E=fazroD3c!tH( zEuLoa{ub|N@xB)C!+Z_GYmodkW-p8Pw0Nq;dsw`?#k*O&tHrxmytBnSS-hjgJ6Jr0 z`SnO(O7&fDwzGI!i?^}(MHWxCcx#KdvUp32U&#DAgasja*O?bsyt&1jSv<+&O)Y-D z#m}?&xfX9?@x~T!WbuX;KgZ%{Tl_5MtIY-$Khxr8Sp0O0pJwr(#RC@iTij=Huf;tU zcQapQx-4#5+_1QAan0hY#hn&+SX>d@_>1{U<4=qKVe#KB{+q>rwfHX<|JmaIwfIjK zKWgzGE&hYWzqj~z7C&O~Z!P|f#lL2Lt?`w`4_o|8i+^G9Ll*zs;-6Xkpv6D6_$L>;{;b9K zSo~>=KV|VJE&jO0AG7!)7JrC&+<4I94_N$ui*L91eHOph;`an5D<;kW{Bwyh+v2mB zFE(acyvpL07O${)xy5H#e7eOW7B6GI$S7rgBTi?uJ=};0LxL~2c*5dwi^nV;wfHiN zFJ->TTw?LX7GGrXYb?Id;#XUIfyL)re4fRxviOx2pKI|em~TW*aBAm9a}M*k%Nkyn zHM}lscwN@;x~$=KS;OnP$0~QX#kX1fE{or3@jEPjyWocPykR|WSkD{Q^M>`jA)nuB zmAj33%(&I!w^;mUi{E7NEf(Kw@f$6^$>JL=zQN+_Exyj;Yb}0*#n)K;dgf8%I*YHi z_$rI9w76IYQA4bQs3F!t)DY_+YKV0ZHN-lI8e$zp4Y3ZQhFAwtL#%_SA=be%L#%^k zhFAy746zQD8DbqQHN-l=37^}s)DY`nsUgFzY}-wqMzhIxPWZt$ji-uGPYY3$zbUf|AjdtC3~ra8wo z+I114q5aF;Y*w26k$C(=W3e#?kpN!A9c}{dXfJ3Ht-HD(H|$ci8=|akcg}LAISt1P zj+Krfj>gKTsP^yv>6riuo;24KZl4r5(*QhDu2U(0-L!DZkm3?b`4%ou8AX<%a`lOL z^-WHxJrV%0 zQ=O!#gb}xL&NSEq3sGJ~?9VGMr=Z*^d8LR%uI84Oq)d?&cTNDxE}NT%Fv#$LEH3F+ zzqw}HBg&UA<;har69BTqG|T38MvuW;4+hi}5eJt-07C*)-E)cy)h=C%uD?T;9F_o# z9rk8k2^iXnB3R0*$}1=)Dy*2HV&J%_%jGoWC+NNN^XDd=KVM4hkN~!whK})44Av^9 znU*VMaAaCooByk_>TSEzT@pa8lP#&KHAi_c{+A$10vbX+kCednjo8sftHa8Rw{Da* zbxZ)NPBqcgk}?_CIexzO#2RNFR-QAyk!89hEQ~q<6WAJ9Szc9G2xn8uK?fhg)#~UH z7@3OHRZ8VcwqMVL1kmXOEiOb=Pzj1y5@c0|KP?T;YISgk42*-ql~aquB?Sn7PAD-U zD+x%xq`@I*eBr%63ollI(eGvDrGLLHTh%oI06U2%A7yIQzzE!_D6`Rk5JGko*sanY zTA-|*Vdpd$lK_I91}===pfO`3NCHFZQn=s$jV3|WJq@6fQUC-h)x#NArDe+obxQ#1 zPUaVCkci=52m>6JMGjnZp}e+Rqy=XS#Vq;C;;8mB47<7RfR>YqUW#$|Flhy zt(g<~R*LSF04ScY;xu(4T^b-6@D7I&0AB0%#NCxYYldy6?3w@sUXCohzsos#LN>Zl z4P|bq)GlVU$yZ)@<8@itm;|8kWDh2FKF!GJGNiaDgxdX|4y=C2qwMIGJIG0*`Nivk2T6uT31y3Barwk@eDulY3_wp_abX!Hh#b%P)(W5} zU!^Zb_1mpP)vINh#K zPA?GyJYk0uj^Rj*Iu$8dl$8OPf)UImX<(>2tj_6D{=DsG+cpj;IT_HYBr^G8->did z+SFMa?Jcc)9LRC{d=q>!3qS_g@TX6wqXLYwbqi{*tW-9Y2W1m`#eo&?ZdF9K7|s#F z22NNS(+R0lx0$22l{MchOXtM_5~mJcf@b0%0{0KRy$sAM$Gf{SkXC{;z1RgP=@|J^ z$=;@rgBhXkkS+*2weuH!^0T%%x?db{@jg~>(%=A(#5{nA0p5(Uq79d34#Fui558MC z6O?NgA%EYE3E8fRabU%1N1cXtW#emuFD(|{SdQs365m;rPREA}TQT9dU{_7aC71?m zh{z4Z-xMIE@gauwuxw6f3S3^DTb>)!#)h6wi~~wO8Wjvd1(x}WV46U`aO`aw1|CGt zS%bs_r>;=#{#)E!&{fEL0wgt z;p*lDJjXVTIaG_@i_EnL=#qG)IOlG_5iWNwT{AM^kwab*2Y@|n4F;sOf_0J(&M>n=Fub1)%I_8j#6APvh^4aGL*f9^o>>me&o(|k32B0vGqQmgq zlfcNGrTc~lD`ZQu;sRCA{Yn$Aek0-cT7D`q6oxFi%Xax4950gN!{H?MYz3eVnbL8f zDj>h`Q;d(=M46geBpWp_UMP;y)UPyaj3KTJQcoqx@ymjA!;q5b{@+tsq68le&IqbL*r>R|>N1cy4uX6TxdL3^%ZgoT)-IN2UwAP=| z31FfLMOKRClULcEp{C`^dR*bAU{lMVW@W;Y*A-m(Ypwz*wXQD4<13Z-+S+HWyaaI5 zbc-js11NP+asK}xRUh}Oa_=o^a@4vdfT5;uw!Hrl9G5OvLn;YxwNB+cKghxoawX?G zJg?iX0G$)##3`K$W*}7$A26U9s4S{o$_V5t&))l@tgcN0KxR70P^qkn{Lu7p?WZ-@ zR%M~lRzBS|0gSR}9Bwq_wCxsHFl;0iuU$}myi4_i_EPAS00^1R;8e>1;N|E8!yvEP zWsFfp%4?U~4hg*zfE3f$j|%~!hcl|kSPiTdeWFTADry(kc5hYI8>O0q zM-t4Lzxw3z#KC83jihnA{Rk^m>TDRb~*y#AGXRqz2Y2G$7w}dTLCa~oAR#) z_NldZ0^nd815$QT#50_H3XWS|Ue}*oIcMSm*_+G+V8hfKY7bOD(pFKjwv$uK~I3uz(<=t zv&XhV`#MkA{NG$z`GCYA@t#rTv}|i`+)3Hl$0=|3!f-3fGh6J-Z)yU_WP0&vVPxWL zRf1(fFwf&Ist*n;o4!0E8__obpfbHcRF)cn2yZw*C0S8)j?)S)BUOoNwJHaI`7CP) z2Oz7_af;Xt*Um*w>}3ck)oVvitJ$WE;{FfJA3m0%%hB6{Dqv ztCAHIGeURx+A<99R^{27J4hMb62ME#PfSjTl-u-y8D53$ypsB1kFfdvR)^#HhBXBN zpQd+$27uzyk+$!+-PWEdQZ}4ptI!4{fS#tefnqpNt8wowLC&*L$dszAIhnf9_1ktw z%RxtF3;HAgtESHt2^xtYk;UPYm)HK?K-m<(S(YD>0NR?gN0YcAs9x$iPudDfeOPlQ z&@aUoJL^AEX8#1>*>t|3HsxTcLg!yxaEfMq)Iixh?rbSyWCD0?C_wo1KbB?$YD+#0 zpQ3wp8>VhLGIPciQfO8J&~7p4P*QLnVI-ks(Wj8A-m!buJANsrR|3FqdX1@n@D(^k zVQucq%Bs}QW$EDw;KAudrV&ps!B$SULFg#|!GN1toqkPWx?=evZW&uz>&+f!5OwKW$!;tAHGGVIqMdDXi^ks;t{(pRckK0-4UOV~t8n zz^E&rW2!#6SYuqa@@l62PNXG(L?_b}^%6H}d=n!u6rEg#{@Gz=_k`PI4@V||N~iTk zJsgg+0sO*o*)K0Rxs>`HTz^ox?iD-FTi*m=>U4O@z~Kqnvgrib5&*Q*W|EA?ICAVDnz2&oLH|jEj14W6{bMhdk~0$*%GC}FMlmcAkj|k7Do!p| z{YJlP;Q=WoBhf-MkZjPSA`uwOpyQB#f!Xf_#%Sj^T_!!VM@q>`Tp$i?6oNxoiOEHP zT-=}pEI+Xrt*WVV?cNDePG+LH80BoV#yWe!Gl}fPRyz;`5*ol`ZQ~QVlm+b*G~NF@ zDR(Ntjlpze%3B`j1PuO6e>2}xz7n6`yWLyiZQ*&#GabJEyWDYip1Yar6XZ@Sb@euX zG@k*C^#bGzEJJpNyY=aMOJpXySG!bmtIw!aYD;7QSm5mL_`$K!5mtUcCI3f%1}ukR zjNWESjyMoEd3Jk`01So5Ruo(#7w#@F>f;TCq8mMV7-- zHiHF`ajJ@3!`QP7UR!$}3e(XWt}|t@E+n;vQy3-%X|kbaCx7rzdGhfq9031xehMb& zvP!Mdc4g7U_R8tH940i{CdtKvVhE5MJv8wM7|mu=hSYgG%VUk?9Oo^E z84boIbQ$+lWR1*#FIiidSo0~$6=Jp(gpS`D9J+*M0H>5lh1NGui4RySrKT;1t&P4U zG?4JAL6o%Pj$vIrn{(vBA!pk?8nhgCHQE+g1`fn%7K{tn_ctAHI_i#&qe-wuiXB1d z(&aF?kp_WxSoozvNmo{e`OHen$;Z{OvMgK;sYCZXXw7E**~Ng=9sDm^C^xmTb!BPG zVWE@Vg}M!4-Tp=!om0BxylfxFhc4H}34ta8u6hIE8_k}skav7(^=9BcMY;aJKgbyv zx*SG5npfKYVbBwi_~1608<`0WV-;2#q~byf?Qd1MAdGDCb>*qqsndqpI+*n3F#6GX zn@3L{u0e`DBGUvB=J zwoQ82a+nP1a!SL7WWacTD4z$tU}NB5_;&O6F?sD9FGEm21H5_DY87Qc05}6hEqO2FaaYZb%b>C!(mCp zO}7*qPSW5Ia->s7YA?^a!>nq3^Ovocl6od!lq5;C6{HD2U2Hx$YggeuSPDs*0FM9) zlavXE-!k=*?In+VAqx*nz(h&whW30UXtzQ*W+Jt01$0p4W(omgLxp9e$bbtfUX}WL zqk8kcnZNdy5=#=7BYcAnkzFA&8!aJ+IYcWe3!yo3b*Y@Ma3je@h%S2za& ztmvv?-3=(n0Nm9=w2L3FhQZ{1NR~^oaKQs{6yO@ufm~@1V^n!%k@i?)WljGKSzBfT zHqac@))akX(HseEIP?MJnSV_C5gi2JB}CLx`{ou8vClJU2^c~LT4M61Q}o~p=xCr* zIF1ao4|`T|MX~d*7NO8zvMCoQVC&5P=fixWQ9V3v;%ByT^MXM}jupRrPcLGL5I#8yfy;#tA zIns*At#YGN{K93T7<;5$UhRCa@PPfw^-9bT3K5FMglkS74%{f3jV}#cc`J%$6_?@W zg%dKOU0_aP zc=U>M+$LJ&&@@n7Dy)nGL=xWU#Cpxdjxz-(lNEi-ud!h>9TKqD(N~ogZ0(hXGWNn! z+msfD?aqxzz*0wg4Fb+&R--?Zfk4@CvfCHqS!(M_w3iku8@rasX&Rq^DUVL#3?;%j zm#p$I3&R`$CGFpkUHj7E`mKTE!kcY)O(+4w9_iL3ObIrbYHTrxKEp%A3byLMQAh3e zn+>)qpC7i3&^ZZM{Rl!uvGD<#L29zzo_ z0n&t$JX!+K;UNq?hrC1HgHwt#TyvG@R(&SL^-91JcqYVUK^%oPJf=AN!inIHUX0}BxStRz;~$B49Z7av_@%8^9i9k_wVDs{Y*@lEqu`Vh>*5ew?NDCo z|E_HDq(p%jjZ%n2^DIT7(92QotbcAmbOp*C`bV}hb7Uf4Y_3!T($p7Et^OZ`YAS%x2JM!A|&=qYPJA5BQ7qM$3Gts z?avHl%U|{zd~ss3xJ|QU#EwE7O9W;qgd*pE5N@nkp#0lsLncQhCW+magk!H}h{*pS zRv*w-zOcWO|5}RFyuSGH01cpEZ{Ljb3eBr3_M;jYvHZF0g*tAJ@W^p-^ z)c{X~OillTXzl1+<)$}$ve}ap6NEmIhnfr!(0Bqq3J`CkjP|tup$hZi#>(%vJ}Rs5 z=tmsOweE^m1Rwv4wLDjbtGBDGtG%lgvYt0`o#FDjH1iMSJpa}_1b^{&%{P(p{8{r! z^I`Koc#Pjy@eH$%*&W%=lg;L46Sx-oO~d#L zSpvQ@zBE43hH6<_U#+`-zJ88=8oaul+HcyA+Sl4=+K0$%{<`*(wny8kJ%p_0TeZ!I zN3c?hBB%LWZKf6pwhy*~-*%(m89{GQ3;YrIDex`)$v@WL)8Eox)t}R!(jS3G`JMXB z`Ud?vWF}mU4C~c;xjs!V&@V-P^jSF;@xY?MRq*?s5x6XnAD9pr9mov~MEru(K&L>PK#Rb6fwKcaL@;mwGx3A} zEB`_NfBgSO41*W_Px~MDKj^>Pf1CeCL@~J5zs!HN{|cZg%KU|hV=&%7(m%wX>F?w3 z=1)N+gJ%B5{xkhPzwZ0f_g};^_`>(G?>*mJzE^$EK@;inruhndm-@!|hQa?m&DYb{+1J*0q3?X(Iq-mY`<&k2ygz!s_I~F55I*p)dtdVI z@$U3KDq zX2Lr6DtF9%jr&UXEcbLoO_<`o#68NL;~wDd=k9^H2^YC9aG&cw%N=l=ZUvDOzIPpV zed_wawa@i0Mh8fdHw&9qU`^P z!iMT_8tPSoT`AaH!LA^tc@7HpsbHT7_AxO-T`SlPf~^tkdcm#}Y_(vk1Y0TCwSuh> zY`I_w!Qz6&1d9r`Ot7VbEfH+7V2cF1MzDo~T`kxG!R8A#kD2Fu!Oj!xT)~yDc zf;ANE9Kp^O>@2|=2zI7mX9#w>V5bQd6f7W^Uoamt_t%1bCD>uXz7*^W!43)bxnQ3O z#?xWAKgHts>i>xa^8bc9{x9~vJ3fkX3ww5Fc6YWUi(Ro01?do)G-)9O2oMqyNXnpJ4q<_GwAR8 z>*J5}kYwIE@4WNQInOzVM()x7!4sg*X3$;|*e&p)zzYJq1fCbzDe#=YvjRH=o^k08 zhiewg8kRFz&R{v6Wi`txmX$0cET^%oU|CMp8Gbwx1P%d>!S`Q*KLq|G@Vmfo0*3^C z75GKqXMvvteiZmY;Cq4Z1ilqGDDaKIzXf=m89rWThL6{o;p25?_;{TeK3->rkJp*u z<8|iI-=*Rn{T+d~1@;QOCGe)e8v?Hjye6t=YjOM{@Uy^A0zV4K&2h-hamdYaER(-26-Wrg1!4kG zf$Ig92rL%3PT*RBYXlYvEEKp};3|PD1^5-|aquhB-;Jeq(_8v|49!>Th?Nj;NCjuV}>=XD%;6s5A1l|{TPv9Q{ z?+Uyl@V3BSfwu(S6nI16b%ECe_6WQx@QT381a5=p({1p4x(%LBx54x2Hh4bW2G6J4 z;Q4eLJfCiZ=hLm<#FaT^m`)j{Q-6BqQWtdJG zrc;LLlwmq$m`)j{Q-mhiuvTD=z-ocp$o}73yH5)~fXHa) zAoAID$zzjGNP0SHUQ(C9m-y32?>OtpT=WWigv%Ayhc-OJX zQQ_$02x=dr>4yAEje_tClLIm^l7>7~HWg%!NVRr5>+jRcCqfHFK{&%dD+NcJC^)__ zj!20TsInvVu68_ksK-+?)YWaH;Piq#$yX!EUJ;m{^)A=WpSnCX3g)irj^zoI z2TE(*?l`_n@4MD^Ht!JyUl-PH@0p~RD+Na$4DjNq;E^DNDw)p^NL0IhcyR=FsE`rb zt3_Yyt6FOv&0ysimj&qu5deR&(8+>4R5I z)w`(zZK7c2+7nd(#a>ChaX6}V23@|m#JJ=~E&8-=PZ=BqBbV%L z-DuImPmf#=aX(1$i>U6EFz%OA{pr;c;XPIuN<~9OAsF9>Raec@Tl_d_r%gn-Fba+? znZhnW|LQu09ldu(<5k*Kqius|P87skGKf-XG4&2Ym}0~m#js%JC0#$b4g8x{#~84Y zu}NFp*)|}ziGr(3wnv)jv`JWJh4t^tuAQ^{tyI&S83hZMZYQ~XGNW2l)AZkZ#g00y z`YlD(RkjPk=qTv8w5Z4#j}pbEWS6wS5~`|3aA`b)N1u_SSNuupWs~hS*DDH2E?MDt zmf*xqO8Lp~c0NXxM)o0X$(lSh#=%iAafyFD29rDpWJuD}uGRZTYCu^^D-4y^TRwRO zFp^Wq=5ml+^ahXtGCJ zIMsf>`bR;vC2J~~(lW{_OF#oX*1XoKN z(tdh7MZtwtg^>P}!u=nmkn`6b1zlpQw>_fZx)RlxS`zMCA-Ld35D+;^S^YiVya%sR zWxGZ}bEO+iWv#3^;mL@Df0QX|@m^6-Qw6(4!EL2Sm~Ur!ab?PmC6bo)C?)e3mNjam zN?s5Jd6hT~RFVR?4+|3~@MtYA+cy0pJ4{PP6ztVBt6Vk`l_MiVs5m8~6vnY??CKU* z=V-{JveSD5>@1G$HcQ=FI$Mwk@hx^xWFw z^m1euq6iv2Dzg^FV+%(vFHn6S6-|+h8pN!n;&6{c_d#5!>)OSC2ocf!nAPgvB2fB? z<5j(B(I)cJqETVH5g*0=AXvK9zi9CfIl}egcIU13+w5trbO)-y)b%~EDI{k?vYIHK4xj>73sO_9#BmWj-DwS z4V7*=21edUxD}sT5QwG_S?j|yj@=RG!Td` z9{x)c)sw-|(`x617C0He`4FE5AA<_`kNmGeo!PkXNBh;>H+rg^H>p!;I6lI*i_aQR zKL1B&@XQUKpgNNkJw@oV!X-u83CRS59jF)#r#!q5BH;JdBaR zLIuOaCD@19ySt>Ek|61J;DaI26QyO^!>Dd#TEn9|5j0p7Jc7vB7Vo;cUi{7zyJUQK zvKmHu^aPofR8+>Pl2cla4pV{)WU|4DuB3R@QJLI&=gi{tp{kZa(MGZ(5rH+c5ai)1 zBoaIZ>AF7c(-@DOKX2O9%|X#%ZB1~>hV>p_qT!$i9q!fco7~IX*Tdquz&*!39lrik+=Z}t=DTy6AVcnklY8k2|6XWO>U0t1dWqVPELk(-N3EMhKh2|N(k z6u1NV3T{IDh3k>AU_oF`U^;RZOo7FJJR;ub28IO&BIbS1K$k#!M7=*Ra8}?{Sp9tg z!~X{&-+$--3U>c}{(t!2^uL1W_s_uc{|MsW-{oKDzZLlz68^>htC68$mcPnh2J8Ps z|Hb~%$kH&xKLGas?*2~xw*Kb+6n|qd0FwQt-|73^_ml4+H~^pdKJ>lgd)@bvZzos) zTYV4t?)7c-t@W(}4!t|6mOw-yf@#Q>m3H`em`$dZx?TSZ%glaung1}~ zG+!}yna`Np%ty@o&AZ^aa;v%0Oqh$!tIhd{VOeFCnMLMA^I~(fnPUzy2bg`#?q(;m zt=Sy>m&WGFX0mCTPQ6 z^<3$>3?b$t2m?O}q1wkGoceHtJnxUN`Hc-V9ERrFPnqLm&Rwt zhv3P)ZoFjdG`2(6_7Ipd8;!NbD&qztW?T!d%w@(*BVv>olZ*-A_KY-!8-tDhMlYi) z*a)qSX2vBfmhz;HK21^552{X1vCrF)&;B$A%1Szg8RN|sl!T)+|$j&RL0#++>0)WH)LA-NI#_BX&Hu9egXMo% z{?76@mWNpW%JLVMKePOa<&P|XVEH}E?^u4z@*vA^SpJ*k*DSwcd4T1YEdRyw3zq+6 z`8mt|EI(uUDa%h-e#~+o%a2%o$npc0@3VZ5nvYm zxrgPeEMH;yGRv1(?q>NS%NJPgV);DFoh+YY`7FyFET3WdG|TNQpJMqW%O_ZFWBEAC ztt=m7xrODUEFWR{Fw2KnKFIO`mYZ4L&+mJ3;4&GIUiSF*f<RRF!Eyl0be8>Drm^hDvMp3U+smS?hT%<>GDr?Whb<*6)BVRt(fmOr!niRF(he_;7N%kNlz%km)0Z&?1D<<~5~VtIh&mn{Fq@(Y&#WcfME z{VYFY`6X z8d&LX2G$0q1^Nbb|0n*({89fTe}DfuzJ2%tT!8Pq?!FVepM#OT3SVhy-Xw6V?=Yw0 zTPoS}sb`C4F+2iVxW95Qb&qrhT(7!ra)n(d;@hRzxB!_0@6${4j?V9$>z%2N9~?^@ zBOIrqJAd_GuNc%nWI3bYrck#Oz*RIA33sc;}w&(?orJa#-Q3EYugMoJFIvTIUAC@DI9VUEdVCc4M^Ay=Tby- zhp+FfRPuX7Z0(vzSvYkF=OL980Z{ahgdZ;a8EZ;mY%kJ(h-eEgw$1U~V~C_cR#;N< zj}9SYHNr&gxQpUhgpTat+(hM5w#BP5hS&)q6s558Bg2%rIF!;3id^a^lxzLVOOdJ< zDXbCSfLw#e!T~uFYK2<+hbWhMc`8g}u%hP{m#4y)5K)%l2Zp5Mhu@9Q4{4Ww9ar-* zG-kz5pg_0-S+AK@4qvx2>TVs)W@>#^SL!e;Vt{kkj~6YoDHs>Vd}6hun=AQwBPp4s zNZ?)om+2!Wz;N!>uDWlB>Pz<+q9>5ekNiQ&%##z^aS!ZE*N_i3-64v~j5U^9jdbvo zD&fmaRkU9WK@-TFl}3vaS&XH6W^aye>MwolAudw?Ms)}wg1WS;GDX#uI z?kOn_rCiXnbH^h(?%c9w?4@?Rkjxk~E@W#Qi^lViw3l4iY5IzBGbUnA55EVgL&_1C zltNyVBXaYA;X|j|URoVv2!}v*(E=j-RtDTEk8FS6n(>#dP(6>t3_qLXE+?iy9&sfQ z6AGCss!=c<@jlz9rne_S3SxK~PA@J!Y*D0=+8QxEvar}fsX5_7lpj`&$xnq<96Dtr za-Sa3+b$`-#b&8=j3F|D>gcF4IMo*;j=>R6@TOHY?$xTJIWYu6$j0ErBc6=^;6xzS zdCN>78x2}v$>$-lD%LM5lb|;J;aEzK9SnY<;*h@W;Oyyk5TQ;n#6h6lNFKOimJpnnb9kX7zebCQ75vo^M*?)5y7W>3D@^_EU7Ds-HYMfnC zURYg9H?kD=8r)ns)FF8}dKfBcr6CX0jXh?bxmoq8TNHr{GSDX~ibUPy{fkbKA)Bjd ziO9gCi>H@!$!41;_c>jaY#Bum0%8korN3F;JwKLQfdsKf!w&8bJPPk;pLn!6!wPDC}XQ&36MG*&p zmN%8c;@GjZtN_LcTvnbwVu-!{b&taPe~@(`YusK0O)HKMO>p0SPuh`)g9g9*gYv3lQ9D{oH_4BcH2aec2Ri#6Y+&Q28L6J z^4%AN5J-{l8eRWx(Pf=}Q3L51g|9y`D{6<21(H?*&H*-A1PhQUi*B2q>r!PpMd9ra zLLZkwj1#=<2VoIWa0s}WVpKa;(|DX8b-DDcX{u1uC>;H1U!sO`@fr;yLO*q9Q_-wm z7pkkyiNd!ZG5t70LPp7~khWg;K3z~bS6$FN3P*j=9QXocIG6>~Rz?Z}1>wR$sZ)oH zQ5Uw1!s{MO02fl6HiX>3;-xI)sM2MoYwMymeW_V=3g1k=bjSS4l+oc?u-vV8`MPMg zkAFnfczzT<@z^V*#vQj4fiZ$HtT*m?T3fMal)A1-6wdB422jqz)u_oBt${(7tgg5q z3WxSItEOy9;j?1{dPgZS=tMCH(OD44ipKtJs&;uV+oaqyI!SdDHy1H;LXjPJR^ze} zn@f8=rE0%03ZHXO-ngH5UDNiArwU}9>XIT%7ypzE18xa?`q4M%LhXvZHLCQvQMi|b z@q*H5W5=4wi0F(K;=!tkb{36uqv9aWE##Eb=>+whl&)RvwIk6rkHX(u-6({Z0Wkq~ z$O62J);p{B=d8U;HP|8ww{5vmcuDdWOvf_ZFEl&3M@2XLscs&fP+MhA`@HsP6`@F& z;(xE#J2oqte5I=LoG4tX)hgnwSL+?KW~OekgFp6&!Z{lItuSQ4#Iv%12tko@iLa}} zuGOzx6){?>%2T6oex_wWeB5lf(~QkRTB`!}kobr7 z3g~@SO*y|x6-bR$wn^sU&uY|KOlJ%IbO0s8mcj*hOa9A_nP@xp#Fhc4i(Ja-F>~c8(6`w=>Vva0FtjqOd3& z!@XXAobxu1czBX(qHQ!w-Er(7#U)b_TD0Ef`m}A+Tp@LN*XS_*dPF0XAq+3;c6mhz z_l~c;@|pF@8CgxV#f$BBE{G15C444kHLn0~Aj&P4l2(Dw8j5)zwt3=u53RVrLp4a> z|J^mj|JxR<3ARlBCi$`C^5m9D-z7boRF%{u@O|Kw!1};tfuVuMuqp5Iul3LIkMXyJ zMfh#s?fCZ3girVV-Vx>@_)ZV;{NZ^RiLQO_``r1iA6#o){b8rP#mF|A=}+mSoZmW^ zJKH&4ca%HaXt2Tm#>PP8r>&+MQ-gq(95-rIg?8VNVq#$D;CqI`r13XBHleaA5JW&S zM7}CSj6ygwiiKs-s>5O93xx8%(f;tB6a(!aFLADWOsE75?a5#U;ZViQv&ur8*N?NI z_fxf7*WRqAdqNBj12~bOArPSH{t^KRJfsN7ZpagJT!YcCI#~IQ{ehYv8z{RU%~KZ6 zc`1Vt9sl@hcAd9E+wj)ys`ueo2A_|3nk;r;E(Nb7Qr$3)pMHGp=>OfPT`}-0)y~)$ zd>8CnjhJAhy}?`MxMs)QzL~b`r?*wzp%~m8@NvR-U{nQhk?>iE$T^g%g`&eAS0nm$ z8!A7wdA*ZkaE|D$mQxX`rU{aCHwYX}_Zu-@j;kTp0|{+wGdq;m#27p)=-o~0DG!1C zW#P&Vp`-}M*NToW;!*Zdqh+k01T3PkT?4{l?Oq+B!E%d00<6@3e?(ibjLbpTxIrpN%|gTJx%l z3n=dfB3V|G-$Y7F&Y&U3Zu%|0Y5&YTds60VpFd)2FGj}T=|P`TbnEh}!Z=K^pGix4 z5{A>t{FBud=WE~R*!qq97@R)vvB1^lLW_myi_&WZ8m9An2Da3qKUcMDl&0NNy;aT1 z#WA>jkm_VAdOWZM`N1ah&S`}<`ZIIDkqCz(23rXtBI>^vX_uGS2b0Vg+(JnCM-xJ+ z0n?!{!s7o^lk4iYS-WeaQ+0J<41OWBB&aUrSt;ho!GETQ#v^OAmFsOksmvHWLsX|Y zPp!4n{;9gYTBWU?ZR^d3#NaAIoO|k&iX=I-3~`YDRAnRfXp86Diiim@_=&V|I=pjb zAIU;UOnhO&_e#5mLg670S0Q}o@J`1=TNa+xHs$cW1+kDp#Dzyh^OSLToNKVdyPw}# zF?N}n#F4R%^xQhUqtHZFs1#uAN`H1DZmlKAW>%uZ=p@>U*C_yTkS#x;WN> zmXX6-ifWHsMw_@wYl+mWvF?tD+U*_IsA!sP+PeG9SSsByhnH00b??~S&i-{a)H<_K zudXXk&q=kF`9osu>5fTV_3qf8t8C}8k=Yli>FgSVS4uln#>aYOWln*c9v(^T{&2>+ z%UP#K`d6O~tj)G@P7JOnCt=;tH+J68H0@50Gh^Yo|%Q@i)DAF^jE@$sIrOW?NMViG@)YvF|Ur1eL+|ol^HOKyBY#xIL25nQ+m2@NwK>CiXYMys} z*6^wprmF9}7~Cw>wC`A2K*l#37+iezyrC{?6@y2GQnMar+{3j!7EF2dHFa%n3=R}H zU-71vMhOpT?L~M2W>jMh!lYQ=9GFVXb?C}>+==A7Pzob4SXe*UO1r#Iv8uFR41N{( z+OYKFq@zbHVUz(^A6BFa=ouqN)T`gKZPu3Ns*3J0_){noUIuJ%$aI4xnN~;|w!^!m zS01Wryg?Q19D^SP4%gf|y9dBZaI^+bZ#HS=a#d)g-HG1vU7(H z(33!`3Nn6Wt0NnCrxuR0oj3-?;5tEbpNTs;3b#?hRkPA;BPD|3ILz?aVQWhLnbk+^ zFF)-`)uGNYcuuHc^sk0m7YcY#^A8`qb8~9`Y>z6{H3n}9+84+)F$~S)B?297H7too z6g;?O;%Tt3N^|4P^__nAzi2olp z-q8?mZBcN3a3)yxMc@JC2Xlgh!LaWh>;Qg!O7L{B>&>7BZv8<-%iD)I0eir!-=4e$ zton_~tHG&{B`*S_er9q-auHa|9b7HJSw0MN3pz^Ttq z$^oOkUs8AQ>02hHfKA^h$pn}F7evkbBCs#;4tVrtKm!Z@p#KYS;NS7@f!<=fe+&5U z8xi?#r9b9h1n&Dxe+8KD6a4w$y$|;H1M9s5^cpGt)BTOWc-Ii~?x61rFdW|T?eXmb z*L@4}A8z!m_N@fZeUWcISnd_RB5)t_5$$fUuOB!N9egc)DPXrZ@|oba|KdFeX8S(x zJK(kNLhghu(35Ngr+p=2CoDn^#hKu<7kMXu&7Ol;3jGkNt^=6tDc;k;V>c0}?iceQ zvMla1-!b=q!M@$x0{;3&b2ZrOF>?{P>od&?FxMv_LS2qI*z5<^dIz&5IP0gIjlfvf zJimai{)J~B*y?*cyTDc7f_RM^J*zz{!Bb!4nGcqFg{KG{^?Xl`XRxQAr#txREj=k< zr#JGL;HLlLJ_u&|KKDED1=)qjcU#=|yEnoQWTiU>FOd1}neYKAa!-H`-2X3;aKw0gvuf3Wa-3%|4QTMG|b_zmM@=4%%2vG7$3 zUt!#0zHH%37Vft2MGIfBaF>P8Te#CgnYS&b%-a@I=5329^R~s5dD~*jylpXM-nN)B zZ;zTXZ;zTXZ;zTXZ;zTXZ;zTXZ;zT=xV=ZsM=gBB!iO0jF*jHU(2}obe$uW?|IA z>n&Vj;bIG~v+!CAud#5Eg$pgb+QO?WywbueEL_0&pn184^DUfb;bj)iwQ!Dwvn`xu zVU2||Eu3NDbPKB)A26#dth6v<;WP^?EG)OM%)(L&ODvpf;S>vtEiAHdvW1f@3^Q&v z3oR_LaH54F3ny53sfFV$yu`wbExd^Fesi3KV=c_LaEyhcEgWUxNDK2U%(ZZYg*g^x zTR7apEXMoHVHOUxaEOJO77n&>kc9&+%&>5Ph3OXdw=j+IUbCNteJ$)`VQ&k2S$Ls^ zJuU2EVRs9=S=iOW3oPtnVQ0pB%uW_|WZYzSV7%K*wXi+oU1mGRI}tOAp65HwHWs$F zu$6@^Eo@<7a|_S6u$hHTEj-V{b1h7$$M)NES&$O_yg=biJx`n4%c&de` zSa`C9Cs}x+g(om>FdJDIv@qGiBntx;`YrTX=(W(a&|{(7LYIYxg}Q}K3mq0}f}a0c z_=ko6vG8}sJ3PNxc*w$E8Mm7MvhWKF|7qdp7Vfw3GYdbp@DmF^ws4xZK?@(Sa5Li?e8W(=HJe)r4n8{HSVPlY%C z0OKxWj*+A9*Q@nT&i^>KIV+w0oDRpUjvF19I2vo8YU|Mi|LYV3k&@Il6c&Q)Zv}|y z1>@j@hU7v-X0=L~-t?>kQ-822Di_AUp(HzC3n*Wqft(5r9L(lqN&-i!5QVcSgdWnx zAyQjmjbWr~SDyNeQgL*NfmTU|iSt>1Oko!a#oGR$kx^I(e!%E(A=u4gWOr=Zh-)D7$KVNF4~Ua#NI^Y&)E+(otABL?Or^_#fjmid=$ZDMmnWp&#J zZL9dilU3QyF;Fo{xkD4hz5tSP_=uTWT2$4fhbomC0~Hg~>pd4^9oRaZL(PFC@c@OT z6T7o(M;C3|swY&5UNNvTDUcs!qv511+5`25gdx`LrF+ai?bWXTQpG#Oz|5ouX^2*w z9kNe8P`8Z!^tM^!Z3fuD7+9H5rJ+U8Ma%g%W`OL<=EwR451(GW;*pBDt>o_$16`Ba z?u)KlX@FrE)*cuVM$XeTP9j#n^G3gP?b@F*Rp&d!z}>_gqw~nbgEE7|-~wPZ*6Y2i z*CX29H(a0!^^1YKNdz{UFyvY)OBq-KBiH|&G-K~3?be&-sVYiirObu*UVa9qAQ#IK zJPr6#Knq{L?}y(A&Lm7W;7ZI)y)}Q>UD6*;t?BumYOg3(;@3_CI+f0 zo-i+^yP~|yu(TIy59GkiSCRr&z2l?Jy+XDI`tnm_#ePa2C!@%qWJe{GAqKY`dR%ZH zgolz2as^Bev_YhS+ztIZC<9=z|D9vj=k19s@2!5bwm(NxxxV<_*J{8-s!R;gdu z9h#}VI?UF{_l;R3-M$!fZZ*=@g8?uQq)TlxM>-l%+#(Gj08{I=A80)B-z`=9nK7_; zX=`8~8&Fgbi!xH9Z5BVRtZLAhYuG*nbInoeGPh0CZK`NS4E$cu5qNV$=IStIZ^B)G zv4~Qb9lJ}$Z;iDzMfT$C76bj4c3XOn;9CtZi^tGD#eE@OBqrYY43cuVEoXh)gY(D#`@W= zdU%_BoSA|5*I#N(KWkw)(@uPKX)K?&CI>f`Qv&~`j@>)_#TG)V%I^JG4W}qJ#?Q1F zZXpAHTd?=S{QZ9?jsikoL-46Mw`W7Ys(n0M7us> zpLs*Ek$&3ZWw4o`qGnG;miXeo)`)&?lft1%YC^-YJU?4Qc|ch(A>%w92~7!4FaK-J zxH>n{Htx00!Qoi0pRK-pF8f;(ed`d3kQT%i&J7bb(Tb030xWAohzx_k=%F2Uu(c6_QhtAcOyknF2 zCdIPqj03NtDx84R!8EMKcK_GL;cKkj@#Sx79GAqvrUy$x*s*kK#$kZo=!KZD%ryK*oV*nhde#5+FecZv<(lZsOm$pA&M-H@Xtge&cs%O zO%A&qz1WVg4a$tTp@V9JzW;k`J2d28yEb@nuqiwM?oOVR+&Ssxq(suCNu84%ffrz_ zodm0_=6}h53nIq#@i+2);JXJl@BzM4z3+MN@lNx0L&UXf%=0{td9vJ}x@Wsjajl0X z_FiMK{tx{gSWn03t(?C(Uv#cA(7~cO1k`tX40lXC*iJ zN3%i*G6^0pT+kyR{*Q?e;gk~u!yi84o^wEZ^V^AP3OdKZ%%sC~8=L{MMXiA2pY|y7 z3Df1O9(`bX>5r>asUdN2FhP&iuHkbB5itxQ{Dx>hdHwv^a!_?B^tc1cCk zkr9AsUH$RZgG-Ia_G`CP+x)LqagZt%@d=b21hcQH43|twfr4O(sUx28UYmN|G7fg6 zBG5tmVe!fbmsioH{rZ&5wz){n<6u0}n~HjX8sTlCx*A@nJ=A-M8fB+AxQpUmiS(uxXT=fhzxHuXg3|w^X6#agY>A4?^58@O+9eB?WNLqANEptm$yGy0Cp5 z1VmD{P&fKlPi>c3){X)Q!!x7=p0T)|0%4S_dh)^^Ip|RX}l@FFsTs(`XZ#XE)LHqEykB%CSpQ>gi#Lu#Hlr$db zDF2R;IKL~H@Rfbm85{@imedOrSOU%?6y08X_|I*3=BS_}xV|&BEI&+Y23ocO= z_3Ej&QR?5Gtj)jMcKz=W2mKaAZ7w+orVgmI>h_^tStFLvmaVaMVr}9e;gYVNG#okQ z5d^V+xbD`icg-*QwyB!Y?s0H!r6rte3c{hX%44_WtV!hD)K3*{69>7Lijo-tk%hvg zHFb*`AG);LitPuvM;xSD>K3VO#DwrLzhQ<(a3n6P|K4!*4Qh8ccB+auM5KCOSbe$DX8P_0jJypbp=r9&kt#N@_HQhTUgw~SsZ zv}?c4SKVqJ4~mYQ^xkQa0_~w%mABR-#r!~B*fyRl{XZ8Mc1-Pr_$N5mJyg45^*0yH zJ-I+#-Z7pe2U+Sn9hI=cCqv^_zcc!68)iIzwkp#u9uSo!H8D6`QUM!CNkzRj26vg7 zV+Sbc9QVs74=q6`5Ajig9hIM?hw3gxgf+>v7KVa?SUZpzZPhHaN)W6<1FQ_dlxKj<}g19N)dep?oqUus4sDNe@1_DGE zsMj_9waDCN_8h0iJ+)oSgxZRfI%ulyVDupyN}AdRpjL6WtU{WyK}GPetvg-LL(M`( z_E$oOxJzyc^$H$e6@^H#M7N~w$n|UXRK8?Cd)?!PD1J$a&DjO|m&27NJycNz6<7U^ z8Qu14*DSZs$^~)VdM6~IxjeWYlF6@rk$T6wI@ABZ&U*TSeN|_ks%E-F+*xN#p|TcG zuh0%yf6B%-D{E}4X8Xq-avUa`86xeF5p+oT#KR1rhno}J*A{4RZMBceX>pD3l!Gea z_y&APu5Uy=ybhNc)YgsYt@_?EHcxE9bnnt4@EgyC_Ar7Ej|Yu9kJYp$6|WsoWxB>L zlg}pBpi|`jLX@gN95yOd??KmI+uykOB~`FZY%cF5Z2lcY+d}=m>aXmcGu!@l6oec5I6wtb`*Mm9)Xh( zRXz^hd=ua2V8l=H_40n}eGrWHZsvc?*AQEMxS0f=%6jn2`*^(W*N{0N?7qP5NBsZk zt|s7SPcxe6Pax`_-+8|?-|>s%c1IdI@c-i9h`43aFXkz;43683{xCJbgcym`w95&T z?XW*$)U}h3AN;8j|CPuAc~!*~Vdq!D39EhTHe4EqjlUZ{;EHK!V_{g98aNh_iKPsI zkQ&;6ar+W&#hbSGQ*Ing09cjK0vr1x&;lcCS3_&nZ(KM%CtG#OnupYpvK3+OMvx|r$pEq_>P6uD**ikK@6?XmOQ@e@8iPu;{z6_?LdEo8?*cEItByF3UlZm5bH+~;Wra`JvrHI9sziav*KU`}}jT+DI*y7y>! zwQnuBBz~y2+7fxg&|{bzDuibmRjfT;=i#>VD)M7&z3}MyMleD3)a(0y)aK8#Ef*u> zQ)_#REI%-R4#q}a)9`wCBi@3o5m(S>Z?lvWM!;7fw3UHiou{7s*M8^+ja= z90vUNg~H(*uJxj! zvq!NoJ+ge1Dt18}ya8&9`Zkc1sAAEjy+XD(ZR^NT4Zh8tudTWG$&RXAr#QF+WN$wM z3n&jNSEwb~#DWx42mob`%jmpHTQojJ6-teRGJyNY153k81fxgT2=zZ1)#n>7*&D@W{-c_?APz17b|#(*$-~8uIgFmA2uX|Y zIyD#07YoL%wcY#M#Vy-E%{$5=g(MWq%@B1W4^$6C_QdxESypn3YQox)UAU>o$VJtvc&j*A0N7;l=}P|hq=$U0wkc<# zRbIhO>e_Dcak7r7DZ~td-59H65WYu_Y(-C-S$wsT=e_%26w_rClw4|Y;r=n&5rrVVu$21AZP0KZr2fjvR`{>Z$OZN=_|@i8*V zlyx!>jE;%rg=F!Tr{akAjB6HZOVjL+&%yE0J}uLlUI`$8KxANEVeIt9gmVj6SjVW# zdHKTJgQcqPZQ`Tk8;$zTUmIEVyFGW`w3RV+^@Z_~@_^A~i>4cA=L+mjY$!dV-};4- z;$DqwOXtaBO&?NNy)E#j!`9Xx%6BY9#3e1%>Mbwl>ZeD|wqIjikf|>%1 zHOkvC3w*jcDR_X@e#5Zc{SlPtUuDVV#=Y@qhzS{Zc>vK;np@ot7|-`wnd?` zkkdGnJx8|qeBMRDtJFaI#j_eRLZ4nq5CAx$WcOnv}_SLqW;CQd7S1Q|00vN+cy{$crnf?o&<< z|DmZ%o5lyr2NuhN|f*y|iHU3F@lm@j%Gy5>-)Qv2}L zDn78*nwEy#a99*AS)$a{|0q1hT-%ax%_=G%n|D z+eUA()fuhh18S!?iz46-M_O4-1Vwm6pHEvDzBo-)e{LKxt>~0S)%P!sR3nZzu1O1) zOfOQ`w2b$!ov4l-I-E}ox!qoOvjdQQGC#p$2P0p#B6V(wR8<$L*nf&xtRax_R zzuHL}TnwcV9%RJyrmC_J4r^n-QCh|O)=m;u36#ea_Ie}*Z@{%{Q^$-xTUFX3-bYnx zc*a2`goN5v;Zdcy(Ae{%cH8N;Gk%MBZ`pY0C7MxCQVb%H_NZ7|9sk{Z**4xw z9z(hku?C8vt_qbxE2b`|aF&xFRhJKqUnpmeOkAFZQ<<<5_}hpQJl3%ZD-*M2T9(H3 zrkf^Rbc(92OS~r!$V-97M`0leL$y@3tqjv1^MLl*C$_$!dAx_b!RREC#ivbcY_3Cl zwC9G|ikP%`cL_5__4AtxrxqmehVHE%tWL1Xp0XpCB+UAOFR)kmMl;aH;IpcyY3 zJB)3{!?4+JfY=- zxFYc8xZiUpvY_4US>{>dx!N-i-sRIgQ#=Kpi#?-|0c{Zc%X@e_dD?4qSE#2&8USPI2TfmF`4D&?OkKA_);UQiVhyAh+Rd@M({`uXSI6%!bwOGWTS7wU0$!!=dg0 z?%wXM?o{}-pX+YyKFJ+$yO7iHXV*b}oqmgcgKMg*&~*v2wPnNaJk8b9)fu_k&Uc;T zI?dI{aZ z{}*29-|AoLpX%@HZ|Se-&%+P>G5rDkZqxAm2N~$TfnU+b@b!5E`RAVVJc+D#r+AaS z9z+ZH6*=z?n4cl@!d~-L#0z-Z+-g2(ZZg*+-`xsC47dhS8$L!p#5a;(N`5Z+$>c{7 zx8cs@waGUpFH2s6T!`}!xnWxJl;i?rLL8MmJb4fzH1t3Yh&IX1lF#;^=RXsf0F(S~ z-+vJo;alVZ{M7fp?=9aezUL7c;W6I>zPo+ve77J6U=*P@6zN`lY@x#;7B@@^nKD-N&AsW@omISTq{op*@t&kRl5T^xDUK|PS0v3z zsz&CC$%ywbHYqo0Xwrb-gUAWFK6qHET5NIxNzCbg9rUK^) zoXeoU&)``uuuNd7Ktdoc5EF=JlhV5h)y0?!KU5O_x5X@TtmPYFCJ@PxoNZ&S?!-828>k|}V>6u4vxTrveNnF5zg zflH>qB~xHb;Nr%m0^P4x4_o|vIbqU23@iS&9?kEvyDJ&fmQ-71zHF+7dT&_nLty4^90TnND*iv zaE`#)0%r-FDbQHp41v=HPV?TRoEQIJ*eI-}m~>WPxpvAC4N{l90e%p?0e%p?0e%p? z0e%p?0e%p?0e%p?0e%p?0e%p?0e%p?0e%p?0e%p?0e%p?fo)Rt;{sa+9uwFi@TkBe z0uK{-0q|T27KIDdQD&?)2Z-B?mH^777 zOZ-c|0UkHs0FPU4fP20CZJogF0&4}<2&@*kP2g66TLe}K+$?aDz>NYc1y%^$Ah29u znZQzkgg{&%CJ+_4USNs9Vu9-ft`)dOV3EMW@RGo8ffof{5ZEQaJD5&ZzWxx)H3iEBD1vs<9~+#T;DUu=zgkq2YCJ` zn@^bqW_!=Cp6BtUKhATe`*VClSKv$eRA>sexvq8PAv^iA#!bjM-U&fUcI$DyK=11O zuk$VEEzSaGM?5I|99tdNIWBdiIy~C*X!?KsJ3j$pJb8hVW(zSjDWYdeetxF5UEj85 z*8P=AjnO*+7W@dl4muM`8AIvVA~1ZlMXsaj0_e_QCaJ>DJ2pU>rfoM)Yo=ZG`vGhMupkIzItcyc!s2ArvJu zLYd#TJKOmN#cW-E^F&)wlu>PIl~7EUPeMLCWT@G$FHWy|*H9IvCfbN1o-WLWX=XAE zK~T}1#-Fa}sgo__kCAuZRg&$;f6fxlk@~BW?L^TwA@K!*spNz_a@)8>2 z!#l?|vX$r;BwE!?4TSkl$tdO6t7$1CDcuk>xX?GFi+|*6SGa2Rg9-5D$v#Pa%nFrM zBY7DjeTI=iX}f;L&hU9Q>$FRv1<$#IjEry;pu{}rS$g?2=qjOZe#*#2qN8CuPhSWOITvW+aEIl;k@QbI;9sa6)3)&>k7ybra+<(Vi?U2b0*}v?n^_Sk8(`cBg zx?7@|sEW^oQV+pk;qDtQCgpEdh~^iQWEV7QR%wZ6(^bhH3555hh@w0e_$6WhG+&Yt zEeAd%<#h@>e>)VqVWKMAGI5@0khzcLFzi*XhNtQ)@8S;W}mB>(cAT>s31~5=}%4P3^#w zAGxaR+MR8>47~cFx-vC!j;OZj%FMD!2#7w59CyJ}t}Ss^;{lJ_7Lsv^vwhk;Ockkx zGs)CV>eCG9XDx4Wp?}~xfDw~om?LWo5_;k9nJJtQa3DB>t+XeN-1ZsZt?S$JW+nSo zce*6b5*r3pPW95oFjJwW5yC9j)_y3cU2*DbwHJeTOe`WEGCd9yHNN)hnz@yy$JNDc z5+E9r`wCq=5EenQ*TcA{`r*9o;ON`z0k=wkXe|A}rWm1JAf>x~t=?q!!f z7WcJkPG|BU+4eDB81&fnnvI{TA^noQXx@WiQY zb=tydY456nof2Rf!?@1{iOo|*REtO@;&{VeTU%&BtIE|ksY1OHU>m1#A#l9QiRTE1 zaN-=2v6al|(_v4qofM~!#3sN2^wc22tOLRB&~0V1+mJQx}FZcs*xBd~MY zZRzdj7N;#$B|0U7wNoO58S;!wNrRQGqE4YF)91w2))oRGS*p?OD4}LBD-*O4s02CiV7zZ;i16s_+yZ z7fI>a{d1>$qiW1ac*R~z-Nha@IRySfgFAUuldA78RaK5nfK07!*>Lz95p@JXlfs~+ zmNmTYz$1n4k5zSNB|x}7iI)TMn`bn*I%8p`wp1IS>bp1rIyR0?SOQcZ%UN4%}?k;456-K#{nG$POtdSaIoPUT=jdtc?18csve#I=Nqe* z`#Y|<3fpx2mL~vI4DbajXN2+Q!dtO{HS62E%zoVt zGd3a)b~zp6>81?`BZ*@b(%dz;&Q8H1UyU07@HmL)#DU^Rf*#t2*5|%=kM@2qn^ZS8 z4sJT}x~ReoBqEk~u9fnuf#WxREYNPByGM0)L>xSJa?+u?MCc z?9Z+-@mcC_Au?DPy`=-#urSym4X*k3h1&X8gQ~Y<<2AK2K`V9)_=xRBRe%`O@Mp|; zxQlkyxvReuNdaL*T{0v_R1RfPbX#2j2=`Z|}$6JG?{8PtAE| z3)r3uJs$U3_aHC>u5h(Q#Pv$!bXcm#>y4csIM+HSIh(=5f2HFh$2r=2sQl0T%T9nw zDLV{UZK3JKaBba@R#sJ14jRT#cu^KtB6mDUnaI~%Rg^jqzD>wbUWDjtV3p%T72n~; z^d(w+dy*PjzXYh3w8eD8lLc}crLslBC`?=l*m>Fxin|7XcIJ*3<2cCNA-zJ2G_%i* zJrfgT^QS6s7AJS;0Ytt(dSPc#lk6v+Q0@0jfPG1C4l101UXyb`De`k1y|8}QrkM$w zJ2D~xDyG^N$kh*DemFNaa7LW-cIPb4R2{k?0d^)$F?R?@Ul6d4(U*mXA`5O%<@zST z$Rs63H$0)XUqb;W-a1AF#up2OVE0>f%`u(rulGrELnBSXle&iE^#kt35u^ z-a+#d;C9li&p^)+-w5#z@Y#Nxb?aX)nRks%*&CMt5tQxm6A{AIkLoBCPh2P=_H@7afp~Z@uWH zeIgy~P@MS*uvY0MPE(UrTv$fL`{S(HxMG2}EMPOFCnmsVC6y~pPbO4z)%X%YnjH$W z#60%n>%a5I$b{SHsks`L0OwVf4Q+Astxx3S;~l|S`P#yXO;qLM6GD}>ZbUd`T)3jB zCL#_h$JcxPdaXL&RvlfM0KJwrXqtV|RA6!@%jxv^8ZdevK%`WAenut0%cT>gv`~pS zoyS@4Gl#TQ?cY;V6H0)-OPee|QuL0_6kQzH_+V!rUmN;25$*EcF4ab10=!@HYM?eO zB{eqlniP)OgU`j|ZRUq1+T~kgs+q9~5Qo*y(_cPk$oKd-$B?(C^!1-q-Q5%58j~)m z6`ldSKx&BoZk=DWr=g?ftjBa5f`ZX;hO61w#j5Do1gOVUl#bVV#c*b;tRePsUU+5= ziq?Nu{NGMko@HIMUl;dOb&pAaq)b7AsBV07lh*_06`JY>*KG73t}VX*L{;;+1Q^X& z7oyj}F`Kk~RrG1kUR@3CxATV{6W+G0rcW8xt2KCDMl8^-_h+bz3lboO<8@~*8ICa!MpQOMs>r)$Et?^B|c6;G2)!&N}AiApusy|5XoS&WUDS6>ExYNdhOl|qCw$}ZkL^q{C z!~tUxll^(7q2*7jZ1{rLhwm+Y_j%R#@rkbLi4tp2PWcSjN1!w3IB&&O4c~?JM;Fc+ z)mk-hVd4UxmW|gN89UjzZveCfX>hqFV`j@Vw`owyvAL z|GR06===YQ;DF@!lIJ9!2sU+jWC03#|8-j2T7;{Wtw-{aQUkZ{&Q!IoH|4@r7dz zvH_f}eTe3c_?Nd7<|)!JT|#?u%8r{#s^BYB$Ylji{Kc|IZ_SB22<* zNP8J7saO2^Cff2>epbbMFNI-?zEpZ+YO_L!&|ZcTrRdMGD$t*rJ9p$Os(ji~7`y05 zKrsTds&{OtE&*Wx?H@UuI%CjZ)h_F7D*^^Ah0Tj5CJl9@hsv100FOCn31R4{-;rVD zCN(Zp2K!d=RDE5unJw)_K71)GVAvhG8iWT76|!p;C!0hj&xxUu9c%FN)}9|2f_E9| zj%O60n!1yt-@Sj<^ml5<2J0A|IcaV(Cy!cwKpBFNM?!T+Wu)!amdv*I_fAV;NTXXu5q$=Rz?I;yc5MklKuk>;jJ>i9XGg=m zN4vVMTaBatQrObybexB|NJFRt1Yd-83=Y?%o(h#s#mj*|w{duZHY+a#Jpj}g`rVsn z_UWf8>9Q2IH5v@H45fX47|E-OCsm`a`fV>R&~7-}RK>b2g>{YY19w{DD5c6H8@h;oOO+SGVvrL7kjuoSj2dZMz>OMFz4M=@03 z^^5RW;gwl63pqJ5%c^Q3VdM5b+KuO&rh1*b6jrd_Tn(8jO2ZtifK{4sBSdV32%@a~ z-)q%39GK;PLsi;#DGXtB8)!gO#}O0oLgrk*&9}*33L{rKE~h8U+V|z-i7o!<2Tt)6 z!*|KhFx|F6p;AOw;js-1Lm4}`deS7l`L;==_IY^VQkb@gcQRCFv;|(*q@~S7fXI6H zP$~(PmLoLrfbvlMBeCNP*I9x z`deApIDMwJu)7^ueArUhoO+8*AfHC1an642 z>RmSTpuw4qkLW5Q}Zp}S0)D90y0^r5LkFf-^>qrBbDMi<(l2AU;c zw4q0pI+X#g0&EpEmD)}ZzE1u%)FuLSNx=R>YpoS7LpmMAB?+Y<`-b)$rDHCqkl_5g zq?rlF6Lvcxtl_2juYf-rJ|$s`afcHJwkOh`<0NGk9kR zqX9160318=%1gB8GTM&`*;T4jv`u=qe)(b~v|M-;3AZNvu;!fuTymUPf8TK<)%JD42@N)L^?6>1{6*I_nA4q z-W#JY-=r#X#fq6~93wN(B#6ib9_s&OrVQSzEt`6+%3;!q8PTSih$S_v{NI<}NNgT6 z{HrvT_GK&b#AQ1*6_K`Pqxkuh(!hx-cK z&9+6(xv&LL2!Hk&&MD6E@Mu5GIl$Q$KJ7a?+c{gp9zcC(9j6z5?JbU9@DBcz<8ye> zJPa?FZ{sEWPI$L}*72m{VfeSd*Rk3WhKKtb9oIXqh82PmN4_HmUhXG5#=;K45J!rm zx1%dO-M4`yg2wQ5U)$k!*nL0w&icNFr}>Y42k{bnukSVA4&MvDExyO`=KKNpo4>;s z^xfiHf>-BP`DXcweKUMnzNx;6zA?TLzCphJzMj6$c<~+YyTsSfccHJA&+zHq-@HF~ zPkX=ge(F7nclYml-|+78Zuf5WZpO>|hrH{&cY9ZPS9ov6+xrFHx$wJK=*{(J;Pw4@ zZ<=?QcYwFAw>#e7xAV62#(C>|>v+9*J8$v);`z>V%JaGB7+%jG@VxEWnd}+s8RZ$`N%8c?d-x8XHlF65#-4hf z+ISIf_h{~)+-KciyHC15b{}-_ckc!FV~6_%_ZIi#?v3sT+-ux-xP!38u*AL4eU*Eb zyVyMg))=O`C%VVDN4N*M`@22hd9Se=HVBp*HyYO) zR~vKiY9-&uF{T-ljj_fkV+iaJ^ftO09gH?cbE7fd{ns|!hTYIyKe^80<^M_7$F75} z{jR;Z>)PRZ!L`NpxN9R=FKZkctVf)+e{DZ$|JZ)ez904@UbFA8zkp|XkJ~rGg2Wow zxD48Fu`jVNgbj&Vcn>qfo@JkEp9m`wBkY6h{p~&No$U#*BXNnnq5VR8ExTdYVM*c# z+iBaEwoh$G@n+_f{<(fkKMYF|Z{z-Kr~Z=uto|gdact1<)mQ7`Kbvj(a{Wfw>9|^- zqnGIUcy%)k_9e#ZqpHqAeTbf-_tv|@+C&>MBlYHbW4)epkzQMOI~VBo^RDCm{~!KW zTfk;@SzIGoj$k>Q4!18*Q*Rfp4@>-S)SYE^OYL@d^Ud3`A%egEoSk7TNo8>H) zE;b6HMjnZq)hWfsd!mKiMlET^%&g5^|} zm$RJ0@-mi_Sx#a(k>v!I<5`YlIhJKQ%P}l3WtqluG|N#e`?BoAvNy|KEPJx-!LmEc zZY;a9?834$%T6pivP@#xfn_4g1eWbtwqx0rWgC{QS;n($#j+*K7A%{yY{v2umQ7j4 zv24P!G0R3Q8?tP`vOdd;S=M8D5z7l%)@50TWh~3uEH7YLi=~gGv6|(bEbm}>JIhrp zSF#MV46zKd46t0m@-~*sS>DR>7M9Cc^2j%MnizQH5k;E`|e$TxW8 z8$9w29{C23e1k{6!6V<`k#AhZxy)lZmt_UZIV@+hoW-)7Wf{v-mL)8&WLeCzh$WAF zgGau>Bj4bWZ}7-Bc;p*A@(mvO29JD$N4~)$-{6sN@W?lKnizA=S! zyo}{!mXlacWI2K5c$VW>j%At7atzB$S*EcZ&5}pHF_Qm#1k2$php`;WatO=8EC;b1 z$Z`P7RF)|$lUep>*^ed9DTC*f(VPF$i)BxiJy>>U*^OmamR(qOX4#2lN0vz}JFrY- z$#cr!Ic4yiGI&lIJf{qvQwGl|gXfgNbIRa3W$>IbcupBSrwpD`2G1#j=aj*7%HTO= zG~^r`u&mGWVwUw-Uc~Z3mUUUyVHwM^Hp>fG)?(>n>1F9*>1JuNG+4S=I$1hc+F9CI z>MX4+Ei7YLY9w91v;2+auPlFI`7_I(SpLZJ2bSNn{Ep>0mSVR@S6w=7Sw{D$S% zEWcv;CCe{Ze$MhUmM2-BVEHM_<1CM{{DkGlEI(p-l;shYhglwCd64CYEI(lRKFb3v z-($I-sda)@_v@o(%ez_L#d0;vJ6Ybr@^+T1SgvFlW*K4` zWEo(&g5_;2m$ST;_NwOF>AMxDS+{qecda)Mw%;6{cX67W;pynH;6!*E zPJ1oP?_pPOi8;uui}TlGu=AE`cwO(g?sgTqdbnK9cW~k_b0#}}#+m$Xyb$Q>u)z9% zz@Bc8!zt%MTcNEd&N+|iX?jEJ3F}kVQfqI^@0M3B%Pd1JX3RS=x5wnh^wfSqVgAkk zIt0MBhqfbzd~lQUF9Y5r%d|Zf;l2jf;85F^Y}7)YH`T>UuK+mqL@Oc3f5ac!s~^KZTYC=iiRCjd6NU6%lG44nK?EarsDbX7S06N-v>Xbu2BHn zsGqb=_YGEQ^ay}1j}Bp7b_#i%E+j@3lo&&xF{u$(FYloRaw1fZP65e>r&`M=zN3n8 z6<#Bn_3*;0zldC(^$dXKPI@HPo})?VWdge}qTAro8gcbeA8N~buTaJ98~~A>8k&Zj zhy*nyZr|WMa(6nB{fTyvU8sLjpxqO@OhxM#07V_|^f^zu_C!v2=#4u=?kOl{ps=mp zQTnGVwKeIH%jLuXi0H(&W<_^#QBfgiB{ia0Ut4|k)g>y=jsbAY6|Dh^9lU=|B`c^k zvZ=dQyWzWt`YI^^0y!xVsd1`5JL{tkzb)5@F#@4S)zvU3ewp49hMB`%YK~ zfEfu#Nyk%Nk{? zlBBgLv*`B74SI3_bZ_dpJ}4!PEvPK1@1dCa^CWDGztEnlh?pu)3V_wET4zL2xwM&G zqji>^(gHIsR)y~#08yK${#5uu;12#(e%8dzxjiF1-u?kFutkxh-YTKwNr%#+dY)Bl zy>|Dk_Q@*uqyWg)7z8n7TKcka(7D6xch=?FYwRO|CVUBu5nGq$mXG^Z#pw_Ld7740 ziUYgK`GQYSBg#8N=gy8-QThZxgoZMlqhKY55=XlHVUh{+5o*Lg(&Or+rYe4~z#w4( zgR-Rg0nc3}Fyzkk-@*R5*)vcta05Z>t{zFh zZN3&7R~ju8II$uVyrIBjnZlakwm0)kW#Bo=_vW^_R}t!ov{?N7n$TshISli}JxRz$c<5I1bpJyjpG6>Qkp` z%YMH_<=o!7ov-N_L^Nl|;G2fk37fByiW8qm) z5dr=K^T;W9(M;RQ#o9A1B3iu;fsWDfmJUt??Tl)+hV|NWC3_xLStJCKqD#UAe;zF) zHOn;bR9R+4G(v}HgmjP^F&t_{usptb{8y1LWxqh8Fug;AVF=#mGW&@eA{p)i#N*%^ zjaYk`cEi&Vvr63q31TlwV|=8)1YA?Rg~8UV*q;TRX!W?3Qy)(29ASti1=_1lLsU?% z^GeI;TUb4gb(3xO!y#3}wt;q{hU9`!*@Agh2ki$Gh@rWD%eNb+mAF;t4uQ5++8m!P zY*{crs%K#NCjE*Hku6HsKpXMwgzAGmG+3qVjE?>IRgY*b%PjuwQk7TlKx;LcupDDb z6@%{rA`#5hl*SE#cC<#ejvk5H7Y$!k(GvslyfxyrVg%@#6>&+OYDBSovU}=XtyPTn zfmYlUyo*c2HleWcL2XwR&Z++4PHo+k2-mAiprs(m@j(NeC77>DE~tF4glu$Gjc5I2 zuXgR6$Obhr&_Zm%=)3?s73@_CT-Rz*9+*FOR;nslmq7DqPU8yj=*gHk4A!K%g+k@9M#vTkX9Rs9G@wo4!`TA9Hh$AUgJ$`31R;L}!% zrXT36t;t-h@<|Fb5$bKqXL99(v`+?m3ZIy&g|qHjaZOx;iqkpJIJz+(SdNCn!U-cT zpea|6^^s4zHsgef)+f+N9ATQl??L6#xN#t$(XM|w!XWJ&XdqmJ_CONJ`FYwaqwqERL!k5S?&|=Jcbu;t^xg2W2yOQ%*qA@+ zJ>cC7P4`RQEzoms@UDTDd%1TBblh{i#n5n1^G<|*dkCz{clUPi#zVJV&sz(cZO!uo z^x7vqN1@f;>)8dJ_7=~h&}grLErR8qC7uP)W*2*Mq064=NrNW4zo$F&*zuk?Xt8T~ zoX}za0ITjN-ACOA+rmUtp;)ekZH8{MHHjyK|i2?*EJ1Xi8R*`FeSRXI)En;=c)&mgwv&gBXP=k5)6q0&b`iE&X=59 zz>e79Tmwz)a_17~0_PlOF_;h2-~}PgImFo?tcMQHcxRlmp0gGh51Qi#@EuM%j)Lv5 z*Rcy+hb{27u)(p$u?jqgC5{DPITSl`!Eu=ANCU&6zoR?&4e^dRup4T@ro3kV!F~#w z>!bDq&|B}azXYxIqxKEZS+BA$hsJt=eGc^1x$t=~(Vk`>0$p`?dk1K$z;=Dr8M|<=HI~Sfkhl?fDk{QRvRs=&PV1U!pI7e!Ljo7pCbGasM<#@2_`Pt z^TH|XN$XMT0qfrAxV0{@&aoC-bFI_F2)0hNrg?L%L#+M(%@x)EMjVILV$nV{?vQx9 z#8nbkN(@U3NeoI1NL(TDHpUN(X_@2c568A}bSK>Po-$C5bOed_m=PfxPU5o? zpOLtQ@m1H;5;seHO5&3epOE;t#K$B)D)AAC4@=x6aihflNPI}*gAz9|?sBb{_<+Rw zC9acrpTv75u9dh(;yn`YmUtKAE3VZN@056l#M>pVlDJZ0SYk+GP+~yh3W>Kd?sQ!% zae>5ZBwj6XzQn5-Uv|xtI9FnY#5odYOPnRKTw)pH4p*tf5{XwzES6X#u~1@x#C*p0 z4UymbhRE-IL*)0qA@X}4W-#e{{JtUbJ79?X4j3Z81BS@&fFbfbV2Jz<7$Uy|hRE-L zA@Vz5%;fYA7&9d1Nz7$@&zLSTM`E_bEQy&CGbH*YPLp_r#HkW5mpDb@WfCVd?l&e$ zoG5XE#PJfxNgOLNUE&ytmr6{NIGS;vF-qb{i6bNqmpDw~P>Dk%4rbip6796ZCE96+ zOSIDtmuROQF40aqT%w&SU80>TU80>TU80>TU80>TU80>TU80>TU80>TU80>TU80>T zU80>TU80>TU80>TU80>TU80>TU80?~yF@!}cZqh|?h@^^-6h&-yGyjwc9&?U?Jm(y z+g+law!1_-ZFh-w+U^qVwB04zX}e3b({`6=r|mA$PTO6gowm6KaeHlZ4U{-QVyeUx ziOCZCOYA4Huf#qQdrRykv8Tiy61z+6Cb28yORg>wJ4@^&v7^K!i5(;+N=%U0USd0m zZ6&sm*ji#dSi#3m9OGrr(zB(b5y1`_K_yjWsAi5E${ zP-0z)btJ}0tS#{ZiM1s9BzhU2ciANB60H&~5@RH40-e80{EhVgJ+y@y&ips~#``Yz z?t~Y(rk+nc|G|0t68F3AyWCUUjm<;m9p((P2YkQ10B-fAMt#>ISIE`H6$5W`cRL3= zzJxb`Nsi`VMK88@wH>$JVM_*|d6hoM`i*s?H3xP9_gEHMdd8fKc>tFGFM!?uh3Yhv z62u#Qx^o_gyNj`;k`gvv-nI*EGmP8hky)F>G4Ps+i+u6RvH3CW=hq@eUUVAolx4IA+9>kk{G7dw<5lY>WP_V*zJ=|8)#qr;yHgARY zM9avt`vF0`-luzbN-edhv>-1N=D^8Y?OT6YJ^jhYv^yppQ-vB4#OwVoG8wXYfrpj2 zR!+wC)a=62To|hQ>*Vb1_G+&s#i`^{g0ayipODAT#pt=oUnkdrFa5f z0xR5j6-|2LzfR0LettohE-J0mpm^KQX~EcC=1jIpgEu;VlS+Oq7WSabn*+oTJ+MCv~u%dyd_ZUFg zB{THnK5flQ->K?d9<++pk*sXO4?7HfSBpQO2&PvmC;_rR0D?(Aj0n-s0Z>I0 zCXR+iVTMRQ*FUSs@l$Y5p}^p4pzOJ!|7H0Ong(myE(a|5Io zr%3Sp0{TKxVbk;C_CFE7*%9^9=JrX4*}z^g+7VSf&y72Hi(;Al<9}|6c5s8Vxfe^3wCb7W^RYJDqt(EWRs7$aWzXGb1uE# z!8}#+u>lw}Ae}pvoL^Tajt32(=)W)V>qqA=h^Q$O0IL5SYyrsZY-LCmv0ZSC8S zsF)oB(pCb+}iQEYV=YY+6jSw$HbC>5EJjTT{?4~rLZN@})g&3am|op@#VGnGz4 z0HzQ?0pdcZ<4b;CyV!2iw5PKoip=(bD}{=+DP>Iiq=F)FBiDF&=6TMmvA(rLyR$=bG<%o} zAl_3FVq?>US;7icKWuqtYp>fSLx`v%{Q_lz91L7fW-4lVYzzhrH|ejO${&kiGwp5wICKT4bA~DxD37ZKS<2hyovT;d_+gw zJ%G3Sv`{9YY-3Bna)D)cczXH6=CHJ^Kj{0&SG-FgS9~4F-OmWJ>Q7UWPXozd=}?QN zB*0=?h4r%nZNWC1sz9#*p4roCMN|x!?59TL#snRY3`JESBHQ92+vanM3N6<*8FRr( z6?;%1M|{Vq`fSaI{lol&n(M<-wPoFYQVC58;FUam5ZTOe2@Le)mAN zp(FeiWpvg{fU-WnbT-_|@s>(EEr2KVR7L7> zS}L(qgvNg;_Ua&hiP7@+-QMZw;5T1aN%jn6itT?3)LVLn8dHSTvn($&ue1Q%ZJbAE zVk=MrYD=m9@hEMrBUMH26v*I3hS}aD;4K0JZUoU5YEZr%>DrPfBAcKd0l(q^=`i2~ zix=6YWJQSBusCq+v4G45bM@rdD!)i?yjxrPeuNg)B`{6wQQD%oLty8ws2FZaN-4kU zBz9Zd*4n0mNS<{5@2j2E@Ya2XFW&pHceVF2Z$r=fo}gzWJf%P5&Tz+@$Ibi9OtS-C zU%zPFfS1(uT>GH=PIonMz7PHNV0fqB>?n7%hA+VT?4|bM_7=9E@!Efr?Hb!icnA1h ze^-ATuatA3bFFPXX5DI?VEN8+o26yUw=uWGj6ml93;**6K@Z280P`YbMS28I6j)D_ z%h-bSe%vZ#zyc;1*weF1U}g|a1{*zdVa;x)G@OnJUyAiQ8$Ur)1|J_pcubYH+Tb=3 zvzq;aAd}OIP3&GaR7LJgC?#!w)d|)vuFA?aaN^9#XVtiw76hZ5QXq>M;uwJ`K8WVY zzb>PFX=`m?tqCfNjzO@`>0?W)L2^FK3W4Rq8@&Cr4ajc~`IPTrh~=KT8tS|;@vIVrN-W&|%4pB(Ban#!pq72vbM&JxV5 z{tq&la(raH)2cpGgJ8B(BTyz_>gU7yDLxYTwEpX6whpO3v&gS9$OwW4PajUofGw8B z;SPz6u#+jUf1QbC@YLZ2@hX!RK~Ujod&dU8u!QDfVCEEQ`}9#0wVO+`Rk*f6u-%E1 zuTgE;YYo>q9YjH_EBmayTjw>6bU?G<2tn+kROwttHng;TwtEt_rw3jcO%qIZsvw0L z1D-$3du7rQ2j{D7BzgQpZDFTe6}o8<%Kg|9@3S6h za?N9rjYIz+=-;$-lU+kPgs`RSQr`P%?~)fT_>qJy#)`zD*hwdsmf_`Bg>~uX(!~#{ zEc*vR38#&4FN}z>CGf*4Ij^_^`Lh)CCt7Q(Mn;YrLxbRlQxYSQ1T4p+i?9#mHM)8d zDMf;AUbQs3Wv#aGp;f9leS_eR(*UI!VMD{4agu#k<+lH z!X%U9L*AGV&c)41jT-%7al(mOXi__sTK^ze=Bj~{3$lsHT1bW~aZ&l_1-fh0tczb# zNpuZ@Z%$K#8W@!SqCbtN&)BQodUs?~J3a`;Ijs!kh)4@%S#I{9#>KS_*qFGk%!c{Y zyqTrhxX7VR*f26Ws0VCXaKpu_ME!zbrHd}dcLetv%*JNp%YT}_b=4PT&mL4MbP0l) zF6xBYMn{%E8!FZbd-Dq;1{He-1w);Cm!@AjmWr}Jk33@K%$L$srYXTBu~yU2fZvt4 zcuE1@cr)R@we_DT^1=T3=jN(J`Uk;ZABgQRvAffAvG8T#ff;VCD&j`tqC)*)aFO=9E+`} z@{=DnBU)N5+L%!Vdm{H<-GX4S)5Sey#urnxbH_0eUNfm^)ndN6`kDv7QpM~UY$vR1 zH^K0s62eA3j(IR3iJP-@y8o#fSFg8ITYP_nwVxCOtsT1nWQ*@aURf#o^NbreylNaP zz5E%wUS-%J2wpp#-&BV1hXk)c#Z{x|r%!43{SsL{`vk#g$GR9pb0Y=!m?hY4Vv&7E z$ET7G5ak7!b5%!je4=*aWxZ6E{etnlS|C1Jrv!rumrOV@f=l}t@zP_2e>M`q=L#lr zp}r~0E438YNplTTF~QCzTPEiAOFfil>$|e~{u| zBr|7Y>EN$bGATh&>#40dnIf`FiQ*}R%Ac0Sa%$NXPe$HR^bf{G`<%8R|0s!r$@X?`5g}+Wf-_u&VYh7ez z9~cBjA0K^AVeD-3*9F71RIR^Dr*na}w6s#yXL#^pu~;+*R?J8G_%LzvNBIh{gMeqf%#xdQ|5;oE{*{9nR!5QCVE46jke*+Wy1~9H0 zSdW7TFbgmKf3`elnP=%^vBta-b92mum?qk1$o`-IuS-a3)akxnoM6a($jof*L;jY* zFBd=BsIc`*)i%x;t(vV<2r6_M%oI=fz$wPmsu@e)yI#BNqI*=VE+J^jsnbZGz~2{q zhM`oz^8F#+s1@eH05Bds7UjX1!PFT=k=vt=At=X1Zioldvd|dOPQ6AMtxcQc%!q8D zyN50i-&`sp?Zh!iv4V5WVH#d)*V|s+3`lbybTMOVD>+7jk_l-D|=@x>bn|7mgb%Y~oIqxOuKhBG2d#1DY%&r90I=w(b*>nz|d{gi-LN&>tFrBP2;8x|l=z2nZ zZOO4nkM;?-kw*Pj=R>trJ-bI)$K%rUMnl97;B; z>FjrYez+gJ?(v95rfUeQW~^i!3p#o_fRG!yKWM4ne$wv!B66+NDFjtAMk6AUEeU-6 zvA@EerDg+JGuIdAY*f|j7=qSV6cP#xGC>cQT<7OySyM9p%}b(@pcz(?Xu`nk1J3$2 zbFy?kK4hL(Md}`c_LmMIR6crdiS>*w%y0uxaema_OEPOeqN4T+LHDbMAYEvay?tD8 zi+kVc=f$=TpHnb2QN`{SvWP{z%cfIlkxxmtkXCiR;bzzmeK*^Ctr=6#=&LP174fn+BnSmARhBH`W1pOz zL;DqK?FGcp^z0rkZuB?g5Ve9prM=>FSM+DZDfa^8iZb!dbl6WHNJPEOVnb%6nTFT z-sI-O(?$Myg?@gew)KivRd@9bLRYJ1EFSWb*MRAyrA}r;^I%ogEQNm8T5VPT7gPdW zf>7Mj9TQJ^N`U6jACzAIp|5t|`p8XN-yjsSbV{XfF3cq46~gz*`!H_-CBs0_l~|24 zbm-8;vHls@M?$Y;{c5ka;Hwu^#$AKZ#Hy()G=HdnS$6(;CANj?Xq)#(%wl&BLJO;= z#-Mz7nxgJbpUpQqHEV1Az;;dNH&vcJg3!c@sN`v@pa8d9*e~Sc&ad?RY~Nk4z1S{d z(zsU;D%ro7R_Ep1Y-i5)$U>D6lxkU;Rze|OGlI5#XuZcHpV`4dC}oFozhGEplkW;# zv0y!ojP2;6e4xg_wqCk2|3p1i=`KO2Wz_&3Q;tv4Sa2^$y?b6fYkEeT=Ty9IL1<^i ze6|WN)TCS+n@gV4&x<*2ckxvb4NA9QaWrNck12frmO;N!Tk7yl|^n0h6bk@+BjKJQD`~Om`_0~ zD=Tc{@<615qr}W=N&TW}*PVJ<<=;Dah46kv`Qw`n4>bILV51SgLHu8}_%E-Xzcg}z z-ZwZ^^%|lV31_v`_odbPzFGpC7FXmxuJZ35yj)Cr>NIuGz^;(n5ZlA5G4<7&w(3}9 z1JFG%_a>m~;$iO{4+rEdrn`2Sw(W<0ex=JNLpj*!$W-t>OaFaFmW%cd_%Lz>n-QEK&UBQIWFSyo#9r^;>k#i*QPEZG0kJui5cdd7L0xW51kV3B*2yMg%y?g6edhZ^7G1^ql@ zu;GUFzt!*x*xLD#bE7lc@tdR45rD1z=6Gj*qkVwAuI-TRCfi{Bd;L{Cq-W@{)(@;< zyr%AMwOQV?+-F%}8Et71b2{d+m__gmn4tZxy^o?)|6i97Ivz_@457eZgs zYN?dtHcvR(B5M^A!dzy6gVjaT{<>79Aq#wTz(ko z0tXbO#c~;mbEM#!!x2qv+YnUabcISSKbi_bAH$&qbTaZ&{l=#bKf6^GqC*G@a=PVd zgwSIuA1tTKR(MA$Ez%By^8~(!KhJNyG_l~R2q(CG2wHL+sW}SSjf+d3PG7w$;eD;M zK8*~8wjt=tX*g0ASSDcB2c(W@Xvz_p27|puTIp2UZ{YUIdS8=@ zwUJH1h!7O))Q3Y6kseQA$-&qKOC-B67apwspacW6aIJ*FUE;5Nc1BT5rLE`mNLO?S z32i*rd}QUb*x{fm6u4^jXC{tr6uDSQ3Jns~r^XsZqi8%f24vTyTAVe_$JdW2X4;0J zoL3D@w-rnch&Hfw?a*0o4N;9VG6YRMO@hJHz(qLl!?FxK8o?$Td0xbSpm3PiB-(axpx%u(qjhoHyDc8n{TT!zGG$PFya!QdHKm`QITvh(Cv zjg~3qj@&M_zE^3C4y6dK9qEZiV{DgZ7G*%!4GPf!a>GVS04PASOQ{F*@HCNawLTzcqLP}NI-)c+E*z>z8NxM*gp znhTpq`Pf-i32ymep?_bh3Z5Fml`yGdhNCglO5nE@^MQs*&2g5Po|iuh4UEf~Tz__c z%-1XXUEWZo(kle|0PU~IF&k|JQ$Xy*ypsQ^9ZI7H7>h#@^xcJ7wl)*Bheoznu_uK< zDj1E}gK0|x|K`b9Ln&%JxVh7@xdXYQEN(oGzPN^MtsP=7gaZr9W@B#UXD3!qTVH-u zTY14#D(y}o5D@6rpfyd1E6cO9=i;6Pl&2a+vdq%by7X4Dx`x0xpiL&#XIK%osF8cc z8u9d))!KEbktMNxsHf07Q^YO_NnL8@qt8s&mZwL;cMtUt`vfYUJUnMZxgd^FHS)4P z-DBQ>F{+GNA@B&YRjcu*giLAK!*hC9P(rrH@ejrSir6LyMEYmRJ-HFgDRPhA&?BP=5jyKPAEM)o7gHftJown zXZOb{(!dZ126W(~nVyE5WzyG9$OE@8>u++m>|8h{XSGTvDFi+NU2IY-^9COTl+yF^ zw&Z4%M+)3K1O@?CQXT?u;tf^>ip*AqN22=Y#nvs0wd+RqQCW5mfk;4?`jll_9@sIM z{B*to1qV%6eau=G_PsPcvajhF0*yd5)exNPD&mHL{(oL1eSb=Rt7v{5qWQtMGEOqw z%EdU|qLr&p8Oz|KLtlv;j*~*53#itirz6RjAm^7cd*`T2E?3!g41p}5%9viBfsb4n zOl;LGqjm1)D=&zAoCbtI6`)x~-HD?&mKdxxtXrv3z#4Pfs&C7f+D7F)It1Q8ADK*Y zVa05JMLVqj6}d&T8E4}r<-C%R|7o0taXib%a$aF6KR)`6nhR*}By5CW-y z^pO;4AoSIK9C&L)(P!@0Zd+5J@@XFekASvXbb*mpo)1DxjR@AamR)tUzY5=-D(W{UpJJ zHG$SaNAssdHtiilP}HjdNNz!~z~FRULszNysjuC*GNj7eGX&*49fhc6q)|=qe%1C7sL(s{K{uYWu8d^2-v#d-V`(u1GJLun4cC;$-Biy)n@CxXntVUd0 z?}ge!yCcNxo}v0;A4DS`mwuoH(NUc)9av9UBewO?-Ls#K&~Fk$7e~vg#%9eJ&#ag` zJfhC(5vnH+AJjBVgd8fgG|2jVMeasuC^r5_)w6r(B3?$gS<_KcI=B2uE$wcf_DbTd zDr(2jg;honnkdCT*NfhOpze#k=Sur;@SXMNdvhxJNpKdaYr$gi47ZGveAlPsvWb|ZMEp(IO{_{ z_WS)kqfhaD?==r&!Zwg$X`Bqoo5R624Qt%}&OkI6W~d5AkAaKuO!{ ze4#>i4P(ajQ|S^-4OUwV@$oC=Yuh~WE}J8Me5~Vh;UU(~wQ79oiu#OrrA{CV7yDneoy ztdb;|18jc zQvu_{ppZ0^Ne{>?0gsF=)pO8`E8@&UpQ@kx- zxGLwaZhUxSx{47Wc1N3us*;9F4RUQjiMy_A)bqwP6|_SbgpW?L9^-H}F9a2lI49+} zf5vSON3o1=vLN|@iqbR;ibq`;1%{oAC`{|zI~#Ysx1S2rDGV}44;dyI>$M-RA-L30 z%M*yzs!2wp4zn{21W%3 zu9MR6t*mdNf$h=21LqWFl~)<)v8_%oZ}3ior=o#D(@-f_4NQYPHa^DP@X}@%sKA}V zpl7HGj?T<1FXjz*Tq2n;&de(&ckPIkwy|~J_j}!_Vx@+yhBiqyOA4N_;lKk65+<|AEQ;f%n}uGErwDs5>K^?4i_juF?0!~=wNUv-z9?gtq+Zamxc_(&fJ z3m>@M6jyACcozm&-Rh_H-7l{0+Eb<1H>`;Zr&Odj7FOx8r6@rWU{9im636W!u4Vis znc4ZM99e=Wv3A&+_i_7Zn#bP=m}P1SBHxm)GfIdnDO zL&WeAqYyl_(#lP2!4keOOtMwe9}A4%1Y$(V_VwpG@Qft^x`gJ^JP>Chbh@9s+o1mkmLt__1+wh! zeA&`nDqf#Zg?MmET>)J|VQ%GpVl1ZPS^^^q(X01~<(PKGplek8zM(m^912qE0Ny6h z@U0%DMvEjI&vWFf1p0(#i%VMK4n(dM-H8%LbKGMAQfb3 z5gwKoAQFtX;C8bVvlKR2&g-x0qb#}g%>8>*fqI6(7@-?gQqZNB`}wjRXFrTjcz|KQ zMOBBkwQ}mb4sj~-m7y||6%5zX3xE;jF!TT}L?PH0=hp*Hi2iXAtGA%#S1n`52$g4k zsMO@Hzc!XijKPsW5a=g#J4}(%it?dwf`R$? z@uaFL^S6$~(mqUVuy3D=l@J2ugk}uIqD^iA7CT(|Lam~zV)=Pv#*Yz2T=x(dCcXYB z!XM>z!<-A+L@sp`L;2!(OL;{G`G|5F-;vBdZ9XkE^47g)2y~KuGP4w%d~tC;urw3a z=J6lrS1sm_`dwz-q^i~?1Wt))bE~6MM|@}C0HZXT)7vGNf0w2LcM5?>qFOH%Gak3_ zq~;<`Njdfjs(jjQTJ5zdDpq0$Bob2WP>pD>kPnRtT?iIbX}&Lg(~eb9G=Vxox;Jib z^epbNS?w6f!IHLY#GTiv99oBR#KflX^n76!7PV;D89$}1k38#b6$1T(?ocQ!UR#oG zL6zG&bbrAG->Ou*hd}dCoj3}8-bEZ((5i#+W)IeLa9W5&ed&vons|FW~TZe?v1 zv{eYK3!zBHjRHnX9;UTWr&)c3w!-!r{Br8`Cnpt{0rCy ze|K25hdq1Y$pDuB_rl))D%eRVhJF9;u^4z~I=*y%rN z-^-o?w!lBYa(D(9;_MGU02(|19ALZuOJM7N8m#=s!@9o{mitVf|Nn`Xfym|5|FQpIyPoIV!mj8!x3DXE&MoYUo^=bm zqG#R0uIO2}uq%4jE$oV(bql+qXWhcC=vlXi(>v>SOEe`K5?zdE+)jxOiFS#?F6kM! zuuFQ{JjH)MZGI#1Yl&Y;{F3oo^9zZeOZ-gYNr@*Uek$>}#A6aak@&I1k0c(I2;K_p zGJk6xW;|scl6a8uOY?q->m=SM@m`5*C9aWp591f+-4gGTxLV?!67P_ByTnxzS4s>^ z3`q9 z%ioja?}?1Z%?a}F7Cp@^`BI_Y{fA^6&i_Pni8A_LYC{!+6~6EwPuxp7P&&FrF~G z%irDPzju{??;`)+S^n-M|GlI9dy@Qn2l@9zi3#%G+sl7%C$X*kdmF~%W^2Y{X1v5! z5?e}aA+fo{W)d%v*i>Si#3m9OOKc>up~MCf>r1>?Vm*l$F@9oRD6y`@Iuc_g)|PmI z#99)461@^V65SF_iH1a%M5jcDM7usze@Z?;?EL) zlK7*>FC>00@iU1hC7zJ@sl?+F zk4gMQ;>Qv{V*Jp!OX6zAGj7pNXWXKl&bUQ8opFnHI%A4f;fNvn;fNvn;fNvn;fNvn;fNvn;fNvn;fNvn z;fNvn;fNvn;fNvn;fNvn;fNvn;fNvn;jkh4;jkh4;jkh4;jkh4;jkh4;jkh4;jkh4 z;jkh4;jkh4;jkh4;jkh4;jkh4;jkh4;jkh4;jkh4;gBKv;gBKv;gBKv;gBKv;gBKv z;gBKv;gBKv;gBKv;gBKv;gBKv;gBKP|BxZt|BxZ(+aW{Dw?l@QZ-)#q-wqjKz8x~e zd^==_`F6+<^X;G^=G#F-%(sJvm~RISG2advV!jlfEK_(^N6U!phA>*yZcZv7pe z(!RBR?r7_1?r7w=(BXrRxfuIT_A~Y`?Z@qh?eD?M+^hEO_UG(R!WO^-_Iu!G?l!yz zxXyl+z1&_1>j2a2lU!fh$G}eD0DB*MS9>D7%{8^xx5wJucAM=tum(=qKC^vn`w%t+ zU$^bFy$FwUkJ%ow-Dg{E3)yb5Er!pz3R{V7rY*~Mxox~{G`!9wJMMG@;e%k2;~Jc) zuXH@^_{i}q&e|6{YdaI1sm|W;u6L<3$5{q%1uJo~Ug~_px!?IFyz~9&8Q|&T>FP;@ zH^HW!`kq*i+hcS82HS_H+@HBWc7F&T2(P<$x?hCny2soPx$kqYc8A=zxEJG;U*Rrs z&va+GFL#f3kH)z;+1=CK$=%M~!rjIWXhS@SFNQ}YN;u5X#InU&^N^C|r){b7AQyw=^Wuh4JOuh-}6v-BdcCj9zjJzXE6 z540Y%zF|IWu7?M_+szf`P3HCHd~=pr1Rr>QbF!IkjxYzBea&vTMQLqbVm2`Am>$z^ z{BHfkx(}WZzcoHLJ~0j&`;0e?SKtfr8RK!|KgK%aE+cH*YU^q1WNT+@VQXx=2)_GV zHjDnVepdfV|5QJsAJE^@U(+k~t?-$6tufaqHS&#YW2!L$UK58JDMl}&v(esYX*7Y~ z#0w0=u)3aiT@7wXu`AD&;Tr22=^6yjh)J$Cu4b-=uDUL-%i%oj{K9$6c?h>E+nmqh z1xI9_(V0N;lXI_`DMaAZ2BIL0|f zIR@kYq=%#9AB`sODDPmsuk|i#*!QFFwC@YwG2bEIe&3t$b+OI&tnUfmM&JFuyL~J1 z@@1)SA=ocvz5-v4?+V{U-=)4`zEodtUl(73uNAypUhJ#wGkv=C74NU!@4Vl@)8$9r z54`Vq_jq6SzTkZtzAhj1-s`>78w7J^k@p&SySx&9G%~$YyyM{OvWK^$x2?Ciw~_Zk zuMgfXV>~~3&Un7`9QPddya#`muX?t7o`cPe2R!${-{q!%f2Clz##nrw#ssxI^~JAx z;@3q4Mofu-D+Lq_C=yU8pg=&rfSCej2*?wVOW<v(xHv+yE@Rfis z1$-gka{-?TI4R(SfKLS+7jTTgqaPx0>u~~_2;hEj>y5;(h5{N0;LdUD7mHuqM{b?_ z$gN)}{#aK)9RaZdY74kPKrI120bT(f0d4`N07HO_z_bJf1O%)QaGQYT0&W#>i-2VU zZWeHpfExuY6|h9WVgZW?4CiD4lLSl@FhRh00pkRW6_74qjDSl8qzM=;V3dH740>My zeFXFt&`Us10X+nC7tl>WR{>oFbQaJ_Kt};d3^C;b$^?`W#JYKQ#JXpSUo!;o?1**q z?1*(w7k|tVkS!pKz@y7y^NINNv4D>R92Iaxz+r+|vp|5z*5qtGI*-9vQ)Fw3Y)z4^ zDY7*=TaV6zHrC7(sbmQ76L@qU*Rkdm;*V3sA9+%G^xwoUo|LgB_om0j^ETGx-t^db zPJ3)Tr(;d-O^=PIy~oDWKGx*k^w?}72kuRe%`Sd%Z^oM3n;u(T&d*jyfKz}&gd8GZ zu=pcSl2~(~_~QTpsp8*wI(ck7onp=Y;@|oS;PDb`@_6yu7SkWSwngIKc)Y}#JYHf= z9xt&bkC#}J$4jiq<0aPQ@e*tDc=398BE*_JUSiD-BC$jQmxt#{tl3`tv7Lan0@?^@ zP2lnb1n_Khd3ZLuJUkm+9-fUZ56?!IXPF4evoY3;^Q_X^{IhQc#WOsQi0B~!L4sJ5 zSE*Q2wi&m4tSMVwc9rZu?%UcX_fc&#mZH}-YYVtQKrI120bT(f0d4`N07HOF0FRdo zoUhZb3!Hld>=y8vfL8_V67Y(EodRAKutPwlfb9ad33y4sivnICsO5N60Jlpm$HU^+ zCIK4-{71k;0v;5wLBM(e4+yxQ!Ok@z2g;O#og1>2og1>2og1>2of{HOC4%rgs%7VS zRLjnDtd@+-u_|_u9D0y*6%guZ^4BYvU&O+PKNRwsj)0+Xbu=uu?!+0FQaE zjmNy##xu@q;~D3*@r?7@mWzt|_hy zoyVc?UgDhMZ08MZ-q7w{uamFx7m z`Y^q|^?U0c>pk$do@6;~dBRd=8H!f{Cu1ItDTo<}R{^K~eJ!Ig+lE0?qi0$dfFCgu zmgVt;nk?>2@K=;-C&zWPZYi0k=P7nX^DqnFX`~r6@=zE;cm~1>6XLBbM-8${DqSz?$B@A8| zJ(8uSnp^~X0@CCmWz=oHc4NmyDx=R~PHr@+QlGC4z09RCwwGcS#8tlzy&F^YSK zK@n5YtL5JDk8|I4&RrbyL^L``Vk-Jy=bogUu-0wy=KBp&_U%#8+l4_JYx_raPioC| z{dKtei5+n&c$+ZzVv45?lZ<#hDj$jB+Q^Bt* zfhg>3_kFXLsgTXWpoLv5OOg%;UFiu_-uOXJH9oTS1{JDZ7>qF0vIAgc1FtXf%AM@) z`#I6i%}V zdrzm8Dp=DnSYL|F4{LDQRKB(i-ngXK^#fIy7Gco68p&F~i3@xZb?nGl)-7q2G--kg z*D?&QmwF(AnM%(e#+6dQ_~crRzI}Uy3fLkHs+US|1Z+mJ!7ys*cZbEzG)}5;3E|1n z*C7cB3G^6^o@VBYXR}nB7n-==%ZNN^XcwLoZApF|l8g7?h*XYesg(XZuQyt9j*hFhwYLh|E<8S3 z05P3oC7e#LgT;e0Y5})P~zkzZ4zCWwtH4l%8 zCJzI4;M3-d@qDkR;p8F}EIxc`v?XK@BbNfITI+;Xap~iZtDvpJY0;-|R1#S4o=(OrD!4QUZfIite6@;@8XgjTyONC8 zO=XCbg7+(E`q>#p6=b&=PcsMjv$F8is;eda!uO55<@>aVOic7hG- zv{HXQb#-j3cTY9)#9yyMcMA`qZ@Z`&Y>@W}P>k3Zv@ZIhSDLqxV4&jvO>ne8PnO+XEFWH$HTu#pusbAXO(#TSKwu;gv zoE#lkgUHf9ULK@m2z%O?rd+TSdpzU& zKc_;s4EKx9i|CU@>VamR8&3K*^4c>Y+&9{eG)zXL+e_j)cc&M1rQ9_8wlz61^)Z!l zi*TQ4(@+F5!AK>DZ+VYr-NQGlaP7jqqw5)7ZBnnottVDW*`IxzHZDxRCmOuhUkC5= zeWMpIIIV&=4fl+Ge8?gcS~@nq-kXiBR&n-=?uv$U~^kE%KHv)yv7!Jvl|~yiZ1tK{TZ-L4I9^` zyeWylu&MjzX|JjDtFKaALIhgWz|8hAR9w!<~eD z9F0-Xs>#ibzFZoa2_3=-(J4yfbud|+jDvNwd>n(YP2$3@X!3Qie>9u+(QJ5D$EW4t zg%&*w!-l;hZ(3WlKjH57YjYK+S-4$vYn7Z;l9yA)ZP{#UqwmaKD%5~*TSL1{wm*Gf zF#^&vQRPf*-sSH>WEdD{1H5N}^T_PhoXo-caT(7?Hq^btZK~|YX(UxEU=sH9Dmot~ zS{}Q}{cSCaDn(Mbb+mrT_>^FygMy63{uQnp@_6})jqm+XKv+Zk7wJqP;?^2SMtuKT(1wG9rd{F{cGM;8X11Dc95&WM|GOSTGQIP5XES#iaB z()zLWeW%CiaK<=(cASIO^)tNZKje7N@fJ?;FFRgzJmYx6vB|OCu@<`akmFXzQpa_U z`HtDpw$F5AJFaj{a-`#=KiHA%=n3}v9nPTh7Tg0YbYA701@8L{XO?p+wD4n`Bb#=VhIlbqaV4tFxN$l2MbjG;1Mv3^TK)WKGT*mo*|QA54bqtnOKz zv)W~OvvhD7_B%gvzUTbAbFcFyuo?d7eAM}%^B(8z&K=-0Y9P6|Zxk65z{wb5 z0Cr7+L;r{rmkN`rq-t?tj_;tpAVxNBsB0GUcuQ8~od0n_`RqeE*sL_5O8u zrKdFUNL2%Q@`+`<)Jt-TNo}2mfU^hfh)HpTOaG z4##mgmcua|j^=O_ha)*0!QpTYhjBQR!yz0NaG1~GU=H&*9K_*34s$uo;cx(l{W4oWsr>cH*!jhaEU<&*5Plw&O6! zVSqyjEYUxH4t*SYIrMPo=Fr7q7Kcs_bq*aI+Bvjw$UX1-mj3ShhQqHp{EEXbIsAgd ze{#5=!_PVVjKfbk{Di}gIsAyj4>{b&;XgS1fW!AWe2>F-Iedr1w>f-^!#6qnJBM#@ z_%{w;=kPTSU*&Kwhkxbp6%PNx;maKE;qWC6U*zxw4xi`nIS!xY@Xs7R!{O5${)t1L zlRlo4zCZH6Jjvl7IDCS`$2okA!$&!Mgu{n9{5^*cakz`a2RVFz!}~e>9f$XEcrS_f49NBKMk~d(F?i=I37XbFcZi*ZkaTe(p8zr##4B9wILfk(Y zh`c;RULGPZ50RIL$jd|Imsf+ASA&;VgO^u>msf+Ag^YH8%D7nj z^LIAA|MfqqiwqZsSsXe!hqrKeGlw^Ecq4~5aCkk3*Kv3)hu3g;HHTMmxShi*IlO|y%Q@V};bk0N z%Hgj#yoAH89Hu!;ahT*V!QmDTFXr$f4lm?zGlv&&xQWB_IXsWUjU1lK;W-?h&EZ)b zp2^_`4$t85bPiAB@Kg>@;cz{NCv$ibhbMA)0*A+QcpQi8IBer^Ew4@YFoB^0Lj(#0 z@&yJnIA0amEAUr=R|Nhd@Up-jftLhc6nKF_|E<8?0?a$G>vzg8<{j8|<{j8|<{j8| z<{jAe+a$`Z0?a$G>nwt|>nwt|>nwt|>zgGCi{R}#i{R}#i{R}#i{R}#i{R}#i{R}# zi{R}#i{R}#3*GHH3*GJd2FZ+t?slDp?slDp?slDp?slDp?slDp?slDp?sokoNq3^a z2?ECp94COmu-WWbq6o1>5n_oVWb%gH&$JS||2~fFzgOTM0qI1)bfRB6(J!6omrnFc zC;ES*X|@~w*Kch9HyS|8(!Yemqc~j5;UW$fa=3uQ`5eyUa4v^c9M0izHiwlQR&Y3r z!*UL1ayWy-=^U1EIE}-p98Te|l*1AZi#aUfu#m&a93IKxBn~H%{C|Yjss--|o)DZL z>=*bGSj!!Zhm5sG2sZ!P{73j6^BwP-;R|^`246hso#*Y~c^Vo53p~BtAGmk9Pj?r& zK8BRP0C(o5tj@UI9_`H1uhtjfPI;xH%Ko1HJbQudueS4S1=_lF#S z$V@eJEL*{bpBKP08uEip{P_`Byn{M5_r-XZWcr@XykeZ z0s(r~VMBO_n*G#wwT-7*LiAY)JOjZ*EB8!!G~5t9 z5IN-h+Ba*b$1Rh@OA>feQth8fe#_V!1sVP<#d~1gA!om2tag6$U8=fACHk=S3T{6L z1bCFJ4Hb%?S$d&9)ZQI?4@{O?R`qKV*cpc`B3n6oX2hBq* z=G`~6%L{C(5#@>AnLaO%t%x0Je$J{dv>o?ZHe(hiLL`=uNdZAQSv8*$fmtQ8a9?w% znd>{Nv~=9E&NDaBiyj`$%%d=gi-%;GI6vfU_b$~goA-+9gPDn*vc$>e*rIUVnn<1Y z?!il17W{#WI@I4<|Bi1rYo|UwMP+w%q6eFw@lbYn7l->+h?OevPKzbTf>u1#9!mcD zjB4%N=U!C#&rQHiCb5FZz8Fblt6C#X;zz0Zkn(k$r8Qq^*$7&a=*A}JxY{5EH7svo zOK@T=5uyP2+dHIMU%p%0@}XsNdO-rVIB8-~ufUiP-q1-hQYh9O4=v|jBeXNCEyGI- z5-{FLw)m+(Nd8$AsSd{>>qVDi`W;f%j)l&KXD6wiJ~{zIpD-jOT|!cQWXaAyX{pa7 zH-?8clFo_(?dGP%D*q)3SO$f&5YC@HI#QQZM&P=Ve4m$+)$2p*^4KZbrgV$Sz99jN zqDPt8SHb#KD;$Bf@REdy9a#J>H~j%&Lu8AX74YG9NafwWPfJ%Eqsp6|=tPn)8Hn;I z4BtXNQPLc*J)}$>S9e@p-%;f`GXa~WL~5hKg+c$;C}drSQb+s#5z8*JtP)O6bP&f_ z#Ha(Yq@@m@@#ZjGt-z%#*jVU({!o&r9Y$cA>$P|04YMz5D8In6Sv5YWiiNmCir~;tE!F(Mt0U}LY(0$h|c3877 zKhaLsc_$P^&L|)=qY6%q)z@h6(2k^+7Hj7&vrIsZOa$4U7<1xaIk!GiA3ru+7lJ8J zY!cXfAlAXwgGxDWy=UEV7pXc;O$5AJIr_LC3Yr;*sc9k^l8;ZAA)AKM=!-cw##?wU zN`^&7d_fyy1!&zw4Xv}bru>8QAiw6@S<_!DW>Pw1#^Za!IMaAd+K8H}d>L>ECw z$c{GIqslu)@pbFS%2tfb16IROU>k(*j>9*sSo)C4VRFK&a)9wV7}BG)4eNQ3?8jQQ zcgj|yu`^(?9)=lPTce>Wa<#74B(zPBT&=R`m++9}S;&Y*B&Ech;t_Qe=GIO9t%^4! z;g$mlbq}w19uatbY*^0z?Wuz*3$*hVUZIidb{Uu_D&>9ij{!H-bcQ&cW zIf<;yMQhAYIAzo1g@6$fz8=mk@T6c)l8gJsA6lXEo}SR< zv=>I*r($hKw737=H!^cXcKR;YuG()I{why6NGR#?P-f)+W>KtpPq zj!xK#n<4ovfX9_k8D?v2rCOLmG(Cj+IzHH^t^bWr zO1=v>H2m5!)?T*dL^&i<^JkF!_z<$v+i%oPf1ps+apsm2WJ9OCc#EiLJf!SSU#MMt z?yppK@!u`>@8x^m1h7sLvD@2voJAu4kc5^W7X^aVR?bb-vVo| zbkMRk8F0<`(86Y;iQ()l(@rTEr7F>Pix9`aQG`_ORDhhBQr z*9rIj6TKmm-=FLLtNRAX^{2agLNEJz*Xhu~4ngn#`mEEk=4a(Nzj8heoBwg=OlK}6 z)lWf}J+6;(yyMsoi~pk>y8Su(c6*C`y1kw44cl$DMq81sz4oSdFREbv$w`1K<pA(TU~agp8u{DW?qX{z5tQRh6?G9dOG*#X-uQw;#9DqYCMt z0RLKSRElBPdh@u4h~3B5UTPVu%}*@j?<99{87?bv9EWhPg{RftHJ1BrYhol1pAr`*jGD>h~M5k>O_@dP+}<`K)AtdsD1^#RiJB&aAW?^ZU3gK zdbwo-vmgOxHXX8iUNCK>F@<&C!)u=EKW9j&TqhTh!W7Xx23F{H3H~|7T z9VV%Mbm^eoj21U>QZpJF%vNkUAd~km(N11vc_1uHfYnXgFy+F`RZIP(5)59m_nV=- zLOjeG?8yhV|Mgzl<*!>kHX#AZH_YrxjardB2j<(u>_v(6UtniD(mOX(6@BBo+Qpe8 zYEA-FaC+vVs?3ZuU~OAnm$kg3_H3)=OC>J>DmXo0kuMb@;7d%acOCoh(N1~2RQ2w_ z1gPM23ZmX6pGEK{ePF-toYgkeYQ?|=v%#erP+4h?HH9-3aej4;wktMBX}>VO1j;G&2l6Kqao zMZ7j5F_%?0owi41pPK*=oaQ}!)=Kc@XynZf1U0J3t6ymAeaEV}gA(9?)3oJJU=({m zA&mAn)`E>mvGwJXwDaDyE_8zuV1BFEd>F-JET$VR66%iLo3(2}kNwBZ9oM}&_2xba zaKA;%imbcCTOw%ah-QCp>9Y6!sbURHfccGGfNOw5bq&$Z>!FJR?*aUa>oMsb?VNR% zzSNP4GWl@RU5MT>u-%Xs5`4aCr}<#sFs#)1xQ&#wp+%tbt!(kQn{EBHKd4d%C8o)Z zk%oYu2kF5AiYoQs>m$A6)UxJ1H>lVn5>w@MgL;V%%?DmdaBrh6ms0K9tgWx^r;=qS zrpRj<6#`@IQTQH1Ec<;M7ri%MMH-(dl|CJgNZ+}(NJC1n1Z(TyTW>D;@3TMAb;x0^b58tU$b~biZQHCZa|C21!xZ8W z^WVv39o=qd0bnQO3QoI6JI`)Sr6Gw)nTsZWoAI1P2zIfWO!}svcCpPeXFVtZdiam5 z0#w!Uaf7!0LdzxH=mbdO^g2zG04CL;5txGy7WE2%2)fHuo)fzXDo*>KqjB?j{H-K@Po z4e#^K(Y0{I8ihpU+P$6nSspCsB*0Lo-L4in(1SkHlFP~tv0nDCI#&0~R@IuF0Gplm zXKFO>xy;l*w5ICtWWD8rzo|TzCct{9hfk{Lk8KTyR)XWr6HY39Nfi)IfFw_|?F3Ys zx1BlgAj^)Af3P!3+R&&xoNku?tJ(01SG(_(JXOa01jzODPEL*Z?rwO9l|Si{=4gMF zadiS@e46~!%A6g-L=U&}NNr2-I z?-$%LQ?TRJ;0cqCRJg)bMq*8PDtNyj{W3n2LDU4 zPK?O%Htph$9S*Z5Pjdo#0kn-#_x!|d4BPt;j{Cn@`jKARj-J-7VPXOr2DCVPqfq*I z7DBPMmNz84JyzGX#@5i{%*-R*vsOFx;y463F>KV>L#@`c zUugGTdydMsJOPb_Bh0QgKbD6!cJ_O^F1oT-<+m^aZ3Wpq@f=QPfoKE|6F9BR3`4`@ z5VL;no}+55r`VDNR2*nYlFK37@<^+#Y9*ugK0N9+(r}Yo)q?VB9Jk>w2VO|YS&edZuHOH@w)}qBX5Y`T#`o_m@%>~Qd$7;w`2dXiy`C2_i2wcb-yZmH z5B#?W{@Vlp?ScRH!2i)6AhxmYWyZJeWyZJeWyZJeWyZJeWs7RMmo2L4Ubd*Fd#{mn zY*9`3vPCuB%NEsi@0Id@R|s4#uub4HflCE`C2)zrR)Mqt+hxo@4Wz)S( z3fH|%3fH|%3fH|%3fH|%3fH|%bJx90bJx90bJx90bJx9jlII|SfdaV#IRXO&`U~_E z=qu1iAX}ifKuDk$gXb}UM+F`ccv#@~0uKr75_nMH0fGAkm>;ftm>;ftm>;ftm>;ft zm>;ftm>;ftm>;ftm>;ftm>;ftm>;ftm}IYem}IYem}IYem}IYem}IYec1U@*2;3}i zlK`97(>*uHFPRJ;nG7D844x_Sf29H?0>uJF0)+yT1&$P$Brs86g1~rzaROrn#t4iS z7$qQMO^QSKu9i^#UggoFs6fzzG7!3mhk~PM}R-t-uSV{<4ppxm>sg19kQ4mvX~vRm>t(h%&P^i z64)+qCCUH$YsYKQ^*$rmBXDP6p7Eh^voYKMSAQI~{%-f3>g(>k$~y#l+QsfY&`}-@ z>i{)bzt0-v{L*>9vya{a?dZk!efB%;lWc#og|$zR*-!ivPqy>1cx!zpypJ%Y8B&>M z5r32OU64VwPfBanz`-O-X+Xe>;KhU~Z1hrN{w{}~PdHMCcp9(qFtLDV8%UZ~M zkomFJI>(ArV$-ixFFwa6gY3T8!{rvX!u4V`oJ}^a{ACKWKQeZ4?g^@}hGf9UZ$Mnw zbWr*ucv>oE%Em8Ko?}#V^lR%S_1L6wK;uZRLGS7$Dg0%6vh|6k)0V5otx5WQ{6r`{ z2^I>Z1K=nU9c4ffNk-@)`WGtslp9;e>#F3DNstuj)vhQ@zRXdu%>@QbbA{+yP4%97!aNrH4rf(LS(EnQjF z8f&6;N3u+ka(`@Xm5#@6Kkg2TH$6BB`YB1ddZATwXtPDPuQ?#P{&rt&TZttMUf((C z@Noj}he|TQRE^i@|A|g`dy;nP5Q`wRzFX36Zn88&!d7ji7kt`%{vXZx1IEaiSD;Cmq2+&|T6znJ;?6ayT4R&o$`ZSTrp|)8Hj{hwTJgmNjS89w zLYbHYlY}}{#?V7*DaP` zb7GzORinoK$XD$bXy=TjD<9aX+S!_DGmjbE!v`NT$h_N6Ug!r;!0&hOar;_MwoW%S ziM8fgfr_=x3jcZQZ0C0zy6?BDbwd(h0h64Rjxy82O-*g2>kx$=;zuPo@PaS^wGhmP7SIWxS=YQgiY)Bc zFPz`nS7i}SG?|l{dW3o)4zBBe+6T4`V~2HoMU}BE5%V#jZ#|V!6{$ug|MP*(SzG(m zXjR1WM5DR6QxPzy49Y4rivHtv6yKQBvRW0gBGF);q^Xc;U?qhHlr}(9xVG*;Eyyvl zs_x}4R6$b{^|H=r3lQ!c8<-{51+8u}xov8XkrMZj+D8Z6Z(gikvcb{?8Jt+D$kp`C zBMb4Mpp-yCpcbd{Hezk3daa#jEfBi@Pt?2zGmNH-rK$NJYRS&^%S~af#!dE*DbDfuIaAMu$y-;EaV-VRhZSm`6j&e zodG*`Ir``N1Nuh&Xg%BUf#VLx>5jRMp7uTV%j^+*f7=JPi){03ZWR5W{wYd=nu;T^ zZ74c#espyV^v+m)xF$xV@^TzfW7>Z3SE|9N0|PZ0rek3f?uEZAUUIX=Dw&=HV--9% z8&Nf8?Ya{7>v5?phcR6wX=$M>rW0Qhtm|+s{<~l?G-AQksEyS`8|z|Nrmch9)NoEn zg3t=CmyL$AGKS>Pn%Z?8E~cTvrf_s^tP$Mm{jQRDO&r@Mv>P44FIGH!wMxDq38pL2 z^;aVK6vPjMf)DMv`Y;lK@g2i_sErj&hn^!ctqeyCX2zqWlh+L1^>-_FsY4Ywz%7nv-Z=iDr&JchlVHu#NKo<9ylfs%s!RTd>W$`jK0QM1DC>3{)Go8?GKlKxppdbnAEJ%##A8eQP zMExuSN%^3TaddvSW?z#^F(L`NtPCWktLXfg?TZ{#HOI5g8#X~!f%p~W@9b_7~OeI6?00~oI8rd{f0lsFZyFOfFKr^VX(jrXYH z1}DLp#mREYS7)l+bCO`O(mdnpgd3J~p3}pvl%Hei#->tBA$52X z+*GjgIO;rnjGzw!Ln(E*fnmohtY6U#?jaRWxp2k@)vAEpB-p25qH!uP071{D{UREx z=E}VHaQGtYd2~<`L{ge0RGIQf9A^x0=3{tBt;cHua(-AlDs4@v{z*_mY3@o-l3i=; zR^T3@;+GVx9%8ZB1}8!B#ETswVpVV(kuf?B)Ltl{Bl;%~XlGpUt*UY;39=@XL^$KZ z8aQ;IILq&8eCT-ce(w=M>+lG9H=)^^xX0HEM1g9Xl&5AA>4%1?~Ims4_JVubT6Fm1b}f zbVt>`Lc9+(VjiIgXf!s*sP0+yZ)h(LAFtvMOM=Hp9|5}P}A;dPiwQ0qY5uvnzU zwm)4mK6#r;v@8j-B2fX?$YP|=I?eUMdKgaDKEq)@5}FZjsRL~q&QS1@hAR$qtno2} z^$D;|Vcw%Pv>*~CJ~LDws>tTLb565%b3cn_-;^BWW7`kwJD_5s++-fnMMwGvOPLWN zOU<)jJ%u=p|F%rWG?Ao<9K}5aj#jXSe7MoGu=h6 z#PmFjjf-Eqer5^Io+Gqteq+^raWY2;=v;SvQ1Ou`0`Skw-SOz=b+4VPhI>(RfT%Nb z=A;W*N3V}RH}5xho^(|^mG{DAe|i3+yg_oWX=x%|sUIBOe?OkJV;fgl7w4tPe!_dD zSvmz@1}MISDx;C=NXyU6U(e3f&bZuqD_WTBo2fh5e`zJd7(X*_$8u-m4OW*gP4>yu zy$m0uIpPT;&&uQzMJE(p?Dw(Y&3^Xcmrv@J!eo%gH?R8_Lc3Q@`K{(l) zKZm@O@Lj?=f@tWpN6d&qt?FkEZ)!ul#%jUxWJr~Pog7C;I*{ST0@{_(3i-KZ=$)&y z(-&BZC&QAxWE|+sI1MM9aD+j^cI%^`tG*qR>?tZjl!#PevE0#m z>?e2|!C1B)m=vGo8@g;&Ne3o-$R0#zFlZn&ke7>0LAI(V2EJq67KSIg^Vfu*&KHrP zF?=7X6gnAZ61iR)p?!T>CsoAYWVg(N`*f&CHnDG_Onm3qJ=*mZJ5~G<$*!_{QES+L z3c8p|fdP@o0mV3jyS1xM8KRQqB##hHMM_qIH^BpmCDRVs>e;La zK0~z!q|(3Ht6f?5v`RHNd3dHBQ<}+G%L-g*GVRbmo}_I{oUP*LCp*h7CKbZrmbLH> zNI=@{SMIZ_Rgml?ON0^}sAH8W!ud%;yZ?Mk>NzlJ+O(n3gTf&zyJuqCF1cpp0!s~K zMY4nWJVA127-C`Vw_ijAXn)|6MZejl8a^c1p3f)z!d`~Q*A`(J)i}D9b6e49C#;CZhQ#~ z<8us`{{nxhzq9Xo-zHf9>*M{_yW4xEH|m`L`+tvne&uO~KlkqLPu!2ec6roY=K*u$6u^B=o9sz<88-p9TzxOIQrW^ zu|H@()4s$$$o7@(8QXSS+&0zLL3;~T`e}dqrZBmbODEdqrpK0RUphMXe{6VpY~&Ey-*_z#3EuabW z>p1>;&55+en>pnXA70S$hzl&|It3{(0fw5Tpchw1*o;CI9urzHc3jpC6@iZ@=c;-Y zq`a9FMf70JzP;w-;-`kUL+zP?ZTa`A6cbY(dPFChy#D_axy6+AZb5JTPGv|uXwV2bSc`t*}q1*0>otBqc?wR_eASkx{-9^`g z>!XxshYj0;?aEs-c|s)nZ*^@cr>8sCa`?wu5Uy-341QWCVm_KQS>l z;^A*Iv9(NWyrL7w0$o8qz9@Fbi4V71|CBY0$0i}UEHGgh$7W!kVDjO%|G*B8_E zr1piQL)Yv?hYbyuv&Boa!jg_&LGs6?dzcxyjbdC>6zG>*!M*2W^JqF8nNL^gLa~%}cgqy2082@FYO4 z*=uYj1%x~*MP;NJ zik!If;q)*El%dEPF5}MYgC(mnt~8TP2RF2so&%)wp4k}eJ<;+|*gqM|d>g2nr!dKm zD$#dIyVE|mynpsjHfAD{;X5dMVl$< zUJ@b>_06kTu_8(a8SC2`nxfS*A9lPHoZ_0QqUR?e$50=es>s?nZee(>g&{b4f#p89 z|H*b!er>JIoaC_wZ?PqK`6vHPRF%+Gf!jBosq*fZjAp6~tAb*c@SkYf*v-MuUOr&{ z)MdIAHt1GHT9?xYonj8_6#Q_o)vdY7+RXf+ZY?A+9t|(WJ;E9M%f7Cv^ql01Ohs|; zuE)Cxp5i3xpd*84{K=!D4opVq{3y%2B#I|;c$y+!TN~xu;U7bSOFytC+LUCCS35@S z1*n5`@;E#`<3SGoy{f^Oq}`yYo{V9Nm#kdMsMBGu9#&a*mnyY?vN|*LqyyVRFVgHg z>XuGD--%ehqXs6IXR0?9XH-pQqOSCSsiA2PZhXW9B-sO%l<`_eCYbY{9x`8c(cmpZiY z{T_X1f3ET>N-p6Wq-_RnE%Qm7fnM7W*(51=(~BOz9X5swzZ&2vV)z#by1S9L&OU^y|4rfJ2Nm0YM;ArR=@cw zn+eIqe1o!$MK&|z;SfX$6}9mOWH1MZ98~8!aw7ZY;DQqC7Lu1-L{q?HBQrX13tATr zO@XJ>{jTzObF?1fFGtSiV>ejuJ!Q#-@?0vFZi0A?p0H_**W#f!h95{fD-spS8%eq8 zJ4*~d)ZB63<`V~5ug@*X1#Cvdb`pBAIE-sJ3FD}xCD;ce$g~2cUqUlsmJWFqR<}h_ zN;CeyrJ#^H8gI2l&GB^wI1uf+1{TFxURD)p_)dHEO-r@p!&6m%O-s(_o0_ehyFE^0 zhswtBJkEtck^eh|;QO$yfDW|PF~=PnjvvrXWi>B3k7l69Mg)M$a1)5hcus%~%qEDZ zNf6l(g@Ld*KAo+xf|5uLi}3Jz(h`Fh4@uoLi`C=7*ypI*P_{m*jrVh!wxv=I)cUbB0eCZ9MraO%c<}LBP!z7EQ3}z3VsmdimJ2h7@qivCj>IZ-8Lgtq*(F#( zwapmY>5xWY$dUW5>zW~*_)dFmS3ErGS<4*3XvZfjWm$}+6^?!{gusC$xg=f2ITB;gyzBZfM4%AxR>$^iR!0&#Z&7lSl#4-|6?%NOKrc$wiZ5 z=UX!SvgEAHazmNuLYfF*Ccqp5&hc#y`ZL;}5}OT06hnule@-_W9m|zqA*?19;STzwb`p z4&SxDZN4O42hQ}J>|5(=^40m4`4;*rebaoCePet>d^x_5uZypp4{T)UyYKV9<=yLj z0j~&;!k*xr-W}d+z1!eVU=wuRPxh|$HhJs3%e)J{mELLI$=)&EA>JHs$lJx+&Wo#) zXTN8k=PhWtzu?*JdDL^i=T6TK&$XUyo}_1!=SD~l;h9|q%!b@Qt zJg+TuSGuRcL*W?r5cpjSxx2XAx!rEfwcoW577zEjUU2PpJ?gsOb*F2G>sr?~SJJh~ zb*AfN*IHMTtIoB|wa``Rn&z798si!QUw9!`7kI*R!^7bItbO1~?9F-so)R9-x*xs; zcVt})&w|OUO?WFgIcqKaC)8yvgHOTAtZDElI3{Zd{0WA#y1<*DJ4=Hv!F|rRoO_)w zICsO3;Qh`!;YILT=Qj8d+~hnH9t77qo8UiinRB7OAN~Q~()a2wz>nZG=VWIN{0O?8 zL*PZQi?f|m(|7BS!eii_`VROD+@>etE$~eJWcUhf((B+UaG_oaKY^3=G4K+Yqle%l zu$}IPH;4U>eee>w*YSd5x8qUA{f;{wI~>=JAjbO*J-ej^#!7kDeMH}C@d?mZf~ADSsU0@nt%!Ry|pz?p%Q18W0KfjaoyTNtPe zOoRQ1F@YiQxEBg^3A78i1DdfP{`TH7_8Ko3yNySU`{6lnhjFd3&Ddm|2@ij3jV7bc zSY|9VDvfEzWV_wg)tKjU0FN-{GIlYl7!Nn*Fm^U(Gj=j63Dx5i|66xs0b@5~KI0+g zW$S2EaJml0EXMXmIpbl*OvZM`491`_-NZ5zrNEMPQ@d=m$om}lZ369<}@ zYhsRx15E61Vn0Tw(bvR2CT5%1+r$u~-{{5YHhMDpj2?_$qdTL==*H+Wx|+X_V00T@ z%zrXCbl>6FcaIE7&I|pqG6)nM4yRX6FrPN+_lo2br>!avrKfF zsGI08(Qcy6L`~5Dt%={5__c{&nfRrNUzqq$6Ze}4VL0kx_kU*MrzU=4;>RX_Wa5V= z?lbWpCVpVz`zF3;;=3lkW8&K;zGdQ@CjQ;TH%$B+qs{-iiLaUXs)>6|{HuwtnD`eH zUp8@%i7%P>qKPjsYX0XwP_>hUaOnlJ92TZ)*#NU~CpNaRHc#ny{HSul}?=taD6Yntbb`yWY z_>KQo#;^T5P26GPEhgS<;!P&rXyOefUT@-cCSGgeH6~td;#DSYH}OgnuQ2g)6StXo znTeO0_$w1HF>$MjX~wVoDaJ4TTTHyz#EVS4(8SFqUSQ%T6VEsCJQFvXc&>@(n0U5{ zXPJ1Wi5pBj!^G1~Jk7*YO+3ZK^(LOo_=W!@6Hhep1QU-p@i-ILnb>CHS`*ipxZ1?H ziLEBKnAmLMDifPbjG5SIVuOkGCayH`SjK<)qbAmwSZm@66C){s zN18ao#Nj3mGjXViLrg3%G2g_&jGy`QOdMq5KofIK%rS9*iTzFNXJTIy`j0=n# z80Q<;GtM)3KeNp>ct5jM8N8p_<`}%6*=8HOpV`J4yr0=B4c^ae6$bBTwpj-6XSQ;K z_cPl}gZDGr41@PG+jN8XGh3O#`a`lnuyZH(g#-rsCv z4c^~uV+`KkY@-d{-)y4{-rsB^4c^~uBMjc(Y{L!S-)zGS-rsCPjTq5uGz&+_m@Bm)$Z^PTbc)!#46z==S`1*R^_TKH?;GORs;I(@m^qk_E?Wcqm78{$nH3@_s6Q*xhXu7tBTC2Yiq4*psElvo8oSmHGX5WiaRic z7jl(x5uV$im=ppJ$&9S;KX14u6->l#p`4$8aq@LlD)OKd-pj4d zW9Bw8h2)ron27ECtbMgHLd71D!o&EHW&<mDOuic=1;XO^=GH>5Dt2X z^dlbcVdtG9b$Dp*t-n=y4@}{?TU8tMP*_WVN%oa2O{HpI|NDtgTGbwr!eh6p2x)dw zbtQTjLg!`{v~WMZ*|~6=Wo*7r3h&xI%!)u*2%>Vd#-`cruYH{Va*?XZxD?)@A<#v2 zVdxdU4e;*VSb*2w`Wjf1r$K5(8z2L~NNIL=L#wu7(0-M8SPC!C&=X-@Sv6{lYcudymG5~?hSu7g+y@$|}3 zrCY7M`lRsWs=93fh<26H+7`re{bl8eL#;_VIEANGwOXJt11bU$QxF}(+*XS3{AR+k zW2~p|oD^PARip8&jX^Z~i=v))(W3fVRnfjFXcvJ^BaLp1ts%EkT+h?GOnY{?iZ(0- z{UNLGA=V_#M{~I5HL~cAI@CElUG?DQDp9`_^n{Q%Q^4my6v(Se`_}Gp{3f5w8q+y`=v@VJ;G{S%&VZB!&?V< zey4KIO_eB_AQV$AFF&9eaGvY7j@e+XsXnP<#SnwSV*~79Kom$NFL-#=l6;k8L8>TI z*Ge*NtT>&f{bourx$B762dfnMsX`^EN9!P1rN+U`Iyh9&U5QZ)RFV6nCjDUh z?Efe$*b`K-2Baot3a`Mv0QD!@!>O9~#t#R)V(qkfsR;)R@(;`j$HwVncUVINA#n3WpoG^doahc8yiha#JHS)3dCxr4=WS z(2Ov69NgU>Z69)&)uxH55vof_#SNZ=;KPB|h|hpmX5g2x*!j5|dqj3y%$bR) z;XgV3FjFuedhYHvCAQ8^4I{Z2Z5=SZ9tCAu`^M3s-`fj%9DVK<6)7(@l)sQ1iMDGf z!}9TkcB8Ky9rJ$mX0I=|UZbMtr-o$M8*_=5L=7sAfRfkR9OeW!PV9O1Y)i&JBvqh> zOLyVe0=fcg+Lgfp0tDQW)@&A+vmL#o34C5FO{FE5=3d(=)grPZK;OHl}p%C z*Q=^+vWh+?1$CQZvzZ_(z;h@3APMuY6ni9A1oiMRPCDzgUaKeNWs*Ya=HDkBN=XL~ zx~kW=(?3v2N2La-eHo^B;>}RC#_584V@{Np32o3^<{##VULVq|5{^hgB?jLUtHX&d z!5i%?Y+u;iS4Ud7yq*tdH+^}dN;W(Ng_p5rGWuMq6GN=VoI=vTt??cmAG8`cJeBir zQgPezl4tbnH|t1M*1!~$QxrRe>FF3P_-+8}g=WOHwqD=d5?7H&ruviGTBbc{0qqhq zBegg-AK3R>vwQyb1FIiKruzNcbW*v?_Vm<0zD1Rnm+G6D9W-IF9Z_+yW+*|RdV_X8 zll}Fr&#UMoQ+*CDraWBR7$uSt7B2b`nsP8rK+W2AWA87Y%~9zlrLw(R#R1Kl8gHZl zCbBnNgG0t2T8wYOf$h6&Waz@pk7Y9G{nIm$h93Rb(4^b`rZUJ&g${1$Ofu3B$C?m` zbA>P8-Sgthu2azmr+TT)T@-3(#&A|JTgdUxYv^5Z`-v+4_*Bmf!;s^e&H9mv)mGQ* z#Z^NyseAmy)aC>m9ttddQ>7l0>YiD5MNng-?E`aqD&*$Xt>80Bw+`oO-*|U#Bm3=4 z(r!N`DKCb>-G=t+@VkpLNxS}(q+H>_#y6po6UtT6iK!#x5ZDKIQA{|f#b6sFZ$qMY zOit9auk6qohv$dsU?jEZ_kK2Oto0=yk?L~bqL)trs1c@P8vYQ_4qkrslp_b!bXUcW zO&y-0w34a}2n}om3R?zU0ZB!j)QlR5+?1=G)T3kDBPuQ3|BJOdwcyU+ir}!o%aE>4 z57>=+jkAo2{x|$rgAvdJa{u#uU2*IGop*~j;+^OXdS3Tj=UD?;`v8v(RsnB;^!zAy zzT4&cBkuiS*GQKu>!qyQvNk}LJrwu;hnyEWmpHrVdmvvP;JD9mx})6D$)2zuV;^Dr z*mkRJm2I-Ev-S?E@ss})q_JfQ6&EZUXguOd3Pq{g07ii0`m#3gXuL=n9uPVM?a>(r2+#{MK^ zO?rNSN;$Y$vCuGb)dk8jrEvb`!{yIfXZ}fPY)l927|q0>#hnw&3VR0MI!UG1oZ2=g zXlBuyx_>cog&MI*X>3(LHG^T4LH{1xdyRg0OeTYa_pE+2= zr4il+R~$dP%W?9%2KwuS5v zsNB^!zpaanBPJ%1g+N$ZjSjZ?on2g&drZ3!Oc|abS#-@k& z0I2;R;10eh(gx3DHn%f~lN`JN&j1D5xy8Apy=8G~WE$HYbxba$D=f#zvPPWE=d>4w z={8S}rrEwi`#TFyuy|9W(%9(eOG@Sy%E=B6Ie{T=oXzV5eGhskAUVMx#k#QlimL}M z?4{=EigY(0-=fzWNJ+^V;XxxCMywja`mYZcVCM-H#$kD8 z2A&jX2{hKOpjo>HG%KhFgI)=(28aLSq0I-(T5O7RuIPty%Fy%>+&M#gJBN2Uy8PtY zT+VjWFd3GIX2hbfcA;;XIK8u#K~wq&GF4^sa82R55rjQH^OMyAR>%D%>O5iQh}%-C zbH=5yo8sw!Igl{ofkQYZz(K=TFdy!maqR||t49C&>Dkk*Yky%Hdn#S1slgyo5s?b) zS@O)v?tl47=KF14vT;hI)#efD&T^R@M0rG7aH_@U%a(=70D4^nI{xwc<&kO-#dh3P zcES6q-udZHauK1T3-M@K6Q(qn24Qp?lq>4PjtAeIIO-UcU`)DW=8HvVovJ#Vf$8YS z3fnF8J)mj9>+I~}9{Y}bN3G9-bO*J4k*P==S7v}@-iVJ=9a$ejiVg$zOz7#4TL-zm zY3MF>L&wl{VR{twS~J?oC-f}%$jUe`eb~Xr6826hc8a(jzxzwi#Oc;&C^y~iU;;HX zKKRzeabH~3%eLzoRp-9xV5SD8wYBg=Bo+PR&K`f+V(HurOb0T@Q|gscSZIK$*Ope! z^QrYcpMr}~^D;3g4OJz)h;pk?_KGODrm!LlwP=pLr+v>2?foitZW_u;O0j8XMb%uW z$%Mv?8#mq_$0} zdr<_h7WBZW4)idaz!iJxcfD%oq*c06Y3M1*GZ5}_;g(i>Mw%lnIK<|$_QjMql&E+f z^!M!QG5M3EO4v8;&fIJ1-oVdnx_-E0bB}eeY*909VA@69L^cbck%~)HOKTe}l+ngx za|HF5J8BQsTY9M3=`5PZ5*c=Q2G0poq#=8>Yi<~(a?DFR={zctitC_l9RiWE3S7_H zIOXYB-k@zb)=<%N(>e{RSpk^rC1P_C8Iz#6mwB~KP$^SxCDRU?CuY`=3V?}Bv0m$_ zZCx@U6U%;JEF#fTET>+eJ-WkElkA_i(Sbnnnni5Y8s46fUHBAjL+K2aUEj1u9Vrpv zgE?Fi$1aX&8+U5w27EPk_TuAb`a6I zZlSiPzolV2AhlLFwIqPS%T806x+PXkLueoR+=8d)t1R>jp4>ll$CD%suQkRT*Y(vluRdOtJ0k_PCtBCUwkCOsvO+K?hAs7nWpgB@Q_Zj^->7}> zA(h*N)G8U~(a3FPbOjl5!fdN(JUFLJZS2QCSADki0z5C(MBAdrRzb4_UqT*4ayQS9 z-4*{{L)eJIDRU{{O(Q|EK#S_q*=Dx&PvR&ixb^_7Ax4 zcHic{(S4QsQg;Fz`?K7qxQ}zUx*Oap+{b`rKifUsUF@FV9*LKO0pQsm;coBtxpmiP zuq5!7>s8lFu4i0-fK7q>Tz7zJe}!wS>mt`i*BP#pz_efGI@VR~TH>1Ln&lb`ivxpP zeO*0Von1jN?QL0KWPP0VUe+5~uVg(BuKi(^N~WnB%f{RLTPXPugLd{#WG zF{>7A`$buEvSwtJWKGN(l~n+~eebNUSsk+cSx)CS&d|5-s^3C*> z`X>2CLn9>Dm+kB3>*zClS+FOu-}|BW9q;Sjm%Yz=|LA=LS|N9NZ}r~b-R}Jr-kHw- zc|H(555ZH#?Vekp9dfxR?YYo%uIF^miFm8(scFJNm z*eQ$M5T`5#J7uvO;*`Z;r!01ZowC>scFJNm*eQ$MV5cm0<4Vc;3W3W7wh3G&aH+tr z1TGQSDv%aP5$HxzAR+&_Mc`tAiv%td*eq~?z$St71kVgii<4FdH7D+P`fhzisR)C#O1a2OGR8u`a+ zf#m{Wfn@^62rLyiT40I5Q38tv76~jASU{i~^X1n(fw=-z0&@gr3seeJ2+R^F7nmt9 zgTP@-mtSQ9(*&jpOc5v*C=n&J)-uaIU~P0%r@HC2*#|27xmKP8T>$;8cNA z1l9|jEO3&*i2^4G94~O3z&ZimvmE}l@@tL2YJs>wt3ZoDv%o5WCV`khqdyu)AQmjvk z^+~ZlDb^>&`lMK&6zh{>eNwE?EOv>Mew4ss0p2PdzJ>B@fxvu$c>;3F|w_ zU!w&^35*mNAuwEEn7~khAp!*g`2vFl@&pD63>3%}$PpMI&|jdRKwp7A0@(t+1wsP7 z1bPbe5a=$@O`xj)Z+2>1nj0$u@+fLp*N zkR{+0&;=X>cK_=FuL-;=uvg%(0hXQ}GKQq$Hg#SiTHqZef zFN;CkQ3%UiWo2b~FqYTS0#Z&5SyAe3>u2vWH5#stH9+DXuZGozsQtEJ-UWB7_mFAn zW4zi7h->=crDl4(DT;UbJmzb`>I-uQAXb|mgL$9UHd|k02C8j%HCg0rX?1{qEA8`DSQNt(ENBpRF*#fx-JD5tOnl-5|TGGd2kb>hs@>nN!rRKQpbOk}Vh38EE{ ztbF*WPL2qyKkAaua7El{o&~)C~-DQB-1YRayARk+Axuh zmrcoQ^ia@nq_f9C>K?&U@6ZwB@b1?_q8XU&UOSGS5+UzL$Ke@JjG;teD35+rk$hor zWqrIMM6~TTTW@<8dg^WtmDRVw=~8HJbzL~RGPb&9Wt+Zzc}2J0s%oWa=mQWbk7Vt0 zA~4qxfq`qZZp4^zp%M9HZa4%F32|Epof=*aMmU@nz$C`5>l`1~7e4oz%4c?Zu~$3F z%m=J@aG~l~?z*QrVwxQ!WBg{#Ve@Qd8&S(`z3g4)kV`0#O%{MC2LCp%RTiA~s>*Y5 z8c&7|W}dUc%Q4ZwL@2I<5pJ;XvgZ?V3Eo|z%nYl7VcG%V`Y74A3AaYFZ9Qog;Q6!( zGTiwvBNWw#Oe@)*P?--;FBGXVHM|fKf7nKehHX9UUC0{EI$}P=K{04`<`&O8tDQ=9 zbb5hTt3{Q*%cmGgbc$jk2gI7kh05|R!UUwHA#_{J*4_TYl!>nc;ZNJE{8y&uW1=`v zz)&olssjldLx+r@GD=WUur)&2AgI;E8naQ@{Cv~a9%fDxNc*j^mYA)ZZZn^Kx|>N)|DcM=}LS z-LO-^(dmNup;4n{MizpdK{7vcQbLd>iXo6mK?>RhlPAKCN~Sbp>OvWXsk)JRhdns- z{DG=jYtt~)vz`oJk?4Tdbvd@lXt-`1Hl;d{RPtb?cP^*~^t>E`?fW(oP`1H|8NXXY zJ)i;B`B>@&dv@dr(02HbmF#|XqjteVpQxf6)3Z^u6Gf9S2a;Y0wrJ$2twa$7FbAP$8v~gh7Y0DwQD=9?KBe`3})-8l(A#Rgt8S)2f_fgonpRHQd_4VDbx1c z`Mn;p=p(ghD5SKRMIJOkhe0F=!%5hm(LSsRT6a=1*2!>gpGj5f_#-9RKe>Czot9)e zoQ5h3l|)||t0b!jOH~ifnI9T9YHTRGs)@d1wEC>2ZtGz00uc=?4hc;P#-1FWn}>H= zu6nRCT`pg;!Bhr>ee`7^TaJ*?AF#AJPyTOPd#mo17>@{OF7b5muUN;qwxIoRee0I#k8fAmh0@cMQ998?;3(%7mOX22OXJg1 z<(NVx&VsT6QA1`%R-go85I}?n$q;#sTHY3+)Q-tRM-IG270^FDg~aPp-v#uAD_jGT zJ{Qxjq^QRiD&p`o)N#g}5vNDi;2UagI}qGMLJ3ZVWPg6waUBl$LP0r4rTQ^06195B zRVCS$?e@NDsOb=0i#riQT9`a-;kp-39l7KMRiy!G=;;Xg5Sl;Dv6a~UNXw989v>L< zcgw*>ZW{VI!cT_?S{;LksLpX0^c|J3)C6Ffe_j z;tJ6YjlGXLg}7Ob9C`n^$(LHbKl9R)6yI9p;566xniK>F*pjQScU*tcgx-TPX`!++ z7+paDjURr(7wI$_N+VSaevT!MFRTNfWakQfb%?I@oN2BkStaofG zdge)0@|g5kp@mWEDReG{&t^~qm_GX5q>hRwMy;?uS!2>;GD$_s9*dJ_3Cxr4mFnob zVfc0HGNq2rB(16jqXlPU9)y)YkaS7!(FMn%!SFPcg=jaT z3@T$Vgb02wwyp1_x^(jRqv9&ns5CT&6lWIvY51YQZGrZ|? zx{6&NOHyKupLN_so5dj*oF1$+naJ}QxE;73)Poub&TD;*4e_(8yvG(-s@w;pp(~`e zCz++;)leRxn2x*clRH|xi<~r6gM>s#>Vq-(PU8zp3rBtW_l4K^RHk`pC zh!$5=w}K5#CqxWxk=?^AhSCz*4|Rm9I_QmRMN>M9S)r4v7;76YA6Ma3xwglf%sSY z(_<>mI8l{z)K(Bu7a<85(#)9);yLMjMG@+sq8fP|n;)3=Ds47P*vPSqnI2 zcuRm92pWQ098~3Tae`;U^S>TA$Dwi`x)nTDA&?UF8cYw|I+^MXy^I06%g-F1gbHhL>~t;J{v%`;419IK)Jgrrk& z8OQcjfIBR-@!BYptioZDi{Do%M{EVlRS2tm8Ux|JfT-mdF|>Xz&gjU7k~ucNFs?14 zk`3Dmo+};VsK7aqy72N)4jE(yyShmc-3sl2tnjCi$E*chw$&q7SyfB^@{#5#bvSv- z%vph6&kynDxq{RxX#Wk@<=T*!qjTlZ`#(|@n7xup(QE%N+@w+vhku>zu)6z~!I z%#(xf`v2H_7x<{EYkz#^%$Yg!9#A7eL;@lYAt95=6F~zckdTB&!c!0kWC($fU=l>o zYG`L0%l4*=bXLQ+UvX5UTbgH2GYlnWouN*-!-H!>FymBNX(_dK%jao2myIfnFGGYWFuI_9mY2pr}o z{Qh$bTF)_0xbPTqa8-^rU@;kg$54f`AHI3b(F=CC<96jSpE<}?B60aucqDAo~%FnNJT! zd1e-)N#eXT-i#Q(nW`uiZ zA4Fhm05P319Bn(yTaNhatfgB2akkrS>U_r-*=d%Sa}pl&&_z!0z63r zbI+CzI8uxP$j~o;of}nvYw4z0dTVPqvd1^t{V^k~{V4LC_d^&PF=mm2WoW#W*j*Xt zWFw}lR2l_h5Qz*`IuaN@4fAjWV~721u$bcq~NZFPMQ(%K^Z0QY~ z!+^F6^QyjuWo;A^_Sc{_`vzf{1AP>F9_l}cusiK*y#@pAFx6Of2R?jG;}<_+BwuxO z2n}p1+%}S|0hF=~AbWQMP8Au%Fpd@@6;ze41P!oZYcHkh|r}C9mAo$l!JNCMJ zj9hjUdEXR6r*=X`Ber&;dJKePS;Nvw!?3YJKgG3yUH2cL?Zh#34;+Lo4bJs1K+k6h zeD@)|hZT!Z`h`np|JwA!)}zP=r$9CbCgHQ-1}OI0iI%3bD7rDE(Yg^0Y=Bhzvqz3# z7S}hh8*xa~Z&Y9*2sR5K+0l(X9Z-!Qc<^_N6aO&c`;P8KJ5pethK&NW?639ZhTA*&!nZGUur#|rm2;@+dkDIdnSTttH{Y!5KI`v}@yjjI_94%oS~y9c8MY7Gwf=UJtzuuO*CzF?;Nu~=5#h7Ak4v2Ye%`+)C;#Afp; zdyn>_*&IBI05vZK4yfhA-gdUSMQ0g6ayU54T+a}Z?irrO?RgV=2is4Mu<%KvmHMi(F5sgN6m zsmTY!5g<5=hhuDAO`)$5oQvR}ZI$AW{TK{)@3wko&6)95^Lbm3c1L}eqYY<6HPqr2 zzXd!X9EJ{1lbcWs6j!$J5RU3=@vNM0;gNx zbPN3NXaP!*ELEjFrK+^2RF(FWs?wfPRoYXkN_$FGX-}yt?I~5IJ*BF&r&N{pl&aF6 z(!}jb^lgf~Pm%X3@*YLrt;o9+Ii|=_Mc%2%I}~|4kx7ZS5t*!tWJ*;5O{prNDOCkD zrK)nKR8`KDs>+#CRXJ0tDrZVnFHLX)I1cqu z%uYqtDzZkA)rzcAq(hN*McNeMoaRZYWM)#Lm6($fEsCsAWVs@o2R0%M^2| zB1;r$ROAvxE>>i*B8wEcNRfq#G$>N9NSz|Jif|tIqy*=IPfBDIvr3V)B9)3PP^3bU zaz*AVGEWiC1D}+btFGoKGFy>Zif|tIBvo#5wkm)+JJCabJ3G#*cy|1)>grZSZc*fB zMc$&wn-zJJB5zdW4T`*8k((5`QIXdvas!bPRj^Z%IA2}OP-MCyWs01o$V5dZD3Vkp zp-5bjm?BX{B1}{rO-cL#b;TA}5@(AmiL>sO#94Ps;;g$Ran{|EIO}dnoOQP(&bnKo z$|Fit?L&zwb0|@T4J9$w>yjAjbxDjBx+KP$ToPkVE{U-Um&90wOJc0MB{5dok{GLL zNsQIBB({=YH^%x|5@U@liLvsP#8~-CVys{#F;=jW7%NIijCGQ`IV=7#MLw#?eTv+x$VU|U zup%E)kk(?s0R^(bmu2JMwid?P8Rf-%@ z}T=Q)BjGl!08q^-2(qF zwm{7>o$N*HNNre>#pX-Hmv@g0_xZP2(KR?80r?`lJ!)X)C#nXXFu~JY{8$CT-L!Z^ z>-B4~t=I^b18D)O1YQYB_B)DNFj*m30d;^|iZb z5y2DXzw}?O;|F%!Qun*>oA>EFhHSF+c$+ldrhWF{(C#eu2BuYz%zU%bS9Ihd8mIM)~9-@6*E=!{`FRA;6J{%hQi^60DxDmISDR!ZZz90rfAmxZ>}k#UYd+^&h_< z%h4!#LHpZ@=A|F+Fps(F*eo?VqZ2F`+{bjmufzCfm&dtkL5QEqbNFgC>;JT$zoFE}Z??w)U%uc$dTQ?jVAlGuynpu@XS zUUirfCG>i1+0w&9Jy!IF83R4$ck7RxAN6(P<7uU`9V;o_yO6=xbPydy;{_6=NOk(I zz(P0|Pe8Si-#YAHW0kg|LV;FZy0K{{R^0-({_W!P6GrZ($7V!*+aZ^hzi{LWHnHng zi`;rZ(N!(AOIS5^CXRpgzgYINxBRAMx7%o~$EHVpT@X$S_=P=2wk)b%c7@vcb`{$1 zAeQkrW|0gReE8wZu6NV?bJnpkJxtPKS78Rsa-?(&sd^(-YlPGXlrL_;6QB+{@f>Q5 zj3lI%sanadELsp}Iv_1!HBx3NXAx@R@1RVO0c19;Imp=));#~r$B^hD(*OOBTaTf8HvrPZJ;A?Sp72|ZWA)Xk)w;ELw`GR1hBa?I&-8i z8~o|dcD~*{wW;A4w)Zu8FI_>Q~!Ww&M5$L)l&X`obT0%=deBh z`=GxStCSdOXk*WAEVN_nwfFY7ywqYEf6p;&m`>RMROhLexXTVuzH>Fk45%(LLok$W zxbQ-xvmgr!8!lI?)mo#rEmkQd#gx-{O676bjd6%hc}Fsg|K3lZH?__@YR9p2qP~52 zl+=IG_{{q{HvL*a0!5uub)uuVK3hCF_858>tBKwQAtqxve1esE3yyaGD@cBRQn$>1L zq5W8C)VCI&K#Q_EdxJWiYuMBXjMv}5*>z}jf3sb>6g6wSYx2nP2lm--+2DKY8cW1Y zQdvf{Jsj53_hVOTDo9+7O|>akOAW!*8Gn=g%B7eUgTA|F{N0F~c?|mwPsQ8O$9G|0 zXJi-;`DU@N&HWOyK9S82_%?)?Xl z)Jo(=7!`hI(8=SZ0*m}utjIu(1!o5BV|i=4x$JP z=`tj}*k&7lGf5&ls){L77zZsO%@*$rkGB*0Th@g!q^GApdlx2&P6vb?G)lOfcX ztr*r~8j+WOsA5-lpudbCmY%8~#%UfX9Yuale}8R5ZQ1JKotQ;%>IEK%6a5DI4rF^f zma3<9X4=cDmNwASsw%7JmQ~kOmDl1w-9Rw|C_G>>jfcDU3=ZOHcHgw5Z*qyRZVErG z#*e{tWKTCLtoEfFs+Z7k3P{&Zx#3MH0M51`WpQ`+m8-hc!gltz^M_w`p`>w{qSJUnWOuY58;D&toh08sh(uD;?vSbr>_?JBxV)#=)~*tQ^3UXOo6gFAPU z5Vxato{Nr};yZut#4{%?@MZjz?%9oW7u11|WGbu5x-j9vM`5U->{+xR6%4Llx4vsh zeRaCBiXKp3nVwr#lS!A?Rn=APJ-Ac-*wbd)rX+n+N__Js^D}DvbixYK>VZQJrzZEVHE zYBHEavKmy@Lk()`$}4Lc>aIWvBK_Q`HI%KVlsm_L42j%_R7v>7fpl#Z;7->;I`2sV zX?zu&1oHg`TifxJ+Dd#AJtdQdQbWCYVimf4{i)Gfd{!B0_)0q>6N&JN6PMrgR%(3d^5 zjGC&Uy0W^mJgxeowuY3snhd|DzGpv+X~ej)t9y8a#uxkGnRwWw>GP)1mnRyxYBe;}mZvL~VtX0s zkzSJ7h~m}$EIl?bd`8kYb+Ye*sT0qfzF@%uKh>>F6p?#}1Q(lRGZ2hDQhOrxvAE>agm!HI{kc+3# zDN|=>rjf5%fU!A?0d047hl-it4ITs#Ub;-( zv!QlbS$aji8hYSXYwPRb#B12~)smkjMtxmP?Oy$)1C2xc407pLCec|_Ce3A+j^=@r z-KWBb!`SWO;Bb9ax)NEF>9VeMWvezeQ|Dl`SfV}py4n?GRm<4<)z#y>tKs~rYid|m zT}BPkSgB|dV6-u-ZZo!$Efhu3Dypq$u19tCVj zOdUS{5je1><@kS(^!3-lMOBv9*453csUfdR;~+dCo_hkPuD+%QElWrTk(t5a>c)f0 zxm4^NvU6v}X#|_RU@pJF3hj*tm-J)P1-wSzAZ8kChPsd6O>@)1vQ6{R4h>+_v~ML& zGV2=}>|Ckd2tEv>0p5z=s0wdXRaFPqNjgFA=;72=!dt_(2P?YOgBmf?<4G00gID0S z0=Y9{N#C?dHREME zE32xyj=vw^-eG9a(^kRUc~NSs z@+In}76Tw*&xW2sf@FyEP_ZtY2uj>&vxvdr&VwkfMJXD#3)n?(vb?W<55l_XnwnR7 zG3;VePQw{BlzNQ}I$v~4bY4S}`ap)bP?Q zu;an~7*s3gWva@6zN!Ev5O1!`^x)Uq52&B(VS8uRKIj03O!jS@%-_=BUjmVRJu8N& zpsaHc6%Ejq{q&gQ@6DDW(n-Dm-UC4?0^Z#{BXClgV6k>HLHgVVW_eRC(3`{wyEAH)tmDEmDAxz4`+;eE$%E6bq9Ye6k+0?F#j zj%1N7-kCjslIy-*>1rCKf#tApP@S%;E32%oZrDTho#M}fxif=F-}DR0XY(VMKxb(~nBj_{iouFDKnF~v%NiEcRQ`*H!_eg6RXF+z zqo4aS>KYIU&l=9|JJh&0JF=4>zytC&o11$<2__r!(4|ZF9)Dzs(&47+IIE>Emt?xmklBPpCckvA504y(5CMGwR(tesajE%Uc%#S zO&TM59o%tsT{^uRo{D8iD+dNFMzM>h`KF*B>-_CFkEk!(cKksqD6V2ixj+z^d`LA3Xk%VVv)WfwLclK+XHn*zjKEWzG8!AiR&54-Z{*Tnr7R zOEA_99KY=#)xfyJ8OkYoQSE^t7J~>C$+V-e6JuMtu9AlkY=w3FgBS+MPofNG*bH-N zye38yGt3c0ZU6{mh2YUdIJLDXNgM8ML<7?M>5(Kr^Z#>#7x_|0Q`3_VBv&SWmbf~R zihnS^IQGrhu9zLYE!q(Id}Jf`_P;TFp7RN3Id;|W4JCtj<433eoo<2CEpWO8{&%*( z-irW^ru!C5!-T8cx7fet;NI>o+MADd1nthu@9f@Nwsa2_>myX%-2*7wi^ZOyZ0kTz zUv~{=UE4P1{QE}4z590W zCWjE%*nm%(L_2e{tnG1Z=N-}6G>>1EIxB^ZPRhL8ABbmxN#PoMj z+yYBmpUoohzw{u29N4h}mG{F-P-KV)4s_#l0F$ffaq!dC8U9ZugB8Nw!HQmpLvSp6 zL_fA0IJpkrGugLb@|n|0(msxw36fXyo_IhMqQ0Kjr8J&tCuv@nt#Mnnr|wjIFQQP+stXS47*T^rLI$}-KX_(6cLbq#g3 zWi@qGRWxC(*uyeB;A(F*>%#&(2x^CLJJ$1g!y3%GuyAuF=El1DUg=@0fWh0dy&Y& zt1tlD`@0Thv22H^e+GEC7M4_Ai>(=IfPky^@~zEg&voMsXM?+{Ft?lROHW3y zZ61Boz!2?b&~fni#|Doq!>%>3R|HuHXu^jQbi_O{eZaBieFGH8tC^RnE^A0vBf!r8 zhvjVg^>*0bpi#W+aBz1T(0_^#Jv5oe2250tvGk>U_o0o)AK1IAZ{O;np2GtO;&fv^ zgDqi(yAQ2F{?R~BWhDYn_4BZb0gPQ=RbQ5=gVkb0(Lb*^q<-Ic=s?ARe*4NwL=`UZ z)lHjtKF~aZPrMywb{J6;fKA?Up|`zn@4!w>y@nBQrtLQntlZhV1XC*PE!(|+!-iF~ z+QSi415AI$7m7n5kD4D35k&Y)F#;`F6#(S(VXVmi$#!CXa^lAmmR9DpN|rJ zgmfsVhS+{nA54)ZX}hwBebJUlL~@F7?d z;{P2YDHXjeM(Y8d)iamJybR{8_$=~(L%Yz^m{`(IHR@T2J@jW0EgWjcNzLjRwGEY6 z;Gu7-E~|qzRjU7C6yH_R!$0>9Lcx7=c=kG1HQq9R6Ap|WAOpwVn%SLK3}toeVZJ1tM2CQtA)z;vDyVQ>>V5Ky4xeaIUp2g#84dN>p?=pVu6VTs1j7P;hHlq2@Z1=USCy_#!@~~@kA$$_&OHnu24&rW$KWSmJ4CMTarz9w0pcs_AQqAL-Oe!|z<2&X;#;Lcb2ZEp$on?>HH6ebBN$VGr7K0zU}6C9u-^oAn`Uo0al^*1yL; z#rHTK^I!h8VCzbMhCkAo0aTGLhZiTHP`Qx*$L)L4?`%xnd)ASkuDEwKHn8+(c(LB0 zsIZa*RG=jlykX{TW^gccv;~b>%?h=IzF_ zAZ~Iu)*>m|pW&4iCuL-&<%`F$n$kG$p|!ug{=A1eus5bZ!$DCeRLasV%R9 z|I$r1HbOP((S}T9s0R&`&P*c-^9m!WsDaWbMla$u@ni!XhoXqJII701E?wY z=*P+C{6;O-myryfemIykXc?jw@lXwy7koz_Mz*DpQnYneJ^t%I*msut3<@9?(cyg%n;4-jo~XOjjRSjiqr{ zlZ(xdGYZmzJY6UVWpOxX8hM!dngL|&Bo3n{TPBkvUQTtQMiOQ-MiPDFxK~h(vNR(X z7xqC5T8`}sm%bfiRm-SI8**?@@Kx2`PA$$?X)v-B8Mr6d7KBODoy@jOcXpKU3wixr zfs7*koe|fCQ;YPjG<+Qi^kd zt~6{|&7&n8>IJI3(q5%0ZoY4{qzT(tL!XgbTjES|rO6kbJcrY$MVrm-M7do~(n#^B zMN!FJu0mitYbXR|zBpl5m?%UM`7cHxnz6<82@Z-h)>YTB9F$grE^L2&f+<0aG}5?C z$@HU|{}1_6_osSOlQ93kDmg3hOyZ_QbNoeQ0c?qvU>|^MV;AC#_SZ)1BfpQlFR~#r zA^bSb0jP1l>%7LP5B(wZ{!nKq8vIOfe{h!lGy6LG;=oIRy91j7G3#M#(3;_Y(BI=f z+xI2k5KaHrVoyjf-i8t)zfg>K9C*9&d^OEnjU6DN+LR6DM9^1Cr1VwMIZ>v^+Obij zKf{STPS6!7Jyu+fj)9A7u#qIDbd(X}1YBv-am8oEG^V~AU3}pE-`$H%B_kP5L2+I| zAZ5t?w^K^Yv)Zu#q!$;VajTFm>uPUNxX5g(*|CG0f+Fn>((|aN;AHx}Q9;~L2YP&ZM$M+uX;Oi}S3qd^^)@taXLzjKZe=7BUt zX7d{rYTruYIEUUTb;U`$rHe|WH%7k#M_$-2r7Vat)_FRQ zCQEyDt;qLI&cOe1w1{r1ZmQ2 zMcR_-%jN4x94{L=^W2vcabqnU89A%F_#pl$ zfoZI;brlH|lTreuGf&N=Oc%FzkaTg6CrU5QJsN4v?Ig`Re@|l&k;&B<@W`l1QyYol z6?X?q+@vP>pM-}`zT$2)q-iBd@nUU~BA)-`SlehvODjq7u4+Jvr$5Jz=@`vuYavPE zl=!PWMqZp#(pu5Ff`k=V5?)K1s0d3koz}6OL~*qm`#1GoBC1ILX2i8OlQ`wy)O4NF z_eBSao30yG=xQQqTvFh~lq#TjNnUPT6$C~zx|Wep?@Si2=+TUE!Ed7|9ZN~5cTEFA zJ&ICfjK^q8^AZv#ehR$;abosk`6)BuY$P!SrUWt4ekV62w@-0QqSxE0mk}w&c{?Mm z73V0DA$TU}4c-N`A|~iYJyzq4MRJ@3^z=$$gLei}^h%*ojiyB;uweQMfdcTyn7*3D zG91bXDc+z?gSYdFDjhSL(7up_dHqu*gh}HU>7UHh6Q?#78Wc&BIl#CK%Jk^!dJ^h& zdWAxZc6vr&YaIzJn6jfZOyX-rOxcZ!tiq{}Yyoqpn#I9-uZk4AIA}Da6^B7G2t~ML zK95LP=Jsd^E!vNf0c3`Z_G)f6Ue?n~8CWqF8!s-7WAudP|7qWiH2?2OO-p_!`G({r zi9aUZomi6y#_x@1<7dad6uT-mAM5{bh)$1uD{@U_cKAo(Yr|>hx6bX(7AF;YBs3H{ zEBKY*HNh(T=k_ssMc_|?cLf$$Pgz6OO#f5iU@T3VgrhT^NI110{AI|x%6!A>#%5`Bz@d+RX!>`JzsJy#o zqh3;Uw&*n*owTqv#}RpnrJpEp9IY$rMI% z4+uY%c(XCItvL?W3-V>@|NY6N9;5f>5W_EwykMjkZTO#wyy%37&K!sNIceIdXWc_f zc~)1(lQwNMt}Dmkepv@n4diM5@gyu86ku5n6?iW}nWO-ENR4mkVYg>+k{ak|0 zVS3emBE6_Ey^+?Qv)NO-xfYOC=T(y8fR53X)*OfZxz55_sG1RZTJmy5R9hHDY07cj zUtl!9nnzJi4x^2ZEYES=zaTJE=hcz10y9QMmgRiZR9=UOrt+xB$sMAGg6%jYlf%Jc zOb{XsRGcxH?%R3|N%MMFdL@x|YTngIZ^5aV-f1{Gptc-YtY!cidm3)^V*S-DiFVI$ z&QfZDtSku&jB^(aqas~bkyx3i@(Z5wL{CFp_4-b=8F2eXs*LNObQB-eaTxWr(@wiSSv*QYqDU)?HEVdL7bt-bQ zZgi^UAip9dv^#T^P9d+$^R;83glqPB&MiIywQ*~10<|q;SjNHDgUb z$tzgVsP^`3aWNjFC(HMdv;t2DY0|x8dOEEpEqh50mx>t6f*en~jcHk?JD2s5qym>& zAnBwo(+FwbLqfO!gOd-@=*YYhohWX`Zj_?Em!uUe1wxwVHC;3 zbx&$j@^8u8l3htB@lc{SQ5t_FelR{g_C)M(tStIe^oD3A^5e*>BQ@dY!^gsH&VM?$ zIbET@hwchp7Md9R64w4F+h4PDc3t3wz-@uefuQxEwb%bo|K0xW{uCbYKlN`*j)T~e zOGt@W-tQ-;KK@)nlVhIaxV9v~E9o-E7r8fxfzr)64s6Tf2FvpVHO5-p(9`;^9EY?e z`h23CaYdhvV(!f$rtO){vd|O4djIV_0;9LBIgWKp1Q$=kXeNQHA|kkE-M>A@fo_@7 zDOuuCibJ7|$5C$qkV=-QMG*kfOuN?RIOZ)84JAu-0*I~Hh=$RL^*IiCOS(ME^ytKR)8!3r z&Z)?^yEvlcN*fkoTBc`Pa~%5SYE=$ZpD3${P_>b@JjY>gap)||qa|ZGbfYAlISzVD z`4j{p2}$B4<0+pq+Oj^EVZZE7>XcCF;c=o#qd9H4Dv~P!4wmbI<3$BHjLvMyrAba^yjk~nV&gv7}>QA7yDXiQt~T>e%!51+r)Gd>jO|Fo`b z$W0+>1qO&Wla?E=0h%7(k~@b4i(^%CbCXHBWH+#M&zfoR*$sbG<>+0x zQf^kafD00lBPH)Ut^zKjM>PMh^4;T0-Ja@7C6bRNN0M_APbH2ds^Y(jAB(SxC$RoM z5}OhI8X^D-Bfp5;8o4O^V)(7$70%1f$DFKl4$cL*CUjx&hrzc5SK2SxciEk`Kk%_Y zf8cEEaqDVpj{j-@P5#Bczu+PNt$(dKM4|yzJRp|_OwZ^x_HHmn-J5b8X_hoUR3Jc> zwB;CSemYvvmQzt?x5QeBk@-e(`RDGa$nj;#8dTCG{KZh5R z4l>I=2q(%bHY6;X!ZBv=#2IbpNl+RGU@)4}p5r*Pgi!I4*eFXry0{RkQI*ad2b#SI zmWERCcH=>?MrWFG9Ch|aR!FGm%*i7wMoC(79CDT%b^cWEvJf^uKKa)9CivKvaY0G6vnrt@$?BC#B zpew3W$tX!nu7{)*%omZTG#-#@RHHSwi$oQ~R3J(We@zkTf7<6X<#uwDxz(Wjk)BQ+ z!*%Ilq&?S7V!RebSy(dtD9)m!BX^KE*%Cp$m53|K6B=n-bK6N;!KAn#d-c>N#YRt> za@$C}>_UQ?8(cPjDl>)T}EOAnX(vKz~^ZG`5N0D|i-)Mw% z<~ETKNtokT@?<@aX98@rWp!>N36;%AAQTx!@@7RBG#SNNmD@lPWirSTJ&IHGWKgfd zHs{uJ9h5!ISoOQK|Y%c4ArQN;At=tFaE4aq84(nBtgAmK5V^vud@ zS8g@Qkwi?q6XeJoWPI~EtqSXNt4ONELzGnM!g0n!8mD7xHSDj}n(H9B1uhJ4E1gk{ z3!A2@msjW7NmhYHAvs4{uy~8o_0UbZHf~F=Q!J1;hEsIZi!IBoBr&qw&yD9<5FKN= zUrA}twUU&A6+5g@%jXqW%w+0Ux8zz#oMdC-r6A6uC#RB)X?%^E|Bv`mA5C>8|B?Ji za&t17_} z$g0Q~ZDXCT0?%`hTW~Jq736>xg>xG(P>aD`c@A$&QXWh5EJ%*4*u@O3Tk{;>mb`Q& zRiYQCR*`9(aeJP_-m+Gr#LJAP$h8tZDO{81sJ8^CPZU>t=8+kKyYd|G77)TBJxO5W z0wHEFZqIYbTf(#~)uT$qg=vjvZqIYDTTn5?6=aMShl-7HttMSO%J!{ImRs^Y4vU*uegx35!aOG2)E3q zS)4Z;?4$?#84X#T=g77MVp)u5*QKHZu|`SS@*LlmX(l8Vx zBd;|-iM*oV5tirCjw0}gQIWR%*(6Kqn^=}dMT)9#GV0NkFJWo!rWlY`kOF#g^lS8D zZT>70BjFY$M!Inv;TEGBUHLOfW`S$Nt4Sw}&$VeyS)D(Fq!w5hqzXVO+QLldZp}|5 zi3QHGK;o%6OC!D`KY_%{{FRpPm&zL z#gJ2wC|W!&*0X`Oe1arOSVl<{B`PW`W7KDLK2FkPRY6G;^(o$+Y1L`V$4Fv<<>8A( zb&9e))32@hC`l`Djs?<+aE?Y+b3Q_{Bp-pl)uSV0OsUP-(w+~K94W+RIUe08u0F}A zNORsHaWeUYI4oQVj2vt7sTE^sKE$8rZvLv|NW-5j++y@$RX)hy=4O*CA)@z1yDqH` z&3T&y78nw~PU0A2>|bCyuPGnUFE)8H?**b>Oyr#01sXBy^A?GbxipLMta*)dE^Tz8 zCGRJ>ve2jG${c;{g+8MX?Rg)+BBue+#u*TWg(}g9BIlY~En0Hdk~mp>P~t=_#tyj{ zPf=ubx;*81kZ&&VW5?A033&f4f9U7@ya#xX5 z$t&PC^k~hgi^%EycqTWcO=>q zR{Vi@Z~WZYw_TmV^&3C7n{htEu%yU3o;=0%%nO2Hi2Roj)uKDuz zJV(U^;Ih#1PaTcv3Kvo+6Aaam1) zIE<>29ej$bDP{pV&+&1IW}hg&*l4yfpw)Q}j|VUOPY&y-E;qR!_0a>4{&*i5-uqF-acW}{gh`DVsL?v9dpYgoE0 zTof6jF{4mRzKP_COH}ei1&VNqTAP;TmyswjL?uda?nw>Nj1TSkr6ffh>xoi|bF4;O zTYd?DpPT;2;ykITMa`~_%B;vYk~Ar)Vribmr!h;a%y`qDzl0=tVKQZ434SOJCL6Wb zn!lLDd809u*d%IkYS9>@C2R7FNxZl}d^f~WYPU6ltugtHw&TuGW&T zCqdqMDtgAFM@7t2^`cs9zK%o{gl3R#B%NGDXr^(tT8eJZ*ODx+1Eka?PlFfd0QGA0 zihK<>m%AG>W>gR-F|x7kPOn0*&sTGMxdmk>N*cE-RSU{3`3%V|n3ZE6C{LVa%#=X0 z|8{%6ibNHx6C$%pLU_fk6B-Ta$frqM!ECf(i>6{{qk0n6l&>Ut1#1_`0unVjdEmwj zDINI*B&J}o0b)c$igjdqJXxNvAbDPkqU0n|k+Cew*mq05oCJA2Vxge1J)#lSl%G$c zB!wNyR>&N2&gQZ7PtwGue^&XW~7Hjfr^tq4-Yh{`Y0n|CeL;zw1!{ z{|lV{w<7#p_+8xmKr+QI0Lk`h$`s_FU}xg9fn8qa0(Fpzw+E#s~@PjWx8>OPz}UcHp-!A!GkQ<1F%nu2aUF@8s&I%LFfXbp>%4o zp$jwcbdGZ1SrW_DYe~4F4llD;#J4;^DiE@gI6&r17 zAN7QusR9k+3Nki}T<-s)T14BD=g_l+O<9~rQ%)&tYV>7q9?@veP8TfPqb~m=h|s82 zSDwSv1;GvEH;Gz}E4X2Ft0k|Z)o#(G`UcUhv5O{6w$S=Kho}pz5-%tkHBPHED$$zf z;Ix!zsaF)a+>AtP^H-8QXg_v+rbEV9o=3mNQwgmn-YfEl zNTy8LSf)p<#)gg>_-x5vL6RiGp(J@!=9H5BwDa1KKSTcx^dfw&k+n5HM6zTO3t0sjqNg^A745p5TiC6VR^nyK zJ&vL$GiEK%AK=gDq*gkSgJq6q9;cP7JwM1V=Wc+i1j)!zT-d`5M62=xB(A_~;>1+x zmZH6;)}pof{Uor!G$BwLZycs+`nxmVPcjQUae>V7cw!^8HNTI9$}AQQ39KcNkRoQW zMq}FYd$|?e(kCTLKDwyVC!;Iv`96{+^E#I1(Ul_Sby{Ou^Lt2~#59yR(U>A)8b)2Z z^1b|_Zr!qyCF(LhZ|LgGZjvfhhDxe5-#84;bZ<*OOERV6>qMDjdsri?Dc?h)WFiYu z2*VURku^%PHNT6*6fE6QG{;@|Jhi1eqct7*og`i|K=~~_(STwTv9;Q)&v%nNSxZpz zq^rjp0MY(yOMVB*E%1)C?(H_iDaHQ{8fwdLC+V_Z58gWCEiNs}5>3x<$ZsQQ1-`aG z+IW4f5!{u(j08)z0>7q5rN)=7pkX)7|0l%G@TDF~?N3cfemyywtWW$raZBPNod5Tc z__lZ?c28^@ZaDq#bPJqrfzvH;x&=`WO?U;l;tDAhf|yj>bYCzsH*qk z_~=xQHj#K);~Y=G#LWHMN4e_DyW~JZWjU_6B?mK8YZ_HWU+y{a+?<}k`pNevFf*y9 zQC08dR%o3l=HwMxM$GzAF7)!wb}3y-W~Jkt?V3q{$0%2R6)X>8$2$qW6uCUu*r3ul zI!C$c%bUPixFOSc5;)BoN6RP|eR*RgBvg8K>{y9WlGahK_VTV8kSH;dB32EIhO~}y zX;*>4L6)>#5e8@acl9WjbxAoE)TBUG(dAf1V#_EOc**iVBo=PSH1@#+dfwhV%9UN- zML~%2D9IR$f+hq+^Z!TuM}4V3rk+hbk@|G%1F5&Au1gK2cBEFN7Nsssm8L?;7n46r zK9zhp`QhZzDv9HBG9lJYrYb+NVh;50r#A;$Q zVyWmqqQ8kg9X%fXX!PCD8>5G!J<+w%i=*?RrO{yI&p3hLiO8oScSUZ&Nd)^Nmqu1Z zsw2}Q$?)HimGGVL7sK}1e7ltQ=ZRbzUv(CRc4>@-_H#^rl{my1* zxs!3qoJ8nvpX)8T?!DSJ=_uVdOQuEtn4u1TPIP z4^{=w3r6j~*gvzMv_Fk~4sW)vvG>{=?4@>veU2Rp{5kM!;PJqNf!hOb3>*pU4s-@C z4qO;GJ78IVu)c3SX5DYS$GXwF!rE!AvKCsitTX)o;eQ^xBYx3;FFN4A{F|6-4Eg+) z6Panh-V6;BbC($2jl#QF@y@qz5Z+?Ld#&&mDc%hGHNv|{@uu5X3U8s|4GOQp@OBHY z-taCHUY+5s6JD+1wF$4r@Rka%+VC2LmodCb;Z+&lY~iI1?>ymE8eWO;78qV!col{h z5MH_Bl?DDLy!nRrqVVP!-XDZ_q2WCzyt#(=GvUoKydMg0w&6W3yjh0#l<+PvyvKz% zQ}Lz+9u?mChWCi@W*FXQg*V;s9ui)e;eA|q(+uyU!aGm#&I^24cvB7U9^sv9cpnhn z6vMkqc;_hI)W99Wn{0Tu3$Il1&JDazc#{n8y}~@#!kcJ#{lc4Ic)Ns`GQ3NLmo&V!!b=!li}2!xcZu*~hF2@RsNt0hFJgEz zg%>uwDZ+CUZ*t%a;e`y(V>3a+3(0-9;rWCY&^*gyN0#Av?8t9;9y{_Gp4ic~h9zcn zjbfErVnweqtY_R8x!SP4?Xs>iEHSGihV_Jd*I~o@ip#oEu_jq!XNL^yi|$=l7?xPx zLBo33y=z3V&bGuBhYjn~?p;HQRbq*CUT#>QbniN#SZ7%ex~xIPI@1!98!#-fko|`B zHus19hV=%Qwa>7wb6I;0>nfMkXIMinYmZ^|xvXBp+TpTx8`egbl{KtYF003|nqAf| z!&>CBb{ba3Wpyjo8P8$TaUAuB^I(- zv;1Npn-puJU+iO}VZGqK#0JCqoy%HpSYj~i4C@!}U0sIt6PMMgSQGqWLu(D|`|e$9 z3`@*vwPA_7TBTSizgSv_VSUq;)vj1czZhSeVSU}bYo%f({7<^9R>g|@#jIKkOH5&f zVcqNgaJgaK>9U#)>s>CZ$*^v5S<4JdAlFjE%DHzfF{~?Hmd0;!zu+hh-{O9OQ5wC) z{eq%2c#Hejxv~}+@q(c=bc^|yx_4>h7W0cKXy6v}i-XX(E#|Luf2d(w%rDlVQCrL} z)}cXL%rDlVFd)Z}atQPT!4QZ$r@%`DoOCz<2Ps~aKwTMp~k;Z9ZpIDlPX<^^z|8MNf-XLqK(LHBE;^b(po}>E zM$iO;WW;fi(F6iy;MkYC_YfQ-j%x%H2#gWObq5m&iV>&9{S^T*;9-D za_=F~MVtvPhaeX?mTNB)2yhW6>fS?ei#VJZAG|O zGr>oL9}T`Mctda`xFgsetPjo%PO$%BKWBg2e#HK;{SNy&`+&XGZn3NFGCLl4Iq-|X zQ-RM0J`lJy@M@fQuqn_Ks0^GN2wN{&Ke3*$9$-zPi`JDb9H2~XqBrtrIkr-5fv z_*UU*ch8u;aap=;p zJC04vYaqHbTrc-&B)TMAEj$fHmxQZ?r?Kdgush~W%xf^ZBwQi)X*Ajxo-aHNM;pWL z=r}R2@#rPtIdY!{q?d#xQj=e&^zY*EEV)lZ(#2tSl$@B?m~?SCCHHAix;X5Pa1-+y zl`eMvDfekuy4ZP9cp8^3c77{74NMn1KNFrtri-2L2~R`Q#m-a0)7W&e^JU>_aJtxe zSa=$pE_Oa4JPl75J0BLF#;1#&_X|%0)J4uw;c0}r$nn^WhNz32H_Ck)qb_o85S|99 ziyV&~X_UIi@z{}usf!$s9ci4p$nn^b2C9o3j~!{GdXeL?BMntAa(2kOXsmjXvsHK+ ztX|}JY)hlni=1_GpN6X!IctQc@#;dyV{aO;E_7DPebq|;7CIgq)R1+dvs~`en6<(2 z*rf)o4bD=zPovg)$78D+w$?imsmW{HTIXCWztzCC*74Y&My|Dv$7VEit#!_m-)ihy z>qvAnufc1r6PNomdaZRNx|!GTwKgP^&b-F2wV^-BZ#96e4Lv73jbLj-KNg;bu(hG5 zg{LuWZRl&l(;&7s^r-MOimeTOMtB;=)`adCp2o2?A&<>yAX^ji_!*64YeMgn-)bmZ z6Y|)R#S40dF+VbEb}~eM1Yog9y=mP3tn}|V@CvPnRlhU%UOmuB0K`N ze4od*2--5QU+yDt%e+0pBX|p5Cgia<0=UfEDfbb?WuC_d3FI=*#yt*d+m7 z=DFy6VxFKbc^>?gR8yJc(}RfqoV547tx|coCPEyVmf0!n;QEf`Y?xuQEKrVY#afPjFc7 zD#QDs$U9?o)4Uqw*t zD5vpXMNsT0r}1A!Q0yqD@n1zy>?o)4UwKgMD5vpXdGO8hE*k%p2VXBdjsMDnVp}`3FkS+>WHH2#}qe?Z=)McMf*`wro0 z{5Q+?*p|kBv+Q@teH#DGvfm**jsGsNJ@%&Y-v#!~a-YV37uX&f)cEfL+x2g!=l}m7 zn*U#?F=uaLi`$RaY0TN1=oFsDoV|%w;c3j-n`jiC#+<#0I^k)|*_)^kp2nQLi3^0M zF=ub$T;XZV*_$}iWVlVdPGip9iKy`AD4pM(u;sTJbMB7+hwwD!+#P>ecp7u=j{jMB z8guTB|4w)sbMB7+N_ZM`?vDRNcp7u=j(=Zx8gpjj-xi+6oY}aHBiCunnT6ukbYH+!24D@HFP!5r4bzH0In9f1~g; z=G+m#UU(XF?ucJ4JdHVb#D|5aG3So>Ug2rXxg*{!JdHVb#5YO1gq8m7h_4o&#+*Ci z%Y~;g=Z^Sd;c3jdBVH{$jX8J3=Lt_^&h7CT!qb>@d)#9)8gp)spDp)k%(*>2!R3u= z%(*=t6`sbN+v8$KqZ)H=kBJ?PYRtJkCU!KcG3WM}*wLuQoZDhzN23~ZZi_u9&()Z7 zTkIFY)0lHxOl)gZW6o`{AIg0ib8d@0BRq{cFN=x2jcUw!S?rr~pT?Y*#l!|jHRil5 z_N3gWG3VBp*yX6koLgh!^G7x2+!7O89o3j~OHAT6qZ)Hw8hcEhp)u#?nAqT`#+;jD z_sM-4b8e2^CA>XK|2D@Y);X#%=jNFB?NN<6H^(H_IjS+|=9tVaM>Xc$96Kz}(3o>` z?11nz=G+|Xb?swRW6sU7ZNk%-b8~FH@HFP!9BUVz#+;jD%Y>&f=cd>~;c3jdDON2! zjX5{PDukyo=cd>k;c3jdDK9aap2nOTqaNGRm~&(FMY&I7&W+I*gr_m*hN#EhH0In8eO~U< zm~%taV}lxVZitG18`YR|ebi%@8gs6X3U(gVm~&m!W2+i-u8T_CW>jO&uIRJ!E*f)o zMm;vDF=uDgV>23ac18s|k7~@>8I@S)sK%U~(GSZr8kK!?MkUrcdWqr5+;a3{!+VST zcCq2zAiPC}cdhU)GCY~%jV?62{c>M};q?fw-tYv6jn*mN+Nj{L(OSc6m*3VHp7@#3 zYQt-k`!a^NPA{L!e!e`}(p z@>`An){8>uRgu5RZ#DkwhRz~&;PvgIp5s%Gi{I@c) zP43h9Z)IeY@HGBg8S&VW#(yg#9y`+bZ)L<|M;iaFjCkxwH2!Oehz;g7 z{%eT{PRwikw<02Tnb-JlMdS=uUS8wBJLa52QYlx-0eG)H_l)r*2AJpSmV>D0O*iZ)#WS zvebsu>QrlLDXIi&QWdG$sp+Y6QfHZNO@Y>|7lZTVT$^K+Exh=UVxi+~nxh%OjS({vtoRgf9oRT~%nLvHP ze?1&xub*rNYE`B<_#>d+blK-^6|z`(ErDv9HFy82bz|7(N`k zGxqM-TX8nRYhu?Tm*GHc56(&49P5m&j4h2VjAdf;Vl!jsBDWzC3r7DL{Y&%@(O*S> z9Q|(espwatk3=7eek}UI=xx!X(VJ1{kdIy!9gglpwZqovx@bqVIl4Gn6Rn8Oik=sp z6ir33!C&O%$P1C*M1C6iUgR5*$0J{id^&P} ztcom;TpX#5EQrjGOp8p4Oo)UdK4eV%Dg2x8Ps85}eLk(D|qH5>9>mrSl`_Y3E7jG3R0D zLFZoQF6TYY+nhIIKgesHL(ZVn>ukrl5UZUP&LvKrv%s0-On1(4&TwKlE8_2=7el`b z{WA1y=;_dtp~pg>$LWzD4SfLl81D?dC3IsbA372m4($u=3T+Lo3$=%uLyJ+7Q4yLI zIxjRSlnTL!gD(eP2tF75Y4Cf&Zv-C?elhsz-~+)A1>YY$7Q8hu9DIH7`rxaAR|MXV zs*T;j?SW&#jltEymcT8+Mr3rP12+Zd2B!zE3tSbP9Gn=81}*z<_Mh$F+CR5{V1LVg z!hRHISbWKT*nZHyH}HUcci=;TZw3C%es5r3;OF++?KcO05cog#4cO)K?{>}(*oW=Q z?LNCZu*=?TciJoM7^*=Q+Ew4kY4_{y6 zOlDe(bQQX<+?m95rgOH>=b!wF0{^!&xq)^$Q@I^?^z!9)`zK7dSnp?gsdFy>dE;)r z++hEhX{U8N)3weN{`0CVUv}8fGHtbPW7=f@h-stsKE7?yF220T{vp#k>%Gj*?BvTT z`v*)btoJbc!fw8tYk!~V1=hQnJ#znOA1Tlq5LoXOO&-pTCH7QPJHPc!vf?_lb4&fq`$E~QKVKkV-? z{k!#cV*CHLnJ@q9Ol0~O``b)kvfjpjesL3DzF>cgFJHh}Fc9)b>#a=x;7nll?>6w| z^Y%BH{>HkM+0U)#%U?PvroXVi!R%kG%O zJCm=sF?n(&|M6=yl;KmqX1$T=6ZY4be${#d(=R(wrjOZAF#VGCdZx#%o0xvl{x_yy za3YFYH?sIgTKV$x*6Wx)Y(LKQbJh(^KjVZIwO-5g)Am=He#&|c(}%3Ubl zg)bkpzryqrj>GhR`^!x4b3#n-wIAc#?_I%{AGW{5^g~XN={@$NOh0IiGW~#koax<; z&Gat&i~RFDm-FQv_7|AK>X_bcKf?4j`}0iSXFsf{m1p{1$Ks#AtC=s4Iew;ZcX*ie zzun65^;<*#$@G@cfAH`yZtwqC__DD)Tp z^I#)i4%nY!y4SjzX1yjR(^a8A^Pk%m@#RYU6HJ#|S2Ar5{fYm)^di1oVt<_JV(SpoMaYY! zXD?dFm-Y4od|BJTm(|u4Of#WBGP|;#FBjPNGo5E0WO`xf5B%o~>-ch({V}E&SR>4y zS<9ExL%(M_%^GI*c{O}F)&3~c$<`3lQlJESqta@=Jj=e1>6zB$%swN-m#NTinI`Rf znI^0Q{O5QTUxw|E@MSp7myR{aG!%NC*>)vgTK0#T`mF(G`xelp@1LRHF#U)9A!7Uf zQNfpgxAybp%jJCe*U)oJ|67CV!sC+&_hWt*Et+=?nG;`Ohz0$m9=m znfrTdFJJy{4qyH@^ed*%+aF-|^RxN#H&!2CJ~xZWuPwkZl*u5vP{2k-^uiQp`R;i^|1J7&gaYTTDzD&ZQsH4I~F@U z-?u_PuzzHV(}abKUo>?iHpnSL$wQ>KsGw=w;4=qF4c zv)SAF9-GdWkJ|5LdOY-FreCz*!}JT*WlSHj-_7*%p=X&sY_lizeXfizKWiUj`kBy= zn10$m%JftAJDEOYze7=LE7MORRhT;d4!qk@a-Qu zk1y}B-_G=dq3<%iJM=WuyR1u@-WmE1)AxtisrqgYeT#p7`&4G%7GihlyUl(ZU%%Vh z%zu98xqSH!`>jlGwKg%mCB*L2_vR^l`6l~TrZ-s|ncf(BihupubNKQ#_AN~F)&{1z z(AR?jzyF%ap@83dl?~tOw+>tDiCh_alKynClrBc>w-7mCts^oR`WpSIe-d5nv*A_! zR0+l1SL(O6S#Z{V>$1?l(Vs3Yp^MG-8;Pv9))HA4dYt~W?ku`k zW50neR-H)~?baG1ZK1CcujLH7SYf}O$TDj+k)@%p(4Ur0q>GE~n}{s7RuON}1iEMl zeVIs|)j_=46kXKV@VkC1ZM74r3_V7Fs!YmTyD&i)vqN7ZGRwY!$OYC) z`qRufU6k3crHir{T}-oDiJTXDlz8Vx>EaywHAE&`EyOF0&_zk;IFYmL>xp+(m@dw= zR?x)+hb~efxK_WFwBgVFR>E3Ne~O3bztJGEBB)&_Vl@*9+oSZSuucCB1&9^2n&`rY zkM&!D&?7`FJ8uX45i1yoSk|&=Xr{k6u+$$qH&hZzgo43;2LBTL1FGMj4L%)wGWZy3 z;6E9>FL-zGy}`E!--O)wR|l^Q9tiG1hWw`BnqX^iNw6W9ra6_&rvhv3KL?fuR;FG~ zy^wk?^^?>y_VcNyQeWYS!pH2Nr9POtE%naSTkP+rUYE+H4%^?vegpebJ*lm!^{M}d zz4wl@qWadnYgg5-s*}50Q4kd{f)R{hK)?i;023I&1Sm=pB&nd?bV30Gf(cMjP*8$_ zU;s>D0y8QgQ3(bx0;XB@?6qs1-+gD^`P|REbLX9z>mT)XKfTZCrmI)gQ+utw&N==& zg)<5*3&$6l78(~C`il$o3T1_K!S(0o|H%KG|1Q75pPgStpH%pM{w@D$>Pqku))gk@ z$NP`v$L6c^Bl3g&2lIXNJ@ei2UHp4!WuaZZb-smPlW&%9l5gbSk*}98&8PCpAClXd z+n(F(_oE&LU*taYuQ%%p{#CTXFfBLPza%#yH#S%8cgl^(4bJuT+vj@by5+j~ZE_u{ z%R%d0i(E7Rgj^GP-aEwKFV~2=0F>qG&$&U3FXREU#vV*gIvpuujvR%CS*^b$E+1A+>*=FAC zY!kB<;XQ3uBfQ6o*CV_KGmA3wGP5$%GLthCyn8ZZGu6~nVX#+|>6_`9>6Yo@-I3{- zX_sl8Y2gjYG|M!}G|JS=lx9+1zl=)nOm9zb_O4H_O@ER8Ful~fD!nK@FJ7DQy3p#x zg!I_3OS(EeB0V_WH|&`1neLYE61JnB4DHgb!`A5*>1OFBVT*L5biH(G*esn&tJKc0 zNosq%QV}-7TE)_^UTP6_ZJ3psmYN)vrY4Z>Rl&~GSTZG>Q`M;v!P?-9)L^=VElu?e z7NvTox~00LItKGn?NY5%ErMC8W~nBrM!~dHy;Nx`6--X4U_!LBcr7Csi`9%-(X?oC zP#sN(#!?rE5y6OPaMU;I84QlPMO~tfQM;&h)FS8`HH(@=jiP!{X_N|jMk?G%Jt8&- z-NLou7vYED(x6MYD4ZA03a14f!^z=D~@m14((EmP+ALcQ5 z)Q9>BA)+v zhzq>;Nc>5gG=3n&CEFVtUWjom?QMzmiV#mq-tA#0jE9DJCh~3xJ7C@ZECp;Ocpw z&%)!t_e1zb_w5h{(OpCxJ>st~2x0x)7eaVG_qh-z&z(l=Q1RCv4`JinM?&~F_W{}$ z6zk*s@8Ub8JMKmd@AF|S-FrhAIQJfZ3-qz{M)CA9KFpyzIy?m9yZudg`CYv*9OZut z)`oC)ZjBEs=T`f$XKs}b8|GHIQ!%eHY>bze!yeLu*1?c(4-YbQp8{_U4+MvX2VnZp z>oFYSuLlQ*`-8WH`+)=9C&2-<{uckx{i)|k%zj}5yu4pe4Eu&~EN)+a9mY4hQ}E@U zu#j#Ke{I;!x%Pkh8dLne{lVc-uzxrNyfGXMb`J-ESJMJxJnzbIAb4pw0K7Q789YDi z51tqH1J9v=jpv^g_5s_`@?<dUIlKYU!9|x|4;wr{U7)Z@OvGiahdQ3yMJOl z$XNj1;{E{+)VO^31L(pLpO^mbPOzWG<;3sn?!dT@`#ad%{msys58kA4x$&>pxZL>H zXzsM``ZXGt9seqg%Z}g8{S|swjmwXJg~sK_zucJ%{W6WqkbjBBWytTMaT)SE zYg~r>&h9UmcY*T~c%J(+c$V`b*k0o@<)7jHgmD|^1+cZoWy?R=-Hve!=XtQX#%0Vu z#@&W-Q)do%q{d~Q&w{STmCO6v-4c(zUCs<}r^c1c`_&u6qW7+gOQ-jaGX<}IOXCvhz3Jjw=)K`Q0ezvyL!h_Nc^u={+_m7# z&ST(wjccek&s~G@TxT-)yvF04_q;O+<2iIAi~oHyor&PHdT(%syBeJCJPJPTJOWO0 zSAkP?eM9GA@JZ((aEiMUe8PDUd`$0U=u7}7yI+Bmoblj9=K=6hXB_y5`z83Wt_MzV zzW~SSy5Rlp3h-X{bMPL$CpeaF#PPpljB`IY+Wi!~Tkiqh<$eOzx*vlzx(--loe8oqNGyx)dCuOTfYIGH{SCfCF_N9N^po-mG(AKb-~p z>I~RNrw!c?z+TQ+u)F&{c(pSIyh^9QE8O?MOPtYQ7af5Yy6=J=ox8yfIt0&l-vQe? zcY$Z>06f)Q3ZCMO0$XYgp5QJ4k8^6lW3>-9BZCwFo)33wz{9i$Hg?|v4{)l%{k01= zaNh*$J5}IbT7i4GZ-8Y^C0ME*Fz3DwW}T5>Wbr*uaICp?Qy03vhI3vLC{XfCY?yKM?XE?aQ{{vj_z5?&D?sg1U`@6tZ z?#qx@-iF}{AFH_Tid!-K++BdLeliThkNh3rhwgmH%ZFn4o{z;__q`z)zU$7zSC%td>j|=Zp1;C=hg2D@h=jeI;@xmj82MS|R18{p`aG^haT0r+gx5B0L#2!}xoLV@U zp4gie4lNv5Xh2WwaUDQdQ1rz9YyQXl=KOkkV*fn#Ks^b2Qgy)P^qGbo zb7$pF&z(Zg?MLSh&mEj=l&eoQ0)<>E=Vt$)t_9y`zsY``T|rOj?_^)kzMOr5>I9z3 zPRdTm-a{P>%d@v;2WERyr9ijrCE4?{XJ=2(w#*(+wE|7D`(^8AchBaiv*ACP9rSd* zC9|G79ekSkfIdHQAw8YX&ODQOg6ajvWkzSJ=;?e&rhlea=34q>g^Q^NLOZG$I5Bff z=J3oxnFg7<^lYBac+?5;SE?EKHobAClfby?44!I-jPG^h@oe&WT&;(;HW%K1(f2Eup9J`KdY7 zQDI8z(bNN}G4u?6M`|dl2d+z9nd+SCm};LoHFZ+z*whhJKhTh#yUS9Ulpp;S{TBU5 zofg+dUq&BC??rD$uSPFLGwG@OvFIV{!f;nKGP*q)M9=W$~6{3iqxOas=hu={p!RqkyaCx{iTpTV4pATnHEy2WaJUwsMgm+Tsh5=;L zyN6xrS-2BDpPoj~jK?MQ1iMkPGz_&!-L%r|Xvbc-@p%zxLDh_3k>S1OFd?hriw5 zLiGeI{ZFY=kM^sma$tzx-|yvL>tEqt?04|nQPseS)K%he z{~*7CU)PUUkUZ~C?^o{!?^|z;_l5V7_pbMb_lo!8|A9{bf8&2ryqdtu7R^4GR!eF=ooTdgF(0wu<-C{uZ#dtKp;AVsV26X?6zee}J7<~+S8{A|-skQiPy<(iI zZZM#vSUl=!(8Hj+!F2}L8c?n(o_TeQHtH&aZU$Wqt~8)DR6OPK7_HT12A3LKV$dZ< zE7jTH;uxo>iwrJ|(NbLy<79=D$H}Ub8Fe)1V1VSr$?9A)I>+E_gR>0U8z5(JvTAEa zXBwOl<0OUU{gc#bW^}4S8-vyctqe{vXlZbAj1$#K1}7SvV9>&#xxw)hZ!7daEL(@16t^cXC7>Dkimflw5k<q0UjB%`@m8%&08th}Rw?Tb_y$tFZ)HT>M#xZISgE|Jg8|-FKW>6aAXjNiRFvuI^ zVjM*&7$6g)nMxa^Vl-7zj3ZTO5Ey6!-@r3)4U~ZcIR6;@ZSa@Dp9X&z?22)Ov(sRQ z!S4pY8T@MSi^0zZKN)O~ak#V1;75ZW48Aw`&R}bd!<;P!n+-M@d>i9X=Np5KF%EGy z7_5)c#90@kv9s1-jltIjs|{8etTgz_;7fxq3|1I?Zt$7Grv{(IIGD1}z()oj8Z0+h zX7GW*`v&hByc^>n=N*Hk21^XyHh9b6%@_wdZy3C8u-ITxj02p72Cv1~-+9&Gl^FXu zFUM%)EHIdFFwbDF!Ak}&8oXfeyuloU*#@%=W*R(a@NA5R&J2U;2G1BgZ7|JXs=-qR zPZ~^#(ZG4a;BkY;3?>^)GME@+U*}PSM+_b|cqqm`&VvRMV(jgVH+UdMeP>*Zy`1|E z?lZX8;2wjq24f6H8{BPhm%%85T7w#cYJ;j6^_)tBkp>k8&2dG0Kd z*;$jfJ{>yp(b-e+|7~z=jbkeuPrqG89FE80cnpq5 z$H(+hI5xwvDUL_tcm$4z$Hx?{sL=6H91p>YCM<6bz{!?7-od*Zl9eDv$!xI2!!;aG-aDUKyL7I4htn2V2I z7RL;ZX&h5HMmUD?(M838tMUInj-KzOs35>g(Ff5xYJ^TX!9783P#)YG3=Db)J%Vn* zCBgZqzit^EA2bb`P*?o=)F&?&1o|JUz}~L6==FM~{*-D2-qs8CJUyFgu%FP6P`~`R zN??Q@qWkM!`dWPj)nCVT0&Vn(`WSt;Euvj>O^>B;kv?=h0cYJh4!?{VD}m{L{&hh;OGC!|3)heoAPV( zU*0AC*5ee*mp3 z?2#|zqrA%PqE&_OavO82bDv|U!D9MUgXeQIa!=BV!g#6!sG+?E!)QI>rd;=2*Ibue zCt6K7Eq5|~+QE^z#P4YyB_$5B;V7B6@D0%%H6&&Wp3J&vP1&4XDg2TL6 z!C_vk;4m*zaF`bm@y zW=92w*-^n^c2sbf9TgmAM+Jx3QNdw$P;i(X6dYy;1&7%|!C`h#aF`tw9Oiin4)Z(( zhk2fY!#q#HVV8c5MV^I-yb2L{6C&~? z&Rr(oP27o}ca+I$BJv4DBo2s36cB&l`QJ0Y zV{T<`VQyw_0;^4))~PmmS>i_4H!#;T*D=>J*D${Zt4u!BsWSOb;!4)PVj^!zI`WlH zrO8tgKgZWAO@5Nb$V)mSO+J$NF}_}5@{mr2$wNBjCJ*V{Y4VB04>0delMkfvdpv%Z ziTobv$mbD}zat`FM?`*(hK5s@z=B0ola1+TlqeVMs{ zIiEQX9O2GoB2ndxa9`x{3ryshNJoCj8E*1QMC6r-Gcj+ti*Uc)MY!MYBHV9t5$?CS z2=`lEg!?cT;XceoxDRs??!#P!`!E;bKFme94|5Uj!(4>>Fc;xIEZ#_^s5vsieOSCv zDjwm1a#*|rO1VQ_JWvjecQ(Z%JWvjG@jy8=-k}tWc%U5W;(>B#ytOD6@jy8w-Xo;k zAub*$hs3*n;t?Jwhq!p49OB}Eaavaq&QT zi;D-!f$=^YEgG&s$7<4wc*x(|A3k@zXINzX?K}UlQF>W-~-Z#4E zn$bB1XB(Vl(B7b(L0f|}WAt**FgV@dG=ozO+8DHsaf92+;1q+F1}De3-aX0S#27u@ z6AW6!=;1bx(cL}X;5dV04URE5+TbXIW(G|Sjx;#J;BbS(3=TCoB*t}a6NAPE2OAt@ zaG=2f2KyWAXV56dwQfU$1_t{Y>|?OELH!ulxO*AYGpK8@XN;@eJq+r^xXRt#V7D0E z+_D&5-BN=RgMvZcAZL&@$QYyzQU;MhXb>1^13$)+YEk;ajE*j;QJVtsPAHQQCkhR7;HA! zWbm!QHwGIGHW;ioSZA=-V2#1o2CHLqR;vtF8hmB&rNI{lD-1q2_$==KH&+e%@Avc)#@?LIRZdL9b%DX>7Psg{>9{m3uKLOx8$^{=7lu-Wn8_N5> zO!?k>D9_u2^1Cf5ue&?tbGJ|)cOm6($I%mDFUr@pp*(F}%Fq5l&v|cn&v_4e6<#0j zQtu3}8Fl{;-Jjf5?hMk{?tb%$;xzw}P zsqvCVCuJ4XOp3){ZHI=kiXMshorv98toGK6Nd2Vn@@j9Dh}2Mu#m_~&CJ{dr@#;i; zS48S5#V>zTL~1I<;%g#OS1A_fiAZgwSezpw^_7BH<;@V08cVU5bUi7npw3b(PLY|^ zT8hQVB2sTD7L%r1Wfjz1ipAt}P0A{$yA;Gq?|ykXwU=V?UJYMDt*rdX^Jk-AJlEcYr!q&8C!@AQ&hU}Y85 zXNtu>GLsrjvDjTi>NLe-(x#=Xf?7?nc%jUsUQ;Y4OYr^?K>iI}utDXTa$ z5u3?O>NmwNPnxTgRZznz78}US(-JXhhf-E?Y9i)jCiR@+mnY4J$||Vo6vR8+KV&9# zono;lxTx(Ei$BUt>N~~aW)Z3J6pKX>N1dlwEQ&a4J;h>C#8K}l7KZ%ZW2|c6$e}Gc6lxLp&I566pi~(4Rdc4?Ew2) z>3dYMztyBySOxc?8sV`6p`%n#am1x|DYN$#gtF(gq zPz_Z{V3k&IAF81$iL25I?n5 z`%n#5$sMt@A~Js)gH#fpr4^yoqz709_o2E)B@tU%!F{N1QFG<{`sTF*)k~szMjN1# zAS|umK2!r#QOs~3ssZW&c`f&$8la?CSULBh8lWnYdF9-PYJienVddP1YJienVddP1 zYJienVddP1YJln{@5g${nX}8f;%$QcfljQex6d%E=-^N-SDQIT=Jqi9stVCwmC#LU}JThmaC; zR#HyZFqUpSRc4Vfgp|ZeNjcdz)(;Qcj-FXyRYW$?_RZ{7X4GKBL_z z??;BuXxG?2xbgGNL0gP%^h_d6)(-kEakM^KL4r`-CNlvAHcPyZt+hkhC5 z&X1y;c|^JL)l_%?Jmtn~C@0>Pa^c5O4m?Y_?{$>(o=dszyD7(g4du2^pqzFI<+8t_ z9QMnUyS|5V);%a!-I8+DyHjp@3+1F2QZ9NN<)C{}?zs)+oa?5&)DM(pek1i<>cLb6 zeeU0-)X}b4YVTAS{S>W=mPB)+M`@4u&C!)n`{>xHVU!7fqrC8Y;Y;CT;a%Y%+K72B zWq%I{3&AexH@7@k5Ih--4Tc5XgHFN8)boEg{kPt%Khdx0r}h2R)!+tw5%n@SOz%k@ z;lB4*_^(gS>c5kKkwl~{*#H;f9dslevykoouUfTVYKJV{c z_eFQIJIcL<*1^tko4fnFd9_n*P|MVOHARh~U-7^FudI@+8NBi{Q4)D&mE_G>JlvkR zvPv>%EH)95+!>2WNS0NSJ!7$v%p`vX@#$zE5y_yjSYJePXe=fHTvkaIjm14>CV4c7 z)1o>el1XDR3HGu|a%m8!Mx`>7Y#NJ6&&sk&@@WvCk`H|=t0bca@yRH;dzMv_Q!`?? zL*A3D8jFeNEUP51#^N_Jlgt{6$sMn(lH3}LpU6zIYb?GiBKb8I7mG-Sjm3E)l4E0W zrif(OSWKRg$|}jTv6x(B$|}jUv3S3{oLn1=qY`l>**1t%!aGGI-^SvtB9d`q@fH!u zxv|(+M6zxy-XJ1*Hx{oIk<1&5SBgmPjm0h^l6_LjwCxBR zL?mO!;%g$3vt#i^5y{%II73A8b}S}0`m&K^?jSxIJR~#8-LWXaHInQdi=$;G`8yV? zMI?jAVo}7A#bdE3;>hH&SQK$&^H?m3I5K)H7DXIcJ&2D4MG;44kHv2CBaz)>@p2K# z@Ud7FhGh9zyijJ6>0_~@h-CX9J{%OqCK*2#&ytyB{a7ptSTcVso+&fQ{y}^wD2ie- zfGj2kwrnI>K!^_pMWIb5ki}%(q--SlK!_89Q{)?w5rjBCC<<6|f-DvV7g<3T8_3Ja z3$nO}h-3y?%!x>DkVRRA97%T2h&p-3D;r6Ekj0!R4)KM}8%nfoPTQNT7z#G?CVLl*DTMN!-!5igbZ+?U0Bbx~;VlZeUcO4-Q0S-eL+ zX0B|c^`B#PQNUXNIaU`1m-U}x_3`rEt^XXWlV!=Wk=B2X)d$K<>p#cpWMQ&wr1hU; zwRpvm)_;!GX?eNzpJTNW(fZG^zBs^<)_;!m#Q~1A{&TD^4sfLPpJV-1@}Aazj`hU> zjqKLEpbBtdUan^s1 z@rxqP`p+?bQN&sQIodCZIO{)0`(x!tvi@_lf0u~Xe~$Kx!qEE9(SAiTv%>n%(f$Y# zt^d5+m)NYZ{_}2ssLZtf^KM@Pw!-?)yM4KDR#^XemoHIVVg2V_et&sS>pw^N6518k ze~$8#RhY60>pyG#-tuzmKWlsm*b3`EYkUc=3hO^>{PX1H)_>Oc$>L>Mh4r5`{>d`a z`p+6aS-vc*u>P~g7q3`h{b!B8pS;}q&l69<@%rmBA4c*k2o zpJl(qTj)=s&$%B%dz6R!gXq)ld-z@b&a^|ht>4OTPEWy&{f3nLF7YGZ@pgFIq7vH8 z?SwnRZQ-VHO}K*gaxV!NhI3O@so|+X^wi!X)s^;>cgQr&I$n3Z==23gMvQk zO|(OyYtT8pCg?!Bxm%@I1kHn{^i1C{sGD9Ml$iedL6n}Eo*MUyPftpZ*W1!#(p7p> zdbnOgJG__cCFw!5Z(**UneL;fh8@DT=^oLfXnZs#-8HI8caDbBKK4FQkEm!*hdjeR4f=UDHje4x&S@ZLU?W zd9G=?G3^a#n5&yBNjJb@7t(6U%2fQws|X3v~-6skw!y(4o*aHM7vF(7ezzHMLMx7+x4u=u_yCnpEhT8lM`I zpIhimt2|R__x+gsr2P1>DnBM)6%Nl2r?r$mVUMtDeo)xCFeX@$??bC8OM->@9;SDH zzH2b4uqhZHj0tCkQ^QH#TyJJ!jW^Ys=}CnZdb}PJcaAJ9H@zbZOSpSv+qfrx zVIl3HZ>$^Au8K4X_CDaq!33jB~QWtRGTRT9J3+zslSW^LLrs z7XM}DHl^C;{^eD<74~(xc3sg`Tu$xmtzKJdS`-X zXtZ+)PWR5h_*Cz7u#HAL7k`8)8}@Ifo(c3i|2Ewcyw#Ku2cx}vaIHQ6=D23T59x zH}5=*yK1!U3A!qjfd^M8lz|7Ad*|ZomnoEk2bbtk7+<1L79Mo*&cV2|LV0*_F)dZc zKleon<>A4F-q{#mpliX7)HgBy`nkFWJjZJfp5?Uz+v{quo!2&|ZmTZ^&(N2Er#q{` z({vZGjqVJ#);Ql3T^C{8%0s!lKFL{y@$sf?ULWnO#P}$EA$Wu-qt}NxD6^*erwgDT zXv*q!BL`*I6szY$-`kYg>$(oguxafS=R@yi%IrVO8q3d*##);JGZ znX-KUFXyv(esGFH`Fzk)kHq){T>&1a%MFzVkI{F6N9jAjW*+`7gQj`}#z$!UeFt}| zdKllO?*pqn{9b}8g>3^txxN?rogRJ;6M#+k(E@+duw(`YL@j*v;Dy?CPuquk;#$SLmz2%e{u+rCtN@ z65S2#LVZ8u_vvi5bLflBb`E{9vj+M_x+~a8UkRS8uP}7J2G7=)=jJ+1|2@~(_;tZ_ zh3^|o)em6&q}m63g8G-nUw=IO7@VZ`1}Exq;6v2cH2(U7;YWt5J~&R_58m$~&Vu_C z;wl(RU1Q_Rx zc)Wl*?8KZMP6wxj&w!J{r@;rpY2e*-ACKo%ginFDQ(vBVJUE;J_79%`Zwwy?yN8c~ z-DoFXJnzzQ5_lnX^NGjj(I*7OJS%(zJTrV4JT-g>JSBV(Jdt|s#`BIR7ZUT>5a*4W zD&oB8W+8t6)FcscOwA7wx75@SaY{`L5tq72I0mn;AL4#MP2_Ohr)F-ru2b_fT(|w- zLtKabAE@6DeLw2Xit8yZB^{mbIl?eNOLUz|_D zpEd3i{*PWM##^0Fz%3g02mc$h-N;|(;P200t8riOSDEcc{z?abcm4|cjm7W(nS;MC z{}V5d@p8xfoh{S2U-<8uZA$(-&N6)cE!_@$(`;Mv-*7&__%*YA$$!;(ALCav?koO0 zvz9>>rt1mSl=_857wbB-89zkI6J`)yyL)+bbs(;XBYUDz8U=7J09Gi2Y_q5=HN=_ z5AY}N1n>vvFYtRk5Zvsw05>{+#taVyp~`YRWZcl zQauFBc_)J@<$w`gS>vz!-bvu$$_H-`mw^LA#BXq8h`0^9Q=U7X-z|I>yfl0Vyf9n} zo<~pN@z>jhZ-b|XZ-FO=Z^qPbddGrGb-#4JtGd=}<l|j4L)JKgk|0Vx z2ai`X%vy$?O5N)CY5QM3rvXpe#n0LHDce3{+b8UQ-};ZYiMrFRFe^v#b3Z@zkD>aA z;oczH716`%>UH)ycx}B_#VZ|lox`qj*fkFRi>FH+|ekoi}{kFNwG>Ipc(7@a8aQGiNbpGM{5U%bdZS&U}XXG;|&AJ+~73PgM>r^yu$>WomCoxZCp1^FuY|cEMc^vat<}u&{ z=DE^&z&uA1o3Y-Mc_i})=Hbl4n1_Pn%=4Qw&OEOX8?$~e^C0Gd;QihK%>9}BF&lyR zne{E_Grt_;&-^=?cQ8kQpZdd@w=-{J-pU-t914Eo4`B{w4r1N{e(Voq4gf#$Z)Wxf zKlJ;7%l*F0KFr?Co0vB;dogcdUeD~w?7{5LypDM-^BQoOe>L+eW;bS6=9SDVn3ppz zV_ph=;9tV*!tBhvn0XQNLhyb60_OS5PRx$rlb$(0PkQG3Jn5P9^Q33a&y$`xKU3)Q zl42h+#WUw;if7Kx6wjQWDV{k$Q#^Birg-N3O!3V5nL?kh6ue09{0@od7M6vDSrLqo;g2{d*=K+=9%;Jm}kz z6Y2Aw%zSfx9yRNt&ZB1ilW5M*qh>vw#^(GyYSznXd_J|88*jbxfAar7zX6=rN4-w} zS^xjPuKvI3Y%a=rC;Ncik5N`-i!hgFt3|X$m`k(6MYKhjOS89#*p}aOY4#=&Z4u_u z?6o4=BFv@P%aXd0DqDoPG<&{?wg_`+w!Mh92y_H;hBFv@PeMGcHm`k&}i)f25mt->{+9J#)SuLV1!d#O1M?_nMxg@hwL|cTpB=fU~ zwg_`c=6exs5$2N2w<6ji%q5w%BHAL%C7G{8v_+V2XFe6t7Gb`f`A|e#g!y*neGzRD z=G&R2BHAL%w=+_ZR%MGY-_9(OnYIY?t;{PT+9J%iG7CgJjQ^J2%1G&2l`X=2EAx`f zv_+V2W?m4{7Gb`bks`OM#{8adWM;`sTZH*WMs`V5*&@u>GtbFPTZFkdGg(Aigt<5~ zUPN1jxi~XgL|cTpI5Sd2TZFkdBUNfuwg_`^=4P2`i!c{wZjd;#MVN~-SBYqgFc)XK zh-iy27iT(%Xp1lxXU-JS7GW;Vv=q@6VJ^-bE21sJT%0*fL|cTpD6_wawg_`kW*-r4 z5$2-Io+8>J%te_}5p5CXqD)3aTZFkNqeZkun2XXy5oe1q7p03L&K6-VN*6_(Ey7%w zE{Zr?gt;)iSx!fm|CSb}H;QPBFc+qa!q66BE=;eInYIXXVfqUZX=N3)(66P7V$&93 zzLx%2X4)dm*V07+Yl|>nOD~g|wg~gpbWs%BBFtCQQdU}Ji!fhF7lpPh!h9tyyCkY? z5$4P3x07#FX^Suyq$OZ0Z4u^zv;caZ4u`D^syq^BFy<|xpP(8BFy>eCNk3&Va`wQFJdqL zTbiGi+gYV8!knMpQ)XVD%q$hLXClfyuCfP<^U`vUtL&bLN?v}Q6;pqScx@s|7*<}B zh`-9rs}pg%h*z;VHzl!I*)0*b%FM2bC;?k}Wg^Obv+@cSUrI?7S6-fo>*YN!WAVk5 zgm&eni72}yDlcL2h1A#b@-8espOS#B?3{=aT$L9m;%oBqixN?`AXQ$Nh%;p71&JtI zkSfnl#D`>Nr$oF*#EywrEnp!1Qi36;({&P<1 ze3@ze=bThga9RI3Cv~RGwElBWspy2kf5>}U|M^^06x!B*J{QR@iAw7~ zpN)Q(ms|fiBPt45>py2iMZsnL=ZxrcdAaqUGolYfwElBO^rnc`f6jp!PQMGEz?cXyQlt1ZApDf)dSC@#!+YaUa5;yZBmC*Rks)Y5PcE75j__@7*$Y> z{-x0w)FpoJC=7oJS5f7|9I7^}4sQ;x4BOMEgf|Q`!Ee;@{k`C&;IZH?+COl0aBk2d zI3OtKU3w$!1X!S-)MNE9-CcLmCsQT*ZvNlY1^yHNHUDY&m`!e@p&6s;w*g&i!6Q>&mve8$`6OY^%FkMC;17x+_Gq zu57FOk%-onZFS!h(Yms&?pq=b;Je9IccF;Zm2GwBi)dZhR`+=ktt;E&J}aViWm{Yc z_G;_OwzyBqOzXXQ9TUYk2TO%{AEBn@!JASowW#35mva)LH$~L-U zr>m_i+vxU{_q48Tqbqj0+Pbohu3VI=tt;E;ik+^uu56<#*Pm+Z$~L-Ur>m_i+vv)r zrrNr)jqXwMBUx9r(UtpnwRL41-G(yLy0VR~nB;2f$~L-rnQ2|wMpy2+)fe*L=LYqs z%(Sj-gDMIx>&iB$Z8FokvJGmBh}M;DP(=}EUD*az6miy-ZBRuKXI&n(DG0D}|m90@lp>18+8YOr9YU|3rmL6wi z)z+1*Rz(48UD;|?6kOJotyW^EtF0?rt;9}OTUWMP-6a1a>&jLux#L$`SGHP-ovya7 zY_*b`d-bvW_qkfNm-n=;Y_*d6c(rw9t5tKEXkAem`h*=i+zxZ1k1 zRcd#cXRUD;PoQEXaQ_LcL7%(SlTE2k)6tt zg?7C}oG0JCE{iLixgze#;^$6L!0wTVMZr}k5y#8RcTYsI)785r;z&EQw7QH$>h9%y zp1A4K>QbvEX1cVx#A=C`F0C$D?J9Y{ywwuZTw0y8S_hezwOZniORF6R!eMf zX?2RV&kmD$k=2rjDyPKRZQ4Yd7D|J}#oQo9|~Qi)iiU``L*iTD$pP_7M@S-Fz?m zkcif9zMCxyZEH8*&5pM-(?Ji_+w1C>3i+U`**hI{HoK>T4k;(v5p4_FnjO?ZD^n{U zG&j}qK~t%h4;n{<;vM)wNz^BU!NLm=y0+52|#JV0dANtrgc@ZMC@WZ0p5!2U{_&+r~TP3te@q0#}Xe<^|eE zUudkGn#ytA*wl{ehNgO4*ERLyy2MnF>&VoQYe%Zc{T=xp@jiEdO}=Zq&pqB7;VDgY@!vpF!N^fjSI~NzaXU8>DA?gX|s^uaDWK;`K25 zRJ^Wcr;67(-OB6mue(*ewrMA|BegBHDYeFH^>25q*ae%oT82Ko5LJxP9}!hC+OPcg z7{4;w8XXIM8=<~2S|1&a@z>E&;8zjq8>7!7)Hg<-MyPL$K8{e|7=0L_zA;)Bp}sMC zKSF(D^lo$rUjI(i1Y8=SzA;)5p}sMi9ihH4niiqHkz(}#%zGf(AG|x-53Gn9fy1JP zVE?EAczv`l*e%)z>>TY4o)^^z&xrN{Pmbz=$47O+X3?JDq0t`Tfl(c>L9{zqFWL>< zEh+4-Vut@jdGL=Y2mT&q!JnzyXZ-aaqcr$^lmfR#5xAMw0^_fL8wKFT zNQ3JmA6yrC;M&LqKc-KXjOV{Yy-Z>*3jYD;hJS<4g@1uhhJS*Ognxkdg}cDoa3^>N zUB}|r4-S6^`%q8Pc-%ew6}%$+1-vl)89a|xEaR`Y3%7%(QXiFgd~*0BczpN+*ev`W zJT&|cJTTk}HVC(X^~25Jp45dUe*JFYw_qXs2F!#T!7$ta>To^ih3h~?om1&`!9Uc) zCFWn@*We%FYH$~=tH%1ya3#1k{0dwbehGdNegQ70Yj-^F?eKH()$lX$h49l<2dD0T zEmq>MhgX`q%J4FE0>+o<7r`#3&NA$*5P9JR`UU70D2hOO-T9{eGVGv^$M{_RJa~?& z#|+O_$6?%FA^yU4ram)ltLH#(s}PUj84B?jo^I+k!_ySvGHjz~V_qAD_zYW{dd{$w zLY#)DD8y;lQXx*mlf8bJf0CXBwlMXc;c;|Vi+|o@y*}X4rtUL5Nc(ADp4G&hhPS6JzPshCd^fTbT z`e{Rj>qoe^o`&&WbeD~PzIvvfG_0$i!gvq;Bv?n`Iuq`$r(j&Bp8!ks<6wz?%+S=K zhFOK{5e4D3&^?9gQt0Z*@i_R~)Tai!)WI0p7bsj8gZX*_#xI)s*kHE8buySmekA_+XLy%Vy=%#T?eF~mRxSR$ zL|Zhjd(mdIe|#(MmM{ z^FH?wXVJ&%W{f}5xK2hNc!;;?9n~NDQjP0o^rnY+ixw%wX|zz|IvTy~A{b7yka5UaS+(q}P z8=>E;ab1o^dx*cNR`r5jqj8;%MtX?H=ni!Q^bs1@?dVnyaTyI$*FztqaUG8as-76% z>>*yGKB@=Cy)~}y(G6xFO?18L4*fcf>wR>shd7R|QP)Ag(nCB)S1817bh*a;AnM{F zzN60S8qB*upt=W5(9qH{dNb9A=43VK_O`$yDPb;I~f4{;rxrn+L> zM&rH`we}F#Q7d&N^piC1Gto)v3XD(m5Z_UAg}984)42ac$C~{;(J|^W%sWb53O4f) z-%(SI`%~0ZT>||G)df7T5qH+I<4pA3l+{8n?M~&4*7$2-I1P@XdfCqYr z`{)3T`(4z?djR^r)PW=ZJKo3aBZ}&K_hY=5{uHd|-3QiH=YxBC_kw%qPry26e^IoX zHx}bE{V`Z-_8CPb-e`;qW}i`1P@OQ&>yN;+{tyiGazoV-^z|~()gOS$>`#gu>J&mh zZ}_)<5By7Y0RPnQg1huP;7+|1+@Y5kdZWN!)Op~KUM;v)oeOT!Z-d`>HQ+jR4!Bmo z1+Ma{!7tR=;0paF_=#5qE>~xP%k&%IyIv*uwrUT)rC$dZdn3VDRXgw%y%?P5Re&$3 zw&3%65jfNA4+*EMGckUKolLZW%ikbRjLifmHK7yPP6YMyhF9d_%`ay5`X_&%|4WHm}-UbEoMJT zI8dE}@c=y^>}&R?gnd*?jC<*M;099;@aw3LA zDYdHQM2t#>B{Gu}F)9jWIlPt=F)9jn%1lngkSM98T291}C<~LdoQNS&vPiX@h#^td zAZs}hL!zW;YdH}^qAWMoaw3LA$yYrM8r5BW5f$Yj1w}k7zF2v7-wXR*j_|hSY+`G5#yYUnb}6fI4NVqB=b{N8)s#V zc!JD~(=xHBgX2Vu^D;&}M#MNVW5l9><;)Ddys6CO%#88_iQ*d0%#fHQnaXN7Go!pf zLc4}DGbGBYe+_45lp8cozEKTlW|RsfU~4!tL!ty%4QFOZOj1o{HJq7IO8+D8$(b1v ze-n{2GbGBYe+_45NR$+94QFOZlm-48&diYbk-R5oW=NE^{2I>8kSIyg8qUm+_>#Pw zGczPUD4HoS7j}BCe)K@{J_o zYB)1PGbQ3`I5R_{L|hGLW=NEXtFf7xf3!qgjm^ybqpy-5$!2E$(N~CQGc*5a3Bwwj znfXUwBr|Ph<{#ZjM4OrUTT5)#*v!n|`fQnLGc$i{3D_E&nfY6{m62^<>elj}HZ$`_QQz_!o0-|AC17i8W@eWz3ND+O*`<@jZdr}Z z%k@q}15hZ(8 zb5J#K+|2rzT=i z#I;GpqKIpqh(!_CDiMn!?vz927QF)aS(7e(>WiFld3=TR*F>KBD}vqbD7 zGn=ybOHtqQ8up*g&wf$Bvi~HpD7e^vlGt3{ll>=&M~cY)lf;8WWdBLxJ|eRJBvHI# z4f{_LGcuF?CyB0z>_45KJ#m0F>_15q2Ux@YlSFZVHS9l0TrKa({*y#;fHmwtou9n- zWG4Gh5{rV1{U?b_15?ia7S4Bo;*+`%e;!B98s1 zv)wC-IQE|;-XlK}`%e<@7LolYiA7<^{*%O!GL!u$iFb&|{?pm!6~!j|PZEd8O!l87 z76mN(PZEpno9sWGAHAX|X8%dz&GMe?Kb;@EqR?jlNutz!)Uf|_zW4gb%h`WAwE8R} z`%e;!f{Xnpi5+An`%e#Jxmh|4E`a zz-soNBqk0pO$*lj{5}r#O-r)jHWzL);WiI$vfzdPkDE1R*lF+4_ofyQ_9_%0^a`$@+-zX~+g^@&)=Ct}^6h;@1* z*5!#6@=y(>I?U?T6y)%JkEv@n9YgV&1|W z$Q;1Dnc1J&kJ*=rJRiMZZyw(SI;Jmm{8Y~48<^KKdop`4yECt2UK`W-$MkO|Ud`jH zn8=Hf-j&B!f`6Mn_|D%N`7R>zTSVlyoWIQHKoGlN{-5UaADlnU=RY`q=!>B5GN13@ z>@uI{Ks=xIPE6#7NJrj>hj|H0hF+{xU*{GIt5 z^H=6C%%8z6{!h&9%x%mcnLjYU2RHlQfuH#!W77R*3v)Ab6Z2c+_>nS8O@&E$!R zAF%#DSZ4CWs?6ktRjJ7f6PM!aB_=Pd3MTJMd<%NP% zL&W(Z;`|W5#`|ydS2J;bNXPjh;`|VCeuy|fM4TTY&JXc3ynciKDHG?%+2G^+5OIEp zI6uVYJZ~8j=ZAEhA7{P)9`yD8yUcf(I6w6DB|Lr`T<7EbIP3g3d5rTzW1Jsnt&j6V z#QAa7_&7gAoFC_FALqwe?c@9qaejz6KSZ1#;=K6%DPGKZS?!ziwAz0O-*>hDBJ&02 z^UOKS+00qYncyn=B$fDlukxQ|&R|YwKEr&PIgL4$`4qU4J~1bLpOyX;<`c}vnU66i zgJ1cRm=l?gG9LlI^dDwE1b*Q^$eaMK@W+Fn`wuY3G4E&I$Gn$$4|6PY40AN|ZsuLg zQOsIq4fvT~&8%Wp{%8LGe_j566enTSVMTq*MqO!EYSp0`S#lf2Nf;7GBx^jQI0-|d zERT)iBn*kYWhN(KNW9K&{3sj6Nf;6@7m<@NBwipQCt*lDOGHk>kl02iO5M95?6}INf^~6{h5fIgdy=G5jhD%;s+vf5{ATg zMC2q4iLxL)ijy!TE|!^`gi(#tuZqY?7!qF=k&`ea%F^|yQ~2+*aeA)IA}3+g{^$VnIy%S7ZP42fA0ISE5z zAR;GWNGystPQs}DQ$-QSNf;7~B94FSAlQ3%U)JY<85{AU0;Nm0-kgXMu(kaYQSO_y{aCCQNfg)iO~eiIo_$!X8%b!__D)2p zlBm6j#XXDqmet-4pR) znR#6z-Yep@iC81zHHjz=u=eUi6bD#)RU(Q5tnHSF*U5WY|G7tWxro+()`>0<(fZFi zkpx$*^`CVjxpUQ8|5+z$BQLl9vrZ%tS8M%eo&Un#n}O?G7w5R_Hf_hou|1`q~@RZu~ZT>(W!MFm9#MMXtLMFm9#MFmB@l~Yw+ zeeZL>_jx||`F?-D-yi-nuXD~M-RUGJImvma!gR(hRrO~k(;2r^)t{M6XWUX%e`YeB zaZ6SG8E0u3r|Qo*yHPKasz2lG1|3xOXPl*_p{hUQEUKqe^=F(pI;iT;7)#4dRe#19 z)>EqbGse;qR@I*|rq7#8RsESk)3R9ApBePJ{!CSW7N%*bt?JLhRI4PGs`|4Ky{czd z^=ClS5?0lp0ZmITReuKbw4Pnnp8?epq@}9<4CrfmN>zUbR7;SSs`@jax>j7O>d%1c zF)x;?`ZJ)9=+9L3XFzoYxK!1j0o4`YQdNHjR9ApYRs9*z8TvC-{TWbQ0WMYbXOxcC zQ>ywiO4E`{)t^zS&sQ}t(*re&O}Kch4)<5c|_rD++b>dz=m z%Q#hk`ZSesV*I~}|0~D;TjoyZ?`-SgHgzkyapxcBJLi4pu=Av|(wXgycJ6dqI92(Z z1d;ut{gHjd-f6F~=kqtV_p{sBHSOXyWk0h|`McQnvh{2+o4^LL+gTk}nm-|YjegDF z!}~nl#@`Yuvfj21T3f87 z^`LdP)zxZb-D(xa*YUUbUHm-WikIUVcqHzLo8d}06GzbZ=mYc;+KyJCIcN;;2De1j zP%(tfpUjWVSIu2!fw{mOZ}vCanzhUlCNq99J~NIP`-~075@TYjcbbu-YO>CzPW2pB zlXW(JPwgBzswV4f{HTMfChKH;t%Is2>tuYcgQ_O$WPGH9swV4Xyr+YzChKIprGu&_ z>twvHgQ_O$WW1zuBuMK~vP*gRv?VOsJZygYmEqs+z2Wq0h|;Rg-lv^7NFdCcE88 z>Y%F0ZZ~v^oKQ7cdqa#|K zx|mL=nyjs%4@n7CleIN;F`ZB~SzALNeG;lBYisCYI-zQ^wuU~?Bveh-*0@bClB&tt z8u~1rP&HXwqqLq<)nsiAT_Pt`P1e>3^pvV5YisB;ZbH>$Z6bf^DOF9@CZdxop=z== zk;{5YRg<-ee6NG5CTkPX8JAEsS(}K?xP+?7+C+55B~(q;CZaPgp=z==5uI@fRg<-j z=!{FKnyht1KW~yyHCgM(i+VX#P1ZW1(=efGveuFPdP-H3wT|r7K~xbKbiyW7P1Y*1O;4$6vX&8@#R*lDwT$QzIiYH@77?A=300G|i0JcuLe*r= zBb)RWshTV+l9sTlCd-PXC6}tnvLdt9?1d9yO~ywpGqO^(bm2r;l0ob~JzZFlK`eE$ zFPsPqGKi%L>B5Py9)nowtX?<~mSYg>pg%9H#vqnDeHTuI#TdjI=;^{*3}UIuxNssY z#UNH*PZw5V5KEQ7g%e>R7RH)o>gmEd3}UH#Dx3(*Fo@ZDy08j^7*er}getORu%`ZldP-GH9nbnwPh@C_X-mI@xx!J?_) z3p!XN6+EDWH>84l^l#5h1-I*9Tn6iTkLh466?{YoRl!-$Td#wv;H>AZ(Lq&k*7H{C zpei`)dCPQA6`Xaw934~zXI(E_2UWpY*IS~4s^F~aEz&_%aMtk_=%6Y%>v;2YP!*iD zy*WCl3eMWzY#meu=WS^(&q}C*vzB+io>CQ@wY-r!s0z+n-XI-R1!pZUt!h#QXDu(S zYElJfEl*cX*{a~I<>{&^TNRwOJY6+qtAewZS1GlJWUGR+mZz(xY*ld9@^sadtqRUs zUg{{Hk*x~OTAr?&vQ@!Z%hgp=wkkMlx>xkKtAewptCK5R6`VC)eQPgU6`VEQFZJxI z;H>HDjLTL9XH8dUT(&AWYq~n)vQ@!Z)72T5tqRVXuFkk@RdCjDb;f0@g0qJEtX?El zaMp02(Lq&k)^PXepei_PxI1)E6`VEPCv;F1oYh@@Hq2H9XLWaro>CQ@)m>fTWUGR+ zx~tEd*{a~I=C0SXtAewdyH*EP!CBSSXV`32a8`9wcS#&8%b3LF%%Nu5%KuLl+U`}4 zc@d?xb}!+4oQoInG4rQb_1*L8ee>>FtB`n~y?Z(wM=#({5V$AO-@fi14dnaR-NWh) z?Ct^e4t95!cniCmdJnt1QRuPV{P11u(cW%uv}?3oG|OEi#>{hPMN5Ta=DAa%EF3e> z9p_&P$INp__^167V#GXmkiRP&d(Lg=Zw=oZ?{D<;!_nvbT(^{4)L-Nl@@M%|d_IPr z%fu*pZbXct=Uf$|=sB1CqRx50kk9ludd^wzw0DAxAcIJ6=QJKix{`KygmZ#q;X$On zbClE|6~risxVLjS949dxBN2DC&N~OJv({7;fNh^ z#<8pDD!b&2VCT^#cGelhPNVbegwvZHMQ7Pzrz<;vPP1K3JGK>_U>lt*K4#5Pmh04K zi_l>|HE^+R>}@5xm$bR)jX)y4TVmoB2S@FhBhYlX+r5p)nfZ%q-SLE^L4xNtm3uCl6Oji421 zDXy0)N()(AxvrMch_#ViwR)3FWGf#Vl8*z)$At_>f*cp{Cts`)!TI1U9|!VuaKh>x z91RZh@gENayZG3TTZ4^!H=qwI>3pfHgGh#4LFq40`?^}f!#~ zNClur$^!|x6&NA6gtY%4<$za6S>TVP4DdTr8d%i&N6?rByup|W%tW9wv*X4L@H4Ex z1&!&z!sta{A!Axd_M>=?fcYta+zvcL+5coOItPXJwX0mzJPKntA* zVq+`NG(hL(80cH@BL?W*?7t1ryV-xCZ^F2J-2mO2{f7a%H~Sj;8sb+C(7)Ng8=!x) ze={~h{8w}ico}^K`~iIl{2qM)ynxOE&l?+n-=fcf<%l6@%mbE1ukef-p>pbflHvEc zg>f8M$oK&0;uz2|K!@pCI0JlaoB~FS_d+`V;KIP`#=F34xDfEFaT0jNI05_x2f$0l zJHQ`s6nN2i8~B~^7VrZ0f#;3mz;BEXN{x4&yClCpBb+K zKgAC4BWwfT#|-!$rofY!08bdN0^h+F@GXpiZ(;;IhE3p64BN?h9YY>CuNy}o{(|ue z@F4mJ__Xmda2J9+b+#KXf&V!A3%J=h3|x<{1J@Xkzs|$xPw?}M7l7I558xu>dEi`h z4LH*{1bh%(1x_+RU+RoUzk@%<0G+8b0{sU5Faz|a&Or1l`27sfn>u%(E8urG_5(Yi zUw|ErXMk;tr-7}|&%i8WAFvU+3~XrZ1=c~AfVGW1!0PBHU^Qbmup;^qSi#r@EQ@{s zmN9k$OQ4Iu;>HeOQR69K5%fJUZfpk@M&AKHWD9^N*?i!e4D!Z#mCXhJMK%Zc9GeZ? z&t?JlvYEi0YzFX22FFk5aR$dt=TY_$#5c1Cft%P=;087YxQ@Z`)G1(-z+b~A0#~yM zz@_W~;2d^8a4H)Q9LL51hqL>D1K3z#FE$3)k&OnnWcLCavQfaAY$UJ(8v!iIh68V4 z_W*r%H;}SnK!XhpY5&QF0DonJfj_Z9zzb|3@GCX|_$j*!_#x{Le2?`5zQg(g-(-D& zue093SJ<7v7ug-a=UFe{bF3%uAnO6#&$efsmtsU^?*EA(FWDc~HTeHE1bNA8SIA5DJA!;o}7JUNz9DOWktOtHZZU%l# zN&r6~#RZLZz*FQV;Jf5T;7Rlm@B}Fae47*nzGbWh9w$YBZ;%^+$4DmdD2WTA)4(G} z0q{liA@Dh44e(hK13rU30PZnX19y`Q;8W;*;5H*4xRn$JZb7Gj8;w=K4WtmT0KErX zWvm3QBmr<4dKZ{uJPb^bC~z@437l`N0L~*ma27fNoMtQsK14j=Wb_X30b?2Pegfw$ zdn|ez{82_8a3q2Am3=pQ3;bb5E^rWm^OrrqNP^!V9S8O{a)5UdIIr0~(3{|QHxj_k z1kQ7IC-esR9gS>YTXYQA##jn$P2fCeH%CXo&oY((8xuGm+Ktfb;5RfD1M3nDtb<+y z);1OaYY-%8ECg0ZuL7$W3xJh~39N{Y04o^td2N&XKUv@Wr=P8!|Nn1%#viW8#r3!v z!Cs7CFGjByW7n&zaDSJ-HN5iHqt>f2>&3Np`gryFDm%Q!79+)rapLtT@y==IL^v|M zbHLf9#)B85!Hcor#Ypf@*8hDJcs&OE|8oTRf1mUJPoMMuPwydxcaYqx?j`rUcx!-q zXMlKPfOubkcw2yYSAcj^KzPj_Ua^PQ>*3XUc@sR#M^#DDetzc)y{y+FOYz$@hy z^$Pv}`~Lql&;FfWtby=2$VcxT1?*2pN{)~mE_sh6)O&nXU#Ryuq2A+!dXE$8Jx-|i zIHBI-902oo=IWpD`#MuNe{;fln-k94oN&J8g!45goToYAJk1H`X-+s#bHaI;6VAJw zaGvFa^C}5b$ zDS1}%pyUC`{gTf}J`HR__DSxQ+#|Ug*qH2++zD(%c1S)2Y)G~P8;~a@pOD-pxmEIU z$;TugmE0n^S@IFdO_CcWH%P7r)+g&E*Gd*hu8~|VnJ>9Ya;4nizF8UZzBtUwa9$Qd6IJ_=Sa?$oFzF^a)#t|$!U@g zNj@k!RdNcjCYdZbNphm(1jz>^@0T1eIZpCEU=1=>a*X6?$$KS7Nsa_oCnF?>OWq@S zH?SHRCOH&Xl?;&_46H&10V|V%k^>~~lI$q*uH_T=x)4$qrCX>G~dBx_05l&m3HU9y^FRbUTVMY6JFCCQ4C6(q|8 zyVF}GZ;>n~Sr*uhmXRzC>`F^XmIQX8Hv=n)`{hO@alf2XY@bS^AHaRFeJY850QbfA zsYJx~sYJx~sVMpZMn%!z;S}4aqUi5%Uu>U>L~Nf5L~Nf5L~Nf5L~Nf5qQ7I57yTVh zv3+h8{T<_0(cdv{5&a#boapaxitSTQ^mn)~wof_H-{HR4KIKGzhx=mtloS0O?u+eH zPV{%UFSbuP(cj^|*gj=Nf5#{*`a7Ir`;-;^9qxV*8X4_g%Ozwoe&xU&Sab?yGR#1lz5&xSzuPV&L<)$w?LgmK66-jFRI1iE*>I ze`1sn_eVH0V7e0G{s;F9Nk5Q`O8SzXq$}x2+LBC?N)ljkai72_F769(A{jR&4atb0 z=yMsxMIVdvFNohH?xXSXu>O?(AClLA{i!&9^{3+a)sKqfS3fF_U;VhoJ?luasS=G|6WYAa>t-IiAU zC6zLBSlYPdNu|sjYNaKtQf3ad(vnLlGlyEXUQVUV9BOGvZBi*ShvMJ$luDU76l>LA zQYkZsVlAmnGP!>a#aiH(RLabu_&xoZN|`wnYb{?=DKm%Sm-LiMnK=||p=?qqGl$}x zdP=3t9E!E>E~%86L-0C1rBY@N!8*BelrnP&&Pz?1qm-FL@KPOA%FH2HXIzd_W)8tR z<8qWTa|qTMm!p)KL$J=c9Hq=0f_28_C}rkgtTQf0DKiJ-p?Z;&GIKB(tIs%FF>c^~gj#K{76qZAQjX?*_^vl!PoVa{Zm1$iOuOJgZ*x?lRaHrDa^VRPZ6aNL^FG$vW62 z6--OR&Z*#iddg0z;JrH7Q3m^1GnB`m+~GOITHZ_CjgNrRvXKsDb`=Re$zEHFQwb zpS@6d9aQyaFLbjGs`|4R(zRlasy}-nPfw}p&t3@WpsGK6nYseZQT1mpQ&)gFs{ZU{ z>IyJN)t|l0&-G`j`m>j*E5IC8fA%!r(o?GXv!|JsT&n);Y3egqj;cRJJAH-OaRwRrP0gGwr;o>d$Uw zS{AGNvzs|lf2OKGyP9dKt?JLN=KXp~ReyFd$LpY~KRcUg39IVQ&SqM2srs|C*-g)` z>d($*I~`Q@XJ@mS4yyXIvsqUMRsGr7)U{%csy{oM<@A)Q{_Jetq=Tyd>}=`^Fh|v& zoy}AQ8210C;H(I(K`ZdlJ4=OnY0CKf5F_L&xnvz6=gC=enw+q9k)z}=IbdxiyU13u zk!z{*K|P%>l>Jt&(7aoVLd84D;tK2fq1K&itodCWQV5jpRiCTgYgiSm6IQ7}c6F_yqOWTe5}jR(iQcXi;VSH_p$a?T8f@__0lpM;RnHRO z^Ff86RQN0bJ{zzg61|E~r;quLPec!kX9=Pkqxtw~G&i~^e3Aekj*bhTB;Z>61K}GA z?A&NOyepa&t#2=i)`(W%%KNS169x8^Xd%2Y%ItBWmI3F7PZiiB{IfXMKWz{4PvAx2 zvjui<{{Wul@3Oo4Tk#ZsqutKW$K(85JIh~$NBFbs`u-F=$RB6d@JHa@{vf-8-y3)J zyV|AvcDS9NWf%49`!(!BILoi#m$I2(R6Ju~M;O=ev-93nc9xy?F0m8rsCS+nW(U|V z?`)`v@Q$*r-eK`zL)RivRrQwTjb61rg-DL5n&gc&GNc>?ZQ4do8r~* zDukVIHcs@y*@&}CD>=})3lv^!aiyrwhz!OdzZbHKV4A&-+ugm&l(8tJ9;D8VPHS@ zBCtDq0oa~B56ohRfc4mOz-sJS;4SPRusAyajIsSdhdl!{*wZ21t85?eC$<;(4ci0! zltKT|{gCYf|0LT9e3R_}zRI2gzR0!%53(nLd)X7fr`R^&<7_K%GkYAkfjtH+V2=V< zu`R&mY%?&)9swrUCg4)G5xAIb04`+ff%Dlq;9RyAIENJgXR|fH2iR)hD3%W#%vJ$= zvz5Ru>|tOVwgT9MEeF9z^TSL;1mM)pWO)+@_*HOGU4}; zkAOE5xKHkuz&C(j+&B#^f-`|P7$1i8w-eak{l~});BO?)1J{s4z!l^-G7k4{_al_{dRu>f&JaTpTPd^k0Y?Z`(s7F-5*V0fA>d;e!D-C z!2a%!5dC()ujse?-3aXOemesDyWfn!{_fW$u)q6N3GDBFIRg8;e-nZI-OnJfzxy_U z{oRic*x$Y13GDCQj|BF2?`yI?{2ksI(Qo%YAZx)tK?;Cx5ZK?nBV;xBFOYoT0kR6X zhrs^sZ6~n5dyk2JyY~oz{oPwnV1M`45ZK?nl?3*8ZyAC8-OCaEb}ySG;PaM{Y~UiY z6u3b2+r4>YG5B*tzulWn7J@%Z^xM7rMZet}N#;R(5Sa_Slgt5jCbNO9$t+-FG81?k znE|XsrUOfpX~3f7Az(lr1QIeer27|{0=y#n?e33c68PuIMBtZX0`LrZAf&(DYyo@{ z!}t4J&F0`gieWkYEoK(@kC@GXn=mYwztL<8{(7?sa2)tKJZ}-zsJwR@O%6OhTr2a#qfLl#Tb5%zsRfy(=Wu6f%7r^E`KhD-{sH7 z@Voq3Sp2S;_d>^o%Sqpdv9t-Sl)&zFK zV}R|=8o*X~G%(Ao4s3+)1=cg6AL`e_qrk6bRs~kXBZ0S=Re+`N2w-uuGO!394vd+V zfKhx8&@n3lEqpf+n-xNOf1Blj*YPmmRr6NhFL)^MXY&@|4|oXhqFE03EglT~#w-i` z0uKV7HOl}$!2^LGo27y8;{m`^W+~tavn22xd>8Pzc{A`B?hia_mH-|xivwT5{eXwf zn}E;bzQ9A~jlgHkV!(sA5Ac9l6!?r;1o$-W4cuqm0Ni6{0(av(fxFB&aHkmq?l3ce zPvJX&+i)-7qqrw1E=_;%nl(+5t*?ST)N9&jvf2OMR(z`Jo<;9%1M_Q!32y-gd~1GfftF&Xf7 z+zQynq`>C5C9sJ}fb}utw^!S=z^{%WzrD&P2LDzJ`R$c45%?uAjpkP zOUO8eeD?~O5%66MdG9&KKj2#!^4`P7-=XjRgCYOjzm31ZzlI_I-K)lR@PEN@9B_X& z{sjLA495faqVWg#=Z$N?Z!zS(d(OBD{udbX**$Cg4*nVAH{d52^4mRa{0jaD1oGc~ zA48tIr;IBQf7kd0coN?RJVD@i;GQsk2LEm2GVm>23wYeP1bl;x6EuDT9>X<(M~xqW zuNyxAUo$QOU&S?mN63A^mvD993qrr-K9Aw};68`pxZplZ#=!p%VmL0i2aNB*-;d$A z;66h}ga0&!v!|}k~L+*w6ZVbl*cNd1^fx8pKalqYad!Cy<@_~Nb+dMS4`f#ZprFZ5DwJ}&of z|Nnnq|36nXVRF*OEzea=n1rKmx#g-ROv0Iyy2q2NnlK4R-yX|VO_+o;PEV8OLM36pSI>Y!@EB%FpisG2Ydr=|{$kT;|gP6ZuQ zO_+pJQU_HNCgI$mgQ^LW?f5#VnlRZ8)j`#S$#x7KR85#{`%fKIO_*%^R~=MMm~8te z9aK%2Z2N)^swPaf{gn=?CQP>dsSc_p%u@S99aK%2rS^L|sG2ZK?RRugHDQ+8Z|b0G z!YsA*4e4Cfgjs68qNh|%m?id$I;fg3OYG-$P&Hwe*!tFWu4=+8u@CAgRTE~hyE_H4@xqmLOC+R6w6J~)uMh8_BW`R9S2UQbhf!$9BRTE}`-CYM& z6J~+kUI$eZW`UihgQ^L$z^)swT`lmX?O92{VsDcBxl|Ko21`40sV2+}R$0%knlLk1TE?j+%nX*6ajFS3gQaC$hTNJnSX#yv zP6g94u8<5)XK5K1q=HB>sbJc9lgQvhG%bs*RPby4nOFuNq-m**QbDbf$TekfYTCHvxrPi*p=k*lNd&O1rh>!uXR7*h3e^>0Qq`Z6X)iscsy`=Fom@#(e@>?Q%#~F2=VaPa z&#vmv$y8@tQq`Z6sm{2hsy`=FopDK3e@>=4U zsy`>uB08w*&q-9LVN%tflW3r)RQ2a1>gu4XKPOV1n@LrFPNbHeQq`XmsZQ9Wsy`=E zecnu}`f~!&S)5e$=LGVX{!CSWK0tJ8CsqCV0MROmq^dvfC)f1ss{R~LbiyW8{W+fK z&Ol{W+e@)Ss#9&+$Z8fJs$tK652i{W*^G)3dAka~w&_I8}d+BWW3@>d$c`E#p-EIgX@doT@*^k+h6c_2+#g zm2r-rZ}j5h|NZCB-~X?9&imh|{KIkVgepU5GL#}i=rM#ELufIC5<}=PgbG7wFwztl zSGn>cR9*0K2E`bI)-FCe-bO3`KYhyozkbRdkHCX4*E8UDI1AUuHE;!73KzwNFyrq} zxQZ^J^XM!(jZUDW=rB5fc8M_qQ7&49W}zu)92$WJ@i!}UMeR^l@c;6ZzfmB%!kqiU zyIh=mCHDZ=h_0})Ms$Tacgpw<$)_Z@OFk+2gyc5hYS9%oR*SAM=VLPdC`GD!4v_-U zul_${$@m&sE&A1*n_>C#MZem}7yW9^jWWIgxJvY^ja8ywZLAdiYR&@q|HGnRZLARe zYR-I!uMque?yr>o!;&i`mrE{_%#+NOOiJcRCM2_g%f&c(#&R)E9_L~iUnIFua)IQ0 z$$641BSjI9jJ{IRJ8J{URLvlJWPmGUcX;}Vtg!4 zem>{xKSzv@WhBJ-Se*AmJR!!%;y&D`=7jssoMYwx;r=rB;XX1a+&AWg`@)=XUzl@* zoF486b06*p8`)xfEY4x@|7?`BY z_u)SDc{ri3V=NKlV{!I^>6VD`vAEv@{KaB?EMu`4AIn%I#>e990{>qq#>X-ii1D#F zJ3@Sc7$1xKw@bghWIM^Wl5HegOG3Ye&(~7=&|l#`^i?>sAU(@+-+NCBFbp z;G^t@$EgYQbKnE?Gs#bZ_tP`L@$?hPk0n2nJT3X5q>oEJCi$r3 z7Rk+$k4SEk+$gyLID)R1Tqn6!vOsc;J`QuZ{|u+ABv(p447`V~kX#PDn=X^g z0}kVQ&T#&rG%1-QnUKtuTq?Ola&Bb}6 z|E>YG24MeKEA+PfdP5w)3WVO4`{MXjAoRA}7ssyxp||C}IDQofy)F0mhyDMK_L2W% z-~Xq6_rLsi4g9+X{#^tAu7Q8oz`twY-!<^>8qjMXBTtEd)~3C;EKiAm3OwCw%2Ohs z0#8ej@{|auz|(D|JS74u@U#RePl0= zf8{9=P=TkLu6arXRNy&!N+kj+@N|PTPlYx$D$k1hm@Spr=$Kpw(`H4k{7QYIl_mDiP3XcexHK z5m3IH)IlWz%6Ahws6;^d?ou68BA|SCu?{K`&?L_jOtCOW7@Kr7tZI;ccIE8NODs6;?3+%h_-L_jOtVmhcqKr7rrI;ccID_p9B zN(8jR`CG3LB?4OR{HlXW1hm{qOD-h>TJBuXQ!=@KE_c4tK_voO?xba$5&<0F3I}#zM6X3JM=wObh<+4389f$#DS9xv zJGw2pDY`nE7hN2k9i18-9~~JT9PJbB7HuDG9&He<8Lb#C9W53u9OW+_@vr%p{R{pV z{zv{v|Cs-hf6(9UZ}T_#tNlEGu|M0N>W}wF`h)#GemB3p-`sED*Yqp;rTt=lVc+%* z@0xen`_B8yJLA3Yz3siupMpQ=?eU)Uws`BjhmnJK<862oUXAncVmup9#pCfvFX7Gi zrh5~;G2Sq*pV!@M&!32|=T-A=@rrvf&+!cYB>YeAH}0qIDfdnHW%nR|{{3-xz5B46 z?ap-{bjS1O-UqsOxSiZqZX>srTamvxu!tMD)cMEx-TBG+*7@A|(0Rvs-Fea3@9cCQ zcQ!byoTRhBneI$*?sbMZefTr%ZJnl09jA&@*16Fs>@fQu`#1Xs`<(rW{jPnCKefK! z-eEs#ueF!kOYGVF{eSn__t%Y-ie@jo2UTGCR*cXCJV)*b(*| z+rzf8jcgUmVe{EE_5d5j2D9F*3v0ugu-dFLE5nMhLX6VCdEeq9{fd4}Px7blU*vbQ zpQ2l60l#aznBOU#%o4ny^}Y3_^%2)0yl%Z< zJ#B5bHd||~JZq6P)0$+Bv4&awtnOBOK0ZV}tD1F-RoseMj%DDh_$T}g{uH0WZ{nBn zL3{`9gj?Z8xE8L+bp}On6kF&z`UQQ5zThf@chGC-d9)8bi5@|#xyE22nt>*w(P${@ zi@I@zK{HerRYm2{O(=t6+c3v@i}`>Uck0^eU+ceV4Z!Ms&|40i>Ma9K@$!I^yHt>FLDR8{EgkhWC$?tD35Jo?HzA*aQ^MujIo-2&r_8ei{Y0nnM z9ri3?^s;9Pqo+MX7(MLi!su>K6Gk`tAz^eSe+#1v`AZm`$#r3LB7X{_Bl$xZ9mq9d z+)l0vqdoau812Y!!e~o=6-FC!MHsEgFT!X=eilYca#JsllBxw4cbE()oFKORHNO5QI&QTMitsc7?o*fVN{}>gi(=p6h;NwK^W!f?ZUW~ zwim`Nw4E@@(YC@UOWO#e3~eop(zKN@O3{|WC`nrg<7V1i7$sLU zi7<+xd|?zttAtSmtrW%$=wV@Gq7}l3qvgVgp=H9zKzYI_%wL8I`)VPS6h?q@gb_sv zVfZLp7#>V2g+(C;)#72vR!O%isP$YMLg5=I`A-VHoBzJy<!uTCc62@<6 zqA-3%6NGUEJs^x<(EY;r8I2dlW&Uzl_~c9IK4JWX#tP#{G)5RdpwYs(i0&1}_h^(b zzC$C0aRH4G#(6Yc7~i6Mgz*i!TNq!XVZu0vh6>{=G(;F*qQS!W0*SpPau$ibCGt5E zdrRaqB=(lbr%3EAkuyl_Es;-9V=?>3sF5%}LJfs+8Z{8chp4_VK0x(^@jj|6j8mwN zFy2G8h4C)BO&BLpEn%EMHHGmGsv(TGQFURwg{leTIM+78%6yZHmcV#}tCYYv#^p(1 z9Oe2XFka`vAuwL!iXbpv<&qvSj&SV`7_V^A4j36MXF&=1g-NaE7@RINf|4 zIL&+v_>lQ1@IG%5;nN#qYXipI1{hrnaBoe(s2YHg)d3@_0ftuv+*1W`cV)n^N`Rpi z;j@R(mw|)nOTa;V$f*7-ur?Lj{x&MMeJv`seN8T4 z38$|?#kQ|b#kQ};FF(R~RVsdO6)JvjWh#DeB|a=z`2UJj{N4&&z!Li9srbFOQt^9l z;TJJsyc`w3w=5OEw+t7sgz?f`z!I_)T?s5n9|qpc1uS8_1QqpaaegTj`ZrNguinT7 zETLbF3s^!HrJ`OfLPfoL1Aj?*7|)~&fpNM37^Cxn88kf78GJa4xxhkn4lv*Xl`tOV zmt7%!Iuq#889 zp11>Ufg5mzcX@m>&cq%@=nr(6zgNBytHmm^QmhDzGK*g4D!A|H7xXlJhrY%WY9HSz z9^o4zm#>@|bYd{odfR%H@OL{9A8kV$`3Qa`gBt?hYHKyM>R45*veu1O;h?6)@IOJX zpkvU|T3}7LCRq1cL##ghE$uk^XY^-&@8N9p!|2=5SEGjrw*It!wl1JmC@UU^yq}>z0o23zC_n(+i25hooJP4+31b@t_1V{ z@qhDw@Xz_5`0tv3pwH0<=q+>vJ%{%2I~0fg{r(RBQGcz!++V`)PfYRe^Y8KR@_YIn z{1*J~L=C^Zf3u(Idp`31;P)oZd!KtBcyD<}yyy6RiEZ9SZ|iQ9`HtagT3DP z9R38qi;v;Mct74@9kTZFkqI_&Wq#7@;)!45cYCAMw%lUbkPcpSHK#o9#7rp1sJP zX-~4p*u(68c6YnIon_avtJ$~M#qF5w*ajcf@F(^S`;?txZ?c!!LAHxM&epSsSvH%? z9%SR$2sV)2!8);4YTpcg4}J{34$cJc1#bi|;d}nS_Qqgm@K~@eSP?7@=J47APDbV! zCQ2ydM;0X=BN(E_J^ZdoSmPLXvsZ*Mj4uyFhO(E0F@%q|2$8|;MPUqLF9>5GdtMj= zY*FkO?;s{3ZzC#V`RL==q16&4r& z`h~@W@iWU1#${Gm7?=3X9r%i$SRjnK_*r4h!G8*4Ha;MXSy&VY#!P%rL}s8Hg)tqA zYS);CZWfV;&<(iHrl6w2n2h%eV-glMpfQ}i3K8=@etZZQ%pA)^NozKD zMFC+paYX@Pwsb|=VK#C_*WoGr<}KivE6w~7*9IKh4F;*rZBcSZwOkL#4s@t#bXah}YJ`}p{(kXBGEN5Sa;ts+{qRqm{ z!E1$)K*fZSjl}+AEJc5d$P!di7>lvopBG`dU<*+Z@vjBwqA=#8n}jhBiM%j(QMqUC zq;k*PLB+2ypQ2(3&Fxf9{3I1g#IFfN67h=y@umE#KqL{rEO;Hhf?pTBCX7d^Jb-MW z;y}&IVR4`~AF;%N(cEN-z1Q4miM`j{V2QogTyKd4G1pl#LDpI|#3vV6Vr80ZEb)`g z)t1;6X1*oXyt&G%EGAxQRT9R-Rz+c~Fir_$xgisFnIV62o*`FDt|3=T(vT}5$B=2B zFyz|EHsl&xYRJ{H#E^-<*pTaIks;U5LPM^f1%_Nd^G*3V^GrGWTvN_9$CPu;HsxHi zOgYy~Q?At+rd+GjO}SR5nd0#z^y$Fh-a^31hhVqcH9< ze-Osq=0#x)Grt$cQ1d%s3^6YVW3YK%7=z4jg)z|lMi>LkuZ3}!c}^Jp&98*f&-_vt zea$a~(Z@V1jNazw!no7?Oc-~Vp9-Uwc}5sLk=!UfklZNUk=!WVklZL;k=!UrEFzQ;j2&0Zw zP8hYVvckB{DkF?qR%v0>v`Pu1h9!;?W_9ak5vgX0W0YCdDlQ^bEOBr!Z;r@?FAbS-(~!P#djIku=pbHYVSE%> zBaG9L)x!8Nk}r%8BCCY)eq^OEPDLIT#w+%4VZ3bLBaD~qyM=Ms9wv+z?V-YW!5$)v z=k3A5IAjkJ#&h;SVLax%E{sQ=*Mzafc~uyjog>27;mCt|Lq7016a#x5aSAZ@IO3>o z>~`e2ptUO&!))r_3lp1J?r1Sr0jUwZ6sh~4mpkHfMziXC)@J|t?5Q~%w8+?jW=DcQ zf-C%*>RbLs^^byggExaC!Slg0{MuumIv8rb}&Df5lrUe?vD(H1pR`ZL8qWi z&@8CWl>n83vO)16Gl&M1kGg-2UypwuJs15n`a$%a=uxf)c$QytZ;w72T_0V=$J}2W zofCbCUw4m*-V+_j$J_4~y*=78+L&K^SBsYC z|Em82zv|w_bpem~1^x;@;Vf>^OksX`IY!YZ>%?*kB{GnYXLfV zt@t%}U9UPH9lx}9Bi93Xp2e@bf9G$izuFe}xI`S*-rcOPlhEvfg+ql1_v~x-89U8R@@w%U{K|Ge+s&R}Ti80TBgkb- z_!apyHj#~G!`UF#hhKBxO(wsEl_jf9Cl|eC5 znApUyu349@3)UB0XK>OwX1!z`w05IEt!@0i%4)7PSZvL`E*<5jO4PV9=@E7=Fes|^#{0e>!@5S5k7JlF5VVuD8@eDi(kHy3B zKzyeh^`HT+$<+vD@QpYFyZo-$MRX2*ir(jUk6uGBpl8rd^f=mp^20F?A_VcE|+x){Q|-x7wOjQ16cE`l&`zl7l@;(Y|83n9$AF=2RHytiO<0fc#TCJb+l z-zgZK4`JS`3B!-a?+}d6gD`L1gyF~Hy#%9kA^cb!a378L6tv)hz{r+(5Ab)j zUC@FD1S5~cyMfQUJitxyu7VakFc{ew?*cyW`2aV>I}2Ly0AXZ(yc77m0|Zb@ebhgeh{!Ae!HLr4;V()#M^_~XRG%j`x-i88yNnGp`yc-4n z;<(rucvA}eMRBng@ZJ>o3*%z*^A;8O3*utC^G+4`^W(Jzt)akq@!JHgA;7uuT7uSK z;GB2~L4L&=?pCwo#RbhLfwST_37SuY`8zXyBf#7iVn)0ez}y;Qdb}vWd_2UocoBg4 zScr$>Hvr5>Lp&Jw06_-quxC;nw2k;^9d2mYH0R-&N!{_thgg5~NtpQ#l!~<~)5VQjD0rq+D{x}8%Edd@sLKx=wI06JM z03JU+a5Yuj1O&|i9zQx5=6!Jk5M%*(myZX>#(uOA^!m6nCiX+<@QxpMM#nCO4)6PM z=ib=&p~Jg>+!+=7E_8SgkUJw|7ea@30=Y9Hc0P1?Kae}aW8a1j?+S9~p4c~`!+V3= zxjXiC=YjC~HE zFNPQp`wT!|2ys{JQviKFME}?s06i3bjeN_XYi zeN_V30K9h`1}n$l`zi;p0eB-h3|5N4_f-mD1MseL7_1nB@2eQV2H-8`Fjyf5-&Y}k z4Z!=&VX%A*zOQ@$8-O>T!{Dtk_`X{M*Z{l}9R_cS!3?(q&A_9ugO!WH4CR8RVUYKz zLzIod3}u5R;8ED!%EVxXGC|`o$h+4eO2=S^(m^BeDC~TtVlYFgpkWx~eeDn>V=zO> zpaFRF;Se{+V1}E6`ry$OAxgwxh7v(N@aXao#bYo-@t`hvbXka-Vlcx^K^^dDUWglG zFvE>OZSZJrh+;9Ap;&Mmcofb-MPo2S(V$isFgq5sS?SP(Vg(Ug+^wdx*lZxc~|%6q^%zyzL$$h|LC2Kr}Wh^mq$C zgddv;pa3s6BlLJXK7<>a4xj)hHZAmcYd(Y>dk8=QEcRgN@iu)38k-8B01}%Ldc0*H z!ivG_u>#0c-oFonxbzi34Av43AYpk=KMbPMzW`#evQPkd%lrIc&@BBkAO@epoBkHE z&C-{{zp=^TU*7+ZZZ?*nR>Ue{Wm>*P@Zb11uCP95^|yKkb%Sa_dESjL5)_ISM3+ai zqw}KE_;vf}=&)%2XwPWJXe)lzUYmE!%SDSv<57=avtReG_!oK4{EUB!U$GzY5BdB2 z?fw?tCtu-b`}6#1{se!tKa5|k_w+mZt^CG*ZNCb?Rxj?yd9NIM*S#zJO8p$y@t^XJ z^KSVeex1IZtN7P?E4*xP9=}ST;Em>b{r+B0uOq)kZ_NARRlIUsu^;DG=-9pPUg4eb zbM6^_eSX|M;vTXZyZhYjya&G4UBPwx^W16f1a~yQI`40FbbGoT-BwmBx3OEBU!RwA zi}PN%=VIqNzdFC@oO8}Nr+7E~2){PpXVrGLJ6oK!&I+rFlg+Qrr*RGcXlIzy-|5M( z&0Fzqcx|g3*YTHgit}r8&%yR}-VwjZmHcPyQ}%KDh<(W3$9v*ixR!r~oo&yvr`Z$u zRrxT~(e7{eMCa^|b}MwoZfw^^r|c?rIdq(N$m8e;zdFb05WCK8k@l7m!sJ*E}rbqdUEMwN8Um2&lwTzwf3Tf7eWL z{yvvDe;13#--Cj2V{#qWCRcD3auJs!=Wuay2FJ-M?2+RblOyC1x=!|y?dS^GLe`>- zWCh6%Ch_M9rUhfk1Ts3fhYTbAg8`%`=@{HWT9L*XGtzmrcC(*y7zeQh*{uuox`a<+Gen0COt})pW-K<9dj6}jq0i$l_EpSP2HGUd= zH~u})iGK&Q;}?J|ejZ5U-vUYe8=w{c8i?cPfGGYI(2RcxG~!x7smuUaGBXOiInxK0$n=24GhJZwOt|zk zxU3!gtW3D{G`PAQ{AQVO>1j00giB7NNhVxs8jUmI64Pju373{e!%VoOG#X^WrKC|m zvpmdSFZ0%rkv-8QzpVl{1-N`PjO>mN5{&Z0D!=u?)udr~SA3vglpj%fn2Srp@Ws;A zf!~y_20T}~D)7V7m4IhTR|I}ix&q9$w?zc}J@LUIjW#9WQrzHLfACwEgiCRQOa8%c zRT3`64X*qLzhy}=RuF#x0Q?r2aLI1)=K#RxqJJRQ`~$h;&q>~g$k;ow;$tfa{!+ziI zXYK3Sd;h-IzCOSG+k1b1e|-Am^}fegt+nPH^LamO9Paym_QCx|eZ8n8prVj~iaG)+ z$_S{aBA}v(fQlLdDoO~bs34%CfPjkn0cvfEwQbxberlr>Z%sHTD&Tg* z)Ih7|UTTBX0ITL6YC2`d5h@M1T|d>|s=1q5FLjYsa~HKH)z7LKPpwW}Xw}?FO{Ffd zYVM#WQ+7O{CV|^w%8mz=CU84ZZNDEC3f!)$w%?CJ1#ZWy?f0Wzf!jf~{eF}!aNDo8 z;|bLZ+>TY-@q{75qaTh_g1h;=ne_*wm<1m8a32yI9ueVywaT!4^ z1-E}qzi-uCOZ_GNo>en~x+A^Ls=0>xb9${+b2as+^t)EgaO(E-8ms0i>W}GnteRoe zAJVI>nk%W_r{A_}uAqLGe#@#EO8qvy%BmSc-IiWy)m%>fCjF*WGnl$Hy~3)wjQVx@ z4XcK}iEK$P=Qe6Ls9&X*SvB-cKT+ii0!bwir-Mr1?Hvv%7Y zL;WDl`6Kc{%`CfZ+ELf1@3mU+pX3- zZq*z@eLH=d)tbkwnuDotrLAvK0mJQ8Y3o}Q!f<EO zhTCtXt#45z!|mm1>s!>yaC=$W`V}QJ++Lc#&Z=_@bxHbKt4@WwI6cCuQ>MP2zQ$_J zG^=8N@1pe8++I{O)vDOv|5|!Dw_mGy)T-Fmu`qoVw-?sf@r@cBZoiryX0^tSbCl$8 z`<3*SR%`5dM}-czUrt|PwZ@Kn6zp*OrSwp%HFn&ieuvvHriWOqvEv@)JltN8zT9e! z9rvj2;r0vZ!B%VRxYuGIormYAt-t3daq9r5Td4if-Os13&7V)+jnlR(|Ia=V`)__a zUjyon^fk;&+o@$<689?b(olw^yXU6u3^O;$k>niNU~k>;9MPZ^_3#FJQ4eddC-u+< zEvaoAw4ff+pgHy6276GOHi*|DU#aQzFVy$$JDX(FdSjstURI zf8l!R$K=-J7s-!twX`O=GPx92P79KA@ce&zatitZ+?~7?_YrPNj!a&a9E^?teUd$K zC*c(2-XEQ8i=F^`C7a@2LYRyq|9%&`0&EL6<8H$H;p*@WWZl0Q&IxDYe!|1yec_#9 z8JYK^!x6ZnaB0{tJTL5y-T)oL<8V*mps;n=B5aKA0C8mC|C#tT@k8S4#HPfDiM5GU zxUcYPVt(S;#EitFi3bxC61U>{{}^QA4^0e2CxD)K`rj#WT;gzK+_y?J#k2pagsIwH zwWI1=pxkJ~KWoJ}Eu{Py2JotsjA&00ZNF@vOgF zyi@!*WY-^nt^iHr_2X4>6YLIlAisVy`U0#ARs~CfmxH-@%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..2f30165e6 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,12 @@ +# Chinook Knowledge (remote-store demo) + +This Data Agent uses the Chinook SQLite sample database. + +Primary entities: +- `Artist` -> `Album` -> `Track` +- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` + +Guidance: +- Always discover schema with `sql_list_tables` and `sql_get_schema`. +- Use read-only `SELECT` statements. +- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..c8315594c --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-remote/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,14 @@ +--- +name: query-writing +description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). +--- + +# Query writing (remote-store) + +1. Call `sql_list_tables` if you do not yet know table names. +2. Call `sql_get_schema` for each table you join or filter on. +3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). +4. Summarise results in plain language. + +See the full skill in `agentscope-examples/harness-example` under +`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/README.md b/agentscope-examples/harness-examples/harness-example-sandbox/README.md new file mode 100644 index 000000000..23ee842e3 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/README.md @@ -0,0 +1,76 @@ +# harness-example-sandbox — Filesystem **模式二(沙箱)** + +本模块用最小的 **Chinook Text-to-SQL Data Agent** 业务,演示在 `HarnessAgent` 中如何启用 **`SandboxFilesystemSpec`**(与 [`docs/zh/harness/filesystem.md`](../../docs/zh/harness/filesystem.md) 中的 **模式二**、以及 `HarnessAgent.Builder#filesystem(SandboxFilesystemSpec)` 注释中的 **Mode 2** 一致)。 + +--- + +## 模式二在 Harness 里是什么 + +- **对外**:仍是 `AbstractFilesystem` + `FilesystemTool`;若后端实现 `AbstractSandboxFilesystem`,Harness 会注册 **`ShellExecuteTool`**,命令在**沙箱进程/容器**里执行,而不是宿主 `sh -c`。 +- **生命周期**:`SandboxLifecycleHook` 在每次 `call` 前后 **acquire / persist / release** 沙箱,工作区投影、状态落盘由 `SandboxStateStore` + 隔离键描述。 +- **与模式一、三的区别**(简表): + +| 模式 | 典型配置 | Shell | 本仓库示例 | +|------|----------|-------|------------| +| 模式一 | `RemoteFilesystemSpec` | 无(宿主侧) | [`harness-example-remote`](../harness-example-remote/README.md) | +| **模式二** | **`SandboxFilesystemSpec`** | **有(在沙箱内)** | **本模块** | +| 模式三 | 不写 `filesystem(...)` 或 `LocalFilesystemSpec` | 有(宿主) | [`harness-example-local`](../harness-example-local/README.md) | + +--- + +## 本示例如何实现「沙箱模式」 + +### 1. 显式使用 `SandboxFilesystemSpec` 子类 + +`DataAgentService` 中构建 `HarnessAgent` 时使用: + +```java +.filesystem(fsSpec) // fsSpec 为 InMemorySandboxFilesystemSpec,extends SandboxFilesystemSpec +``` + +`InMemorySandboxFilesystemSpec` 在本模块的 `support/` 包内:用 **`InMemorySandboxClient`** 在本地 JVM 里分配临时目录,**代替**生产里的 Docker `SandboxClient`;行为上仍是「通过 Sandbox 抽象执行 shell / 投影工作区」。 + +### 2. 共享 `SandboxStateStore` + `IsolationScope.USER` + +- **`SharedInMemorySandboxStateStore`**:内存版 `SandboxStateStore`,模拟多副本共用的 **Redis / 元数据存储**(保存沙箱句柄、工作区根路径等,便于 **resume**)。 +- **`fsSpec.isolationScope(IsolationScope.USER).sandboxStateStore(stateStore)`**:同一 `userId` 多次请求(可不同 `sessionId`)**复用同一沙箱工作区**;不同 `userId` 隔离。 +- 生产部署时:各实例配置**相同的** `SandboxStateStore` 与 **同一套** `SandboxClient`/镜像策略即可;本示例把复杂度收进内存,便于单机跑通。 + +### 3. 业务层刻意保持简单 + +- **Spring Boot**:`POST /query`,body 为 `sessionId`、`userId`、`question`。 +- **宿主工作区**:`WorkspaceClasspathMaterializer` 把 classpath 里的 `AGENTS.md`、`skills/`、`knowledge/` 落到临时目录,再经沙箱 **workspace projection** 进入会话工作区(与生产「仓库里带 skills」一致)。 +- **Chinook**:`SqliteTool` 直连宿主 materialize 出的 `chinook.db`(JDBC 在 JVM 内执行,与「是否在沙箱里跑 SQL」正交;重点是 **文件与 shell 走沙箱路径**)。 + +--- + +## 运行 + +```bash +export DASHSCOPE_API_KEY=your_key +# 可选:AGENTSCOPE_MODEL(默认 qwen-max) + +cd agentscope-java +mvn -pl agentscope-examples/harness-example-sandbox -am package -DskipTests +java -jar agentscope-examples/harness-example-sandbox/target/harness-example-sandbox-*.jar +``` + +默认端口 **`8787`**(见 `application.properties`)。 + +```bash +curl -s -X POST http://localhost:8787/query \ + -H 'Content-Type: application/json' \ + -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in Chinook?"}' +``` + +--- + +## 相关源码入口 + +| 文件 | 作用 | +|------|------| +| `DataAgentService.java` | `HarnessAgent.builder().filesystem(fsSpec)...` | +| `support/InMemorySandboxFilesystemSpec.java` | `SandboxFilesystemSpec` + `SandboxClient` | +| `support/SharedInMemorySandboxStateStore.java` | 分布式沙箱元数据的单机替身 | + +更完整的沙箱概念见 [`docs/zh/harness/sandbox.md`](../../docs/zh/harness/sandbox.md)。 diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/pom.xml b/agentscope-examples/harness-examples/harness-example-sandbox/pom.xml new file mode 100644 index 000000000..7bdacef8a --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + + io.agentscope + harness-examples + ${revision} + ../pom.xml + + + AgentScope Java - Harness Sandbox Example + io.agentscope.examples + harness-example-sandbox + jar + Spring Boot app: in-memory sandbox Data Agent (text-to-SQL pattern from harness-example), USER isolation, shared store, projected workspace + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + io.agentscope + agentscope-harness + + + + org.xerial + sqlite-jdbc + 3.47.2.0 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + + diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java new file mode 100644 index 000000000..68b834ac0 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentController.java @@ -0,0 +1,93 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * HTTP entry point for the sandbox Data Agent. + * + *
+ * GET  /        — usage hint
+ * POST /query   — ask the data agent a question
+ * 
+ * + *

Example: + * + *

{@code
+ * curl -X POST http://localhost:8787/query \
+ *   -H 'Content-Type: application/json' \
+ *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are in the database?"}'
+ * }
+ */ +@RestController +public class DataAgentController { + + private final DataAgentService agentService; + + public DataAgentController(DataAgentService agentService) { + this.agentService = agentService; + } + + @GetMapping("/") + public String index() { + return "Sandbox Data Agent — POST /query with" + + " {\"sessionId\":\"...\",\"userId\":\"...\",\"question\":\"...\"}"; + } + + /** + * Processes a natural-language question about the Chinook database. + * + *

The agent sandbox and memory are scoped by {@code userId}: the same user always resumes + * the same sandbox (and sees the same {@code MEMORY.md}) regardless of {@code sessionId}. The + * conversation context (messages) is scoped by {@code sessionId}. + */ + @PostMapping("/query") + public ResponseEntity query(@RequestBody QueryRequest request) { + if (blank(request.sessionId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("sessionId is required")); + } + if (blank(request.userId())) { + return ResponseEntity.badRequest().body(QueryResponse.error("userId is required")); + } + if (blank(request.question())) { + return ResponseEntity.badRequest().body(QueryResponse.error("question is required")); + } + String answer = + agentService.query(request.sessionId(), request.userId(), request.question()); + return ResponseEntity.ok(QueryResponse.ok(answer)); + } + + private static boolean blank(String s) { + return s == null || s.isBlank(); + } + + record QueryRequest(String sessionId, String userId, String question) {} + + record QueryResponse(String answer, String error) { + static QueryResponse ok(String answer) { + return new QueryResponse(answer, null); + } + + static QueryResponse error(String error) { + return new QueryResponse(null, error); + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java new file mode 100644 index 000000000..2f8df5cb2 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DataAgentService.java @@ -0,0 +1,166 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import io.agentscope.core.agent.RuntimeContext; +import io.agentscope.core.message.Msg; +import io.agentscope.core.message.MsgRole; +import io.agentscope.core.tool.Toolkit; +import io.agentscope.examples.harness.sandbox.data.SqliteTool; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; +import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; +import io.agentscope.examples.harness.sandbox.support.SharedInMemorySandboxStateStore; +import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; +import jakarta.annotation.PostConstruct; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Data Agent service: Chinook text-to-SQL with sandbox isolation. + * + *

Infrastructure shared across all requests (initialized once on startup): + * + *

    + *
  • {@link InMemorySandboxClient} — local-process sandbox (stands in for Docker in + * production) + *
  • {@link SharedInMemorySandboxStateStore} — shared state store (stands in for Redis) + *
  • {@link InMemorySandboxFilesystemSpec} with {@link IsolationScope#USER} — each unique + * {@code userId} gets its own sandbox; the sandbox persists across sessions for that user + *
+ * + *

A fresh {@link HarnessAgent} is built per request so concurrent calls with different + * {@code userId} values do not interfere. The heavy shared state (sandbox instance, workspace + * files, memory) lives in the stores above, not in the agent object itself. + * + *

Required environment variables: + * + *

    + *
  • {@code DASHSCOPE_API_KEY} — DashScope API key + *
  • {@code AGENTSCOPE_MODEL} — model name (default: {@code qwen-max}) + *
+ */ +@Service +public class DataAgentService { + + private static final Logger log = LoggerFactory.getLogger(DataAgentService.class); + + private static final String AGENT_NAME = "data-agent"; + private static final String BUNDLED_CHINOOK_RESOURCE = "chinook-default.sqlite"; + private static final String SYS_PROMPT = + "You are a Text-to-SQL agent with access to the Chinook music store database." + + " Use the sql_* tools to explore the schema and run read-only SELECT queries." + + " Follow the query-writing skill and answer clearly in plain language."; + + private Path hostWorkspace; + private Path dbPath; + private String llmModelId; + private InMemorySandboxFilesystemSpec fsSpec; + private SharedInMemorySandboxStateStore stateStore; + + @PostConstruct + void init() throws Exception { + hostWorkspace = WorkspaceClasspathMaterializer.materialize(); + dbPath = materialiseChinook(hostWorkspace.resolve("chinook.db")); + llmModelId = resolveLlmModelId(); + + stateStore = new SharedInMemorySandboxStateStore(); + fsSpec = new InMemorySandboxFilesystemSpec(new InMemorySandboxClient()); + fsSpec.isolationScope(IsolationScope.USER).sandboxStateStore(stateStore); + + log.info("DataAgentService ready: workspace={} db={}", hostWorkspace, dbPath); + } + + /** + * Processes a user question with the data agent. + * + *
    + *
  • {@code sessionId} — scopes the conversation history (same session = same chat context) + *
  • {@code userId} — scopes the sandbox workspace and memory (same user = shared sandbox + * and MEMORY.md across sessions) + *
+ * + * @param sessionId session identifier + * @param userId user identifier + * @param question natural-language question about the Chinook database + * @return agent answer + */ + public String query(String sessionId, String userId, String question) { + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(new SqliteTool(dbPath)); + + HarnessAgent agent = + HarnessAgent.builder() + .name(AGENT_NAME) + .model(llmModelId) + .workspace(hostWorkspace) + .filesystem(fsSpec) + .sysPrompt(SYS_PROMPT) + .toolkit(toolkit) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) + .enableAgentTracingLog(true) + .build(); + + RuntimeContext ctx = RuntimeContext.builder().sessionId(sessionId).userId(userId).build(); + Msg userMsg = Msg.builder().role(MsgRole.USER).textContent(question).build(); + Msg reply = agent.call(userMsg, ctx).block(); + return reply != null ? reply.getTextContent() : "(no response)"; + } + + private String resolveLlmModelId() { + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.isBlank()) { + throw new IllegalStateException("Environment variable DASHSCOPE_API_KEY is not set."); + } + String modelName = envOrDefault("AGENTSCOPE_MODEL", "qwen-max"); + String id = "dashscope:" + modelName; + log.info("Using model: {}", id); + return id; + } + + private static Path materialiseChinook(Path target) throws Exception { + if (Files.exists(target)) { + return target.toAbsolutePath(); + } + try (InputStream in = + DataAgentService.class.getResourceAsStream(BUNDLED_CHINOOK_RESOURCE)) { + if (in == null) { + throw new IllegalStateException( + "Bundled Chinook DB not found on classpath: " + BUNDLED_CHINOOK_RESOURCE); + } + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + return target.toAbsolutePath(); + } + + private static String envOrDefault(String name, String defaultValue) { + String v = System.getenv(name); + return (v != null && !v.isBlank()) ? v : defaultValue; + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java new file mode 100644 index 000000000..953e784d8 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxApplication.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot entry for the sandbox Data Agent (text-to-SQL) demo. + * + *

Set {@code DASHSCOPE_API_KEY} before starting. Optionally override the model with + * {@code AGENTSCOPE_MODEL} (default: {@code qwen-max}). + * + *

Once started, send questions via: + * + *

+ * curl -X POST http://localhost:8787/query \
+ *   -H 'Content-Type: application/json' \
+ *   -d '{"sessionId":"s1","userId":"alice","question":"How many artists are there?"}'
+ * 
+ */ +@SpringBootApplication +public class HarnessSandboxApplication { + + public static void main(String[] args) { + SpringApplication.run(HarnessSandboxApplication.class, args); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java new file mode 100644 index 000000000..7c425ed1d --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/WorkspaceClasspathMaterializer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +/** + * Copies known {@code classpath:workspace/...} entries into a temp directory so {@link + * io.agentscope.harness.agent.HarnessAgent} can use it as the host workspace root for sandbox + * projection (e.g. {@code skills/query-writing/} for the Data Agent demo). + */ +public final class WorkspaceClasspathMaterializer { + + private static final String[] CLASSPATH_FILES = { + "classpath:workspace/AGENTS.md", + "classpath:workspace/skills/query-writing/SKILL.md", + "classpath:workspace/knowledge/KNOWLEDGE.md", + }; + + private WorkspaceClasspathMaterializer() {} + + /** + * Materializes bundled workspace resources to disk. + * + * @return absolute path to the host workspace directory (contains {@code AGENTS.md}, + * {@code skills/}, …) + */ + public static Path materialize() { + try { + Path dir = Files.createTempDirectory("data-agent-host-workspace-"); + PathMatchingResourcePatternResolver resolver = + new PathMatchingResourcePatternResolver(); + for (String location : CLASSPATH_FILES) { + Resource resource = resolver.getResource(location); + if (!resource.exists()) { + throw new IllegalStateException("Missing required resource: " + location); + } + String pathWithinWorkspace = location.substring("classpath:workspace/".length()); + Path target = dir.resolve(pathWithinWorkspace); + Files.createDirectories(target.getParent()); + try (InputStream in = resource.getInputStream()) { + Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING); + } + } + return dir.toAbsolutePath().normalize(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to materialize workspace from classpath", e); + } + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java new file mode 100644 index 000000000..9649b157c --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/data/SqliteTool.java @@ -0,0 +1,225 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.data; + +import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SQLite helpers for the sandbox Data Agent — same tool names and behaviour as {@code + * io.agentscope.harness.example.SqliteTool} in {@code agentscope-examples/harness-example}. + * + *

Tools: {@code sql_list_tables}, {@code sql_get_schema}, {@code sql_execute_query}. + */ +public class SqliteTool { + + private static final Logger log = LoggerFactory.getLogger(SqliteTool.class); + + private static final int MAX_ROWS = 50; + + private static final int SAMPLE_ROWS = 3; + + private final String jdbcUrl; + + public SqliteTool(Path dbPath) { + this.jdbcUrl = "jdbc:sqlite:" + dbPath.toAbsolutePath(); + } + + @Tool( + name = "sql_list_tables", + description = + "Lists all tables in the SQLite database. Use this first to discover what data" + + " is available before writing queries.") + public String listTables() { + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + List tables = new ArrayList<>(); + try (ResultSet rs = meta.getTables(null, null, "%", new String[] {"TABLE"})) { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } + if (tables.isEmpty()) { + return "No tables found in the database."; + } + return "Tables (" + tables.size() + "):\n" + String.join("\n", tables); + } catch (SQLException e) { + log.warn("sql_list_tables failed", e); + return "Error listing tables: " + e.getMessage(); + } + } + + @Tool( + name = "sql_get_schema", + description = + "Returns the schema (column names, types, keys) and sample rows for one or more" + + " tables. Pass a comma-separated list of table names to inspect" + + " multiple tables at once.") + public String getSchema( + @ToolParam( + name = "tables", + description = + "Comma-separated table names, e.g. \"Artist,Album,Track\"") + String tables) { + StringBuilder sb = new StringBuilder(); + for (String table : tables.split(",")) { + table = table.strip(); + if (table.isEmpty()) continue; + sb.append(describeTable(table)).append("\n\n"); + } + return sb.toString().strip(); + } + + @Tool( + name = "sql_execute_query", + description = + "Executes a read-only SELECT query against the SQLite database and returns the" + + " results as a formatted table. Never use DML statements" + + " (INSERT / UPDATE / DELETE / DROP).") + public String executeQuery( + @ToolParam(name = "query", description = "A valid SQLite SELECT statement") + String query) { + String trimmed = query.strip(); + if (!trimmed.toUpperCase().startsWith("SELECT")) { + return "Error: only SELECT statements are allowed. Received: " + trimmed; + } + try (Connection conn = DriverManager.getConnection(jdbcUrl); + Statement stmt = conn.createStatement()) { + stmt.setMaxRows(MAX_ROWS); + try (ResultSet rs = stmt.executeQuery(trimmed)) { + return formatResultSet(rs); + } + } catch (SQLException e) { + log.warn("sql_execute_query failed for: {}", trimmed, e); + return "Error executing query: " + e.getMessage(); + } + } + + private String describeTable(String tableName) { + StringBuilder sb = new StringBuilder(); + sb.append("## ").append(tableName).append("\n\n"); + + try (Connection conn = DriverManager.getConnection(jdbcUrl)) { + DatabaseMetaData meta = conn.getMetaData(); + + List pks = new ArrayList<>(); + try (ResultSet rs = meta.getPrimaryKeys(null, null, tableName)) { + while (rs.next()) { + pks.add(rs.getString("COLUMN_NAME")); + } + } + + List fks = new ArrayList<>(); + try (ResultSet rs = meta.getImportedKeys(null, null, tableName)) { + while (rs.next()) { + fks.add( + rs.getString("FKCOLUMN_NAME") + + " → " + + rs.getString("PKTABLE_NAME") + + "." + + rs.getString("PKCOLUMN_NAME")); + } + } + + sb.append("### Columns\n"); + try (ResultSet rs = meta.getColumns(null, null, tableName, "%")) { + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String type = rs.getString("TYPE_NAME"); + String nullable = "YES".equals(rs.getString("IS_NULLABLE")) ? "" : " NOT NULL"; + String pk = pks.contains(col) ? " [PK]" : ""; + sb.append("- ") + .append(col) + .append(" (") + .append(type) + .append(nullable) + .append(pk) + .append(")\n"); + } + } + + if (!fks.isEmpty()) { + sb.append("\n### Foreign Keys\n"); + fks.forEach(fk -> sb.append("- ").append(fk).append("\n")); + } + + sb.append("\n### Sample Data (").append(SAMPLE_ROWS).append(" rows)\n"); + try (Statement stmt = conn.createStatement()) { + stmt.setMaxRows(SAMPLE_ROWS); + try (ResultSet rs = + stmt.executeQuery("SELECT * FROM " + tableName + " LIMIT " + SAMPLE_ROWS)) { + sb.append(formatResultSet(rs)); + } + } + + } catch (SQLException e) { + sb.append("Error describing table '") + .append(tableName) + .append("': ") + .append(e.getMessage()); + } + return sb.toString(); + } + + private static String formatResultSet(ResultSet rs) throws SQLException { + ResultSetMetaData meta = rs.getMetaData(); + int cols = meta.getColumnCount(); + + StringJoiner header = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + header.add(meta.getColumnName(i)); + } + + String separator = "-".repeat(header.toString().length()); + + List rows = new ArrayList<>(); + int count = 0; + while (rs.next()) { + StringJoiner row = new StringJoiner(" | "); + for (int i = 1; i <= cols; i++) { + Object val = rs.getObject(i); + row.add(val == null ? "NULL" : val.toString()); + } + rows.add(row.toString()); + count++; + } + + if (rows.isEmpty()) { + return "(no rows returned)"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(header).append("\n").append(separator).append("\n"); + rows.forEach(r -> sb.append(r).append("\n")); + if (count >= MAX_ROWS) { + sb.append("... (result truncated at ").append(MAX_ROWS).append(" rows)\n"); + } + return sb.toString(); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java new file mode 100644 index 000000000..a51409c0b --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java @@ -0,0 +1,170 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.ExecResult; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceProjectionApplier; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; + +/** + * In-process {@link Sandbox} that uses a local temp directory as the workspace (for examples). + * + *

Applies {@link WorkspaceProjectionApplier} payloads on {@link #start} and extracts tar + * archives in {@link #hydrateWorkspace} so host-projected skills match production behaviour. + */ +public class InMemorySandbox implements Sandbox { + + private final InMemorySandboxState state; + private final Path workspaceDir; + private final AtomicBoolean running = new AtomicBoolean(false); + private final int defaultTimeoutSeconds; + + public InMemorySandbox(InMemorySandboxState state, int defaultTimeoutSeconds) { + this.state = state; + this.workspaceDir = Path.of(state.getWorkspaceRoot()); + this.defaultTimeoutSeconds = defaultTimeoutSeconds; + } + + @Override + public void start() throws Exception { + if (!Files.exists(workspaceDir)) { + Files.createDirectories(workspaceDir); + } + applyWorkspaceProjectionIfChanged(state.getWorkspaceSpec()); + state.setWorkspaceRootReady(true); + running.set(true); + } + + private void applyWorkspaceProjectionIfChanged(WorkspaceSpec spec) throws Exception { + WorkspaceProjectionApplier.ProjectionPayload payload = + WorkspaceProjectionApplier.build(spec); + if (payload == null) { + return; + } + if (Objects.equals(payload.hash(), state.getWorkspaceProjectionHash())) { + return; + } + if (payload.fileCount() > 0) { + try (InputStream archive = new ByteArrayInputStream(payload.tarBytes())) { + hydrateWorkspace(archive); + } + } + state.setWorkspaceProjectionHash(payload.hash()); + } + + @Override + public void stop() throws Exception { + state.setWorkspaceRootReady(true); + running.set(false); + } + + @Override + public void shutdown() throws Exception { + // Leave workspace dir in place for resume in tests + } + + @Override + public void close() throws Exception { + try { + stop(); + } catch (Exception e) { + // best-effort + } + shutdown(); + } + + @Override + public boolean isRunning() { + return running.get(); + } + + @Override + public SandboxState getState() { + return state; + } + + @Override + public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { + int timeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeoutSeconds; + ProcessBuilder pb = new ProcessBuilder("sh", "-c", command); + pb.directory(workspaceDir.toFile()); + pb.redirectErrorStream(false); + Process process = pb.start(); + + boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + return new ExecResult(124, "", "Command timed out after " + timeout + "s", false); + } + + String stdout = new String(process.getInputStream().readAllBytes()); + String stderr = new String(process.getErrorStream().readAllBytes()); + return new ExecResult(process.exitValue(), stdout, stderr, false); + } + + @Override + public InputStream persistWorkspace() throws Exception { + return new ByteArrayInputStream(new byte[1024]); + } + + @Override + public void hydrateWorkspace(InputStream archive) throws Exception { + if (archive == null) { + return; + } + Path root = workspaceDir.normalize(); + try (TarArchiveInputStream tar = new TarArchiveInputStream(archive)) { + TarArchiveEntry entry; + while ((entry = tar.getNextEntry()) != null) { + if (entry.isDirectory()) { + continue; + } + String name = entry.getName(); + if (name.startsWith("/")) { + name = name.substring(1); + } + if (name.isBlank()) { + continue; + } + Path dest = root.resolve(name).normalize(); + if (!dest.startsWith(root)) { + throw new IOException("Tar entry escapes workspace: " + name); + } + Files.createDirectories(dest.getParent()); + try (OutputStream out = Files.newOutputStream(dest)) { + tar.transferTo(out); + } + } + } + } + + public Path getWorkspaceDir() { + return workspaceDir; + } +} diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java rename to agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java rename to agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java rename to agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java new file mode 100644 index 000000000..59d06f7c8 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/SharedInMemorySandboxStateStore.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxIsolationKey; +import io.agentscope.harness.agent.sandbox.SandboxStateStore; +import java.io.IOException; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +/** + * In-memory {@link SandboxStateStore} for examples: simulates a shared Redis-style slot map so + * multiple {@link io.agentscope.harness.agent.HarnessAgent} instances can resume the same user's + * sandbox metadata. + */ +public final class SharedInMemorySandboxStateStore implements SandboxStateStore { + + private final ConcurrentHashMap store = new ConcurrentHashMap<>(); + + private static String mapKey(SandboxIsolationKey key) { + return key.getScope().name() + ":" + key.getValue(); + } + + @Override + public Optional load(SandboxIsolationKey key) throws IOException { + String v = store.get(mapKey(key)); + return Optional.ofNullable(v); + } + + @Override + public void save(SandboxIsolationKey key, String json) throws IOException { + store.put(mapKey(key), json); + } + + @Override + public void delete(SandboxIsolationKey key) throws IOException { + store.remove(mapKey(key)); + } +} diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/application.properties b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/application.properties new file mode 100644 index 000000000..37ad2486c --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=harness-example-sandbox +server.port=8787 diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/io/agentscope/examples/harness/sandbox/chinook-default.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..f385c2651f80914c3b93c62431b0b000465a921b GIT binary patch literal 1007616 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


i$ls7I_D*~2++TE5+AovN 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%0Dfbgw6oB2DxAip79S2 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 RqHA=xT8F5W+Huig{|$mqR1N?D literal 0 HcmV?d00001 diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md new file mode 100644 index 000000000..1203157cd --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/knowledge/KNOWLEDGE.md @@ -0,0 +1,12 @@ +# Chinook Knowledge (sandbox demo) + +This Data Agent uses the Chinook SQLite sample database. + +Primary entities: +- `Artist` -> `Album` -> `Track` +- `Track` -> `InvoiceLine` -> `Invoice` -> `Customer` + +Guidance: +- Always discover schema with `sql_list_tables` and `sql_get_schema`. +- Use read-only `SELECT` statements. +- Add `LIMIT` when the user did not request full output. diff --git a/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md new file mode 100644 index 000000000..055899406 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-example-sandbox/src/main/resources/workspace/skills/query-writing/SKILL.md @@ -0,0 +1,14 @@ +--- +name: query-writing +description: Discover schema, write SELECT-only SQLite queries, execute, and explain results (aligned with harness-example). +--- + +# Query writing (sandbox) + +1. Call `sql_list_tables` if you do not yet know table names. +2. Call `sql_get_schema` for each table you join or filter on. +3. Run `sql_execute_query` with a single `SELECT` (add `LIMIT` for large scans). +4. Summarise results in plain language. + +See the full skill in `agentscope-examples/harness-example` under +`src/main/resources/workspace/skills/query-writing/SKILL.md` for multi-table JOIN patterns. diff --git a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java index 4a7e46411..4d8676e66 100644 --- a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java +++ b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/QuickstartExample.java @@ -20,10 +20,10 @@ import static io.agentscope.examples.harness.common.util.ExampleUtils.printWelcome; import static io.agentscope.examples.harness.common.util.ExampleUtils.startChat; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.memory.compaction.CompactionConfig; import java.nio.file.Files; import java.nio.file.Path; diff --git a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java index 51baf24d5..ae80abac0 100644 --- a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java +++ b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/TextToSqlExample.java @@ -19,11 +19,11 @@ import static io.agentscope.examples.harness.common.util.ExampleUtils.runHarnessTurn; import static io.agentscope.examples.harness.common.util.ExampleUtils.startHarnessChat; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.core.tool.Toolkit; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; diff --git a/agentscope-examples/harness-examples/harness-sandbox/pom.xml b/agentscope-examples/harness-examples/harness-sandbox-docker/pom.xml similarity index 97% rename from agentscope-examples/harness-examples/harness-sandbox/pom.xml rename to agentscope-examples/harness-examples/harness-sandbox-docker/pom.xml index 28ef753fc..90d4ea694 100644 --- a/agentscope-examples/harness-examples/harness-sandbox/pom.xml +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/pom.xml @@ -28,7 +28,7 @@ AgentScope Java - Harness Sandbox Example io.agentscope.examples - harness-example-sandbox + harness-sandbox-docker jar Runnable examples: local filesystem, in-memory sandbox isolation scopes, and store-backed namespaces (no remote LLM required) diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/docker/python-sandbox/Dockerfile similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/docker/python-sandbox/Dockerfile rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/docker/python-sandbox/Dockerfile diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java similarity index 99% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java index 110119ab1..f1c75e9eb 100644 --- a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java @@ -21,10 +21,10 @@ import static io.agentscope.examples.harness.common.util.ExampleUtils.startChat; import static io.agentscope.examples.harness.sandbox.DockerPythonSandboxImage.ensureImage; +import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.RuntimeContext; import io.agentscope.harness.agent.sandbox.filesystem.DockerFilesystemSpec; import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; import java.nio.file.Files; diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java new file mode 100644 index 000000000..88b9c6c16 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java @@ -0,0 +1,122 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.agentscope.harness.agent.sandbox.Sandbox; +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.SandboxState; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +/** In-process {@link SandboxClient} that allocates local temp directories as sandboxes. */ +public class InMemorySandboxClient implements SandboxClient { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final int DEFAULT_TIMEOUT_SECONDS = 30; + + private final AtomicInteger createCount = new AtomicInteger(0); + private final AtomicInteger resumeCount = new AtomicInteger(0); + private final Path baseDir; + + public InMemorySandboxClient() { + try { + this.baseDir = Files.createTempDirectory("agentscope-inmemory-sandbox-"); + } catch (IOException e) { + throw new UncheckedIOException( + "Failed to create base temp dir for InMemorySandboxClient", e); + } + } + + @Override + public Sandbox create( + WorkspaceSpec workspaceSpec, + SandboxSnapshotSpec snapshotSpec, + SandboxClientOptions options) { + createCount.incrementAndGet(); + String sessionId = UUID.randomUUID().toString(); + Path workspaceDir = baseDir.resolve(sessionId); + try { + Files.createDirectories(workspaceDir); + } catch (IOException e) { + throw new UncheckedIOException("Failed to create workspace dir", e); + } + + InMemorySandboxState state = new InMemorySandboxState(sessionId, workspaceDir.toString()); + WorkspaceSpec spec = workspaceSpec != null ? workspaceSpec.copy() : new WorkspaceSpec(); + spec.setRoot(workspaceDir.toString()); + state.setWorkspaceSpec(spec); + + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public Sandbox resume(SandboxState sessionState) { + resumeCount.incrementAndGet(); + InMemorySandboxState state = (InMemorySandboxState) sessionState; + return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); + } + + @Override + public void delete(Sandbox session) { + // no-op + } + + @Override + public String serializeState(SandboxState state) { + try { + InMemorySandboxState s = (InMemorySandboxState) state; + return MAPPER.writeValueAsString(new StateDto(s.getSessionId(), s.getWorkspaceRoot())); + } catch (IOException e) { + throw new UncheckedIOException("Failed to serialize sandbox state", e); + } + } + + @Override + public SandboxState deserializeState(String json) { + try { + StateDto dto = MAPPER.readValue(json, StateDto.class); + InMemorySandboxState state = + new InMemorySandboxState(dto.sessionId(), dto.workspaceRoot()); + state.setWorkspaceRootReady(true); + return state; + } catch (IOException e) { + throw new UncheckedIOException("Failed to deserialize sandbox state", e); + } + } + + public int getCreateCount() { + return createCount.get(); + } + + public int getResumeCount() { + return resumeCount.get(); + } + + public void resetCounts() { + createCount.set(0); + resumeCount.set(0); + } + + record StateDto(String sessionId, String workspaceRoot) {} +} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java new file mode 100644 index 000000000..b34b7e5fb --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java @@ -0,0 +1,81 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxClient; +import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import io.agentscope.harness.agent.sandbox.WorkspaceSpec; +import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; +import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; + +/** + * {@link SandboxFilesystemSpec} backed by an {@link InMemorySandboxClient}. + * + *

Uses a local temp directory as the sandbox workspace. No Docker or external services are + * required. The {@link InMemorySandboxClient} exposes create/resume counters to illustrate + * {@link io.agentscope.harness.agent.IsolationScope} behaviour. + */ +public class InMemorySandboxFilesystemSpec extends SandboxFilesystemSpec { + + private final InMemorySandboxClient client; + + /** + * Creates a spec backed by the given in-memory sandbox client. + * + * @param client the in-memory client to use for session create/resume + */ + public InMemorySandboxFilesystemSpec(InMemorySandboxClient client) { + this.client = client; + } + + /** + * Creates a spec with a new default {@link InMemorySandboxClient}. + */ + public InMemorySandboxFilesystemSpec() { + this(new InMemorySandboxClient()); + } + + /** + * Returns the underlying {@link InMemorySandboxClient}. + * + * @return the client + */ + public InMemorySandboxClient getClient() { + return client; + } + + @Override + protected SandboxClient createClient() { + return client; + } + + @Override + protected SandboxClientOptions clientOptions() { + return null; + } + + @Override + protected SandboxSnapshotSpec snapshotSpec() { + return null; + } + + @Override + protected WorkspaceSpec workspaceSpec() { + WorkspaceSpec s = new WorkspaceSpec(); + s.setRoot("/workspace"); + return s; + } +} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java new file mode 100644 index 000000000..d2be8fc79 --- /dev/null +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024-2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.agentscope.examples.harness.sandbox.support; + +import io.agentscope.harness.agent.sandbox.SandboxState; + +/** + * In-memory {@link SandboxState} for {@link InMemorySandboxClient}. + */ +public class InMemorySandboxState extends SandboxState { + + private String workspaceRoot; + + public InMemorySandboxState() {} + + public InMemorySandboxState(String sessionId, String workspaceRoot) { + setSessionId(sessionId); + this.workspaceRoot = workspaceRoot; + } + + public String getWorkspaceRoot() { + return workspaceRoot; + } + + public void setWorkspaceRoot(String workspaceRoot) { + this.workspaceRoot = workspaceRoot; + } +} diff --git a/agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java similarity index 100% rename from agentscope-examples/harness-examples/harness-sandbox/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java rename to agentscope-examples/harness-examples/harness-sandbox-docker/src/test/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImageTest.java diff --git a/agentscope-examples/harness-examples/pom.xml b/agentscope-examples/harness-examples/pom.xml index b98fb7361..b6138a18b 100644 --- a/agentscope-examples/harness-examples/pom.xml +++ b/agentscope-examples/harness-examples/pom.xml @@ -22,6 +22,9 @@ harness-example-common harness-quickstart - harness-sandbox + harness-sandbox-docker + harness-example-local + harness-example-sandbox + harness-example-remote From d508ae1840f0137552c17ebcbdc518e9ba07a14b Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 18:31:22 +0800 Subject: [PATCH 22/28] update harness example --- .../harness-example-local/.env.example | 22 ----------------- .../main/resources/agentscope.json.example | 24 ------------------- 2 files changed, 46 deletions(-) delete mode 100644 agentscope-examples/harness-examples/harness-example-local/.env.example delete mode 100644 agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example diff --git a/agentscope-examples/harness-examples/harness-example-local/.env.example b/agentscope-examples/harness-examples/harness-example-local/.env.example deleted file mode 100644 index 3a20c5633..000000000 --- a/agentscope-examples/harness-examples/harness-example-local/.env.example +++ /dev/null @@ -1,22 +0,0 @@ -# ───────────────────────────────────────────────────────────── -# AgentScope Harness Example — Environment Variables -# Copy this file to .env and fill in your values. -# ───────────────────────────────────────────────────────────── - -# Required: DashScope API key (https://dashscope.aliyun.com/) -DASHSCOPE_API_KEY=your_api_key_here - -# Optional: LLM model to use (default: qwen-max) -# Other options: qwen-plus, qwen-turbo, qwen-long -AGENTSCOPE_MODEL=qwen-max - -# Optional: path to the Chinook SQLite database (default: chinook.db). -# If this file does not exist, the example copies the bundled sample from the JAR (no curl needed). -AGENTSCOPE_DB_PATH=chinook.db - -# Optional: workspace directory (default: .agentscope/workspace) -# Modify the files here to customise agent behaviour without recompiling. -AGENTSCOPE_WORKSPACE=.agentscope/workspace - -# Optional: Log4j2 level for io.agentscope loggers (default: INFO). Example: DEBUG, TRACE -# AGENTSCOPE_LOG_LEVEL=DEBUG diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example deleted file mode 100644 index a09a7c4eb..000000000 --- a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/agentscope.json.example +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://agentscope.io/schema/agentscope.json", - "main": "text-to-sql", - "agents": { - "text-to-sql": { - "name": "Text-to-SQL", - "description": "Answers natural-language questions about the Chinook music store database by translating them into SQL and executing the queries.", - "workspace": ".agentscope/workspace", - "maxIters": 20 - }, - "schema-analyst": { - "name": "Schema Analyst", - "description": "Deep schema analysis and documentation specialist. Loaded on-demand from workspace/subagents/schema-analyst.md.", - "workspace": ".agentscope/workspace", - "maxIters": 10 - } - }, - "channels": { - "chatui": { - "defaultAgentId": "text-to-sql", - "dmScope": "MAIN" - } - } -} From e58fa551d8864902c49922991f63e5b09d8c7e2b Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 18:40:23 +0800 Subject: [PATCH 23/28] code format --- .../agentscope/core/model/ModelRegistry.java | 2 +- .../src/main/resources/log4j2.xml | 15 ++++++++++++ .../harness-quickstart/.env.example | 22 ----------------- .../main/resources/agentscope.json.example | 24 ------------------- .../src/main/resources/log4j2.xml | 15 ++++++++++++ .../src/main/docker/python-sandbox/Dockerfile | 14 +++++++++++ agentscope-examples/harness-examples/pom.xml | 16 +++++++++++++ 7 files changed, 61 insertions(+), 47 deletions(-) delete mode 100644 agentscope-examples/harness-examples/harness-quickstart/.env.example delete mode 100644 agentscope-examples/harness-examples/harness-quickstart/src/main/resources/agentscope.json.example diff --git a/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java b/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java index e6d5637a7..101889b22 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java +++ b/agentscope-core/src/main/java/io/agentscope/core/model/ModelRegistry.java @@ -122,7 +122,7 @@ public static void register(String name, Model model) { * Pattern#matches}. Newly registered factories are consulted before older user registrations * and before built-in providers. * - * @param modelNameRegex regex with semantics of {@link Pattern#matches(CharSequence)} on the + * @param modelNameRegex regex with semantics of Pattern#matches(CharSequence) on the * full model id * @param factory creates a {@link Model} from the full model id */ diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml index b6ecbb49f..995cbb683 100644 --- a/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/resources/log4j2.xml @@ -1,4 +1,19 @@ + + 4.0.0 From a8c9561431722fff6d691662947e54d4462f1c22 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 19:14:57 +0800 Subject: [PATCH 24/28] feat: enhance SandboxDistributedOptions and related tests for improved isolation scope handling --- .../harness/agent/HarnessAgent.java | 26 ++++++------- .../sandbox/SandboxDistributedOptions.java | 38 ++++++------------- .../HarnessAgentDistributedSandboxTest.java | 4 +- .../harness/agent/HarnessAgentTest.java | 2 + ...teFilesystemIsolationScopeExampleTest.java | 6 +++ ...oxFilesystemIsolationScopeExampleTest.java | 21 ++++++++++ docs/zh/harness/sandbox.md | 2 +- 7 files changed, 55 insertions(+), 44 deletions(-) diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 9626fe4e8..780ff1e29 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -719,14 +719,17 @@ public Builder session(Session session) { /** * Enables high-level distributed sandbox configuration. * - *

This helper bundles three distributed concerns: + *

Bundles distributed concerns that pair with {@link #filesystem(SandboxFilesystemSpec)}: + * *

    - *
  • distributed {@link Session} for sandbox state slots
  • - *
  • remote/non-noop {@link io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec} - * for workspace archive persistence
  • - *
  • {@link IsolationScope} for sharing granularity
  • + *
  • distributed {@link Session} for sandbox state slots + *
  • optional {@link io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec} + * override for workspace archive persistence + *
  • {@code requireDistributed} gate for fail-fast validation *
* + *

Configure {@link IsolationScope} on the {@code SandboxFilesystemSpec} only. + * *

Requires sandbox mode (i.e. {@link #filesystem(SandboxFilesystemSpec)}). */ public Builder sandboxDistributed(SandboxDistributedOptions options) { @@ -917,15 +920,10 @@ public HarnessAgent build() { SandboxContext defaultSandboxContext = null; SandboxBackedFilesystem capturedSandboxFs = null; if (sandboxFilesystemSpec != null) { - if (sandboxDistributedOptions != null) { - if (sandboxDistributedOptions.getIsolationScope() != null) { - sandboxFilesystemSpec.isolationScope( - sandboxDistributedOptions.getIsolationScope()); - } - if (sandboxDistributedOptions.getSnapshotSpec() != null) { - sandboxFilesystemSpec.snapshotSpec( - sandboxDistributedOptions.getSnapshotSpec()); - } + if (sandboxDistributedOptions != null + && sandboxDistributedOptions.getSnapshotSpec() != null) { + sandboxFilesystemSpec.snapshotSpec( + sandboxDistributedOptions.getSnapshotSpec()); } capturedSandboxFs = new SandboxBackedFilesystem(); capturedSandboxFs.configureNamespace(buildDynamicNamespaceFactory(userIdRef)); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java index c4c3758ba..b67db4fbb 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/SandboxDistributedOptions.java @@ -16,35 +16,35 @@ package io.agentscope.harness.agent.sandbox; import io.agentscope.core.session.Session; -import io.agentscope.harness.agent.IsolationScope; import io.agentscope.harness.agent.sandbox.snapshot.OssSnapshotSpec; import io.agentscope.harness.agent.sandbox.snapshot.RedisSnapshotSpec; import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; -import java.util.Objects; /** * High-level distributed sandbox configuration used by * {@link io.agentscope.harness.agent.HarnessAgent.Builder#sandboxDistributed}. * - *

This options object intentionally bundles the three pieces required for - * distributed sandbox restore/sharing: + *

Bundles the pieces required for distributed sandbox restore/sharing that are not already on + * {@link io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec}: + * *

    - *
  • distributed {@link Session} (for state-store slots)
  • - *
  • {@link SandboxSnapshotSpec} (for workspace archive persistence)
  • - *
  • {@link IsolationScope} (for sharing granularity)
  • + *
  • distributed {@link Session} (for state-store slots) + *
  • optional {@link SandboxSnapshotSpec} override (workspace archive persistence) + *
  • {@code requireDistributed} — fail-fast when distributed prerequisites are not met *
+ * + *

Configure {@link io.agentscope.harness.agent.IsolationScope} on {@code SandboxFilesystemSpec} + * only; it is not duplicated here. */ public final class SandboxDistributedOptions { private final Session session; private final SandboxSnapshotSpec snapshotSpec; - private final IsolationScope isolationScope; private final boolean requireDistributed; private SandboxDistributedOptions(Builder builder) { this.session = builder.session; this.snapshotSpec = builder.snapshotSpec; - this.isolationScope = builder.isolationScope; this.requireDistributed = builder.requireDistributed; } @@ -52,9 +52,9 @@ private SandboxDistributedOptions(Builder builder) { * Creates a builder with safe distributed defaults. * *

Defaults: + * *

    - *
  • {@code isolationScope = USER}
  • - *
  • {@code requireDistributed = true}
  • + *
  • {@code requireDistributed = true} *
*/ public static Builder builder() { @@ -89,13 +89,6 @@ public SandboxSnapshotSpec getSnapshotSpec() { return snapshotSpec; } - /** - * Returns the isolation scope for sandbox state sharing. - */ - public IsolationScope getIsolationScope() { - return isolationScope; - } - /** * Whether builder should fail-fast when distributed prerequisites are not met. */ @@ -107,7 +100,6 @@ public static final class Builder { private Session session; private SandboxSnapshotSpec snapshotSpec; - private IsolationScope isolationScope = IsolationScope.USER; private boolean requireDistributed = true; private Builder() {} @@ -128,14 +120,6 @@ public Builder snapshotSpec(SandboxSnapshotSpec snapshotSpec) { return this; } - /** - * Sets sandbox isolation scope. Default is {@link IsolationScope#USER}. - */ - public Builder isolationScope(IsolationScope isolationScope) { - this.isolationScope = Objects.requireNonNull(isolationScope, "isolationScope"); - return this; - } - /** * Enables/disables fail-fast checks for distributed prerequisites. * diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java index bf26c5c31..f8a121cc0 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentDistributedSandboxTest.java @@ -107,16 +107,16 @@ void sandboxMode_explicitSandboxDistributed_alsoFailsOnLocalSession() { } @Test - void sandboxDistributed_appliesIsolationAndSnapshotOverride() { + void sandboxDistributed_appliesSnapshotOverride() { Session distributedSession = mock(Session.class); DockerFilesystemSpec spec = new DockerFilesystemSpec(); + spec.isolationScope(IsolationScope.AGENT); LocalSnapshotSpec snapshotSpec = new LocalSnapshotSpec(workspace.resolve("snapshots")); SandboxDistributedOptions options = SandboxDistributedOptions.builder() .session(distributedSession) .snapshotSpec(snapshotSpec) - .isolationScope(IsolationScope.AGENT) .build(); assertDoesNotThrow( diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java index 899cfbb8b..f3f3ca386 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java @@ -30,6 +30,7 @@ import io.agentscope.core.model.ChatResponse; import io.agentscope.core.model.Model; import io.agentscope.core.model.ToolSchema; +import io.agentscope.core.session.Session; import io.agentscope.harness.agent.filesystem.LocalFilesystem; import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; import io.agentscope.harness.agent.hook.SubagentsHook.SubagentEntry; @@ -207,6 +208,7 @@ void remoteFilesystemSpec_sharesMemoryMdInNonsandboxMode() throws Exception { .model(stubModel("ok")) .workspace(workspace) .filesystem(new RemoteFilesystemSpec(store)) + .session(mock(Session.class)) .build(); agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared-memory"); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java index 5109e40e0..207171ab1 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/RemoteFilesystemIsolationScopeExampleTest.java @@ -28,6 +28,7 @@ import io.agentscope.core.message.TextBlock; import io.agentscope.core.model.ChatResponse; import io.agentscope.core.model.Model; +import io.agentscope.core.session.Session; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; @@ -99,6 +100,7 @@ void sessionScope_differentSessions_isolatedNamespaces() throws Exception { .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) + .session(mock(Session.class)) .build(); // Call as session-1 and write MEMORY.md @@ -132,6 +134,7 @@ void sessionScope_sameSession_sharedNamespace() throws Exception { .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.SESSION)) + .session(mock(Session.class)) .build(); // First call writes MEMORY.md under session-1 @@ -168,6 +171,7 @@ void userScope_sameUser_sharedAcrossSessions() throws Exception { .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .session(mock(Session.class)) .build(); // Call as alice / session-a and write MEMORY.md @@ -201,6 +205,7 @@ void userScope_differentUsers_isolatedNamespaces() throws Exception { .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem( new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) + .session(mock(Session.class)) .build(); agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); @@ -235,6 +240,7 @@ void agentScope_allCallersShareOneNamespace() throws Exception { .filesystem( new RemoteFilesystemSpec(store) .isolationScope(IsolationScope.AGENT)) + .session(mock(Session.class)) .build(); // Alice writes diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java index a3527705d..0e367f23f 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -29,6 +29,7 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; import io.agentscope.harness.agent.example.support.InMemorySandboxClient; import io.agentscope.harness.agent.example.support.InMemorySandboxFilesystemSpec; import java.nio.file.Files; @@ -91,6 +92,10 @@ void sessionScope_sameSession_resumesSandbox() throws Exception { .model(stubModel("done")) .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .build(); // First call — no persisted state → create @@ -121,6 +126,10 @@ void sessionScope_differentSession_createsFreshSandbox() throws Exception { .model(stubModel("done")) .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .build(); agent.call(userMsg("call from session-1"), ctx("session-2-1", "alice")).block(); @@ -155,6 +164,10 @@ void userScope_sameUser_differentSessions_resumesSandbox() throws Exception { .model(stubModel("done")) .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .build(); agent.call(userMsg("session A"), ctx("session-a", "alice")).block(); @@ -184,6 +197,10 @@ void userScope_differentUsers_createsFreshSandbox() throws Exception { .model(stubModel("done")) .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .build(); agent.call(userMsg("hi from alice2"), ctx("s1", "alice2")).block(); @@ -217,6 +234,10 @@ void agentScope_allCallsShareOneSandbox() throws Exception { .model(stubModel("done")) .workspace(workspace.toAbsolutePath().normalize().toString()) .filesystem(spec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .build(); // Different users, different sessions — all share one AGENT-scoped sandbox diff --git a/docs/zh/harness/sandbox.md b/docs/zh/harness/sandbox.md index c5ddd2295..e99ddbe5c 100644 --- a/docs/zh/harness/sandbox.md +++ b/docs/zh/harness/sandbox.md @@ -274,7 +274,7 @@ call 3: shell_execute("cat results.csv") → 读 call 2 产生的文件 `HarnessAgent.Builder#sandboxDistributed(SandboxDistributedOptions)` 可统一下发: -- 覆盖/合并 **`isolationScope`** 与 **`snapshotSpec`**(若提供); +- 覆盖 **`snapshotSpec`**(若提供);**`IsolationScope` 只在 `SandboxFilesystemSpec` 上配置**,不在此重复; - 在选项中**显式指定**用于沙箱的 `Session`(若与主 `session` 不同); - 使用 `SandboxDistributedOptions#oss` / `#redis` 等辅助构造常见组合(见类 JavaDoc)。 From cafb9d7367349138d8154f7dc1b868b65768b1ef Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 22:23:43 +0800 Subject: [PATCH 25/28] code format --- .../main/java/io/agentscope/harness/agent/HarnessAgent.java | 3 +-- .../example/SandboxFilesystemIsolationScopeExampleTest.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java index 780ff1e29..189f1bade 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgent.java @@ -922,8 +922,7 @@ public HarnessAgent build() { if (sandboxFilesystemSpec != null) { if (sandboxDistributedOptions != null && sandboxDistributedOptions.getSnapshotSpec() != null) { - sandboxFilesystemSpec.snapshotSpec( - sandboxDistributedOptions.getSnapshotSpec()); + sandboxFilesystemSpec.snapshotSpec(sandboxDistributedOptions.getSnapshotSpec()); } capturedSandboxFs = new SandboxBackedFilesystem(); capturedSandboxFs.configureNamespace(buildDynamicNamespaceFactory(userIdRef)); diff --git a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java index 0e367f23f..f63d5bd95 100644 --- a/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java +++ b/agentscope-harness/src/test/java/io/agentscope/harness/agent/example/SandboxFilesystemIsolationScopeExampleTest.java @@ -29,9 +29,9 @@ import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; import io.agentscope.harness.agent.example.support.InMemorySandboxClient; import io.agentscope.harness.agent.example.support.InMemorySandboxFilesystemSpec; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; From 8cdd055662a622cc8933b15f039fde7409879fe4 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 7 May 2026 23:01:06 +0800 Subject: [PATCH 26/28] fix javadoc --- .../harness/example/WorkspaceInitializer.java | 2 +- .../harness/example/WorkspaceInitializer.java | 2 +- .../sandbox/HarnessSandboxExampleApp.java | 53 ------ ...calFilesystemPersonalAssistantExample.java | 120 ------------- ...RemoteFilesystemIsolationScopeExample.java | 168 ----------------- ...andboxFilesystemIsolationScopeExample.java | 170 ------------------ .../harness/agent/hook/MemoryFlushHook.java | 5 +- .../snapshot/RedisRemoteSnapshotClient.java | 2 +- .../sandbox/snapshot/RedisSnapshotSpec.java | 2 +- 9 files changed, 6 insertions(+), 518 deletions(-) delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java diff --git a/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java index 1fec9b2f7..264066803 100644 --- a/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java +++ b/agentscope-examples/harness-examples/harness-example-local/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java @@ -38,7 +38,7 @@ * the JAR. When the example is run for the first time, {@link #init(Path)} extracts them into the * given workspace directory so the agent can read and modify them at runtime. * - *

Workspace structure

+ * Workspace structure: * *
  * <workspace>/
diff --git a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java
index 1fec9b2f7..264066803 100644
--- a/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java
+++ b/agentscope-examples/harness-examples/harness-quickstart/src/main/java/io/agentscope/harness/example/WorkspaceInitializer.java
@@ -38,7 +38,7 @@
  * the JAR. When the example is run for the first time, {@link #init(Path)} extracts them into the
  * given workspace directory so the agent can read and modify them at runtime.
  *
- * 

Workspace structure

+ * Workspace structure: * *
  * <workspace>/
diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java
deleted file mode 100644
index b29ef11b2..000000000
--- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/HarnessSandboxExampleApp.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2024-2026 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.agentscope.examples.harness.sandbox;
-
-import io.agentscope.examples.harness.common.model.FixedReplyModel;
-import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec;
-
-/**
- * Runs harness filesystem examples (local, in-memory sandbox, in-memory store). No LLM API key
- * required — uses {@link FixedReplyModel} for a single turn per {@code call}. The
- * {@code store} mode is an alias for {@code remote} (shared KV / {@link RemoteFilesystemSpec}).
- *
- * 

Usage: {@code java ... HarnessSandboxExampleApp [all|local|sandbox|remote|store|docker-python]} - */ -public final class HarnessSandboxExampleApp { - - public static void main(String[] args) throws Exception { - String mode = args.length == 0 ? "all" : args[0].toLowerCase(); - System.out.println( - "Model: " + FixedReplyModel.done().getModelName() + " (no remote LLM)\n"); - switch (mode) { - case "all" -> { - LocalFilesystemPersonalAssistantExample.main(new String[0]); - System.out.println(); - SandboxFilesystemIsolationScopeExample.main(new String[0]); - System.out.println(); - RemoteFilesystemIsolationScopeExample.main(new String[0]); - } - case "local" -> LocalFilesystemPersonalAssistantExample.main(new String[0]); - case "sandbox" -> SandboxFilesystemIsolationScopeExample.main(new String[0]); - case "remote", "store" -> RemoteFilesystemIsolationScopeExample.main(new String[0]); - case "docker-python" -> DockerPythonSandboxExample.main(new String[0]); - default -> { - System.err.println("Unknown mode: " + mode); - System.err.println("Use: all | local | sandbox | remote | store | docker-python"); - System.exit(1); - } - } - } -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java deleted file mode 100644 index 3d5fbb2b5..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/LocalFilesystemPersonalAssistantExample.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; -import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; - -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.common.model.FixedReplyModel; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.filesystem.LocalFilesystemWithShell; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Example: local personal-assistant mode using {@link LocalFilesystemWithShell} — direct disk I/O - * and {@link ProcessBuilder} shell in one workspace, no container or distributed store. - */ -public final class LocalFilesystemPersonalAssistantExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-local-fs-example-"); - System.out.println("Workspace: " + workspace.toAbsolutePath()); - - demonstrateFilesPersistAcrossCalls(workspace, model); - demonstrateSharedWorkspaceForAllUsersAndSessions(workspace, model); - demonstrateHostWrittenFileVisibleToAgent(workspace, model); - - System.out.println("Local filesystem example finished successfully."); - } - - static void demonstrateFilesPersistAcrossCalls(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - agent.call(userMsg("first call"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "# Notes\n- item 1"); - - Path memoryFile = workspace.resolve("MEMORY.md"); - if (!Files.isRegularFile(memoryFile)) { - throw new IllegalStateException("MEMORY.md should exist on disk after first call"); - } - String content = Files.readString(memoryFile, StandardCharsets.UTF_8); - if (!content.contains("item 1")) { - throw new IllegalStateException("MEMORY.md should contain persisted item"); - } - - agent.call(userMsg("second call"), ctx("session-2", "alice")).block(); - if (!Files.isRegularFile(memoryFile)) { - throw new IllegalStateException("MEMORY.md should still exist after second call"); - } - if (!content.equals(Files.readString(memoryFile, StandardCharsets.UTF_8))) { - throw new IllegalStateException("MEMORY.md content should be unchanged"); - } - System.out.println("[local] files persist across calls: OK"); - } - - static void demonstrateSharedWorkspaceForAllUsersAndSessions(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - agent.call(userMsg("alice here"), ctx("session-alice", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("shared.txt", "alice was here"); - agent.call(userMsg("bob here"), ctx("session-bob", "bob")).block(); - if (!Files.isRegularFile(workspace.resolve("shared.txt"))) { - throw new IllegalStateException( - "local workspace is not partitioned by user or session"); - } - System.out.println("[local] same workspace for all user/session context values: OK"); - } - - static void demonstrateHostWrittenFileVisibleToAgent(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - HarnessAgent agent = - HarnessAgent.builder() - .name("my-local-assistant") - .model(model) - .workspace(workspace) - .abstractFilesystem(new LocalFilesystemWithShell(workspace)) - .build(); - - Path doc = workspace.resolve("document.txt"); - Files.writeString(doc, "Host-written document content"); - agent.call(userMsg("check document"), ctx("s1", "user")).block(); - String read = agent.getWorkspaceManager().readManagedWorkspaceFileUtf8("document.txt"); - if (read == null || !read.contains("Host-written")) { - throw new IllegalStateException("agent should read host-written file"); - } - System.out.println("[local] host file visible to workspace manager: OK"); - } -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java deleted file mode 100644 index bacf72614..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/RemoteFilesystemIsolationScopeExample.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; -import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; - -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.common.model.FixedReplyModel; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import io.agentscope.harness.agent.filesystem.RemoteFilesystemSpec; -import io.agentscope.harness.agent.store.InMemoryStore; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -/** - * Example: {@link RemoteFilesystemSpec} with in-memory key-value store and different {@link - * IsolationScope} namespaces. - */ -public final class RemoteFilesystemIsolationScopeExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-store-isolation-example-"); - System.out.println("Workspace: " + workspace.toAbsolutePath()); - - sessionScopeIsolated(model, workspace); - sessionScopeSharedWithinSession(model, workspace); - userScopeSharedAcrossSessions(model, workspace); - userScopeIsolatedByUser(model, workspace); - agentScopeSharedByAllCallers(model, workspace); - - System.out.println("Store isolation example finished successfully."); - } - - static void sessionScopeIsolated(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.SESSION)) - .build(); - - agent.call(userMsg("from session-1"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "session-1 notes"); - if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") - == null) { - throw new IllegalStateException("data should exist under session-1"); - } - if (store.get(List.of("agents", "assistant", "sessions", "session-2"), "/MEMORY.md") - != null) { - throw new IllegalStateException("session-2 namespace should be empty"); - } - System.out.println("[store] SESSION: per-session namespace: OK"); - } - - static void sessionScopeSharedWithinSession(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.SESSION)) - .build(); - - agent.call(userMsg("call 1"), ctx("session-1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared memory"); - agent.call(userMsg("call 2"), ctx("session-1", "alice")).block(); - if (store.get(List.of("agents", "assistant", "sessions", "session-1"), "/MEMORY.md") - == null) { - throw new IllegalStateException("MEMORY under session-1"); - } - System.out.println("[store] SESSION: same session reuses key: OK"); - } - - static void userScopeSharedAcrossSessions(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) - .build(); - - agent.call(userMsg("hi from session-a"), ctx("session-a", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's memory"); - if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { - throw new IllegalStateException("data under user alice"); - } - agent.call(userMsg("hi from session-b"), ctx("session-b", "alice")).block(); - if (store.get(List.of("agents", "assistant", "users", "alice"), "/MEMORY.md") == null) { - throw new IllegalStateException("alice's key still present"); - } - System.out.println("[store] USER: one namespace per user: OK"); - } - - static void userScopeIsolatedByUser(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store).isolationScope(IsolationScope.USER)) - .build(); - - agent.call(userMsg("alice writes"), ctx("s1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "alice's data"); - if (store.get(List.of("agents", "assistant", "users", "bob"), "/MEMORY.md") != null) { - throw new IllegalStateException("bob should not see alice's data"); - } - System.out.println("[store] USER: users are isolated: OK"); - } - - static void agentScopeSharedByAllCallers(Model model, Path workspace) throws Exception { - Files.createDirectories(workspace); - InMemoryStore store = new InMemoryStore(); - HarnessAgent agent = - HarnessAgent.builder() - .name("shared-assistant") - .model(model) - .workspace(workspace) - .filesystem( - new RemoteFilesystemSpec(store) - .isolationScope(IsolationScope.AGENT)) - .build(); - - agent.call(userMsg("alice"), ctx("s1", "alice")).block(); - agent.getWorkspaceManager().writeUtf8WorkspaceRelative("MEMORY.md", "shared knowledge"); - if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { - throw new IllegalStateException("shared namespace"); - } - agent.call(userMsg("bob"), ctx("s2", "bob")).block(); - if (store.get(List.of("agents", "shared-assistant", "shared"), "/MEMORY.md") == null) { - throw new IllegalStateException("data still in shared"); - } - System.out.println("[store] AGENT: shared key for all callers: OK"); - } -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java deleted file mode 100644 index ed41f9d5c..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/SandboxFilesystemIsolationScopeExample.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox; - -import static io.agentscope.examples.harness.common.util.ExampleUtils.ctx; -import static io.agentscope.examples.harness.common.util.ExampleUtils.userMsg; - -import io.agentscope.core.model.Model; -import io.agentscope.examples.harness.common.model.FixedReplyModel; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxClient; -import io.agentscope.examples.harness.sandbox.support.InMemorySandboxFilesystemSpec; -import io.agentscope.harness.agent.HarnessAgent; -import io.agentscope.harness.agent.IsolationScope; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Example: sandbox filesystem with {@link IsolationScope} (in-process {@link InMemorySandboxClient} - * simulates create/resume without Docker). - */ -public final class SandboxFilesystemIsolationScopeExample { - - public static void main(String[] args) throws Exception { - Model model = FixedReplyModel.done(); - Path workspace = Files.createTempDirectory("harness-sandbox-isolation-example-"); - System.out.println("Control workspace: " + workspace.toAbsolutePath()); - - sessionScopeSameSessionResumes(workspace, model); - sessionScopeDifferentSessionCreatesTwo(workspace, model); - userScopeSameUserResumesAcrossSessions(workspace, model); - userScopeDifferentUsersGetTwoSandboxes(workspace, model); - agentScopeEveryoneSharesOneSandbox(workspace, model); - - System.out.println("Sandbox isolation example finished successfully."); - } - - static void sessionScopeSameSessionResumes(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.SESSION); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("hello"), ctx("session-1", null)).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 0) { - throw new IllegalStateException("expected 1 create, 0 resume after first call"); - } - agent.call(userMsg("hello again"), ctx("session-1", null)).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { - throw new IllegalStateException("expected 1 create, 1 resume for same session"); - } - System.out.println("[sandbox] SESSION: same session resumes: OK"); - } - - static void sessionScopeDifferentSessionCreatesTwo(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.SESSION); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call( - userMsg("call from session-DifferentSessionCreatesTwo-1"), - ctx("session-DifferentSessionCreatesTwo-1", "alice")) - .block(); - agent.call( - userMsg("call from session-DifferentSessionCreatesTwo-2"), - ctx("session-DifferentSessionCreatesTwo-2", "alice")) - .block(); - if (client.getCreateCount() != 2 || client.getResumeCount() != 0) { - throw new IllegalStateException("expected 2 creates for distinct sessions"); - } - System.out.println("[sandbox] SESSION: different sessions get new sandboxes: OK"); - } - - static void userScopeSameUserResumesAcrossSessions(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.USER); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("session A"), ctx("session-a", "alice")).block(); - if (client.getCreateCount() != 1) { - throw new IllegalStateException("expected 1 create"); - } - agent.call(userMsg("session B"), ctx("session-b", "alice")).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 1) { - throw new IllegalStateException("same user should resume across sessions"); - } - System.out.println("[sandbox] USER: same user resumes across sessions: OK"); - } - - static void userScopeDifferentUsersGetTwoSandboxes(Path workspace, Model model) - throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.USER); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("hi from alice2"), ctx("s1", "alice2")).block(); - agent.call(userMsg("hi from bob2"), ctx("s2", "bob2")).block(); - if (client.getCreateCount() != 2) { - throw new IllegalStateException("each user should get a new sandbox"); - } - System.out.println("[sandbox] USER: different users are isolated: OK"); - } - - static void agentScopeEveryoneSharesOneSandbox(Path workspace, Model model) throws Exception { - Files.createDirectories(workspace); - InMemorySandboxFilesystemSpec spec = new InMemorySandboxFilesystemSpec(); - spec.isolationScope(IsolationScope.AGENT); - InMemorySandboxClient client = spec.getClient(); - HarnessAgent agent = - HarnessAgent.builder() - .name("shared-assistant") - .model(model) - .workspace(workspace) - .filesystem(spec) - .build(); - - agent.call(userMsg("alice says hi"), ctx("s1", "alice")).block(); - agent.call(userMsg("bob says hi"), ctx("s2", "bob")).block(); - agent.call(userMsg("charlie says hi"), ctx("s3", "charlie")).block(); - if (client.getCreateCount() != 1 || client.getResumeCount() != 2) { - throw new IllegalStateException("AGENT scope: 1 create, 2 resume"); - } - System.out.println("[sandbox] AGENT: all callers share one sandbox: OK"); - } -} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java index 0a2317f33..74b02fae6 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/hook/MemoryFlushHook.java @@ -37,9 +37,8 @@ * *

Fires on {@link PostCallEvent} to ensure long-term memories are extracted and * persisted after every call, even when conversation compaction was not triggered during - * that call. When {@link io.agentscope.harness.agent.memory.compaction.CompactionHook} - * is active, it handles flush/offload for the messages it summarizes; this hook covers - * the remaining tail of messages that were kept verbatim. + * that call. When CompactionHook is active, it handles flush/offload for the messages it summarizes; + * this hook covers the remaining tail of messages that were kept verbatim. * *

Priority is 5 — runs early so state is persisted before the session-persistence hook * (priority 900) saves the overall agent state. diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java index d3d596c5b..4ee41775e 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisRemoteSnapshotClient.java @@ -36,7 +36,7 @@ public class RedisRemoteSnapshotClient implements RemoteSnapshotClient { * * @param jedis initialized jedis client * @param keyPrefix redis key prefix (optional) - * @param ttlSeconds optional TTL in seconds (null/<=0 means no TTL) + * @param ttlSeconds optional TTL in seconds (null or negative means no TTL) */ public RedisRemoteSnapshotClient(UnifiedJedis jedis, String keyPrefix, Integer ttlSeconds) { this.jedis = Objects.requireNonNull(jedis, "jedis must not be null"); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java index 40d28f57f..a8fcd4f0b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/snapshot/RedisSnapshotSpec.java @@ -27,7 +27,7 @@ public class RedisSnapshotSpec extends RemoteSnapshotSpec { * * @param jedis initialized jedis client * @param keyPrefix redis key prefix (optional) - * @param ttlSeconds optional TTL in seconds (null/<=0 means no TTL) + * @param ttlSeconds optional TTL in seconds (null or negative means no TTL) */ public RedisSnapshotSpec(UnifiedJedis jedis, String keyPrefix, Integer ttlSeconds) { super(new RedisRemoteSnapshotClient(jedis, keyPrefix, ttlSeconds)); From 7822f3af079944812e46f0949a3418231ea832a2 Mon Sep 17 00:00:00 2001 From: fang-tech Date: Fri, 8 May 2026 12:26:40 +0800 Subject: [PATCH 27/28] remove roadmap.md --- docs/zh/harness/overview.md | 3 +-- docs/zh/harness/roadmap.md | 24 ------------------------ 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 docs/zh/harness/roadmap.md diff --git a/docs/zh/harness/overview.md b/docs/zh/harness/overview.md index 0debfe749..bb7ffc00b 100644 --- a/docs/zh/harness/overview.md +++ b/docs/zh/harness/overview.md @@ -160,5 +160,4 @@ mvn -pl agentscope-examples/harness-example exec:java \ - [沙箱(Sandbox)](./sandbox.md) — 隔离执行、沙箱状态与分布式选项 - [子 Agent(Subagent)](./subagent.md) — 子 agent 规格与编排 - [工具(Tool)](./tool.md) — 内置工具参考 -- [会话(Session)](./session.md) — 会话持久化与状态恢复 -- [Roadmap](./roadmap.md) — 已识别的待改进项 +- [会话(Session)](./session.md) — 会话持久化与状态恢复 \ No newline at end of file diff --git a/docs/zh/harness/roadmap.md b/docs/zh/harness/roadmap.md deleted file mode 100644 index c51c2691a..000000000 --- a/docs/zh/harness/roadmap.md +++ /dev/null @@ -1,24 +0,0 @@ -# roadmap (暂定) - - -## examples - -1. claw类型的应用 - -## enhance - -1. harness的大部分的机制和能力都是通过hook机制来注入的, 用户插入的hook可能会破坏我们默认的hook执行顺序,队列需要分级, 分为internal和external, 前者的优先级高于后者, 用户的hook默认是在external队列中, 另外提供接口来注入到internal队列中, 将两边隔离 -2. 对于harness的构建方法, 支持直接将agent传入, 这样用户能复用过去的reactAgent的代码, 避免重复配置, 最小成本化升级 -3. 和core那边的统一化, 避免用户迷惑 - -## feature - -1. 按照生命周期/作用范围/权限/内部机制等来分类记忆类型, 而不是根据业务语义来分类 -2. 网关层的构建, 需不需要放在harness层, 如何以灵活的方式让agent能根据skill来自己将某个IM挂载到agent上 -3. agent请求human进行review的callback function入口 - - -## robustness - -1. 补齐UT -2. refactor Result类 \ No newline at end of file From 668a59ac7b83afe1f52d37f83cd3da4cf6813f11 Mon Sep 17 00:00:00 2001 From: fang-tech Date: Fri, 8 May 2026 12:54:02 +0800 Subject: [PATCH 28/28] add network option and additional run args option for docker sandbox Co-authored-by: Copilot --- .../sandbox/DockerPythonSandboxExample.java | 7 +- .../sandbox/DockerPythonSandboxImage.java | 3 +- .../sandbox/support/InMemorySandbox.java | 116 ----------------- .../support/InMemorySandboxClient.java | 122 ------------------ .../InMemorySandboxFilesystemSpec.java | 81 ------------ .../sandbox/support/InMemorySandboxState.java | 41 ------ .../filesystem/DockerFilesystemSpec.java | 16 +++ .../sandbox/impl/docker/DockerSandbox.java | 7 + .../impl/docker/DockerSandboxClient.java | 2 + .../docker/DockerSandboxClientOptions.java | 89 +++++++++++++ .../impl/docker/DockerSandboxState.java | 57 ++++++++ 11 files changed, 179 insertions(+), 362 deletions(-) delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java delete mode 100644 agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java index f1c75e9eb..f0a92db54 100644 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxExample.java @@ -25,6 +25,7 @@ import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.model.Model; import io.agentscope.harness.agent.HarnessAgent; +import io.agentscope.harness.agent.sandbox.SandboxDistributedOptions; import io.agentscope.harness.agent.sandbox.filesystem.DockerFilesystemSpec; import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; import java.nio.file.Files; @@ -52,9 +53,9 @@ public static void main(String[] args) throws Exception { SandboxFilesystemSpec sandboxSpec = new DockerFilesystemSpec() .image(DockerPythonSandboxImage.IMAGE) + .network("none") .workspaceRoot("/workspace") .workspaceProjectionRoots(List.of("AGENTS.md", "examples")); - HarnessAgent agent = HarnessAgent.builder() .name("docker-python-sandbox-agent") @@ -62,6 +63,10 @@ public static void main(String[] args) throws Exception { .model(model) .workspace(workspace) .filesystem(sandboxSpec) + .sandboxDistributed( + SandboxDistributedOptions.builder() + .requireDistributed(false) + .build()) .maxIters(20) .build(); diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java index 81b4cb2fe..57f78d4d4 100644 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java +++ b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/DockerPythonSandboxImage.java @@ -82,7 +82,8 @@ static String dockerAvailabilityErrorMessage(String output) { private static Path findDockerfile() { String relative = "src/main/docker/python-sandbox/Dockerfile"; - String moduleRelative = "agentscope-examples/harness-examples/harness-sandbox/" + relative; + String moduleRelative = + "agentscope-examples/harness-examples/harness-sandbox-docker/" + relative; Path cwd = Path.of(System.getProperty("user.dir")); for (Path candidate : List.of(cwd.resolve(relative), cwd.resolve(moduleRelative))) { if (Files.isRegularFile(candidate)) { diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java deleted file mode 100644 index 4ee8de504..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandbox.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.ExecResult; -import io.agentscope.harness.agent.sandbox.Sandbox; -import io.agentscope.harness.agent.sandbox.SandboxState; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * In-process {@link Sandbox} that uses a local temp directory as the workspace (for examples). - */ -public class InMemorySandbox implements Sandbox { - - private final InMemorySandboxState state; - private final Path workspaceDir; - private final AtomicBoolean running = new AtomicBoolean(false); - private final int defaultTimeoutSeconds; - - public InMemorySandbox(InMemorySandboxState state, int defaultTimeoutSeconds) { - this.state = state; - this.workspaceDir = Path.of(state.getWorkspaceRoot()); - this.defaultTimeoutSeconds = defaultTimeoutSeconds; - } - - @Override - public void start() throws Exception { - if (!Files.exists(workspaceDir)) { - Files.createDirectories(workspaceDir); - } - state.setWorkspaceRootReady(true); - running.set(true); - } - - @Override - public void stop() throws Exception { - state.setWorkspaceRootReady(true); - running.set(false); - } - - @Override - public void shutdown() throws Exception { - // Leave workspace dir in place for resume in tests - } - - @Override - public void close() throws Exception { - try { - stop(); - } catch (Exception e) { - // best-effort - } - shutdown(); - } - - @Override - public boolean isRunning() { - return running.get(); - } - - @Override - public SandboxState getState() { - return state; - } - - @Override - public ExecResult exec(String command, Integer timeoutSeconds) throws Exception { - int timeout = timeoutSeconds != null ? timeoutSeconds : defaultTimeoutSeconds; - ProcessBuilder pb = new ProcessBuilder("sh", "-c", command); - pb.directory(workspaceDir.toFile()); - pb.redirectErrorStream(false); - Process process = pb.start(); - - boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); - if (!finished) { - process.destroyForcibly(); - return new ExecResult(124, "", "Command timed out after " + timeout + "s", false); - } - - String stdout = new String(process.getInputStream().readAllBytes()); - String stderr = new String(process.getErrorStream().readAllBytes()); - return new ExecResult(process.exitValue(), stdout, stderr, false); - } - - @Override - public InputStream persistWorkspace() throws Exception { - return new ByteArrayInputStream(new byte[1024]); - } - - @Override - public void hydrateWorkspace(InputStream archive) throws Exception { - // no-op - } - - public Path getWorkspaceDir() { - return workspaceDir; - } -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java deleted file mode 100644 index 88b9c6c16..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxClient.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.agentscope.harness.agent.sandbox.Sandbox; -import io.agentscope.harness.agent.sandbox.SandboxClient; -import io.agentscope.harness.agent.sandbox.SandboxClientOptions; -import io.agentscope.harness.agent.sandbox.SandboxState; -import io.agentscope.harness.agent.sandbox.WorkspaceSpec; -import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; - -/** In-process {@link SandboxClient} that allocates local temp directories as sandboxes. */ -public class InMemorySandboxClient implements SandboxClient { - - private static final ObjectMapper MAPPER = new ObjectMapper(); - private static final int DEFAULT_TIMEOUT_SECONDS = 30; - - private final AtomicInteger createCount = new AtomicInteger(0); - private final AtomicInteger resumeCount = new AtomicInteger(0); - private final Path baseDir; - - public InMemorySandboxClient() { - try { - this.baseDir = Files.createTempDirectory("agentscope-inmemory-sandbox-"); - } catch (IOException e) { - throw new UncheckedIOException( - "Failed to create base temp dir for InMemorySandboxClient", e); - } - } - - @Override - public Sandbox create( - WorkspaceSpec workspaceSpec, - SandboxSnapshotSpec snapshotSpec, - SandboxClientOptions options) { - createCount.incrementAndGet(); - String sessionId = UUID.randomUUID().toString(); - Path workspaceDir = baseDir.resolve(sessionId); - try { - Files.createDirectories(workspaceDir); - } catch (IOException e) { - throw new UncheckedIOException("Failed to create workspace dir", e); - } - - InMemorySandboxState state = new InMemorySandboxState(sessionId, workspaceDir.toString()); - WorkspaceSpec spec = workspaceSpec != null ? workspaceSpec.copy() : new WorkspaceSpec(); - spec.setRoot(workspaceDir.toString()); - state.setWorkspaceSpec(spec); - - return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); - } - - @Override - public Sandbox resume(SandboxState sessionState) { - resumeCount.incrementAndGet(); - InMemorySandboxState state = (InMemorySandboxState) sessionState; - return new InMemorySandbox(state, DEFAULT_TIMEOUT_SECONDS); - } - - @Override - public void delete(Sandbox session) { - // no-op - } - - @Override - public String serializeState(SandboxState state) { - try { - InMemorySandboxState s = (InMemorySandboxState) state; - return MAPPER.writeValueAsString(new StateDto(s.getSessionId(), s.getWorkspaceRoot())); - } catch (IOException e) { - throw new UncheckedIOException("Failed to serialize sandbox state", e); - } - } - - @Override - public SandboxState deserializeState(String json) { - try { - StateDto dto = MAPPER.readValue(json, StateDto.class); - InMemorySandboxState state = - new InMemorySandboxState(dto.sessionId(), dto.workspaceRoot()); - state.setWorkspaceRootReady(true); - return state; - } catch (IOException e) { - throw new UncheckedIOException("Failed to deserialize sandbox state", e); - } - } - - public int getCreateCount() { - return createCount.get(); - } - - public int getResumeCount() { - return resumeCount.get(); - } - - public void resetCounts() { - createCount.set(0); - resumeCount.set(0); - } - - record StateDto(String sessionId, String workspaceRoot) {} -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java deleted file mode 100644 index b34b7e5fb..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxFilesystemSpec.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.SandboxClient; -import io.agentscope.harness.agent.sandbox.SandboxClientOptions; -import io.agentscope.harness.agent.sandbox.WorkspaceSpec; -import io.agentscope.harness.agent.sandbox.filesystem.SandboxFilesystemSpec; -import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; - -/** - * {@link SandboxFilesystemSpec} backed by an {@link InMemorySandboxClient}. - * - *

Uses a local temp directory as the sandbox workspace. No Docker or external services are - * required. The {@link InMemorySandboxClient} exposes create/resume counters to illustrate - * {@link io.agentscope.harness.agent.IsolationScope} behaviour. - */ -public class InMemorySandboxFilesystemSpec extends SandboxFilesystemSpec { - - private final InMemorySandboxClient client; - - /** - * Creates a spec backed by the given in-memory sandbox client. - * - * @param client the in-memory client to use for session create/resume - */ - public InMemorySandboxFilesystemSpec(InMemorySandboxClient client) { - this.client = client; - } - - /** - * Creates a spec with a new default {@link InMemorySandboxClient}. - */ - public InMemorySandboxFilesystemSpec() { - this(new InMemorySandboxClient()); - } - - /** - * Returns the underlying {@link InMemorySandboxClient}. - * - * @return the client - */ - public InMemorySandboxClient getClient() { - return client; - } - - @Override - protected SandboxClient createClient() { - return client; - } - - @Override - protected SandboxClientOptions clientOptions() { - return null; - } - - @Override - protected SandboxSnapshotSpec snapshotSpec() { - return null; - } - - @Override - protected WorkspaceSpec workspaceSpec() { - WorkspaceSpec s = new WorkspaceSpec(); - s.setRoot("/workspace"); - return s; - } -} diff --git a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java b/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java deleted file mode 100644 index d2be8fc79..000000000 --- a/agentscope-examples/harness-examples/harness-sandbox-docker/src/main/java/io/agentscope/examples/harness/sandbox/support/InMemorySandboxState.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2024-2026 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.agentscope.examples.harness.sandbox.support; - -import io.agentscope.harness.agent.sandbox.SandboxState; - -/** - * In-memory {@link SandboxState} for {@link InMemorySandboxClient}. - */ -public class InMemorySandboxState extends SandboxState { - - private String workspaceRoot; - - public InMemorySandboxState() {} - - public InMemorySandboxState(String sessionId, String workspaceRoot) { - setSessionId(sessionId); - this.workspaceRoot = workspaceRoot; - } - - public String getWorkspaceRoot() { - return workspaceRoot; - } - - public void setWorkspaceRoot(String workspaceRoot) { - this.workspaceRoot = workspaceRoot; - } -} diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java index 57c1c938a..a6f563537 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/filesystem/DockerFilesystemSpec.java @@ -22,6 +22,7 @@ import io.agentscope.harness.agent.sandbox.snapshot.NoopSnapshotSpec; import io.agentscope.harness.agent.sandbox.snapshot.SandboxSnapshotSpec; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -70,6 +71,21 @@ public DockerFilesystemSpec exposedPorts(int... exposedPorts) { return this; } + public DockerFilesystemSpec network(String network) { + options.network(network); + return this; + } + + public DockerFilesystemSpec additionalRunArgs(String... additionalRunArgs) { + options.additionalRunArgs(additionalRunArgs); + return this; + } + + public DockerFilesystemSpec additionalRunArgs(List additionalRunArgs) { + options.setAdditionalRunArgs(additionalRunArgs); + return this; + } + public DockerFilesystemSpec snapshotSpec(SandboxSnapshotSpec snapshotSpec) { this.snapshotSpec = snapshotSpec; return this; diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java index d6bb50f9d..537339d2b 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandbox.java @@ -478,6 +478,13 @@ private List buildDockerRunCommand(String containerName) { } } + String network = dockerState.getNetwork(); + cmd.add("--network=" + (network == null || network.isBlank() ? "none" : network)); + + if (dockerState.getAdditionalRunArgs() != null) { + cmd.addAll(dockerState.getAdditionalRunArgs()); + } + cmd.add(dockerState.getImage()); // Keep the container alive with an idle shell loop cmd.add("sh"); diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java index 0f1285e1f..5e246dab1 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClient.java @@ -80,6 +80,8 @@ public Sandbox create( state.setMemorySizeBytes(options.getMemorySizeBytes()); state.setCpuCount(options.getCpuCount()); state.setExposedPorts(options.getExposedPorts()); + state.setNetwork(options.getNetwork()); + state.setAdditionalRunArgs(options.getAdditionalRunArgs()); } if (snapshotSpec != null) { diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java index b3e1c6cba..42381f84d 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxClientOptions.java @@ -17,7 +17,9 @@ import io.agentscope.harness.agent.sandbox.SandboxClient; import io.agentscope.harness.agent.sandbox.SandboxClientOptions; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -48,6 +50,12 @@ public class DockerSandboxClientOptions extends SandboxClientOptions { /** Host ports to expose from the container ({@code hostPort:containerPort} mapping). */ private int[] exposedPorts = {}; + /** Additional raw arguments appended to {@code docker run} before the image name. */ + private List additionalRunArgs = new ArrayList<>(); + + /** Docker network mode or network name passed to {@code docker run --network}. */ + private String network; + @Override public String getType() { return "docker"; @@ -225,4 +233,85 @@ public DockerSandboxClientOptions exposedPorts(int... exposedPorts) { public void setExposedPorts(int[] exposedPorts) { this.exposedPorts = exposedPorts != null ? exposedPorts : new int[0]; } + + /** + * Returns the docker network mode or network name. + * + * @return docker network value, or {@code null} when unset + */ + public String getNetwork() { + return network; + } + + /** + * Sets the docker network mode or network name. + * + * @param network docker network value + * @return this options instance + */ + public DockerSandboxClientOptions network(String network) { + this.network = normalizeNetwork(network); + return this; + } + + /** + * Sets the docker network mode or network name. + * + * @param network docker network value + */ + public void setNetwork(String network) { + this.network = normalizeNetwork(network); + } + + /** + * Returns additional raw arguments appended to {@code docker run}. + * + * @return additional docker run arguments + */ + public List getAdditionalRunArgs() { + return additionalRunArgs; + } + + /** + * Appends additional raw arguments to {@code docker run} before the image name. + * + * @param additionalRunArgs additional docker run arguments + * @return this options instance + */ + public DockerSandboxClientOptions additionalRunArgs(String... additionalRunArgs) { + if (additionalRunArgs == null) { + return this; + } + for (String additionalRunArg : additionalRunArgs) { + if (additionalRunArg != null && !additionalRunArg.isBlank()) { + this.additionalRunArgs.add(additionalRunArg); + } + } + return this; + } + + /** + * Sets the additional raw arguments appended to {@code docker run}. + * + * @param additionalRunArgs additional docker run arguments + */ + public void setAdditionalRunArgs(List additionalRunArgs) { + this.additionalRunArgs = new ArrayList<>(); + if (additionalRunArgs == null) { + return; + } + for (String additionalRunArg : additionalRunArgs) { + if (additionalRunArg != null && !additionalRunArg.isBlank()) { + this.additionalRunArgs.add(additionalRunArg); + } + } + } + + private String normalizeNetwork(String network) { + if (network == null) { + return null; + } + String trimmed = network.trim(); + return trimmed.isEmpty() ? null : trimmed; + } } diff --git a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java index 4349692be..c0d4aec47 100644 --- a/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java +++ b/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerSandboxState.java @@ -16,6 +16,8 @@ package io.agentscope.harness.agent.sandbox.impl.docker; import io.agentscope.harness.agent.sandbox.SandboxState; +import java.util.ArrayList; +import java.util.List; /** * Serializable state for a Docker-backed {@link io.agentscope.harness.agent.sandbox.Sandbox}. @@ -54,6 +56,12 @@ public class DockerSandboxState extends SandboxState { /** Exposed port numbers stored for container recreation on resume. */ private int[] exposedPorts = {}; + /** Docker network mode or network name passed to {@code docker run --network}. */ + private String network; + + /** Additional raw arguments appended to {@code docker run} before the image name. */ + private List additionalRunArgs = new ArrayList<>(); + /** * Returns the Docker container ID. * @@ -197,4 +205,53 @@ public int[] getExposedPorts() { public void setExposedPorts(int[] exposedPorts) { this.exposedPorts = exposedPorts != null ? exposedPorts : new int[0]; } + + /** + * Returns the docker network mode or network name. + * + * @return docker network value, or {@code null} when unset + */ + public String getNetwork() { + return network; + } + + /** + * Sets the docker network mode or network name. + * + * @param network docker network value + */ + public void setNetwork(String network) { + if (network == null) { + this.network = null; + return; + } + String trimmed = network.trim(); + this.network = trimmed.isEmpty() ? null : trimmed; + } + + /** + * Returns additional raw arguments appended to {@code docker run}. + * + * @return additional docker run arguments + */ + public List getAdditionalRunArgs() { + return additionalRunArgs; + } + + /** + * Sets additional raw arguments appended to {@code docker run}. + * + * @param additionalRunArgs additional docker run arguments + */ + public void setAdditionalRunArgs(List additionalRunArgs) { + this.additionalRunArgs = new ArrayList<>(); + if (additionalRunArgs == null) { + return; + } + for (String additionalRunArg : additionalRunArgs) { + if (additionalRunArg != null && !additionalRunArg.isBlank()) { + this.additionalRunArgs.add(additionalRunArg); + } + } + } }