@inkeep/agents-manage-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.
- package/README.md +176 -0
- package/dist/ManagementServer.d.ts +28 -0
- package/dist/ManagementServer.d.ts.map +1 -0
- package/dist/ManagementServer.js +41 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +26 -0
- package/dist/__tests__/utils/testProject.d.ts +18 -0
- package/dist/__tests__/utils/testProject.d.ts.map +1 -0
- package/dist/__tests__/utils/testProject.js +26 -0
- package/dist/__tests__/utils/testRequest.d.ts +2 -0
- package/dist/__tests__/utils/testRequest.d.ts.map +1 -0
- package/dist/__tests__/utils/testRequest.js +11 -0
- package/dist/__tests__/utils/testTenant.d.ts +64 -0
- package/dist/__tests__/utils/testTenant.d.ts.map +1 -0
- package/dist/__tests__/utils/testTenant.js +71 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +140 -0
- package/dist/data/conversations.d.ts +59 -0
- package/dist/data/conversations.d.ts.map +1 -0
- package/dist/data/conversations.js +216 -0
- package/dist/data/db/clean.d.ts +6 -0
- package/dist/data/db/clean.d.ts.map +1 -0
- package/dist/data/db/clean.js +77 -0
- package/dist/data/db/dbClient.d.ts +3 -0
- package/dist/data/db/dbClient.d.ts.map +1 -0
- package/dist/data/db/dbClient.js +13 -0
- package/dist/data/graphFull.d.ts +11 -0
- package/dist/data/graphFull.d.ts.map +1 -0
- package/dist/data/graphFull.js +90 -0
- package/dist/data/graphFullClient.d.ts +22 -0
- package/dist/data/graphFullClient.d.ts.map +1 -0
- package/dist/data/graphFullClient.js +189 -0
- package/dist/data/tools.d.ts +81 -0
- package/dist/data/tools.d.ts.map +1 -0
- package/dist/data/tools.js +266 -0
- package/dist/env.d.ts +41 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +59 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +32 -0
- package/dist/middleware/auth.d.ts +12 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +36 -0
- package/dist/openapi.d.ts +2 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +38 -0
- package/dist/routes/agentArtifactComponents.d.ts +4 -0
- package/dist/routes/agentArtifactComponents.d.ts.map +1 -0
- package/dist/routes/agentArtifactComponents.js +230 -0
- package/dist/routes/agentDataComponents.d.ts +4 -0
- package/dist/routes/agentDataComponents.d.ts.map +1 -0
- package/dist/routes/agentDataComponents.js +225 -0
- package/dist/routes/agentGraph.d.ts +4 -0
- package/dist/routes/agentGraph.d.ts.map +1 -0
- package/dist/routes/agentGraph.js +289 -0
- package/dist/routes/agentRelations.d.ts +4 -0
- package/dist/routes/agentRelations.d.ts.map +1 -0
- package/dist/routes/agentRelations.js +290 -0
- package/dist/routes/agentToolRelations.d.ts +4 -0
- package/dist/routes/agentToolRelations.d.ts.map +1 -0
- package/dist/routes/agentToolRelations.js +342 -0
- package/dist/routes/agents.d.ts +4 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +213 -0
- package/dist/routes/apiKeys.d.ts +4 -0
- package/dist/routes/apiKeys.d.ts.map +1 -0
- package/dist/routes/apiKeys.js +236 -0
- package/dist/routes/artifactComponents.d.ts +4 -0
- package/dist/routes/artifactComponents.d.ts.map +1 -0
- package/dist/routes/artifactComponents.js +202 -0
- package/dist/routes/contextConfigs.d.ts +4 -0
- package/dist/routes/contextConfigs.d.ts.map +1 -0
- package/dist/routes/contextConfigs.js +181 -0
- package/dist/routes/credentials.d.ts +4 -0
- package/dist/routes/credentials.d.ts.map +1 -0
- package/dist/routes/credentials.js +219 -0
- package/dist/routes/dataComponents.d.ts +4 -0
- package/dist/routes/dataComponents.d.ts.map +1 -0
- package/dist/routes/dataComponents.js +188 -0
- package/dist/routes/externalAgents.d.ts +4 -0
- package/dist/routes/externalAgents.d.ts.map +1 -0
- package/dist/routes/externalAgents.js +216 -0
- package/dist/routes/graphFull.d.ts +4 -0
- package/dist/routes/graphFull.d.ts.map +1 -0
- package/dist/routes/graphFull.js +248 -0
- package/dist/routes/index.d.ts +4 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +37 -0
- package/dist/routes/oauth.d.ts +14 -0
- package/dist/routes/oauth.d.ts.map +1 -0
- package/dist/routes/oauth.js +191 -0
- package/dist/routes/projects.d.ts +4 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +221 -0
- package/dist/routes/tools.d.ts +4 -0
- package/dist/routes/tools.d.ts.map +1 -0
- package/dist/routes/tools.js +547 -0
- package/dist/utils/auth-detection.d.ts +22 -0
- package/dist/utils/auth-detection.d.ts.map +1 -0
- package/dist/utils/auth-detection.js +149 -0
- package/dist/utils/oauth-service.d.ts +88 -0
- package/dist/utils/oauth-service.d.ts.map +1 -0
- package/dist/utils/oauth-service.js +240 -0
- package/package.json +68 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type ConversationScopeOptions, type ConversationHistoryConfig, type AgentConversationHistoryConfig } from '@inkeep/agents-core';
|
|
2
|
+
/**
|
|
3
|
+
* Creates default conversation history configuration
|
|
4
|
+
* @param mode - The conversation history mode ('full' | 'scoped' | 'none')
|
|
5
|
+
* @returns Default AgentConversationHistoryConfig
|
|
6
|
+
*/
|
|
7
|
+
export declare function createDefaultConversationHistoryConfig(mode?: 'full' | 'scoped' | 'none'): AgentConversationHistoryConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Saves the result of an A2A client sendMessage call as a conversation message
|
|
10
|
+
* @param response - The response from a2aClient.sendMessage()
|
|
11
|
+
* @param params - Parameters for saving the message
|
|
12
|
+
* @returns The saved message or null if no text content was found
|
|
13
|
+
*/
|
|
14
|
+
export declare function saveA2AMessageResponse(response: any, // SendMessageResponse type
|
|
15
|
+
params: {
|
|
16
|
+
tenantId: string;
|
|
17
|
+
projectId: string;
|
|
18
|
+
conversationId: string;
|
|
19
|
+
messageType: 'a2a-response' | 'a2a-request';
|
|
20
|
+
visibility: 'internal' | 'external' | 'user-facing';
|
|
21
|
+
fromAgentId?: string;
|
|
22
|
+
toAgentId?: string;
|
|
23
|
+
fromExternalAgentId?: string;
|
|
24
|
+
toExternalAgentId?: string;
|
|
25
|
+
a2aTaskId?: string;
|
|
26
|
+
a2aSessionId?: string;
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
}): Promise<any | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Applies filtering based on agent, task, or both criteria
|
|
31
|
+
* Returns the filtered messages array
|
|
32
|
+
*/
|
|
33
|
+
export declare function getScopedHistory({ tenantId, projectId, conversationId, filters, options, }: {
|
|
34
|
+
tenantId: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
conversationId: string;
|
|
37
|
+
filters?: ConversationScopeOptions;
|
|
38
|
+
options?: ConversationHistoryConfig;
|
|
39
|
+
}): Promise<any[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Get user-facing conversation history (for client display)
|
|
42
|
+
*/
|
|
43
|
+
export declare function getUserFacingHistory(tenantId: string, projectId: string, conversationId: string, limit?: number): Promise<any[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Get full conversation context (for agent processing)
|
|
46
|
+
*/
|
|
47
|
+
export declare function getFullConversationContext(tenantId: string, projectId: string, conversationId: string, maxTokens?: number): Promise<any[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Get formatted conversation history for a2a
|
|
50
|
+
*/
|
|
51
|
+
export declare function getFormattedConversationHistory({ tenantId, projectId, conversationId, currentMessage, options, filters, }: {
|
|
52
|
+
tenantId: string;
|
|
53
|
+
projectId: string;
|
|
54
|
+
conversationId: string;
|
|
55
|
+
currentMessage?: string;
|
|
56
|
+
options?: ConversationHistoryConfig;
|
|
57
|
+
filters?: ConversationScopeOptions;
|
|
58
|
+
}): Promise<string>;
|
|
59
|
+
//# sourceMappingURL=conversations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../src/data/conversations.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EAEpC,MAAM,qBAAqB,CAAC;AAE7B;;;;GAIG;AACH,wBAAgB,sCAAsC,CACpD,IAAI,GAAE,MAAM,GAAG,QAAQ,GAAG,MAAe,GACxC,8BAA8B,CAQhC;AAYD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,GAAG,EAAE,2BAA2B;AAC1C,MAAM,EAAE;IACN,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,cAAc,GAAG,aAAa,CAAC;IAC5C,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GACA,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAkDrB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,QAAQ,EACR,SAAS,EACT,cAAc,EACd,OAAO,EACP,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACrC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAyDjB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,KAAK,SAAK,GACT,OAAO,CAAC,GAAG,EAAE,CAAC,CAUhB;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,GAAG,EAAE,CAAC,CAUhB;AAED;;GAEG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,OAAO,EACP,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import dbClient from './db/dbClient.js';
|
|
3
|
+
import { createMessage, getConversationHistory, } from '@inkeep/agents-core';
|
|
4
|
+
/**
|
|
5
|
+
* Creates default conversation history configuration
|
|
6
|
+
* @param mode - The conversation history mode ('full' | 'scoped' | 'none')
|
|
7
|
+
* @returns Default AgentConversationHistoryConfig
|
|
8
|
+
*/
|
|
9
|
+
export function createDefaultConversationHistoryConfig(mode = 'full') {
|
|
10
|
+
return {
|
|
11
|
+
mode,
|
|
12
|
+
limit: 50,
|
|
13
|
+
includeInternal: true,
|
|
14
|
+
messageTypes: ['chat'],
|
|
15
|
+
maxOutputTokens: 4000,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extracts text content from A2A Message parts array
|
|
20
|
+
*/
|
|
21
|
+
function extractA2AMessageText(parts) {
|
|
22
|
+
return parts
|
|
23
|
+
.filter((part) => part.kind === 'text' && part.text)
|
|
24
|
+
.map((part) => part.text)
|
|
25
|
+
.join('');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Saves the result of an A2A client sendMessage call as a conversation message
|
|
29
|
+
* @param response - The response from a2aClient.sendMessage()
|
|
30
|
+
* @param params - Parameters for saving the message
|
|
31
|
+
* @returns The saved message or null if no text content was found
|
|
32
|
+
*/
|
|
33
|
+
export async function saveA2AMessageResponse(response, // SendMessageResponse type
|
|
34
|
+
params) {
|
|
35
|
+
// Handle error responses
|
|
36
|
+
if (response.error) {
|
|
37
|
+
throw new Error(response.error.message);
|
|
38
|
+
}
|
|
39
|
+
// Extract text content based on result type
|
|
40
|
+
let messageText = '';
|
|
41
|
+
if (response.result.kind === 'message') {
|
|
42
|
+
// Handle Message type with parts array
|
|
43
|
+
messageText = extractA2AMessageText(response.result.parts);
|
|
44
|
+
}
|
|
45
|
+
else if (response.result.kind === 'task') {
|
|
46
|
+
// Handle Task type - extract text from artifacts if available
|
|
47
|
+
if (response.result.artifacts && response.result.artifacts.length > 0) {
|
|
48
|
+
const firstArtifact = response.result.artifacts[0];
|
|
49
|
+
if (firstArtifact.parts) {
|
|
50
|
+
messageText = extractA2AMessageText(firstArtifact.parts);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (typeof response.result === 'string') {
|
|
55
|
+
// Handle direct string responses (for backward compatibility)
|
|
56
|
+
messageText = response.result;
|
|
57
|
+
}
|
|
58
|
+
// Only save if we have meaningful text content
|
|
59
|
+
if (!messageText || messageText.trim() === '') {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// Save the message
|
|
63
|
+
return await createMessage(dbClient)({
|
|
64
|
+
id: nanoid(),
|
|
65
|
+
tenantId: params.tenantId,
|
|
66
|
+
projectId: params.projectId,
|
|
67
|
+
conversationId: params.conversationId,
|
|
68
|
+
role: 'agent',
|
|
69
|
+
content: {
|
|
70
|
+
text: messageText,
|
|
71
|
+
},
|
|
72
|
+
visibility: params.visibility,
|
|
73
|
+
messageType: params.messageType,
|
|
74
|
+
fromAgentId: params.fromAgentId,
|
|
75
|
+
toAgentId: params.toAgentId,
|
|
76
|
+
fromExternalAgentId: params.fromExternalAgentId,
|
|
77
|
+
toExternalAgentId: params.toExternalAgentId,
|
|
78
|
+
a2aTaskId: params.a2aTaskId,
|
|
79
|
+
a2aSessionId: params.a2aSessionId,
|
|
80
|
+
metadata: params.metadata,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Applies filtering based on agent, task, or both criteria
|
|
85
|
+
* Returns the filtered messages array
|
|
86
|
+
*/
|
|
87
|
+
export async function getScopedHistory({ tenantId, projectId, conversationId, filters, options, }) {
|
|
88
|
+
try {
|
|
89
|
+
// Get conversation history with internal messages included
|
|
90
|
+
const messages = await getConversationHistory(dbClient)({
|
|
91
|
+
scopes: { tenantId, projectId },
|
|
92
|
+
conversationId,
|
|
93
|
+
options,
|
|
94
|
+
});
|
|
95
|
+
// If no filters provided, return all messages
|
|
96
|
+
if (!filters || (!filters.agentId && !filters.taskId)) {
|
|
97
|
+
return messages;
|
|
98
|
+
}
|
|
99
|
+
// Filter messages based on provided criteria
|
|
100
|
+
const relevantMessages = messages.filter((msg) => {
|
|
101
|
+
// Always include user messages
|
|
102
|
+
if (msg.role === 'user')
|
|
103
|
+
return true;
|
|
104
|
+
let matchesAgent = true;
|
|
105
|
+
let matchesTask = true;
|
|
106
|
+
// Apply agent filtering if agentId is provided
|
|
107
|
+
if (filters.agentId) {
|
|
108
|
+
matchesAgent =
|
|
109
|
+
(msg.role === 'agent' && msg.visibility === 'user-facing') ||
|
|
110
|
+
msg.toAgentId === filters.agentId ||
|
|
111
|
+
msg.fromAgentId === filters.agentId;
|
|
112
|
+
}
|
|
113
|
+
// Apply task filtering if taskId is provided
|
|
114
|
+
if (filters.taskId) {
|
|
115
|
+
matchesTask = msg.taskId === filters.taskId || msg.a2aTaskId === filters.taskId;
|
|
116
|
+
}
|
|
117
|
+
// For combined filtering (both agent and task), both must match
|
|
118
|
+
// For single filtering, only the relevant one needs to match
|
|
119
|
+
if (filters.agentId && filters.taskId) {
|
|
120
|
+
return matchesAgent && matchesTask;
|
|
121
|
+
}
|
|
122
|
+
if (filters.agentId) {
|
|
123
|
+
return matchesAgent;
|
|
124
|
+
}
|
|
125
|
+
if (filters.taskId) {
|
|
126
|
+
return matchesTask;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
});
|
|
130
|
+
return relevantMessages;
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error('Failed to fetch scoped messages:', error);
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get user-facing conversation history (for client display)
|
|
139
|
+
*/
|
|
140
|
+
export async function getUserFacingHistory(tenantId, projectId, conversationId, limit = 50) {
|
|
141
|
+
return await getConversationHistory(dbClient)({
|
|
142
|
+
scopes: { tenantId, projectId },
|
|
143
|
+
conversationId,
|
|
144
|
+
options: {
|
|
145
|
+
limit,
|
|
146
|
+
includeInternal: false,
|
|
147
|
+
messageTypes: ['chat'],
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get full conversation context (for agent processing)
|
|
153
|
+
*/
|
|
154
|
+
export async function getFullConversationContext(tenantId, projectId, conversationId, maxTokens) {
|
|
155
|
+
return await getConversationHistory(dbClient)({
|
|
156
|
+
scopes: { tenantId, projectId },
|
|
157
|
+
conversationId,
|
|
158
|
+
options: {
|
|
159
|
+
limit: 100,
|
|
160
|
+
includeInternal: true,
|
|
161
|
+
maxOutputTokens: maxTokens,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get formatted conversation history for a2a
|
|
167
|
+
*/
|
|
168
|
+
export async function getFormattedConversationHistory({ tenantId, projectId, conversationId, currentMessage, options, filters, }) {
|
|
169
|
+
// Ensure includeInternal defaults to true for formatted history
|
|
170
|
+
const historyOptions = options ?? { includeInternal: true };
|
|
171
|
+
// Get filtered conversation history using unified function
|
|
172
|
+
const conversationHistory = await getScopedHistory({
|
|
173
|
+
tenantId,
|
|
174
|
+
projectId,
|
|
175
|
+
conversationId,
|
|
176
|
+
filters,
|
|
177
|
+
options: historyOptions,
|
|
178
|
+
});
|
|
179
|
+
// Filter out the current message if it's the most recent one
|
|
180
|
+
let messagesToFormat = conversationHistory;
|
|
181
|
+
if (currentMessage && conversationHistory.length > 0) {
|
|
182
|
+
const lastMessage = conversationHistory[conversationHistory.length - 1];
|
|
183
|
+
if (lastMessage.content.text === currentMessage) {
|
|
184
|
+
// Remove the last message if it matches the current prompt
|
|
185
|
+
messagesToFormat = conversationHistory.slice(0, -1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!messagesToFormat.length) {
|
|
189
|
+
return '';
|
|
190
|
+
}
|
|
191
|
+
const formattedHistory = messagesToFormat
|
|
192
|
+
.map((msg) => {
|
|
193
|
+
let roleLabel;
|
|
194
|
+
if (msg.role === 'user') {
|
|
195
|
+
roleLabel = 'user';
|
|
196
|
+
}
|
|
197
|
+
else if (msg.role === 'agent' &&
|
|
198
|
+
(msg.messageType === 'a2a-request' || msg.messageType === 'a2a-response')) {
|
|
199
|
+
// For agent messages, include sender and recipient info when available
|
|
200
|
+
const fromAgent = msg.fromAgentId || msg.fromExternalAgentId || 'unknown';
|
|
201
|
+
const toAgent = msg.toAgentId || msg.toExternalAgentId || 'unknown';
|
|
202
|
+
roleLabel = `${fromAgent} to ${toAgent}`;
|
|
203
|
+
}
|
|
204
|
+
else if (msg.role === 'agent' && msg.messageType === 'chat') {
|
|
205
|
+
const fromAgent = msg.fromAgentId || 'unknown';
|
|
206
|
+
roleLabel = `${fromAgent} to User`;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// System or other message types
|
|
210
|
+
roleLabel = msg.role || 'system';
|
|
211
|
+
}
|
|
212
|
+
return `${roleLabel}: """${msg.content.text}"""`; // TODO: add timestamp?
|
|
213
|
+
})
|
|
214
|
+
.join('\n');
|
|
215
|
+
return `<conversation_history>\n${formattedHistory}\n</conversation_history>\n`;
|
|
216
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../../src/data/db/clean.ts"],"names":[],"mappings":"AAwBA;;;GAGG;AACH,wBAAsB,aAAa,kBA6DlC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
import { env } from '../../env.js';
|
|
3
|
+
import { agentArtifactComponents, agentDataComponents, agentGraph, agentRelations, agents, agentToolRelations, artifactComponents, contextCache, contextConfigs, conversations, credentialReferences, dataComponents, externalAgents, ledgerArtifacts, messages, taskRelations, tasks, tools, } from '@inkeep/agents-core';
|
|
4
|
+
import dbClient from './dbClient.js';
|
|
5
|
+
/**
|
|
6
|
+
* Truncates all tables in the database, respecting foreign key constraints
|
|
7
|
+
* Tables are cleared in dependency order (child tables first, then parent tables)
|
|
8
|
+
*/
|
|
9
|
+
export async function cleanDatabase() {
|
|
10
|
+
console.log(`🗑️ Cleaning database for environment: ${env.ENVIRONMENT}`);
|
|
11
|
+
console.log(`📁 Using database: ${env.DB_FILE_NAME}`);
|
|
12
|
+
console.log('---');
|
|
13
|
+
try {
|
|
14
|
+
// Disable foreign key constraints temporarily to make cleanup easier
|
|
15
|
+
await dbClient.run(sql `PRAGMA foreign_keys = OFF`);
|
|
16
|
+
// Order matters: clear dependent tables first
|
|
17
|
+
const tablesToClear = [
|
|
18
|
+
{ table: messages, name: 'messages' },
|
|
19
|
+
{ table: conversations, name: 'conversations' },
|
|
20
|
+
{ table: taskRelations, name: 'task_relations' },
|
|
21
|
+
{ table: tasks, name: 'tasks' },
|
|
22
|
+
{ table: agentArtifactComponents, name: 'agent_artifact_components' },
|
|
23
|
+
{ table: agentDataComponents, name: 'agent_data_components' },
|
|
24
|
+
{ table: agentToolRelations, name: 'agent_tool_relations' },
|
|
25
|
+
{ table: agentRelations, name: 'agent_relations' },
|
|
26
|
+
{ table: agentGraph, name: 'agent_graph' },
|
|
27
|
+
{ table: artifactComponents, name: 'artifact_components' },
|
|
28
|
+
{ table: dataComponents, name: 'data_components' },
|
|
29
|
+
{ table: tools, name: 'tools' },
|
|
30
|
+
{ table: agents, name: 'agents' },
|
|
31
|
+
{ table: externalAgents, name: 'external_agents' },
|
|
32
|
+
{ table: ledgerArtifacts, name: 'ledger_artifacts' },
|
|
33
|
+
{ table: credentialReferences, name: 'credential_references' },
|
|
34
|
+
{ table: contextConfigs, name: 'context_configs' },
|
|
35
|
+
{ table: contextCache, name: 'context_cache' },
|
|
36
|
+
];
|
|
37
|
+
for (const { table, name } of tablesToClear) {
|
|
38
|
+
try {
|
|
39
|
+
await dbClient.delete(table).run();
|
|
40
|
+
console.log(`✅ Cleared table: ${name}`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Handle case where table doesn't exist
|
|
44
|
+
const errorMessage = error?.message || '';
|
|
45
|
+
const causeMessage = error?.cause?.message || '';
|
|
46
|
+
if (errorMessage.includes('no such table') ||
|
|
47
|
+
causeMessage.includes('no such table') ||
|
|
48
|
+
(error?.cause?.code === 'SQLITE_ERROR' && causeMessage.includes('no such table'))) {
|
|
49
|
+
console.log(`⚠️ Table ${name} doesn't exist, skipping`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Re-enable foreign key constraints
|
|
57
|
+
await dbClient.run(sql `PRAGMA foreign_keys = ON`);
|
|
58
|
+
console.log('---');
|
|
59
|
+
console.log('🎉 Database cleaned successfully');
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('❌ Failed to clean database:', error);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Run the clean function if executed directly
|
|
67
|
+
if (import.meta.url === new URL(import.meta.url).href) {
|
|
68
|
+
cleanDatabase()
|
|
69
|
+
.then(() => {
|
|
70
|
+
console.log('Database cleanup completed');
|
|
71
|
+
process.exit(0);
|
|
72
|
+
})
|
|
73
|
+
.catch((error) => {
|
|
74
|
+
console.error('Database cleanup failed:', error);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dbClient.d.ts","sourceRoot":"","sources":["../../../src/data/db/dbClient.ts"],"names":[],"mappings":"AAcA,QAAA,MAAM,QAAQ,8CAA4C,CAAC;AAC3D,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { env } from '../../env.js';
|
|
2
|
+
import { createDatabaseClient } from '@inkeep/agents-core';
|
|
3
|
+
// Create database URL - use in-memory for tests, file for other environments
|
|
4
|
+
const getDbUrl = () => {
|
|
5
|
+
// Use in-memory database for tests - each worker gets its own isolated database
|
|
6
|
+
if (env.ENVIRONMENT === 'test') {
|
|
7
|
+
return ':memory:';
|
|
8
|
+
}
|
|
9
|
+
return env.DB_FILE_NAME;
|
|
10
|
+
};
|
|
11
|
+
// Create the SQLite client
|
|
12
|
+
const dbClient = createDatabaseClient({ url: getDbUrl() });
|
|
13
|
+
export default dbClient;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FullGraphDefinition } from '@inkeep/agents-core';
|
|
2
|
+
/**
|
|
3
|
+
* Client-side implementation of createFullGraph that makes HTTP requests to the API endpoint.
|
|
4
|
+
* This function should be used by client code instead of directly accessing the data layer.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createFullGraph: (tenantId: string, graphData: FullGraphDefinition) => Promise<FullGraphDefinition>;
|
|
7
|
+
/**
|
|
8
|
+
* Client-side implementation of updateFullGraph that makes HTTP requests to the API endpoint.
|
|
9
|
+
*/
|
|
10
|
+
export declare const updateFullGraph: (tenantId: string, graphId: string, graphData: FullGraphDefinition) => Promise<FullGraphDefinition>;
|
|
11
|
+
//# sourceMappingURL=graphFull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphFull.d.ts","sourceRoot":"","sources":["../../src/data/graphFull.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,qBAAqB,CAAC;AAIzF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,WAAW,mBAAmB,KAC7B,OAAO,CAAC,mBAAmB,CAkD7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,SAAS,MAAM,EACf,WAAW,mBAAmB,KAC7B,OAAO,CAAC,mBAAmB,CAyD7B,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { env } from '../env.js';
|
|
2
|
+
import { getLogger } from '../logger.js';
|
|
3
|
+
import { validateAndTypeGraphData } from '@inkeep/agents-core';
|
|
4
|
+
const logger = getLogger('graphFull');
|
|
5
|
+
/**
|
|
6
|
+
* Client-side implementation of createFullGraph that makes HTTP requests to the API endpoint.
|
|
7
|
+
* This function should be used by client code instead of directly accessing the data layer.
|
|
8
|
+
*/
|
|
9
|
+
export const createFullGraph = async (tenantId, graphData) => {
|
|
10
|
+
logger.info({
|
|
11
|
+
tenantId,
|
|
12
|
+
graphId: graphData.id,
|
|
13
|
+
agentCount: Object.keys(graphData.agents || {}).length,
|
|
14
|
+
}, 'Creating full graph via API endpoint');
|
|
15
|
+
try {
|
|
16
|
+
const baseUrl = env.AGENT_BASE_URL || `http://localhost:${env.PORT}`;
|
|
17
|
+
const endpoint = `${baseUrl}/tenants/${tenantId}/crud/graph`;
|
|
18
|
+
const response = await fetch(endpoint, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify(graphData),
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const errorText = await response.text();
|
|
27
|
+
throw new Error(`HTTP error ${response.status}: ${errorText}`);
|
|
28
|
+
}
|
|
29
|
+
const result = await response.json();
|
|
30
|
+
logger.info({
|
|
31
|
+
tenantId,
|
|
32
|
+
graphId: graphData.id,
|
|
33
|
+
status: response.status,
|
|
34
|
+
}, 'Full graph created successfully via API');
|
|
35
|
+
return result.data;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
logger.error({
|
|
39
|
+
tenantId,
|
|
40
|
+
graphId: graphData.id,
|
|
41
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
42
|
+
}, 'Failed to create full graph via API');
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Client-side implementation of updateFullGraph that makes HTTP requests to the API endpoint.
|
|
48
|
+
*/
|
|
49
|
+
export const updateFullGraph = async (tenantId, graphId, graphData) => {
|
|
50
|
+
const typed = validateAndTypeGraphData(graphData);
|
|
51
|
+
// Validate that the graphId matches the data.id
|
|
52
|
+
if (graphId !== typed.id) {
|
|
53
|
+
throw new Error(`Graph ID mismatch: expected ${graphId}, got ${typed.id}`);
|
|
54
|
+
}
|
|
55
|
+
logger.info({
|
|
56
|
+
tenantId,
|
|
57
|
+
graphId,
|
|
58
|
+
agentCount: Object.keys(graphData.agents || {}).length,
|
|
59
|
+
}, 'Updating full graph via API endpoint');
|
|
60
|
+
try {
|
|
61
|
+
const baseUrl = env.AGENT_BASE_URL || `http://localhost:${env.PORT}`;
|
|
62
|
+
const endpoint = `${baseUrl}/tenants/${tenantId}/crud/graph/${graphId}`;
|
|
63
|
+
const response = await fetch(endpoint, {
|
|
64
|
+
method: 'PUT',
|
|
65
|
+
headers: {
|
|
66
|
+
'Content-Type': 'application/json',
|
|
67
|
+
},
|
|
68
|
+
body: JSON.stringify(graphData),
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
const errorText = await response.text();
|
|
72
|
+
throw new Error(`HTTP error ${response.status}: ${errorText}`);
|
|
73
|
+
}
|
|
74
|
+
const result = await response.json();
|
|
75
|
+
logger.info({
|
|
76
|
+
tenantId,
|
|
77
|
+
graphId,
|
|
78
|
+
status: response.status,
|
|
79
|
+
}, 'Full graph updated successfully via API');
|
|
80
|
+
return result.data;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
logger.error({
|
|
84
|
+
tenantId,
|
|
85
|
+
graphId,
|
|
86
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
87
|
+
}, 'Failed to update full graph via API');
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side functions for interacting with the Full Graph API
|
|
3
|
+
* These functions make HTTP requests to the server instead of direct database calls
|
|
4
|
+
*/
|
|
5
|
+
import type { FullGraphDefinition } from '@inkeep/agents-core';
|
|
6
|
+
/**
|
|
7
|
+
* Create a full graph via HTTP API
|
|
8
|
+
*/
|
|
9
|
+
export declare function createFullGraphViaAPI(tenantId: string, projectId: string, apiUrl: string, graphData: FullGraphDefinition): Promise<FullGraphDefinition>;
|
|
10
|
+
/**
|
|
11
|
+
* Update a full graph via HTTP API (upsert behavior)
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateFullGraphViaAPI(tenantId: string, projectId: string, apiUrl: string, graphId: string, graphData: FullGraphDefinition): Promise<FullGraphDefinition>;
|
|
14
|
+
/**
|
|
15
|
+
* Get a full graph via HTTP API
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFullGraphViaAPI(tenantId: string, projectId: string, apiUrl: string, graphId: string): Promise<FullGraphDefinition | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Delete a full graph via HTTP API
|
|
20
|
+
*/
|
|
21
|
+
export declare function deleteFullGraphViaAPI(tenantId: string, projectId: string, apiUrl: string, graphId: string): Promise<boolean>;
|
|
22
|
+
//# sourceMappingURL=graphFullClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphFullClient.d.ts","sourceRoot":"","sources":["../../src/data/graphFullClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAyD9B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAyD9B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA4DrC;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CA0DlB"}
|