Skip to content

V14: Reject unknown createAgent and defineTool options - #688

Merged
LinuxDevil merged 1 commit into
mainfrom
v14-reject-unknown-options
Oct 19, 2026
Merged

LinuxDevil merged 1 commit into
mainfrom
v14-reject-unknown-options

Conversation

@LinuxDevil

Copy link
Copy Markdown
Owner

Fixes audit finding DX-8 (Vercel competitor audit, 2026-10-19).

What was wrong

From JavaScript, YAML-built configs or as any, unknown top-level keys were silently ignored: createAgent({ maxOutputTokens: 100 }) built an agent with no token cap, and defineTool({ ..., requireApproval: true }) built a tool that runs without approval. Only TypeScript object literals caught it (TS2353). modelSettings already rejected unknown keys; the top level did not.

What changed

Behavior change: createAgent() and defineTool() now throw LOUSHO_CONFIG_INVALID for an option key they do not know (a key whose value is undefined is still ignored).

  • New src/utils/knownOptionKeys.ts: unknownOptionKey() finds the first unknown key and builds the message, reusing closestMatch() (edit distance) plus an alias map.
  • New src/createAgentKeys.ts: the createAgent allowlist, typed satisfies Record<keyof CreateAgentConfig, true> so it cannot drift from the type. Aliases: system/systemPrompt -> instructions, stopWhen/maxIterations/maxTurns -> maxSteps, every modelSettings key and its synonyms (maxOutputTokens, max_tokens, temperature, ...) -> modelSettings.<key>. The manifest key of a spread claudeProject() result is accepted (typed against ClaudeProject), since createAgent({ provider, ...project }) is the documented pattern.
  • defineTool(): allowlist typed satisfies Record<keyof DefineToolOptions, true>. Aliases: requireApproval/requiresApproval/needApproval -> needsApproval, inputSchema/parameters/schema/args -> input, handler/run/invoke -> execute, title -> displayName, timeout -> timeoutMs. Re-defining a tool by spreading it back in (defineTool({ ...tool, execute }), used in the test suite) still works: a defined tool's extra keys (inputSchema, tool, metadata) are accepted when inputSchema is the same schema as input.
  • SETTING_SYNONYMS in src/execution/modelSettings.ts is now exported (internal module) so the createAgent aliases reuse it.
  • Docs: docs/configuration.md (createAgent options) and docs/tools.md (defineTool options) describe the new error; llms.txt/llms-full.txt regenerated.

Tests

  • src/createAgent.test.ts "unknown options": maxOutputTokens and max_tokens throw did you mean 'modelSettings.maxTokens'?; temperature -> modelSettings.temperature; system/systemPrompt -> instructions; typos maxStep/permisions -> nearest key; a key with no match lists the allowed options; an undefined value is ignored. Confirmed failing before the fix.
  • src/tools/defineTool.test.ts: requireApproval: true throws did you mean 'needsApproval'? (plus needApproval, inputSchema, parameters, handler, deferLoad); no-match lists allowed options; undefined ignored; a spread defined tool is accepted while a stray inputSchema is rejected.
  • npx tsc --noEmit, npm run typecheck:tests, npm run lint, npm run api:check, npm run docs:llms:check: pass. npm run test:coverage: 407 files / 6037 tests pass; npm run fallow: exit 0. (A first full run had two timing-only flakes under load - upstreamFailures timeout and mcp/connect optional server - which pass in isolation and on rerun.)

Changelog: createAgent() and defineTool() now reject unknown option keys with a "did you mean" (e.g. requireApproval -> needsApproval, maxOutputTokens -> modelSettings.maxTokens) instead of silently ignoring them.

🤖 Generated with Claude Code

createAgent() and defineTool() now throw LOUSHO_CONFIG_INVALID for an
option key they do not know, with a "did you mean" that covers typos and
other SDKs' names (requireApproval -> needsApproval, maxOutputTokens ->
modelSettings.maxTokens, system -> instructions). The allowlists are typed
with `satisfies Record<keyof Options, true>` so they cannot drift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LinuxDevil
LinuxDevil force-pushed the v14-reject-unknown-options branch from ffaaaec to 07f66c4 Compare October 19, 2026 23:12
@LinuxDevil
LinuxDevil merged commit a130949 into main Oct 19, 2026
2 checks 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