@axiom-lattice/core 1.0.13 → 1.0.21
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 +201 -0
- package/package.json +16 -13
- package/.eslintrc.json +0 -22
- package/.turbo/turbo-build.log +0 -21
- package/jest.config.js +0 -21
- package/src/__tests__/AgentManager.test.ts +0 -202
- package/src/__tests__/setup.ts +0 -5
- package/src/agent_lattice/AgentLatticeManager.ts +0 -216
- package/src/agent_lattice/builders/AgentBuilder.ts +0 -79
- package/src/agent_lattice/builders/AgentGraphBuilder.ts +0 -22
- package/src/agent_lattice/builders/AgentGraphBuilderFactory.ts +0 -70
- package/src/agent_lattice/builders/AgentParamsBuilder.ts +0 -86
- package/src/agent_lattice/builders/DeepAgentGraphBuilder.ts +0 -46
- package/src/agent_lattice/builders/PlanExecuteAgentGraphBuilder.ts +0 -46
- package/src/agent_lattice/builders/ReActAgentGraphBuilder.ts +0 -42
- package/src/agent_lattice/builders/index.ts +0 -14
- package/src/agent_lattice/index.ts +0 -27
- package/src/agent_lattice/types.ts +0 -42
- package/src/base/BaseLatticeManager.ts +0 -145
- package/src/base/index.ts +0 -1
- package/src/createPlanExecuteAgent.ts +0 -475
- package/src/deep_agent/graph.ts +0 -106
- package/src/deep_agent/index.ts +0 -25
- package/src/deep_agent/prompts.ts +0 -284
- package/src/deep_agent/state.ts +0 -63
- package/src/deep_agent/subAgent.ts +0 -185
- package/src/deep_agent/tools.ts +0 -273
- package/src/deep_agent/types.ts +0 -71
- package/src/index.ts +0 -9
- package/src/logger/Logger.ts +0 -186
- package/src/memory_lattice/DefaultMemorySaver.ts +0 -4
- package/src/memory_lattice/MemoryLatticeManager.ts +0 -105
- package/src/memory_lattice/index.ts +0 -9
- package/src/model_lattice/ModelLattice.ts +0 -208
- package/src/model_lattice/ModelLatticeManager.ts +0 -125
- package/src/model_lattice/index.ts +0 -1
- package/src/tool_lattice/ToolLatticeManager.ts +0 -221
- package/src/tool_lattice/get_current_date_time/index.ts +0 -14
- package/src/tool_lattice/index.ts +0 -2
- package/src/tool_lattice/internet_search/index.ts +0 -66
- package/src/types.ts +0 -28
- package/src/util/PGMemory.ts +0 -16
- package/src/util/genUICard.ts +0 -3
- package/src/util/genUIMarkdown.ts +0 -3
- package/src/util/getLastHumanMessageData.ts +0 -41
- package/src/util/returnAIResponse.ts +0 -30
- package/src/util/returnErrorResponse.ts +0 -26
- package/src/util/returnFeedbackResponse.ts +0 -25
- package/src/util/returnToolResponse.ts +0 -32
- package/src/util/withAgentName.ts +0 -220
- package/src/util/zod-to-prompt.ts +0 -50
- package/tsconfig.json +0 -26
package/src/deep_agent/tools.ts
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool functions for Deep Agents
|
|
3
|
-
*
|
|
4
|
-
* TypeScript versions of all tools using @langchain/core/tools tool() function.
|
|
5
|
-
* Uses getCurrentTaskInput() for state access and returns Command objects for state updates.
|
|
6
|
-
* Implements mock filesystem operations using state.files similar to Python version.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { tool, ToolRunnableConfig } from "@langchain/core/tools";
|
|
10
|
-
import { ToolMessage } from "@langchain/core/messages";
|
|
11
|
-
import { Command, getCurrentTaskInput } from "@langchain/langgraph";
|
|
12
|
-
import { z } from "zod";
|
|
13
|
-
import {
|
|
14
|
-
WRITE_TODOS_DESCRIPTION,
|
|
15
|
-
EDIT_DESCRIPTION,
|
|
16
|
-
TOOL_DESCRIPTION,
|
|
17
|
-
} from "./prompts";
|
|
18
|
-
import { DeepAgentStateType } from "./types";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Write todos tool - manages todo list with Command return
|
|
22
|
-
* Uses getCurrentTaskInput() instead of Python's InjectedState
|
|
23
|
-
*/
|
|
24
|
-
export const writeTodos = tool(
|
|
25
|
-
(input, config: ToolRunnableConfig) => {
|
|
26
|
-
return new Command({
|
|
27
|
-
update: {
|
|
28
|
-
todos: input.todos,
|
|
29
|
-
messages: [
|
|
30
|
-
new ToolMessage({
|
|
31
|
-
content: `Updated todo list to ${JSON.stringify(input.todos)}`,
|
|
32
|
-
tool_call_id: config.toolCall?.id as string,
|
|
33
|
-
}),
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
name: "write_todos",
|
|
41
|
-
description: WRITE_TODOS_DESCRIPTION,
|
|
42
|
-
schema: z.object({
|
|
43
|
-
todos: z
|
|
44
|
-
.array(
|
|
45
|
-
z.object({
|
|
46
|
-
content: z.string().describe("Content of the todo item"),
|
|
47
|
-
status: z
|
|
48
|
-
.enum(["pending", "in_progress", "completed"])
|
|
49
|
-
.describe("Status of the todo"),
|
|
50
|
-
})
|
|
51
|
-
)
|
|
52
|
-
.describe("List of todo items to update"),
|
|
53
|
-
}),
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* List files tool - returns list of files from state.files
|
|
59
|
-
* Equivalent to Python's ls function
|
|
60
|
-
*/
|
|
61
|
-
export const ls = tool(
|
|
62
|
-
() => {
|
|
63
|
-
const state = getCurrentTaskInput<DeepAgentStateType>();
|
|
64
|
-
const files = state.files || {};
|
|
65
|
-
return Object.keys(files);
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: "ls",
|
|
69
|
-
description: "List all files in the mock filesystem",
|
|
70
|
-
schema: z.object({}),
|
|
71
|
-
}
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Read file tool - reads from mock filesystem in state.files
|
|
76
|
-
* Matches Python read_file function behavior exactly
|
|
77
|
-
*/
|
|
78
|
-
export const readFile = tool(
|
|
79
|
-
(input: { file_path: string; offset?: number; limit?: number }) => {
|
|
80
|
-
const state = getCurrentTaskInput<DeepAgentStateType>();
|
|
81
|
-
const mockFilesystem = state.files || {};
|
|
82
|
-
const { file_path, offset = 0, limit = 2000 } = input;
|
|
83
|
-
|
|
84
|
-
if (!(file_path in mockFilesystem)) {
|
|
85
|
-
return `Error: File '${file_path}' not found`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Get file content
|
|
89
|
-
const content = mockFilesystem[file_path];
|
|
90
|
-
|
|
91
|
-
// Handle empty file
|
|
92
|
-
if (!content || content.trim() === "") {
|
|
93
|
-
return "System reminder: File exists but has empty contents";
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Split content into lines
|
|
97
|
-
const lines = content.split("\n");
|
|
98
|
-
|
|
99
|
-
// Apply line offset and limit
|
|
100
|
-
const startIdx = offset;
|
|
101
|
-
const endIdx = Math.min(startIdx + limit, lines.length);
|
|
102
|
-
|
|
103
|
-
// Handle case where offset is beyond file length
|
|
104
|
-
if (startIdx >= lines.length) {
|
|
105
|
-
return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Format output with line numbers (cat -n format)
|
|
109
|
-
const resultLines: string[] = [];
|
|
110
|
-
for (let i = startIdx; i < endIdx; i++) {
|
|
111
|
-
let lineContent = lines[i];
|
|
112
|
-
|
|
113
|
-
// Truncate lines longer than 2000 characters
|
|
114
|
-
if (lineContent.length > 2000) {
|
|
115
|
-
lineContent = lineContent.substring(0, 2000);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Line numbers start at 1, so add 1 to the index
|
|
119
|
-
const lineNumber = i + 1;
|
|
120
|
-
resultLines.push(`${lineNumber.toString().padStart(6)} ${lineContent}`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return resultLines.join("\n");
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: "read_file",
|
|
127
|
-
description: TOOL_DESCRIPTION,
|
|
128
|
-
schema: z.object({
|
|
129
|
-
file_path: z.string().describe("Absolute path to the file to read"),
|
|
130
|
-
offset: z
|
|
131
|
-
.number()
|
|
132
|
-
.optional()
|
|
133
|
-
.default(0)
|
|
134
|
-
.describe("Line offset to start reading from"),
|
|
135
|
-
limit: z
|
|
136
|
-
.number()
|
|
137
|
-
.optional()
|
|
138
|
-
.default(2000)
|
|
139
|
-
.describe("Maximum number of lines to read"),
|
|
140
|
-
}),
|
|
141
|
-
}
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Write file tool - writes to mock filesystem with Command return
|
|
146
|
-
* Matches Python write_file function behavior exactly
|
|
147
|
-
*/
|
|
148
|
-
export const writeFile = tool(
|
|
149
|
-
(
|
|
150
|
-
input: { file_path: string; content: string },
|
|
151
|
-
config: ToolRunnableConfig
|
|
152
|
-
) => {
|
|
153
|
-
const state = getCurrentTaskInput<DeepAgentStateType>();
|
|
154
|
-
const files = { ...(state.files || {}) };
|
|
155
|
-
files[input.file_path] = input.content;
|
|
156
|
-
|
|
157
|
-
return new Command({
|
|
158
|
-
update: {
|
|
159
|
-
files: files,
|
|
160
|
-
messages: [
|
|
161
|
-
new ToolMessage({
|
|
162
|
-
content: `Updated file ${input.file_path}`,
|
|
163
|
-
tool_call_id: config.toolCall?.id as string,
|
|
164
|
-
}),
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: "write_file",
|
|
171
|
-
description: "Write content to a file in the mock filesystem",
|
|
172
|
-
schema: z.object({
|
|
173
|
-
file_path: z.string().describe("Absolute path to the file to write"),
|
|
174
|
-
content: z.string().describe("Content to write to the file"),
|
|
175
|
-
}),
|
|
176
|
-
}
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Edit file tool - edits files in mock filesystem with Command return
|
|
181
|
-
* Matches Python edit_file function behavior exactly
|
|
182
|
-
*/
|
|
183
|
-
export const editFile = tool(
|
|
184
|
-
(
|
|
185
|
-
input: {
|
|
186
|
-
file_path: string;
|
|
187
|
-
old_string: string;
|
|
188
|
-
new_string: string;
|
|
189
|
-
replace_all?: boolean;
|
|
190
|
-
},
|
|
191
|
-
config: ToolRunnableConfig
|
|
192
|
-
) => {
|
|
193
|
-
const state = getCurrentTaskInput<DeepAgentStateType>();
|
|
194
|
-
const mockFilesystem = { ...(state.files || {}) };
|
|
195
|
-
const { file_path, old_string, new_string, replace_all = false } = input;
|
|
196
|
-
|
|
197
|
-
// Check if file exists in mock filesystem
|
|
198
|
-
if (!(file_path in mockFilesystem)) {
|
|
199
|
-
return `Error: File '${file_path}' not found`;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Get current file content
|
|
203
|
-
const content = mockFilesystem[file_path];
|
|
204
|
-
|
|
205
|
-
// Check if old_string exists in the file
|
|
206
|
-
if (!content.includes(old_string)) {
|
|
207
|
-
return `Error: String not found in file: '${old_string}'`;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// If not replace_all, check for uniqueness
|
|
211
|
-
if (!replace_all) {
|
|
212
|
-
const escapedOldString = old_string.replace(
|
|
213
|
-
/[.*+?^${}()|[\]\\]/g,
|
|
214
|
-
"\\$&"
|
|
215
|
-
);
|
|
216
|
-
const occurrences = (
|
|
217
|
-
content.match(new RegExp(escapedOldString, "g")) || []
|
|
218
|
-
).length;
|
|
219
|
-
if (occurrences > 1) {
|
|
220
|
-
return `Error: String '${old_string}' appears ${occurrences} times in file. Use replace_all=True to replace all instances, or provide a more specific string with surrounding context.`;
|
|
221
|
-
} else if (occurrences === 0) {
|
|
222
|
-
return `Error: String not found in file: '${old_string}'`;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Perform the replacement
|
|
227
|
-
let newContent: string;
|
|
228
|
-
|
|
229
|
-
if (replace_all) {
|
|
230
|
-
const escapedOldString = old_string.replace(
|
|
231
|
-
/[.*+?^${}()|[\]\\]/g,
|
|
232
|
-
"\\$&"
|
|
233
|
-
);
|
|
234
|
-
newContent = content.replace(
|
|
235
|
-
new RegExp(escapedOldString, "g"),
|
|
236
|
-
new_string
|
|
237
|
-
);
|
|
238
|
-
} else {
|
|
239
|
-
newContent = content.replace(old_string, new_string);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Update the mock filesystem
|
|
243
|
-
mockFilesystem[file_path] = newContent;
|
|
244
|
-
|
|
245
|
-
return new Command({
|
|
246
|
-
update: {
|
|
247
|
-
files: mockFilesystem,
|
|
248
|
-
messages: [
|
|
249
|
-
new ToolMessage({
|
|
250
|
-
content: `Updated file ${file_path}`,
|
|
251
|
-
tool_call_id: config.toolCall?.id as string,
|
|
252
|
-
}),
|
|
253
|
-
],
|
|
254
|
-
},
|
|
255
|
-
});
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
name: "edit_file",
|
|
259
|
-
description: EDIT_DESCRIPTION,
|
|
260
|
-
schema: z.object({
|
|
261
|
-
file_path: z.string().describe("Absolute path to the file to edit"),
|
|
262
|
-
old_string: z
|
|
263
|
-
.string()
|
|
264
|
-
.describe("String to be replaced (must match exactly)"),
|
|
265
|
-
new_string: z.string().describe("String to replace with"),
|
|
266
|
-
replace_all: z
|
|
267
|
-
.boolean()
|
|
268
|
-
.optional()
|
|
269
|
-
.default(false)
|
|
270
|
-
.describe("Whether to replace all occurrences"),
|
|
271
|
-
}),
|
|
272
|
-
}
|
|
273
|
-
);
|
package/src/deep_agent/types.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript type definitions for Deep Agents
|
|
3
|
-
*
|
|
4
|
-
* This file contains all the TypeScript interfaces and types that correspond
|
|
5
|
-
* to the Python TypedDict and other type definitions. Defines all necessary
|
|
6
|
-
* TypeScript interfaces and types including StateSchemaType, SubAgent, Todo,
|
|
7
|
-
* and proper generic types for state schemas.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type {
|
|
11
|
-
BaseLanguageModelInput,
|
|
12
|
-
LanguageModelOutput,
|
|
13
|
-
} from "@langchain/core/language_models/base";
|
|
14
|
-
import type { StructuredTool } from "@langchain/core/tools";
|
|
15
|
-
import type { DeepAgentState } from "./state";
|
|
16
|
-
import { z } from "zod";
|
|
17
|
-
import { Runnable } from "@langchain/core/runnables";
|
|
18
|
-
import { ModelLattice } from "../model_lattice/ModelLattice";
|
|
19
|
-
|
|
20
|
-
export type InferZodObjectShape<T> = T extends z.ZodObject<infer Shape>
|
|
21
|
-
? Shape
|
|
22
|
-
: never;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* SubAgent interface matching Python's TypedDict structure
|
|
26
|
-
*/
|
|
27
|
-
export interface SubAgent {
|
|
28
|
-
name: string;
|
|
29
|
-
description: string;
|
|
30
|
-
prompt: string;
|
|
31
|
-
tools?: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type TodoStatus = "pending" | "in_progress" | "completed";
|
|
35
|
-
|
|
36
|
-
export interface Todo {
|
|
37
|
-
content: string;
|
|
38
|
-
status: TodoStatus;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export type DeepAgentStateType = z.infer<typeof DeepAgentState>;
|
|
42
|
-
|
|
43
|
-
export type LanguageModelLike = Runnable<
|
|
44
|
-
BaseLanguageModelInput,
|
|
45
|
-
LanguageModelOutput
|
|
46
|
-
>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Parameters for createDeepAgent function with TypeScript types
|
|
50
|
-
*/
|
|
51
|
-
export interface CreateDeepAgentParams<
|
|
52
|
-
StateSchema extends z.ZodObject<any, any, any, any, any>
|
|
53
|
-
> {
|
|
54
|
-
tools?: StructuredTool[];
|
|
55
|
-
instructions?: string;
|
|
56
|
-
model?: ModelLattice;
|
|
57
|
-
subagents?: SubAgent[];
|
|
58
|
-
stateSchema?: StateSchema;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Parameters for createTaskTool function
|
|
63
|
-
*/
|
|
64
|
-
export interface CreateTaskToolParams<
|
|
65
|
-
StateSchema extends z.ZodObject<any, any, any, any, any>
|
|
66
|
-
> {
|
|
67
|
-
subagents: SubAgent[];
|
|
68
|
-
tools?: Record<string, StructuredTool>;
|
|
69
|
-
model?: ModelLattice;
|
|
70
|
-
stateSchema?: StateSchema;
|
|
71
|
-
}
|
package/src/index.ts
DELETED
package/src/logger/Logger.ts
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import pino from "pino";
|
|
2
|
-
import "pino-pretty";
|
|
3
|
-
import "pino-roll";
|
|
4
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
5
|
-
|
|
6
|
-
export interface LoggerContext {
|
|
7
|
-
"x-user-id"?: string;
|
|
8
|
-
"x-tenant-id"?: string;
|
|
9
|
-
"x-request-id"?: string;
|
|
10
|
-
"x-task-id"?: string;
|
|
11
|
-
"x-thread-id"?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface LoggerOptions {
|
|
15
|
-
name?: string;
|
|
16
|
-
serviceName?: string;
|
|
17
|
-
context?: LoggerContext;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 单例的Pino日志工厂类,管理底层pino实例
|
|
22
|
-
*/
|
|
23
|
-
class PinoLoggerFactory {
|
|
24
|
-
private static instance: PinoLoggerFactory;
|
|
25
|
-
private pinoLogger: pino.Logger;
|
|
26
|
-
|
|
27
|
-
private constructor() {
|
|
28
|
-
const isProd = process.env.NODE_ENV === "production";
|
|
29
|
-
|
|
30
|
-
const loggerConfig: pino.LoggerOptions = {
|
|
31
|
-
// 自定义时间戳格式
|
|
32
|
-
timestamp: () => `,"@timestamp":"${new Date().toISOString()}"`,
|
|
33
|
-
|
|
34
|
-
// 关闭默认的时间戳键
|
|
35
|
-
base: {
|
|
36
|
-
"@version": "1",
|
|
37
|
-
app_name: "lattice",
|
|
38
|
-
service_name: "lattice/graph-server",
|
|
39
|
-
thread_name: "main",
|
|
40
|
-
logger_name: "lattice-graph-logger",
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
formatters: {
|
|
44
|
-
level: (label, number) => {
|
|
45
|
-
return {
|
|
46
|
-
level: label.toUpperCase(),
|
|
47
|
-
level_value: number * 1000,
|
|
48
|
-
};
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// 生产环境使用文件日志
|
|
54
|
-
if (isProd) {
|
|
55
|
-
try {
|
|
56
|
-
this.pinoLogger = pino(
|
|
57
|
-
loggerConfig,
|
|
58
|
-
pino.transport({
|
|
59
|
-
target: "pino-roll",
|
|
60
|
-
options: {
|
|
61
|
-
file: "./logs/fin_ai_graph_server",
|
|
62
|
-
frequency: "daily",
|
|
63
|
-
mkdir: true,
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error(
|
|
69
|
-
"无法初始化 pino-roll 日志记录器,回退到控制台日志",
|
|
70
|
-
error
|
|
71
|
-
);
|
|
72
|
-
// 回退到开发环境的配置
|
|
73
|
-
this.pinoLogger = pino({
|
|
74
|
-
...loggerConfig,
|
|
75
|
-
transport: {
|
|
76
|
-
target: "pino-pretty",
|
|
77
|
-
options: {
|
|
78
|
-
colorize: true,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
// 开发环境使用格式化输出
|
|
85
|
-
this.pinoLogger = pino({
|
|
86
|
-
...loggerConfig,
|
|
87
|
-
transport: {
|
|
88
|
-
target: "pino-pretty",
|
|
89
|
-
options: {
|
|
90
|
-
colorize: true,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public static getInstance(): PinoLoggerFactory {
|
|
98
|
-
if (!PinoLoggerFactory.instance) {
|
|
99
|
-
PinoLoggerFactory.instance = new PinoLoggerFactory();
|
|
100
|
-
}
|
|
101
|
-
return PinoLoggerFactory.instance;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
public getPinoLogger(): pino.Logger {
|
|
105
|
-
return this.pinoLogger;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Logger类,可以创建多个实例,每个实例有自己的上下文
|
|
111
|
-
*/
|
|
112
|
-
export class Logger {
|
|
113
|
-
private context: LoggerContext;
|
|
114
|
-
private name: string;
|
|
115
|
-
private serviceName: string;
|
|
116
|
-
|
|
117
|
-
constructor(options?: LoggerOptions) {
|
|
118
|
-
this.context = options?.context || {};
|
|
119
|
-
this.name = options?.name || "lattice-graph-logger";
|
|
120
|
-
this.serviceName = options?.serviceName || "lattice/graph-server";
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 获取合并了上下文的日志对象
|
|
125
|
-
* @param additionalContext 额外的上下文数据
|
|
126
|
-
* @returns 带有上下文的pino日志对象
|
|
127
|
-
*/
|
|
128
|
-
private getContextualLogger(additionalContext?: object): pino.Logger {
|
|
129
|
-
const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();
|
|
130
|
-
|
|
131
|
-
// 合并Logger实例的上下文和额外上下文
|
|
132
|
-
const contextObj = {
|
|
133
|
-
"x-user-id": this.context["x-user-id"] || "",
|
|
134
|
-
"x-tenant-id": this.context["x-tenant-id"] || "",
|
|
135
|
-
"x-request-id": this.context["x-request-id"] || "",
|
|
136
|
-
"x-task-id": this.context["x-task-id"] || "",
|
|
137
|
-
"x-thread-id": this.context["x-thread-id"] || "",
|
|
138
|
-
service_name: this.serviceName,
|
|
139
|
-
logger_name: this.name,
|
|
140
|
-
...additionalContext,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
// 创建带有上下文的子日志记录器
|
|
144
|
-
return pinoLogger.child(contextObj);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
info(msg: string, obj?: object): void {
|
|
148
|
-
this.getContextualLogger(obj).info(msg);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
error(msg: string, obj?: object | Error): void {
|
|
152
|
-
this.getContextualLogger(obj).error(msg);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
warn(msg: string, obj?: object): void {
|
|
156
|
-
this.getContextualLogger(obj).warn(msg);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
debug(msg: string, obj?: object): void {
|
|
160
|
-
this.getContextualLogger(obj).debug(msg);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* 更新Logger实例的上下文
|
|
165
|
-
*/
|
|
166
|
-
updateContext(context: Partial<LoggerContext>): void {
|
|
167
|
-
this.context = {
|
|
168
|
-
...this.context,
|
|
169
|
-
...context,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* 创建一个新的Logger实例,继承当前Logger的上下文
|
|
175
|
-
*/
|
|
176
|
-
child(options: Partial<LoggerOptions>): Logger {
|
|
177
|
-
return new Logger({
|
|
178
|
-
name: options.name || this.name,
|
|
179
|
-
serviceName: options.serviceName || this.serviceName,
|
|
180
|
-
context: {
|
|
181
|
-
...this.context,
|
|
182
|
-
...options.context,
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MemoryLatticeManager
|
|
3
|
-
*
|
|
4
|
-
* 记忆Lattice管理器,负责管理和注册检查点保存器
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
8
|
-
import { BaseLatticeManager } from "../base/BaseLatticeManager";
|
|
9
|
-
import { MemoryLatticeProtocol, MemoryType } from "@axiom-lattice/protocols";
|
|
10
|
-
|
|
11
|
-
// Re-export types from protocols
|
|
12
|
-
export { MemoryType };
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 记忆Lattice管理器类
|
|
16
|
-
*/
|
|
17
|
-
export class MemoryLatticeManager extends BaseLatticeManager {
|
|
18
|
-
private static instance: MemoryLatticeManager;
|
|
19
|
-
|
|
20
|
-
// 检查点保存器注册表
|
|
21
|
-
private static checkpointSavers: Map<string, BaseCheckpointSaver> = new Map();
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 私有构造函数,防止外部直接实例化
|
|
25
|
-
*/
|
|
26
|
-
private constructor() {
|
|
27
|
-
super();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 获取单例实例
|
|
32
|
-
*/
|
|
33
|
-
public static getInstance(): MemoryLatticeManager {
|
|
34
|
-
if (!MemoryLatticeManager.instance) {
|
|
35
|
-
MemoryLatticeManager.instance = new MemoryLatticeManager();
|
|
36
|
-
}
|
|
37
|
-
return MemoryLatticeManager.instance;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 获取Lattice类型
|
|
42
|
-
*/
|
|
43
|
-
protected getLatticeType(): string {
|
|
44
|
-
return "memory";
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 注册检查点保存器
|
|
49
|
-
* @param key 保存器键名
|
|
50
|
-
* @param saver 检查点保存器实例
|
|
51
|
-
*/
|
|
52
|
-
public registerCheckpointSaver(
|
|
53
|
-
key: string,
|
|
54
|
-
saver: BaseCheckpointSaver
|
|
55
|
-
): void {
|
|
56
|
-
if (MemoryLatticeManager.checkpointSavers.has(key)) {
|
|
57
|
-
throw new Error(`检查点保存器 "${key}" 已经存在,无法重复注册`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
MemoryLatticeManager.checkpointSavers.set(key, saver);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 获取检查点保存器
|
|
65
|
-
* @param key 保存器键名
|
|
66
|
-
*/
|
|
67
|
-
public getCheckpointSaver(key: string): BaseCheckpointSaver {
|
|
68
|
-
const saver = MemoryLatticeManager.checkpointSavers.get(key);
|
|
69
|
-
if (!saver) {
|
|
70
|
-
throw new Error(`检查点保存器 "${key}" 不存在`);
|
|
71
|
-
}
|
|
72
|
-
return saver;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 获取所有已注册的检查点保存器键名
|
|
77
|
-
*/
|
|
78
|
-
public getCheckpointSaverKeys(): string[] {
|
|
79
|
-
return Array.from(MemoryLatticeManager.checkpointSavers.keys());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 检查检查点保存器是否存在
|
|
84
|
-
* @param key 保存器键名
|
|
85
|
-
*/
|
|
86
|
-
public hasCheckpointSaver(key: string): boolean {
|
|
87
|
-
return MemoryLatticeManager.checkpointSavers.has(key);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* 移除检查点保存器
|
|
92
|
-
* @param key 保存器键名
|
|
93
|
-
*/
|
|
94
|
-
public removeCheckpointSaver(key: string): boolean {
|
|
95
|
-
return MemoryLatticeManager.checkpointSavers.delete(key);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const getCheckpointSaver = (key: string) =>
|
|
100
|
-
MemoryLatticeManager.getInstance().getCheckpointSaver(key);
|
|
101
|
-
|
|
102
|
-
export const registerCheckpointSaver = (
|
|
103
|
-
key: string,
|
|
104
|
-
saver: BaseCheckpointSaver
|
|
105
|
-
) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);
|