@jsonstudio/llms 0.6.3405 → 0.6.3539

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 (90) hide show
  1. package/dist/conversion/codecs/anthropic-openai-codec.d.ts +12 -3
  2. package/dist/conversion/codecs/anthropic-openai-codec.js +32 -92
  3. package/dist/conversion/codecs/gemini-openai-codec.d.ts +6 -5
  4. package/dist/conversion/codecs/gemini-openai-codec.js +48 -685
  5. package/dist/conversion/codecs/openai-openai-codec.d.ts +1 -1
  6. package/dist/conversion/codecs/openai-openai-codec.js +34 -100
  7. package/dist/conversion/codecs/responses-openai-codec.d.ts +1 -1
  8. package/dist/conversion/codecs/responses-openai-codec.js +47 -159
  9. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.d.ts +2 -6
  10. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +29 -245
  11. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.d.ts +3 -0
  12. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.js +30 -0
  13. package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +21 -232
  14. package/dist/conversion/compat/actions/deepseek-web-request.js +41 -276
  15. package/dist/conversion/compat/actions/deepseek-web-response.js +64 -859
  16. package/dist/conversion/compat/actions/gemini-cli-request.d.ts +1 -1
  17. package/dist/conversion/compat/actions/gemini-cli-request.js +20 -613
  18. package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -15
  19. package/dist/conversion/compat/actions/gemini-web-search.js +22 -69
  20. package/dist/conversion/compat/actions/glm-tool-extraction.d.ts +3 -2
  21. package/dist/conversion/compat/actions/glm-tool-extraction.js +28 -257
  22. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +0 -8
  23. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +24 -206
  24. package/dist/conversion/compat/actions/qwen-transform.d.ts +3 -2
  25. package/dist/conversion/compat/actions/qwen-transform.js +30 -271
  26. package/dist/conversion/compat/actions/tool-text-request-guidance.js +3 -173
  27. package/dist/conversion/compat/actions/universal-shape-filter.d.ts +6 -23
  28. package/dist/conversion/compat/actions/universal-shape-filter.js +4 -383
  29. package/dist/conversion/hub/pipeline/compat/native-adapter-context.js +1 -0
  30. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +1 -2
  31. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +50 -104
  32. package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +12 -10
  33. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +0 -2
  34. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +46 -67
  35. package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +15 -40
  36. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +47 -348
  37. package/dist/conversion/responses/responses-openai-bridge.js +129 -611
  38. package/dist/conversion/shared/chat-output-normalizer.js +6 -0
  39. package/dist/conversion/shared/chat-request-filters.js +1 -1
  40. package/dist/conversion/shared/output-content-normalizer.js +10 -0
  41. package/dist/conversion/shared/responses-conversation-store.js +22 -135
  42. package/dist/conversion/shared/responses-output-builder.d.ts +0 -2
  43. package/dist/conversion/shared/responses-output-builder.js +28 -318
  44. package/dist/conversion/shared/responses-response-utils.js +35 -86
  45. package/dist/conversion/shared/streaming-text-extractor.d.ts +1 -2
  46. package/dist/conversion/shared/streaming-text-extractor.js +13 -14
  47. package/dist/conversion/shared/tool-call-id-manager.js +18 -21
  48. package/dist/native/router_hotpath_napi.node +0 -0
  49. package/dist/router/virtual-router/bootstrap/routing-config.d.ts +2 -1
  50. package/dist/router/virtual-router/bootstrap/routing-config.js +57 -4
  51. package/dist/router/virtual-router/engine-legacy.d.ts +3 -3
  52. package/dist/router/virtual-router/engine-legacy.js +15 -7
  53. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +16 -0
  54. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +434 -46
  55. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +83 -0
  56. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +295 -0
  57. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.d.ts +1 -0
  58. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.d.ts +7 -0
  59. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js +8 -1
  60. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +383 -298
  61. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +20 -0
  62. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +201 -0
  63. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +1 -0
  64. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +37 -0
  65. package/dist/router/virtual-router/engine-selection/tier-load-balancing.d.ts +16 -0
  66. package/dist/router/virtual-router/engine-selection/tier-load-balancing.js +120 -0
  67. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.d.ts +2 -0
  68. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +44 -66
  69. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +53 -84
  70. package/dist/router/virtual-router/engine.js +0 -38
  71. package/dist/router/virtual-router/features.js +44 -3
  72. package/dist/router/virtual-router/routing-instructions/parse.d.ts +0 -12
  73. package/dist/router/virtual-router/routing-instructions/parse.js +9 -389
  74. package/dist/router/virtual-router/stop-message-state-sync.d.ts +3 -6
  75. package/dist/router/virtual-router/stop-message-state-sync.js +50 -21
  76. package/dist/router/virtual-router/types.d.ts +16 -0
  77. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -0
  78. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +26 -0
  79. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +12 -2
  80. package/package.json +1 -1
  81. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +0 -9
  82. package/dist/router/virtual-router/engine-legacy/route-finalize.js +0 -84
  83. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +0 -17
  84. package/dist/router/virtual-router/engine-legacy/route-selection.js +0 -205
  85. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +0 -3
  86. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +0 -36
  87. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +0 -12
  88. package/dist/router/virtual-router/engine-legacy/route-state.js +0 -386
  89. package/dist/router/virtual-router/engine-legacy/routing.d.ts +0 -8
  90. package/dist/router/virtual-router/engine-legacy/routing.js +0 -8
