Skip to content

refactor: replace global singletons with AgentContext instance - #16

Merged
hewliyang merged 7 commits into
mainfrom
refactor/agent-context
Mar 29, 2026
Merged

refactor: replace global singletons with AgentContext instance#16
hewliyang merged 7 commits into
mainfrom
refactor/agent-context

Conversation

@hewliyang

Copy link
Copy Markdown
Owner

Summary

Replaces the scattered module-level singleton pattern (setCustomCommands(), configureNamespace(), getVfs(), getBash(), etc.) with a single AgentContext class that AgentRuntime owns and threads to all consumers.

What changed

New: AgentContext (packages/sdk/src/context.ts)

  • Owns VFS (InMemoryFs), bash (Bash), and StorageNamespace
  • Provides file operations (readFile, writeFile, deleteFile, fileExists, listUploads)
  • Provides VFS lifecycle (reset, restoreVfs, snapshotVfs)
  • Constructed by AgentRuntime, passed explicitly to tools and storage functions

Tools → factories

  • bashToolcreateBashTool(ctx: AgentContext)
  • readToolcreateReadTool(ctx: AgentContext)
  • evalOfficeJsToolcreateEvalOfficeJsTool(ctx) (Excel, PPT, Word variants)
  • getOoxmlToolcreateGetOoxmlTool(ctx) (Word)
  • App tool indices export createExcelTools(ctx), createPptTools(ctx), createWordTools(ctx)

Adapter pattern update

  • AppAdapter.tools accepts AgentTool[] | ((ctx: AgentContext) => AgentTool[]) — factory or static array
  • AppAdapter.customCommands now receives (ns: StorageNamespace) => CustomCommandsResult from the runtime
  • No more hardcoded prefix strings ("openexcel", "openppt", "openword") in custom command files

localStorage helpers take StorageNamespace

  • loadSavedConfig(ns), saveConfig(ns, config)
  • loadWebConfig(ns), saveWebConfig(ns, config)
  • loadOAuthCredentials(ns, provider), saveOAuthCredentials(ns, provider, creds), removeOAuthCredentials(ns, provider)
  • Settings panel uses chat.context.namespace instead of a raw prefix string

Storage functions take StorageNamespace

  • All storage/db.ts functions (createSession, saveSession, listSessions, etc.) take ns as first param
  • storage/namespace.ts reduced to a type re-export

Deleted globals

  • setCustomCommands(), setStaticFiles(), setSkillFiles(), resetVfs(), getVfs(), getBash()
  • configureNamespace(), getNamespace()
  • readFile(), writeFile(), readFileBuffer(), fileExists(), deleteFile(), listUploads(), snapshotVfs(), restoreVfs() (all now on AgentContext)
  • vfs/index.ts gutted to pure utilities only (getFileType, detectImageMimeType, toBase64)

Tests

  • All tests create isolated AgentContext instances — no shared global state
  • No more resetVfs() / setStaticFiles({}) ceremony in beforeEach/afterEach

Bridge

  • Bridge client handles tools as array or factory
  • VFS pass-through from app.svelte removed (bridge VFS support to be re-wired separately)

Why

  • No hidden coupling — every function declares what it needs
  • No ordering bugs — context is fully constructed before use
  • Testable — spin up isolated instances, no global resets
  • Self-documentingchat.context.namespace instead of magic prefix strings

@hewliyang
hewliyang force-pushed the refactor/agent-context branch 2 times, most recently from fbf00c0 to 903b486 Compare March 23, 2026 13:09
- Introduce AgentContext class that owns VFS, bash, and StorageNamespace
- AgentRuntime accepts optional pre-built AgentContext (ChatController creates it)
- Tools become factories (createBashTool, createReadTool, etc.) that receive context
- Adapter.tools accepts (ctx: AgentContext) => AgentTool[] factory pattern
- All localStorage helpers take StorageNamespace instead of raw prefix strings
- Storage/db functions take StorageNamespace as first param
- Skills functions take namespace + context explicitly
- customCommands adapter receives (ns: StorageNamespace) from runtime
- Remove all module-level VFS singletons and configureNamespace/getNamespace
- Bridge VFS adapter matches AgentContext shape (snapshotVfs, readFile, etc.)
- Bridge accepts lazy vfs getter: () => BridgeVfsAdapter | undefined
- ChatInterface exposes onController callback for bridge wiring
- App.svelte files pass context directly as bridge VFS adapter
- Update all tests to use AgentContext instances
@hewliyang
hewliyang force-pushed the refactor/agent-context branch from 903b486 to 9878b65 Compare March 23, 2026 13:18
…er config in runtime init

- setSkillFiles/setStaticFiles now patch the live InMemoryFs in-place
  instead of calling reset(), which was destroying user uploads and
  generated files
- setCustomCommands only resets bash (no FS mutation needed)
- AgentRuntime.init() now applies adapter.staticFiles and
  adapter.customCommands to the context, so external SDK consumers
  don't silently lose VFS files and command snippets
- Added customCommands to RuntimeAdapter interface
- Replace global singleton examples with AgentContext pattern
- Document RuntimeAdapter.staticFiles/customCommands and init() behavior
- Update all code examples (tools, sessions, skills, provider config)
- Add AgentContext, custom commands, and built-in tools sections
- All storage/skill functions now show namespace parameter
- Add Word to Used By section
@hewliyang
hewliyang merged commit f7e1f33 into main Mar 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant