Commit Graph

63 Commits

Author SHA1 Message Date
JackChen a24dcb462a
Merge pull request #47 from JackChen-me/feat/local-model-tool-calling
feat(llm): fallback tool-call extraction for local models
2026-04-05 12:00:35 +08:00
JackChen a4a1add8ca fix(agent): merge abort signals instead of overriding caller's signal
When both timeoutMs and a caller-provided abortSignal were set, the
timeout signal silently replaced the caller's signal. Now they are
combined via mergeAbortSignals() so either source can cancel the run.

Also removes dead array-handling branch in text-tool-extractor.ts
(extractJSONObjects only returns objects, never arrays).
2026-04-05 12:00:16 +08:00
JackChen bc31008f4e feat(llm): add fallback tool-call extraction for local models (#15)
Local models (Ollama, vLLM) sometimes return tool calls as text instead
of using the native tool_calls wire format. This adds a safety-net
extractor that parses tool calls from model text output when native
tool_calls is empty.

- Add text-tool-extractor with support for bare JSON, code fences,
  and Hermes <tool_call> tags
- Wire fallback into OpenAI adapter chat() and stream() paths
- Add onWarning callback when model ignores configured tools
- Add timeoutMs on AgentConfig for per-run abort (local models can
  be slow)
- Add 26 tests for extractor and fallback behavior
- Document local model compatibility in README
2026-04-05 11:49:10 +08:00
JackChen 9a81a13982
feat(llm): add Gemini adapter (#28)
feat: Add support for Gemini model
2026-04-05 11:48:32 +08:00
MrAvalonApple 553bf24e61 chore: support Node >=18, add optional @google/genai peer dependency and API key fallback 2026-04-04 22:12:28 +03:00
JackChen 9f5afb10f5
feat(orchestrator): add onApproval callback for human-in-the-loop (#32)
* feat(orchestrator): add onApproval callback for human-in-the-loop (#32)

Add an optional `onApproval` callback to OrchestratorConfig that gates
between task execution rounds. After each batch of parallel tasks
completes, the callback receives the completed tasks and the tasks about
to start, returning true to continue or false to abort gracefully.

Key changes:
- Add 'skipped' to TaskStatus for user-initiated abort (distinct from 'failed')
- Add skip(), skipRemaining(), cascadeSkip() to TaskQueue
- Add 'task_skipped' to OrchestratorEvent for progress monitoring
- Approval gate in executeQueue() with try/catch for callback errors
- Synthesis prompt now includes skipped tasks section
- 17 new tests covering queue skip operations and orchestrator integration

Closes #32

* docs: clarify onApproval contract and add missing test scenarios

- Document skip() cascade semantics, skipRemaining() in-flight constraint,
  and onApproval trigger conditions / mutation warning
- Add concurrency safety comment on completedThisRound
- Note task_skipped as breaking union addition on OrchestratorEvent
- Add 3 test scenarios: single-batch no-callback, mixed success/failure
  batch, and onProgress task_skipped event relay
2026-04-05 02:46:20 +08:00
JackChen d327acb89b
Merge pull request #35 from tmchow/osc/34-add-llama-cpp-server
docs: add llama.cpp server to local model providers
2026-04-05 02:26:35 +08:00
Trevin Chow 9e72c5029e docs: add llama.cpp server to local model providers
llama-server exposes an OpenAI-compatible API at /v1/chat/completions,
so it works with provider: 'openai' + baseURL like Ollama and vLLM.
Added to the supported providers table and the feature bullet.

Fixes #34
2026-04-04 10:49:21 -07:00
JackChen a1ccbfea61
feat(agent): add beforeRun / afterRun lifecycle hooks (#45)
* feat(agent): add beforeRun / afterRun lifecycle hooks (#31)

Add optional hook callbacks to AgentConfig for cross-cutting concerns
(guardrails, logging, token budgets) without modifying framework internals.

- beforeRun: receives prompt + agent config, can modify or throw to abort
- afterRun: receives AgentRunResult, can modify or throw to fail
- Works with all three execution modes: run(), prompt(), stream()
- 15 test cases covering modify, throw, async, composition, and history integrity

* fix(agent): preserve non-text content blocks in beforeRun hook

- applyHookContext now replaces only text blocks, keeping images and
  tool results intact (was silently stripping them)
- Use backward loop instead of reverse() + find() for efficiency
- Clarify JSDoc that only `prompt` is applied from hook return value
- Add test for mixed-content user messages

* fix(agent): address review feedback on beforeRun/afterRun hooks

- Normalize stream done event to always yield AgentRunResult
- Move transitionTo('completed') after afterRun to fix state ordering
- Strip hook functions from BeforeRunHookContext.agent to avoid self-references
- Pass originalPrompt to applyHookContext to avoid redundant message scan
- Clarify afterRun JSDoc: not called when the run throws
- Add tests: error-path skip, outputSchema+afterRun, ctx.agent shape, multi-turn hooks
2026-04-05 00:41:21 +08:00
Ibrahim Kazimov 944918d5ae
Merge branch 'main' into main 2026-04-04 13:43:40 +03:00
JackChen 25b144acf3 chore: remove hardcoded cache bust param from Star History URLs 2026-04-04 18:29:11 +08:00
Marcelo Ceccon 10074c9b7d
feat(llm): add first-class Grok (xAI) support with dedicated GrokAdapter (#44)
feat(llm): add first-class Grok (xAI) support with dedicated GrokAdapter
2026-04-04 18:20:55 +08:00
JackChen 071d5dce61 docs: add Latent Space mention to README 2026-04-03 19:18:52 +08:00
JackChen fea9df3f7a chore: add coverage/ to .gitignore 2026-04-03 17:38:41 +08:00
JackChen 2253122515 docs: reposition README around TypeScript-native, goal-to-result, lightweight differentiators 2026-04-03 17:35:12 +08:00
JackChen 0111876264
feat: add onTrace observability callback (#18)
Add lightweight onTrace callback to OrchestratorConfig that emits
structured span events (llm_call, tool_call, task, agent) with timing,
token usage, and runId correlation. Zero overhead when not subscribed.

Closes #18
2026-04-03 15:28:59 +08:00
JackChen 17546fd93e docs: merge Gemma 4 examples, reorder README sections
- Merge examples 08 (runTasks) and 09 (runTeam) into a single Gemma 4 example
- Renumber: structured output → 09, task retry → 10
- Move Author and Contributors sections to bottom in both READMEs
- Add Author section to English README
2026-04-03 14:32:48 +08:00
JackChen 27c0103736 docs: add examples for structured output and task retry 2026-04-03 14:23:22 +08:00
JackChen 043deaf562 docs: update CLAUDE.md with structured output and task retry 2026-04-03 14:16:44 +08:00
JackChen d9b20c0cf6 fix: guard retry fields against Infinity/NaN
Use Number.isFinite() to sanitize maxRetries, retryDelayMs, and
retryBackoff before entering the retry loop. Prevents unbounded
retries from Infinity or broken loop bounds from NaN.
2026-04-03 14:14:34 +08:00
JackChen 42f3717115 chore: bump version to 0.2.0 2026-04-03 14:13:33 +08:00
JackChen 2187f3b310
docs: add Structured Output and Task Retry to feature list (#39) 2026-04-03 14:11:54 +08:00
JackChen 4d7564b71a
feat: task-level retry with exponential backoff (#37)
* feat: add task-level retry with exponential backoff

Add `maxRetries`, `retryDelayMs`, and `retryBackoff` to task config.
When a task fails and retries remain, the orchestrator waits with
exponential backoff and re-runs the task with a fresh agent conversation.
A `task_retry` event is emitted via `onProgress` for observability.
Cascade failure only occurs after all retries are exhausted.

Closes #30

* fix: address review — extract executeWithRetry, add delay cap, fix tests

- Extract `executeWithRetry()` as a testable exported function
- Add `computeRetryDelay()` with 30s max cap (prevents runaway backoff)
- Remove retry fields from `ParsedTaskSpec` (dead code for runTeam path)
- Deduplicate retry event emission (single code path for both error types)
- Injectable delay function for test determinism
- Rewrite tests to call the real `executeWithRetry`, not a copy
- 15 tests covering: success, retry+success, retry+failure, backoff
  calculation, delay cap, delay function injection, no-retry default

* fix: clamp negative maxRetries/retryBackoff to safe values

- maxRetries clamped to >= 0 (negative values treated as no retry)
- retryBackoff clamped to >= 1 (prevents zero/negative delay oscillation)
- retryDelayMs clamped to >= 0
- Add tests for negative maxRetries and negative backoff

Addresses Codex review P1 on #37

* fix: accumulate token usage across retry attempts

Previously only the final attempt's tokenUsage was returned, causing
under-reporting of actual model consumption when retries occurred.
Now all attempts' token counts are summed in the returned result.

Addresses Codex review P2 (token usage) on #37
2026-04-03 14:08:36 +08:00
JackChen 99b028dc1d
fix: address Codex review for structured output (#36) (#38)
- Include error feedback user turn in mergedMessages to maintain
  alternating user/assistant roles required by Anthropic API
- Use explicit undefined check instead of ?? for structured merge
  to preserve null as a valid structured output value
2026-04-03 14:08:27 +08:00
JackChen fbc5546fa1
feat: add optional outputSchema (Zod) for structured agent output (#36)
When `outputSchema` is set on AgentConfig, the agent's final text output
is parsed as JSON, validated against the Zod schema, and exposed via
`result.structured`. On validation failure a single retry with error
feedback is attempted automatically.

Closes #29
2026-04-03 13:45:47 +08:00
JackChen e0438e3764 docs: add security policy 2026-04-03 12:10:47 +08:00
JackChen 277dac2fe4 docs: add Code of Conduct and issue templates
Add Contributor Covenant Code of Conduct and GitHub issue templates
(bug report + feature request) to reach 100% community health score.
2026-04-03 12:09:41 +08:00
JackChen 0db0a4d869 docs: adapt Star History chart for dark mode 2026-04-03 09:57:18 +08:00
JackChen 37bd56b193 docs: refresh Star History chart cache 2026-04-03 09:56:17 +08:00
JackChen 4fc7bb3f85 docs: add Gemma 4 to Model Agnostic feature description 2026-04-03 09:38:22 +08:00
JackChen d86ea766d3 feat: add Gemma 4 auto-orchestration example (runTeam)
Add examples/09-gemma4-auto-orchestration.ts demonstrating runTeam()
with Gemma 4 as the coordinator — the framework's key feature running
fully local. The coordinator successfully decomposes goals into JSON
task arrays, schedules dependencies, and synthesises results.

Verified on gemma4:e2b (5.1B params) with Ollama 0.20.0-rc1.
2026-04-03 09:28:45 +08:00
JackChen f9fcac0c38 feat: add Gemma 4 local model example with tool-calling
Add examples/08-gemma4-local.ts demonstrating a pure-local multi-agent
team using Gemma 4 via Ollama — zero API cost. Two agents (researcher +
summarizer) collaborate through a task pipeline with bash, file_write,
and file_read tools. Verified on gemma4:e2b with Ollama 0.20.0-rc1.

Update both READMEs: add example 08 to the examples table and note
Gemma 4 as a verified local model with tool-calling support.
2026-04-03 09:12:44 +08:00
MrAvalonApple 9f3e4751aa docs: update example for Gemini adapter with correct usage instructions 2026-04-02 22:17:54 +03:00
MrAvalonApple 91826b5c22 docs: add example for Gemini model 2026-04-02 22:16:16 +03:00
MrAvalonApple 4e4226783d docs: update README to include Gemini model support 2026-04-02 22:06:55 +03:00
JackChen d8a217106f docs: add DECISIONS.md recording deliberate "won't do" choices
Document 5 features we evaluated and chose not to implement
(handoffs, checkpointing, A2A, MCP, dashboard) to maintain
our "simplest multi-agent framework" positioning.

Closes #17, #20.
2026-04-03 03:02:56 +08:00
MrAvalonApple ec6be79dc4 Merge remote-tracking branch 'upstream/main' 2026-04-02 21:56:17 +03:00
JackChen 8d27c6a1fe docs: add supported providers section and clarify contributing guidelines
- Add Supported Providers table with 4 verified providers (Anthropic, OpenAI,
  Copilot, Ollama) and note that other OpenAI-compatible providers are unverified
- Update Contributing to distinguish baseURL verification (#25) from new adapters
- Note that local models via Ollama require no API key in Quick Start
2026-04-03 02:47:02 +08:00
MrAvalonApple 2bb220fc63 feat: add support for Gemini model 2026-04-02 21:41:56 +03:00
JackChen 24a2c4fe1a chore: add tsx to devDependencies for running examples 2026-04-03 02:20:47 +08:00
JackChen 94cccf24d7 docs: replace inline code examples with examples/ index table
Remove ~160 lines of duplicated code snippets from both READMEs.
Link to the runnable scripts in examples/ instead — single source of truth,
type-checked by npm run lint.
2026-04-03 02:18:58 +08:00
JackChen 31a0fa4951 docs: add examples for local models (Ollama) and fan-out/aggregate pattern
- 06-local-model.ts: mix Ollama (local) + Claude (cloud) in a runTasks pipeline,
  demonstrating baseURL and apiKey placeholder for OpenAI-compatible servers
- 07-fan-out-aggregate.ts: MapReduce pattern using AgentPool.runParallel() to
  fan out analysis to 3 perspective agents, then aggregate via a synthesizer
2026-04-03 02:12:05 +08:00
JackChen 6e6a85178b docs: sync Chinese README source file count (20 → 27) 2026-04-03 00:07:11 +08:00
JackChen 54400580a2 docs: fix source file count in README (20 → 27) 2026-04-03 00:05:31 +08:00
JackChen 3a46669a69 fix: use explicit crypto import for Node 18 compatibility
crypto.randomUUID() is not globally available in Node 18. Import
randomUUID from node:crypto explicitly so the framework works on
all supported Node versions (>=18).
2026-04-02 23:46:43 +08:00
JackChen a772312a68 chore: add tests, CI, contributing guide, and PR template
- 5 test files, 61 test cases covering TaskQueue, SharedMemory,
  ToolExecutor, ToolRegistry, and Semaphore
- GitHub Actions CI running lint + test on Node 18/20/22
- CONTRIBUTING.md with setup, commands, and PR workflow
- Pull request template with checklist
2026-04-02 23:43:54 +08:00
JackChen 80a8c1dcff fix: blocked tasks never unblocked when dependencies complete
isTaskReady() rejects non-pending tasks on its first line, but
unblockDependents() passed blocked tasks directly to it. This meant
dependent tasks stayed blocked forever after their dependencies
completed, breaking any workflow with task dependencies.

Fix: pass a pending-status copy so isTaskReady only checks the
dependency condition.
2026-04-02 23:43:49 +08:00
JackChen 01b93d9897 docs: lead Quick Start with runTeam, add output example and Node version 2026-04-02 22:35:45 +08:00
JackChen 736121fe10 docs: add lightweight positioning tagline to README headers 2026-04-02 22:24:08 +08:00
JackChen 9f9f4e95d4 docs: highlight auto task decomposition, add run modes table, move contributors up
- Rewrite headline to emphasize automatic goal-to-task decomposition
- Add "Auto Task Decomposition" as first item in Why section
- Add "Three Ways to Run" table (runAgent / runTeam / runTasks)
- Move Contributors section higher for visibility
- Bust star-history cache to refresh chart
2026-04-02 21:55:04 +08:00