linkque-cli-v2 1.1.2 → 1.1.4-beta.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.
Files changed (16) hide show
  1. package/linkquejs.js +37 -15
  2. package/package.json +1 -1
  3. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{anthropic-messages-B5T6TFD2.js → anthropic-messages-YOPI234A.js} +1 -1
  4. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{azure-openai-responses-S7HNQOSE.js → azure-openai-responses-67YPFLZQ.js} +2 -2
  5. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{chunk-XGIMLCNP.js → chunk-IMZDZMKV.js} +186 -53
  6. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{chunk-IKZ25GJD.js → chunk-LSBJJGJC.js} +1 -1
  7. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{chunk-3S3TOEBZ.js → chunk-Y3G4J3TB.js} +1 -0
  8. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{google-generative-ai-IOXNKFEV.js → google-generative-ai-R5DASQKW.js} +1 -1
  9. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{google-vertex-U4ZV5IXZ.js → google-vertex-OLX2NFGJ.js} +1 -1
  10. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{mistral-conversations-G3K7SSWR.js → mistral-conversations-L6T7EWC2.js} +1 -1
  11. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{openai-codex-responses-4JJLPTCS.js → openai-codex-responses-7QJMWGY5.js} +2 -2
  12. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{openai-completions-PH4WW6E7.js → openai-completions-75YD6VJJ.js} +1 -1
  13. package/vendor/linkque-agent-appwrite-integrate/dist/esm/{openai-responses-KGWAX6HR.js → openai-responses-G6MVJCGC.js} +2 -2
  14. package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/handler/chat.js +2 -2
  15. package/vendor/linkque-agent-appwrite-integrate/dist/esm/runtime/protocol.js +2 -2
  16. package/worker.js +207 -44