@@ -2,6 +2,7 @@ import { computeContextMultiplier } from '../context-weighted.js';
2
2
  import { pinCandidatesByAliasQueue, resolveAliasSelectionStrategy } from './alias-selection.js';
3
3
  import { computeContextWeightMultipliers } from './context-weight-multipliers.js';
4
4
  import { extractKeyAlias, extractProviderId, getProviderModelId } from './key-parsing.js';
5
+ import { buildCandidateWeights, buildGroupWeights, hasNonUniformWeights, resolveTierLoadBalancing } from './tier-load-balancing.js';
5
6
  import { pickPriorityGroup } from './tier-priority.js';
6
7
  import { selectProviderKeyWithQuotaBuckets } from './tier-selection-quota-integration.js';
7
8
  function buildPrimaryTargetGroups(candidates, deps) {
@@ -25,50 +26,6 @@ function buildPrimaryTargetGroups(candidates, deps) {
25
26
  }
26
27
  return groups;
27
28
  }
28
- function resolveGroupWeight(groupId, weights) {
29
- if (!weights) {
30
- return 1;
31
- }
32
- const direct = weights[groupId];
33
- if (typeof direct === 'number' && Number.isFinite(direct) && direct > 0) {
34
- return direct;
35
- }
36
- const providerId = groupId.split('.')[0] ?? groupId;
37
- const providerOnly = weights[providerId];
38
- if (typeof providerOnly === 'number' && Number.isFinite(providerOnly) && providerOnly > 0) {
39
- return providerOnly;
40
- }
41
- return 1;
42
- }
43
- function buildGroupWeights(groups, weights) {
44
- if (!groups.size) {
45
- return undefined;
46
- }
47
- const out = {};
48
- for (const [groupId] of groups.entries()) {
49
- out[groupId] = resolveGroupWeight(groupId, weights);
50
- }
51
- return out;
52
- }
53
- function hasNonUniformWeights(candidates, weights) {
54
- if (!weights || candidates.length < 2) {
55
- return false;
56
- }
57
- let ref;
58
- for (const key of candidates) {
59
- const raw = weights[key];
60
- if (typeof raw !== 'number' || !Number.isFinite(raw)) {
61
- continue;
62
- }
63
- if (ref === undefined) {
64
- ref = raw;
65
- }
66
- else if (Math.abs(raw - ref) > 1e-6) {
67
- return true;
68
- }
69
- }
70
- return false;
71
- }
72
29
  function applyAliasStickyQueuePinning(opts) {
73
30
  const { candidates, orderedTargets, deps, excludedKeys } = opts;
74
31
  if (!Array.isArray(candidates) || candidates.length < 2) {
@@ -202,6 +159,7 @@ function preferAntigravityAliasesOnRetry(opts) {
202
159
  export function selectProviderKeyFromCandidatePool(opts) {
203
160
  const { routeName, tier, stickyKey, candidates, isSafePool, deps, options, contextResult, warnRatio, excludedKeys, isRecoveryAttempt, now, nowForWeights, healthWeightedCfg, contextWeightedCfg } = opts;
204
161
  const quotaView = deps.quotaView;
162
+ const tierLoadBalancing = resolveTierLoadBalancing(tier, deps.loadBalancer.getPolicy());
205
163
  const isAvailable = (key) => {
206
164
  if (!quotaView) {
207
165
  return deps.healthManager.isAvailable(key);
@@ -265,28 +223,33 @@ export function selectProviderKeyFromCandidatePool(opts) {
265
223
  if (!group) {
266
224
  return null;
267
225
  }
268
- const weights = (() => {
269
- if (!isSafePool)
270
- return undefined;
271
- const ctx = computeContextWeightMultipliers({ candidates: group.groupCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
272
- if (!ctx)
273
- return undefined;
274
- const out = {};
275
- for (const key of group.groupCandidates) {
276
- const m = computeContextMultiplier({
277
- effectiveSafeRefTokens: ctx.ref,
278
- effectiveSafeTokens: ctx.eff[key] ?? 1,
279
- cfg: contextWeightedCfg
280
- });
281
- out[key] = Math.max(1, Math.round(100 * m));
282
- }
283
- return out;
284
- })();
226
+ const weights = buildCandidateWeights({
227
+ candidates: group.groupCandidates,
228
+ providerRegistry: deps.providerRegistry,
229
+ staticWeights: tierLoadBalancing.weights,
230
+ dynamicWeights: (() => {
231
+ if (!isSafePool)
232
+ return undefined;
233
+ const ctx = computeContextWeightMultipliers({ candidates: group.groupCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
234
+ if (!ctx)
235
+ return undefined;
236
+ const out = {};
237
+ for (const key of group.groupCandidates) {
238
+ const m = computeContextMultiplier({
239
+ effectiveSafeRefTokens: ctx.ref,
240
+ effectiveSafeTokens: ctx.eff[key] ?? 1,
241
+ cfg: contextWeightedCfg
242
+ });
243
+ out[key] = Math.max(1, Math.round(100 * m));
244
+ }
245
+ return out;
246
+ })()
247
+ });
285
248
  const allowGrouped = !hasNonUniformWeights(group.groupCandidates, weights);
286
- if (allowGrouped && deps.loadBalancer.getPolicy().strategy !== 'sticky') {
249
+ if (allowGrouped && tierLoadBalancing.strategy !== 'sticky') {
287
250
  const groups = buildPrimaryTargetGroups(group.groupCandidates, deps);
288
251
  if (groups.size > 0) {
289
- const groupWeights = buildGroupWeights(groups, deps.loadBalancer.getPolicy().weights);
252
+ const groupWeights = buildGroupWeights(groups, tierLoadBalancing.weights);
290
253
  const selected = deps.loadBalancer.selectGrouped({
291
254
  routeName: `${routeName}:${tier.id}:priority:group:${group.groupId}`,
292
255
  groups,
@@ -307,35 +270,40 @@ export function selectProviderKeyFromCandidatePool(opts) {
307
270
  availabilityCheck: isAvailable
308
271
  }, 'round-robin');
309
272
  }
310
- const weights = (() => {
311
- if (!isSafePool || !contextWeightedCfg.enabled)
312
- return undefined;
313
- const ctx = computeContextWeightMultipliers({ candidates: pinnedCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
314
- if (!ctx)
315
- return undefined;
316
- const out = {};
317
- for (const key of pinnedCandidates) {
318
- const m = computeContextMultiplier({
319
- effectiveSafeRefTokens: ctx.ref,
320
- effectiveSafeTokens: ctx.eff[key] ?? 1,
321
- cfg: contextWeightedCfg
322
- });
323
- out[key] = Math.max(1, Math.round(100 * m));
324
- }
325
- return out;
326
- })();
273
+ const weights = buildCandidateWeights({
274
+ candidates: pinnedCandidates,
275
+ providerRegistry: deps.providerRegistry,
276
+ staticWeights: tierLoadBalancing.weights,
277
+ dynamicWeights: (() => {
278
+ if (!isSafePool || !contextWeightedCfg.enabled)
279
+ return undefined;
280
+ const ctx = computeContextWeightMultipliers({ candidates: pinnedCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
281
+ if (!ctx)
282
+ return undefined;
283
+ const out = {};
284
+ for (const key of pinnedCandidates) {
285
+ const m = computeContextMultiplier({
286
+ effectiveSafeRefTokens: ctx.ref,
287
+ effectiveSafeTokens: ctx.eff[key] ?? 1,
288
+ cfg: contextWeightedCfg
289
+ });
290
+ out[key] = Math.max(1, Math.round(100 * m));
291
+ }
292
+ return out;
293
+ })()
294
+ });
327
295
  const allowGrouped = !hasNonUniformWeights(pinnedCandidates, weights);
328
- if (allowGrouped && deps.loadBalancer.getPolicy().strategy !== 'sticky') {
296
+ if (allowGrouped && tierLoadBalancing.strategy !== 'sticky') {
329
297
  const groups = buildPrimaryTargetGroups(pinnedCandidates, deps);
330
298
  if (groups.size > 0) {
331
- const groupWeights = buildGroupWeights(groups, deps.loadBalancer.getPolicy().weights);
299
+ const groupWeights = buildGroupWeights(groups, tierLoadBalancing.weights);
332
300
  const selected = deps.loadBalancer.selectGrouped({
333
301
  routeName: `${routeName}:${tier.id}`,
334
302
  groups,
335
303
  stickyKey: options.allowAliasRotation ? undefined : stickyKey,
336
304
  weights: groupWeights,
337
305
  availabilityCheck: isAvailable
338
- }, tier.mode === 'round-robin' ? 'round-robin' : undefined);
306
+ }, tier.mode === 'round-robin' ? 'round-robin' : tierLoadBalancing.strategy);
339
307
  if (selected) {
340
308
  return selected;
341
309
  }
@@ -347,7 +315,7 @@ export function selectProviderKeyFromCandidatePool(opts) {
347
315
  stickyKey: options.allowAliasRotation ? undefined : stickyKey,
348
316
  weights,
349
317
  availabilityCheck: isAvailable
350
- }, tier.mode === 'round-robin' ? 'round-robin' : undefined);
318
+ }, tier.mode === 'round-robin' ? 'round-robin' : tierLoadBalancing.strategy);
351
319
  }
352
320
  return selectProviderKeyWithQuotaBuckets({
353
321
  routeName,
@@ -365,6 +333,7 @@ export function selectProviderKeyFromCandidatePool(opts) {
365
333
  nowForWeights,
366
334
  healthWeightedCfg,
367
335
  contextWeightedCfg,
336
+ tierLoadBalancing,
368
337
  quotaView,
369
338
  isAvailable,
370
339
  selectFirstAvailable,
@@ -1,9 +1,6 @@
1
1
  import { VirtualRouterError, VirtualRouterErrorCode } from './types.js';
2
- import { ROUTING_INSTRUCTION_MARKER_PATTERN } from './routing-instructions/types.js';
3
- import { parseRoutingInstructions } from './routing-instructions/parse.js';
4
2
  import { createVirtualRouterEngineProxy } from './engine-selection/native-virtual-router-engine-proxy.js';
5
3
  import { cleanRoutingInstructionMarkersWithNative, parseRoutingInstructionKindsWithNative } from './engine-selection/native-virtual-router-routing-instructions-semantics.js';
6
- import { getLatestUserTextFromResponsesContext, hasLatestUserRoutingInstructionMarker, hasRoutingInstructionMarkerInResponsesContext } from './engine-legacy/helpers.js';
7
4
  import { extractMessageText, getLatestUserMessage } from './message-utils.js';
8
5
  import { ProviderRegistry } from './provider-registry.js';
9
6
  import { resolveStopMessageScope } from './engine/routing-state/store.js';
@@ -349,38 +346,3 @@ function cleanRoutingInstructionMarkersInPlace(request) {
349
346
  }
350
347
  }
351
348
  }
352
- function collectClientScopedInstructions(request) {
353
- const messages = Array.isArray(request.messages)
354
- ? request.messages
355
- : [];
356
- const responsesContext = request.semantics && typeof request.semantics === 'object'
357
- ? request.semantics.responses?.context
358
- : undefined;
359
- const responsesHasMarker = hasRoutingInstructionMarkerInResponsesContext(responsesContext);
360
- const latestUserHasMarker = hasLatestUserRoutingInstructionMarker(messages) || responsesHasMarker;
361
- if (!latestUserHasMarker && !messages.some((message) => {
362
- if (!message || typeof message !== 'object') {
363
- return false;
364
- }
365
- const record = message;
366
- return record.role === 'user' && typeof record.content === 'string' && ROUTING_INSTRUCTION_MARKER_PATTERN.test(record.content);
367
- })) {
368
- return { instructions: [], latestUserHasMarker };
369
- }
370
- let instructions = parseRoutingInstructions(messages);
371
- if (instructions.length === 0 && responsesHasMarker) {
372
- const responsesLatestUserText = getLatestUserTextFromResponsesContext(responsesContext);
373
- if (responsesLatestUserText) {
374
- instructions = parseRoutingInstructions([{ role: 'user', content: responsesLatestUserText }]);
375
- }
376
- }
377
- return { instructions, latestUserHasMarker };
378
- }
379
- function isClientScopedInstruction(instruction) {
380
- return (instruction.type === 'stopMessageSet' ||
381
- instruction.type === 'stopMessageMode' ||
382
- instruction.type === 'stopMessageClear' ||
383
- instruction.type === 'preCommandSet' ||
384
- instruction.type === 'preCommandClear' ||
385
- instruction.type === 'clear');
386
- }
@@ -3,6 +3,46 @@ import { extractAntigravityGeminiSessionIdWithNative } from './engine-selection/
3
3
  import { detectCodingTool, detectLastAssistantToolCategory, detectVisionTool, detectWebSearchToolDeclared, detectWebTool, extractMeaningfulDeclaredToolNames } from './tool-signals.js';
4
4
  import { computeRequestTokens } from './token-estimator.js';
5
5
  const THINKING_KEYWORDS = ['let me think', 'chain of thought', 'cot', 'reason step', 'deliberate'];
6
+ function asRecord(value) {
7
+ return value && typeof value === 'object' && !Array.isArray(value)
8
+ ? value
9
+ : null;
10
+ }
11
+ function getLatestResponsesContextMessage(request) {
12
+ const contextInput = asRecord(request.semantics)?.responses;
13
+ const context = asRecord(contextInput)?.context;
14
+ const input = Array.isArray(asRecord(context)?.input) ? asRecord(context)?.input : [];
15
+ for (let idx = input.length - 1; idx >= 0; idx -= 1) {
16
+ const entry = asRecord(input[idx]);
17
+ if (!entry) {
18
+ continue;
19
+ }
20
+ const entryType = typeof entry.type === 'string' && entry.type.trim()
21
+ ? entry.type.trim().toLowerCase()
22
+ : 'message';
23
+ if (entryType !== 'message') {
24
+ continue;
25
+ }
26
+ const role = typeof entry.role === 'string' && entry.role.trim()
27
+ ? entry.role.trim().toLowerCase()
28
+ : 'user';
29
+ if (role !== 'user' && role !== 'assistant' && role !== 'tool') {
30
+ continue;
31
+ }
32
+ const content = entry.content;
33
+ if (typeof content !== 'string' && !Array.isArray(content)) {
34
+ continue;
35
+ }
36
+ return {
37
+ role,
38
+ message: {
39
+ role: role,
40
+ content: content
41
+ }
42
+ };
43
+ }
44
+ return null;
45
+ }
6
46
  export function buildRoutingFeatures(request, metadata) {
7
47
  const antigravitySessionId = (() => {
8
48
  try {
@@ -18,10 +58,11 @@ export function buildRoutingFeatures(request, metadata) {
18
58
  return undefined;
19
59
  }
20
60
  })();
21
- const latestMessageRole = getLatestMessageRole(request.messages);
22
- const latestMessage = Array.isArray(request.messages) && request.messages.length
61
+ const responsesLatestMessage = getLatestResponsesContextMessage(request);
62
+ const latestMessageRole = responsesLatestMessage?.role || getLatestMessageRole(request.messages);
63
+ const latestMessage = responsesLatestMessage?.message || (Array.isArray(request.messages) && request.messages.length
23
64
  ? request.messages[request.messages.length - 1]
24
- : undefined;
65
+ : undefined);
25
66
  const assistantMessages = request.messages.filter((msg) => msg.role === 'assistant');
26
67
  const latestUserText = latestMessageRole === 'user' && latestMessage
27
68
  ? extractMessageText(latestMessage)
@@ -1,18 +1,6 @@
1
1
  import type { StandardizedMessage } from '../../../conversion/hub/types/standardized.js';
2
2
  import type { RoutingInstruction } from './types.js';
3
3
  export declare function parseRoutingInstructions(messages: StandardizedMessage[]): RoutingInstruction[];
4
- /**
5
- * 解析并预处理路由指令,优先处理 clear 指令,确保新指令能够覆盖旧状态。
6
- * 返回清理后的指令列表,移除冗余的 stopMessageSet 指令。
7
- */
8
4
  export declare function parseAndPreprocessRoutingInstructions(messages: StandardizedMessage[]): RoutingInstruction[];
9
- /**
10
- * 提取 clear 指令(如果存在)。用于在路由选择前优先执行清理操作。
11
- * @returns 是否存在 clear 指令
12
- */
13
5
  export declare function extractClearInstruction(messages: StandardizedMessage[]): boolean;
14
- /**
15
- * 提取 stopMessageClear 指令(如果存在)。
16
- * @returns 是否存在 stopMessageClear 指令
17
- */
18
6
  export declare function extractStopMessageClearInstruction(messages: StandardizedMessage[]): boolean;