This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Setup and installation
pnpm install # Install all dependencies for monorepo
# Development workflow
pnpm dev # Start development server (port 3002)
pnpm test # Run test suite with Vitest
pnpm test:coverage # Run tests with coverage report
pnpm build # Build for production
pnpm lint # Run Biome linter
pnpm format # Format code with Biome
# Database operations (run from monorepo root)
pnpm db:generate # Generate Drizzle migrations
pnpm db:push # Push schema changes to SQLite (shared database at ./local.db)
pnpm db:migrate # Run database migrations
pnpm db:studio # Open Drizzle Studio for database inspection
pnpm db:clean # Clean database
pnpm db:check # Check database schema
pnpm db:reset-schema # Reset database schema
# Running examples (from the examples directory)
# Note: Use the globally installed inkeep CLI, not npx
inkeep push agent-configurations/graph.graph.ts
inkeep chat
# Documentation development (from agents-docs directory)
pnpm dev # Start documentation site (port 3000)
pnpm build # Build documentation for productionThis is the Inkeep Agent Framework - a multi-agent AI system with A2A (Agent-to-Agent) communication capabilities. The system provides OpenAI Chat Completions compatible API while supporting sophisticated agent orchestration.
- Hub and Spoke Pattern: Router agents coordinate specialized agents
- Graph-Based Networks: Agents connected by transfer/delegation relationships
- A2A Protocol: JSON-RPC based communication following Google's A2A specification
- Context Preservation: Conversation state maintained across agent transitions
- Shared Database: Single SQLite database (
./local.db) at monorepo root shared by both APIs - agents: Individual AI agents with instructions and capabilities
- agent_graphs: Collections of agents with default entry points
- agent_relations: Transfer (
complete control transfer) and delegation (task assignment with return) relationships - tasks: Work units with hierarchical parent-child relationships via
task_relations - conversations: User sessions with active agent tracking
- messages: Unified format supporting both OpenAI Chat and A2A protocols
- tools: MCP servers and hosted tools with configuration
Agent Relationships:
- Transfer: Complete control transfer (router → specialist agent)
- Delegation: Task assignment with return (agent → sub-agent → return)
Task Communication:
// A2A JSON-RPC methods
POST /a2a/{agentId}
{
method: 'tasks/send' | 'tasks/get' | 'tasks/cancel'
params: { message, taskId, etc. }
}Builder Pattern for Configuration:
const agent = agent({
id: 'qa-agent',
name: 'QA Agent',
instructions: 'Answer questions...',
canTransferTo: () => [routerAgent],
canDelegateTo: () => [specialistAgent],
tools: { search: searchTool }
});
export const graph = agentGraph({
defaultAgent: routerAgent,
agents: [routerAgent, qaAgent, orderAgent]
// No tenantId or apiUrl needed - CLI injects from inkeep.config.ts
});
// No graph.init() call - CLI handles initialization when pushing- Context ID Preservation:
contextIdmust be maintained across all agent transitions for conversation continuity - Task Hierarchy: Parent-child task relationships track delegation chains via
task_relationstable - Message Threading: All messages stored in unified format supporting both chat and A2A protocols
- Multiple Transports: stdio, SSE, streamable HTTP
- Dynamic Discovery: Tools discovered from MCP servers at runtime
- Health Monitoring: Automated health checks for external tools
- JSON Schema → Zod: Automatic schema transformation for type safety
- Multi-tenancy: All entities scoped by
tenantId - Parallel Database Operations: Use
Promise.all()for concurrent queries (seegenerateTaskHandler.ts:49-60) - Race Condition Prevention: Check for existing tasks before creation (see
executionHandler.ts:71-96)
- Vitest: Test framework with 60-second timeouts for A2A interactions
- Isolated Databases: Each test worker gets in-memory SQLite database
- Integration Tests: End-to-end A2A communication testing
- Test Structure: Tests must be in
__tests__directories, named*.test.ts - Coverage Requirements: All new code paths must have test coverage
// src/builder/__tests__/myFeature.test.ts
import { describe, it, expect, beforeEach, vi } from 'vitest';
describe('MyFeature', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should handle success case', async () => {
// Test implementation
});
it('should handle error case', async () => {
// Test error handling
});
});Required environment variables in .env files:
ENVIRONMENT=development|production|test
DB_FILE_NAME=path/to/sqlite.db
PORT=3002
ANTHROPIC_API_KEY=required
OPENAI_API_KEY=optional
LOG_LEVEL=debug|info|warn|error
ALL new work MUST include these three components - NO EXCEPTIONS:
✅ 1. Unit Tests
- Write comprehensive unit tests using Vitest
- Place tests in
__tests__directories adjacent to the code - Follow naming convention:
*.test.ts - Minimum coverage for new code paths
- Test both success and error cases
✅ 2. Agent Builder UI Components
- Add corresponding UI components in
/agents-manage-ui/src/components/ - Include form validation schemas
- Update relevant pages in
/agents-manage-ui/src/app/ - Follow existing Next.js and React patterns
- Use the existing UI component library
✅ 3. Documentation
- Create or update documentation in
/agents-docs/content/docs/(public-facing docs) - Documentation should be in MDX format (
.mdxfiles) - Update
/agents-docs/navigation.tsto include new pages in the navigation - Follow existing Fumadocs structure and patterns
- Add code examples and diagrams where helpful
- Note:
/agents-docs/is a Next.js documentation site for public consumption
Before marking any feature complete, verify:
- Tests written and passing (
pnpm test) - UI components implemented in agents-manage-ui
- Documentation added to
/agents-docs/ - All linting passes (
pnpm lint)
After completing a feature and ensuring all tests, typecheck, and build are passing:
-
Create a new branch (if not already on one):
git checkout -b feature/your-feature-name
-
Run verification commands to ensure everything passes:
pnpm test pnpm typecheck # or pnpm tsc --noEmit pnpm build pnpm lint
-
Commit your changes with a descriptive message
-
Open a GitHub Pull Request once all checks pass:
gh pr create --title "feat: Your feature description" --body "Description of changes"
This is the standard development procedure to ensure code review and CI/CD processes.
Note: The user may override this workflow if they prefer to work directly on main or have different branch strategies.
- Always call
graph.init()after creating agent relationships to persist to database - Use builder patterns (
agent(),agentGraph(),tool()) instead of direct database manipulation - Preserve contextId when implementing transfer/delegation logic - extract from task IDs if needed
- Validate tool results with proper type guards instead of unsafe casting
- Test A2A communication end-to-end when adding new agent relationships
- Follow the mandatory requirements above for all new features
- Parallelize database operations using
Promise.all()instead of sequentialawaitcalls - Optimize array processing with
flatMap()andfilter()instead of nested loops - Implement cleanup mechanisms for debug files and logs to prevent memory leaks
- Empty Task Messages: Ensure task messages contain actual text content
- Context Extraction: For delegation scenarios, extract contextId from task ID patterns like
task_math-demo-123456-chatcmpl-789 - Tool Health: MCP tools require health checks before use
- Agent Discovery: Agents register capabilities via
/.well-known/{agentId}/agent.jsonendpoints
- Core Agents:
/execution/src/agents/Agent.ts,/inkeep-chat/src/agents/generateTaskHandler.ts - A2A Communication:
/execution/src/a2a/,/inkeep-chat/src/handlers/executionHandler.ts - Database Layer:
/packages/agents-core/src/data-access/(agents, tasks, conversations, tools) - Builder Patterns:
/configuration/src/builder/(agent.ts, graph.ts, tool.ts) - Schemas:
/packages/agents-core/src/data/db/schema.ts(Drizzle),/agents-run-api/src/schemas/(Zod validation) - Tests:
/inkeep-chat/src/__tests__/(unit and integration tests) - UI Components:
/agents-manage-ui/src/components/(React components) - UI Pages:
/agents-manage-ui/src/app/(Next.js pages and routing) - Documentation:
/agents-docs/(Next.js/Fumadocs public documentation site) - Legacy Documentation:
/docs-legacy/(internal/development notes) - Examples:
/examples/for reference implementations
// agents-manage-api/src/builder/__tests__/newFeature.test.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { NewFeature } from '../newFeature';
describe('NewFeature', () => {
let feature: NewFeature;
beforeEach(() => {
feature = new NewFeature({ tenantId: 'test-tenant' });
});
it('should initialize correctly', () => {
expect(feature).toBeDefined();
expect(feature.tenantId).toBe('test-tenant');
});
it('should handle errors gracefully', async () => {
await expect(feature.process(null)).rejects.toThrow('Invalid input');
});
});// agents-manage-ui/src/components/new-feature/new-feature-form.tsx
import { useState } from 'react';
import { z } from 'zod';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Form } from '../ui/form';
const newFeatureSchema = z.object({
name: z.string().min(1, 'Name is required'),
config: z.object({
enabled: z.boolean(),
value: z.string().optional()
})
});
export function NewFeatureForm() {
const [formData, setFormData] = useState({});
return (
<Form schema={newFeatureSchema} onSubmit={handleSubmit}>
{/* Form fields */}
</Form>
);
}// agents-docs/content/docs/features/new-feature.mdx
---
title: New Feature
description: Brief description of what the feature does
---
## Overview
Brief description of what the feature does and why it's useful.
## Usage
```typescript
const feature = new NewFeature({
id: 'feature-1',
config: { enabled: true }
});
await feature.execute();NewFeature(config)- Creates a new feature instanceexecute()- Executes the featurevalidate()- Validates configuration
[Include practical examples here]
// Also update agents-docs/navigation.ts to include the new page:
```typescript
export default {
docs: [
// ... existing entries
{
group: "Features",
pages: [
"features/new-feature", // Add this line
// ... other feature pages
],
},
],
};
Use curl commands to query Jaeger API running on localhost:16686:
# Get all services
curl "http://localhost:16686/api/services"
# Get operations for a service
curl "http://localhost:16686/api/operations?service=inkeep-chat"
# Search traces for recent activity (last hour)
curl "http://localhost:16686/api/traces?service=inkeep-chat&limit=20&lookback=1h"
# Search traces by operation name
curl "http://localhost:16686/api/traces?service=inkeep-chat&operation=agent.generate&limit=10"
# Search traces by tags (useful for finding specific agent/conversation)
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22agent.id%22:%22qa-agent%22%7D&limit=10"
# Search traces by tags for conversation ID
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22conversation.id%22:%22conv-123%22%7D"
# Get specific trace by ID
curl "http://localhost:16686/api/traces/{trace-id}"
# Search for traces with errors
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22error%22:%22true%22%7D&limit=10"
# Search for tool call traces
curl "http://localhost:16686/api/traces?service=inkeep-chat&operation=tool.call&limit=10"
# Search traces within time range (Unix timestamps)
curl "http://localhost:16686/api/traces?service=inkeep-chat&start=1640995200000000&end=1641081600000000"Debugging Agent Transfers:
- View traces:
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22conversation.id%22:%22conv-123%22%7D"
Debugging Tool Calls:
- Find tool call traces:
curl "http://localhost:16686/api/traces?service=inkeep-chat&operation=tool.call&limit=10"
Debugging Task Delegation:
- Trace execution flow:
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22task.id%22:%22task-id%22%7D"
Debugging Performance Issues:
- Find slow operations:
curl "http://localhost:16686/api/traces?service=inkeep-chat&minDuration=5s" - View error traces:
curl "http://localhost:16686/api/traces?service=inkeep-chat&tags=%7B%22error%22:%22true%22%7D"