Skip to content

feat: mock AI provider for run route testing without API keys#2056

Merged
nick-inkeep merged 13 commits intomainfrom
feat/echo-ai-provider
Feb 17, 2026
Merged

feat: mock AI provider for run route testing without API keys#2056
nick-inkeep merged 13 commits intomainfrom
feat/echo-ai-provider

Conversation

@nick-inkeep
Copy link
Collaborator

@nick-inkeep nick-inkeep commented Feb 17, 2026

Summary

  • Adds a built-in mock AI provider implementing LanguageModelV2 for testing run routes without real API keys
  • Registered in ModelFactory as mock/{modelName} alongside anthropic, openai, google, etc.
  • 19 unit tests covering interface compliance, streaming, ModelFactory integration, and edge cases
  • Docs updated in models.mdx

Motivation

Run domain endpoints (/v1/chat/completions, /api/chat, A2A) require a real Anthropic/OpenAI API key to produce responses. This blocks:

  • Local dev pipeline validation after pnpm setup-dev
  • CI/CD integration tests for run routes
  • Quick health checks on the run API without incurring LLM costs

Approach

Mock provider (packages/agents-core/src/utils/mock-provider.ts):

  • Implements LanguageModelV2 from @ai-sdk/provider
  • doGenerate: returns deterministic text with model name, message count, last user message, timestamp
  • doStream: streams response line-by-line with small delays simulating real streaming
  • Synthetic token usage (chars/4)
  • No API keys required

ModelFactory integration (packages/agents-core/src/utils/model-factory.ts):

  • Added mock to BUILT_IN_PROVIDERS
  • mock/default, mock/anything all resolve via createMockModel()

Test plan

19 unit tests in packages/agents-core/src/__tests__/utils/mock-provider.test.ts:

  • LanguageModelV2 interface compliance (specificationVersion, provider, modelId)
  • Any model name accepted under mock/ prefix
  • Structured mock response with all fields
  • Message count reflects prompt length
  • Synthetic token usage (inputTokens + outputTokens = totalTokens)
  • Long messages truncated to 200 chars
  • No user message → "(no user message)"
  • Custom model names in response
  • Streaming: multiple chunks with correct part types
  • Streaming: line-by-line deltas with newline separators
  • Streaming: conversation history message count
  • ModelFactory.parseModelString for mock/
  • ModelFactory.createModel produces working mock model
  • Mock model works without API keys
  • Mock model works with providerOptions present
  • Unsupported providers rejected
  • validateConfig passes for mock/default

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Feb 17, 2026 1:45pm
agents-docs Ready Ready Preview, Comment Feb 17, 2026 1:45pm
agents-manage-ui Ready Ready Preview, Comment Feb 17, 2026 1:45pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Feb 17, 2026

🦋 Changeset detected

Latest commit: b6a707b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@inkeep/agents-core Patch
@inkeep/agents-api Patch
@inkeep/agents-manage-ui Patch
@inkeep/agents-cli Patch
@inkeep/agents-sdk Patch
@inkeep/agents-work-apps Patch
@inkeep/ai-sdk-provider Patch
@inkeep/create-agents Patch
@inkeep/agents-manage-mcp Patch
@inkeep/agents-mcp Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

nick-inkeep and others added 4 commits February 17, 2026 03:59
Implements LanguageModelV2 interface that returns deterministic, structured
responses with streaming support. Registered as 'echo' provider in
ModelFactory. No API key required. Logs warning in production.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests cover LanguageModelV2 interface compliance, non-streaming/streaming
responses, message counting, token usage, truncation, ModelFactory
integration, and production warning behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Echo provider entry to the Supported Models table and a dedicated
section covering configuration, response format, token usage, streaming,
and production warning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The echo provider is a dev/testing utility, not a key product feature.
Reduce documentation to a table entry and a one-line tip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

(2) Total Issues | Risk: Medium

🟠⚠️ Major (1) 🟠⚠️

Inline Comments:

  • 🟠 Major: model-factory.ts:206 Echo provider throws "Unsupported provider: echo" when providerOptions are supplied

🟡 Minor (1) 🟡

Inline Comments:

  • 🟡 Minor: echo-provider.test.ts:322-339 Production warning test doesn't verify logger was actually called

💭 Consider (5) 💭

💭 1) echo-provider.ts / index.ts Public API surface expansion

Issue: The echo provider is exported via the utils/index.ts barrel, making createEchoModel and EchoLanguageModel part of the public @inkeep/agents-core API.
Why: While internally-facing, this expands the public contract surface. Any breaking changes to the echo provider shape would technically be breaking changes to the core package API.
Fix: Consider either: (1) not exporting from the barrel file and importing directly in model-factory.ts, or (2) adding a JSDoc comment marking it as @internal or @experimental.
Refs: utils/index.ts:6

