@inkeep/agents-run-api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +117 -0
  2. package/dist/AgentExecutionServer.d.ts +23 -0
  3. package/dist/AgentExecutionServer.d.ts.map +1 -0
  4. package/dist/AgentExecutionServer.js +32 -0
  5. package/dist/__tests__/setup.d.ts +4 -0
  6. package/dist/__tests__/setup.d.ts.map +1 -0
  7. package/dist/__tests__/setup.js +50 -0
  8. package/dist/__tests__/utils/testProject.d.ts +18 -0
  9. package/dist/__tests__/utils/testProject.d.ts.map +1 -0
  10. package/dist/__tests__/utils/testProject.js +26 -0
  11. package/dist/__tests__/utils/testRequest.d.ts +8 -0
  12. package/dist/__tests__/utils/testRequest.d.ts.map +1 -0
  13. package/dist/__tests__/utils/testRequest.js +32 -0
  14. package/dist/__tests__/utils/testTenant.d.ts +64 -0
  15. package/dist/__tests__/utils/testTenant.d.ts.map +1 -0
  16. package/dist/__tests__/utils/testTenant.js +71 -0
  17. package/dist/a2a/client.d.ts +182 -0
  18. package/dist/a2a/client.d.ts.map +1 -0
  19. package/dist/a2a/client.js +645 -0
  20. package/dist/a2a/handlers.d.ts +4 -0
  21. package/dist/a2a/handlers.d.ts.map +1 -0
  22. package/dist/a2a/handlers.js +657 -0
  23. package/dist/a2a/transfer.d.ts +18 -0
  24. package/dist/a2a/transfer.d.ts.map +1 -0
  25. package/dist/a2a/transfer.js +22 -0
  26. package/dist/a2a/types.d.ts +63 -0
  27. package/dist/a2a/types.d.ts.map +1 -0
  28. package/dist/a2a/types.js +1 -0
  29. package/dist/agents/Agent.d.ts +154 -0
  30. package/dist/agents/Agent.d.ts.map +1 -0
  31. package/dist/agents/Agent.js +1105 -0
  32. package/dist/agents/ModelFactory.d.ts +62 -0
  33. package/dist/agents/ModelFactory.d.ts.map +1 -0
  34. package/dist/agents/ModelFactory.js +208 -0
  35. package/dist/agents/SystemPromptBuilder.d.ts +14 -0
  36. package/dist/agents/SystemPromptBuilder.d.ts.map +1 -0
  37. package/dist/agents/SystemPromptBuilder.js +62 -0
  38. package/dist/agents/ToolSessionManager.d.ts +61 -0
  39. package/dist/agents/ToolSessionManager.d.ts.map +1 -0
  40. package/dist/agents/ToolSessionManager.js +143 -0
  41. package/dist/agents/artifactTools.d.ts +30 -0
  42. package/dist/agents/artifactTools.d.ts.map +1 -0
  43. package/dist/agents/artifactTools.js +463 -0
  44. package/dist/agents/generateTaskHandler.d.ts +41 -0
  45. package/dist/agents/generateTaskHandler.d.ts.map +1 -0
  46. package/dist/agents/generateTaskHandler.js +350 -0
  47. package/dist/agents/relationTools.d.ts +33 -0
  48. package/dist/agents/relationTools.d.ts.map +1 -0
  49. package/dist/agents/relationTools.js +245 -0
  50. package/dist/agents/types.d.ts +23 -0
  51. package/dist/agents/types.d.ts.map +1 -0
  52. package/dist/agents/types.js +1 -0
  53. package/dist/agents/versions/V1Config.d.ts +21 -0
  54. package/dist/agents/versions/V1Config.d.ts.map +1 -0
  55. package/dist/agents/versions/V1Config.js +285 -0
  56. package/dist/app.d.ts +4 -0
  57. package/dist/app.d.ts.map +1 -0
  58. package/dist/app.js +194 -0
  59. package/dist/data/agentGraph.d.ts +4 -0
  60. package/dist/data/agentGraph.d.ts.map +1 -0
  61. package/dist/data/agentGraph.js +73 -0
  62. package/dist/data/agents.d.ts +4 -0
  63. package/dist/data/agents.d.ts.map +1 -0
  64. package/dist/data/agents.js +73 -0
  65. package/dist/data/conversations.d.ts +59 -0
  66. package/dist/data/conversations.d.ts.map +1 -0
  67. package/dist/data/conversations.js +216 -0
  68. package/dist/data/db/clean.d.ts +6 -0
  69. package/dist/data/db/clean.d.ts.map +1 -0
  70. package/dist/data/db/clean.js +77 -0
  71. package/dist/data/db/dbClient.d.ts +3 -0
  72. package/dist/data/db/dbClient.d.ts.map +1 -0
  73. package/dist/data/db/dbClient.js +13 -0
  74. package/dist/env.d.ts +43 -0
  75. package/dist/env.d.ts.map +1 -0
  76. package/dist/env.js +63 -0
  77. package/dist/handlers/executionHandler.d.ts +36 -0
  78. package/dist/handlers/executionHandler.d.ts.map +1 -0
  79. package/dist/handlers/executionHandler.js +402 -0
  80. package/dist/index.d.ts +5 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +43 -0
  83. package/dist/instrumentation.d.ts +13 -0
  84. package/dist/instrumentation.d.ts.map +1 -0
  85. package/dist/instrumentation.js +66 -0
  86. package/dist/logger.d.ts +4 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +32 -0
  89. package/dist/middleware/api-key-auth.d.ts +22 -0
  90. package/dist/middleware/api-key-auth.d.ts.map +1 -0
  91. package/dist/middleware/api-key-auth.js +139 -0
  92. package/dist/middleware/index.d.ts +2 -0
  93. package/dist/middleware/index.d.ts.map +1 -0
  94. package/dist/middleware/index.js +1 -0
  95. package/dist/openapi.d.ts +2 -0
  96. package/dist/openapi.d.ts.map +1 -0
  97. package/dist/openapi.js +36 -0
  98. package/dist/routes/agents.d.ts +4 -0
  99. package/dist/routes/agents.d.ts.map +1 -0
  100. package/dist/routes/agents.js +155 -0
  101. package/dist/routes/chat.d.ts +4 -0
  102. package/dist/routes/chat.d.ts.map +1 -0
  103. package/dist/routes/chat.js +308 -0
  104. package/dist/routes/chatDataStream.d.ts +4 -0
  105. package/dist/routes/chatDataStream.d.ts.map +1 -0
  106. package/dist/routes/chatDataStream.js +179 -0
  107. package/dist/routes/mcp.d.ts +4 -0
  108. package/dist/routes/mcp.d.ts.map +1 -0
  109. package/dist/routes/mcp.js +500 -0
  110. package/dist/tracer.d.ts +24 -0
  111. package/dist/tracer.d.ts.map +1 -0
  112. package/dist/tracer.js +97 -0
  113. package/dist/types/chat.d.ts +25 -0
  114. package/dist/types/chat.d.ts.map +1 -0
  115. package/dist/types/chat.js +1 -0
  116. package/dist/types/execution-context.d.ts +14 -0
  117. package/dist/types/execution-context.d.ts.map +1 -0
  118. package/dist/types/execution-context.js +14 -0
  119. package/dist/utils/agent-operations.d.ts +79 -0
  120. package/dist/utils/agent-operations.d.ts.map +1 -0
  121. package/dist/utils/agent-operations.js +67 -0
  122. package/dist/utils/artifact-component-schema.d.ts +29 -0
  123. package/dist/utils/artifact-component-schema.d.ts.map +1 -0
  124. package/dist/utils/artifact-component-schema.js +119 -0
  125. package/dist/utils/artifact-parser.d.ts +71 -0
  126. package/dist/utils/artifact-parser.d.ts.map +1 -0
  127. package/dist/utils/artifact-parser.js +251 -0
  128. package/dist/utils/cleanup.d.ts +19 -0
  129. package/dist/utils/cleanup.d.ts.map +1 -0
  130. package/dist/utils/cleanup.js +66 -0
  131. package/dist/utils/data-component-schema.d.ts +6 -0
  132. package/dist/utils/data-component-schema.d.ts.map +1 -0
  133. package/dist/utils/data-component-schema.js +43 -0
  134. package/dist/utils/graph-session.d.ts +200 -0
  135. package/dist/utils/graph-session.d.ts.map +1 -0
  136. package/dist/utils/graph-session.js +1009 -0
  137. package/dist/utils/incremental-stream-parser.d.ts +57 -0
  138. package/dist/utils/incremental-stream-parser.d.ts.map +1 -0
  139. package/dist/utils/incremental-stream-parser.js +287 -0
  140. package/dist/utils/response-formatter.d.ts +27 -0
  141. package/dist/utils/response-formatter.d.ts.map +1 -0
  142. package/dist/utils/response-formatter.js +160 -0
  143. package/dist/utils/stream-helpers.d.ts +162 -0
  144. package/dist/utils/stream-helpers.d.ts.map +1 -0
  145. package/dist/utils/stream-helpers.js +385 -0
  146. package/dist/utils/stream-registry.d.ts +18 -0
  147. package/dist/utils/stream-registry.d.ts.map +1 -0
  148. package/dist/utils/stream-registry.js +33 -0
  149. package/package.json +88 -0
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # Inkeep Execution API
2
+
3
+ The Execution API is responsible for runtime agent operations, including Agent-to-Agent (A2A) communication, chat completions, and MCP (Model Context Protocol) tool integrations.
4
+
5
+ ## Overview
6
+
7
+ This API handles the execution layer of the Inkeep Agent Framework:
8
+ - **A2A Communication**: JSON-RPC based agent-to-agent communication following Google's A2A specification
9
+ - **Chat Completions**: OpenAI-compatible chat API with multi-agent orchestration
10
+ - **MCP Integration**: Model Context Protocol tools and external integrations
11
+ - **Task Execution**: Real-time task processing and delegation workflows
12
+
13
+ ## Architecture
14
+
15
+ ### Core Components
16
+
17
+ - **A2A Protocol**: Agent communication via JSON-RPC methods (`tasks/send`, `tasks/get`, `tasks/cancel`)
18
+ - **Chat API**: OpenAI-compatible endpoints with agent routing and context preservation
19
+ - **MCP Tools**: Dynamic tool discovery and execution from multiple transport types (stdio, SSE, HTTP)
20
+ - **Task Management**: Hierarchical task execution with parent-child relationships
21
+
22
+ ### Key Features
23
+
24
+ - **Context Preservation**: Maintains conversation state across agent transfers and delegations
25
+ - **Multi-Agent Orchestration**: Hub-and-spoke and graph-based agent networks
26
+ - **Real-time Communication**: WebSocket and HTTP-based agent interactions
27
+ - **Tool Health Monitoring**: Automated health checks for external MCP tools
28
+
29
+ ## Development
30
+
31
+ ### Setup
32
+ If you do not have the db setup:
33
+ ```bash
34
+ cd packages/core
35
+ pnpm db:push
36
+ ```
37
+
38
+ Then:
39
+ ```bash
40
+ cd inkeep-execution-api
41
+ pnpm install
42
+ ```
43
+
44
+
45
+ ### Environment Variables
46
+ ```env
47
+ ENVIRONMENT=development|production|test
48
+ PORT=3003
49
+ DB_FILE_NAME=path/to/sqlite.db
50
+ ANTHROPIC_API_KEY=required
51
+ OPENAI_API_KEY=optional
52
+ LOG_LEVEL=debug|info|warn|error
53
+ ```
54
+
55
+ ### Development Commands
56
+ ```bash
57
+ pnpm dev # Start development server
58
+ pnpm test # Run test suite
59
+ pnpm test:coverage # Run tests with coverage
60
+ pnpm build # Build for production
61
+ pnpm lint # Run linting
62
+ pnpm format # Format code
63
+ ```
64
+
65
+ ### Testing
66
+ All tests are located in `src/__tests__/` and use Vitest with 60-second timeouts for A2A interactions.
67
+
68
+ ```bash
69
+ pnpm test # Run all tests
70
+ pnpm test:coverage # Run with coverage report
71
+ pnpm test src/__tests__/a2a/ # Run A2A-specific tests
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ The API uses environment-based configuration with defaults for local development. Key configuration areas:
77
+
78
+ - **Database**: SQLite connection via `DB_FILE_NAME`
79
+ - **AI Models**: Anthropic and OpenAI API keys
80
+ - **Observability**: OpenTelemetry tracing support
81
+ - **CORS**: Configurable for web clients
82
+
83
+ ## Integration
84
+
85
+ ### With Management API
86
+ The Execution API reads agent configurations and relationships created by the Management API but doesn't modify them during runtime.
87
+
88
+ ### With MCP Tools
89
+ Supports multiple MCP transport types:
90
+ - **stdio**: Local process-based tools
91
+ - **SSE**: Server-sent events for streaming tools
92
+ - **HTTP**: REST-based tool integrations
93
+
94
+ ### With Agent Builder
95
+ Provides runtime execution for agents configured via the Agent Builder UI.
96
+
97
+ ## Observability
98
+
99
+ - **Structured Logging**: JSON-formatted logs with correlation IDs
100
+ - **OpenTelemetry**: Distributed tracing for agent interactions
101
+ - **Health Checks**: Endpoint monitoring and tool availability
102
+ - **Performance Metrics**: Request timing and success rates
103
+
104
+ ## Error Handling
105
+
106
+ The API implements comprehensive error handling:
107
+ - **Validation Errors**: Request schema validation
108
+ - **Agent Errors**: Agent execution failures and timeouts
109
+ - **Tool Errors**: MCP tool failures and recovery
110
+ - **Network Errors**: Resilient communication patterns
111
+
112
+ ## Security
113
+
114
+ - **API Key Authentication**: Configurable authentication methods
115
+ - **Input Validation**: Request sanitization and type checking
116
+ - **CORS**: Configurable cross-origin policies
117
+ - **Rate Limiting**: Configurable request throttling
@@ -0,0 +1,23 @@
1
+ import { BaseServer, type AgentFrameworkServerConfig } from '@inkeep/agents-core';
2
+ export declare const EXECUTION_API_PORT = 3003;
3
+ /**
4
+ * Execution Server for chat, agent-to-agent communication, and MCP endpoints
5
+ * Extends BaseServer with Execution API specific functionality
6
+ */
7
+ export declare class AgentExecutionServer extends BaseServer {
8
+ constructor(config?: AgentFrameworkServerConfig);
9
+ /**
10
+ * Initialize the Execution API application
11
+ */
12
+ protected initialize(): Promise<void>;
13
+ /**
14
+ * Get default server options for Execution API
15
+ */
16
+ protected getServerOptions(): {
17
+ port: number;
18
+ keepAliveTimeout: number;
19
+ keepAlive: boolean;
20
+ requestTimeout: number;
21
+ };
22
+ }
23
+ //# sourceMappingURL=AgentExecutionServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentExecutionServer.d.ts","sourceRoot":"","sources":["../src/AgentExecutionServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAIlF,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;gBACtC,MAAM,GAAE,0BAA+B;IAInD;;OAEG;cACa,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3C;;OAEG;IACH,SAAS,CAAC,gBAAgB;;;;;;CAS3B"}
@@ -0,0 +1,32 @@
1
+ import { BaseServer } from '@inkeep/agents-core';
2
+ import { getLogger } from './logger.js';
3
+ import app from './app.js';
4
+ export const EXECUTION_API_PORT = 3003;
5
+ /**
6
+ * Execution Server for chat, agent-to-agent communication, and MCP endpoints
7
+ * Extends BaseServer with Execution API specific functionality
8
+ */
9
+ export class AgentExecutionServer extends BaseServer {
10
+ constructor(config = {}) {
11
+ super(config, getLogger('ExecutionServer'));
12
+ }
13
+ /**
14
+ * Initialize the Execution API application
15
+ */
16
+ async initialize() {
17
+ this.app = app;
18
+ this.logger.info('Execution API initialized');
19
+ }
20
+ /**
21
+ * Get default server options for Execution API
22
+ */
23
+ getServerOptions() {
24
+ return {
25
+ port: this.config.port || EXECUTION_API_PORT,
26
+ keepAliveTimeout: 60000,
27
+ keepAlive: true,
28
+ requestTimeout: 60000,
29
+ ...this.config.serverOptions,
30
+ };
31
+ }
32
+ }
@@ -0,0 +1,4 @@
1
+ import { NodeSDK } from '@opentelemetry/sdk-node';
2
+ declare const sdk: NodeSDK;
3
+ export { sdk };
4
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAYlD,QAAA,MAAM,GAAG,SAgBP,CAAC;AA6BH,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
2
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
3
+ import { ConsoleMetricExporter, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
4
+ /*instrumentation.ts*/
5
+ import { NodeSDK } from '@opentelemetry/sdk-node';
6
+ const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
7
+ import { sql } from 'drizzle-orm';
8
+ import { migrate } from 'drizzle-orm/libsql/migrator';
9
+ import { afterAll, afterEach, beforeAll } from 'vitest';
10
+ import dbClient from '../data/db/dbClient.js';
11
+ import { getLogger } from '@inkeep/agents-core';
12
+ getLogger('Test Setup').debug({}, 'Setting up instrumentation');
13
+ const sdk = new NodeSDK({
14
+ serviceName: 'inkeep-execution-api',
15
+ spanProcessors: [
16
+ new SimpleSpanProcessor(new OTLPTraceExporter({
17
+ // optional - default url is http://localhost:4318/v1/traces
18
+ // url: 'http://localhost:4318/v1/traces',
19
+ })),
20
+ ],
21
+ instrumentations: [getNodeAutoInstrumentations()],
22
+ // optional - default url is http://localhost:4318/v1/metrics
23
+ // url: 'http://localhost:4318/v1/metrics',
24
+ metricReader: new PeriodicExportingMetricReader({
25
+ exporter: new ConsoleMetricExporter(),
26
+ }),
27
+ });
28
+ sdk.start();
29
+ // Initialize database schema for in-memory test databases using Drizzle migrations
30
+ beforeAll(async () => {
31
+ const logger = getLogger('Test Setup');
32
+ try {
33
+ logger.debug({}, 'Applying database migrations to in-memory test database');
34
+ // Temporarily disable foreign key constraints for tests due to composite key issues
35
+ await dbClient.run(sql `PRAGMA foreign_keys = OFF`);
36
+ await migrate(dbClient, { migrationsFolder: '../packages/agents-core/drizzle' });
37
+ logger.debug({}, 'Database migrations applied successfully');
38
+ }
39
+ catch (error) {
40
+ logger.error({ error }, 'Failed to apply database migrations');
41
+ throw error;
42
+ }
43
+ });
44
+ afterEach(() => {
45
+ // Any cleanup if needed
46
+ });
47
+ afterAll(() => {
48
+ // Any final cleanup if needed
49
+ });
50
+ export { sdk };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Ensures a project exists for a given tenant ID.
3
+ * This is needed because of foreign key constraints in the database.
4
+ *
5
+ * @param tenantId - The tenant ID
6
+ * @param projectId - The project ID (defaults to 'default')
7
+ * @returns Promise that resolves when the project is created
8
+ */
9
+ export declare function ensureTestProject(tenantId: string, projectId?: string): Promise<void>;
10
+ /**
11
+ * Creates multiple test projects for a tenant.
12
+ *
13
+ * @param tenantId - The tenant ID
14
+ * @param projectIds - Array of project IDs to create
15
+ * @returns Promise that resolves when all projects are created
16
+ */
17
+ export declare function ensureTestProjects(tenantId: string, projectIds: string[]): Promise<void>;
18
+ //# sourceMappingURL=testProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testProject.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/testProject.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9F;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9F"}
@@ -0,0 +1,26 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import dbClient from '../../data/db/dbClient.js';
3
+ /**
4
+ * Ensures a project exists for a given tenant ID.
5
+ * This is needed because of foreign key constraints in the database.
6
+ *
7
+ * @param tenantId - The tenant ID
8
+ * @param projectId - The project ID (defaults to 'default')
9
+ * @returns Promise that resolves when the project is created
10
+ */
11
+ export async function ensureTestProject(tenantId, projectId = 'default') {
12
+ await dbClient.run(sql `
13
+ INSERT OR IGNORE INTO projects (tenant_id, id, name, description, created_at, updated_at)
14
+ VALUES (${tenantId}, ${projectId}, ${`Test Project ${projectId}`}, ${`Test project for ${projectId}`}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
15
+ `);
16
+ }
17
+ /**
18
+ * Creates multiple test projects for a tenant.
19
+ *
20
+ * @param tenantId - The tenant ID
21
+ * @param projectIds - Array of project IDs to create
22
+ * @returns Promise that resolves when all projects are created
23
+ */
24
+ export async function ensureTestProjects(tenantId, projectIds) {
25
+ await Promise.all(projectIds.map((projectId) => ensureTestProject(tenantId, projectId)));
26
+ }
@@ -0,0 +1,8 @@
1
+ export declare const makeRequest: (url: string, options?: RequestInit) => Promise<Response>;
2
+ export declare const makeRequestWithContext: (url: string, context: {
3
+ tenantId?: string;
4
+ projectId?: string;
5
+ graphId?: string;
6
+ agentId?: string;
7
+ }, options?: RequestInit) => Promise<Response>;
8
+ //# sourceMappingURL=testRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testRequest.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/testRequest.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,EAAE,UAAS,WAAgB,sBAavE,CAAC;AAGF,eAAO,MAAM,sBAAsB,GACjC,KAAK,MAAM,EACX,SAAS;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,EACD,UAAS,WAAgB,sBAe1B,CAAC"}
@@ -0,0 +1,32 @@
1
+ import app from '../../app.js';
2
+ // Helper function to make requests with JSON headers and test authentication
3
+ export const makeRequest = async (url, options = {}) => {
4
+ return app.request(url, {
5
+ ...options,
6
+ headers: {
7
+ 'Content-Type': 'application/json',
8
+ Authorization: 'Bearer test-api-key',
9
+ 'x-inkeep-tenant-id': 'test-tenant',
10
+ 'x-inkeep-project-id': 'default',
11
+ 'x-inkeep-graph-id': 'test-graph',
12
+ 'x-test-bypass-auth': 'true',
13
+ ...options.headers,
14
+ },
15
+ });
16
+ };
17
+ // Helper function to make requests with custom execution context
18
+ export const makeRequestWithContext = async (url, context, options = {}) => {
19
+ return app.request(url, {
20
+ ...options,
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ Authorization: 'Bearer test-api-key',
24
+ 'x-inkeep-tenant-id': context.tenantId || 'test-tenant',
25
+ 'x-inkeep-project-id': context.projectId || 'test-project',
26
+ 'x-inkeep-graph-id': context.graphId || 'test-graph',
27
+ 'x-test-bypass-auth': 'true',
28
+ ...(context.agentId && { 'x-inkeep-agent-id': context.agentId }),
29
+ ...options.headers,
30
+ },
31
+ });
32
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Creates a unique tenant ID for test isolation.
3
+ *
4
+ * Each test run gets its own tenant to ensure parallel tests don't interfere with each other.
5
+ * The generated tenant ID follows the format: test-tenant-{prefix}-{uuid} or test-tenant-{uuid}
6
+ *
7
+ * @param prefix - Optional prefix to include in the tenant ID (e.g., test file name)
8
+ * @returns A unique tenant ID for test isolation
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createTestTenantId } from './utils/testTenant.js';
13
+ *
14
+ * describe('My test suite', () => {
15
+ * const tenantId = createTestTenantId('agents');
16
+ *
17
+ * it('should work with isolated tenant', async () => {
18
+ * // Your test code using the unique tenant ID
19
+ * console.log(tenantId); // e.g., "test-tenant-agents-123e4567-e89b-12d3-a456-426614174000"
20
+ * });
21
+ * });
22
+ * ```
23
+ */
24
+ export declare function createTestTenantId(prefix?: string): string;
25
+ /**
26
+ * Creates multiple unique tenant IDs for test isolation.
27
+ *
28
+ * Useful when you need multiple tenants in a single test.
29
+ *
30
+ * @param count - Number of tenant IDs to generate
31
+ * @param prefix - Optional prefix to include in all tenant IDs
32
+ * @returns Array of unique tenant IDs
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { createTestTenantIds } from './utils/testTenant.js';
37
+ *
38
+ * describe('Multi-tenant test suite', () => {
39
+ * const [tenantA, tenantB] = createTestTenantIds(2, 'multi-tenant');
40
+ *
41
+ * it('should handle cross-tenant operations', async () => {
42
+ * // Test operations across different tenants
43
+ * });
44
+ * });
45
+ * ```
46
+ */
47
+ export declare function createTestTenantIds(count: number, prefix?: string): string[];
48
+ /**
49
+ * Checks if a tenant ID is a test tenant.
50
+ *
51
+ * @param tenantId - The tenant ID to check
52
+ * @returns True if the tenant ID is a test tenant
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { isTestTenant } from './utils/testTenant.js';
57
+ *
58
+ * const tenantId = createTestTenantId();
59
+ * console.log(isTestTenant(tenantId)); // true
60
+ * console.log(isTestTenant('production-tenant')); // false
61
+ * ```
62
+ */
63
+ export declare function isTestTenant(tenantId: string): boolean;
64
+ //# sourceMappingURL=testTenant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testTenant.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/testTenant.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAE5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,71 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * Creates a unique tenant ID for test isolation.
4
+ *
5
+ * Each test run gets its own tenant to ensure parallel tests don't interfere with each other.
6
+ * The generated tenant ID follows the format: test-tenant-{prefix}-{uuid} or test-tenant-{uuid}
7
+ *
8
+ * @param prefix - Optional prefix to include in the tenant ID (e.g., test file name)
9
+ * @returns A unique tenant ID for test isolation
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { createTestTenantId } from './utils/testTenant.js';
14
+ *
15
+ * describe('My test suite', () => {
16
+ * const tenantId = createTestTenantId('agents');
17
+ *
18
+ * it('should work with isolated tenant', async () => {
19
+ * // Your test code using the unique tenant ID
20
+ * console.log(tenantId); // e.g., "test-tenant-agents-123e4567-e89b-12d3-a456-426614174000"
21
+ * });
22
+ * });
23
+ * ```
24
+ */
25
+ export function createTestTenantId(prefix) {
26
+ const uuid = randomUUID();
27
+ return prefix ? `test-tenant-${prefix}-${uuid}` : `test-tenant-${uuid}`;
28
+ }
29
+ /**
30
+ * Creates multiple unique tenant IDs for test isolation.
31
+ *
32
+ * Useful when you need multiple tenants in a single test.
33
+ *
34
+ * @param count - Number of tenant IDs to generate
35
+ * @param prefix - Optional prefix to include in all tenant IDs
36
+ * @returns Array of unique tenant IDs
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * import { createTestTenantIds } from './utils/testTenant.js';
41
+ *
42
+ * describe('Multi-tenant test suite', () => {
43
+ * const [tenantA, tenantB] = createTestTenantIds(2, 'multi-tenant');
44
+ *
45
+ * it('should handle cross-tenant operations', async () => {
46
+ * // Test operations across different tenants
47
+ * });
48
+ * });
49
+ * ```
50
+ */
51
+ export function createTestTenantIds(count, prefix) {
52
+ return Array.from({ length: count }, () => createTestTenantId(prefix));
53
+ }
54
+ /**
55
+ * Checks if a tenant ID is a test tenant.
56
+ *
57
+ * @param tenantId - The tenant ID to check
58
+ * @returns True if the tenant ID is a test tenant
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * import { isTestTenant } from './utils/testTenant.js';
63
+ *
64
+ * const tenantId = createTestTenantId();
65
+ * console.log(isTestTenant(tenantId)); // true
66
+ * console.log(isTestTenant('production-tenant')); // false
67
+ * ```
68
+ */
69
+ export function isTestTenant(tenantId) {
70
+ return tenantId.startsWith('test-tenant-');
71
+ }
@@ -0,0 +1,182 @@
1
+ import type { AgentCard, CancelTaskResponse, GetTaskPushNotificationConfigResponse, GetTaskResponse, Message, MessageSendParams, SendMessageResponse, SetTaskPushNotificationConfigResponse, Task, TaskArtifactUpdateEvent, TaskIdParams, TaskPushNotificationConfig, TaskQueryParams, TaskStatusUpdateEvent } from '@inkeep/agents-core';
2
+ type A2AStreamEventData = Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent;
3
+ export type BackoffStrategy = {
4
+ initialInterval: number;
5
+ maxInterval: number;
6
+ exponent: number;
7
+ maxElapsedTime: number;
8
+ };
9
+ export type RetryConfig = {
10
+ strategy: 'none';
11
+ } | {
12
+ strategy: 'backoff';
13
+ backoff?: BackoffStrategy;
14
+ retryConnectionErrors?: boolean;
15
+ statusCodes?: string[];
16
+ };
17
+ export interface A2AClientOptions {
18
+ retryConfig?: RetryConfig;
19
+ headers?: Record<string, string>;
20
+ }
21
+ /**
22
+ * A2AClient is a TypeScript HTTP client for interacting with A2A-compliant agents.
23
+ *
24
+ * Features:
25
+ * - Configurable retry behavior with exponential backoff
26
+ * - Automatic retry on network errors and configurable HTTP status codes
27
+ * - Support for custom retry strategies and timeouts
28
+ *
29
+ * Default retry behavior:
30
+ * - Retries on: 429, 500, 502, 503, 504 status codes and network errors
31
+ * - Initial delay: 500ms, max delay: 60s, exponential backoff (1.5x)
32
+ * - Max total retry time: 30 seconds
33
+ *
34
+ * @example
35
+ * // Default retry behavior
36
+ * const client = new A2AClient('https://agent.example.com');
37
+ *
38
+ * // Custom retry configuration
39
+ * const client = new A2AClient('https://agent.example.com', {
40
+ * retryConfig: {
41
+ * strategy: 'backoff',
42
+ * retryConnectionErrors: true,
43
+ * statusCodes: ['429', '502', '503', '504'],
44
+ * backoff: {
45
+ * initialInterval: 1000,
46
+ * maxInterval: 30000,
47
+ * exponent: 2,
48
+ * maxElapsedTime: 60000
49
+ * }
50
+ * }
51
+ * });
52
+ *
53
+ * // Disable retries
54
+ * const client = new A2AClient('https://agent.example.com', {
55
+ * retryConfig: { strategy: 'none' }
56
+ * });
57
+ */
58
+ export declare class A2AClient {
59
+ private agentBaseUrl;
60
+ private agentCardPromise;
61
+ private requestIdCounter;
62
+ private serviceEndpointUrl?;
63
+ private options;
64
+ /**
65
+ * Constructs an A2AClient instance.
66
+ * It initiates fetching the agent card from the provided agent baseUrl.
67
+ * The Agent Card is expected at `${agentBaseUrl}/.well-known/agent.json`.
68
+ * The `url` field from the Agent Card will be used as the RPC service endpoint.
69
+ * @param agentBaseUrl The base URL of the A2A agent (e.g., https://agent.example.com).
70
+ * @param options Optional configuration including retry behavior.
71
+ */
72
+ constructor(agentBaseUrl: string, options?: A2AClientOptions);
73
+ /**
74
+ * Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
75
+ * This method is called by the constructor.
76
+ * @returns A Promise that resolves to the AgentCard.
77
+ */
78
+ private _fetchAndCacheAgentCard;
79
+ /**
80
+ * Retrieves the Agent Card.
81
+ * If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
82
+ * Otherwise, it returns the card fetched and cached during client construction.
83
+ * @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
84
+ * If provided, this will fetch a new card, not use the cached one from the constructor's URL.
85
+ * @returns A Promise that resolves to the AgentCard.
86
+ */
87
+ getAgentCard(agentBaseUrl?: string): Promise<AgentCard>;
88
+ /**
89
+ * Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
90
+ * @returns A Promise that resolves to the service endpoint URL string.
91
+ */
92
+ private _getServiceEndpoint;
93
+ /**
94
+ * Retry utility functions
95
+ */
96
+ private retry;
97
+ private wrapFetcher;
98
+ private isRetryableResponse;
99
+ private isRetryableError;
100
+ private retryBackoff;
101
+ private retryIntervalFromResponse;
102
+ private delay;
103
+ /**
104
+ * Helper method to make a generic JSON-RPC POST request.
105
+ * @param method The RPC method name.
106
+ * @param params The parameters for the RPC method.
107
+ * @returns A Promise that resolves to the RPC response.
108
+ */
109
+ private _postRpcRequest;
110
+ /**
111
+ * Sends a message to the agent.
112
+ * The behavior (blocking/non-blocking) and push notification configuration
113
+ * are specified within the `params.configuration` object.
114
+ * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
115
+ * @param params The parameters for sending the message, including the message content and configuration.
116
+ * @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
117
+ */
118
+ sendMessage(params: MessageSendParams): Promise<SendMessageResponse>;
119
+ /**
120
+ * Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
121
+ * Push notification configuration can be specified in `params.configuration`.
122
+ * Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
123
+ * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
124
+ * @param params The parameters for sending the message.
125
+ * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
126
+ * The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
127
+ */
128
+ sendMessageStream(params: MessageSendParams): AsyncGenerator<A2AStreamEventData, void, undefined>;
129
+ /**
130
+ * Sets or updates the push notification configuration for a given task.
131
+ * Requires the agent to support push notifications (`capabilities.pushNotifications: true` in AgentCard).
132
+ * @param params Parameters containing the taskId and the TaskPushNotificationConfig.
133
+ * @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
134
+ */
135
+ setTaskPushNotificationConfig(params: TaskPushNotificationConfig): Promise<SetTaskPushNotificationConfigResponse>;
136
+ /**
137
+ * Gets the push notification configuration for a given task.
138
+ * @param params Parameters containing the taskId.
139
+ * @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
140
+ */
141
+ getTaskPushNotificationConfig(params: TaskIdParams): Promise<GetTaskPushNotificationConfigResponse>;
142
+ /**
143
+ * Retrieves a task by its ID.
144
+ * @param params Parameters containing the taskId and optional historyLength.
145
+ * @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
146
+ */
147
+ getTask(params: TaskQueryParams): Promise<GetTaskResponse>;
148
+ /**
149
+ * Cancels a task by its ID.
150
+ * @param params Parameters containing the taskId.
151
+ * @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
152
+ */
153
+ cancelTask(params: TaskIdParams): Promise<CancelTaskResponse>;
154
+ /**
155
+ * Resubscribes to a task's event stream using Server-Sent Events (SSE).
156
+ * This is used if a previous SSE connection for an active task was broken.
157
+ * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
158
+ * @param params Parameters containing the taskId.
159
+ * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
160
+ */
161
+ resubscribeTask(params: TaskIdParams): AsyncGenerator<A2AStreamEventData, void, undefined>;
162
+ /**
163
+ * Parses an HTTP response body as an A2A Server-Sent Event stream.
164
+ * Each 'data' field of an SSE event is expected to be a JSON-RPC 2.0 Response object,
165
+ * specifically a SendStreamingMessageResponse (or similar structure for resubscribe).
166
+ * @param response The HTTP Response object whose body is the SSE stream.
167
+ * @param originalRequestId The ID of the client's JSON-RPC request that initiated this stream.
168
+ * Used to validate the `id` in the streamed JSON-RPC responses.
169
+ * @returns An AsyncGenerator yielding the `result` field of each valid JSON-RPC success response from the stream.
170
+ */
171
+ private _parseA2ASseStream;
172
+ /**
173
+ * Processes a single SSE event's data string, expecting it to be a JSON-RPC response.
174
+ * @param jsonData The string content from one or more 'data:' lines of an SSE event.
175
+ * @param originalRequestId The ID of the client's request that initiated the stream.
176
+ * @returns The `result` field of the parsed JSON-RPC success response.
177
+ * @throws Error if data is not valid JSON, not a valid JSON-RPC response, an error response, or ID mismatch.
178
+ */
179
+ private _processSseEventData;
180
+ }
181
+ export {};
182
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,SAAS,EACT,kBAAkB,EAClB,qCAAqC,EACrC,eAAe,EAKf,OAAO,EACP,iBAAiB,EACjB,mBAAmB,EAGnB,qCAAqC,EACrC,IAAI,EACJ,uBAAuB,EACvB,YAAY,EACZ,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAK7B,KAAK,kBAAkB,GAAG,OAAO,GAAG,IAAI,GAAG,qBAAqB,GAAG,uBAAuB,CAAC;AAG3F,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IACE,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AA0CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAS;IACpC,OAAO,CAAC,OAAO,CAAmB;IAElC;;;;;;;OAOG;gBACS,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAc5D;;;;OAIG;YACW,uBAAuB;IA+BrC;;;;;;;OAOG;IACU,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAqBpE;;;OAGG;YACW,mBAAmB;IAgBjC;;OAEG;YACW,KAAK;IAgBnB,OAAO,CAAC,WAAW;IA4BnB,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,gBAAgB;YAiBV,YAAY;IAqE1B,OAAO,CAAC,yBAAyB;YAoBnB,KAAK;IAInB;;;;;OAKG;YACW,eAAe;IAyE7B;;;;;;;OAOG;IACU,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIjF;;;;;;;;OAQG;IACW,iBAAiB,CAC7B,MAAM,EAAE,iBAAiB,GACxB,cAAc,CAAC,kBAAkB,EAAE,IAAI,EAAE,SAAS,CAAC;IA4DtD;;;;;OAKG;IACU,6BAA6B,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,qCAAqC,CAAC;IAcjD;;;;OAIG;IACU,6BAA6B,CACxC,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,qCAAqC,CAAC;IAQjD;;;;OAIG;IACU,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAIvE;;;;OAIG;IACU,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI1E;;;;;;OAMG;IACW,eAAe,CAC3B,MAAM,EAAE,YAAY,GACnB,cAAc,CAAC,kBAAkB,EAAE,IAAI,EAAE,SAAS,CAAC;IAyDtD;;;;;;;;OAQG;YACY,kBAAkB;IAoEjC;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;CA2D7B"}