@linnlabs/linnkit 0.8.0 → 0.10.0

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 (83) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/bin/linnkit.cjs +7 -0
  5. package/dist/{agentSpec-EkmviZjy.d.cts → agentSpec-Du4Iye0q.d.cts} +16 -1
  6. package/dist/{agentSpec-EkmviZjy.d.ts → agentSpec-Du4Iye0q.d.ts} +16 -1
  7. package/dist/cli.cjs +234 -91
  8. package/dist/cli.cjs.map +1 -1
  9. package/dist/cli.js +234 -91
  10. package/dist/cli.js.map +1 -1
  11. package/dist/context-manager.cjs +230 -32
  12. package/dist/context-manager.cjs.map +1 -1
  13. package/dist/context-manager.d.cts +52 -15
  14. package/dist/context-manager.d.ts +52 -15
  15. package/dist/context-manager.js +230 -33
  16. package/dist/context-manager.js.map +1 -1
  17. package/dist/{context-trace-HE2qY5Q-.d.cts → context-trace-BHKDS-eq.d.cts} +2 -2
  18. package/dist/{context-trace-DRi5M4lX.d.ts → context-trace-CHbqHmyE.d.ts} +2 -2
  19. package/dist/contracts.cjs +3 -1
  20. package/dist/contracts.cjs.map +1 -1
  21. package/dist/contracts.d.cts +3 -3
  22. package/dist/contracts.d.ts +3 -3
  23. package/dist/contracts.js +3 -1
  24. package/dist/contracts.js.map +1 -1
  25. package/dist/{defaultGraphExecutor-BBswR8wn.d.ts → defaultGraphExecutor-B29_qTHy.d.ts} +16 -15
  26. package/dist/{defaultGraphExecutor-BIjJj7WF.d.cts → defaultGraphExecutor-C2E59v_R.d.cts} +16 -15
  27. package/dist/{index-Cm-JbzTH.d.cts → index-BAaUP9yU.d.cts} +38 -15
  28. package/dist/{index-DRBWi1fy.d.ts → index-BaVpVNi2.d.ts} +38 -15
  29. package/dist/{index-DO4dQgf2.d.cts → index-BnYCS8Zg.d.cts} +2 -2
  30. package/dist/{index-CJeWHopy.d.ts → index-C0DAjsdX.d.ts} +2 -2
  31. package/dist/{index-Dl5PLgAv.d.cts → index-CKQzzZ5Y.d.cts} +2 -2
  32. package/dist/{index-CHqwkvGp.d.ts → index-D0mKxTR5.d.ts} +2 -2
  33. package/dist/index.cjs +327 -110
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +10 -10
  36. package/dist/index.d.ts +10 -10
  37. package/dist/index.js +327 -110
  38. package/dist/index.js.map +1 -1
  39. package/dist/{ports-DnLuKfpE.d.ts → ports-DpPTFhSd.d.ts} +2 -2
  40. package/dist/{ports-DaatKJXp.d.cts → ports-s-tSp3sB.d.cts} +2 -2
  41. package/dist/quickstart.cjs +232 -88
  42. package/dist/quickstart.cjs.map +1 -1
  43. package/dist/quickstart.d.cts +7 -7
  44. package/dist/quickstart.d.ts +7 -7
  45. package/dist/quickstart.js +232 -88
  46. package/dist/quickstart.js.map +1 -1
  47. package/dist/{runAgent-CPj_9e58.d.ts → runAgent-C6F-399C.d.ts} +5 -5
  48. package/dist/{runAgent-HYKlXbVr.d.cts → runAgent-ilEj66Ik.d.cts} +5 -5
  49. package/dist/{runHandle-D3gPsD7B.d.cts → runHandle-BNOqS-Bl.d.cts} +3 -3
  50. package/dist/{runHandle-CyXvzgzk.d.ts → runHandle-BdLXOFqF.d.ts} +3 -3
  51. package/dist/runtime-kernel/events.cjs +1 -0
  52. package/dist/runtime-kernel/events.cjs.map +1 -1
  53. package/dist/runtime-kernel/events.d.cts +4 -4
  54. package/dist/runtime-kernel/events.d.ts +4 -4
  55. package/dist/runtime-kernel/events.js +1 -0
  56. package/dist/runtime-kernel/events.js.map +1 -1
  57. package/dist/runtime-kernel.cjs +318 -103
  58. package/dist/runtime-kernel.cjs.map +1 -1
  59. package/dist/runtime-kernel.d.cts +8 -8
  60. package/dist/runtime-kernel.d.ts +8 -8
  61. package/dist/runtime-kernel.js +315 -104
  62. package/dist/runtime-kernel.js.map +1 -1
  63. package/dist/testkit.cjs +331 -116
  64. package/dist/testkit.cjs.map +1 -1
  65. package/dist/testkit.d.cts +8 -8
  66. package/dist/testkit.d.ts +8 -8
  67. package/dist/testkit.js +331 -116
  68. package/dist/testkit.js.map +1 -1
  69. package/dist/{todo-B1PmDlp3.d.cts → todo-Ca8llpRQ.d.cts} +1 -1
  70. package/dist/{todo-B1PmDlp3.d.ts → todo-Ca8llpRQ.d.ts} +1 -1
  71. package/dist/{toolContracts-CLkQmhTG.d.cts → toolContracts-Bm3EZ1UM.d.cts} +13 -2
  72. package/dist/{toolContracts-Blll0241.d.ts → toolContracts-f8lzZBNa.d.ts} +13 -2
  73. package/docs/integration/README.md +1 -1
  74. package/docs/integration/agent-registration-guide.md +1 -1
  75. package/docs/integration/child-runs.md +4 -1
  76. package/docs/integration/context-engineering.md +30 -15
  77. package/docs/integration/context-fences.md +32 -3
  78. package/docs/integration/llm-provider.md +1 -1
  79. package/docs/integration/persistence.md +1 -0
  80. package/docs/integration/run-supervisor.md +3 -0
  81. package/docs/integration/tool-development-guide.md +7 -5
  82. package/docs/integration/tool-history.md +43 -17
  83. package/package.json +5 -4
