veryfront 0.1.144 → 0.1.145
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/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui-handler.d.ts +77 -0
- package/esm/src/agent/ag-ui-handler.d.ts.map +1 -0
- package/esm/src/agent/ag-ui-handler.js +331 -0
- package/esm/src/agent/index.d.ts +2 -1
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +2 -1
- package/esm/src/agent/runtime/index.d.ts +2 -0
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +15 -7
- package/esm/src/agent/runtime/resume-session.d.ts +61 -0
- package/esm/src/agent/runtime/resume-session.d.ts.map +1 -0
- package/esm/src/agent/runtime/resume-session.js +232 -0
- package/esm/src/agent/runtime/tool-helpers.d.ts +4 -2
- package/esm/src/agent/runtime/tool-helpers.d.ts.map +1 -1
- package/esm/src/agent/runtime/tool-helpers.js +57 -4
- package/esm/src/agent/types.d.ts +2 -1
- package/esm/src/agent/types.d.ts.map +1 -1
- package/esm/src/internal-agents/session-manager.d.ts +8 -24
- package/esm/src/internal-agents/session-manager.d.ts.map +1 -1
- package/esm/src/internal-agents/session-manager.js +55 -178
- package/esm/src/mcp/index.d.ts +2 -0
- package/esm/src/mcp/index.d.ts.map +1 -1
- package/esm/src/mcp/index.js +2 -0
- package/esm/src/mcp/server.d.ts +1 -0
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +47 -8
- package/esm/src/mcp/session.d.ts +9 -0
- package/esm/src/mcp/session.d.ts.map +1 -0
- package/esm/src/mcp/session.js +25 -0
- package/esm/src/mcp/sse.d.ts +8 -0
- package/esm/src/mcp/sse.d.ts.map +1 -0
- package/esm/src/mcp/sse.js +17 -0
- package/esm/src/platform/cloud/resolver.d.ts.map +1 -1
- package/esm/src/platform/cloud/resolver.js +13 -3
- package/esm/src/provider/index.d.ts +2 -0
- package/esm/src/provider/index.d.ts.map +1 -1
- package/esm/src/provider/index.js +1 -0
- package/esm/src/provider/veryfront-cloud/context.d.ts +10 -0
- package/esm/src/provider/veryfront-cloud/context.d.ts.map +1 -0
- package/esm/src/provider/veryfront-cloud/context.js +11 -0
- package/esm/src/tool/index.d.ts +3 -1
- package/esm/src/tool/index.d.ts.map +1 -1
- package/esm/src/tool/index.js +1 -0
- package/esm/src/tool/remote-mcp.d.ts +14 -0
- package/esm/src/tool/remote-mcp.d.ts.map +1 -0
- package/esm/src/tool/remote-mcp.js +176 -0
- package/esm/src/tool/types.d.ts +12 -0
- package/esm/src/tool/types.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/agent/ag-ui-handler.ts +451 -0
- package/src/src/agent/index.ts +21 -1
- package/src/src/agent/runtime/index.ts +28 -3
- package/src/src/agent/runtime/resume-session.ts +319 -0
- package/src/src/agent/runtime/tool-helpers.ts +89 -6
- package/src/src/agent/types.ts +2 -1
- package/src/src/internal-agents/session-manager.ts +69 -243
- package/src/src/mcp/index.ts +3 -0
- package/src/src/mcp/server.ts +54 -9
- package/src/src/mcp/session.ts +31 -0
- package/src/src/mcp/sse.ts +19 -0
- package/src/src/platform/cloud/resolver.ts +15 -3
- package/src/src/provider/index.ts +5 -0
- package/src/src/provider/veryfront-cloud/context.ts +28 -0
- package/src/src/tool/index.ts +9 -1
- package/src/src/tool/remote-mcp.ts +261 -0
- package/src/src/tool/types.ts +17 -0
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import type { ToolAnnotations } from "../mcp/types.js";
|
|
3
|
+
import type { JsonSchema } from "./schema/json-schema.js";
|
|
4
|
+
import type { RemoteToolSource, ToolDefinition, ToolExecutionContext } from "./types.js";
|
|
5
|
+
|
|
6
|
+
type ResolvableValue<T> = T | ((context?: ToolExecutionContext) => T | Promise<T>);
|
|
7
|
+
|
|
8
|
+
export interface RemoteMCPToolSourceConfig {
|
|
9
|
+
id?: string;
|
|
10
|
+
endpoint: ResolvableValue<string>;
|
|
11
|
+
headers?: ResolvableValue<dntShim.HeadersInit | undefined>;
|
|
12
|
+
fetch?: typeof dntShim.fetch;
|
|
13
|
+
listMethod?: string;
|
|
14
|
+
callMethod?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface JsonRpcErrorObject {
|
|
18
|
+
message?: unknown;
|
|
19
|
+
data?: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface JsonRpcCallToolContentItem {
|
|
23
|
+
text?: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
27
|
+
return typeof value === "object" && value !== null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isResolver<T>(
|
|
31
|
+
value: ResolvableValue<T>,
|
|
32
|
+
): value is (context?: ToolExecutionContext) => T | Promise<T> {
|
|
33
|
+
return typeof value === "function";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isToolAnnotations(value: unknown): value is ToolAnnotations {
|
|
37
|
+
if (!isRecord(value)) return false;
|
|
38
|
+
|
|
39
|
+
for (const key of Object.keys(value)) {
|
|
40
|
+
if (
|
|
41
|
+
key !== "readOnlyHint" &&
|
|
42
|
+
key !== "destructiveHint" &&
|
|
43
|
+
key !== "idempotentHint" &&
|
|
44
|
+
key !== "openWorldHint"
|
|
45
|
+
) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const entry = value[key];
|
|
50
|
+
if (entry !== undefined && typeof entry !== "boolean") {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function normalizeParameters(inputSchema: unknown): JsonSchema {
|
|
59
|
+
if (!isRecord(inputSchema) || Object.keys(inputSchema).length === 0) {
|
|
60
|
+
return { type: "object", properties: {} };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return inputSchema as JsonSchema;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function normalizeToolDefinitions(result: unknown): ToolDefinition[] {
|
|
67
|
+
if (!isRecord(result)) return [];
|
|
68
|
+
const rawTools = result.tools;
|
|
69
|
+
if (!Array.isArray(rawTools)) return [];
|
|
70
|
+
|
|
71
|
+
const definitions: ToolDefinition[] = [];
|
|
72
|
+
for (const entry of rawTools) {
|
|
73
|
+
if (!isRecord(entry)) continue;
|
|
74
|
+
if (typeof entry.name !== "string" || entry.name.length === 0) continue;
|
|
75
|
+
if (typeof entry.description !== "string") continue;
|
|
76
|
+
|
|
77
|
+
const definition: ToolDefinition = {
|
|
78
|
+
name: entry.name,
|
|
79
|
+
description: entry.description,
|
|
80
|
+
parameters: normalizeParameters(entry.inputSchema),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (typeof entry.title === "string" && entry.title.length > 0) {
|
|
84
|
+
definition.title = entry.title;
|
|
85
|
+
}
|
|
86
|
+
if (isToolAnnotations(entry.annotations)) {
|
|
87
|
+
definition.annotations = entry.annotations;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
definitions.push(definition);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return definitions;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function joinCallToolText(content: JsonRpcCallToolContentItem[]): string {
|
|
97
|
+
return content
|
|
98
|
+
.map((item) => (typeof item.text === "string" ? item.text : ""))
|
|
99
|
+
.filter((item) => item.length > 0)
|
|
100
|
+
.join("\n");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function parseJsonText(text: string): unknown | undefined {
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(text);
|
|
106
|
+
} catch {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function extractJsonRpcErrorMessage(payload: Record<string, unknown>): string {
|
|
112
|
+
const rawError = payload.error;
|
|
113
|
+
if (!isRecord(rawError)) return "Remote MCP server returned an error";
|
|
114
|
+
|
|
115
|
+
const errorObject = rawError as JsonRpcErrorObject;
|
|
116
|
+
if (typeof errorObject.message === "string" && errorObject.message.length > 0) {
|
|
117
|
+
return errorObject.message;
|
|
118
|
+
}
|
|
119
|
+
if (typeof errorObject.data === "string" && errorObject.data.length > 0) {
|
|
120
|
+
return errorObject.data;
|
|
121
|
+
}
|
|
122
|
+
if (isRecord(errorObject.data) && typeof errorObject.data.detail === "string") {
|
|
123
|
+
return errorObject.data.detail;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return "Remote MCP server returned an error";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function resolveValue<T>(
|
|
130
|
+
value: ResolvableValue<T>,
|
|
131
|
+
context?: ToolExecutionContext,
|
|
132
|
+
): Promise<T> {
|
|
133
|
+
if (isResolver(value)) {
|
|
134
|
+
return await value(context);
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function resolveHeaders(
|
|
140
|
+
headers: ResolvableValue<dntShim.HeadersInit | undefined> | undefined,
|
|
141
|
+
context?: ToolExecutionContext,
|
|
142
|
+
): Promise<dntShim.Headers> {
|
|
143
|
+
const resolvedHeaders = headers ? await resolveValue(headers, context) : undefined;
|
|
144
|
+
const finalHeaders = new dntShim.Headers(resolvedHeaders);
|
|
145
|
+
finalHeaders.set("Content-Type", "application/json");
|
|
146
|
+
return finalHeaders;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function postJsonRpc(
|
|
150
|
+
endpoint: string,
|
|
151
|
+
headers: dntShim.Headers,
|
|
152
|
+
body: Record<string, unknown>,
|
|
153
|
+
fetchImpl: typeof dntShim.fetch,
|
|
154
|
+
): Promise<unknown> {
|
|
155
|
+
const response = await fetchImpl(endpoint, {
|
|
156
|
+
method: "POST",
|
|
157
|
+
headers,
|
|
158
|
+
body: JSON.stringify(body),
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const detail = await response.text();
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Remote MCP request failed (${response.status})${detail ? `: ${detail}` : ""}`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return await response.json();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getJsonRpcResult(payload: unknown): unknown {
|
|
172
|
+
if (!isRecord(payload)) {
|
|
173
|
+
throw new Error("Remote MCP response was not a JSON object");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if ("error" in payload) {
|
|
177
|
+
throw new Error(extractJsonRpcErrorMessage(payload));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!("result" in payload)) {
|
|
181
|
+
throw new Error("Remote MCP response did not include a result");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return payload.result;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function normalizeCallToolResult(result: unknown): unknown {
|
|
188
|
+
if (!isRecord(result)) return result;
|
|
189
|
+
|
|
190
|
+
const rawContent = result.content;
|
|
191
|
+
if (Array.isArray(rawContent)) {
|
|
192
|
+
const text = joinCallToolText(
|
|
193
|
+
rawContent.filter((item): item is JsonRpcCallToolContentItem => isRecord(item)),
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (result.isError === true) {
|
|
197
|
+
return parseJsonText(text) ?? { error: "tool_error", message: text };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if ("structuredContent" in result) {
|
|
201
|
+
return result.structuredContent;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return parseJsonText(text) ?? text;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if ("structuredContent" in result) {
|
|
208
|
+
return result.structuredContent;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function createRemoteMCPToolSource(
|
|
215
|
+
config: RemoteMCPToolSourceConfig,
|
|
216
|
+
): RemoteToolSource {
|
|
217
|
+
const id = config.id ?? "remote-mcp";
|
|
218
|
+
const listMethod = config.listMethod ?? "tools/list";
|
|
219
|
+
const callMethod = config.callMethod ?? "tools/call";
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
id,
|
|
223
|
+
async listTools(context) {
|
|
224
|
+
const endpoint = await resolveValue(config.endpoint, context);
|
|
225
|
+
const headers = await resolveHeaders(config.headers, context);
|
|
226
|
+
const payload = await postJsonRpc(
|
|
227
|
+
endpoint,
|
|
228
|
+
headers,
|
|
229
|
+
{
|
|
230
|
+
jsonrpc: "2.0",
|
|
231
|
+
id: `${id}:tools:list`,
|
|
232
|
+
method: listMethod,
|
|
233
|
+
},
|
|
234
|
+
config.fetch ?? dntShim.dntGlobalThis.fetch,
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
return normalizeToolDefinitions(getJsonRpcResult(payload));
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
async executeTool(toolName, args, context) {
|
|
241
|
+
const endpoint = await resolveValue(config.endpoint, context);
|
|
242
|
+
const headers = await resolveHeaders(config.headers, context);
|
|
243
|
+
const payload = await postJsonRpc(
|
|
244
|
+
endpoint,
|
|
245
|
+
headers,
|
|
246
|
+
{
|
|
247
|
+
jsonrpc: "2.0",
|
|
248
|
+
id: `${id}:tools:call:${toolName}`,
|
|
249
|
+
method: callMethod,
|
|
250
|
+
params: {
|
|
251
|
+
name: toolName,
|
|
252
|
+
arguments: args,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
config.fetch ?? dntShim.dntGlobalThis.fetch,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
return normalizeCallToolResult(getJsonRpcResult(payload));
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
package/src/src/tool/types.ts
CHANGED
|
@@ -119,4 +119,21 @@ export interface ToolDefinition {
|
|
|
119
119
|
name: string;
|
|
120
120
|
description: string;
|
|
121
121
|
parameters: JsonSchema;
|
|
122
|
+
title?: string;
|
|
123
|
+
annotations?: ToolAnnotations;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Remote tool source loaded dynamically at runtime.
|
|
128
|
+
* Hosts can provide these to expose tools from remote MCP-compatible systems
|
|
129
|
+
* without registering those tools globally inside the framework.
|
|
130
|
+
*/
|
|
131
|
+
export interface RemoteToolSource {
|
|
132
|
+
id: string;
|
|
133
|
+
listTools(context?: ToolExecutionContext): Promise<ToolDefinition[]>;
|
|
134
|
+
executeTool(
|
|
135
|
+
toolName: string,
|
|
136
|
+
args: Record<string, unknown>,
|
|
137
|
+
context?: ToolExecutionContext,
|
|
138
|
+
): Promise<unknown>;
|
|
122
139
|
}
|