linkque-cli-v2 1.0.7 → 1.1.1
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/linkquejs.js +53 -46
- package/package.json +1 -1
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/{chunk-FJ2BZPIM.js → chunk-TM6MTGSL.js} +269 -89
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/handler/chat.js +77 -10
- package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/protocol.js +1 -1
- package/worker.js +438 -127
package/vendor/linkque-agent-appwrite-integrate/dist/esm/{chunk-FJ2BZPIM.js → chunk-TM6MTGSL.js}
RENAMED
|
@@ -1385,7 +1385,7 @@ var require_errors = __commonJS({
|
|
|
1385
1385
|
message: ({ keyword }) => (0, codegen_1.str)`must pass "${keyword}" keyword validation`
|
|
1386
1386
|
};
|
|
1387
1387
|
exports.keyword$DataError = {
|
|
1388
|
-
message: ({ keyword, schemaType }) =>
|
|
1388
|
+
message: ({ keyword, schemaType: schemaType2 }) => schemaType2 ? (0, codegen_1.str)`"${keyword}" keyword must be ${schemaType2} ($data)` : (0, codegen_1.str)`"${keyword}" keyword is invalid ($data)`
|
|
1389
1389
|
};
|
|
1390
1390
|
function reportError(cxt, error = exports.keywordError, errorPaths, overrideAllErrors) {
|
|
1391
1391
|
const { it } = cxt;
|
|
@@ -2044,8 +2044,8 @@ var require_keyword = __commonJS({
|
|
|
2044
2044
|
throw new Error(`keyword "${keyword}" failed to compile`);
|
|
2045
2045
|
return gen.scopeValue("keyword", typeof result == "function" ? { ref: result } : { ref: result, code: (0, codegen_1.stringify)(result) });
|
|
2046
2046
|
}
|
|
2047
|
-
function validSchemaType(schema,
|
|
2048
|
-
return !
|
|
2047
|
+
function validSchemaType(schema, schemaType2, allowUndefined = false) {
|
|
2048
|
+
return !schemaType2.length || schemaType2.some((st) => st === "array" ? Array.isArray(schema) : st === "object" ? schema && typeof schema == "object" && !Array.isArray(schema) : typeof schema == st || allowUndefined && typeof schema == "undefined");
|
|
2049
2049
|
}
|
|
2050
2050
|
exports.validSchemaType = validSchemaType;
|
|
2051
2051
|
function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keyword) {
|
|
@@ -2823,11 +2823,11 @@ var require_validate = __commonJS({
|
|
|
2823
2823
|
check$data(valid = codegen_1.nil, $dataValid = codegen_1.nil) {
|
|
2824
2824
|
if (!this.$data)
|
|
2825
2825
|
return;
|
|
2826
|
-
const { gen, schemaCode, schemaType, def } = this;
|
|
2826
|
+
const { gen, schemaCode, schemaType: schemaType2, def } = this;
|
|
2827
2827
|
gen.if((0, codegen_1.or)((0, codegen_1._)`${schemaCode} === undefined`, $dataValid));
|
|
2828
2828
|
if (valid !== codegen_1.nil)
|
|
2829
2829
|
gen.assign(valid, true);
|
|
2830
|
-
if (
|
|
2830
|
+
if (schemaType2.length || def.validateSchema) {
|
|
2831
2831
|
gen.elseIf(this.invalid$data());
|
|
2832
2832
|
this.$dataError();
|
|
2833
2833
|
if (valid !== codegen_1.nil)
|
|
@@ -2836,13 +2836,13 @@ var require_validate = __commonJS({
|
|
|
2836
2836
|
gen.else();
|
|
2837
2837
|
}
|
|
2838
2838
|
invalid$data() {
|
|
2839
|
-
const { gen, schemaCode, schemaType, def, it } = this;
|
|
2839
|
+
const { gen, schemaCode, schemaType: schemaType2, def, it } = this;
|
|
2840
2840
|
return (0, codegen_1.or)(wrong$DataType(), invalid$DataSchema());
|
|
2841
2841
|
function wrong$DataType() {
|
|
2842
|
-
if (
|
|
2842
|
+
if (schemaType2.length) {
|
|
2843
2843
|
if (!(schemaCode instanceof codegen_1.Name))
|
|
2844
2844
|
throw new Error("ajv implementation error");
|
|
2845
|
-
const st = Array.isArray(
|
|
2845
|
+
const st = Array.isArray(schemaType2) ? schemaType2 : [schemaType2];
|
|
2846
2846
|
return (0, codegen_1._)`${(0, dataType_2.checkDataTypes)(st, schemaCode, it.opts.strictNumbers, dataType_2.DataType.Wrong)}`;
|
|
2847
2847
|
}
|
|
2848
2848
|
return codegen_1.nil;
|
|
@@ -16666,6 +16666,9 @@ function isJsonValue(value) {
|
|
|
16666
16666
|
return value.every(isJsonValue);
|
|
16667
16667
|
return isPlainRecord(value) && Object.values(value).every(isJsonValue);
|
|
16668
16668
|
}
|
|
16669
|
+
function cloneJsonValue(value) {
|
|
16670
|
+
return isJsonValue(value) ? JSON.parse(JSON.stringify(value)) : void 0;
|
|
16671
|
+
}
|
|
16669
16672
|
function cloneJsonObject(value) {
|
|
16670
16673
|
if (!isPlainRecord(value) || !isJsonValue(value))
|
|
16671
16674
|
return void 0;
|
|
@@ -17027,6 +17030,7 @@ function analyzeA2UIBindings(protocol) {
|
|
|
17027
17030
|
}
|
|
17028
17031
|
}
|
|
17029
17032
|
return {
|
|
17033
|
+
surfaceIds: [...surfaces],
|
|
17030
17034
|
surfaceId: surfaces.size === 1 ? [...surfaces][0] : void 0,
|
|
17031
17035
|
occurrences,
|
|
17032
17036
|
issues
|
|
@@ -17978,7 +17982,7 @@ function optionalString(value, path2, issues) {
|
|
|
17978
17982
|
|
|
17979
17983
|
// ../agent-a2ui-card-contract/dist/esm/resolver.js
|
|
17980
17984
|
var A2UICardResolverError = class extends Error {
|
|
17981
|
-
constructor(code, message, fieldId) {
|
|
17985
|
+
constructor(code, message, fieldId, expectedType, actualType) {
|
|
17982
17986
|
super(message);
|
|
17983
17987
|
Object.defineProperty(this, "code", {
|
|
17984
17988
|
enumerable: true,
|
|
@@ -17992,9 +17996,23 @@ var A2UICardResolverError = class extends Error {
|
|
|
17992
17996
|
writable: true,
|
|
17993
17997
|
value: void 0
|
|
17994
17998
|
});
|
|
17999
|
+
Object.defineProperty(this, "expectedType", {
|
|
18000
|
+
enumerable: true,
|
|
18001
|
+
configurable: true,
|
|
18002
|
+
writable: true,
|
|
18003
|
+
value: void 0
|
|
18004
|
+
});
|
|
18005
|
+
Object.defineProperty(this, "actualType", {
|
|
18006
|
+
enumerable: true,
|
|
18007
|
+
configurable: true,
|
|
18008
|
+
writable: true,
|
|
18009
|
+
value: void 0
|
|
18010
|
+
});
|
|
17995
18011
|
this.name = "A2UICardResolverError";
|
|
17996
18012
|
this.code = code;
|
|
17997
18013
|
this.fieldId = fieldId;
|
|
18014
|
+
this.expectedType = expectedType;
|
|
18015
|
+
this.actualType = actualType;
|
|
17998
18016
|
}
|
|
17999
18017
|
};
|
|
18000
18018
|
async function executeA2UICardResolver(input) {
|
|
@@ -18014,8 +18032,8 @@ async function executeA2UICardResolver(input) {
|
|
|
18014
18032
|
if (!tool) {
|
|
18015
18033
|
throw new A2UICardResolverError("MCP_TOOL_UNAVAILABLE", `MCP tool ${call.mcpResourceId}/${call.toolName} is unavailable`, fieldId);
|
|
18016
18034
|
}
|
|
18017
|
-
if (!tool.
|
|
18018
|
-
throw new A2UICardResolverError("MCP_SCHEMA_UNSUPPORTED", `MCP tool ${call.mcpResourceId}/${call.toolName}
|
|
18035
|
+
if (!tool.outputSchema) {
|
|
18036
|
+
throw new A2UICardResolverError("MCP_SCHEMA_UNSUPPORTED", `MCP tool ${call.mcpResourceId}/${call.toolName} has no output schema`, fieldId);
|
|
18019
18037
|
}
|
|
18020
18038
|
const args = {};
|
|
18021
18039
|
for (const binding of call.inputBindings) {
|
|
@@ -18042,7 +18060,7 @@ async function executeA2UICardResolver(input) {
|
|
|
18042
18060
|
for (const binding of input.resolver.outputBindings) {
|
|
18043
18061
|
const field = fieldById.get(binding.fieldId);
|
|
18044
18062
|
const result = results.get(binding.callId);
|
|
18045
|
-
if (!field ||
|
|
18063
|
+
if (!field || result === void 0) {
|
|
18046
18064
|
throw new A2UICardResolverError("CARD_BINDING_INVALID", `Output binding ${binding.fieldId} is invalid`, binding.fieldId);
|
|
18047
18065
|
}
|
|
18048
18066
|
let value;
|
|
@@ -18078,7 +18096,7 @@ async function executeA2UICardResolver(input) {
|
|
|
18078
18096
|
}
|
|
18079
18097
|
const value = readJsonPointer(viewModel, field.path);
|
|
18080
18098
|
if (field.required && value === void 0) {
|
|
18081
|
-
throw new A2UICardResolverError("CARD_REQUIRED_FIELD_MISSING", `Required card field ${field.fieldId} is missing`, field.fieldId);
|
|
18099
|
+
throw new A2UICardResolverError("CARD_REQUIRED_FIELD_MISSING", `Required card field ${field.fieldId} is missing`, field.fieldId, field.type, "missing");
|
|
18082
18100
|
}
|
|
18083
18101
|
if (value !== void 0) {
|
|
18084
18102
|
assertSchemaValue(field.valueSchema, value, "CARD_MAPPING_SCHEMA_MISMATCH", `card field ${field.fieldId}`, field.fieldId);
|
|
@@ -18118,8 +18136,8 @@ function normalizeOptionalNulls(value, schema, required) {
|
|
|
18118
18136
|
}
|
|
18119
18137
|
async function executeTool(tool, args, signal, fieldId) {
|
|
18120
18138
|
const response = await tool.call(args, signal);
|
|
18121
|
-
const structured =
|
|
18122
|
-
if (
|
|
18139
|
+
const structured = cloneJsonValue(response.structuredContent);
|
|
18140
|
+
if (structured === void 0) {
|
|
18123
18141
|
throw new A2UICardResolverError("MCP_STRUCTURED_CONTENT_REQUIRED", `MCP tool ${tool.resourceId}/${tool.toolName} did not return structuredContent`, fieldId);
|
|
18124
18142
|
}
|
|
18125
18143
|
return structured;
|
|
@@ -18133,9 +18151,19 @@ function toolKey(resourceId, toolName) {
|
|
|
18133
18151
|
function assertSchemaValue(schema, value, code, label, fieldId) {
|
|
18134
18152
|
const issues = validateJsonSchemaValue2(schema, value);
|
|
18135
18153
|
if (issues.length > 0) {
|
|
18136
|
-
throw new A2UICardResolverError(code, `${label} does not match schema at ${issues[0].path}: ${issues[0].message}`, fieldId);
|
|
18154
|
+
throw new A2UICardResolverError(code, `${label} does not match schema at ${issues[0].path}: ${issues[0].message}`, fieldId, schemaType(schema), valueType2(value));
|
|
18137
18155
|
}
|
|
18138
18156
|
}
|
|
18157
|
+
function schemaType(schema) {
|
|
18158
|
+
return typeof schema.type === "string" ? schema.type : "unknown";
|
|
18159
|
+
}
|
|
18160
|
+
function valueType2(value) {
|
|
18161
|
+
if (value === null)
|
|
18162
|
+
return "null";
|
|
18163
|
+
if (Array.isArray(value))
|
|
18164
|
+
return "array";
|
|
18165
|
+
return typeof value === "object" ? "object" : typeof value;
|
|
18166
|
+
}
|
|
18139
18167
|
|
|
18140
18168
|
// ../linkque-agent-runtime/dist/esm/core/mcpNaming.js
|
|
18141
18169
|
import { createHash } from "node:crypto";
|
|
@@ -18172,7 +18200,7 @@ async function executeCardPresentation(resource, registry, runtimeContext, args,
|
|
|
18172
18200
|
if (!handle) {
|
|
18173
18201
|
throw new Error(`MCP tool ${call.mcpResourceId}/${call.toolName} is unavailable`);
|
|
18174
18202
|
}
|
|
18175
|
-
const inputSchema =
|
|
18203
|
+
const inputSchema = normalizeMcpInputSchema(handle.inputSchema);
|
|
18176
18204
|
return {
|
|
18177
18205
|
resourceId: call.mcpResourceId,
|
|
18178
18206
|
toolName: call.toolName,
|
|
@@ -18182,9 +18210,6 @@ async function executeCardPresentation(resource, registry, runtimeContext, args,
|
|
|
18182
18210
|
// ViewModel Schema 校验。
|
|
18183
18211
|
inputSchema,
|
|
18184
18212
|
outputSchema: isJsonObject(handle.outputSchema) ? handle.outputSchema : FALLBACK_OBJECT_SCHEMA,
|
|
18185
|
-
// 未声明 readOnlyHint 是旧 MCP 的常见情况;只拒绝明确声明
|
|
18186
|
-
// readOnlyHint=false 的工具。
|
|
18187
|
-
readOnly: handle.readOnly !== false,
|
|
18188
18213
|
call: async (input, callSignal) => {
|
|
18189
18214
|
const result = await handle.execute(supplementMcpInput(input, invocation, config.presentationInputSchema, inputSchema), callSignal);
|
|
18190
18215
|
return { structuredContent: readStructuredContent(result) };
|
|
@@ -18233,29 +18258,46 @@ async function executeCardPresentationFromSources(resource, runtimeContext, sour
|
|
|
18233
18258
|
transform: binding.transform
|
|
18234
18259
|
}))
|
|
18235
18260
|
};
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18258
|
-
|
|
18261
|
+
let viewModel;
|
|
18262
|
+
try {
|
|
18263
|
+
viewModel = await executeA2UICardResolver({
|
|
18264
|
+
resolver,
|
|
18265
|
+
fields: config.fields,
|
|
18266
|
+
presentationInputSchema: {
|
|
18267
|
+
type: "object",
|
|
18268
|
+
properties: {},
|
|
18269
|
+
additionalProperties: false
|
|
18270
|
+
},
|
|
18271
|
+
argsSchema: config.a2uiTemplate.argsSchema,
|
|
18272
|
+
invocation: {},
|
|
18273
|
+
runtimeContext,
|
|
18274
|
+
tools: config.dataSources.filter((source) => sourceResults.has(source.sourceId)).map((source) => ({
|
|
18275
|
+
resourceId: source.mcpResourceId,
|
|
18276
|
+
toolName: source.toolName,
|
|
18277
|
+
inputSchema: FALLBACK_OBJECT_SCHEMA,
|
|
18278
|
+
outputSchema: source.outputSchema ?? FALLBACK_OBJECT_SCHEMA,
|
|
18279
|
+
call: async () => ({
|
|
18280
|
+
structuredContent: sourceResults.get(source.sourceId)
|
|
18281
|
+
})
|
|
18282
|
+
})),
|
|
18283
|
+
signal
|
|
18284
|
+
});
|
|
18285
|
+
} catch (error) {
|
|
18286
|
+
if (error instanceof A2UICardResolverError) {
|
|
18287
|
+
const binding = config.bindings.find((candidate) => candidate.fieldId === error.fieldId);
|
|
18288
|
+
const field = config.fields.find((candidate) => candidate.fieldId === error.fieldId);
|
|
18289
|
+
throw new CardMappingError({
|
|
18290
|
+
code: error.code,
|
|
18291
|
+
cardId: resource.resourceId,
|
|
18292
|
+
fieldId: error.fieldId ?? "unknown",
|
|
18293
|
+
sourceId: binding?.sourceId ?? "unknown",
|
|
18294
|
+
expectedType: error.expectedType ?? field?.type ?? "unknown",
|
|
18295
|
+
actualType: error.actualType ?? "unknown",
|
|
18296
|
+
retryable: false
|
|
18297
|
+
});
|
|
18298
|
+
}
|
|
18299
|
+
throw error;
|
|
18300
|
+
}
|
|
18259
18301
|
return createPresentationResult(resource, config, viewModel);
|
|
18260
18302
|
}
|
|
18261
18303
|
function createPresentationResult(resource, config, viewModel) {
|
|
@@ -18290,25 +18332,46 @@ function isAgentPresentationToolResult(value) {
|
|
|
18290
18332
|
}
|
|
18291
18333
|
function injectResolvedViewModel(protocol, viewModel) {
|
|
18292
18334
|
const analysis = analyzeA2UIBindings(protocol);
|
|
18293
|
-
|
|
18294
|
-
|
|
18335
|
+
const declaredSurfaceIds = analysis.surfaceIds;
|
|
18336
|
+
const surfaceIds = Array.isArray(declaredSurfaceIds) && declaredSurfaceIds.every((surfaceId) => typeof surfaceId === "string") ? declaredSurfaceIds : collectA2UISurfaceIdsForLegacyContract(protocol);
|
|
18337
|
+
if (analysis.issues.length || surfaceIds.length === 0) {
|
|
18338
|
+
throw new Error("CARD template does not contain a valid A2UI surface");
|
|
18295
18339
|
}
|
|
18296
18340
|
return [
|
|
18297
18341
|
...protocol,
|
|
18298
18342
|
{
|
|
18299
18343
|
version: "0.9",
|
|
18300
|
-
datas:
|
|
18301
|
-
{
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
value: viewModel
|
|
18306
|
-
}
|
|
18344
|
+
datas: surfaceIds.map((surfaceId) => ({
|
|
18345
|
+
updateDataModel: {
|
|
18346
|
+
surfaceId,
|
|
18347
|
+
path: "/",
|
|
18348
|
+
value: viewModel
|
|
18307
18349
|
}
|
|
18308
|
-
|
|
18350
|
+
}))
|
|
18309
18351
|
}
|
|
18310
18352
|
];
|
|
18311
18353
|
}
|
|
18354
|
+
function collectA2UISurfaceIdsForLegacyContract(protocol) {
|
|
18355
|
+
const surfaceIds = /* @__PURE__ */ new Set();
|
|
18356
|
+
for (const message of protocol) {
|
|
18357
|
+
if (!isJsonObject(message) || !Array.isArray(message.datas))
|
|
18358
|
+
continue;
|
|
18359
|
+
for (const instruction of message.datas) {
|
|
18360
|
+
if (!isJsonObject(instruction))
|
|
18361
|
+
continue;
|
|
18362
|
+
const operations = [
|
|
18363
|
+
"createSurface" in instruction ? instruction.createSurface : void 0,
|
|
18364
|
+
"updateComponents" in instruction ? instruction.updateComponents : void 0
|
|
18365
|
+
];
|
|
18366
|
+
for (const operation of operations) {
|
|
18367
|
+
if (isJsonObject(operation) && typeof operation.surfaceId === "string") {
|
|
18368
|
+
surfaceIds.add(operation.surfaceId);
|
|
18369
|
+
}
|
|
18370
|
+
}
|
|
18371
|
+
}
|
|
18372
|
+
}
|
|
18373
|
+
return [...surfaceIds];
|
|
18374
|
+
}
|
|
18312
18375
|
function createPresentationDescription(config) {
|
|
18313
18376
|
return [
|
|
18314
18377
|
config.description,
|
|
@@ -18349,23 +18412,44 @@ function compatibleSchemaTypes(source, target) {
|
|
|
18349
18412
|
function readStructuredContent(result) {
|
|
18350
18413
|
if (!isJsonObject(result))
|
|
18351
18414
|
return void 0;
|
|
18352
|
-
if (
|
|
18353
|
-
return
|
|
18415
|
+
if (Object.hasOwn(result, "structuredContent") && isJsonValue(result.structuredContent)) {
|
|
18416
|
+
return cloneJsonValue(result.structuredContent);
|
|
18354
18417
|
}
|
|
18355
|
-
if (!Array.isArray(result.content) || result.content.length
|
|
18418
|
+
if (!Array.isArray(result.content) || result.content.length === 0) {
|
|
18356
18419
|
return void 0;
|
|
18357
18420
|
}
|
|
18358
|
-
const
|
|
18359
|
-
|
|
18360
|
-
|
|
18421
|
+
const texts = [];
|
|
18422
|
+
for (const content of result.content) {
|
|
18423
|
+
if (!isJsonObject(content) || content.type !== "text" || typeof content.text !== "string")
|
|
18424
|
+
return void 0;
|
|
18425
|
+
texts.push(content.text);
|
|
18361
18426
|
}
|
|
18427
|
+
if (texts.length > 1)
|
|
18428
|
+
return texts.join("\n");
|
|
18362
18429
|
try {
|
|
18363
|
-
const parsed = JSON.parse(
|
|
18364
|
-
return
|
|
18430
|
+
const parsed = JSON.parse(texts[0]);
|
|
18431
|
+
return isJsonValue(parsed) ? cloneJsonValue(parsed) : texts[0];
|
|
18365
18432
|
} catch {
|
|
18366
|
-
return
|
|
18433
|
+
return texts[0];
|
|
18434
|
+
}
|
|
18435
|
+
}
|
|
18436
|
+
function normalizeMcpInputSchema(value) {
|
|
18437
|
+
if (!isJsonObject(value) || getJsonSchemaIssues2(value).length > 0) {
|
|
18438
|
+
return { ...FALLBACK_OBJECT_SCHEMA };
|
|
18367
18439
|
}
|
|
18440
|
+
if (value.type === "object" && (!isJsonObject(value.properties) || Object.keys(value.properties).length === 0))
|
|
18441
|
+
return { ...FALLBACK_OBJECT_SCHEMA };
|
|
18442
|
+
return JSON.parse(JSON.stringify(value));
|
|
18368
18443
|
}
|
|
18444
|
+
var CardMappingError = class extends Error {
|
|
18445
|
+
details;
|
|
18446
|
+
retryable = false;
|
|
18447
|
+
constructor(details) {
|
|
18448
|
+
super(JSON.stringify(details));
|
|
18449
|
+
this.name = "CardMappingError";
|
|
18450
|
+
this.details = details;
|
|
18451
|
+
}
|
|
18452
|
+
};
|
|
18369
18453
|
function isJsonObject(value) {
|
|
18370
18454
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
18371
18455
|
}
|
|
@@ -18473,11 +18557,9 @@ var McpProxyTool = class {
|
|
|
18473
18557
|
const tool = entry.tools.find((t) => t.name === toolName);
|
|
18474
18558
|
if (!tool)
|
|
18475
18559
|
return void 0;
|
|
18476
|
-
const annotations = tool.annotations;
|
|
18477
18560
|
return {
|
|
18478
18561
|
inputSchema: tool.inputSchema,
|
|
18479
18562
|
outputSchema: tool.outputSchema,
|
|
18480
|
-
readOnly: annotations?.readOnlyHint,
|
|
18481
18563
|
execute: (args, sig) => entry.server.callTool(tool.name, args, sig)
|
|
18482
18564
|
};
|
|
18483
18565
|
}
|
|
@@ -19690,6 +19772,7 @@ function wrapToolWithHooks(tool, dispatcher, commonParams, now = Date.now) {
|
|
|
19690
19772
|
|
|
19691
19773
|
// ../linkque-agent-runtime/dist/esm/core/hook/noopHookExecutor.js
|
|
19692
19774
|
var NoopHookExecutor = class {
|
|
19775
|
+
name = "NoopHookExecutor";
|
|
19693
19776
|
execute(_resource, _context, _options) {
|
|
19694
19777
|
return Promise.resolve({
|
|
19695
19778
|
ok: true,
|
|
@@ -19808,6 +19891,7 @@ function buildLinkquegwEventBody(context) {
|
|
|
19808
19891
|
};
|
|
19809
19892
|
}
|
|
19810
19893
|
var LinkquegwEventHookExecutor = class {
|
|
19894
|
+
name = EHookExecutorName.LinkquegwEventHookExecutor;
|
|
19811
19895
|
baseUrl;
|
|
19812
19896
|
getAuthHeaders;
|
|
19813
19897
|
fetchImpl;
|
|
@@ -30194,10 +30278,10 @@ function coerceWithJsonSchema(value, schema) {
|
|
|
30194
30278
|
nextValue = coerceWithUnionSchema(nextValue, schema.oneOf);
|
|
30195
30279
|
}
|
|
30196
30280
|
const schemaTypes = getSchemaTypes(schema);
|
|
30197
|
-
const matchesUnionMember = schemaTypes.length > 1 && schemaTypes.some((
|
|
30281
|
+
const matchesUnionMember = schemaTypes.length > 1 && schemaTypes.some((schemaType2) => matchesJsonType(nextValue, schemaType2));
|
|
30198
30282
|
if (schemaTypes.length > 0 && !matchesUnionMember) {
|
|
30199
|
-
for (const
|
|
30200
|
-
const candidate = coercePrimitiveByType(nextValue,
|
|
30283
|
+
for (const schemaType2 of schemaTypes) {
|
|
30284
|
+
const candidate = coercePrimitiveByType(nextValue, schemaType2);
|
|
30201
30285
|
if (candidate !== nextValue) {
|
|
30202
30286
|
nextValue = candidate;
|
|
30203
30287
|
break;
|
|
@@ -52217,10 +52301,6 @@ ${currentTurn}`;
|
|
|
52217
52301
|
}
|
|
52218
52302
|
|
|
52219
52303
|
// ../linkque-agent-runtime/dist/esm/core/cardRenderMcpServer.js
|
|
52220
|
-
var FALLBACK_SOURCE_INPUT_SCHEMA = {
|
|
52221
|
-
type: "object",
|
|
52222
|
-
additionalProperties: true
|
|
52223
|
-
};
|
|
52224
52304
|
var CardRenderMcpServer = class {
|
|
52225
52305
|
resources;
|
|
52226
52306
|
registry;
|
|
@@ -52322,7 +52402,7 @@ Select this card first, then call its card_source tools and card_finish tool.`,
|
|
|
52322
52402
|
resourceId: resource.resourceId,
|
|
52323
52403
|
label: source.purpose,
|
|
52324
52404
|
description: `Use after selecting ${name}. ${source.purpose}. Choose all MCP arguments from the conversation and prior source results.`,
|
|
52325
|
-
inputSchema: discoveredHandle?.inputSchema
|
|
52405
|
+
inputSchema: normalizeMcpInputSchema(discoveredHandle?.inputSchema),
|
|
52326
52406
|
outputSchema: discoveredHandle?.outputSchema ?? source.outputSchema,
|
|
52327
52407
|
execute: async (args, signal) => {
|
|
52328
52408
|
if (!state2.selected || this.activeCardId !== resource.resourceId)
|
|
@@ -52333,12 +52413,21 @@ Select this card first, then call its card_source tools and card_finish tool.`,
|
|
|
52333
52413
|
const handle = discoveredHandle ?? await this.registry.resolve(source.mcpResourceId, source.toolName, signal);
|
|
52334
52414
|
if (!handle)
|
|
52335
52415
|
throw new Error(`MCP tool ${source.mcpResourceId}/${source.toolName} is unavailable`);
|
|
52336
|
-
if (handle.readOnly === false)
|
|
52337
|
-
throw new Error(`Card data source ${source.mcpResourceId}/${source.toolName} must be read-only`);
|
|
52338
52416
|
const result = await handle.execute(args, signal);
|
|
52339
52417
|
const structured = readStructuredContent(result);
|
|
52340
|
-
if (
|
|
52341
|
-
|
|
52418
|
+
if (structured === void 0) {
|
|
52419
|
+
const binding = config.bindings.find((candidate) => candidate.sourceId === source.sourceId);
|
|
52420
|
+
const field = config.fields.find((candidate) => candidate.fieldId === binding?.fieldId);
|
|
52421
|
+
throw new CardMappingError({
|
|
52422
|
+
code: "MCP_RESULT_UNSUPPORTED",
|
|
52423
|
+
cardId: resource.resourceId,
|
|
52424
|
+
fieldId: binding?.fieldId ?? "unknown",
|
|
52425
|
+
sourceId: source.sourceId,
|
|
52426
|
+
expectedType: field?.type ?? "json",
|
|
52427
|
+
actualType: "mixed-or-empty-content",
|
|
52428
|
+
retryable: false
|
|
52429
|
+
});
|
|
52430
|
+
}
|
|
52342
52431
|
state2.results.set(source.sourceId, structured);
|
|
52343
52432
|
return structured;
|
|
52344
52433
|
}
|
|
@@ -52563,6 +52652,92 @@ var NoopKnowledgeSearchPort = class {
|
|
|
52563
52652
|
}
|
|
52564
52653
|
};
|
|
52565
52654
|
|
|
52655
|
+
// ../linkque-agent-runtime/dist/esm/core/agentRuntimePlugin.js
|
|
52656
|
+
var validatePlugins = (plugins) => {
|
|
52657
|
+
const names = /* @__PURE__ */ new Set();
|
|
52658
|
+
for (const plugin of plugins) {
|
|
52659
|
+
const name = plugin.name.trim();
|
|
52660
|
+
if (!name) {
|
|
52661
|
+
throw new Error("Agent runtime \u63D2\u4EF6 name \u4E0D\u80FD\u4E3A\u7A7A");
|
|
52662
|
+
}
|
|
52663
|
+
if (names.has(name)) {
|
|
52664
|
+
throw new Error(`Agent runtime \u63D2\u4EF6 name \u91CD\u590D: ${name}`);
|
|
52665
|
+
}
|
|
52666
|
+
names.add(name);
|
|
52667
|
+
}
|
|
52668
|
+
return plugins;
|
|
52669
|
+
};
|
|
52670
|
+
function assertAgentConfigRoot(value, pluginName) {
|
|
52671
|
+
if (typeof value !== "object" || value === null || !("agent" in value)) {
|
|
52672
|
+
throw new Error(`Agent runtime \u63D2\u4EF6 ${pluginName} \u7684 modifyAgentConfig \u8FD4\u56DE\u4E86\u65E0\u6548\u914D\u7F6E`);
|
|
52673
|
+
}
|
|
52674
|
+
}
|
|
52675
|
+
var applyAgentRuntimePluginConfig = (agentConfig, plugins = []) => {
|
|
52676
|
+
const validatedPlugins = validatePlugins(plugins);
|
|
52677
|
+
const modifiers = validatedPlugins.filter((plugin) => plugin.modifyAgentConfig !== void 0);
|
|
52678
|
+
if (modifiers.length === 0)
|
|
52679
|
+
return agentConfig;
|
|
52680
|
+
let current = structuredClone(agentConfig);
|
|
52681
|
+
for (const plugin of modifiers) {
|
|
52682
|
+
try {
|
|
52683
|
+
const modified = plugin.modifyAgentConfig?.(current);
|
|
52684
|
+
if (modified !== void 0) {
|
|
52685
|
+
assertAgentConfigRoot(modified, plugin.name);
|
|
52686
|
+
current = modified;
|
|
52687
|
+
}
|
|
52688
|
+
current = structuredClone(current);
|
|
52689
|
+
} catch (error) {
|
|
52690
|
+
throw new Error(`Agent runtime \u63D2\u4EF6 ${plugin.name} \u4FEE\u6539 Agent Config \u5931\u8D25`, { cause: error });
|
|
52691
|
+
}
|
|
52692
|
+
}
|
|
52693
|
+
return current;
|
|
52694
|
+
};
|
|
52695
|
+
var MergedHookExecutorHandler = class {
|
|
52696
|
+
executorByName;
|
|
52697
|
+
constructor(executorByName) {
|
|
52698
|
+
this.executorByName = executorByName;
|
|
52699
|
+
}
|
|
52700
|
+
async execute(resource, context, options) {
|
|
52701
|
+
const executor = this.executorByName.get(resource.config.executorName);
|
|
52702
|
+
if (executor)
|
|
52703
|
+
return executor.execute(resource, context, options);
|
|
52704
|
+
return {
|
|
52705
|
+
ok: true,
|
|
52706
|
+
skipped: true,
|
|
52707
|
+
code: "PLUGIN_EXECUTOR_NOT_FOUND",
|
|
52708
|
+
message: `\u672A\u627E\u5230 name=${resource.config.executorName} \u7684 hook executor`
|
|
52709
|
+
};
|
|
52710
|
+
}
|
|
52711
|
+
};
|
|
52712
|
+
var resolveAgentRuntimeHookExecutor = (plugins = [], portHookExecutorList = [], debugLog) => {
|
|
52713
|
+
const entries = validatePlugins(plugins).flatMap((plugin) => (plugin.hookExecutorList ?? []).map((executor, index2) => ({
|
|
52714
|
+
executor,
|
|
52715
|
+
source: `plugin:${plugin.name}[${index2}]`
|
|
52716
|
+
})));
|
|
52717
|
+
entries.push(...portHookExecutorList.map((executor, index2) => ({
|
|
52718
|
+
executor,
|
|
52719
|
+
source: `ports.hookExecutorList[${index2}]`
|
|
52720
|
+
})));
|
|
52721
|
+
if (entries.length === 0)
|
|
52722
|
+
return void 0;
|
|
52723
|
+
const merged = /* @__PURE__ */ new Map();
|
|
52724
|
+
for (const entry of entries) {
|
|
52725
|
+
const name = entry.executor.name;
|
|
52726
|
+
if (!name.trim())
|
|
52727
|
+
throw new Error(`Hook executor name \u4E0D\u80FD\u4E3A\u7A7A: ${entry.source}`);
|
|
52728
|
+
const previous = merged.get(name);
|
|
52729
|
+
if (previous) {
|
|
52730
|
+
try {
|
|
52731
|
+
debugLog?.(`[hook-executor-merge] name=${name} \u51B2\u7A81: ${previous.source} \u88AB ${entry.source} \u8986\u76D6`, EDebugLogScope.HOOK);
|
|
52732
|
+
} catch {
|
|
52733
|
+
}
|
|
52734
|
+
}
|
|
52735
|
+
merged.set(name, entry);
|
|
52736
|
+
}
|
|
52737
|
+
const executorByName = new Map([...merged].map(([name, entry]) => [name, entry.executor]));
|
|
52738
|
+
return new MergedHookExecutorHandler(executorByName);
|
|
52739
|
+
};
|
|
52740
|
+
|
|
52566
52741
|
// ../linkque-agent-runtime/dist/esm/core/agentRuntime.js
|
|
52567
52742
|
var DEFAULT_HARNESS_PROMPT = `# Harness \u8FD0\u884C\u89C4\u7EA6
|
|
52568
52743
|
|
|
@@ -52625,13 +52800,14 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
52625
52800
|
* 本 constructor 供单测/noop 调试或需要完全自定义默认的场景。
|
|
52626
52801
|
*/
|
|
52627
52802
|
constructor(ports = {}) {
|
|
52803
|
+
const mergedHookExecutor = resolveAgentRuntimeHookExecutor(ports.plugins, ports.hookExecutorList, ports.debugLog);
|
|
52628
52804
|
this.agentLoop = ports.agentLoop ?? new PiAgentLoop(void 0, ports.linkqueBaseUrl);
|
|
52629
52805
|
this.followUpQuestionGenerator = ports.followUpQuestionGenerator ?? new PiFollowUpQuestionGenerator(ports.linkqueBaseUrl);
|
|
52630
52806
|
this.sessionManager = ports.sessionManager ?? new InMemorySessionManager();
|
|
52631
52807
|
this.skillLoader = ports.skillLoader ?? new NoopSkillLoader();
|
|
52632
52808
|
this.mcpServerProvider = ports.mcpServerProvider ?? new NoopMcpServerProvider();
|
|
52633
52809
|
this.knowledgeSearchPort = ports.knowledgeSearchPort ?? new NoopKnowledgeSearchPort();
|
|
52634
|
-
this.hookExecutor =
|
|
52810
|
+
this.hookExecutor = mergedHookExecutor ?? new NoopHookExecutor();
|
|
52635
52811
|
this.hookMetricsSink = ports.hookMetricsSink;
|
|
52636
52812
|
this.portsDebugLog = ports.debugLog;
|
|
52637
52813
|
}
|
|
@@ -52647,31 +52823,32 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
52647
52823
|
* @param ports 可选端口覆盖(任一缺省走默认适配器)
|
|
52648
52824
|
*/
|
|
52649
52825
|
static create(protocol, ports) {
|
|
52650
|
-
const model = protocol.agent.model;
|
|
52651
|
-
const skillResources = protocol.agent.resources.filter((r) => r.resourceType === EResourceType.SKILL);
|
|
52652
|
-
const mcpResources = protocol.agent.resources.filter((r) => r.resourceType === EResourceType.MCP);
|
|
52653
|
-
const mcpToolResources = protocol.agent.resources.filter((r) => r.resourceType === EResourceType.MCP_TOOL);
|
|
52654
|
-
const cardResources = protocol.agent.resources.filter((r) => r.resourceType === EResourceType.CARD);
|
|
52655
|
-
const knowledgeResources = protocol.agent.resources.filter((r) => r.resourceType === EResourceType.KNOWLEDGE);
|
|
52656
|
-
const followUpQuestionGenerationEnabled = protocol.agent.resources.filter((resource) => resource.resourceType === EResourceType.FOLLOW_UP_QUESTIONS).some((resource) => resource.config.enable === true);
|
|
52657
|
-
const mcpServerSpecs = aggregateMcpServers([...mcpResources, ...mcpToolResources], protocol.agentId);
|
|
52658
52826
|
const portsArg = ports ?? {};
|
|
52827
|
+
const agentConfig = applyAgentRuntimePluginConfig(protocol, portsArg.plugins);
|
|
52828
|
+
const model = agentConfig.agent.model;
|
|
52829
|
+
const skillResources = agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.SKILL);
|
|
52830
|
+
const mcpResources = agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.MCP);
|
|
52831
|
+
const mcpToolResources = agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.MCP_TOOL);
|
|
52832
|
+
const cardResources = agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.CARD);
|
|
52833
|
+
const knowledgeResources = agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.KNOWLEDGE);
|
|
52834
|
+
const followUpQuestionGenerationEnabled = agentConfig.agent.resources.filter((resource) => resource.resourceType === EResourceType.FOLLOW_UP_QUESTIONS).some((resource) => resource.config.enable === true);
|
|
52835
|
+
const mcpServerSpecs = aggregateMcpServers([...mcpResources, ...mcpToolResources], agentConfig.agentId);
|
|
52659
52836
|
const innerProvider = portsArg.mcpServerProvider ?? new NoopMcpServerProvider();
|
|
52660
52837
|
const rt = new _AgentRuntime({
|
|
52661
52838
|
...portsArg,
|
|
52662
52839
|
mcpServerProvider: new CardRenderMcpServerProvider(innerProvider)
|
|
52663
52840
|
});
|
|
52664
|
-
rt.defaultSystemPrompt =
|
|
52665
|
-
rt.defaultHarnessPrompt =
|
|
52841
|
+
rt.defaultSystemPrompt = agentConfig.agent.systemPrompt.content;
|
|
52842
|
+
rt.defaultHarnessPrompt = agentConfig.agent.harness ? agentConfig.agent.harness.systemPrompt : DEFAULT_HARNESS_PROMPT;
|
|
52666
52843
|
rt.defaultModel = model.defaultModel || void 0;
|
|
52667
52844
|
rt.defaultThinkingLevel = model.callParams?.thinkingLevel;
|
|
52668
52845
|
rt.skillResources = skillResources;
|
|
52669
52846
|
rt.mcpServerSpecs = mcpServerSpecs;
|
|
52670
52847
|
rt.cardResources = cardResources;
|
|
52671
52848
|
rt.knowledgeResources = knowledgeResources;
|
|
52672
|
-
rt.agentId =
|
|
52849
|
+
rt.agentId = agentConfig.agentId;
|
|
52673
52850
|
rt.followUpQuestionGenerationEnabled = followUpQuestionGenerationEnabled;
|
|
52674
|
-
rt.hookResources = normalizeHookResources(
|
|
52851
|
+
rt.hookResources = normalizeHookResources(agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.HOOK));
|
|
52675
52852
|
return rt;
|
|
52676
52853
|
}
|
|
52677
52854
|
async prepareFollowUpQuestionContext(sessionId, history = []) {
|
|
@@ -60279,6 +60456,9 @@ function setBakedProtocol(protocol) {
|
|
|
60279
60456
|
|
|
60280
60457
|
export {
|
|
60281
60458
|
EResourceType,
|
|
60459
|
+
EResourceProviderType,
|
|
60460
|
+
EHookStage,
|
|
60461
|
+
EHookExecutorName,
|
|
60282
60462
|
executeHomeData,
|
|
60283
60463
|
FOLLOW_UP_CONTEXT_MAX_HISTORY_RUNS,
|
|
60284
60464
|
LinkquegwEventHookExecutor,
|