• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

agentic-dev-library / thumbcode / 21933693261

12 Feb 2026 04:34AM UTC coverage: 27.702% (-0.7%) from 28.372%
21933693261

push

github

web-flow
feat(ai): real Anthropic/OpenAI streaming + agent routing (#117)

* feat(ai): add AI client abstraction with Anthropic and OpenAI implementations

Create provider-agnostic AIClient interface with types for messages and
streaming chunks. Implement AnthropicClient using @anthropic-ai/sdk with
message streaming via the stream() API, and OpenAIClient using the openai
SDK with async iterator streaming. Add AIClientFactory for provider-based
client creation. Includes comprehensive unit tests for all components.

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

* feat(ai): replace ChatService mock with real AI streaming

Remove simulateAgentResponse() and getAgentResponsePlaceholder() mock
methods. Integrate AIClientFactory with CredentialService to resolve the
user's AI provider and API key from secure storage. Stream real AI
responses through the existing message delta event system. Add error
handling that displays helpful messages when no API key is configured.

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

* feat(ai): add agent-specific system prompts for response routing

Create AgentPrompts module with specialized system prompts for each agent
type: Architect (system design), Implementer (code generation), Reviewer
(code review), and Tester (test writing). Wire ChatService to use
agent-specific prompts when calling the AI client, giving each agent a
distinct personality and area of expertise.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

399 of 2256 branches covered (17.69%)

Branch coverage included in aggregate %.

36 of 73 new or added lines in 5 files covered. (49.32%)

204 existing lines in 13 files now uncovered.

1075 of 3065 relevant lines covered (35.07%)

7.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.86
/packages/core/src/api/api.ts
1
/**
2
 * Secure API Client
3
 *
4
 * A wrapper around the global fetch function that adds request signing
5
 * for all calls to the MCP server.
6
 */
7
import { requestSigningService } from '../security/RequestSigningService';
8

9
const MCP_SERVER_HOST = 'mcp.thumbcode.com'; // Replace with actual host
4✔
10

11
export async function secureFetch(
12
  input: RequestInfo | URL,
13
  init?: RequestInit
14
): Promise<Response> {
15
  let url: string;
UNCOV
16
  if (typeof input === 'string') {
×
UNCOV
17
    url = input;
×
UNCOV
18
  } else if (input instanceof URL) {
×
19
    url = input.href;
×
20
  } else {
21
    url = input.url;
×
22
  }
23

24
  // Securely validate the hostname to prevent subdomain attacks
25
  // Only match exact hostname OR legitimate subdomains (prefixed with '.')
UNCOV
26
  const hostname = new URL(url).hostname;
×
27
  const isValidMcpHost =
UNCOV
28
    hostname === MCP_SERVER_HOST || hostname.endsWith(`.${MCP_SERVER_HOST}`);
×
29

30
  if (isValidMcpHost) {
×
UNCOV
31
    const method = init?.method?.toUpperCase() || 'GET';
×
32
    let body: string | undefined;
UNCOV
33
    if (!init?.body) {
×
UNCOV
34
      body = undefined;
×
UNCOV
35
    } else if (typeof init.body === 'string') {
×
UNCOV
36
      body = init.body;
×
37
    } else {
UNCOV
38
      body = JSON.stringify(init.body);
×
39
    }
40

UNCOV
41
    const signingHeaders = await requestSigningService.signRequest(url, method, body);
×
42

UNCOV
43
    if (signingHeaders) {
×
UNCOV
44
      init = {
×
45
        ...init,
46
        headers: {
47
          ...init?.headers,
48
          ...signingHeaders,
49
        },
50
      };
51
    }
52
  }
53

UNCOV
54
  return fetch(input, init);
×
55
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc