Production-oriented TypeScript monorepo for LLM stream parsing, agent infrastructure, and VS Code integration. The plan/ directory contains phased implementation plans but most domains have been promoted to manifest-backed packages.
This repository is a pnpm workspace monorepo orchestrated with Turborepo containing 23 manifest-backed packages.
Core infrastructure:
@agentsy/core— Stream processing bundle (processor, SSE (Server-Sent Events), XML filter, structured JSON, thinking block parsing, retry, recovery)@agentsy/types— Shared TypeScript types across all packages@agentsy/providers— Provider normalizers (Anthropic, OpenAI, Mistral, and others) and API adapters@agentsy/mcp— Model Context Protocol (MCP) types and utilities
Runtime and orchestration:
@agentsy/runtime— Agent execution runtime with sandboxing and Agent-Generated User Interface (AG-UI) protocol adapter@agentsy/orchestrator— Agent orchestration and scheduling@agentsy/memory— Three-tier memory engine (raw event log, synthesized wiki, vector retrieval)@agentsy/session— Session management and caching@agentsy/context— Token budgeting and output compression@agentsy/guardrails— Safety and validation boundaries@agentsy/observability— Metrics and tracing@agentsy/retrieval— Retrieval-Augmented Generation (RAG) retrieval and indexing@agentsy/models— Model selection and recommendation
Surfaces and utilities:
@agentsy/vscode— VS Code Language Model Chat Provider integration (currently published)@agentsy/renderers— CLI, Text-based User Interface (TUI), and renderers (plain text, streaming markdown, Ink components)@agentsy/ui— UI components and event sourcingng@agentsy/cli— CLI commands@agentsy/connectors— Platform connectors (Discord, Slack, Telegram)@agentsy/tools— Tool implementations and filesystem utilities@agentsy/prompts— Prompt management@agentsy/plugins— Plugin system@agentsy/secrets— Secret management
Build and testing:
@agentsy/scripts(private) — Release and validation scripts@agentsy/testing(private) — Cross-package integration tests
The only currently published package is @agentsy/vscode. All others are internal/pre-release.
- Core stream/transformation primitives:
@agentsy/core - Provider adaptation + normalization:
@agentsy/providers,@agentsy/mcp - Orchestration and execution:
@agentsy/orchestrator,@agentsy/runtime,@agentsy/guardrails - Durability and long-horizon state:
@agentsy/session,@agentsy/memory,@agentsy/context,@agentsy/retrieval - Surface and presentation:
@agentsy/renderers,@agentsy/ui,@agentsy/vscode,@agentsy/cli,@agentsy/connectors - Extensibility:
@agentsy/plugins
Important:
@agentsy/providersis an active boundary, not merged into@agentsy/core.
Use the highest-level tool available. Prefer IDE actions and repository-native scripts over ad hoc shell work.
- VS Code / language-server actions for symbol-aware operations
- Repository tooling via root scripts and per-package scripts
- Terminal commands only when no higher-level option exists
This repo uses pnpm + Turborepo for workspace orchestration. No Taskfile.
Run these from the repository root:
pnpm build # turbo run build
pnpm test # turbo run test
pnpm test:coverage # turbo run coverage
pnpm check-types # turbo run check-types
pnpm lint # turbo run lint
pnpm lint:fix # turbo run lint -- --fix
pnpm format # turbo run format
pnpm precommit # turbo run precommit
pnpm release # Run release tooling
pnpm fallow # Run Fallow codebase intelligenceUse package-local scripts when working on one package in isolation:
cd packages/vscode && pnpm build
cd packages/vscode && pnpm test
cd packages/vscode && pnpm coverage
// Or any other package:
cd packages/core && pnpm build
cd packages/providers && pnpm testBefore considering work complete, run at minimum:
pnpm check-types
pnpm testWhen a change is package-scoped, run the corresponding package scripts first, then root checks if it affects shared code, exports, docs, or monorepo wiring.
When making changes to packages/cli/, also run the E2E terminal test suite:
pnpm --filter @agentsy/cli test:e2eE2E specs use @microsoft/tui-test and are located in packages/cli/src/e2e/. Each CLI command with a non-trivial output or interactive flow should have a corresponding .spec.ts file when it meaningfully validates behavior. See docs/developers/contributing.md for the full workflow.
- Develop against Node.js 22 to match CI (VS Code package declares
>=18, but repo targets Node 22 consistently) - Package manager is pnpm with workspace: protocol for internal dependencies
- Module system is ESM-first (ECMAScript Modules) with
.jsextensions in imports - Build tool is tsup
- Test framework is Vitest
- Linter/formatter is Biome (via ultracite preset)
Follow the root tsconfig.json as source of truth.
{
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true
}- Avoid introducing
any; when type information is genuinely unknown, useunknown,Record<string, unknown>, null-prototype objects, or explicit narrowing instead - Preserve exact optional-property behavior; do not add
undefinedloosely where omission is intended
- Use
.jsextensions in relative imports inside.tsfiles (verbatimModuleSyntax) - Keep imports ESM-compatible throughout the codebase
- Do not use cross-package relative imports like
../../core/...; use workspace package imports instead (e.g.,@agentsy/core/processor)
The repo uses Biome via the ultracite preset (oxfmt.config.ts extends ultracite). See .agents/instructions/code-standards.md for coding standards.
{
arrowParens: 'avoid',
printWidth: 120,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none'
}Enabled plugins: ['eslint', 'typescript', 'unicorn', 'oxc', 'import', 'react', 'jsdoc', 'node', 'promise', 'vitest']
Key rules:
- Type-aware mode enabled (
typeAware: true,typeCheck: true) - TypeScript safety:
no-non-null-assertion: error,no-unsafe-*: error - Relaxed:
max-classes-per-file: off,unicorn/no-array-for-each: off,unicorn/no-array-reduce: off - Vitest:
max-expects: offto support comprehensive test cases
For test inputs that intentionally include mixed HTML/XML or other exceptions, use comment disables:
// biome-ignore lint: xss/no-mixed-html -- Test inputs intentionally include mixed HTML/XML- VS Code-specific integration layer
- Depends on internal workspace packages via
workspace:*protocol - Preserve ESM-only packaging and explicit externals in tsup.config.ts:
external: ['vscode', ...@agentsy/* peers] - Keep VS Code APIs, extension runtime, secret storage, status bars, chat providers, and extension settings here
- Durable knowledge layer, not a hidden orchestration dependency
- Should remain pluggable so consumers can substitute backends when needed
- Prefer abstract interfaces for memory providers, retrievers, and lifecycle hooks
- Expose as both Agentsy-native package and standalone Model Context Protocol (MCP) server or plugin surface when possible
Important dependencies intentionally not flagged by Fallow (see .fallowrc.jsonc):
"ignoreDependencies": [
"@agentsy/types", "@agentsy/core", "@agentsy/renderers",
"@agentsy/runtime", "@agentsy/memory", "@agentsy/providers",
"@agentsy/session", "@agentsy/context"
]These are safe to ignore in unused-dependencies checks — they are workspace packages used as dev/build references across the monorepo.
- VS Code extension behavior →
@agentsy/vscode - Durable memory/retrieval/persistence →
@agentsy/memoryor memory-adjacent - Transient token budgets/prompt reduction →
@agentsy/context - Everything else → appropriate focused package
Follow existing patterns throughout the repo:
- Factory functions:
create* - Parser classes:
*Parser - Processor classes:
*Processor - Validators:
validate* - Builders:
build* - Extractors:
extract* - Managers:
*Manager - Adapters:
*Adapteror*Bridge
- Prefer factory functions over direct instantiation for public APIs
- Use classes for stateful streaming/parser components where the codebase already does so (e.g.,
LLMStreamProcessor,XmlStreamFilter) - Use functions for stateless operations and pure transformations
- Use options objects with sensible defaults via
?? - Export public module APIs through
index.tsbarrel files - Keep tests colocated beside the source they verify (
*.test.tsnext to source)
// Value exports
export { createFoo, type Bar } from "./foo.js";
// Type-only exports (favored when module exports only types)
export type * from "./types.js";
// Re-exports from sub-modules
export * from "./subpath/index.js";Packages define multiple entry points in tsup.config.ts:
export default defineConfig({
entry: {
index: "src/index.ts",
processor: "src/processor/index.ts",
"xml-filter": "src/xml-filter/index.ts",
// ...
},
external: ["@agentsy/types", "zod"], // Workspace and peer deps
format: ["esm", "cjs"],
target: "node18",
treeshake: true,
});Mirror these entries in package.json exports to enable subpath imports like @agentsy/core/processor.
Align package.json exports with tsup entry points:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./processor": {
"types": "./dist/processor.d.ts",
"import": "./dist/processor.js",
"require": "./dist/processor.cjs"
}
}
}- Prefer graceful degradation for malformed LLM output
- Malformed output should be skipped, partially recovered, or surfaced through warnings rather than thrown exceptions
- Use
onWarning-style callbacks for recoverable issues in processors/parsers - Test chunk-by-chunk behavior explicitly, including boundary splits and incomplete chunks
- Throw explicit
Errorvalues for invalid configuration, invalid public API input, or impossible setup states - Validate early, fail fast
- Treat model output as untrusted input
- Preserve existing limits for depth, key counts, nesting, and tool-call size
- Keep privacy-tag scrubbing and safety defaults intact
- Do not weaken bounded parsing, validation, or sanitization logic for convenience
Use Vitest. Tests are colocated as *.test.ts files beside source.
- Use
vi.fn()or equivalent spies for callbacks and event handlers - For streaming/parsing logic, test chunk-by-chunk behavior explicitly with partial and boundary-split inputs
- Add adversarial and malformed-input cases for parsing and recovery code
- Test warning/recovery behavior through callback spies
- Test safety rails and size/depth limits
- Test exported API behavior, not just internals
- Partial chunks and boundary splits
- Empty and malformed input
- Warning and recovery behavior
- Safety rails and size/depth limits
- Exported API behavior, not just internals
- Any package:
cd packages/<name> && pnpm coverage - All packages:
pnpm test:coverage - Release tooling tests:
pnpm test:release
/* oxlint-disable xss/no-mixed-html -- Test inputs intentionally include mixed HTML/XML */
import { describe, expect, it, vi } from "vitest";LLMStreamProcessor and similar components:
- Emit structured
StreamChunkinterfaces withcontent,thinking,toolCalls,parts - Accumulate state across chunks and emit partial results
- Respect configurable limits (e.g.,
maxToolCallsPerMessage,maxInputLength) - Support optional callbacks:
onWarning,onText,onThinking,onDone - Track incompleteness on flush:
IncompletenessDetailindicates missing or incomplete data
- Use
stream-jsonand structured parsing utilities from@agentsy/core/structured - Support partial JSON repair at chunk boundaries
- Track field-level completion status for streaming progress
- Use
emitPartials: truefor partial object emission during streaming
- Each provider has dedicated normalizer function (e.g.,
normalizeAnthropicEvent,normalizeOpenAIChatChunk) - Convert provider-specific chunks to unified
StreamChunkformat before processor - Handle provider quirks in normalization layer, not in core processor
- Create
packages/<name>/withpackage.json,tsconfig.json,tsup.config.ts - Add entry to
pnpm-workspace.yaml(already haspackages/*) - Add to root
package.jsonworkspace dependencies if needed - Implement build/test/lint scripts
- Update
README.mdpackage list if publicly visible - Add to
.fallowrc.jsoncignoreDependenciesif it will be used as workspace reference
- Add source module under
packages/<name>/src/... - Export from nearest
index.tsbarrel - Add tsup entry in
tsup.config.ts - Add matching export in
package.jsonexports field - Add or update tests for the new entry point
- Update docs if the API is user-facing
- Keep package boundaries explicit
- Preserve independent installability
- Do not accidentally inline or blur package boundaries through incorrect build config
- Update tsup.config.ts entry points accordingly
- The repo is a monorepo with 23 packages
- Root workflow is pnpm + turbo (not Taskfile)
- The only currently published package is
@agentsy/vscode - CI uses Node 22
@agentsy/providersis an active boundary, not merged into core- Type safety is strict with no
anyallowed
- Update docs when public APIs, commands, package names, or workflows change
- Keep root docs aligned with current monorepo structure (README.md lists current packages)
- Do not reintroduce stale references to obsolete packages or missing tooling
- Update implementation-plan documents only when genuinely planning future work; actual implementation belongs in
IMPLEMENTATION-PLAN.mdfiles within packages
- CI lives in
.github/workflows/(tests.yml, release.yml, docs-deploy.yml) - Runs
pnpm install --frozen-lockfile,pnpm turbo run coverage - Uploads coverage to Codecov, Codacy, and as artifacts
- Node 22 is CI target
- Uses pnpm action-setup and setup-node with
cache: 'pnpm'
- When adding scripts, package paths, coverage outputs, or build artifacts, check whether workflows need updates
- Ensure CI commands match current root scripts and Turbo tasks
- Don't assume one-package release logic; this is a monorepo with 23 packages
- Do not recommend
task ...commands — there is no Taskfile in this repo - Do not use hypothetical package names (
@agentsy/agent,@agentsy/adapters) — they don't exist - Do not add
anyto "fix" strict TypeScript friction — use proper types orunknown - Do not forget
.jsextensions on relative TypeScript imports — it's required by verbatimModuleSyntax - Do not place VS Code-specific logic in non-vscode packages
- Do not rely on omitted optional properties having
undefined— exactOptionalPropertyTypes is enabled - Do not assume providers are merged away —
@agentsy/providersis active - Do not bypass workspace-* dependencies in favor of relative imports across packages
When uncertain, optimize for:
- Consistency with the current monorepo (23 packages, pnpm + turbo)
- Strict type safety (no
any, properunknownhandling) - Clear package boundaries (providers is separate from core)
- Resilient handling of malformed LLM output (graceful degradation)
- ESM-first package exports with proper subpaths
- Comprehensive testing of streaming behavior
- Docs and CI staying in sync with code