package/linkquejs.js CHANGED
@@ -25304,6 +25304,7 @@ function analyzeA2UIBindings(protocol) {
25304
25304
  const listRoots = inferListRoots(components, issues);
25305
25305
  for (const component of components) {
25306
25306
  const context = {
25307
+ surfaceId,
25307
25308
  component,
25308
25309
  listRoot: listRoots.get(component.id),
25309
25310
  occurrences,
@@ -25317,6 +25318,7 @@ function analyzeA2UIBindings(protocol) {
25317
25318
  issues.push(issue2(`card.surfaces.${surfaceId}.components.${component.id}.children.path`, "INVALID_BINDING_PATH", `Invalid list path ${children.path}`));
25318
25319
  } else {
25319
25320
  occurrences.push({
25321
+ surfaceId,
25320
25322
  componentId: component.id,
25321
25323
  componentName: component.component,
25322
25324
  propertyPath: "children.path",
@@ -25335,6 +25337,16 @@ function analyzeA2UIBindings(protocol) {
25335
25337
  issues
25336
25338
  };
25337
25339
  }
25340
+ function collectReferencedA2UICardBusinessFieldIds(protocol, fields) {
25341
+ const businessFields = fields.filter((field) => field.source === "business").slice().sort((left, right) => right.path.length - left.path.length);
25342
+ const result = /* @__PURE__ */ new Set();
25343
+ for (const occurrence of analyzeA2UIBindings(protocol).occurrences) {
25344
+ const field = businessFields.find((candidate) => occurrence.canonicalPath === candidate.path || occurrence.canonicalPath.startsWith(`${candidate.path}/*/`) || occurrence.canonicalPath.startsWith(`${candidate.path}/`));
25345
+ if (field)
25346
+ result.add(field.fieldId);
25347
+ }
25348
+ return result;
25349
+ }
25338
25350
  function visitValue(value, propertyPath, context) {
25339
25351
  if (propertyPath === "action.local.path" && typeof value === "string") {
25340
25352
  addOccurrence(value, propertyPath, "local", context);
@@ -25366,6 +25378,7 @@ function addOccurrence(rawPath, propertyPath, usage, context) {
25366
25378
  return;
25367
25379
  }
25368
25380
  context.occurrences.push({
25381
+ surfaceId: context.surfaceId,
25369
25382
  componentId: context.component.id,
25370
25383
  componentName: context.component.component,
25371
25384
  propertyPath,
@@ -26051,12 +26064,15 @@ function validateA2UICardBindings(input, options = {}) {
26051
26064
  readyCandidates.set(candidateKey(candidate.resourceId, candidate.tool.toolName), candidate.tool);
26052
26065
  }
26053
26066
  const bindingByField = new Map(bindings.map((binding) => [binding.fieldId, binding]));
26067
+ const requiredFields = collectReferencedA2UICardBusinessFieldIds(input.draft.card, input.draft.manifest.fields.filter((field) => field.required));
26054
26068
  for (const field of input.draft.manifest.fields) {
26055
26069
  if (field.source !== "business")
26056
26070
  continue;
26057
26071
  if (selectedFields && !selectedFields.has(field.fieldId))
26058
26072
  continue;
26059
26073
  const binding = bindingByField.get(field.fieldId);
26074
+ if (!selectedFields && !requiredFields.has(field.fieldId) && !binding)
26075
+ continue;
26060
26076
  if (!binding) {
26061
26077
  issues.push(issue2(`fields.${field.fieldId}`, "CARD_BINDING_INCOMPLETE", `business field ${field.fieldId} has not been bound`));
26062
26078
  continue;
@@ -26394,9 +26410,9 @@ function getA2UICardResourceConfigIssues(value) {
26394
26410
  validateLooseJsonSchema(value.presentationInputSchema, "config.presentationInputSchema", issues);
26395
26411
  const fields = validateFields(value.fields, "config.fields", issues);
26396
26412
  const resolver = validateResolver(value.resolver, "config.resolver", issues);
26397
- validateTemplate(value.a2uiTemplate, fields, issues);
26413
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
26398
26414
  if (fields && resolver)
26399
- validateResolverCoverage(fields, resolver, issues);
26415
+ validateResolverCoverage(fields, resolver, issues, card);
26400
26416
  return issues;
26401
26417
  }
26402
26418
  function getA2UICardResourceConfigV3Issues(value) {
@@ -26429,9 +26445,9 @@ function getA2UICardResourceConfigV3Issues(value) {
26429
26445
  }
26430
26446
  const dataSources = validateDataSources(value.dataSources, "config.dataSources", issues);
26431
26447
  const bindings = validateV3OutputBindings(value.bindings, "config.bindings", issues);
26432
- validateTemplate(value.a2uiTemplate, fields, issues);
26448
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
26433
26449
  if (fields && dataSources && bindings) {
26434
- validateV3Coverage(fields, dataSources, bindings, issues);
26450
+ validateV3Coverage(fields, dataSources, bindings, issues, { card });
26435
26451
  }
26436
26452
  return issues;
26437
26453
  }
@@ -26545,7 +26561,8 @@ function validateV3Coverage(fields, dataSources, bindings, issues, options = {})
26545
26561
  bound.add(binding.fieldId);
26546
26562
  });
26547
26563
  if (options.requireComplete !== false) {
26548
- for (const fieldId of businessFields) {
26564
+ const requiredFields = options.card ? collectReferencedA2UICardBusinessFieldIds(options.card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
26565
+ for (const fieldId of requiredFields) {
26549
26566
  if (bound.has(fieldId))
26550
26567
  continue;
26551
26568
  issues.push(issue2("config.bindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
@@ -26983,13 +27000,13 @@ function validateInstructionShape(instruction, path22, issues) {
26983
27000
  function validateTemplate(value, fields, issues) {
26984
27001
  if (!isPlainRecord(value)) {
26985
27002
  issues.push(issue2("config.a2uiTemplate", "INVALID_A2UI_TEMPLATE", "a2uiTemplate must be an object"));
26986
- return;
27003
+ return void 0;
26987
27004
  }
26988
27005
  exactKeys(value, ["argsSchema", "content"], "config.a2uiTemplate", issues);
26989
27006
  validateLooseJsonSchema(value.argsSchema, "config.a2uiTemplate.argsSchema", issues);
26990
27007
  if (typeof value.content !== "string") {
26991
27008
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must be serialized A2UI JSON"));
26992
- return;
27009
+ return void 0;
26993
27010
  }
26994
27011
  try {
26995
27012
  const card = validateProtocol(JSON.parse(value.content), "config.a2uiTemplate.content", issues);
@@ -26997,9 +27014,11 @@ function validateTemplate(value, fields, issues) {
26997
27014
  const analysis = analyzeA2UIBindings(card);
26998
27015
  issues.push(...analysis.issues);
26999
27016
  }
27017
+ return card;
27000
27018
  } catch {
27001
27019
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must contain valid JSON"));
27002
27020
  }
27021
+ return void 0;
27003
27022
  }
27004
27023
  function validateLooseJsonSchema(value, path22, issues) {
27005
27024
  const schemaIssues = getJsonSchemaIssues(value, path22, {
@@ -27008,7 +27027,7 @@ function validateLooseJsonSchema(value, path22, issues) {
27008
27027
  issues.push(...schemaIssues);
27009
27028
  return schemaIssues.length === 0;
27010
27029
  }
27011
- function validateResolverCoverage(fields, resolver, issues) {
27030
+ function validateResolverCoverage(fields, resolver, issues, card) {
27012
27031
  const businessFields = new Set(fields.filter((field) => field.source === "business").map((field) => field.fieldId));
27013
27032
  const bound = /* @__PURE__ */ new Set();
27014
27033
  resolver.outputBindings.forEach((binding, index) => {
@@ -27017,7 +27036,8 @@ function validateResolverCoverage(fields, resolver, issues) {
27017
27036
  }
27018
27037
  bound.add(binding.fieldId);
27019
27038
  });
27020
- for (const fieldId of businessFields) {
27039
+ const requiredFields = card ? collectReferencedA2UICardBusinessFieldIds(card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
27040
+ for (const fieldId of requiredFields) {
27021
27041
  if (!bound.has(fieldId)) {
27022
27042
  issues.push(issue2("config.resolver.outputBindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
27023
27043
  }
@@ -27065,6 +27085,7 @@ function compileA2UICardResource(input) {
27065
27085
  }
27066
27086
  const fieldById = new Map(draft.manifest.fields.map((field) => [field.fieldId, field]));
27067
27087
  const selectionByField = /* @__PURE__ */ new Map();
27088
+ const requiredFields = collectReferencedA2UICardBusinessFieldIds(draft.card, draft.manifest.fields.filter((field) => field.required));
27068
27089
  for (const selection of input.bindings) {
27069
27090
  const field = fieldById.get(selection.fieldId);
27070
27091
  if (!field || field.source !== "business") {
@@ -27078,9 +27099,9 @@ function compileA2UICardResource(input) {
27078
27099
  }
27079
27100
  selectionByField.set(selection.fieldId, cloneSelection(selection));
27080
27101
  }
27081
- for (const field of draft.manifest.fields) {
27082
- if (field.source === "business" && !selectionByField.has(field.fieldId)) {
27083
- throw new A2UICardCompileError("CARD_BINDING_INCOMPLETE", `Business field ${field.fieldId} has not been bound`);
27102
+ for (const fieldId of requiredFields) {
27103
+ if (!selectionByField.has(fieldId)) {
27104
+ throw new A2UICardCompileError("CARD_BINDING_INCOMPLETE", `Required referenced business field ${fieldId} has not been bound`);
27084
27105
  }
27085
27106
  }
27086
27107
  const resolver = compileResolver([...selectionByField.values()]);
@@ -27172,6 +27193,7 @@ function compileV3Resource(draft, revision, bindings, tools) {
27172
27193
  const sourceById = /* @__PURE__ */ new Map();
27173
27194
  const outputBindings = [];
27174
27195
  const boundFields = /* @__PURE__ */ new Set();
27196
+ const requiredFields = collectReferencedA2UICardBusinessFieldIds(draft.card, draft.manifest.fields.filter((field) => field.required));
27175
27197
  for (const binding of bindings) {
27176
27198
  const field = fieldById.get(binding.fieldId);
27177
27199
  if (!field || field.source !== "business" || boundFields.has(binding.fieldId)) {
@@ -27199,9 +27221,9 @@ function compileV3Resource(draft, revision, bindings, tools) {
27199
27221
  transform: binding.transform
27200
27222
  });
27201
27223
  }
27202
- for (const field of draft.manifest.fields) {
27203
- if (field.source === "business" && !boundFields.has(field.fieldId)) {
27204
- throw new A2UICardCompileError("CARD_BINDING_INCOMPLETE", `Business field ${field.fieldId} has not been bound`);
27224
+ for (const fieldId of requiredFields) {
27225
+ if (!boundFields.has(fieldId)) {
27226
+ throw new A2UICardCompileError("CARD_BINDING_INCOMPLETE", `Required referenced business field ${fieldId} has not been bound`);
27205
27227
  }
27206
27228
  }
27207
27229
  const resource = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linkque-cli-v2",
3
- "version": "1.1.2",
3
+ "version": "1.1.4-beta.1",
4
4
  "description": "Public Linkque CLI bundle for sandbox debugging",
5
5
  "bin": {
6
6
  "linkquejs": "linkquejs.js"
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-Y6UTJIT4.js";
20
20
  import {
21
21
  calculateCost
22
- } from "./chunk-3S3TOEBZ.js";
22
+ } from "./chunk-Y3G4J3TB.js";
23
23
  import {
24
24
  getProviderEnvValue
25
25
  } from "./chunk-OXGCUIKV.js";
@@ -2,7 +2,7 @@ import {
2
2
  convertResponsesMessages,
3
3
  convertResponsesTools,
4
4
  processResponsesStream
5
- } from "./chunk-IKZ25GJD.js";
5
+ } from "./chunk-LSBJJGJC.js";
6
6
  import "./chunk-UFVAKOTZ.js";
7
7
  import {
8
8
  AzureOpenAI
@@ -23,7 +23,7 @@ import {
23
23
  } from "./chunk-Y6UTJIT4.js";
24
24
  import {
25
25
  clampThinkingLevel
26
- } from "./chunk-3S3TOEBZ.js";
26
+ } from "./chunk-Y3G4J3TB.js";
27
27
  import {
28
28
  getProviderEnvValue
29
29
  } from "./chunk-OXGCUIKV.js";
@@ -132,8 +132,9 @@ import {
132
132
  import {
133
133
  createModels,
134
134
  createProvider,
135
- lazyApi
136
- } from "./chunk-3S3TOEBZ.js";
135
+ lazyApi,
136
+ lazyStream
137
+ } from "./chunk-Y3G4J3TB.js";
137
138
  import {
138
139
  getProviderEnvValue
139
140
  } from "./chunk-OXGCUIKV.js";
@@ -16583,6 +16584,7 @@ var require_dist2 = __commonJS({
16583
16584
  // ../linkque-agent-runtime/dist/esm/core/types.js
16584
16585
  var EDebugLogScope;
16585
16586
  (function(EDebugLogScope2) {
16587
+ EDebugLogScope2["CONFIG"] = "CONFIG";
16586
16588
  EDebugLogScope2["LLM"] = "LLM";
16587
16589
  EDebugLogScope2["PI_EVENT"] = "PI_EVENT";
16588
16590
  EDebugLogScope2["MCP"] = "MCP";
@@ -17005,6 +17007,7 @@ function analyzeA2UIBindings(protocol) {
17005
17007
  const listRoots = inferListRoots(components, issues);
17006
17008
  for (const component of components) {
17007
17009
  const context = {
17010
+ surfaceId,
17008
17011
  component,
17009
17012
  listRoot: listRoots.get(component.id),
17010
17013
  occurrences,
@@ -17018,6 +17021,7 @@ function analyzeA2UIBindings(protocol) {
17018
17021
  issues.push(issue2(`card.surfaces.${surfaceId}.components.${component.id}.children.path`, "INVALID_BINDING_PATH", `Invalid list path ${children.path}`));
17019
17022
  } else {
17020
17023
  occurrences.push({
17024
+ surfaceId,
17021
17025
  componentId: component.id,
17022
17026
  componentName: component.component,
17023
17027
  propertyPath: "children.path",
@@ -17036,6 +17040,16 @@ function analyzeA2UIBindings(protocol) {
17036
17040
  issues
17037
17041
  };
17038
17042
  }
17043
+ function collectReferencedA2UICardBusinessFieldIds(protocol, fields) {
17044
+ const businessFields = fields.filter((field) => field.source === "business").slice().sort((left, right) => right.path.length - left.path.length);
17045
+ const result = /* @__PURE__ */ new Set();
17046
+ for (const occurrence of analyzeA2UIBindings(protocol).occurrences) {
17047
+ const field = businessFields.find((candidate) => occurrence.canonicalPath === candidate.path || occurrence.canonicalPath.startsWith(`${candidate.path}/*/`) || occurrence.canonicalPath.startsWith(`${candidate.path}/`));
17048
+ if (field)
17049
+ result.add(field.fieldId);
17050
+ }
17051
+ return result;
17052
+ }
17039
17053
  function visitValue(value, propertyPath, context) {
17040
17054
  if (propertyPath === "action.local.path" && typeof value === "string") {
17041
17055
  addOccurrence(value, propertyPath, "local", context);
@@ -17067,6 +17081,7 @@ function addOccurrence(rawPath, propertyPath, usage, context) {
17067
17081
  return;
17068
17082
  }
17069
17083
  context.occurrences.push({
17084
+ surfaceId: context.surfaceId,
17070
17085
  componentId: context.component.id,
17071
17086
  componentName: context.component.component,
17072
17087
  propertyPath,
@@ -17478,9 +17493,9 @@ function getA2UICardResourceConfigIssues(value) {
17478
17493
  validateLooseJsonSchema(value.presentationInputSchema, "config.presentationInputSchema", issues);
17479
17494
  const fields = validateFields(value.fields, "config.fields", issues);
17480
17495
  const resolver = validateResolver(value.resolver, "config.resolver", issues);
17481
- validateTemplate(value.a2uiTemplate, fields, issues);
17496
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
17482
17497
  if (fields && resolver)
17483
- validateResolverCoverage(fields, resolver, issues);
17498
+ validateResolverCoverage(fields, resolver, issues, card);
17484
17499
  return issues;
17485
17500
  }
17486
17501
  function getA2UICardResourceConfigV3Issues(value) {
@@ -17513,9 +17528,9 @@ function getA2UICardResourceConfigV3Issues(value) {
17513
17528
  }
17514
17529
  const dataSources = validateDataSources(value.dataSources, "config.dataSources", issues);
17515
17530
  const bindings = validateV3OutputBindings(value.bindings, "config.bindings", issues);
17516
- validateTemplate(value.a2uiTemplate, fields, issues);
17531
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
17517
17532
  if (fields && dataSources && bindings) {
17518
- validateV3Coverage(fields, dataSources, bindings, issues);
17533
+ validateV3Coverage(fields, dataSources, bindings, issues, { card });
17519
17534
  }
17520
17535
  return issues;
17521
17536
  }
@@ -17629,7 +17644,8 @@ function validateV3Coverage(fields, dataSources, bindings, issues, options = {})
17629
17644
  bound.add(binding.fieldId);
17630
17645
  });
17631
17646
  if (options.requireComplete !== false) {
17632
- for (const fieldId of businessFields) {
17647
+ const requiredFields = options.card ? collectReferencedA2UICardBusinessFieldIds(options.card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
17648
+ for (const fieldId of requiredFields) {
17633
17649
  if (bound.has(fieldId))
17634
17650
  continue;
17635
17651
  issues.push(issue2("config.bindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
@@ -17929,13 +17945,13 @@ function validateInstructionShape(instruction, path2, issues) {
17929
17945
  function validateTemplate(value, fields, issues) {
17930
17946
  if (!isPlainRecord(value)) {
17931
17947
  issues.push(issue2("config.a2uiTemplate", "INVALID_A2UI_TEMPLATE", "a2uiTemplate must be an object"));
17932
- return;
17948
+ return void 0;
17933
17949
  }
17934
17950
  exactKeys(value, ["argsSchema", "content"], "config.a2uiTemplate", issues);
17935
17951
  validateLooseJsonSchema(value.argsSchema, "config.a2uiTemplate.argsSchema", issues);
17936
17952
  if (typeof value.content !== "string") {
17937
17953
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must be serialized A2UI JSON"));
17938
- return;
17954
+ return void 0;
17939
17955
  }
17940
17956
  try {
17941
17957
  const card = validateProtocol(JSON.parse(value.content), "config.a2uiTemplate.content", issues);
@@ -17943,9 +17959,11 @@ function validateTemplate(value, fields, issues) {
17943
17959
  const analysis = analyzeA2UIBindings(card);
17944
17960
  issues.push(...analysis.issues);
17945
17961
  }
17962
+ return card;
17946
17963
  } catch {
17947
17964
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must contain valid JSON"));
17948
17965
  }
17966
+ return void 0;
17949
17967
  }
17950
17968
  function validateLooseJsonSchema(value, path2, issues) {
17951
17969
  const schemaIssues = getJsonSchemaIssues2(value, path2, {
@@ -17954,7 +17972,7 @@ function validateLooseJsonSchema(value, path2, issues) {
17954
17972
  issues.push(...schemaIssues);
17955
17973
  return schemaIssues.length === 0;
17956
17974
  }
17957
- function validateResolverCoverage(fields, resolver, issues) {
17975
+ function validateResolverCoverage(fields, resolver, issues, card) {
17958
17976
  const businessFields = new Set(fields.filter((field) => field.source === "business").map((field) => field.fieldId));
17959
17977
  const bound = /* @__PURE__ */ new Set();
17960
17978
  resolver.outputBindings.forEach((binding, index2) => {
@@ -17963,7 +17981,8 @@ function validateResolverCoverage(fields, resolver, issues) {
17963
17981
  }
17964
17982
  bound.add(binding.fieldId);
17965
17983
  });
17966
- for (const fieldId of businessFields) {
17984
+ const requiredFields = card ? collectReferencedA2UICardBusinessFieldIds(card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
17985
+ for (const fieldId of requiredFields) {
17967
17986
  if (!bound.has(fieldId)) {
17968
17987
  issues.push(issue2("config.resolver.outputBindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
17969
17988
  }
@@ -18647,6 +18666,9 @@ var McpProxyTool = class {
18647
18666
  if (params.describe !== void 0) {
18648
18667
  return this.executeDescribe(params.describe, params.server, signal);
18649
18668
  }
18669
+ if (params.searches !== void 0) {
18670
+ return this.executeBatchSearch(params.searches, params.server);
18671
+ }
18650
18672
  if (params.search !== void 0) {
18651
18673
  return this.executeSearch(params.search, params.server);
18652
18674
  }
@@ -18743,6 +18765,20 @@ ${formatSchema(tool.inputSchema, " ")}`);
18743
18765
  }
18744
18766
  return lines.join("\n").trim();
18745
18767
  }
18768
+ /** `mcp({ searches: [...] })`:一次连接元数据并按 query 分组执行多组搜索。 */
18769
+ async executeBatchSearch(queries, serverHint) {
18770
+ const normalized = [
18771
+ ...new Set(queries.map((query) => query.trim()).filter(Boolean))
18772
+ ].slice(0, MCP_BATCH_SEARCH_MAX_ITEMS);
18773
+ if (normalized.length === 0) {
18774
+ return "Batch search requires at least one non-empty query.";
18775
+ }
18776
+ const specs = serverHint ? this.specsMatching(serverHint) : this.specs;
18777
+ await Promise.all(specs.map((spec) => this.ensureEntry(spec.serverName)));
18778
+ const results = await Promise.all(normalized.map((query) => this.executeSearch(query, serverHint)));
18779
+ return results.map((result, index2) => `Query ${index2 + 1}: "${normalized[index2]}"
18780
+ ${result}`).join("\n\n");
18781
+ }
18746
18782
  /** `mcp({ describe: "tool" })`:输出工具所属 server + 参数 schema。 */
18747
18783
  async executeDescribe(toolName, serverHint, signal) {
18748
18784
  const found = await this.findTool(toolName, serverHint, signal);
@@ -18834,6 +18870,9 @@ function parseProxyArgs(args) {
18834
18870
  out.describe = args.describe;
18835
18871
  if (typeof args.search === "string")
18836
18872
  out.search = args.search;
18873
+ if (Array.isArray(args.searches)) {
18874
+ out.searches = args.searches.filter((query) => typeof query === "string").slice(0, MCP_BATCH_SEARCH_MAX_ITEMS);
18875
+ }
18837
18876
  if (typeof args.tool === "string")
18838
18877
  out.tool = args.tool;
18839
18878
  if (typeof args.server === "string")
@@ -18877,12 +18916,14 @@ function truncate(text, max2) {
18877
18916
  function isRecord(value) {
18878
18917
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
18879
18918
  }
18919
+ var MCP_BATCH_SEARCH_MAX_ITEMS = 5;
18880
18920
  var MCP_PROXY_DESCRIPTION = [
18881
18921
  "MCP \u7F51\u5173:\u53D1\u73B0\u5E76\u8C03\u7528 MCP server \u63D0\u4F9B\u7684\u5DE5\u5177\u3002\u53EF\u7528\u52A8\u4F5C:",
18882
18922
  "- mcp({}) \u6216 mcp({ status: true }):\u67E5\u770B\u6240\u6709 server \u8FDE\u63A5\u72B6\u6001\u4E0E\u5DE5\u5177\u6570\u3002",
18883
18923
  '- mcp({ connect: "server" }):\u8FDE\u63A5\u5E76\u5237\u65B0\u67D0 server \u7684\u5DE5\u5177\u5217\u8868\u3002',
18884
18924
  '- mcp({ server: "name" }):\u5217\u51FA\u8BE5 server \u7684\u5DE5\u5177\u3002',
18885
18925
  '- mcp({ search: "\u5173\u952E\u8BCD" }):\u6309\u540D\u79F0/\u63CF\u8FF0\u6A21\u7CCA\u641C\u7D22\u5DE5\u5177(\u7A7A\u683C\u5206\u8BCD OR)\u3002',
18926
+ '- mcp({ searches: ["\u5173\u952E\u8BCD1", "\u5173\u952E\u8BCD2"] }):\u4E00\u6B21\u6267\u884C\u591A\u7EC4\u641C\u7D22\u5E76\u6309 query \u5206\u7EC4\u8FD4\u56DE(\u6700\u591A 5 \u7EC4)\u3002',
18886
18927
  '- mcp({ describe: "toolName" }):\u67E5\u770B\u67D0\u5DE5\u5177\u7684\u53C2\u6570 schema\u3002',
18887
18928
  '- mcp({ tool: "toolName", args: { ... } }):\u8C03\u7528\u67D0\u5DE5\u5177,args \u4E3A\u5BF9\u8C61\u3002',
18888
18929
  "\u53EF\u7528 server \u540D\u89C1 mcp({}) \u8F93\u51FA\u3002\u4EC5\u5728\u786E\u9700\u8C03\u7528 MCP \u5DE5\u5177\u65F6\u4F7F\u7528\u672C\u5DE5\u5177\u3002",
@@ -18905,6 +18946,13 @@ var MCP_PROXY_INPUT_SCHEMA = {
18905
18946
  type: "string",
18906
18947
  description: "\u6309\u540D\u79F0/\u63CF\u8FF0\u6A21\u7CCA\u641C\u7D22\u5DE5\u5177(\u7A7A\u683C\u5206\u8BCD OR)"
18907
18948
  },
18949
+ searches: {
18950
+ type: "array",
18951
+ description: "\u6279\u91CF\u641C\u7D22\u5173\u952E\u8BCD\uFF1B\u4E00\u6B21\u63D0\u4EA4\u6240\u6709\u5019\u9009 query\uFF0C\u6309 query \u5206\u7EC4\u8FD4\u56DE",
18952
+ minItems: 1,
18953
+ maxItems: MCP_BATCH_SEARCH_MAX_ITEMS,
18954
+ items: { type: "string", minLength: 1 }
18955
+ },
18908
18956
  describe: { type: "string", description: "\u67E5\u770B\u67D0\u5DE5\u5177\u7684\u53C2\u6570 schema" },
18909
18957
  tool: { type: "string", description: "\u8981\u8C03\u7528\u7684\u5DE5\u5177\u540D(\u53EF\u914D\u5408 server \u6D88\u6B67)" },
18910
18958
  args: {
@@ -20153,10 +20201,10 @@ function extractName(args) {
20153
20201
  }
20154
20202
 
20155
20203
  // ../../node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.lazy.js
20156
- var anthropicMessagesApi = () => lazyApi(() => import("./anthropic-messages-B5T6TFD2.js"));
20204
+ var anthropicMessagesApi = () => lazyApi(() => import("./anthropic-messages-YOPI234A.js"));
20157
20205
 
20158
20206
  // ../../node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.lazy.js
20159
- var azureOpenAIResponsesApi = () => lazyApi(() => import("./azure-openai-responses-S7HNQOSE.js"));
20207
+ var azureOpenAIResponsesApi = () => lazyApi(() => import("./azure-openai-responses-67YPFLZQ.js"));
20160
20208
 
20161
20209
  // ../../node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.lazy.js
20162
20210
  var __rewriteRelativeImportExtension = function(path2, preserveJsx) {
@@ -20175,22 +20223,22 @@ var bedrockModuleOverride;
20175
20223
  var bedrockConverseStreamApi = () => lazyApi(async () => bedrockModuleOverride ?? await importNodeOnlyApi("./bedrock-converse-stream.ts"));
20176
20224
 
20177
20225
  // ../../node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.lazy.js
20178
- var googleGenerativeAIApi = () => lazyApi(() => import("./google-generative-ai-IOXNKFEV.js"));
20226
+ var googleGenerativeAIApi = () => lazyApi(() => import("./google-generative-ai-R5DASQKW.js"));
20179
20227
 
20180
20228
  // ../../node_modules/@earendil-works/pi-ai/dist/api/google-vertex.lazy.js
20181
- var googleVertexApi = () => lazyApi(() => import("./google-vertex-U4ZV5IXZ.js"));
20229
+ var googleVertexApi = () => lazyApi(() => import("./google-vertex-OLX2NFGJ.js"));
20182
20230
 
20183
20231
  // ../../node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.lazy.js
20184
- var mistralConversationsApi = () => lazyApi(() => import("./mistral-conversations-G3K7SSWR.js"));
20232
+ var mistralConversationsApi = () => lazyApi(() => import("./mistral-conversations-L6T7EWC2.js"));
20185
20233
 
20186
20234
  // ../../node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.lazy.js
20187
- var openAICodexResponsesApi = () => lazyApi(() => import("./openai-codex-responses-4JJLPTCS.js"));
20235
+ var openAICodexResponsesApi = () => lazyApi(() => import("./openai-codex-responses-7QJMWGY5.js"));
20188
20236
 
20189
20237
  // ../../node_modules/@earendil-works/pi-ai/dist/api/openai-completions.lazy.js
20190
- var openAICompletionsApi = () => lazyApi(() => import("./openai-completions-PH4WW6E7.js"));
20238
+ var openAICompletionsApi = () => lazyApi(() => import("./openai-completions-75YD6VJJ.js"));
20191
20239
 
20192
20240
  // ../../node_modules/@earendil-works/pi-ai/dist/api/openai-responses.lazy.js
20193
- var openAIResponsesApi = () => lazyApi(() => import("./openai-responses-KGWAX6HR.js"));
20241
+ var openAIResponsesApi = () => lazyApi(() => import("./openai-responses-G6MVJCGC.js"));
20194
20242
 
20195
20243
  // ../../node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.js
20196
20244
  var piMessagesApi = () => lazyApi(() => import("./pi-messages-ZX3KUWSZ.js"));
@@ -51496,8 +51544,68 @@ var import_yaml2 = __toESM(require_dist(), 1);
51496
51544
  var DEFAULT_MAX_BYTES = 50 * 1024;
51497
51545
  var runtimeBuffer = globalThis.Buffer;
51498
51546
 
51547
+ // ../linkque-agent-runtime/dist/esm/impl/agent/pi/llmRequestThrottle.js
51548
+ var DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS = 1e3;
51549
+ var LlmRequestThrottle = class {
51550
+ minIntervalMs;
51551
+ now;
51552
+ delay;
51553
+ onDelay;
51554
+ queue = Promise.resolve();
51555
+ nextRequestAt = 0;
51556
+ constructor(options = {}) {
51557
+ const configured = options.minIntervalMs ?? DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS;
51558
+ this.minIntervalMs = Number.isFinite(configured) && configured > 0 ? Math.floor(configured) : 0;
51559
+ this.now = options.now ?? Date.now;
51560
+ this.delay = options.delay ?? delayWithSignal;
51561
+ this.onDelay = options.onDelay ?? (() => {
51562
+ });
51563
+ }
51564
+ /** 等到当前请求允许启动;取消信号会中断尚未开始的等待。 */
51565
+ waitForTurn(signal) {
51566
+ const scheduled = this.queue.then(async () => {
51567
+ signal?.throwIfAborted();
51568
+ const delayMs = Math.max(0, this.nextRequestAt - this.now());
51569
+ if (delayMs > 0) {
51570
+ this.onDelay(delayMs);
51571
+ await this.delay(delayMs, signal);
51572
+ }
51573
+ signal?.throwIfAborted();
51574
+ this.nextRequestAt = this.now() + this.minIntervalMs;
51575
+ });
51576
+ this.queue = scheduled.catch(() => void 0);
51577
+ return scheduled;
51578
+ }
51579
+ };
51580
+ function delayWithSignal(delayMs, signal) {
51581
+ return new Promise((resolve, reject) => {
51582
+ if (signal?.aborted) {
51583
+ reject(signal.reason);
51584
+ return;
51585
+ }
51586
+ const timer = setTimeout(() => {
51587
+ signal?.removeEventListener("abort", onAbort);
51588
+ resolve();
51589
+ }, delayMs);
51590
+ const onAbort = () => {
51591
+ clearTimeout(timer);
51592
+ reject(signal?.reason);
51593
+ };
51594
+ signal?.addEventListener("abort", onAbort, { once: true });
51595
+ });
51596
+ }
51597
+
51499
51598
  // ../linkque-agent-runtime/dist/esm/impl/agent/pi/createAgentSession.js
51500
51599
  async function createAgentSession(options) {
51600
+ const llmThrottle = new LlmRequestThrottle({
51601
+ minIntervalMs: options.llmRequestMinIntervalMs ?? DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS,
51602
+ onDelay: (delayMs) => {
51603
+ try {
51604
+ options.debugLog?.(`[llm-throttle] wait ${delayMs}ms before next request`, EDebugLogScope.LLM);
51605
+ } catch {
51606
+ }
51607
+ }
51608
+ });
51501
51609
  const agent = new Agent({
51502
51610
  initialState: {
51503
51611
  model: options.model,
@@ -51517,28 +51625,30 @@ async function createAgentSession(options) {
51517
51625
  // 不 await/转换(否则破坏 stream)。
51518
51626
  streamFn: (model, context, streamOptions) => {
51519
51627
  const logSink = options.debugLog;
51520
- if (!logSink) {
51521
- return options.models.streamSimple(model, context, streamOptions);
51522
- }
51523
51628
  const opts = { ...streamOptions };
51524
- const baseUrl = model.baseUrl ?? "<unknown>";
51525
- const prevOnPayload = opts.onPayload;
51526
- opts.onPayload = async (payload, m) => {
51527
- await prevOnPayload?.(payload, m);
51528
- try {
51529
- logSink(formatHttpLogLine("llm", "req", `POST ${baseUrl} model=${m.id} payload=${summarizeBody(safeStringifyPayload(payload))}`), EDebugLogScope.LLM);
51530
- } catch {
51531
- }
51532
- };
51533
- const prevOnResponse = opts.onResponse;
51534
- opts.onResponse = async (response, m) => {
51535
- await prevOnResponse?.(response, m);
51536
- try {
51537
- logSink(formatHttpLogLine("llm", "resp", `POST ${baseUrl} model=${m.id} ${response.status} headers=${redactHeaders(response.headers)}`), EDebugLogScope.LLM);
51538
- } catch {
51539
- }
51540
- };
51541
- return options.models.streamSimple(model, context, opts);
51629
+ if (logSink) {
51630
+ const baseUrl = model.baseUrl ?? "<unknown>";
51631
+ const prevOnPayload = opts.onPayload;
51632
+ opts.onPayload = async (payload, m) => {
51633
+ await prevOnPayload?.(payload, m);
51634
+ try {
51635
+ logSink(formatHttpLogLine("llm", "req", `POST ${baseUrl} model=${m.id} payload=${summarizeBody(safeStringifyPayload(payload))}`), EDebugLogScope.LLM);
51636
+ } catch {
51637
+ }
51638
+ };
51639
+ const prevOnResponse = opts.onResponse;
51640
+ opts.onResponse = async (response, m) => {
51641
+ await prevOnResponse?.(response, m);
51642
+ try {
51643
+ logSink(formatHttpLogLine("llm", "resp", `POST ${baseUrl} model=${m.id} ${response.status} headers=${redactHeaders(response.headers)}`), EDebugLogScope.LLM);
51644
+ } catch {
51645
+ }
51646
+ };
51647
+ }
51648
+ return lazyStream(model, async () => {
51649
+ await llmThrottle.waitForTurn(opts.signal);
51650
+ return options.models.streamSimple(model, context, opts);
51651
+ });
51542
51652
  },
51543
51653
  getApiKey: options.getApiKey
51544
51654
  });
@@ -52805,6 +52915,8 @@ var AgentRuntime = class _AgentRuntime {
52805
52915
  hookMetricsSink;
52806
52916
  /** 装配期固化的统一诊断 sink(逐 run options.debugLog 可覆盖)。 */
52807
52917
  portsDebugLog;
52918
+ /** 插件处理后、runtime 实际使用的完整 Agent Config JSON 快照。 */
52919
+ effectiveAgentConfigJson;
52808
52920
  // —— 从 IAgentProtocol 提取并固化的运行期默认(经 create 注入)——
52809
52921
  /** systemPrompt 默认(来自 protocol.agent.systemPrompt.content)。 */
52810
52922
  defaultSystemPrompt = "";
@@ -52888,6 +53000,11 @@ var AgentRuntime = class _AgentRuntime {
52888
53000
  rt.agentId = agentConfig.agentId;
52889
53001
  rt.followUpQuestionGenerationEnabled = followUpQuestionGenerationEnabled;
52890
53002
  rt.hookResources = normalizeHookResources(agentConfig.agent.resources.filter((r) => r.resourceType === EResourceType.HOOK));
53003
+ try {
53004
+ rt.effectiveAgentConfigJson = JSON.stringify(agentConfig);
53005
+ } catch {
53006
+ rt.effectiveAgentConfigJson = void 0;
53007
+ }
52891
53008
  return rt;
52892
53009
  }
52893
53010
  async prepareFollowUpQuestionContext(sessionId, history = []) {
@@ -52908,6 +53025,12 @@ var AgentRuntime = class _AgentRuntime {
52908
53025
  async *runAgentLoop(request, auth2, options = {}) {
52909
53026
  const sessionId = options.sessionId;
52910
53027
  const debugLog = options.debugLog ?? this.portsDebugLog;
53028
+ if (debugLog) {
53029
+ try {
53030
+ debugLog(this.effectiveAgentConfigJson === void 0 ? "[agent-config] final=<Agent Config \u5E8F\u5217\u5316\u5931\u8D25\uFF0C\u65E0\u6CD5\u6253\u5370\u5B8C\u6574\u5185\u5BB9>" : `[agent-config] final=${this.effectiveAgentConfigJson}`, EDebugLogScope.CONFIG);
53031
+ } catch {
53032
+ }
53033
+ }
52911
53034
  const newTurns = request.messages.map((m) => ({
52912
53035
  role: m.role,
52913
53036
  content: m.content,
@@ -53015,6 +53138,19 @@ var AgentRuntime = class _AgentRuntime {
53015
53138
  let assistantText = "";
53016
53139
  let failed = false;
53017
53140
  let runError;
53141
+ let terminalHookDispatched = false;
53142
+ const dispatchTerminalHook = async () => {
53143
+ if (terminalHookDispatched || hookDispatcher.isEmpty)
53144
+ return;
53145
+ terminalHookDispatched = true;
53146
+ if (failed) {
53147
+ await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, {
53148
+ error: runError ?? { message: "unknown error" }
53149
+ });
53150
+ return;
53151
+ }
53152
+ await hookDispatcher.dispatch(EHookStage.RUN_COMPLETED, hookCommonParams, { runDurationMs: Date.now() - runStartedAt });
53153
+ };
53018
53154
  try {
53019
53155
  for await (const ev of this.agentLoop.run(agentReq)) {
53020
53156
  if (ev.type === "delta")
@@ -53022,6 +53158,7 @@ var AgentRuntime = class _AgentRuntime {
53022
53158
  if (ev.type === "error") {
53023
53159
  failed = true;
53024
53160
  runError = { message: ev.error.message, code: ev.error.code };
53161
+ await dispatchTerminalHook();
53025
53162
  }
53026
53163
  if (ev.type === "done" && !failed && sessionId !== void 0) {
53027
53164
  const completedTurns = [
@@ -53036,22 +53173,18 @@ var AgentRuntime = class _AgentRuntime {
53036
53173
  }
53037
53174
  }
53038
53175
  }
53176
+ if (ev.type === "done")
53177
+ await dispatchTerminalHook();
53039
53178
  yield ev;
53040
53179
  }
53041
- if (!hookDispatcher.isEmpty) {
53042
- if (failed) {
53043
- await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, { error: runError ?? { message: "unknown error" } });
53044
- } else {
53045
- await hookDispatcher.dispatch(EHookStage.RUN_COMPLETED, hookCommonParams, { runDurationMs: Date.now() - runStartedAt });
53046
- }
53047
- }
53180
+ await dispatchTerminalHook();
53048
53181
  } catch (error) {
53049
- if (!hookDispatcher.isEmpty) {
53050
- await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, {
53051
- error: {
53052
- message: error instanceof Error ? error.message : String(error)
53053
- }
53054
- });
53182
+ if (!terminalHookDispatched) {
53183
+ failed = true;
53184
+ runError = {
53185
+ message: error instanceof Error ? error.message : String(error)
53186
+ };
53187
+ await dispatchTerminalHook();
53055
53188
  }
53056
53189
  throw error;
53057
53190
  } finally {
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-CT4G24PS.js";
10
10
  import {
11
11
  calculateCost
12
- } from "./chunk-3S3TOEBZ.js";
12
+ } from "./chunk-Y3G4J3TB.js";
13
13
  import {
14
14
  parseStreamingJson
15
15
  } from "./chunk-DYEQRE6N.js";
@@ -600,6 +600,7 @@ function clampThinkingLevel(model, level) {
600
600
  }
601
601
 
602
602
  export {
603
+ lazyStream,
603
604
  lazyApi,
604
605
  createModels,
605
606
  createProvider,
@@ -24,7 +24,7 @@ import {
24
24
  import {
25
25
  calculateCost,
26
26
  clampThinkingLevel
27
- } from "./chunk-3S3TOEBZ.js";
27
+ } from "./chunk-Y3G4J3TB.js";
28
28
  import {
29
29
  AssistantMessageEventStream
30
30
  } from "./chunk-46SEH6ER.js";
@@ -26,7 +26,7 @@ import {
26
26
  import {
27
27
  calculateCost,
28
28
  clampThinkingLevel
29
- } from "./chunk-3S3TOEBZ.js";
29
+ } from "./chunk-Y3G4J3TB.js";
30
30
  import {
31
31
  getProviderEnvValue
32
32
  } from "./chunk-OXGCUIKV.js";
@@ -73,7 +73,7 @@ import {
73
73
  import {
74
74
  calculateCost,
75
75
  clampThinkingLevel
76
- } from "./chunk-3S3TOEBZ.js";
76
+ } from "./chunk-Y3G4J3TB.js";
77
77
  import {
78
78
  parseStreamingJson
79
79
  } from "./chunk-DYEQRE6N.js";
@@ -13,7 +13,7 @@ import {
13
13
  convertResponsesMessages,
14
14
  convertResponsesTools,
15
15
  processResponsesStream
16
- } from "./chunk-IKZ25GJD.js";
16
+ } from "./chunk-LSBJJGJC.js";
17
17
  import "./chunk-UFVAKOTZ.js";
18
18
  import {
19
19
  clampOpenAIPromptCacheKey
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-Y6UTJIT4.js";
32
32
  import {
33
33
  clampThinkingLevel
34
- } from "./chunk-3S3TOEBZ.js";
34
+ } from "./chunk-Y3G4J3TB.js";
35
35
  import {
36
36
  getProviderEnvValue
37
37
  } from "./chunk-OXGCUIKV.js";
@@ -25,7 +25,7 @@ import {
25
25
  import {
26
26
  calculateCost,
27
27
  clampThinkingLevel
28
- } from "./chunk-3S3TOEBZ.js";
28
+ } from "./chunk-Y3G4J3TB.js";
29
29
  import {
30
30
  getProviderEnvValue
31
31
  } from "./chunk-OXGCUIKV.js";
@@ -9,7 +9,7 @@ import {
9
9
  convertResponsesMessages,
10
10
  convertResponsesTools,
11
11
  processResponsesStream
12
- } from "./chunk-IKZ25GJD.js";
12
+ } from "./chunk-LSBJJGJC.js";
13
13
  import "./chunk-UFVAKOTZ.js";
14
14
  import {
15
15
  OpenAI
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-Y6UTJIT4.js";
31
31
  import {
32
32
  clampThinkingLevel
33
- } from "./chunk-3S3TOEBZ.js";
33
+ } from "./chunk-Y3G4J3TB.js";
34
34
  import {
35
35
  getProviderEnvValue
36
36
  } from "./chunk-OXGCUIKV.js";
@@ -51,12 +51,12 @@ import {
51
51
  parseConversationRunRequest,
52
52
  parseSkillFile,
53
53
  streamToConversationEvents
54
- } from "../../chunk-XGIMLCNP.js";
54
+ } from "../../chunk-IMZDZMKV.js";
55
55
  import "../../chunk-XUFLSZM4.js";
56
56
  import "../../chunk-I64V3ICJ.js";
57
57
  import "../../chunk-6MHDOBWO.js";
58
58
  import "../../chunk-E2P6TIFG.js";
59
- import "../../chunk-3S3TOEBZ.js";
59
+ import "../../chunk-Y3G4J3TB.js";
60
60
  import "../../chunk-OXGCUIKV.js";
61
61
  import "../../chunk-DYEQRE6N.js";
62
62
  import "../../chunk-46SEH6ER.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getBakedProtocol,
3
3
  setBakedProtocol
4
- } from "../chunk-XGIMLCNP.js";
4
+ } from "../chunk-IMZDZMKV.js";
5
5
  import "../chunk-XUFLSZM4.js";
6
6
  import "../chunk-I64V3ICJ.js";
7
7
  import "../chunk-6MHDOBWO.js";
8
8
  import "../chunk-E2P6TIFG.js";
9
- import "../chunk-3S3TOEBZ.js";
9
+ import "../chunk-Y3G4J3TB.js";
10
10
  import "../chunk-OXGCUIKV.js";
11
11
  import "../chunk-DYEQRE6N.js";
12
12
  import "../chunk-46SEH6ER.js";
package/worker.js CHANGED
@@ -4981,6 +4981,7 @@ var init_types2 = __esm({
4981
4981
  "../linkque-agent-runtime/dist/esm/core/types.js"() {
4982
4982
  "use strict";
4983
4983
  (function(EDebugLogScope2) {
4984
+ EDebugLogScope2["CONFIG"] = "CONFIG";
4984
4985
  EDebugLogScope2["LLM"] = "LLM";
4985
4986
  EDebugLogScope2["PI_EVENT"] = "PI_EVENT";
4986
4987
  EDebugLogScope2["MCP"] = "MCP";
@@ -13821,6 +13822,7 @@ function analyzeA2UIBindings(protocol) {
13821
13822
  const listRoots = inferListRoots(components, issues);
13822
13823
  for (const component of components) {
13823
13824
  const context2 = {
13825
+ surfaceId,
13824
13826
  component,
13825
13827
  listRoot: listRoots.get(component.id),
13826
13828
  occurrences,
@@ -13834,6 +13836,7 @@ function analyzeA2UIBindings(protocol) {
13834
13836
  issues.push(issue2(`card.surfaces.${surfaceId}.components.${component.id}.children.path`, "INVALID_BINDING_PATH", `Invalid list path ${children.path}`));
13835
13837
  } else {
13836
13838
  occurrences.push({
13839
+ surfaceId,
13837
13840
  componentId: component.id,
13838
13841
  componentName: component.component,
13839
13842
  propertyPath: "children.path",
@@ -13852,6 +13855,16 @@ function analyzeA2UIBindings(protocol) {
13852
13855
  issues
13853
13856
  };
13854
13857
  }
13858
+ function collectReferencedA2UICardBusinessFieldIds(protocol, fields) {
13859
+ const businessFields = fields.filter((field) => field.source === "business").slice().sort((left, right) => right.path.length - left.path.length);
13860
+ const result = /* @__PURE__ */ new Set();
13861
+ for (const occurrence of analyzeA2UIBindings(protocol).occurrences) {
13862
+ const field = businessFields.find((candidate) => occurrence.canonicalPath === candidate.path || occurrence.canonicalPath.startsWith(`${candidate.path}/*/`) || occurrence.canonicalPath.startsWith(`${candidate.path}/`));
13863
+ if (field)
13864
+ result.add(field.fieldId);
13865
+ }
13866
+ return result;
13867
+ }
13855
13868
  function visitValue(value, propertyPath, context2) {
13856
13869
  if (propertyPath === "action.local.path" && typeof value === "string") {
13857
13870
  addOccurrence(value, propertyPath, "local", context2);
@@ -13883,6 +13896,7 @@ function addOccurrence(rawPath, propertyPath, usage, context2) {
13883
13896
  return;
13884
13897
  }
13885
13898
  context2.occurrences.push({
13899
+ surfaceId: context2.surfaceId,
13886
13900
  componentId: context2.component.id,
13887
13901
  componentName: context2.component.component,
13888
13902
  propertyPath,
@@ -14257,6 +14271,7 @@ var init_binding_context = __esm({
14257
14271
  init_json2();
14258
14272
  init_schema2();
14259
14273
  init_expression();
14274
+ init_binding_analyzer();
14260
14275
  }
14261
14276
  });
14262
14277
 
@@ -14308,9 +14323,9 @@ function getA2UICardResourceConfigIssues(value) {
14308
14323
  validateLooseJsonSchema(value.presentationInputSchema, "config.presentationInputSchema", issues);
14309
14324
  const fields = validateFields(value.fields, "config.fields", issues);
14310
14325
  const resolver = validateResolver(value.resolver, "config.resolver", issues);
14311
- validateTemplate(value.a2uiTemplate, fields, issues);
14326
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
14312
14327
  if (fields && resolver)
14313
- validateResolverCoverage(fields, resolver, issues);
14328
+ validateResolverCoverage(fields, resolver, issues, card);
14314
14329
  return issues;
14315
14330
  }
14316
14331
  function getA2UICardResourceConfigV3Issues(value) {
@@ -14343,9 +14358,9 @@ function getA2UICardResourceConfigV3Issues(value) {
14343
14358
  }
14344
14359
  const dataSources = validateDataSources(value.dataSources, "config.dataSources", issues);
14345
14360
  const bindings = validateV3OutputBindings(value.bindings, "config.bindings", issues);
14346
- validateTemplate(value.a2uiTemplate, fields, issues);
14361
+ const card = validateTemplate(value.a2uiTemplate, fields, issues);
14347
14362
  if (fields && dataSources && bindings) {
14348
- validateV3Coverage(fields, dataSources, bindings, issues);
14363
+ validateV3Coverage(fields, dataSources, bindings, issues, { card });
14349
14364
  }
14350
14365
  return issues;
14351
14366
  }
@@ -14459,7 +14474,8 @@ function validateV3Coverage(fields, dataSources, bindings, issues, options = {})
14459
14474
  bound.add(binding.fieldId);
14460
14475
  });
14461
14476
  if (options.requireComplete !== false) {
14462
- for (const fieldId of businessFields) {
14477
+ const requiredFields = options.card ? collectReferencedA2UICardBusinessFieldIds(options.card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
14478
+ for (const fieldId of requiredFields) {
14463
14479
  if (bound.has(fieldId))
14464
14480
  continue;
14465
14481
  issues.push(issue2("config.bindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
@@ -14759,13 +14775,13 @@ function validateInstructionShape(instruction, path6, issues) {
14759
14775
  function validateTemplate(value, fields, issues) {
14760
14776
  if (!isPlainRecord(value)) {
14761
14777
  issues.push(issue2("config.a2uiTemplate", "INVALID_A2UI_TEMPLATE", "a2uiTemplate must be an object"));
14762
- return;
14778
+ return void 0;
14763
14779
  }
14764
14780
  exactKeys(value, ["argsSchema", "content"], "config.a2uiTemplate", issues);
14765
14781
  validateLooseJsonSchema(value.argsSchema, "config.a2uiTemplate.argsSchema", issues);
14766
14782
  if (typeof value.content !== "string") {
14767
14783
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must be serialized A2UI JSON"));
14768
- return;
14784
+ return void 0;
14769
14785
  }
14770
14786
  try {
14771
14787
  const card = validateProtocol(JSON.parse(value.content), "config.a2uiTemplate.content", issues);
@@ -14773,9 +14789,11 @@ function validateTemplate(value, fields, issues) {
14773
14789
  const analysis = analyzeA2UIBindings(card);
14774
14790
  issues.push(...analysis.issues);
14775
14791
  }
14792
+ return card;
14776
14793
  } catch {
14777
14794
  issues.push(issue2("config.a2uiTemplate.content", "INVALID_A2UI_CONTENT", "a2uiTemplate.content must contain valid JSON"));
14778
14795
  }
14796
+ return void 0;
14779
14797
  }
14780
14798
  function validateLooseJsonSchema(value, path6, issues) {
14781
14799
  const schemaIssues = getJsonSchemaIssues2(value, path6, {
@@ -14784,7 +14802,7 @@ function validateLooseJsonSchema(value, path6, issues) {
14784
14802
  issues.push(...schemaIssues);
14785
14803
  return schemaIssues.length === 0;
14786
14804
  }
14787
- function validateResolverCoverage(fields, resolver, issues) {
14805
+ function validateResolverCoverage(fields, resolver, issues, card) {
14788
14806
  const businessFields = new Set(fields.filter((field) => field.source === "business").map((field) => field.fieldId));
14789
14807
  const bound = /* @__PURE__ */ new Set();
14790
14808
  resolver.outputBindings.forEach((binding, index2) => {
@@ -14793,7 +14811,8 @@ function validateResolverCoverage(fields, resolver, issues) {
14793
14811
  }
14794
14812
  bound.add(binding.fieldId);
14795
14813
  });
14796
- for (const fieldId of businessFields) {
14814
+ const requiredFields = card ? collectReferencedA2UICardBusinessFieldIds(card, fields.filter((field) => field.required)) : new Set(fields.filter((field) => field.source === "business" && field.required).map((field) => field.fieldId));
14815
+ for (const fieldId of requiredFields) {
14797
14816
  if (!bound.has(fieldId)) {
14798
14817
  issues.push(issue2("config.resolver.outputBindings", "CARD_BINDING_INCOMPLETE", `business field ${fieldId} is not bound`));
14799
14818
  }
@@ -14846,6 +14865,7 @@ var init_compiler = __esm({
14846
14865
  "../agent-a2ui-card-contract/dist/esm/compiler.js"() {
14847
14866
  "use strict";
14848
14867
  init_json2();
14868
+ init_binding_analyzer();
14849
14869
  init_validation();
14850
14870
  init_schema2();
14851
14871
  }
@@ -15069,6 +15089,25 @@ var init_template = __esm({
15069
15089
  }
15070
15090
  });
15071
15091
 
15092
+ // ../agent-a2ui-card-contract/dist/esm/authoring-model.js
15093
+ var init_authoring_model = __esm({
15094
+ "../agent-a2ui-card-contract/dist/esm/authoring-model.js"() {
15095
+ "use strict";
15096
+ init_binding_analyzer();
15097
+ init_json2();
15098
+ init_validation();
15099
+ }
15100
+ });
15101
+
15102
+ // ../agent-a2ui-card-contract/dist/esm/authoring-operation.js
15103
+ var init_authoring_operation = __esm({
15104
+ "../agent-a2ui-card-contract/dist/esm/authoring-operation.js"() {
15105
+ "use strict";
15106
+ init_authoring_model();
15107
+ init_json2();
15108
+ }
15109
+ });
15110
+
15072
15111
  // ../agent-a2ui-card-contract/dist/esm/index.js
15073
15112
  var init_esm4 = __esm({
15074
15113
  "../agent-a2ui-card-contract/dist/esm/index.js"() {
@@ -15086,6 +15125,8 @@ var init_esm4 = __esm({
15086
15125
  init_binding_context();
15087
15126
  init_preview_binding();
15088
15127
  init_template();
15128
+ init_authoring_model();
15129
+ init_authoring_operation();
15089
15130
  }
15090
15131
  });
15091
15132
 
@@ -15466,6 +15507,9 @@ function parseProxyArgs(args) {
15466
15507
  out.describe = args.describe;
15467
15508
  if (typeof args.search === "string")
15468
15509
  out.search = args.search;
15510
+ if (Array.isArray(args.searches)) {
15511
+ out.searches = args.searches.filter((query) => typeof query === "string").slice(0, MCP_BATCH_SEARCH_MAX_ITEMS);
15512
+ }
15469
15513
  if (typeof args.tool === "string")
15470
15514
  out.tool = args.tool;
15471
15515
  if (typeof args.server === "string")
@@ -15509,7 +15553,7 @@ function truncate(text, max2) {
15509
15553
  function isRecord2(value) {
15510
15554
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
15511
15555
  }
15512
- var MCP_PROXY_TOOL_NAME, McpProxyTool, MCP_PROXY_DESCRIPTION, MCP_PROXY_INPUT_SCHEMA;
15556
+ var MCP_PROXY_TOOL_NAME, McpProxyTool, MCP_BATCH_SEARCH_MAX_ITEMS, MCP_PROXY_DESCRIPTION, MCP_PROXY_INPUT_SCHEMA;
15513
15557
  var init_mcpProxyTool = __esm({
15514
15558
  "../linkque-agent-runtime/dist/esm/core/mcpProxyTool.js"() {
15515
15559
  "use strict";
@@ -15654,6 +15698,9 @@ var init_mcpProxyTool = __esm({
15654
15698
  if (params.describe !== void 0) {
15655
15699
  return this.executeDescribe(params.describe, params.server, signal);
15656
15700
  }
15701
+ if (params.searches !== void 0) {
15702
+ return this.executeBatchSearch(params.searches, params.server);
15703
+ }
15657
15704
  if (params.search !== void 0) {
15658
15705
  return this.executeSearch(params.search, params.server);
15659
15706
  }
@@ -15750,6 +15797,20 @@ ${formatSchema(tool.inputSchema, " ")}`);
15750
15797
  }
15751
15798
  return lines.join("\n").trim();
15752
15799
  }
15800
+ /** `mcp({ searches: [...] })`:一次连接元数据并按 query 分组执行多组搜索。 */
15801
+ async executeBatchSearch(queries, serverHint) {
15802
+ const normalized = [
15803
+ ...new Set(queries.map((query) => query.trim()).filter(Boolean))
15804
+ ].slice(0, MCP_BATCH_SEARCH_MAX_ITEMS);
15805
+ if (normalized.length === 0) {
15806
+ return "Batch search requires at least one non-empty query.";
15807
+ }
15808
+ const specs = serverHint ? this.specsMatching(serverHint) : this.specs;
15809
+ await Promise.all(specs.map((spec) => this.ensureEntry(spec.serverName)));
15810
+ const results = await Promise.all(normalized.map((query) => this.executeSearch(query, serverHint)));
15811
+ return results.map((result, index2) => `Query ${index2 + 1}: "${normalized[index2]}"
15812
+ ${result}`).join("\n\n");
15813
+ }
15753
15814
  /** `mcp({ describe: "tool" })`:输出工具所属 server + 参数 schema。 */
15754
15815
  async executeDescribe(toolName, serverHint, signal) {
15755
15816
  const found = await this.findTool(toolName, serverHint, signal);
@@ -15831,12 +15892,14 @@ ${formatSchema(tool.inputSchema)}`);
15831
15892
  return lines.join("\n").trim();
15832
15893
  }
15833
15894
  };
15895
+ MCP_BATCH_SEARCH_MAX_ITEMS = 5;
15834
15896
  MCP_PROXY_DESCRIPTION = [
15835
15897
  "MCP \u7F51\u5173:\u53D1\u73B0\u5E76\u8C03\u7528 MCP server \u63D0\u4F9B\u7684\u5DE5\u5177\u3002\u53EF\u7528\u52A8\u4F5C:",
15836
15898
  "- mcp({}) \u6216 mcp({ status: true }):\u67E5\u770B\u6240\u6709 server \u8FDE\u63A5\u72B6\u6001\u4E0E\u5DE5\u5177\u6570\u3002",
15837
15899
  '- mcp({ connect: "server" }):\u8FDE\u63A5\u5E76\u5237\u65B0\u67D0 server \u7684\u5DE5\u5177\u5217\u8868\u3002',
15838
15900
  '- mcp({ server: "name" }):\u5217\u51FA\u8BE5 server \u7684\u5DE5\u5177\u3002',
15839
15901
  '- mcp({ search: "\u5173\u952E\u8BCD" }):\u6309\u540D\u79F0/\u63CF\u8FF0\u6A21\u7CCA\u641C\u7D22\u5DE5\u5177(\u7A7A\u683C\u5206\u8BCD OR)\u3002',
15902
+ '- mcp({ searches: ["\u5173\u952E\u8BCD1", "\u5173\u952E\u8BCD2"] }):\u4E00\u6B21\u6267\u884C\u591A\u7EC4\u641C\u7D22\u5E76\u6309 query \u5206\u7EC4\u8FD4\u56DE(\u6700\u591A 5 \u7EC4)\u3002',
15840
15903
  '- mcp({ describe: "toolName" }):\u67E5\u770B\u67D0\u5DE5\u5177\u7684\u53C2\u6570 schema\u3002',
15841
15904
  '- mcp({ tool: "toolName", args: { ... } }):\u8C03\u7528\u67D0\u5DE5\u5177,args \u4E3A\u5BF9\u8C61\u3002',
15842
15905
  "\u53EF\u7528 server \u540D\u89C1 mcp({}) \u8F93\u51FA\u3002\u4EC5\u5728\u786E\u9700\u8C03\u7528 MCP \u5DE5\u5177\u65F6\u4F7F\u7528\u672C\u5DE5\u5177\u3002",
@@ -15859,6 +15922,13 @@ ${formatSchema(tool.inputSchema)}`);
15859
15922
  type: "string",
15860
15923
  description: "\u6309\u540D\u79F0/\u63CF\u8FF0\u6A21\u7CCA\u641C\u7D22\u5DE5\u5177(\u7A7A\u683C\u5206\u8BCD OR)"
15861
15924
  },
15925
+ searches: {
15926
+ type: "array",
15927
+ description: "\u6279\u91CF\u641C\u7D22\u5173\u952E\u8BCD\uFF1B\u4E00\u6B21\u63D0\u4EA4\u6240\u6709\u5019\u9009 query\uFF0C\u6309 query \u5206\u7EC4\u8FD4\u56DE",
15928
+ minItems: 1,
15929
+ maxItems: MCP_BATCH_SEARCH_MAX_ITEMS,
15930
+ items: { type: "string", minLength: 1 }
15931
+ },
15862
15932
  describe: { type: "string", description: "\u67E5\u770B\u67D0\u5DE5\u5177\u7684\u53C2\u6570 schema" },
15863
15933
  tool: { type: "string", description: "\u8981\u8C03\u7528\u7684\u5DE5\u5177\u540D(\u53EF\u914D\u5408 server \u6D88\u6B67)" },
15864
15934
  args: {
@@ -187318,8 +187388,74 @@ var init_dist4 = __esm({
187318
187388
  }
187319
187389
  });
187320
187390
 
187391
+ // ../linkque-agent-runtime/dist/esm/impl/agent/pi/llmRequestThrottle.js
187392
+ function delayWithSignal(delayMs, signal) {
187393
+ return new Promise((resolve, reject) => {
187394
+ if (signal?.aborted) {
187395
+ reject(signal.reason);
187396
+ return;
187397
+ }
187398
+ const timer = setTimeout(() => {
187399
+ signal?.removeEventListener("abort", onAbort);
187400
+ resolve();
187401
+ }, delayMs);
187402
+ const onAbort = () => {
187403
+ clearTimeout(timer);
187404
+ reject(signal?.reason);
187405
+ };
187406
+ signal?.addEventListener("abort", onAbort, { once: true });
187407
+ });
187408
+ }
187409
+ var DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS, LlmRequestThrottle;
187410
+ var init_llmRequestThrottle = __esm({
187411
+ "../linkque-agent-runtime/dist/esm/impl/agent/pi/llmRequestThrottle.js"() {
187412
+ "use strict";
187413
+ DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS = 1e3;
187414
+ LlmRequestThrottle = class {
187415
+ minIntervalMs;
187416
+ now;
187417
+ delay;
187418
+ onDelay;
187419
+ queue = Promise.resolve();
187420
+ nextRequestAt = 0;
187421
+ constructor(options = {}) {
187422
+ const configured = options.minIntervalMs ?? DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS;
187423
+ this.minIntervalMs = Number.isFinite(configured) && configured > 0 ? Math.floor(configured) : 0;
187424
+ this.now = options.now ?? Date.now;
187425
+ this.delay = options.delay ?? delayWithSignal;
187426
+ this.onDelay = options.onDelay ?? (() => {
187427
+ });
187428
+ }
187429
+ /** 等到当前请求允许启动;取消信号会中断尚未开始的等待。 */
187430
+ waitForTurn(signal) {
187431
+ const scheduled = this.queue.then(async () => {
187432
+ signal?.throwIfAborted();
187433
+ const delayMs = Math.max(0, this.nextRequestAt - this.now());
187434
+ if (delayMs > 0) {
187435
+ this.onDelay(delayMs);
187436
+ await this.delay(delayMs, signal);
187437
+ }
187438
+ signal?.throwIfAborted();
187439
+ this.nextRequestAt = this.now() + this.minIntervalMs;
187440
+ });
187441
+ this.queue = scheduled.catch(() => void 0);
187442
+ return scheduled;
187443
+ }
187444
+ };
187445
+ }
187446
+ });
187447
+
187321
187448
  // ../linkque-agent-runtime/dist/esm/impl/agent/pi/createAgentSession.js
187322
187449
  async function createAgentSession(options) {
187450
+ const llmThrottle = new LlmRequestThrottle({
187451
+ minIntervalMs: options.llmRequestMinIntervalMs ?? DEFAULT_LLM_REQUEST_MIN_INTERVAL_MS,
187452
+ onDelay: (delayMs) => {
187453
+ try {
187454
+ options.debugLog?.(`[llm-throttle] wait ${delayMs}ms before next request`, EDebugLogScope.LLM);
187455
+ } catch {
187456
+ }
187457
+ }
187458
+ });
187323
187459
  const agent = new Agent({
187324
187460
  initialState: {
187325
187461
  model: options.model,
@@ -187339,28 +187475,30 @@ async function createAgentSession(options) {
187339
187475
  // 不 await/转换(否则破坏 stream)。
187340
187476
  streamFn: (model, context2, streamOptions) => {
187341
187477
  const logSink = options.debugLog;
187342
- if (!logSink) {
187343
- return options.models.streamSimple(model, context2, streamOptions);
187344
- }
187345
187478
  const opts = { ...streamOptions };
187346
- const baseUrl = model.baseUrl ?? "<unknown>";
187347
- const prevOnPayload = opts.onPayload;
187348
- opts.onPayload = async (payload, m2) => {
187349
- await prevOnPayload?.(payload, m2);
187350
- try {
187351
- logSink(formatHttpLogLine("llm", "req", `POST ${baseUrl} model=${m2.id} payload=${summarizeBody(safeStringifyPayload(payload))}`), EDebugLogScope.LLM);
187352
- } catch {
187353
- }
187354
- };
187355
- const prevOnResponse = opts.onResponse;
187356
- opts.onResponse = async (response, m2) => {
187357
- await prevOnResponse?.(response, m2);
187358
- try {
187359
- logSink(formatHttpLogLine("llm", "resp", `POST ${baseUrl} model=${m2.id} ${response.status} headers=${redactHeaders(response.headers)}`), EDebugLogScope.LLM);
187360
- } catch {
187361
- }
187362
- };
187363
- return options.models.streamSimple(model, context2, opts);
187479
+ if (logSink) {
187480
+ const baseUrl = model.baseUrl ?? "<unknown>";
187481
+ const prevOnPayload = opts.onPayload;
187482
+ opts.onPayload = async (payload, m2) => {
187483
+ await prevOnPayload?.(payload, m2);
187484
+ try {
187485
+ logSink(formatHttpLogLine("llm", "req", `POST ${baseUrl} model=${m2.id} payload=${summarizeBody(safeStringifyPayload(payload))}`), EDebugLogScope.LLM);
187486
+ } catch {
187487
+ }
187488
+ };
187489
+ const prevOnResponse = opts.onResponse;
187490
+ opts.onResponse = async (response, m2) => {
187491
+ await prevOnResponse?.(response, m2);
187492
+ try {
187493
+ logSink(formatHttpLogLine("llm", "resp", `POST ${baseUrl} model=${m2.id} ${response.status} headers=${redactHeaders(response.headers)}`), EDebugLogScope.LLM);
187494
+ } catch {
187495
+ }
187496
+ };
187497
+ }
187498
+ return lazyStream(model, async () => {
187499
+ await llmThrottle.waitForTurn(opts.signal);
187500
+ return options.models.streamSimple(model, context2, opts);
187501
+ });
187364
187502
  },
187365
187503
  getApiKey: options.getApiKey
187366
187504
  });
@@ -187450,9 +187588,11 @@ var init_createAgentSession = __esm({
187450
187588
  "../linkque-agent-runtime/dist/esm/impl/agent/pi/createAgentSession.js"() {
187451
187589
  "use strict";
187452
187590
  init_dist4();
187591
+ init_dist3();
187453
187592
  init_types2();
187454
187593
  init_cardTools();
187455
187594
  init_httpLoggingFetch();
187595
+ init_llmRequestThrottle();
187456
187596
  }
187457
187597
  });
187458
187598
 
@@ -188764,6 +188904,8 @@ var init_agentRuntime = __esm({
188764
188904
  hookMetricsSink;
188765
188905
  /** 装配期固化的统一诊断 sink(逐 run options.debugLog 可覆盖)。 */
188766
188906
  portsDebugLog;
188907
+ /** 插件处理后、runtime 实际使用的完整 Agent Config JSON 快照。 */
188908
+ effectiveAgentConfigJson;
188767
188909
  // —— 从 IAgentProtocol 提取并固化的运行期默认(经 create 注入)——
188768
188910
  /** systemPrompt 默认(来自 protocol.agent.systemPrompt.content)。 */
188769
188911
  defaultSystemPrompt = "";
@@ -188847,6 +188989,11 @@ var init_agentRuntime = __esm({
188847
188989
  rt.agentId = agentConfig.agentId;
188848
188990
  rt.followUpQuestionGenerationEnabled = followUpQuestionGenerationEnabled;
188849
188991
  rt.hookResources = normalizeHookResources(agentConfig.agent.resources.filter((r2) => r2.resourceType === EResourceType.HOOK));
188992
+ try {
188993
+ rt.effectiveAgentConfigJson = JSON.stringify(agentConfig);
188994
+ } catch {
188995
+ rt.effectiveAgentConfigJson = void 0;
188996
+ }
188850
188997
  return rt;
188851
188998
  }
188852
188999
  async prepareFollowUpQuestionContext(sessionId, history = []) {
@@ -188867,6 +189014,12 @@ var init_agentRuntime = __esm({
188867
189014
  async *runAgentLoop(request, auth2, options = {}) {
188868
189015
  const sessionId = options.sessionId;
188869
189016
  const debugLog = options.debugLog ?? this.portsDebugLog;
189017
+ if (debugLog) {
189018
+ try {
189019
+ debugLog(this.effectiveAgentConfigJson === void 0 ? "[agent-config] final=<Agent Config \u5E8F\u5217\u5316\u5931\u8D25\uFF0C\u65E0\u6CD5\u6253\u5370\u5B8C\u6574\u5185\u5BB9>" : `[agent-config] final=${this.effectiveAgentConfigJson}`, EDebugLogScope.CONFIG);
189020
+ } catch {
189021
+ }
189022
+ }
188870
189023
  const newTurns = request.messages.map((m2) => ({
188871
189024
  role: m2.role,
188872
189025
  content: m2.content,
@@ -188974,6 +189127,19 @@ var init_agentRuntime = __esm({
188974
189127
  let assistantText = "";
188975
189128
  let failed = false;
188976
189129
  let runError;
189130
+ let terminalHookDispatched = false;
189131
+ const dispatchTerminalHook = async () => {
189132
+ if (terminalHookDispatched || hookDispatcher.isEmpty)
189133
+ return;
189134
+ terminalHookDispatched = true;
189135
+ if (failed) {
189136
+ await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, {
189137
+ error: runError ?? { message: "unknown error" }
189138
+ });
189139
+ return;
189140
+ }
189141
+ await hookDispatcher.dispatch(EHookStage.RUN_COMPLETED, hookCommonParams, { runDurationMs: Date.now() - runStartedAt });
189142
+ };
188977
189143
  try {
188978
189144
  for await (const ev of this.agentLoop.run(agentReq)) {
188979
189145
  if (ev.type === "delta")
@@ -188981,6 +189147,7 @@ var init_agentRuntime = __esm({
188981
189147
  if (ev.type === "error") {
188982
189148
  failed = true;
188983
189149
  runError = { message: ev.error.message, code: ev.error.code };
189150
+ await dispatchTerminalHook();
188984
189151
  }
188985
189152
  if (ev.type === "done" && !failed && sessionId !== void 0) {
188986
189153
  const completedTurns = [
@@ -188995,22 +189162,18 @@ var init_agentRuntime = __esm({
188995
189162
  }
188996
189163
  }
188997
189164
  }
189165
+ if (ev.type === "done")
189166
+ await dispatchTerminalHook();
188998
189167
  yield ev;
188999
189168
  }
189000
- if (!hookDispatcher.isEmpty) {
189001
- if (failed) {
189002
- await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, { error: runError ?? { message: "unknown error" } });
189003
- } else {
189004
- await hookDispatcher.dispatch(EHookStage.RUN_COMPLETED, hookCommonParams, { runDurationMs: Date.now() - runStartedAt });
189005
- }
189006
- }
189169
+ await dispatchTerminalHook();
189007
189170
  } catch (error40) {
189008
- if (!hookDispatcher.isEmpty) {
189009
- await hookDispatcher.dispatch(EHookStage.RUN_FAILED, hookCommonParams, {
189010
- error: {
189011
- message: error40 instanceof Error ? error40.message : String(error40)
189012
- }
189013
- });
189171
+ if (!terminalHookDispatched) {
189172
+ failed = true;
189173
+ runError = {
189174
+ message: error40 instanceof Error ? error40.message : String(error40)
189175
+ };
189176
+ await dispatchTerminalHook();
189014
189177
  }
189015
189178
  throw error40;
189016
189179
  } finally {