@mongodb-js/agent-engine-runner-shared 0.11.3
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/CHANGELOG.md +55 -0
- package/LICENSE.md +201 -0
- package/README.md +29 -0
- package/dist/agent_config.d.ts +167 -0
- package/dist/agent_config.d.ts.map +1 -0
- package/dist/agent_config.js +544 -0
- package/dist/call_interrupted.d.ts +12 -0
- package/dist/call_interrupted.d.ts.map +1 -0
- package/dist/call_interrupted.js +11 -0
- package/dist/checkpoint_workspace.d.ts +25 -0
- package/dist/checkpoint_workspace.d.ts.map +1 -0
- package/dist/checkpoint_workspace.js +44 -0
- package/dist/context.d.ts +235 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +322 -0
- package/dist/db_config.d.ts +28 -0
- package/dist/db_config.d.ts.map +1 -0
- package/dist/db_config.js +66 -0
- package/dist/db_naming.d.ts +54 -0
- package/dist/db_naming.d.ts.map +1 -0
- package/dist/db_naming.js +94 -0
- package/dist/error_reporting.d.ts +67 -0
- package/dist/error_reporting.d.ts.map +1 -0
- package/dist/error_reporting.js +311 -0
- package/dist/generated/workflow/v1/activity_pb.d.ts +342 -0
- package/dist/generated/workflow/v1/activity_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/activity_pb.js +115 -0
- package/dist/generated/workflow/v1/common_pb.d.ts +184 -0
- package/dist/generated/workflow/v1/common_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/common_pb.js +86 -0
- package/dist/generated/workflow/v1/runtime_pb.d.ts +200 -0
- package/dist/generated/workflow/v1/runtime_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/runtime_pb.js +40 -0
- package/dist/generated/workflow/v1/state_pb.d.ts +254 -0
- package/dist/generated/workflow/v1/state_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/state_pb.js +68 -0
- package/dist/guardrails_evaluator/core.d.ts +23 -0
- package/dist/guardrails_evaluator/core.d.ts.map +1 -0
- package/dist/guardrails_evaluator/core.js +122 -0
- package/dist/guardrails_evaluator/index.d.ts +10 -0
- package/dist/guardrails_evaluator/index.d.ts.map +1 -0
- package/dist/guardrails_evaluator/index.js +11 -0
- package/dist/guardrails_evaluator/regex.d.ts +20 -0
- package/dist/guardrails_evaluator/regex.d.ts.map +1 -0
- package/dist/guardrails_evaluator/regex.js +233 -0
- package/dist/hooks.d.ts +109 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +216 -0
- package/dist/http_path.d.ts +18 -0
- package/dist/http_path.d.ts.map +1 -0
- package/dist/http_path.js +53 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/launcher.d.ts +130 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +325 -0
- package/dist/logger.d.ts +96 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +204 -0
- package/dist/mcp_oauth.d.ts +51 -0
- package/dist/mcp_oauth.d.ts.map +1 -0
- package/dist/mcp_oauth.js +389 -0
- package/dist/mcp_oauth_secret.d.ts +21 -0
- package/dist/mcp_oauth_secret.d.ts.map +1 -0
- package/dist/mcp_oauth_secret.js +122 -0
- package/dist/mcp_tools.d.ts +71 -0
- package/dist/mcp_tools.d.ts.map +1 -0
- package/dist/mcp_tools.js +301 -0
- package/dist/memory_appbound.d.ts +42 -0
- package/dist/memory_appbound.d.ts.map +1 -0
- package/dist/memory_appbound.js +159 -0
- package/dist/memory_writer.d.ts +49 -0
- package/dist/memory_writer.d.ts.map +1 -0
- package/dist/memory_writer.js +171 -0
- package/dist/metrics.d.ts +84 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +205 -0
- package/dist/models.d.ts +1458 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +1726 -0
- package/dist/node_logger.d.ts +43 -0
- package/dist/node_logger.d.ts.map +1 -0
- package/dist/node_logger.js +158 -0
- package/dist/owner_callback.d.ts +16 -0
- package/dist/owner_callback.d.ts.map +1 -0
- package/dist/owner_callback.js +40 -0
- package/dist/progress.d.ts +57 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +140 -0
- package/dist/runtime.d.ts +131 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +351 -0
- package/dist/secure_llm_proxy.d.ts +115 -0
- package/dist/secure_llm_proxy.d.ts.map +1 -0
- package/dist/secure_llm_proxy.js +922 -0
- package/dist/secure_wrapper.d.ts +332 -0
- package/dist/secure_wrapper.d.ts.map +1 -0
- package/dist/secure_wrapper.js +1249 -0
- package/dist/server/aer.d.ts +61 -0
- package/dist/server/aer.d.ts.map +1 -0
- package/dist/server/aer.js +1124 -0
- package/dist/server/auth.d.ts +56 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +132 -0
- package/dist/server/base.d.ts +104 -0
- package/dist/server/base.d.ts.map +1 -0
- package/dist/server/base.js +150 -0
- package/dist/server/callInterrupt.d.ts +49 -0
- package/dist/server/callInterrupt.d.ts.map +1 -0
- package/dist/server/callInterrupt.js +68 -0
- package/dist/server/callback_delivery.d.ts +14 -0
- package/dist/server/callback_delivery.d.ts.map +1 -0
- package/dist/server/callback_delivery.js +141 -0
- package/dist/server/chunk_types.d.ts +50 -0
- package/dist/server/chunk_types.d.ts.map +1 -0
- package/dist/server/chunk_types.js +62 -0
- package/dist/server/cors.d.ts +52 -0
- package/dist/server/cors.d.ts.map +1 -0
- package/dist/server/cors.js +107 -0
- package/dist/server/drain.d.ts +169 -0
- package/dist/server/drain.d.ts.map +1 -0
- package/dist/server/drain.js +455 -0
- package/dist/server/function.d.ts +77 -0
- package/dist/server/function.d.ts.map +1 -0
- package/dist/server/function.js +337 -0
- package/dist/server/http_retry.d.ts +37 -0
- package/dist/server/http_retry.d.ts.map +1 -0
- package/dist/server/http_retry.js +157 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +5 -0
- package/dist/server/metadata.d.ts +50 -0
- package/dist/server/metadata.d.ts.map +1 -0
- package/dist/server/metadata.js +193 -0
- package/dist/server/oe_url.d.ts +36 -0
- package/dist/server/oe_url.d.ts.map +1 -0
- package/dist/server/oe_url.js +50 -0
- package/dist/server/owner_url.d.ts +35 -0
- package/dist/server/owner_url.d.ts.map +1 -0
- package/dist/server/owner_url.js +146 -0
- package/dist/server/query.d.ts +42 -0
- package/dist/server/query.d.ts.map +1 -0
- package/dist/server/query.js +28 -0
- package/dist/server/tool.d.ts +138 -0
- package/dist/server/tool.d.ts.map +1 -0
- package/dist/server/tool.js +1017 -0
- package/dist/span_names.d.ts +21 -0
- package/dist/span_names.d.ts.map +1 -0
- package/dist/span_names.js +31 -0
- package/dist/structured_logging/constants.d.ts +17 -0
- package/dist/structured_logging/constants.d.ts.map +1 -0
- package/dist/structured_logging/constants.js +71 -0
- package/dist/structured_logging/env.d.ts +18 -0
- package/dist/structured_logging/env.d.ts.map +1 -0
- package/dist/structured_logging/env.js +39 -0
- package/dist/structured_logging/install.d.ts +56 -0
- package/dist/structured_logging/install.d.ts.map +1 -0
- package/dist/structured_logging/install.js +107 -0
- package/dist/structured_logging/layout.d.ts +9 -0
- package/dist/structured_logging/layout.d.ts.map +1 -0
- package/dist/structured_logging/layout.js +144 -0
- package/dist/structured_logging/serialize.d.ts +27 -0
- package/dist/structured_logging/serialize.d.ts.map +1 -0
- package/dist/structured_logging/serialize.js +61 -0
- package/dist/structured_logging/stdio_capture.d.ts +59 -0
- package/dist/structured_logging/stdio_capture.d.ts.map +1 -0
- package/dist/structured_logging/stdio_capture.js +164 -0
- package/dist/structured_logging/uncaught.d.ts +14 -0
- package/dist/structured_logging/uncaught.d.ts.map +1 -0
- package/dist/structured_logging/uncaught.js +58 -0
- package/dist/structured_logging.d.ts +48 -0
- package/dist/structured_logging.d.ts.map +1 -0
- package/dist/structured_logging.js +47 -0
- package/dist/tls_client.d.ts +61 -0
- package/dist/tls_client.d.ts.map +1 -0
- package/dist/tls_client.js +298 -0
- package/dist/tool_api_error.d.ts +62 -0
- package/dist/tool_api_error.d.ts.map +1 -0
- package/dist/tool_api_error.js +399 -0
- package/dist/tool_memory_ownership.d.ts +10 -0
- package/dist/tool_memory_ownership.d.ts.map +1 -0
- package/dist/tool_memory_ownership.js +36 -0
- package/dist/toolpod_handlers.d.ts +126 -0
- package/dist/toolpod_handlers.d.ts.map +1 -0
- package/dist/toolpod_handlers.js +1016 -0
- package/dist/tracing/exporters.d.ts +51 -0
- package/dist/tracing/exporters.d.ts.map +1 -0
- package/dist/tracing/exporters.js +327 -0
- package/dist/tracing/index.d.ts +3 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +2 -0
- package/dist/tracing/setup.d.ts +76 -0
- package/dist/tracing/setup.d.ts.map +1 -0
- package/dist/tracing/setup.js +436 -0
- package/dist/utils.d.ts +204 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +867 -0
- package/dist/workflow/activity.d.ts +71 -0
- package/dist/workflow/activity.d.ts.map +1 -0
- package/dist/workflow/activity.js +357 -0
- package/dist/workflow/attempt.d.ts +12 -0
- package/dist/workflow/attempt.d.ts.map +1 -0
- package/dist/workflow/attempt.js +96 -0
- package/dist/workflow/client.d.ts +46 -0
- package/dist/workflow/client.d.ts.map +1 -0
- package/dist/workflow/client.js +299 -0
- package/dist/workflow/context.d.ts +37 -0
- package/dist/workflow/context.d.ts.map +1 -0
- package/dist/workflow/context.js +350 -0
- package/dist/workflow/heartbeat.d.ts +15 -0
- package/dist/workflow/heartbeat.d.ts.map +1 -0
- package/dist/workflow/heartbeat.js +78 -0
- package/dist/workflow/index.d.ts +14 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/memory.d.ts +17 -0
- package/dist/workflow/memory.d.ts.map +1 -0
- package/dist/workflow/memory.js +184 -0
- package/package.json +73 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-neutral helpers for remote MCP tool discovery and execution.
|
|
3
|
+
*
|
|
4
|
+
* Port of `agent_engine_runner_shared/mcp_tools.py`. Built directly on
|
|
5
|
+
* `@modelcontextprotocol/sdk` (mirroring Python's `mcp` PyPI package) rather
|
|
6
|
+
* than a framework-specific adapter, since the platform needs custom result
|
|
7
|
+
* normalization, egress host derivation, and the Tool-Pod/AER dispatch split
|
|
8
|
+
* that a framework wrapper doesn't support.
|
|
9
|
+
*/
|
|
10
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
11
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
12
|
+
const UNSAFE_TOOL_NAME_CHARS_RE = /[^a-zA-Z0-9_]/g;
|
|
13
|
+
const LEADING_TRAILING_UNDERSCORES_RE = /^_+|_+$/g;
|
|
14
|
+
const MAX_LIST_TOOL_PAGES = 100;
|
|
15
|
+
const MAX_TOOLS_PER_SERVER = 10_000;
|
|
16
|
+
/** Raised when remote MCP configuration cannot be resolved. */
|
|
17
|
+
export class MCPConfigError extends Error {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "MCPConfigError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Raised when a remote MCP tool returns an MCP error result or a transport failure occurs. */
|
|
24
|
+
export class MCPToolError extends Error {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "MCPToolError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Return the server-prefixed SDK name for a remote MCP tool. */
|
|
31
|
+
export function makeMcpSdkToolName(serverName, toolName) {
|
|
32
|
+
const serverPart = sanitizeToolNamePart(serverName);
|
|
33
|
+
const toolPart = sanitizeToolNamePart(toolName);
|
|
34
|
+
return `${serverPart}__${toolPart}`;
|
|
35
|
+
}
|
|
36
|
+
// Provider names can contain punctuation that downstream LLM tool-call APIs
|
|
37
|
+
// reject, so the SDK exposes a stable identifier and keeps the original MCP
|
|
38
|
+
// tool name only for the outbound tools/call request.
|
|
39
|
+
function sanitizeToolNamePart(value) {
|
|
40
|
+
let sanitized = value
|
|
41
|
+
.trim()
|
|
42
|
+
.replace(UNSAFE_TOOL_NAME_CHARS_RE, "_")
|
|
43
|
+
.replace(LEADING_TRAILING_UNDERSCORES_RE, "");
|
|
44
|
+
if (sanitized === "") {
|
|
45
|
+
throw new MCPConfigError("mcp server and tool names must contain alphanumeric characters");
|
|
46
|
+
}
|
|
47
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
48
|
+
sanitized = `mcp_${sanitized}`;
|
|
49
|
+
}
|
|
50
|
+
return sanitized;
|
|
51
|
+
}
|
|
52
|
+
/** Resolve headers for a remote MCP server without exposing secret values in config. */
|
|
53
|
+
export function resolveMcpHeaders(serverName, config) {
|
|
54
|
+
const headers = { ...config.headers };
|
|
55
|
+
if (config.auth.type === "none" ||
|
|
56
|
+
config.auth.type === "oauth" ||
|
|
57
|
+
config.auth.type === "client_credentials") {
|
|
58
|
+
return headers;
|
|
59
|
+
}
|
|
60
|
+
const tokenEnv = config.auth.token_env;
|
|
61
|
+
if (tokenEnv === null) {
|
|
62
|
+
throw new MCPConfigError(`mcp server '${serverName}' auth.token_env is required`);
|
|
63
|
+
}
|
|
64
|
+
const token = process.env[tokenEnv];
|
|
65
|
+
if (token === undefined || token.trim() === "") {
|
|
66
|
+
throw new MCPConfigError(`mcp server '${serverName}' references missing env var ${tokenEnv}`);
|
|
67
|
+
}
|
|
68
|
+
headers["Authorization"] = `Bearer ${token.trim()}`;
|
|
69
|
+
return headers;
|
|
70
|
+
}
|
|
71
|
+
/** Resolve an MCP SDK OAuth provider for the configured auth mode, if any. */
|
|
72
|
+
export async function resolveMcpAuth(serverName, config) {
|
|
73
|
+
if (config.auth.type === "none" || config.auth.type === "bearer_env") {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const { makeMcpOauthAuth, makeMcpClientCredentialsAuth } = await import("./mcp_oauth.js");
|
|
77
|
+
try {
|
|
78
|
+
if (config.auth.type === "oauth") {
|
|
79
|
+
return makeMcpOauthAuth(serverName, config);
|
|
80
|
+
}
|
|
81
|
+
if (config.auth.type === "client_credentials") {
|
|
82
|
+
return makeMcpClientCredentialsAuth(serverName, config);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
throw new MCPConfigError(err instanceof Error ? err.message : String(err));
|
|
87
|
+
}
|
|
88
|
+
throw new MCPConfigError(`mcp server '${serverName}' has unsupported auth.type ${config.auth.type}`);
|
|
89
|
+
}
|
|
90
|
+
/** Return the outbound hosts needed to reach a configured MCP server. */
|
|
91
|
+
export function mcpServerNetworkHosts(config) {
|
|
92
|
+
const hosts = [new URL(config.url).hostname];
|
|
93
|
+
if (config.auth.token_url !== null) {
|
|
94
|
+
const tokenHost = new URL(config.auth.token_url).hostname;
|
|
95
|
+
if (!hosts.includes(tokenHost))
|
|
96
|
+
hosts.push(tokenHost);
|
|
97
|
+
}
|
|
98
|
+
return hosts;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Discover remote MCP tools for all configured servers.
|
|
102
|
+
*
|
|
103
|
+
* Mirrors common MCP client adapters: initialize each server, call
|
|
104
|
+
* `tools/list`, then expose the returned schemas as framework-native tools.
|
|
105
|
+
*/
|
|
106
|
+
export async function discoverMcpTools(config) {
|
|
107
|
+
const bindings = [];
|
|
108
|
+
const usedNames = new Map();
|
|
109
|
+
for (const [serverName, serverConfig] of Object.entries(config.servers)) {
|
|
110
|
+
let tools = await listServerTools(serverName, serverConfig);
|
|
111
|
+
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
112
|
+
const allowedTools = serverConfig.allowed_tools;
|
|
113
|
+
if (allowedTools !== null) {
|
|
114
|
+
const missing = allowedTools
|
|
115
|
+
.filter((name) => !availableToolNames.has(name))
|
|
116
|
+
.sort();
|
|
117
|
+
if (missing.length > 0) {
|
|
118
|
+
throw new MCPConfigError(`mcp server '${serverName}' did not expose configured allowed_tools: ${missing.join(", ")}`);
|
|
119
|
+
}
|
|
120
|
+
const allowedSet = new Set(allowedTools);
|
|
121
|
+
tools = tools.filter((tool) => allowedSet.has(tool.name));
|
|
122
|
+
}
|
|
123
|
+
for (const tool of tools) {
|
|
124
|
+
const sdkToolName = makeMcpSdkToolName(serverName, tool.name);
|
|
125
|
+
const previous = usedNames.get(sdkToolName);
|
|
126
|
+
if (previous !== undefined) {
|
|
127
|
+
throw new MCPConfigError(`mcp tool name collision for '${sdkToolName}': ${previous} and ${serverName}.${tool.name}`);
|
|
128
|
+
}
|
|
129
|
+
usedNames.set(sdkToolName, `${serverName}.${tool.name}`);
|
|
130
|
+
bindings.push({
|
|
131
|
+
serverName,
|
|
132
|
+
toolName: tool.name,
|
|
133
|
+
sdkToolName,
|
|
134
|
+
description: tool.description ?? "",
|
|
135
|
+
inputSchema: tool.inputSchema,
|
|
136
|
+
serverConfig,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return bindings;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Map an SDK-visible tool name back to configured MCP call metadata.
|
|
144
|
+
*
|
|
145
|
+
* AER discovers remote MCP schemas at startup and exposes server-prefixed
|
|
146
|
+
* names such as `github__search_issues` to the LLM. Tool Pods skip
|
|
147
|
+
* `tools/list` startup discovery, so call-time execution resolves that SDK
|
|
148
|
+
* name against `agent.yaml` and calls the original MCP tool name.
|
|
149
|
+
*/
|
|
150
|
+
export function resolveConfiguredMcpToolBinding(config, sdkToolName, mcpServerName, mcpToolName) {
|
|
151
|
+
const serverConfig = config.servers[mcpServerName];
|
|
152
|
+
if (serverConfig === undefined)
|
|
153
|
+
return null;
|
|
154
|
+
const expectedSdkToolName = makeMcpSdkToolName(mcpServerName, mcpToolName);
|
|
155
|
+
if (expectedSdkToolName !== sdkToolName) {
|
|
156
|
+
throw new MCPConfigError(`mcp call metadata for '${mcpServerName}'.'${mcpToolName}' does not match '${sdkToolName}'`);
|
|
157
|
+
}
|
|
158
|
+
if (serverConfig.allowed_tools !== null &&
|
|
159
|
+
!serverConfig.allowed_tools.includes(mcpToolName)) {
|
|
160
|
+
throw new MCPConfigError(`mcp server '${mcpServerName}' tool '${mcpToolName}' is not in allowed_tools`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
serverName: mcpServerName,
|
|
164
|
+
toolName: mcpToolName,
|
|
165
|
+
sdkToolName,
|
|
166
|
+
description: "",
|
|
167
|
+
inputSchema: {},
|
|
168
|
+
serverConfig,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** Return whether `sdkToolName` belongs to a configured MCP server. */
|
|
172
|
+
export function isConfiguredMcpSdkToolName(config, sdkToolName) {
|
|
173
|
+
for (const serverName of Object.keys(config.servers)) {
|
|
174
|
+
const serverPrefix = `${sanitizeToolNamePart(serverName)}__`;
|
|
175
|
+
if (sdkToolName.startsWith(serverPrefix) &&
|
|
176
|
+
sdkToolName.length > serverPrefix.length) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
/** Execute a remote MCP tool and normalize its result. */
|
|
183
|
+
export async function callMcpTool(binding, args) {
|
|
184
|
+
return withMcpSession(binding.serverName, binding.serverConfig, `tool '${binding.toolName}'`, async (client) => {
|
|
185
|
+
const result = await client.callTool({
|
|
186
|
+
name: binding.toolName,
|
|
187
|
+
arguments: args,
|
|
188
|
+
});
|
|
189
|
+
// `callTool()`'s return type also covers the deprecated `{ toolResult }`
|
|
190
|
+
// shape from pre-2025-06-18 servers; MCP tool servers we target return
|
|
191
|
+
// the standard `content`/`structuredContent`/`isError` shape.
|
|
192
|
+
return normalizeMcpToolResult(result);
|
|
193
|
+
}, MCPToolError);
|
|
194
|
+
}
|
|
195
|
+
/** Create the async callable used to invoke a discovered MCP tool. */
|
|
196
|
+
export function makeMcpToolCallable(binding) {
|
|
197
|
+
return (args) => callMcpTool(binding, args);
|
|
198
|
+
}
|
|
199
|
+
/** Convert an MCP `CallToolResult` into a JSON-safe result, raising on an error result. */
|
|
200
|
+
export function normalizeMcpToolResult(result) {
|
|
201
|
+
const content = result.content ?? [];
|
|
202
|
+
ensureJsonSafe("content", content);
|
|
203
|
+
const rawStructuredContent = result.structuredContent ?? null;
|
|
204
|
+
if (rawStructuredContent !== null) {
|
|
205
|
+
if (typeof rawStructuredContent !== "object" ||
|
|
206
|
+
Array.isArray(rawStructuredContent)) {
|
|
207
|
+
throw new MCPToolError("MCP tool returned structuredContent that is not an object");
|
|
208
|
+
}
|
|
209
|
+
ensureJsonSafe("structuredContent", rawStructuredContent);
|
|
210
|
+
}
|
|
211
|
+
const normalized = {
|
|
212
|
+
content,
|
|
213
|
+
structuredContent: rawStructuredContent,
|
|
214
|
+
isError: Boolean(result.isError),
|
|
215
|
+
};
|
|
216
|
+
if (result.isError) {
|
|
217
|
+
const textParts = [];
|
|
218
|
+
for (const block of content) {
|
|
219
|
+
if (block !== null && typeof block === "object") {
|
|
220
|
+
const b = block;
|
|
221
|
+
if (b["type"] === "text" &&
|
|
222
|
+
typeof b["text"] === "string" &&
|
|
223
|
+
b["text"]) {
|
|
224
|
+
textParts.push(b["text"]);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (textParts.length > 0) {
|
|
229
|
+
throw new MCPToolError(`MCP tool returned error: ${textParts.join("\n")}`);
|
|
230
|
+
}
|
|
231
|
+
throw new MCPToolError("MCP tool returned an error");
|
|
232
|
+
}
|
|
233
|
+
return normalized;
|
|
234
|
+
}
|
|
235
|
+
function ensureJsonSafe(fieldName, value) {
|
|
236
|
+
try {
|
|
237
|
+
JSON.stringify(value);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
throw new MCPToolError(`MCP tool returned non-JSON-serializable ${fieldName}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function listServerTools(serverName, config) {
|
|
244
|
+
return withMcpSession(serverName, config, "tools/list", async (client) => {
|
|
245
|
+
const tools = [];
|
|
246
|
+
let cursor;
|
|
247
|
+
for (let page = 0; page < MAX_LIST_TOOL_PAGES; page++) {
|
|
248
|
+
const result = await client.listTools({ cursor });
|
|
249
|
+
tools.push(...result.tools.map((tool) => ({
|
|
250
|
+
name: tool.name,
|
|
251
|
+
description: tool.description,
|
|
252
|
+
inputSchema: tool.inputSchema,
|
|
253
|
+
})));
|
|
254
|
+
if (tools.length > MAX_TOOLS_PER_SERVER) {
|
|
255
|
+
throw new MCPConfigError(`mcp server '${serverName}' returned more than ${MAX_TOOLS_PER_SERVER} tools`);
|
|
256
|
+
}
|
|
257
|
+
cursor = result.nextCursor;
|
|
258
|
+
if (cursor === undefined)
|
|
259
|
+
return tools;
|
|
260
|
+
}
|
|
261
|
+
throw new MCPConfigError(`mcp server '${serverName}' tools/list exceeded ${MAX_LIST_TOOL_PAGES} pages`);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async function withMcpSession(serverName, config, operation, fn,
|
|
265
|
+
// Discovery (tools/list) failures are config-adjacent — they happen once at
|
|
266
|
+
// startup against a server the tenant configured — so they wrap as
|
|
267
|
+
// MCPConfigError. Invocation (tools/call) failures are per-call runtime
|
|
268
|
+
// errors and wrap as MCPToolError, matching its docstring ("...or a
|
|
269
|
+
// transport failure occurs") and Python's mcp_tools.py split between
|
|
270
|
+
// _list_server_tools (MCPConfigError) and _call_mcp_tool (MCPToolError).
|
|
271
|
+
transportErrorClass = MCPConfigError) {
|
|
272
|
+
const headers = resolveMcpHeaders(serverName, config);
|
|
273
|
+
const authProvider = await resolveMcpAuth(serverName, config);
|
|
274
|
+
const transport = new StreamableHTTPClientTransport(new URL(config.url), {
|
|
275
|
+
requestInit: {
|
|
276
|
+
headers,
|
|
277
|
+
signal: AbortSignal.timeout(config.timeout_seconds * 1000),
|
|
278
|
+
},
|
|
279
|
+
authProvider,
|
|
280
|
+
});
|
|
281
|
+
const client = new Client({
|
|
282
|
+
name: "agent-engine-runner",
|
|
283
|
+
version: "1.0.0",
|
|
284
|
+
});
|
|
285
|
+
try {
|
|
286
|
+
await client.connect(transport);
|
|
287
|
+
return await fn(client);
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
if (err instanceof MCPConfigError || err instanceof MCPToolError)
|
|
291
|
+
throw err;
|
|
292
|
+
throw new transportErrorClass(mcpTransportErrorMessage(serverName, operation, err));
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
await client.close().catch(() => { });
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function mcpTransportErrorMessage(serverName, operation, err) {
|
|
299
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
300
|
+
return `mcp server '${serverName}' ${operation} failed: ${message}`;
|
|
301
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-bound memory adapters for the platform runtime.
|
|
3
|
+
*
|
|
4
|
+
* These let the unified `Memory` facade from `@mongodb-js/agent-engine-sdk-memory`
|
|
5
|
+
* run in app-bound mode (inside an agent, on the platform stack). App-bound memory
|
|
6
|
+
* routes through the Orchestration Engine's memory proxy, which serves the aliased
|
|
7
|
+
* memory routes (`/api/v1/memory/{turns,context,search}` plus the CRUD paths) and
|
|
8
|
+
* stamps org/project from the trusted execution context.
|
|
9
|
+
*
|
|
10
|
+
* So the adapters are thin: each call reads the current request context
|
|
11
|
+
* (`OE_URL`, execution id, user id, session id), builds a `MemoryClientAdapter`
|
|
12
|
+
* pointed at the OE with mTLS and the execution-id header, and delegates. Identity
|
|
13
|
+
* is ambient — `requestContext()` exposes the per-request user/session so the
|
|
14
|
+
* facade resolves them without the agent author threading them through.
|
|
15
|
+
*/
|
|
16
|
+
import { type ContextResponse, type CreateEpisodicResult, type CreateProceduralResult, type CreateSemanticResult, type CreateTaxonomicResult, type CustomMemoryRetrieveResult, type CustomMemorySaveResult, type MemoryChunk, type MemoryCrudClient, type MemoryRequestContext, type MemoryRuntime, type WriteTurnResult } from "@mongodb-js/agent-engine-sdk-memory";
|
|
17
|
+
/** `MemoryRuntime` over the OE memory proxy, exposing ambient identity. */
|
|
18
|
+
export declare class AppBoundRuntime implements MemoryRuntime {
|
|
19
|
+
/** Fresh identity from the runner context; blank fields are normalized by the facade. */
|
|
20
|
+
requestContext(): MemoryRequestContext | null;
|
|
21
|
+
recordTurn(args: Parameters<MemoryRuntime["recordTurn"]>[0]): Promise<WriteTurnResult>;
|
|
22
|
+
buildContext(args: Parameters<MemoryRuntime["buildContext"]>[0]): Promise<ContextResponse>;
|
|
23
|
+
searchSemantic(args: Parameters<MemoryRuntime["searchSemantic"]>[0]): Promise<MemoryChunk[]>;
|
|
24
|
+
searchEpisodes(args: Parameters<MemoryRuntime["searchEpisodes"]>[0]): Promise<MemoryChunk[]>;
|
|
25
|
+
searchTaxonomic(args: Parameters<MemoryRuntime["searchTaxonomic"]>[0]): Promise<MemoryChunk[]>;
|
|
26
|
+
discoverProcedures(args: Parameters<MemoryRuntime["discoverProcedures"]>[0]): Promise<Array<Record<string, unknown>>>;
|
|
27
|
+
}
|
|
28
|
+
/** `MemoryCrudClient` over the OE memory proxy. */
|
|
29
|
+
export declare class AppBoundCrudClient implements MemoryCrudClient {
|
|
30
|
+
createSemantic(args: Parameters<MemoryCrudClient["createSemantic"]>[0]): Promise<CreateSemanticResult>;
|
|
31
|
+
getSemantic(args: Parameters<MemoryCrudClient["getSemantic"]>[0]): Promise<unknown | null>;
|
|
32
|
+
createEpisodic(args: Parameters<MemoryCrudClient["createEpisodic"]>[0]): Promise<CreateEpisodicResult>;
|
|
33
|
+
listEpisodic(args: Parameters<MemoryCrudClient["listEpisodic"]>[0]): Promise<unknown[]>;
|
|
34
|
+
createTaxonomic(args: Parameters<MemoryCrudClient["createTaxonomic"]>[0]): Promise<CreateTaxonomicResult>;
|
|
35
|
+
getTaxonomic(args: Parameters<MemoryCrudClient["getTaxonomic"]>[0]): Promise<unknown | null>;
|
|
36
|
+
getDistinctDomains(args: Parameters<MemoryCrudClient["getDistinctDomains"]>[0]): Promise<string[]>;
|
|
37
|
+
createProcedural(args: Parameters<MemoryCrudClient["createProcedural"]>[0]): Promise<CreateProceduralResult>;
|
|
38
|
+
getProcedural(args: Parameters<MemoryCrudClient["getProcedural"]>[0]): Promise<unknown | null>;
|
|
39
|
+
createCustom(args: Parameters<MemoryCrudClient["createCustom"]>[0]): Promise<CustomMemorySaveResult>;
|
|
40
|
+
retrieveCustom(args: Parameters<MemoryCrudClient["retrieveCustom"]>[0]): Promise<CustomMemoryRetrieveResult>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=memory_appbound.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory_appbound.d.ts","sourceRoot":"","sources":["../src/memory_appbound.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-bound memory adapters for the platform runtime.
|
|
3
|
+
*
|
|
4
|
+
* These let the unified `Memory` facade from `@mongodb-js/agent-engine-sdk-memory`
|
|
5
|
+
* run in app-bound mode (inside an agent, on the platform stack). App-bound memory
|
|
6
|
+
* routes through the Orchestration Engine's memory proxy, which serves the aliased
|
|
7
|
+
* memory routes (`/api/v1/memory/{turns,context,search}` plus the CRUD paths) and
|
|
8
|
+
* stamps org/project from the trusted execution context.
|
|
9
|
+
*
|
|
10
|
+
* So the adapters are thin: each call reads the current request context
|
|
11
|
+
* (`OE_URL`, execution id, user id, session id), builds a `MemoryClientAdapter`
|
|
12
|
+
* pointed at the OE with mTLS and the execution-id header, and delegates. Identity
|
|
13
|
+
* is ambient — `requestContext()` exposes the per-request user/session so the
|
|
14
|
+
* facade resolves them without the agent author threading them through.
|
|
15
|
+
*/
|
|
16
|
+
import { MemoryClientAdapter, MemoryNotSupportedError, ContextResponseSchema, } from "@mongodb-js/agent-engine-sdk-memory";
|
|
17
|
+
import { getCurrentExecutionId, getCurrentOeUrl, getCurrentSessionId, getCurrentUserId, getCurrentWorkspaceId, } from "./context.js";
|
|
18
|
+
import { fetchPlatform, getFetchOptionsWithTLS } from "./tls_client.js";
|
|
19
|
+
import { isMemoryReadOwnedByTool } from "./tool_memory_ownership.js";
|
|
20
|
+
import { ActivityKind, WorkflowClient, allocateActivityOrdinal, currentAttemptContext, runSerialActivity, } from "./workflow/index.js";
|
|
21
|
+
const EXECUTION_ID_HEADER = "X-Agent-Engine-Execution-Id";
|
|
22
|
+
/** Legacy name, dual-sent during the rename transition; servers prefer EXECUTION_ID_HEADER. */
|
|
23
|
+
const EXECUTION_ID_HEADER_LEGACY = "X-Agentic-Execution-Id";
|
|
24
|
+
const AGENT_ID_HEADER = "X-Agent-Engine-Agent-Id";
|
|
25
|
+
const AGENT_ID_HEADER_LEGACY = "X-Agentic-Agent-Id";
|
|
26
|
+
/** The OE memory proxy serves the flat memory routes under this prefix. */
|
|
27
|
+
const OE_MEMORY_PREFIX = "/api/v1/memory";
|
|
28
|
+
/**
|
|
29
|
+
* Build a `MemoryClientAdapter` bound to the current request context.
|
|
30
|
+
*
|
|
31
|
+
* Reads `OE_URL` fresh per call because `app.memory` is a long-lived singleton
|
|
32
|
+
* over per-request context. mTLS options and the execution-id header are layered
|
|
33
|
+
* in so the OE can authenticate the connection and attribute the call.
|
|
34
|
+
*/
|
|
35
|
+
function adapterFromContext() {
|
|
36
|
+
const oeUrl = getCurrentOeUrl();
|
|
37
|
+
if (oeUrl === null || oeUrl.trim() === "") {
|
|
38
|
+
throw new MemoryNotSupportedError("app-bound memory is unavailable: no OE_URL in the current execution " +
|
|
39
|
+
"context (memory is only reachable while handling a platform request)");
|
|
40
|
+
}
|
|
41
|
+
const executionId = getCurrentExecutionId();
|
|
42
|
+
const headers = {};
|
|
43
|
+
if (executionId !== null && executionId !== "") {
|
|
44
|
+
headers[EXECUTION_ID_HEADER] = executionId;
|
|
45
|
+
headers[EXECUTION_ID_HEADER_LEGACY] = executionId;
|
|
46
|
+
}
|
|
47
|
+
const workspaceId = getCurrentWorkspaceId();
|
|
48
|
+
if (workspaceId !== null && workspaceId !== "") {
|
|
49
|
+
headers[AGENT_ID_HEADER] = workspaceId;
|
|
50
|
+
headers[AGENT_ID_HEADER_LEGACY] = workspaceId;
|
|
51
|
+
}
|
|
52
|
+
return new MemoryClientAdapter({
|
|
53
|
+
baseUrl: oeUrl,
|
|
54
|
+
apiPrefix: OE_MEMORY_PREFIX,
|
|
55
|
+
routeStyle: "aliased",
|
|
56
|
+
projectScoped: false,
|
|
57
|
+
headers,
|
|
58
|
+
fetchImpl: fetchPlatform,
|
|
59
|
+
requestExtras: () => getFetchOptionsWithTLS(oeUrl) ?? {},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/** Canonical JSON input used to identify a durable context read. */
|
|
63
|
+
function buildContextActivityInput(args) {
|
|
64
|
+
const input = {
|
|
65
|
+
query: args.query,
|
|
66
|
+
user_id: args.userId ?? null,
|
|
67
|
+
session_id: args.sessionId ?? null,
|
|
68
|
+
visibility: args.visibility ?? null,
|
|
69
|
+
metadata_filter: args.metadataFilter ?? null,
|
|
70
|
+
enabled_sources: args.enabledSources == null ? null : [...args.enabledSources].sort(),
|
|
71
|
+
};
|
|
72
|
+
if (args.topK !== undefined)
|
|
73
|
+
input["top_k"] = args.topK;
|
|
74
|
+
if (args.maxTokens !== undefined)
|
|
75
|
+
input["max_tokens"] = args.maxTokens;
|
|
76
|
+
return input;
|
|
77
|
+
}
|
|
78
|
+
async function runBuildContextActivity(args, execute) {
|
|
79
|
+
if (currentAttemptContext() === null || isMemoryReadOwnedByTool()) {
|
|
80
|
+
return execute();
|
|
81
|
+
}
|
|
82
|
+
const oeUrl = getCurrentOeUrl();
|
|
83
|
+
if (oeUrl === null || oeUrl.trim() === "") {
|
|
84
|
+
throw new MemoryNotSupportedError("durable app-bound context reads require OE_URL in the current execution context");
|
|
85
|
+
}
|
|
86
|
+
const result = await runSerialActivity({
|
|
87
|
+
client: new WorkflowClient(oeUrl),
|
|
88
|
+
kind: ActivityKind.MEMORY,
|
|
89
|
+
name: "memory.build_context",
|
|
90
|
+
activityOrdinal: allocateActivityOrdinal(),
|
|
91
|
+
semanticInput: buildContextActivityInput(args),
|
|
92
|
+
execute,
|
|
93
|
+
});
|
|
94
|
+
return ContextResponseSchema.parse(result);
|
|
95
|
+
}
|
|
96
|
+
/** `MemoryRuntime` over the OE memory proxy, exposing ambient identity. */
|
|
97
|
+
export class AppBoundRuntime {
|
|
98
|
+
/** Fresh identity from the runner context; blank fields are normalized by the facade. */
|
|
99
|
+
requestContext() {
|
|
100
|
+
return {
|
|
101
|
+
userId: getCurrentUserId(),
|
|
102
|
+
sessionId: getCurrentSessionId(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async recordTurn(args) {
|
|
106
|
+
return adapterFromContext().recordTurn(args);
|
|
107
|
+
}
|
|
108
|
+
async buildContext(args) {
|
|
109
|
+
return runBuildContextActivity(args, () => adapterFromContext().buildContext(args));
|
|
110
|
+
}
|
|
111
|
+
async searchSemantic(args) {
|
|
112
|
+
return adapterFromContext().searchSemantic(args);
|
|
113
|
+
}
|
|
114
|
+
async searchEpisodes(args) {
|
|
115
|
+
return adapterFromContext().searchEpisodes(args);
|
|
116
|
+
}
|
|
117
|
+
async searchTaxonomic(args) {
|
|
118
|
+
return adapterFromContext().searchTaxonomic(args);
|
|
119
|
+
}
|
|
120
|
+
async discoverProcedures(args) {
|
|
121
|
+
return adapterFromContext().discoverProcedures(args);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** `MemoryCrudClient` over the OE memory proxy. */
|
|
125
|
+
export class AppBoundCrudClient {
|
|
126
|
+
async createSemantic(args) {
|
|
127
|
+
return adapterFromContext().createSemantic(args);
|
|
128
|
+
}
|
|
129
|
+
async getSemantic(args) {
|
|
130
|
+
return adapterFromContext().getSemantic(args);
|
|
131
|
+
}
|
|
132
|
+
async createEpisodic(args) {
|
|
133
|
+
return adapterFromContext().createEpisodic(args);
|
|
134
|
+
}
|
|
135
|
+
async listEpisodic(args) {
|
|
136
|
+
return adapterFromContext().listEpisodic(args);
|
|
137
|
+
}
|
|
138
|
+
async createTaxonomic(args) {
|
|
139
|
+
return adapterFromContext().createTaxonomic(args);
|
|
140
|
+
}
|
|
141
|
+
async getTaxonomic(args) {
|
|
142
|
+
return adapterFromContext().getTaxonomic(args);
|
|
143
|
+
}
|
|
144
|
+
async getDistinctDomains(args) {
|
|
145
|
+
return adapterFromContext().getDistinctDomains(args);
|
|
146
|
+
}
|
|
147
|
+
async createProcedural(args) {
|
|
148
|
+
return adapterFromContext().createProcedural(args);
|
|
149
|
+
}
|
|
150
|
+
async getProcedural(args) {
|
|
151
|
+
return adapterFromContext().getProcedural(args);
|
|
152
|
+
}
|
|
153
|
+
async createCustom(args) {
|
|
154
|
+
return adapterFromContext().createCustom(args);
|
|
155
|
+
}
|
|
156
|
+
async retrieveCustom(args) {
|
|
157
|
+
return adapterFromContext().retrieveCustom(args);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Native-checkpoint conversation-turn ingestion for the TypeScript runner. */
|
|
2
|
+
import type { Message } from "@mongodb-js/agent-engine-sdk";
|
|
3
|
+
import type { MemoryRuntime } from "@mongodb-js/agent-engine-sdk-memory";
|
|
4
|
+
type RecordTurnArgs = Parameters<MemoryRuntime["recordTurn"]>[0];
|
|
5
|
+
export interface WriteTurnArgs {
|
|
6
|
+
message: string;
|
|
7
|
+
resultMessages: readonly Message[];
|
|
8
|
+
userId?: string | null;
|
|
9
|
+
sessionId?: string | null;
|
|
10
|
+
includeUserTurn?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface TurnMemoryWriter {
|
|
13
|
+
readonly pendingWrites: number;
|
|
14
|
+
writeTurnAsync(args: WriteTurnArgs): void;
|
|
15
|
+
drain(timeoutMs?: number): Promise<boolean>;
|
|
16
|
+
shutdown(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract only the current turn from framework messages.
|
|
20
|
+
*
|
|
21
|
+
* The original user prompt is input, so many LangGraph update streams never
|
|
22
|
+
* emit it. Prepend it explicitly, then skip through an echoed copy when one is
|
|
23
|
+
* present so prior checkpoint history and the current prompt are not written
|
|
24
|
+
* twice. Resume legs suppress every user message because they carry no new
|
|
25
|
+
* user prompt.
|
|
26
|
+
*/
|
|
27
|
+
export declare function extractTurnMessages(message: string, resultMessages: readonly Message[], includeUserTurn?: boolean): RecordTurnArgs[];
|
|
28
|
+
/**
|
|
29
|
+
* Process-wide, non-blocking turn writer.
|
|
30
|
+
*
|
|
31
|
+
* Batches are serialized so concurrent executions cannot interleave messages
|
|
32
|
+
* within a conversation turn. Failures are logged and swallowed: Memory is a
|
|
33
|
+
* best-effort side effect and must not replace an otherwise successful agent
|
|
34
|
+
* result. `drain` lets session release and graceful app replacement wait for
|
|
35
|
+
* already-queued writes.
|
|
36
|
+
*/
|
|
37
|
+
export declare class MemoryWriter implements TurnMemoryWriter {
|
|
38
|
+
private readonly runtime;
|
|
39
|
+
private tail;
|
|
40
|
+
private pending;
|
|
41
|
+
private closed;
|
|
42
|
+
constructor(runtime: Pick<MemoryRuntime, "recordTurn">);
|
|
43
|
+
get pendingWrites(): number;
|
|
44
|
+
writeTurnAsync(args: WriteTurnArgs): void;
|
|
45
|
+
drain(timeoutMs?: number): Promise<boolean>;
|
|
46
|
+
shutdown(): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=memory_writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory_writer.d.ts","sourceRoot":"","sources":["../src/memory_writer.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAI/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAOzE,KAAK,cAAc,GAAG,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,SAAS,OAAO,EAAE,EAClC,eAAe,UAAO,GACrB,cAAc,EAAE,CAwDlB;AAgDD;;;;;;;;GAQG;AACH,qBAAa,YAAa,YAAW,gBAAgB;IAKvC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,MAAM,CAAS;gBAEM,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC;IAEvE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAkBnC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB3C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAQhC"}
|