Skip to content

v0.14.0 — Filesystem Mounts, Multimodal Tools & Streaming Improvements

Choose a tag to compare

@nevindra nevindra released this 10 Apr 10:26
· 113 commits to master since this release

Oasis v0.14.0 introduces sandbox filesystem mounts — a three-layer system that backs sandbox paths with external storage, enabling agents to read and write files that persist beyond the sandbox lifecycle. Also ships multimodal tool output, tool-loop streaming for single agents, and several important bug fixes.


✨ Highlights

📁 Sandbox Filesystem Mounts

A new FilesystemMount interface lets apps back specific sandbox paths with external storage (S3, GCS, local disk — you implement the interface). Three layers work together:

specs := []sandbox.MountSpec{{
    Path:     "/workspace/docs",
    Mode:     sandbox.MountReadWrite,
    Prefetch: true,  // copy backend files into sandbox at start
    Flush:    true,  // scan sandbox at close and publish deltas
}}

manifest := sandbox.NewManifest()
tools := sandbox.Tools(sandbox.WithMounts(specs, manifest))
  • Layer 1 — Lifecycle: PrefetchMounts copies backend files in at start; FlushMounts scans and publishes deltas at close
  • Layer 2 — Tool interception: file_write, file_edit, and deliver_file publish writes to the backend immediately with optimistic version checks
  • Layer 3 — Conflict resolution: ErrVersionMismatch surfaces as a tool error so the agent can re-read and retry

MountSpec supports read-only, write-only, and read-write modes, plus Include/Exclude globs and MirrorDeletes for full sync.

🖼️ Multimodal Tool Output

Tools can now return binary attachments alongside text via ToolResult.Attachments. Attachments flow through the agent loop and are passed to the LLM as multimodal input:

func (t *ScreenshotTool) Execute(ctx context.Context, args string) (oasis.ToolResult, error) {
    pngBytes := captureScreen()
    return oasis.ToolResult{
        Content: "Screenshot captured",
        Attachments: []oasis.Attachment{
            {MimeType: "image/png", Data: pngBytes},
        },
    }, nil
}

⚡ Tool-Loop Streaming

LLMAgent now uses ChatStream during tool-loop iterations, providing real-time EventToolCallDelta events as arguments arrive — no more waiting for the full tool call to complete before seeing progress. Networks continue using non-streaming Chat() to preserve text-delta deduplication with sub-agent streaming.


🆕 New Features

Feature Description
FilesystemMount interface Back sandbox paths with external storage — prefetch, flush, and real-time sync
MountSpec Declares path, mode (RO/WO/RW), lifecycle policy, and include/exclude globs
WithMounts ToolsOption Wires mount specs and manifest into the tool layer
Manifest type Concurrent-safe per-sandbox tracking of mount entries for version checking
PrefetchMounts / FlushMounts Lifecycle functions for start-of-session and end-of-session sync
FilesystemMounter stub Optional interface for sandbox runtimes to opt into live FUSE/virtio-fs mounting
ErrKeyNotFound sentinel Distinct from sandbox.ErrNotFound, used by FilesystemMount.Stat/Open
ToolResult.Attachments Tools return binary attachments (images, PDFs) alongside text content
Tool-loop streaming Single agents stream EventToolCallDelta during tool-loop iterations
Embedding provider fallback Unknown embedding providers fall back to OpenAI-compatible when BaseURL is provided
AgentSkills compatibility Compatibility, License, Metadata fields on Skill and SkillSummary
ActivateWithReferences() Resolves skill references at activation time
WithActiveSkills Pre-activates skills at init, injecting instructions into every LLM call
WithSkills Registers a SkillProvider with auto-added discover/activate tools
Prescriptive built-in skills oasis-pdf, oasis-docx, oasis-xlsx, oasis-pptx — agents use libraries directly

🐛 Bug Fixes

Fix Description
Sandbox/skill tools on Network NewNetwork was missing sandbox tool and skill provider registration, causing "unknown tool" errors for execute_code, shell, etc.
Router text-delta after delegation Router's final text-delta was incorrectly suppressed when a child agent had already streamed
Qwen provider resolver qwen and qwen-cn added to the resolver's known-provider list
HNSW index >2000 dimensions Postgres store now skips index creation and falls back to sequential scan for high-dimension embeddings

⚠️ Breaking Changes

Change Migration
Document generation skills Skills now teach agents to use libraries directly (python-docx, openpyxl, Playwright, PptxGenJS) instead of routing through oasis-render

🔧 Changed

  • skill_activate output includes Compatibility, License, and Metadata fields
  • skill_create/skill_update accepts Compatibility, License, Metadata parameters
  • deliver_file tool now consults the mount table to publish files, falling back to legacy FileDelivery

⚠️ Deprecated

Deprecated Replacement
FileDelivery interface FilesystemMount with MountWriteOnly mode. Legacy fallback still works in deliver_file.

🗑️ Removed

Removed Replacement
bin/oasis-render CLI Prescriptive skills that teach agents to use libraries directly
renderers/ directory Removed — library deps remain in Dockerfile
requirements.txt Removed — Python deps for renderers no longer needed at framework level

📖 Full Changelog

v0.13.0...v0.14.0


go get github.com/nevindra/oasis@v0.14.0