💭 2) echo-provider.test.ts Test style inconsistency

Issue: The echo-provider tests use it() syntax while the adjacent model-factory.test.ts uses test() syntax.
Why: While functionally equivalent, maintaining consistent test style within the same directory aids readability.
Fix: Consider changing it to test throughout to match model-factory.test.ts conventions.
Refs: model-factory.test.ts:1-2

💭 3) model-factory.ts:206 Type cast through unknown

Issue: The double cast as unknown as LanguageModel bypasses TypeScript's structural type checking entirely.
Why: If the ai package's LanguageModel type adds required properties in a future version, TypeScript won't catch the incompatibility at compile time. Currently low-risk since both types are from the same AI SDK ecosystem.
Fix: The current approach is pragmatic. Consider adding an integration test that explicitly verifies the echo model works with AI SDK's streamText/generateText functions.
Refs: model-factory.ts:53-55 — similar cast for Azure

💭 4) package.json:137 Version pinning inconsistency

Issue: The new @ai-sdk/provider dependency uses exact pinning ("3.0.2") while some siblings like @ai-sdk/azure use caret (^3.0.4).
Why: Exact pinning is safer for reproducibility but creates more maintenance burden for coordinated upgrades.
Fix: Consider whether all @ai-sdk/* packages should use consistent version pinning strategy.
Refs: package.json:137

💭 5) models.mdx:306-308 Tip placement

Issue: The echo provider Tip is placed after the Provider Options SkillRule section (~230 lines after the models table where echo is introduced).
Why: Users scanning the models table may not discover the Tip explaining echo's purpose. The placement after Provider Options implies echo has special options to configure, but it actually has none.
Fix: Consider moving the Tip closer to the models table (after line 79), or adding a brief inline note in the table description column.
Refs: models.mdx:77


💡 APPROVE WITH SUGGESTIONS

Summary: The echo provider implementation is well-designed and follows existing patterns nicely. The main issue to address is the missing echo case in createProvider() — when users pass any providerOptions (even unrelated ones), the echo provider will crash with "Unsupported provider: echo". This is a straightforward fix. The test coverage is comprehensive (20 tests), the documentation is accurate, and the dependency addition is justified. Once the createProvider case is added, this is ready to ship! 🚀

Discarded (8)
Location Issue Reason Discarded
echo-provider.ts:50-56 Timestamp variability in response Intentional per spec — "deterministic" refers to structure, not exact content
PR description Lists integration tests T1-T8 as implemented Documentation gap in PR body, not code issue; spec clearly defers these
echo-provider.ts LanguageModelV2 interface implementation Validated as consistent with InkeepChatLanguageModel pattern
utils/index.ts Export barrel pattern Validated as following alphabetical order convention
models.mdx:77 Table row format Validated as consistent with other provider entries
package.json Dependency justified @ai-sdk/provider is already a transitive dep, making explicit is correct
pnpm-lock.yaml Lockfile change Proportionate to package.json edit, only 3 lines added
.changeset/ Changeset correctness Correctly scoped to agents-core with patch bump
Reviewers (7)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-standards 1 0 0 0 1 0 0
pr-review-consistency 6 0 1 0 0 0 5
pr-review-product 4 0 1 0 0 0 3
pr-review-tests 2 0 0 0 1 0 1
pr-review-types 1 0 1 0 0 0 0
pr-review-devops 5 0 1 0 0 0 4
pr-review-docs 1 0 1 0 0 0 0
Total 20 0 5 0 2 0 13

Note: The MAJOR finding was identified by both pr-review-standards and pr-review-consistency (merged into single inline comment).

@github-actions github-actions bot deleted a comment from claude bot Feb 17, 2026
@inkeep
Copy link
Contributor

inkeep bot commented Feb 17, 2026

📚 Documentation Review

The documentation updates in models.mdx look good:

  • ✅ Echo provider added to the supported models table with "None required" for API key
  • ✅ Tip block clearly explains the use case for testing and CI/CD

No additional documentation updates needed. The echo provider is appropriately documented in the model configuration reference where users would naturally look for this information.

…sertion

- Guard echo provider from createProvider path when providerOptions are present
- Add test verifying echo works with providerOptions
- Fix production warning test to verify logProductionWarning is called

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

(0) Total Issues | Risk: Low

This is a delta re-review following commit 1dd97408 which addressed the feedback from my prior review.

Prior Issues — Now Resolved

Issue Status Resolution
🟠 MAJOR: Echo provider throws when providerOptions supplied Resolved Added provider !== 'echo' guard at line 186 to bypass createProvider()
🟡 Minor: Production warning test lacks assertion Resolved Added vi.spyOn() on logProductionWarning and expect(logSpy).toHaveBeenCalled()

Delta Changes Reviewed

+ if (provider !== 'echo' && (provider === 'azure' || Object.keys(providerConfig).length > 0)) {

The guard correctly ensures echo models always route to the default switch case (line 205-206), avoiding the createProvider() path that lacks an echo case.

New test coverage:

it('should create echo model even when providerOptions are present', () => {
  const model = ModelFactory.createModel({
    model: 'echo/default',
    providerOptions: { baseURL: 'https://example.com' },
  });
  expect(model).toBeDefined();
});

This validates the fix and guards against regression.


✅ APPROVE

Summary: Both issues from the prior review have been cleanly resolved. The echo provider is now production-ready for its intended use case (testing and CI/CD without API keys). Ship it! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: Delta re-review with minimal scope — subagent dispatch skipped. Orchestrator reviewed delta directly.

Reviewer suggestion — the tip was 230 lines below the table entry where
echo first appears. Moving it right after the models table note improves
discoverability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nick-inkeep
Copy link
Collaborator Author

Review feedback addressed

Resolved (MAJOR + MINOR):
Both inline threads resolved — the provider !== 'echo' guard in model-factory.ts:186 and the logProductionWarning spy in the production warning test. Confirmed by the delta re-review.

Consider items assessment:

  1. Public API surface expansion — Declined. The barrel export follows existing patterns; ModelFactory imports from the barrel. Marking @internal adds JSDoc churn with no enforcement benefit.

  2. Test style it() vs test() — Declined. Both are standard Vitest aliases used across the repo. Not worth a churn commit.

  3. Type cast through unknown — Declined. Same pattern used for Azure (model-factory.ts:53). Pragmatic and acknowledged by reviewer.

  4. Version pinning inconsistency — Declined. @ai-sdk/provider is a type-only import; exact pinning is intentional. Aligning all @ai-sdk/* pinning is a separate concern.

  5. Tip placement in docsAccepted. Moved the echo provider tip from after the Provider Options section (line 306) to right after the models table (line 80). Commit ff3f76da0.

nick-inkeep and others added 2 commits February 17, 2026 05:30
These are local working artifacts from /ship sessions and should not be
checked in.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spec files are local working artifacts and should not be in the repo.
Already gitignored in prior commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot deleted a comment from claude bot Feb 17, 2026
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

(0) Total Issues | Risk: Low

This is a delta re-review following commits 1cc477b0 and fcb3af8e which are pure housekeeping changes.

Delta Changes Reviewed

Commits:

  • 1cc477b0 chore: gitignore .claude/specs/ and ship-state.json
  • fcb3af8e chore: remove spec file from tracked files

Changes:

  1. Added .claude/specs/ and .claude/ship-state.json to .gitignore
  2. Removed .claude/specs/echo-ai-provider.md from version control

Analysis

These are purely administrative changes with no product or code impact:

  • The spec file was an internal design document used during implementation
  • Gitignoring local spec files and ship state is standard practice for working artifacts
  • No code changes, no test changes, no documentation changes

Prior Review Status

Review Status Notes
Initial review (2026-02-17) 2 issues raised (1 Major, 1 Minor)
Delta re-review #1 ✅ Approved Both issues resolved
Delta re-review #2 ✅ Approved Docs improvement only
Delta re-review #3 ✅ Approved Removed production warning (acceptable)
Delta re-review #4 (this) Housekeeping only

✅ APPROVE

Summary: Pure housekeeping delta — removing internal spec file from version control and gitignoring local working artifacts. The echo AI provider implementation is complete and ready to ship. All prior issues resolved, comprehensive test coverage (20+ tests), clean LanguageModelV2 implementation, proper ModelFactory integration. 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: Trivial delta (housekeeping) — subagent dispatch skipped. Orchestrator reviewed delta directly.

Rename echo/ prefix to mock/ across provider, tests, model factory,
exports, docs, and changeset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nick-inkeep nick-inkeep changed the title feat: echo AI provider for run route testing without API keys feat: mock AI provider for run route testing without API keys Feb 17, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

(0) Total Issues | Risk: Low

This is a delta re-review following commits e5ea640a and fcb3af8e which rename the provider from "echo" to "mock".

Delta Changes Reviewed

Commits since last review:

  • e5ea640a refactor: rename echo provider to mock provider
  • fcb3af8e chore: remove spec file from tracked files
  • aaa9b8d7 fix: increase browser screenshot test timeouts (unrelated to this PR)

Rename scope:

Before After
echo-provider.ts mock-provider.ts
EchoLanguageModel MockLanguageModel
createEchoModel() createMockModel()
echo/default mock/default
provider !== 'echo' provider !== 'mock'

Verification:

  • ✅ All file renames applied correctly
  • ✅ Class/function names updated throughout
  • ✅ Model strings updated (echo/mock/)
  • ✅ ModelFactory guard updated at line 186
  • ✅ BUILT_IN_PROVIDERS updated
  • ✅ Documentation (models.mdx) updated
  • ✅ Changeset message updated
  • ✅ Barrel export updated (index.ts)
  • ✅ No residual "echo" references in source code (verified via grep)
  • ✅ Test file renamed and all assertions updated

Analysis

The rename from "echo" to "mock" is a sensible naming improvement:

  • "Mock" is more conventional terminology for test doubles in software engineering
  • The provider's purpose (deterministic responses for testing) aligns better with "mock" semantics
  • All 20+ tests pass with the updated naming

No functional changes were introduced — this is a pure refactoring commit.

Prior Review Status

Review Status Notes
Initial review (2026-02-17) 2 issues raised (1 Major, 1 Minor)
Delta re-review #1 ✅ Approved Both issues resolved
Delta re-review #2 ✅ Approved Docs improvement only
Delta re-review #3 ✅ Approved Removed production warning
Delta re-review #4 ✅ Approved Housekeeping only
Delta re-review #5 (this) Pure rename — echo → mock

✅ APPROVE

Summary: Clean rename from "echo" to "mock" provider — all references updated consistently across source, tests, docs, and changeset. The mock AI provider is ready to ship for its intended use case (testing and CI/CD without API keys). 🎉

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: Trivial delta (pure rename) — subagent dispatch skipped. Orchestrator reviewed delta directly.

@github-actions github-actions bot deleted a comment from claude bot Feb 17, 2026
@nick-inkeep nick-inkeep merged commit 11f4e14 into main Feb 17, 2026
7 of 11 checks passed
@nick-inkeep nick-inkeep deleted the feat/echo-ai-provider branch February 17, 2026 13:42
@github-actions
Copy link
Contributor

🔎💬 Inkeep AI search and chat service is syncing content for source 'Inkeep Agent Framework Docs'

Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

(0) Total Issues | Risk: Low

This is a delta re-review following commit b6a707bf which simplifies the mock provider documentation.

Delta Changes Reviewed

Commit: b6a707bf docs: lighten mock provider entry in models table

Changes:

  • Simplified the models table row from mock/default
    mock/any-name to just mock/default
  • Removed the (testing) suffix from the provider name
  • Removed the Tip block explaining the mock provider's purpose

Analysis

This is a reasonable documentation cleanup:

  • The mock provider accepts any model name (mock/anything works), but documenting just mock/default is sufficient for typical use
  • "None required" for the API key column already signals this is a testing utility
  • The PR description and changeset provide adequate context about the mock provider's purpose
  • Users who need more details can check the source or use mock/default and discover the deterministic response format

The change aligns with keeping documentation concise — the Tip was useful when placed far from the table, but after the prior move (closer to the table) and now with a single clean row, the extra explanation is redundant.

Prior Review Status

Review Status Notes
Initial review (2026-02-17) 2 issues raised (1 Major, 1 Minor)
Delta re-review #1 ✅ Approved Both issues resolved
Delta re-review #2 ✅ Approved Docs improvement (tip placement)
Delta re-review #3 ✅ Approved Removed production warning
Delta re-review #4 ✅ Approved Housekeeping (.gitignore)
Delta re-review #5 ✅ Approved echo → mock rename
Delta re-review #6 (this) Docs simplification

✅ APPROVE

Summary: Clean documentation simplification — the mock provider entry is now minimal and consistent with other providers in the table. The mock AI provider implementation is complete with comprehensive test coverage (20+ tests), proper LanguageModelV2 implementation, and ModelFactory integration. Ready to ship! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: Trivial delta (docs cleanup) — subagent dispatch skipped. Orchestrator reviewed delta directly.

@github-actions github-actions bot deleted a comment from claude bot Feb 17, 2026
nick-inkeep added a commit that referenced this pull request Feb 17, 2026
The mock provider PR (#2056) added 'mock' to BUILT_IN_PROVIDERS but
didn't update the hardcoded error message assertions in agents-api
ModelFactory tests, breaking CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nick-inkeep added a commit that referenced this pull request Feb 17, 2026
…anges

The mock provider PR (#2056) added 'mock' to BUILT_IN_PROVIDERS but
didn't update hardcoded error message assertions in agents-api tests.

- Switch 3 assertions to substring match on the stable prefix instead
  of hardcoding the full provider list (won't break on next addition)
- Remove redundant unsupported-provider test from mock-provider.test.ts
  (already covered by dedicated ModelFactory tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nick-inkeep added a commit that referenced this pull request Feb 17, 2026
…anges (#2068)

The mock provider PR (#2056) added 'mock' to BUILT_IN_PROVIDERS but
didn't update hardcoded error message assertions in agents-api tests.

- Switch 3 assertions to substring match on the stable prefix instead
  of hardcoding the full provider list (won't break on next addition)
- Remove redundant unsupported-provider test from mock-provider.test.ts
  (already covered by dedicated ModelFactory tests)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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