@inkeep/agents-run-api 0.1.0 → 0.1.2
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.
- package/LICENSE.md +49 -0
- package/dist/AgentExecutionServer.d.ts +6 -1
- package/dist/AgentExecutionServer.d.ts.map +1 -1
- package/dist/AgentExecutionServer.js +10 -1
- package/dist/__tests__/utils/testRequest.js +1 -1
- package/dist/agents/Agent.d.ts +3 -3
- package/dist/agents/Agent.d.ts.map +1 -1
- package/dist/agents/Agent.js +9 -7
- package/dist/agents/generateTaskHandler.d.ts +2 -2
- package/dist/agents/generateTaskHandler.d.ts.map +1 -1
- package/dist/agents/generateTaskHandler.js +2 -2
- package/dist/agents/relationTools.d.ts +3 -1
- package/dist/agents/relationTools.d.ts.map +1 -1
- package/dist/agents/relationTools.js +4 -5
- package/dist/app.d.ts +11 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +177 -169
- package/dist/data/agents.d.ts +2 -2
- package/dist/data/agents.d.ts.map +1 -1
- package/dist/data/agents.js +4 -4
- package/dist/env.d.ts +7 -5
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -0
- package/dist/handlers/executionHandler.d.ts.map +1 -1
- package/dist/handlers/executionHandler.js +2 -5
- package/dist/index.d.ts +21 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -36
- package/dist/routes/agents.d.ts +7 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +6 -3
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +61 -0
- package/dist/tracer.d.ts.map +1 -1
- package/dist/tracer.js +9 -0
- package/dist/utils/agent-operations.d.ts +14 -1
- package/dist/utils/agent-operations.d.ts.map +1 -1
- package/dist/utils/agent-operations.js +11 -0
- package/dist/utils/graph-session.d.ts.map +1 -1
- package/dist/utils/graph-session.js +7 -4
- package/dist/utils/stream-helpers.d.ts +12 -0
- package/dist/utils/stream-helpers.d.ts.map +1 -1
- package/dist/utils/stream-helpers.js +111 -30
- package/package.json +22 -18
package/dist/app.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createRoute } from '@hono/zod-openapi';
|
|
2
|
-
import { OpenApiHonoWithExecutionContext } from '@inkeep/agents-core';
|
|
1
|
+
import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
3
2
|
import { context as otelContext, propagation } from '@opentelemetry/api';
|
|
4
3
|
import { cors } from 'hono/cors';
|
|
5
4
|
import { HTTPException } from 'hono/http-exception';
|
|
@@ -13,182 +12,191 @@ import agentRoutes from './routes/agents.js';
|
|
|
13
12
|
import chatRoutes from './routes/chat.js';
|
|
14
13
|
import chatDataRoutes from './routes/chatDataStream.js';
|
|
15
14
|
import mcpRoutes from './routes/mcp.js';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
bag = bag.setEntry('request.id', { value: String(reqId ?? 'unknown') });
|
|
27
|
-
const ctxWithBag = propagation.setBaggage(otelContext.active(), bag);
|
|
28
|
-
return otelContext.with(ctxWithBag, () => next());
|
|
29
|
-
});
|
|
30
|
-
// Baggage middleware for execution API - extracts context from API key authentication
|
|
31
|
-
app.use('*', async (c, next) => {
|
|
32
|
-
// Get the API key context if available (set by auth middleware)
|
|
33
|
-
const executionContext = c.get('executionContext');
|
|
34
|
-
if (!executionContext) {
|
|
35
|
-
// No API key context, skip baggage setup
|
|
36
|
-
return next();
|
|
37
|
-
}
|
|
38
|
-
const { tenantId, projectId, graphId } = executionContext;
|
|
39
|
-
// Extract conversation ID from JSON body if present
|
|
40
|
-
let conversationId;
|
|
41
|
-
if (c.req.header('content-type')?.includes('application/json')) {
|
|
42
|
-
try {
|
|
43
|
-
const body = await c.req.json();
|
|
44
|
-
conversationId = body?.conversationId;
|
|
15
|
+
function createExecutionHono(serverConfig, credentialStores) {
|
|
16
|
+
const app = new OpenAPIHono();
|
|
17
|
+
// Request ID middleware
|
|
18
|
+
app.use('*', requestId());
|
|
19
|
+
// OpenTelemetry baggage middleware
|
|
20
|
+
app.use('*', async (c, next) => {
|
|
21
|
+
const reqId = c.get('requestId');
|
|
22
|
+
let bag = propagation.getBaggage(otelContext.active());
|
|
23
|
+
if (!bag) {
|
|
24
|
+
bag = propagation.createBaggage();
|
|
45
25
|
}
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
bag = bag.setEntry('request.id', { value: String(reqId ?? 'unknown') });
|
|
27
|
+
const ctxWithBag = propagation.setBaggage(otelContext.active(), bag);
|
|
28
|
+
return otelContext.with(ctxWithBag, () => next());
|
|
29
|
+
});
|
|
30
|
+
// Baggage middleware for execution API - extracts context from API key authentication
|
|
31
|
+
app.use('*', async (c, next) => {
|
|
32
|
+
// Get the API key context if available (set by auth middleware)
|
|
33
|
+
const executionContext = c.get('executionContext');
|
|
34
|
+
if (!executionContext) {
|
|
35
|
+
// No API key context, skip baggage setup
|
|
36
|
+
return next();
|
|
48
37
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const [, v] = entry;
|
|
57
|
-
return typeof v === 'string' && v.length > 0;
|
|
58
|
-
}));
|
|
59
|
-
if (!Object.keys(entries).length) {
|
|
60
|
-
return next();
|
|
61
|
-
}
|
|
62
|
-
const bag = Object.entries(entries).reduce((b, [key, value]) => b.setEntry(key, { value: value || '' }), propagation.getBaggage(otelContext.active()) ?? propagation.createBaggage());
|
|
63
|
-
const ctxWithBag = propagation.setBaggage(otelContext.active(), bag);
|
|
64
|
-
return otelContext.with(ctxWithBag, () => next());
|
|
65
|
-
});
|
|
66
|
-
// Logging middleware
|
|
67
|
-
app.use(pinoLogger({
|
|
68
|
-
pino: getLogger(),
|
|
69
|
-
http: {
|
|
70
|
-
onResLevel(c) {
|
|
71
|
-
if (c.res.status >= 500) {
|
|
72
|
-
return 'error';
|
|
38
|
+
const { tenantId, projectId, graphId } = executionContext;
|
|
39
|
+
// Extract conversation ID from JSON body if present
|
|
40
|
+
let conversationId;
|
|
41
|
+
if (c.req.header('content-type')?.includes('application/json')) {
|
|
42
|
+
try {
|
|
43
|
+
const body = await c.req.json();
|
|
44
|
+
conversationId = body?.conversationId;
|
|
73
45
|
}
|
|
74
|
-
|
|
46
|
+
catch (_) {
|
|
47
|
+
// Silently ignore parse errors for non-JSON bodies
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const entries = Object.fromEntries(Object.entries({
|
|
51
|
+
'graph.id': graphId,
|
|
52
|
+
'tenant.id': tenantId,
|
|
53
|
+
'project.id': projectId,
|
|
54
|
+
'conversation.id': conversationId,
|
|
55
|
+
}).filter((entry) => {
|
|
56
|
+
const [, v] = entry;
|
|
57
|
+
return typeof v === 'string' && v.length > 0;
|
|
58
|
+
}));
|
|
59
|
+
if (!Object.keys(entries).length) {
|
|
60
|
+
return next();
|
|
61
|
+
}
|
|
62
|
+
const bag = Object.entries(entries).reduce((b, [key, value]) => b.setEntry(key, { value: value || '' }), propagation.getBaggage(otelContext.active()) ?? propagation.createBaggage());
|
|
63
|
+
const ctxWithBag = propagation.setBaggage(otelContext.active(), bag);
|
|
64
|
+
return otelContext.with(ctxWithBag, () => next());
|
|
65
|
+
});
|
|
66
|
+
// Server config and credential stores middleware
|
|
67
|
+
app.use('*', async (c, next) => {
|
|
68
|
+
c.set('serverConfig', serverConfig);
|
|
69
|
+
c.set('credentialStores', credentialStores);
|
|
70
|
+
return next();
|
|
71
|
+
});
|
|
72
|
+
// Logging middleware
|
|
73
|
+
app.use(pinoLogger({
|
|
74
|
+
pino: getLogger(),
|
|
75
|
+
http: {
|
|
76
|
+
onResLevel(c) {
|
|
77
|
+
if (c.res.status >= 500) {
|
|
78
|
+
return 'error';
|
|
79
|
+
}
|
|
80
|
+
return 'info';
|
|
81
|
+
},
|
|
75
82
|
},
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
}));
|
|
84
|
+
// Error handling
|
|
85
|
+
app.onError(async (err, c) => {
|
|
86
|
+
const isExpectedError = err instanceof HTTPException;
|
|
87
|
+
const status = isExpectedError ? err.status : 500;
|
|
88
|
+
const requestId = c.get('requestId') || 'unknown';
|
|
89
|
+
// Zod validation error detection
|
|
90
|
+
let zodIssues;
|
|
91
|
+
if (err && typeof err === 'object') {
|
|
92
|
+
if (err.cause && Array.isArray(err.cause.issues)) {
|
|
93
|
+
zodIssues = err.cause.issues;
|
|
94
|
+
}
|
|
95
|
+
else if (Array.isArray(err.issues)) {
|
|
96
|
+
zodIssues = err.issues;
|
|
97
|
+
}
|
|
88
98
|
}
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
if (status === 400 && Array.isArray(zodIssues)) {
|
|
100
|
+
c.status(400);
|
|
101
|
+
c.header('Content-Type', 'application/problem+json');
|
|
102
|
+
c.header('X-Content-Type-Options', 'nosniff');
|
|
103
|
+
return c.json({
|
|
104
|
+
type: 'https://docs.inkeep.com/agents-api/errors#bad_request',
|
|
105
|
+
title: 'Validation Failed',
|
|
106
|
+
status: 400,
|
|
107
|
+
detail: 'Request validation failed',
|
|
108
|
+
errors: zodIssues.map((issue) => ({
|
|
109
|
+
detail: issue.message,
|
|
110
|
+
pointer: issue.path ? `/${issue.path.join('/')}` : undefined,
|
|
111
|
+
name: issue.path ? issue.path.join('.') : undefined,
|
|
112
|
+
reason: issue.message,
|
|
113
|
+
})),
|
|
114
|
+
});
|
|
91
115
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
116
|
+
if (status >= 500) {
|
|
117
|
+
if (!isExpectedError) {
|
|
118
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
119
|
+
const errorStack = err instanceof Error ? err.stack : undefined;
|
|
120
|
+
getLogger().error({
|
|
121
|
+
error: err,
|
|
122
|
+
message: errorMessage,
|
|
123
|
+
stack: errorStack,
|
|
124
|
+
path: c.req.path,
|
|
125
|
+
requestId,
|
|
126
|
+
}, 'Unexpected server error occurred');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
getLogger().error({
|
|
130
|
+
error: err,
|
|
131
|
+
path: c.req.path,
|
|
132
|
+
requestId,
|
|
133
|
+
status,
|
|
134
|
+
}, 'Server error occurred');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (isExpectedError) {
|
|
138
|
+
try {
|
|
139
|
+
const response = err.getResponse();
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
catch (responseError) {
|
|
143
|
+
getLogger().error({ error: responseError }, 'Error while handling HTTPException response');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const { status: respStatus, title, detail, instance } = await handleApiError(err, requestId);
|
|
147
|
+
c.status(respStatus);
|
|
95
148
|
c.header('Content-Type', 'application/problem+json');
|
|
96
149
|
c.header('X-Content-Type-Options', 'nosniff');
|
|
97
150
|
return c.json({
|
|
98
|
-
type: 'https://docs.inkeep.com/agents-api/errors#
|
|
99
|
-
title
|
|
100
|
-
status:
|
|
101
|
-
detail
|
|
102
|
-
|
|
103
|
-
detail: issue.message,
|
|
104
|
-
pointer: issue.path ? `/${issue.path.join('/')}` : undefined,
|
|
105
|
-
name: issue.path ? issue.path.join('.') : undefined,
|
|
106
|
-
reason: issue.message,
|
|
107
|
-
})),
|
|
151
|
+
type: 'https://docs.inkeep.com/agents-api/errors#internal_server_error',
|
|
152
|
+
title,
|
|
153
|
+
status: respStatus,
|
|
154
|
+
detail,
|
|
155
|
+
...(instance && { instance }),
|
|
108
156
|
});
|
|
109
|
-
}
|
|
110
|
-
if (status >= 500) {
|
|
111
|
-
if (!isExpectedError) {
|
|
112
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
113
|
-
const errorStack = err instanceof Error ? err.stack : undefined;
|
|
114
|
-
getLogger().error({
|
|
115
|
-
error: err,
|
|
116
|
-
message: errorMessage,
|
|
117
|
-
stack: errorStack,
|
|
118
|
-
path: c.req.path,
|
|
119
|
-
requestId,
|
|
120
|
-
}, 'Unexpected server error occurred');
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
getLogger().error({
|
|
124
|
-
error: err,
|
|
125
|
-
path: c.req.path,
|
|
126
|
-
requestId,
|
|
127
|
-
status,
|
|
128
|
-
}, 'Server error occurred');
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (isExpectedError) {
|
|
132
|
-
try {
|
|
133
|
-
const response = err.getResponse();
|
|
134
|
-
return response;
|
|
135
|
-
}
|
|
136
|
-
catch (responseError) {
|
|
137
|
-
getLogger().error({ error: responseError }, 'Error while handling HTTPException response');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
const { status: respStatus, title, detail, instance } = await handleApiError(err, requestId);
|
|
141
|
-
c.status(respStatus);
|
|
142
|
-
c.header('Content-Type', 'application/problem+json');
|
|
143
|
-
c.header('X-Content-Type-Options', 'nosniff');
|
|
144
|
-
return c.json({
|
|
145
|
-
type: 'https://docs.inkeep.com/agents-api/errors#internal_server_error',
|
|
146
|
-
title,
|
|
147
|
-
status: respStatus,
|
|
148
|
-
detail,
|
|
149
|
-
...(instance && { instance }),
|
|
150
157
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return origin
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
: null;
|
|
160
|
-
},
|
|
161
|
-
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
162
|
-
allowHeaders: ['*'],
|
|
163
|
-
exposeHeaders: ['Content-Length'],
|
|
164
|
-
maxAge: 86400,
|
|
165
|
-
credentials: true,
|
|
166
|
-
}));
|
|
167
|
-
// Apply API key authentication to all routes except health and docs
|
|
168
|
-
app.use('/tenants/*', apiKeyAuth());
|
|
169
|
-
app.use('/agents/*', apiKeyAuth());
|
|
170
|
-
app.use('/v1/*', apiKeyAuth());
|
|
171
|
-
app.use('/api/*', apiKeyAuth());
|
|
172
|
-
// Health check endpoint (no auth required)
|
|
173
|
-
app.openapi(createRoute({
|
|
174
|
-
method: 'get',
|
|
175
|
-
path: '/health',
|
|
176
|
-
tags: ['health'],
|
|
177
|
-
summary: 'Health check',
|
|
178
|
-
description: 'Check if the execution service is healthy',
|
|
179
|
-
responses: {
|
|
180
|
-
204: {
|
|
181
|
-
description: 'Service is healthy',
|
|
158
|
+
// CORS middleware
|
|
159
|
+
app.use('*', cors({
|
|
160
|
+
origin: (origin) => {
|
|
161
|
+
if (!origin)
|
|
162
|
+
return origin;
|
|
163
|
+
return origin.startsWith('http://localhost:') || origin.startsWith('https://localhost:')
|
|
164
|
+
? origin
|
|
165
|
+
: null;
|
|
182
166
|
},
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
app.
|
|
191
|
-
app.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
167
|
+
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
168
|
+
allowHeaders: ['*'],
|
|
169
|
+
exposeHeaders: ['Content-Length'],
|
|
170
|
+
maxAge: 86400,
|
|
171
|
+
credentials: true,
|
|
172
|
+
}));
|
|
173
|
+
// Apply API key authentication to all routes except health and docs
|
|
174
|
+
app.use('/tenants/*', apiKeyAuth());
|
|
175
|
+
app.use('/agents/*', apiKeyAuth());
|
|
176
|
+
app.use('/v1/*', apiKeyAuth());
|
|
177
|
+
app.use('/api/*', apiKeyAuth());
|
|
178
|
+
// Health check endpoint (no auth required)
|
|
179
|
+
app.openapi(createRoute({
|
|
180
|
+
method: 'get',
|
|
181
|
+
path: '/health',
|
|
182
|
+
tags: ['health'],
|
|
183
|
+
summary: 'Health check',
|
|
184
|
+
description: 'Check if the execution service is healthy',
|
|
185
|
+
responses: {
|
|
186
|
+
204: {
|
|
187
|
+
description: 'Service is healthy',
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
}), (c) => {
|
|
191
|
+
return c.body(null, 204);
|
|
192
|
+
});
|
|
193
|
+
// Mount execution routes - API key provides tenant, project, and graph context
|
|
194
|
+
app.route('/v1/chat', chatRoutes);
|
|
195
|
+
app.route('/api', chatDataRoutes);
|
|
196
|
+
app.route('/v1/mcp', mcpRoutes);
|
|
197
|
+
app.route('/agents', agentRoutes);
|
|
198
|
+
// Setup OpenAPI documentation endpoints (/openapi.json and /docs)
|
|
199
|
+
setupOpenAPIRoutes(app);
|
|
200
|
+
return app;
|
|
201
|
+
}
|
|
202
|
+
export { createExecutionHono };
|
package/dist/data/agents.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { RegisteredAgent } from '../a2a/types.js';
|
|
2
|
-
import { ExecutionContext } from '@inkeep/agents-core';
|
|
3
|
-
export declare function getRegisteredAgent(executionContext: ExecutionContext): Promise<RegisteredAgent | null>;
|
|
2
|
+
import { ExecutionContext, CredentialStoreRegistry } from '@inkeep/agents-core';
|
|
3
|
+
export declare function getRegisteredAgent(executionContext: ExecutionContext, credentialStoreRegistry?: CredentialStoreRegistry): Promise<RegisteredAgent | null>;
|
|
4
4
|
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/data/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAEL,gBAAgB,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/data/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAEL,gBAAgB,EAIhB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAyE7B,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,gBAAgB,EAClC,uBAAuB,CAAC,EAAE,uBAAuB,GAChD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAiBjC"}
|
package/dist/data/agents.js
CHANGED
|
@@ -7,7 +7,7 @@ const logger = getLogger('agents');
|
|
|
7
7
|
* Create a RegisteredAgent from database agent data
|
|
8
8
|
* Hydrates agent directly from database schema using types from schema.ts
|
|
9
9
|
*/
|
|
10
|
-
async function hydrateAgent({ dbAgent, graphId, baseUrl, apiKey, }) {
|
|
10
|
+
async function hydrateAgent({ dbAgent, graphId, baseUrl, apiKey, credentialStoreRegistry, }) {
|
|
11
11
|
try {
|
|
12
12
|
// Create task handler for the agent
|
|
13
13
|
const taskHandlerConfig = await createTaskHandlerConfig({
|
|
@@ -18,7 +18,7 @@ async function hydrateAgent({ dbAgent, graphId, baseUrl, apiKey, }) {
|
|
|
18
18
|
baseUrl: baseUrl,
|
|
19
19
|
apiKey: apiKey,
|
|
20
20
|
});
|
|
21
|
-
const taskHandler = createTaskHandler(taskHandlerConfig);
|
|
21
|
+
const taskHandler = createTaskHandler(taskHandlerConfig, credentialStoreRegistry);
|
|
22
22
|
// Create AgentCard from database data using schema.ts types
|
|
23
23
|
const agentCard = {
|
|
24
24
|
name: dbAgent.name,
|
|
@@ -56,7 +56,7 @@ async function hydrateAgent({ dbAgent, graphId, baseUrl, apiKey, }) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
// A2A functions that hydrate agents on-demand
|
|
59
|
-
export async function getRegisteredAgent(executionContext) {
|
|
59
|
+
export async function getRegisteredAgent(executionContext, credentialStoreRegistry) {
|
|
60
60
|
const { tenantId, projectId, graphId, agentId, baseUrl } = executionContext;
|
|
61
61
|
if (!agentId) {
|
|
62
62
|
throw new Error('Agent ID is required');
|
|
@@ -69,5 +69,5 @@ export async function getRegisteredAgent(executionContext) {
|
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
const agentFrameworkBaseUrl = `${baseUrl}/agents`;
|
|
72
|
-
return hydrateAgent({ dbAgent, graphId, baseUrl: agentFrameworkBaseUrl });
|
|
72
|
+
return hydrateAgent({ dbAgent, graphId, baseUrl: agentFrameworkBaseUrl, credentialStoreRegistry });
|
|
73
73
|
}
|
package/dist/env.d.ts
CHANGED
|
@@ -7,36 +7,38 @@ declare const envSchema: z.ZodObject<{
|
|
|
7
7
|
}>>;
|
|
8
8
|
ENVIRONMENT: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
9
9
|
development: "development";
|
|
10
|
-
production: "production";
|
|
11
10
|
pentest: "pentest";
|
|
11
|
+
production: "production";
|
|
12
12
|
test: "test";
|
|
13
13
|
}>>>;
|
|
14
14
|
DB_FILE_NAME: z.ZodDefault<z.ZodString>;
|
|
15
15
|
PORT: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
16
16
|
AGENT_BASE_URL: z.ZodOptional<z.ZodString>;
|
|
17
17
|
LOG_LEVEL: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
18
|
-
|
|
18
|
+
error: "error";
|
|
19
19
|
debug: "debug";
|
|
20
20
|
info: "info";
|
|
21
|
+
trace: "trace";
|
|
21
22
|
warn: "warn";
|
|
22
|
-
error: "error";
|
|
23
23
|
}>>>;
|
|
24
24
|
NANGO_SECRET_KEY: z.ZodOptional<z.ZodString>;
|
|
25
25
|
OPENAI_API_KEY: z.ZodOptional<z.ZodString>;
|
|
26
26
|
ANTHROPIC_API_KEY: z.ZodString;
|
|
27
27
|
INKEEP_AGENTS_RUN_BYPASS_SECRET: z.ZodOptional<z.ZodString>;
|
|
28
|
+
OTEL_TRACES_FORCE_FLUSH_ENABLED: z.ZodOptional<z.ZodCodec<z.ZodString, z.ZodBoolean>>;
|
|
28
29
|
}, z.core.$strip>;
|
|
29
30
|
export declare const env: {
|
|
30
|
-
ENVIRONMENT: "development" | "
|
|
31
|
+
ENVIRONMENT: "development" | "pentest" | "production" | "test";
|
|
31
32
|
DB_FILE_NAME: string;
|
|
32
33
|
PORT: number;
|
|
33
|
-
LOG_LEVEL: "
|
|
34
|
+
LOG_LEVEL: "error" | "debug" | "info" | "trace" | "warn";
|
|
34
35
|
ANTHROPIC_API_KEY: string;
|
|
35
36
|
NODE_ENV?: "development" | "production" | "test" | undefined;
|
|
36
37
|
AGENT_BASE_URL?: string | undefined;
|
|
37
38
|
NANGO_SECRET_KEY?: string | undefined;
|
|
38
39
|
OPENAI_API_KEY?: string | undefined;
|
|
39
40
|
INKEEP_AGENTS_RUN_BYPASS_SECRET?: string | undefined;
|
|
41
|
+
OTEL_TRACES_FORCE_FLUSH_ENABLED?: boolean | undefined;
|
|
40
42
|
};
|
|
41
43
|
export type Env = z.infer<typeof envSchema>;
|
|
42
44
|
export {};
|
package/dist/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB,QAAA,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAeb,CAAC;AAuBH,eAAO,MAAM,GAAG;;;;;;;;;;;;CAAa,CAAC;AAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
|
package/dist/env.js
CHANGED
|
@@ -42,6 +42,7 @@ const envSchema = z.object({
|
|
|
42
42
|
OPENAI_API_KEY: z.string().optional(),
|
|
43
43
|
ANTHROPIC_API_KEY: z.string(),
|
|
44
44
|
INKEEP_AGENTS_RUN_BYPASS_SECRET: z.string().optional(),
|
|
45
|
+
OTEL_TRACES_FORCE_FLUSH_ENABLED: z.stringbool().optional(),
|
|
45
46
|
});
|
|
46
47
|
const parseEnv = () => {
|
|
47
48
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executionHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/executionHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"executionHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/executionHandler.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAK/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI5D,UAAU,sBAAsB;IAC9B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;CACzB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAK;IAEhC;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC;CA8cxE"}
|
|
@@ -3,7 +3,7 @@ import { A2AClient } from '../a2a/client.js';
|
|
|
3
3
|
import { executeTransfer, isTransferResponse } from '../a2a/transfer.js';
|
|
4
4
|
import { createMessage, getActiveAgentForConversation, createTask, getTask, updateTask, getFullGraph, } from '@inkeep/agents-core';
|
|
5
5
|
import { getLogger } from '../logger.js';
|
|
6
|
-
import { agentInitializingOp, agentReadyOp, completionOp, errorOp, } from '../utils/agent-operations.js';
|
|
6
|
+
import { agentInitializingOp, agentReadyOp, agentThinkingOp, completionOp, errorOp, } from '../utils/agent-operations.js';
|
|
7
7
|
import { graphSessionManager } from '../utils/graph-session.js';
|
|
8
8
|
import { MCPStreamHelper } from '../utils/stream-helpers.js';
|
|
9
9
|
import { registerStreamHelper, unregisterStreamHelper } from '../utils/stream-registry.js';
|
|
@@ -59,10 +59,7 @@ export class ExecutionHandler {
|
|
|
59
59
|
await sseHelper.writeOperation(agentInitializingOp(requestId, graphId));
|
|
60
60
|
await sseHelper.writeOperation(agentReadyOp(requestId, graphId));
|
|
61
61
|
// Send agent thinking operation after ready
|
|
62
|
-
await sseHelper.
|
|
63
|
-
type: 'agent_thinking',
|
|
64
|
-
ctx: { agent: 'system' },
|
|
65
|
-
});
|
|
62
|
+
await sseHelper.writeOperation(agentThinkingOp('system'));
|
|
66
63
|
// Check for existing task first to prevent race conditions
|
|
67
64
|
const taskId = `task_${conversationId}-${requestId}`;
|
|
68
65
|
const existingTask = await getTask(dbClient)({ id: taskId });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import './instrumentation.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { createExecutionHono } from './app.js';
|
|
3
|
+
import { CredentialStoreRegistry, type CredentialStore, type ServerConfig } from '@inkeep/agents-core';
|
|
4
|
+
declare const app: import("@hono/zod-openapi").OpenAPIHono<{
|
|
5
|
+
Variables: {
|
|
6
|
+
executionContext: import("@inkeep/agents-core").ExecutionContext;
|
|
7
|
+
serverConfig: ServerConfig;
|
|
8
|
+
credentialStores: CredentialStoreRegistry;
|
|
9
|
+
};
|
|
10
|
+
}, {}, "/">;
|
|
11
|
+
export default app;
|
|
12
|
+
export { createExecutionHono };
|
|
13
|
+
export declare function createExecutionApp(config?: {
|
|
14
|
+
serverConfig?: ServerConfig;
|
|
15
|
+
credentialStores?: CredentialStore[];
|
|
16
|
+
}): import("@hono/zod-openapi").OpenAPIHono<{
|
|
17
|
+
Variables: {
|
|
18
|
+
executionContext: import("@inkeep/agents-core").ExecutionContext;
|
|
19
|
+
serverConfig: ServerConfig;
|
|
20
|
+
credentialStores: CredentialStoreRegistry;
|
|
21
|
+
};
|
|
22
|
+
}, {}, "/">;
|
|
5
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EACL,uBAAuB,EAEvB,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAiB7B,QAAA,MAAM,GAAG;;;;;;WAAsD,CAAC;AAGhE,eAAe,GAAG,CAAC;AAGnB,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAG/B,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE;IAC1C,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;CACtC;;;;;;YAMA"}
|
package/dist/index.js
CHANGED
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
import './instrumentation.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// Create credential stores
|
|
8
|
-
const credentialStores = [
|
|
9
|
-
new InMemoryCredentialStore('memory-default'), // In-memory store + env vars
|
|
10
|
-
// Nango store (only loads if NANGO_SECRET_KEY is set)
|
|
11
|
-
...(process.env.NANGO_SECRET_KEY
|
|
12
|
-
? [
|
|
13
|
-
createNangoCredentialStore('nango-default', {
|
|
14
|
-
apiUrl: process.env.NANGO_HOST || 'https://api.nango.dev',
|
|
15
|
-
secretKey: process.env.NANGO_SECRET_KEY,
|
|
16
|
-
}),
|
|
17
|
-
]
|
|
18
|
-
: []),
|
|
19
|
-
createKeyChainStore('keychain-default'),
|
|
20
|
-
];
|
|
21
|
-
// Initialize Execution Server
|
|
22
|
-
const executionServer = new AgentExecutionServer({
|
|
23
|
-
port: EXECUTION_API_PORT,
|
|
24
|
-
credentialStores,
|
|
2
|
+
import { createExecutionHono } from './app.js';
|
|
3
|
+
import { CredentialStoreRegistry, createDefaultCredentialStores, } from '@inkeep/agents-core';
|
|
4
|
+
// Create default configuration
|
|
5
|
+
const defaultConfig = {
|
|
6
|
+
port: 3003,
|
|
25
7
|
serverOptions: {
|
|
26
8
|
requestTimeout: 120000, // 120 seconds for execution requests
|
|
27
9
|
keepAliveTimeout: 60000,
|
|
28
10
|
keepAlive: true,
|
|
29
11
|
},
|
|
30
|
-
}
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
};
|
|
13
|
+
// Create default credential stores
|
|
14
|
+
const defaultStores = createDefaultCredentialStores();
|
|
15
|
+
const defaultRegistry = new CredentialStoreRegistry(defaultStores);
|
|
16
|
+
// Create default app instance for simple usage
|
|
17
|
+
const app = createExecutionHono(defaultConfig, defaultRegistry);
|
|
18
|
+
// Export the default app for Vite dev server and simple deployments
|
|
19
|
+
export default app;
|
|
20
|
+
// Also export the factory function for advanced usage
|
|
21
|
+
export { createExecutionHono };
|
|
22
|
+
// Export a helper to create app with custom credential stores - fallsback to default configs
|
|
23
|
+
export function createExecutionApp(config) {
|
|
24
|
+
const serverConfig = config?.serverConfig ?? defaultConfig;
|
|
25
|
+
const stores = config?.credentialStores ?? defaultStores;
|
|
26
|
+
const registry = new CredentialStoreRegistry(stores);
|
|
27
|
+
return createExecutionHono(serverConfig, registry);
|
|
42
28
|
}
|
|
43
|
-
export { executionServer };
|
package/dist/routes/agents.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { OpenAPIHono } from '@hono/zod-openapi';
|
|
2
|
-
|
|
2
|
+
import { type CredentialStoreRegistry } from '@inkeep/agents-core';
|
|
3
|
+
type AppVariables = {
|
|
4
|
+
credentialStores: CredentialStoreRegistry;
|
|
5
|
+
};
|
|
6
|
+
declare const app: OpenAPIHono<{
|
|
7
|
+
Variables: AppVariables;
|
|
8
|
+
}, {}, "/">;
|
|
3
9
|
export default app;
|
|
4
10
|
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI7D,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAM7B,KAAK,YAAY,GAAG;IAClB,gBAAgB,EAAE,uBAAuB,CAAC;CAC3C,CAAC;AAEF,QAAA,MAAM,GAAG;eAAgC,YAAY;WAAK,CAAC;AAqM3D,eAAe,GAAG,CAAC"}
|
package/dist/routes/agents.js
CHANGED
|
@@ -61,7 +61,8 @@ app.openapi(createRoute({
|
|
|
61
61
|
graphId,
|
|
62
62
|
agentId,
|
|
63
63
|
}, 'agent-level well-known agent.json');
|
|
64
|
-
const
|
|
64
|
+
const credentialStores = c.get('credentialStores');
|
|
65
|
+
const agent = await getRegisteredAgent(executionContext, credentialStores);
|
|
65
66
|
logger.info({ agent }, 'agent registered: well-known agent.json');
|
|
66
67
|
if (!agent) {
|
|
67
68
|
return c.json({ error: 'Agent not found' }, 404);
|
|
@@ -108,7 +109,8 @@ app.post('/a2a', async (c) => {
|
|
|
108
109
|
agentId,
|
|
109
110
|
}, 'agent-level a2a endpoint');
|
|
110
111
|
// Ensure agent is registered (lazy loading)
|
|
111
|
-
const
|
|
112
|
+
const credentialStores = c.get('credentialStores');
|
|
113
|
+
const agent = await getRegisteredAgent(executionContext, credentialStores);
|
|
112
114
|
if (!agent) {
|
|
113
115
|
return c.json({
|
|
114
116
|
jsonrpc: '2.0',
|
|
@@ -140,7 +142,8 @@ app.post('/a2a', async (c) => {
|
|
|
140
142
|
}
|
|
141
143
|
executionContext.agentId = graph.defaultAgentId;
|
|
142
144
|
// fetch the default agent and use it as entry point for the graph
|
|
143
|
-
const
|
|
145
|
+
const credentialStores = c.get('credentialStores');
|
|
146
|
+
const defaultAgent = await getRegisteredAgent(executionContext, credentialStores);
|
|
144
147
|
if (!defaultAgent) {
|
|
145
148
|
return c.json({
|
|
146
149
|
jsonrpc: '2.0',
|