Add Cactus (needle-rs) local tool-calling provider#524
Merged
Conversation
ToolCallingTask.requires and StructuredGenerationTask.requires no longer include text.generation. Specialty tool/json-only models can now advertise honest capabilities. Existing chat-LLM providers continue to match via the strict-superset dispatch rule.
…ctus/src/__tests__
…e cache, eviction
…on eviction, atomic disk writes
…ove, ToolCalling, JobRunFns
@workglow/cli
@workglow/ai
@workglow/browser-control
@workglow/indexeddb
@workglow/javascript
@workglow/job-queue
@workglow/knowledge-base
@workglow/mcp
@workglow/storage
@workglow/task-graph
@workglow/tasks
@workglow/util
workglow
@workglow/anthropic
@workglow/bun-webview
@workglow/cactus
@workglow/chrome-ai
@workglow/electron
@workglow/google-gemini
@workglow/huggingface-inference
@workglow/huggingface-transformers
@workglow/node-llama-cpp
@workglow/ollama
@workglow/openai
@workglow/playwright
@workglow/postgres
@workglow/sqlite
@workglow/supabase
@workglow/tf-mediapipe
commit: |
Coverage Report
File CoverageNo changed files found. |
Contributor
There was a problem hiding this comment.
Pull request overview
Introduces a new @workglow/cactus local AI provider that wraps the needle-rs WASM runtime to enable lightweight, browser-compatible tool-calling, and relaxes core task capability requirements so tool-only / json-only models can run relevant tasks.
Changes:
- Added
providers/cactuspackage with model catalog/schema, runtime (engine + asset caching), provider registrations, and tests. - Relaxed
ToolCallingTask.requiresto["tool-use"]andStructuredGenerationTask.requiresto["json-mode"], plus updated tests and capability descriptions. - Integrated cactus tests into the repo test runner and added
needle-rsdependency/lockfile entries.
Reviewed changes
Copilot reviewed 37 out of 38 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/test.ts | Adds a cactus test section pointing at the provider’s test folder. |
| providers/cactus/tsconfig.json | New TS project config + references for the cactus provider package. |
| providers/cactus/src/ai/runtime.ts | Runtime entry re-exports for worker/inline registration + runtime helpers. |
| providers/cactus/src/ai/registerCactusWorker.ts | Worker registration helper for the cactus provider. |
| providers/cactus/src/ai/registerCactusInline.ts | Inline (main-thread) registration helper for cactus. |
| providers/cactus/src/ai/registerCactus.ts | Worker-backed registration helper for cactus. |
| providers/cactus/src/ai/index.ts | Public exports + _testOnly re-exports for @workglow/test. |
| providers/cactus/src/ai/common/Cactus_ToolCalling.ts | Implements cactus tool-calling run-fn (streaming + non-streaming). |
| providers/cactus/src/ai/common/Cactus_Runtime.ts | Lazy SDK loading, asset fetch/cache, engine caching, eviction/disposal. |
| providers/cactus/src/ai/common/Cactus_ModelSearch.ts | Model search task implementation over a static catalog. |
| providers/cactus/src/ai/common/Cactus_ModelSchema.ts | Model config/record schemas for cactus provider config. |
| providers/cactus/src/ai/common/Cactus_ModelInfo.ts | Model info implementation (cached/loaded reporting). |
| providers/cactus/src/ai/common/Cactus_ModelCatalog.ts | Static catalog entry + HF asset URL builder. |
| providers/cactus/src/ai/common/Cactus_JobRunFns.ts | Registers cactus run-fns and re-exports runtime internals for tests. |
| providers/cactus/src/ai/common/Cactus_DownloadRemove.ts | Implements model download-remove (cache eviction). |
| providers/cactus/src/ai/common/Cactus_Download.ts | Implements model download (asset fetch + progress phases). |
| providers/cactus/src/ai/common/Cactus_Constants.ts | Provider/model constants (ids, cache name, default cache dir). |
| providers/cactus/src/ai/common/Cactus_CapabilitySets.ts | Declares cactus capability sets for run-fn registrations. |
| providers/cactus/src/ai/common/Cactus_Capabilities.ts | Capability inference + worker run-fn spec export. |
| providers/cactus/src/ai/CactusQueuedProvider.ts | Main-thread queued provider shell. |
| providers/cactus/src/ai/CactusProvider.ts | Worker-side provider implementation. |
| providers/cactus/src/ai.ts | ./ai entrypoint shim. |
| providers/cactus/src/ai-runtime.ts | ./ai-runtime entrypoint shim. |
| providers/cactus/src/tests/* | Unit + integration tests for cactus capabilities, schema, model tasks, download/toolcalling. |
| providers/cactus/README.md | Provider README describing capabilities and entrypoints. |
| providers/cactus/package.json | New published package config + exports. |
| packages/ai/src/task/ToolCallingTask.ts | Relaxes required capabilities to only tool-use. |
| packages/ai/src/task/StructuredGenerationTask.ts | Relaxes required capabilities to only json-mode. |
| packages/ai/src/task/index.test.ts | Adds assertions for the new requires semantics. |
| packages/ai/src/capability/Capabilities.ts | Updates capability descriptions for tool-use and json-mode. |
| package.json | Adds needle-rs dependency. |
| bun.lock | Adds provider workspace entry + needle-rs catalog/version updates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+94
to
+98
| if (validToolCalls.length > 0) { | ||
| emit({ type: "object-delta", port: "toolCalls", objectDelta: [...validToolCalls] }); | ||
| } | ||
| emit({ type: "finish", data: {} as ToolCallingTaskOutput }); | ||
| }; |
Comment on lines
+22
to
+24
| const is_loaded = isModelLoaded(model_id); | ||
| const is_cached = is_loaded || cactusConfigJson.has(model_id); | ||
|
|
Comment on lines
+15
to
+16
| /** Node/Bun on-disk cache root. */ | ||
| export const CACTUS_DEFAULT_MODELS_DIR = "./.cache/cactus"; |
Comment on lines
+79
to
+86
| async function fetchAssetBytesNode( | ||
| url: string, | ||
| models_dir: string, | ||
| model_id: string, | ||
| filename: string | ||
| ): Promise<Uint8Array> { | ||
| const fs = await import("node:fs/promises"); | ||
| const path = await import("node:path"); |
Comment on lines
+23
to
+32
| "exports": { | ||
| "./ai": { | ||
| "types": "./dist/ai.d.ts", | ||
| "import": "./dist/ai.js" | ||
| }, | ||
| "./ai-runtime": { | ||
| "types": "./dist/ai-runtime.d.ts", | ||
| "import": "./dist/ai-runtime.js" | ||
| } | ||
| }, |
…mment, fix entry-point doc
…e dir, browser-safe runtime split, browser export condition Agent-Logs-Url: https://github.com/workglow-dev/libs/sessions/6503bd73-a51a-4cfe-8ead-df9e8985123e Co-authored-by: sroussey <127349+sroussey@users.noreply.github.com>
…ges/test/src/test/ai-provider-cactus to match sibling provider convention Migrates the 7 cactus test files to the cross-package test location used by every other provider, importing from `@workglow/cactus/ai` and `@workglow/cactus/ai-runtime` instead of relative source paths. The Capabilities test is renamed to CactusProvider.test.ts and now exercises `new CactusQueuedProvider().inferCapabilities(model)` (the public provider surface) rather than the internal helper. `_testOnly` now also re-exports `cactusEngines` and `cactusConfigJson`. The `./ai` and `./ai-runtime` entry points are bundled separately, so their copies of `Cactus_Runtime.ts` are distinct module instances. Tests that seed runtime state for run-fns bundled into `./ai` must read that same instance, which is only reachable through `_testOnly`. `scripts/test.ts` renames the `cactus` section to `provider-cactus` (matching `provider-hft`, `provider-nodellama`, `provider-api`) and points it at the new directory.
This was referenced May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces
@workglow/cactus, a new AI provider that wraps the needle-rs WASM runtime and the Needle 26M model for local, browser-compatible tool-calling. This provider enables specialized tool-routing inference without requiring external API calls or large model downloads.Key Changes
New provider package (
providers/cactus/):CactusProviderandCactusQueuedProviderclasses for worker and inline registrationCactus_ToolCalling— tool-routing inference with streaming supportCactus_Download/Cactus_DownloadRemove— model asset managementCactus_ModelSearch/Cactus_ModelInfo— model discovery and metadataRUN_CACTUS_TESTS=1)Core infrastructure:
Capability system:
tool-use,model.download,model.download-remove,model.search,model.infocapabilitiesIntegration:
scripts/test.ts)needle-rsdependency to rootpackage.jsonImplementation Details
~/.cache/cactus-models)run_streamcallback for real-time token emission if available in needle-rs.tmpsuffix pattern to prevent partial downloadsremoveCachedAssets()disposes engines, clears config cache, and removes persisted assetsAll source files include Apache 2.0 license headers with 2026 copyright year per project conventions.
https://claude.ai/code/session_015FARxMpsffnqxqXg59MHX8