@@ -497,6 +497,7 @@ var AgentSpecBudgetPolicy = z.object({
497
497
  });
498
498
  var AgentSpecToolHistoryPolicy = z.object({
499
499
  strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
500
+ retentionMode: z.enum(["drop", "compress"]).optional(),
500
501
  keepLatestToolPairs: z.number().int().nonnegative().optional(),
501
502
  keepLatestRuns: z.number().int().nonnegative().optional(),
502
503
  maxInteractionGroups: z.number().int().nonnegative().optional(),
@@ -611,12 +612,13 @@ var AgentSpecContextPolicy = z.object({
611
612
  var DEFAULT_CONTEXT_POLICY = {
612
613
  profileId: "agent",
613
614
  budget: {
614
- maxTokens: 12e4,
615
+ maxTokens: 232e3,
615
616
  reservedForResponse: 2400,
616
617
  workingMemoryBudgetPercentage: 0.7
617
618
  },
618
619
  toolHistory: {
619
620
  strategy: "per-run",
621
+ retentionMode: "drop",
620
622
  keepLatestToolPairs: 2,
621
623
  keepLatestRuns: 1,
622
624
  maxInteractionGroups: 12,
@@ -1772,6 +1774,157 @@ function findLastIndex(items, predicate) {
1772
1774
  return -1;
1773
1775
  }
1774
1776
 
1777
+ // src/context-manager/shared/preprocessors/currentTurnMessageAssembler.ts
1778
+ var CurrentTurnMessageAssembler = class extends BasePreprocessor {
1779
+ name = "CurrentTurnMessageAssembler";
1780
+ description = "Assembles current-turn fences into system_prompt and user_input messages";
1781
+ priority = 10;
1782
+ fenceRegistry;
1783
+ constructor(options) {
1784
+ super();
1785
+ this.fenceRegistry = options.fenceRegistry;
1786
+ }
1787
+ async process(messages, _context) {
1788
+ const systemResult = assembleSystemPrompt({ messages, fenceRegistry: this.fenceRegistry });
1789
+ const userResult = assembleCurrentUserInput({
1790
+ messages: systemResult.messages,
1791
+ fenceRegistry: this.fenceRegistry
1792
+ });
1793
+ const modifiedCount = systemResult.modifiedCount + userResult.modifiedCount;
1794
+ return this.createResult(
1795
+ messages,
1796
+ userResult.messages,
1797
+ modifiedCount > 0 ? ["current_turn_message_assembly"] : [],
1798
+ modifiedCount
1799
+ );
1800
+ }
1801
+ };
1802
+ function assembleSystemPrompt(params) {
1803
+ const systemIndex = params.messages.findIndex(
1804
+ (message) => message.role === "system" && message.type === "system_prompt"
1805
+ );
1806
+ if (systemIndex === -1) {
1807
+ return { messages: [...params.messages], modifiedCount: 0 };
1808
+ }
1809
+ const fences = collectAdjacentFences({
1810
+ messages: params.messages,
1811
+ startIndex: systemIndex + 1,
1812
+ direction: 1,
1813
+ fenceRegistry: params.fenceRegistry,
1814
+ matches: (descriptor) => descriptor.llmRole === "system" && descriptor.placement === "after-system"
1815
+ });
1816
+ if (fences.length === 0) {
1817
+ return { messages: [...params.messages], modifiedCount: 0 };
1818
+ }
1819
+ const indexesToRemove = new Set(fences.map((fence) => fence.index));
1820
+ const systemPrompt = params.messages[systemIndex];
1821
+ const assembledSystemPrompt = {
1822
+ ...systemPrompt,
1823
+ content: [
1824
+ systemPrompt.content,
1825
+ ...fences.map(formatFence)
1826
+ ].join("\n\n"),
1827
+ metadata: {
1828
+ ...systemPrompt.metadata,
1829
+ assembledFenceKinds: fences.map((fence) => fence.message.metadata?.fenceKind).filter((kind) => typeof kind === "string")
1830
+ }
1831
+ };
1832
+ return {
1833
+ messages: params.messages.map(
1834
+ (message, index) => index === systemIndex ? assembledSystemPrompt : message
1835
+ ).filter((_, index) => !indexesToRemove.has(index)),
1836
+ modifiedCount: fences.length + 1
1837
+ };
1838
+ }
1839
+ function assembleCurrentUserInput(params) {
1840
+ const currentUserIndex = findLastUserInputIndex(params.messages);
1841
+ if (currentUserIndex === -1) {
1842
+ return { messages: [...params.messages], modifiedCount: 0 };
1843
+ }
1844
+ const beforeFences = collectAdjacentFences({
1845
+ messages: params.messages,
1846
+ startIndex: currentUserIndex - 1,
1847
+ direction: -1,
1848
+ fenceRegistry: params.fenceRegistry,
1849
+ matches: (descriptor) => isUserCurrentTurnPlacement(descriptor, "before-current-user")
1850
+ }).reverse();
1851
+ const afterFences = collectAdjacentFences({
1852
+ messages: params.messages,
1853
+ startIndex: currentUserIndex + 1,
1854
+ direction: 1,
1855
+ fenceRegistry: params.fenceRegistry,
1856
+ matches: (descriptor) => isUserCurrentTurnPlacement(descriptor, "after-current-user")
1857
+ });
1858
+ if (beforeFences.length === 0 && afterFences.length === 0) {
1859
+ return { messages: [...params.messages], modifiedCount: 0 };
1860
+ }
1861
+ const indexesToRemove = /* @__PURE__ */ new Set([
1862
+ ...beforeFences.map((fence) => fence.index),
1863
+ ...afterFences.map((fence) => fence.index)
1864
+ ]);
1865
+ const currentUser = params.messages[currentUserIndex];
1866
+ const assembledUser = {
1867
+ ...currentUser,
1868
+ content: [
1869
+ ...beforeFences.map(formatFence),
1870
+ wrapUserRequest(currentUser.content),
1871
+ ...afterFences.map(formatFence)
1872
+ ].join("\n\n"),
1873
+ metadata: {
1874
+ ...currentUser.metadata,
1875
+ assembledFenceKinds: [
1876
+ ...beforeFences.map((fence) => fence.message.metadata?.fenceKind),
1877
+ ...afterFences.map((fence) => fence.message.metadata?.fenceKind)
1878
+ ].filter((kind) => typeof kind === "string")
1879
+ }
1880
+ };
1881
+ return {
1882
+ messages: params.messages.map(
1883
+ (message, index) => index === currentUserIndex ? assembledUser : message
1884
+ ).filter((_, index) => !indexesToRemove.has(index)),
1885
+ modifiedCount: indexesToRemove.size + 1
1886
+ };
1887
+ }
1888
+ function findLastUserInputIndex(messages) {
1889
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
1890
+ const message = messages[index];
1891
+ if (message.role === "user" && message.type === "user_input") {
1892
+ return index;
1893
+ }
1894
+ }
1895
+ return -1;
1896
+ }
1897
+ function collectAdjacentFences(params) {
1898
+ const result = [];
1899
+ for (let index = params.startIndex; index >= 0 && index < params.messages.length; index += params.direction) {
1900
+ const message = params.messages[index];
1901
+ if (message.type !== "context_injection") {
1902
+ break;
1903
+ }
1904
+ const fenceKind = message.metadata?.fenceKind;
1905
+ if (!fenceKind) {
1906
+ break;
1907
+ }
1908
+ const descriptor = params.fenceRegistry.get(fenceKind);
1909
+ if (!descriptor || !params.matches(descriptor)) {
1910
+ break;
1911
+ }
1912
+ result.push({ index, message, descriptor });
1913
+ }
1914
+ return result;
1915
+ }
1916
+ function isUserCurrentTurnPlacement(descriptor, placement) {
1917
+ return descriptor.llmRole === "user" && descriptor.placement === placement;
1918
+ }
1919
+ function formatFence(fence) {
1920
+ return fence.descriptor.formatter(fence.message.content, fence.message.metadata?.fenceAttrs ?? {});
1921
+ }
1922
+ function wrapUserRequest(content) {
1923
+ return `<user_request>
1924
+ ${content.trim()}
1925
+ </user_request>`;
1926
+ }
1927
+
1775
1928
  // src/context-manager/shared/providers/base.ts
1776
1929
  var TOOL_HISTORY_OVERFLOW_ERROR_CODE = "TOOL_HISTORY_OVERFLOW";
1777
1930
  var SUMMARIZATION_FAILED_ERROR_CODE = "SUMMARIZATION_FAILED";
@@ -2574,7 +2727,7 @@ __export(config_exports, {
2574
2727
  var AGENT_CONTEXT_BUILDER_CONFIG = {
2575
2728
  // === 绝对Token限制设置 ===
2576
2729
  /** 默认最大Token预算上限 */
2577
- DEFAULT_MAX_TOKENS: 12e4,
2730
+ DEFAULT_MAX_TOKENS: 232e3,
2578
2731
  /** 响应预留Token数 */
2579
2732
  RESERVED_FOR_RESPONSE: 2400,
2580
2733
  // === Agent专用工作记忆填充策略 ===
@@ -3965,7 +4118,7 @@ var AgentWorkingMemoryProvider = class extends BaseContextProvider2 {
3965
4118
  let workingMemoryTokens = coreTokens;
3966
4119
  let processedCount = 0;
3967
4120
  const strategiesApplied = [];
3968
- const workingMemoryBudget = Math.floor(availableBudget * config.WORKING_MEMORY_BUDGET_PERCENTAGE);
4121
+ const workingMemoryBudget = Math.floor(context.totalBudget * config.WORKING_MEMORY_BUDGET_PERCENTAGE);
3969
4122
  const remainingBudget = workingMemoryBudget - coreTokens;
3970
4123
  if (remainingBudget <= 0 && config.MIN_TOOL_INTERACTIONS_TO_KEEP <= 0) {
3971
4124
  this.debug("\u26A0\uFE0F \u6838\u5FC3\u4E0A\u4E0B\u6587\u5DF2\u7528\u5C3D\u9884\u7B97\uFF0C\u8DF3\u8FC7\u5DE5\u4F5C\u8BB0\u5FC6\u586B\u5145", {
@@ -5108,6 +5261,7 @@ __export(orchestration_exports, {
5108
5261
  var preprocessors_exports = {};
5109
5262
  __export(preprocessors_exports, {
5110
5263
  BasePreprocessor: () => BasePreprocessor2,
5264
+ CurrentTurnMessageAssembler: () => CurrentTurnMessageAssembler,
5111
5265
  FenceLifetimePreprocessor: () => FenceLifetimePreprocessor,
5112
5266
  HistoryPurificationPreprocessor: () => HistoryPurificationPreprocessor,
5113
5267
  PreprocessorPipeline: () => PreprocessorPipeline,
@@ -5159,7 +5313,7 @@ var DEFAULT_KEEP_LATEST_RUNS = 1;
5159
5313
  var DEFAULT_MAX_INTERACTION_GROUPS = 12;
5160
5314
  var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5161
5315
  name = "ToolHistoryCompressorPreprocessor";
5162
- description = "\u5DE5\u5177\u5386\u53F2\u538B\u7F29\u5904\u7406\u5668 - \u5C06\u8F83\u65E9\u7684\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u5BF9\u538B\u7F29\u4E3A\u81EA\u7136\u8BED\u8A00\u8BB0\u5F55\u6D88\u606F";
5316
+ description = "\u5DE5\u5177\u5386\u53F2\u4FDD\u7559\u5904\u7406\u5668 - \u6309\u7B56\u7565\u4FDD\u7559\u3001\u5220\u9664\u6216\u538B\u7F29\u8F83\u65E9\u7684\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u5BF9";
5163
5317
  priority = 0;
5164
5318
  summarizer = createDefaultToolOutputSummarizer();
5165
5319
  options;
@@ -5167,6 +5321,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5167
5321
  super();
5168
5322
  this.options = {
5169
5323
  strategy: options.strategy ?? "per-run",
5324
+ retentionMode: options.retentionMode ?? "drop",
5170
5325
  keepLatestToolPairs: normalizeNonNegativeInteger4(
5171
5326
  options.keepLatestToolPairs,
5172
5327
  DEFAULT_KEEP_LATEST_TOOL_PAIRS
@@ -5183,7 +5338,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5183
5338
  };
5184
5339
  }
5185
5340
  async process(messages, context) {
5186
- this.debug("\u{1F527} \u5F00\u59CB\u5DE5\u5177\u5386\u53F2\u538B\u7F29\u5904\u7406", {
5341
+ this.debug("\u{1F527} \u5F00\u59CB\u5DE5\u5177\u5386\u53F2\u4FDD\u7559\u5904\u7406", {
5187
5342
  \u539F\u59CB\u6D88\u606F\u6570: messages.length
5188
5343
  }, context);
5189
5344
  const currentRunStartIndex = findCurrentRunStartIndex(messages);
@@ -5193,17 +5348,18 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5193
5348
  \u5386\u53F2\u6D88\u606F\u6570: historyMessages.length,
5194
5349
  \u5F53\u524D\u8F6E\u6B21\u6D88\u606F\u6570: currentRunMessages.length,
5195
5350
  \u5F53\u524D\u8F6E\u6B21\u8D77\u70B9\u7D22\u5F15: currentRunStartIndex,
5196
- \u5DE5\u5177\u538B\u7F29\u7B56\u7565: this.options.strategy
5351
+ \u5DE5\u5177\u4FDD\u7559\u7B56\u7565: this.options.strategy,
5352
+ \u5386\u53F2\u5DE5\u5177\u4FDD\u7559\u6A21\u5F0F: this.options.retentionMode
5197
5353
  }, context);
5198
- const compressedHistory = this.compressToolCallPairsInHistory(historyMessages, context);
5199
- const finalMessages = [...compressedHistory, ...currentRunMessages];
5354
+ const processedHistory = this.processToolCallPairsInHistory(historyMessages, context);
5355
+ const finalMessages = [...processedHistory, ...currentRunMessages];
5200
5356
  const originalCount = messages.length;
5201
- const compressedCount = finalMessages.length;
5202
- const removedCount = originalCount - compressedCount;
5203
- const appliedStrategies = removedCount > 0 ? ["tool_history_compression"] : [];
5204
- this.debug("\u2705 \u5DE5\u5177\u5386\u53F2\u538B\u7F29\u5B8C\u6210", {
5357
+ const processedCount = finalMessages.length;
5358
+ const removedCount = originalCount - processedCount;
5359
+ const appliedStrategies = removedCount > 0 ? [this.options.retentionMode === "compress" ? "tool_history_compression" : "tool_history_drop"] : [];
5360
+ this.debug("\u2705 \u5DE5\u5177\u5386\u53F2\u4FDD\u7559\u5904\u7406\u5B8C\u6210", {
5205
5361
  \u539F\u59CB\u6D88\u606F: originalCount,
5206
- \u538B\u7F29\u540E\u6D88\u606F: compressedCount,
5362
+ \u5904\u7406\u540E\u6D88\u606F: processedCount,
5207
5363
  \u51CF\u5C11\u6D88\u606F: removedCount,
5208
5364
  Token\u8282\u7701\u4F30\u8BA1: `\u7EA6${removedCount * 50}\u4E2AToken`
5209
5365
  }, context);
@@ -5224,7 +5380,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5224
5380
  }
5225
5381
  return false;
5226
5382
  }
5227
- compressToolCallPairsInHistory(historyMessages, context) {
5383
+ processToolCallPairsInHistory(historyMessages, context) {
5228
5384
  if (historyMessages.length < 2) {
5229
5385
  return historyMessages;
5230
5386
  }
@@ -5245,8 +5401,10 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
5245
5401
  if (!group.isComplete || keepAnchorIds.has(group.anchorId)) {
5246
5402
  continue;
5247
5403
  }
5248
- const compressedMessage = this.compressToolInteractionGroup(group, context);
5249
- replacementMap.set(group.assistantIndex, compressedMessage);
5404
+ if (this.options.retentionMode === "compress") {
5405
+ const compressedMessage = this.compressToolInteractionGroup(group, context);
5406
+ replacementMap.set(group.assistantIndex, compressedMessage);
5407
+ }
5250
5408
  for (const messageIndex of group.messageIndexes) {
5251
5409
  messagesToRemove.add(messageIndex);
5252
5410
  }
@@ -5665,6 +5823,7 @@ function createDefaultAgentPreprocessorRegistry(options = {}) {
5665
5823
  registry.register(new ToolReplayProtocolGuardPreprocessor({ policy: options.providerReplay }));
5666
5824
  registry.register(new HistoryPurificationPreprocessor({ logPrefix: "Agent-HistoryPurification" }));
5667
5825
  if (options.fenceRegistry) {
5826
+ registry.register(new CurrentTurnMessageAssembler({ fenceRegistry: options.fenceRegistry }));
5668
5827
  registry.register(new FenceLifetimePreprocessor({ fenceRegistry: options.fenceRegistry }));
5669
5828
  }
5670
5829
  return registry;
@@ -6780,6 +6939,18 @@ var AgentMessageOrchestrator = class {
6780
6939
  tokenizer: this.options.tokenizer,
6781
6940
  tokenizerModelId: this.resolvePreprocessorModel(request)
6782
6941
  });
6942
+ return contextBuilderConfig;
6943
+ }
6944
+ resolveEffectiveContextBudget(contextBuilderConfig) {
6945
+ const maxTokens = contextBuilderConfig.DEFAULT_MAX_TOKENS ?? this.options.tokenBudget.maxTokens;
6946
+ const reservedForResponse = contextBuilderConfig.RESERVED_FOR_RESPONSE ?? this.options.tokenBudget.reservedForResponse;
6947
+ return {
6948
+ maxTokens,
6949
+ reservedForResponse,
6950
+ // 中文备注:ContextManager 接收的是“可放入上下文的输入预算”,不是模型完整窗口。
6951
+ // 因此单个 agent 通过 contextPolicy.budget 覆盖预算时,这里必须同步使用覆盖后的值。
6952
+ totalBudget: maxTokens - reservedForResponse
6953
+ };
6783
6954
  }
6784
6955
  async processAgentConversation(request, history, toolManager, callbacks, extraOptions) {
6785
6956
  const historyCount = history.length;
@@ -6798,7 +6969,8 @@ var AgentMessageOrchestrator = class {
6798
6969
  const allMessages = this.buildCompleteMessageList(request, historyMessages);
6799
6970
  this.debug("Built complete message list", { totalCount: allMessages.length });
6800
6971
  const contextPolicy = this.resolveContextPolicy(request);
6801
- this.applyContextPolicy(request, contextPolicy);
6972
+ const contextBuilderConfig = this.applyContextPolicy(request, contextPolicy);
6973
+ const effectiveContextBudget = this.resolveEffectiveContextBudget(contextBuilderConfig);
6802
6974
  const preprocessorPipeline = this.buildPreprocessorPipelineForRequest(toolManager, request, contextPolicy);
6803
6975
  const modelId = this.resolvePreprocessorModel(request);
6804
6976
  preprocessorPipeline.updateContext({
@@ -6826,7 +6998,8 @@ var AgentMessageOrchestrator = class {
6826
6998
  callbacks,
6827
6999
  void 0,
6828
7000
  extraOptions?.generate,
6829
- contextPolicy
7001
+ contextPolicy,
7002
+ effectiveContextBudget.totalBudget
6830
7003
  );
6831
7004
  this.debug("Context built", { afterContextCount: contextResult.messages.length });
6832
7005
  if (this.options.processing.debugMode) {
@@ -6859,7 +7032,7 @@ var AgentMessageOrchestrator = class {
6859
7032
  processedCount: contextResult.messages.length,
6860
7033
  tokenUsage: {
6861
7034
  estimated: contextResult.tokenUsage.used,
6862
- budget: this.options.tokenBudget.maxTokens,
7035
+ budget: effectiveContextBudget.totalBudget,
6863
7036
  remaining: contextResult.tokenUsage.remaining
6864
7037
  },
6865
7038
  processingStats: contextResult.processingStats,
@@ -6879,13 +7052,13 @@ var AgentMessageOrchestrator = class {
6879
7052
  async runPreprocessorPipeline(preprocessorPipeline, messages) {
6880
7053
  return preprocessorPipeline.process(messages);
6881
7054
  }
6882
- async buildContextFromPreprocessedMessages(request, conversationSession, messages, callbacks, phaseOverride, generate, contextPolicy) {
6883
- const totalBudget = this.options.tokenBudget.maxTokens - this.options.tokenBudget.reservedForResponse;
7055
+ async buildContextFromPreprocessedMessages(request, conversationSession, messages, callbacks, phaseOverride, generate, contextPolicy, totalBudget) {
7056
+ const resolvedTotalBudget = totalBudget ?? this.options.tokenBudget.maxTokens - this.options.tokenBudget.reservedForResponse;
6884
7057
  const contextResult = await this.agentContextManager.buildContextFromPreprocessedMessages(
6885
7058
  request,
6886
7059
  conversationSession,
6887
7060
  messages,
6888
- totalBudget,
7061
+ resolvedTotalBudget,
6889
7062
  callbacks,
6890
7063
  phaseOverride,
6891
7064
  generate,
@@ -6966,22 +7139,33 @@ var BaseAgentTask = class {
6966
7139
  });
6967
7140
  }
6968
7141
  messages.push(...fenceMessages["after-system"]);
7142
+ const currentUserIndex = findCurrentUserInputIndex(history, request.query);
7143
+ const historyBeforeCurrentUser = currentUserIndex === -1 ? history : history.slice(0, currentUserIndex);
7144
+ const currentUserMessage = currentUserIndex === -1 ? this.createCurrentUserMessage(request.query) : history[currentUserIndex];
7145
+ const historyAfterCurrentUser = currentUserIndex === -1 ? [] : history.slice(currentUserIndex + 1);
7146
+ messages.push(...historyBeforeCurrentUser);
6969
7147
  messages.push(...fenceMessages["before-current-user"]);
6970
- const hasUserMessageInHistory = history.some((m) => m.role === "user");
6971
- if (!hasUserMessageInHistory && request.query && request.query.trim()) {
6972
- messages.push({
6973
- id: generateMessageId(),
6974
- role: "user",
6975
- type: "user_input",
6976
- content: request.query.trim(),
6977
- timestamp: Date.now()
6978
- });
7148
+ if (currentUserMessage) {
7149
+ messages.push(currentUserMessage);
6979
7150
  }
6980
7151
  messages.push(...fenceMessages["after-current-user"]);
6981
- messages.push(...history);
7152
+ messages.push(...historyAfterCurrentUser);
6982
7153
  this.insertAfterLastToolResult(messages, fenceMessages["after-last-tool-result"]);
6983
7154
  return messages;
6984
7155
  }
7156
+ createCurrentUserMessage(query) {
7157
+ const content = query.trim();
7158
+ if (!content) {
7159
+ return null;
7160
+ }
7161
+ return {
7162
+ id: generateMessageId(),
7163
+ role: "user",
7164
+ type: "user_input",
7165
+ content,
7166
+ timestamp: Date.now()
7167
+ };
7168
+ }
6985
7169
  createFenceMessages(fences) {
6986
7170
  const grouped = {
6987
7171
  "after-system": [],
@@ -7046,6 +7230,19 @@ function findLastIndex2(items, predicate) {
7046
7230
  }
7047
7231
  return -1;
7048
7232
  }
7233
+ function findCurrentUserInputIndex(history, query) {
7234
+ const normalizedQuery = query.trim();
7235
+ if (!normalizedQuery) {
7236
+ return -1;
7237
+ }
7238
+ for (let index = history.length - 1; index >= 0; index -= 1) {
7239
+ const message = history[index];
7240
+ if (message.role === "user" && message.type === "user_input" && message.content.trim() === normalizedQuery) {
7241
+ return index;
7242
+ }
7243
+ }
7244
+ return -1;
7245
+ }
7049
7246
 
7050
7247
  // src/context-manager/profiles/agent/tools/index.ts
7051
7248
  var tools_exports2 = {};
@@ -8645,6 +8842,6 @@ function convertEventsToChatMessages(events) {
8645
8842
  return messages;
8646
8843
  }
8647
8844
 
8648
- export { AGENT_CONSTANTS, AGENT_CONTEXT_BUILDER_CONFIG, AISummaryGenerator, BaseContextProvider2 as BaseContextProvider, BaseConversationalTask, BasePreprocessor, CHECKPOINT_MARKER_TYPE, ContextProviderRegistry3 as ChatContextProviderRegistry, CoreContextProvider as ChatCoreContextProvider, MessageOrchestrator as ChatMessageOrchestrator, WorkingMemoryProvider as ChatWorkingMemoryProvider, ContextProviderError, ContextProviderRegistry, ContextTraceCollector, DEFAULT_MUST_KEEP_POLICY, FenceLifetimePreprocessor, HistoryPurificationPreprocessor, SUMMARIZATION_FAILED_ERROR_CODE, SummarizationCandidateSelector, SummarizationProvider, SummarizationStateUtils, SummarizationTrigger, TOOL_HISTORY_OVERFLOW_ERROR_CODE, config_exports as agentConfig, context_exports as agentContext, contracts_exports as agentContracts, orchestration_exports as agentOrchestration, preprocessors_exports as agentPreprocessors, agentSpecToContextBuilderConfig, agentSpecToRuntimeOptions, tasks_exports as agentTasks, tools_exports2 as agentTools, utils_exports as agentUtils, aiMessageToChatMessage, buildGenerateRequestFromAgentRequest, chatMessageToAiMessage, contextPolicyToContextBuilderConfig, contextPolicyToExecutionOptions, contextPolicyToMustKeepPolicy, contextPolicyToPreprocessorOptions, contextPolicyToProviderOptions, contextPolicyToRuntimeOptions, contextPolicyToSystemReminderOptions, convertEventToChatMessage, convertEventsToChatMessages, createFenceRegistry, createMessageFormatter, findMatchingTruncationRule, formatAgentLlmMessages, getDefaultTokenConfig, isContextProviderError, mergeContextPolicy, messageFormatter };
8845
+ export { AGENT_CONSTANTS, AGENT_CONTEXT_BUILDER_CONFIG, AISummaryGenerator, BaseContextProvider2 as BaseContextProvider, BaseConversationalTask, BasePreprocessor, CHECKPOINT_MARKER_TYPE, ContextProviderRegistry3 as ChatContextProviderRegistry, CoreContextProvider as ChatCoreContextProvider, MessageOrchestrator as ChatMessageOrchestrator, WorkingMemoryProvider as ChatWorkingMemoryProvider, ContextProviderError, ContextProviderRegistry, ContextTraceCollector, CurrentTurnMessageAssembler, DEFAULT_MUST_KEEP_POLICY, FenceLifetimePreprocessor, HistoryPurificationPreprocessor, SUMMARIZATION_FAILED_ERROR_CODE, SummarizationCandidateSelector, SummarizationProvider, SummarizationStateUtils, SummarizationTrigger, TOOL_HISTORY_OVERFLOW_ERROR_CODE, config_exports as agentConfig, context_exports as agentContext, contracts_exports as agentContracts, orchestration_exports as agentOrchestration, preprocessors_exports as agentPreprocessors, agentSpecToContextBuilderConfig, agentSpecToRuntimeOptions, tasks_exports as agentTasks, tools_exports2 as agentTools, utils_exports as agentUtils, aiMessageToChatMessage, buildGenerateRequestFromAgentRequest, chatMessageToAiMessage, contextPolicyToContextBuilderConfig, contextPolicyToExecutionOptions, contextPolicyToMustKeepPolicy, contextPolicyToPreprocessorOptions, contextPolicyToProviderOptions, contextPolicyToRuntimeOptions, contextPolicyToSystemReminderOptions, convertEventToChatMessage, convertEventsToChatMessages, createFenceRegistry, createMessageFormatter, findMatchingTruncationRule, formatAgentLlmMessages, getDefaultTokenConfig, isContextProviderError, mergeContextPolicy, messageFormatter };
8649
8846
  //# sourceMappingURL=context-manager.js.map
8650
8847
  //# sourceMappingURL=context-manager.js.map