Skip to content

feat: add Tier 2 tools (TTS, MOA) and safety config extension - #39

Merged
avoidwork merged 2 commits into
mainfrom
feat/add-tools-tier2
May 27, 2026
Merged

feat: add Tier 2 tools (TTS, MOA) and safety config extension#39
avoidwork merged 2 commits into
mainfrom
feat/add-tools-tier2

Conversation

@avoidwork

Copy link
Copy Markdown
Owner

Description

Adds Tier 2 tools (text-to-speech and mixture of agents) and extends the sandbox safety configuration with a configurable safety subobject. All new tools register with API-key-based gating and 100% test coverage.

Type of Change

  • New feature (non-breaking change which adds functionality)

Testing

  • Added 10 tests for text_to_speech (text validation, model/voice validation, API call, error handling, network errors)
  • Added 11 tests for mixture_of_agents (message validation, API key gating, parallel calls, partial aggregation on failure, all-fail scenario, network errors)
  • Updated 11 existing tests to use safety config from runtime options instead of env vars
  • Updated integration tests to cover new tool registration paths
  • All 449 tests pass across 120 suites

Coverage

  • 100% line coverage maintained (449/449 tests pass, new files at 100% line coverage)

Checklist

  • npm run lint passes
  • Tests pass with 100% line coverage
  • No forbidden patterns used
  • Conventional Commit style applied

Changed Files

New:

  • src/tools/tts.js — OpenAI TTS text-to-speech tool
  • src/tools/moa.js — Mixture of Agents with 4 parallel OpenRouter calls + aggregation
  • tests/unit/tools_tts.test.js — 10 unit tests
  • tests/unit/tools_moa.test.js — 11 unit tests

Modified:

  • src/config/schemas.js — Added sandbox.safety subobject with urlFilter and pythonImportHook booleans
  • config.yaml — Added sandbox.safety section
  • src/tools/index.js — Registered TTS and MOA tools with API-key gating
  • src/tools/code.js — Use pythonImportHook from safety config options instead of PYTHON_IMPORT_HOOK env var
  • src/tools/vision.js — Fixed missing analysisPrompt constant
  • tests/unit/tools_code.test.js — Updated to use safety config from options
  • tests/unit/tool_registration.test.js — Added registration tests for TTS and MOA
  • tests/unit/config.test.js — Added tests for safety config schema

Threat Model

  • TTS tool: Requires OPENAI_API_KEY. Saves MP3 to user home directory. Character-based billing warning in tool description.
  • MOA tool: Requires OPENROUTER_API_KEY. Makes 5 API calls (4 parallel + 1 aggregate). Cost warning in tool description. No network:outbound permission required.
  • Safety config: Users can disable URL filtering and Python import hooks for local/dev usage. Default-enables both for safety.

- Add sandbox.safety subobject with urlFilter and pythonImportHook options
- Update sandbox.timeout.seconds to allow 0 (no limit)
- Add text_to_speech tool (OpenAI TTS API, saves to ~/voice-memos/)
- Add mixture_of_agents tool (4 parallel OpenRouter calls + aggregation)
- Wire pythonImportHook from safety config into code.js instead of env var
- Fix bug in vision.js (missing analysisPrompt constant)
- Add comprehensive tests for all new tools
- Update tool registration with API-key-based gating (OPENAI_API_KEY, OPENROUTER_API_KEY)
@avoidwork avoidwork self-assigned this May 27, 2026
- Add POSIX setrlimit(RLIMIT_AS) enforcement for execute_code tool
- Use posix npm package (CJS) to call setrlimit with 'as' (address space) limit
- Parse memoryLimit config string ('512m', '2g') to bytes via parseMemLimit()
- Explicitly kill child process on timeout via child.kill('SIGKILL')
- AbortController signal may not reliably kill all interpreters
- Add posix as runtime dependency in package.json
@avoidwork
avoidwork merged commit d22cf43 into main May 27, 2026
@avoidwork
avoidwork deleted the feat/add-tools-tier2 branch May 27, 2026 10:30
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