@linnlabs/linnkit 0.9.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.
- package/CHANGELOG.md +13 -0
- package/bin/linnkit.cjs +7 -0
- package/dist/{agentSpec-EkmviZjy.d.cts → agentSpec-Du4Iye0q.d.cts} +16 -1
- package/dist/{agentSpec-EkmviZjy.d.ts → agentSpec-Du4Iye0q.d.ts} +16 -1
- package/dist/cli.cjs +118 -65
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +118 -65
- package/dist/cli.js.map +1 -1
- package/dist/context-manager.cjs +234 -32
- package/dist/context-manager.cjs.map +1 -1
- package/dist/context-manager.d.cts +52 -15
- package/dist/context-manager.d.ts +52 -15
- package/dist/context-manager.js +234 -33
- package/dist/context-manager.js.map +1 -1
- package/dist/{context-trace-HE2qY5Q-.d.cts → context-trace-BHKDS-eq.d.cts} +2 -2
- package/dist/{context-trace-DRi5M4lX.d.ts → context-trace-CHbqHmyE.d.ts} +2 -2
- package/dist/contracts.cjs +3 -1
- package/dist/contracts.cjs.map +1 -1
- package/dist/contracts.d.cts +3 -3
- package/dist/contracts.d.ts +3 -3
- package/dist/contracts.js +3 -1
- package/dist/contracts.js.map +1 -1
- package/dist/{defaultGraphExecutor-BBswR8wn.d.ts → defaultGraphExecutor-B29_qTHy.d.ts} +16 -15
- package/dist/{defaultGraphExecutor-BIjJj7WF.d.cts → defaultGraphExecutor-C2E59v_R.d.cts} +16 -15
- package/dist/{index-BanRABEt.d.cts → index-BAaUP9yU.d.cts} +26 -14
- package/dist/{index-Z8NXKNwI.d.ts → index-BaVpVNi2.d.ts} +26 -14
- package/dist/{index-DO4dQgf2.d.cts → index-BnYCS8Zg.d.cts} +2 -2
- package/dist/{index-CJeWHopy.d.ts → index-C0DAjsdX.d.ts} +2 -2
- package/dist/{index-Dl5PLgAv.d.cts → index-CKQzzZ5Y.d.cts} +2 -2
- package/dist/{index-CHqwkvGp.d.ts → index-D0mKxTR5.d.ts} +2 -2
- package/dist/index.cjs +186 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +186 -85
- package/dist/index.js.map +1 -1
- package/dist/{ports-DnLuKfpE.d.ts → ports-DpPTFhSd.d.ts} +2 -2
- package/dist/{ports-DaatKJXp.d.cts → ports-s-tSp3sB.d.cts} +2 -2
- package/dist/quickstart.cjs +119 -65
- package/dist/quickstart.cjs.map +1 -1
- package/dist/quickstart.d.cts +7 -7
- package/dist/quickstart.d.ts +7 -7
- package/dist/quickstart.js +119 -65
- package/dist/quickstart.js.map +1 -1
- package/dist/{runAgent-CPj_9e58.d.ts → runAgent-C6F-399C.d.ts} +5 -5
- package/dist/{runAgent-HYKlXbVr.d.cts → runAgent-ilEj66Ik.d.cts} +5 -5
- package/dist/{runHandle-D3gPsD7B.d.cts → runHandle-BNOqS-Bl.d.cts} +3 -3
- package/dist/{runHandle-CyXvzgzk.d.ts → runHandle-BdLXOFqF.d.ts} +3 -3
- package/dist/runtime-kernel/events.cjs +1 -0
- package/dist/runtime-kernel/events.cjs.map +1 -1
- package/dist/runtime-kernel/events.d.cts +4 -4
- package/dist/runtime-kernel/events.d.ts +4 -4
- package/dist/runtime-kernel/events.js +1 -0
- package/dist/runtime-kernel/events.js.map +1 -1
- package/dist/runtime-kernel.cjs +181 -82
- package/dist/runtime-kernel.cjs.map +1 -1
- package/dist/runtime-kernel.d.cts +8 -8
- package/dist/runtime-kernel.d.ts +8 -8
- package/dist/runtime-kernel.js +181 -83
- package/dist/runtime-kernel.js.map +1 -1
- package/dist/testkit.cjs +181 -82
- package/dist/testkit.cjs.map +1 -1
- package/dist/testkit.d.cts +8 -8
- package/dist/testkit.d.ts +8 -8
- package/dist/testkit.js +181 -82
- package/dist/testkit.js.map +1 -1
- package/dist/{todo-B1PmDlp3.d.cts → todo-Ca8llpRQ.d.cts} +1 -1
- package/dist/{todo-B1PmDlp3.d.ts → todo-Ca8llpRQ.d.ts} +1 -1
- package/dist/{toolContracts-CLkQmhTG.d.cts → toolContracts-Bm3EZ1UM.d.cts} +13 -2
- package/dist/{toolContracts-Blll0241.d.ts → toolContracts-f8lzZBNa.d.ts} +13 -2
- package/docs/integration/README.md +1 -1
- package/docs/integration/agent-registration-guide.md +1 -1
- package/docs/integration/child-runs.md +4 -1
- package/docs/integration/context-engineering.md +30 -15
- package/docs/integration/context-fences.md +32 -3
- package/docs/integration/llm-provider.md +1 -1
- package/docs/integration/persistence.md +1 -0
- package/docs/integration/run-supervisor.md +3 -0
- package/docs/integration/tool-development-guide.md +7 -5
- package/docs/integration/tool-history.md +43 -17
- package/package.json +4 -3
package/dist/context-manager.cjs
CHANGED
|
@@ -499,6 +499,7 @@ var AgentSpecBudgetPolicy = zod.z.object({
|
|
|
499
499
|
});
|
|
500
500
|
var AgentSpecToolHistoryPolicy = zod.z.object({
|
|
501
501
|
strategy: zod.z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
502
|
+
retentionMode: zod.z.enum(["drop", "compress"]).optional(),
|
|
502
503
|
keepLatestToolPairs: zod.z.number().int().nonnegative().optional(),
|
|
503
504
|
keepLatestRuns: zod.z.number().int().nonnegative().optional(),
|
|
504
505
|
maxInteractionGroups: zod.z.number().int().nonnegative().optional(),
|
|
@@ -613,12 +614,13 @@ var AgentSpecContextPolicy = zod.z.object({
|
|
|
613
614
|
var DEFAULT_CONTEXT_POLICY = {
|
|
614
615
|
profileId: "agent",
|
|
615
616
|
budget: {
|
|
616
|
-
maxTokens:
|
|
617
|
+
maxTokens: 232e3,
|
|
617
618
|
reservedForResponse: 2400,
|
|
618
619
|
workingMemoryBudgetPercentage: 0.7
|
|
619
620
|
},
|
|
620
621
|
toolHistory: {
|
|
621
622
|
strategy: "per-run",
|
|
623
|
+
retentionMode: "drop",
|
|
622
624
|
keepLatestToolPairs: 2,
|
|
623
625
|
keepLatestRuns: 1,
|
|
624
626
|
maxInteractionGroups: 12,
|
|
@@ -1774,6 +1776,157 @@ function findLastIndex(items, predicate) {
|
|
|
1774
1776
|
return -1;
|
|
1775
1777
|
}
|
|
1776
1778
|
|
|
1779
|
+
// src/context-manager/shared/preprocessors/currentTurnMessageAssembler.ts
|
|
1780
|
+
var CurrentTurnMessageAssembler = class extends BasePreprocessor {
|
|
1781
|
+
name = "CurrentTurnMessageAssembler";
|
|
1782
|
+
description = "Assembles current-turn fences into system_prompt and user_input messages";
|
|
1783
|
+
priority = 10;
|
|
1784
|
+
fenceRegistry;
|
|
1785
|
+
constructor(options) {
|
|
1786
|
+
super();
|
|
1787
|
+
this.fenceRegistry = options.fenceRegistry;
|
|
1788
|
+
}
|
|
1789
|
+
async process(messages, _context) {
|
|
1790
|
+
const systemResult = assembleSystemPrompt({ messages, fenceRegistry: this.fenceRegistry });
|
|
1791
|
+
const userResult = assembleCurrentUserInput({
|
|
1792
|
+
messages: systemResult.messages,
|
|
1793
|
+
fenceRegistry: this.fenceRegistry
|
|
1794
|
+
});
|
|
1795
|
+
const modifiedCount = systemResult.modifiedCount + userResult.modifiedCount;
|
|
1796
|
+
return this.createResult(
|
|
1797
|
+
messages,
|
|
1798
|
+
userResult.messages,
|
|
1799
|
+
modifiedCount > 0 ? ["current_turn_message_assembly"] : [],
|
|
1800
|
+
modifiedCount
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
};
|
|
1804
|
+
function assembleSystemPrompt(params) {
|
|
1805
|
+
const systemIndex = params.messages.findIndex(
|
|
1806
|
+
(message) => message.role === "system" && message.type === "system_prompt"
|
|
1807
|
+
);
|
|
1808
|
+
if (systemIndex === -1) {
|
|
1809
|
+
return { messages: [...params.messages], modifiedCount: 0 };
|
|
1810
|
+
}
|
|
1811
|
+
const fences = collectAdjacentFences({
|
|
1812
|
+
messages: params.messages,
|
|
1813
|
+
startIndex: systemIndex + 1,
|
|
1814
|
+
direction: 1,
|
|
1815
|
+
fenceRegistry: params.fenceRegistry,
|
|
1816
|
+
matches: (descriptor) => descriptor.llmRole === "system" && descriptor.placement === "after-system"
|
|
1817
|
+
});
|
|
1818
|
+
if (fences.length === 0) {
|
|
1819
|
+
return { messages: [...params.messages], modifiedCount: 0 };
|
|
1820
|
+
}
|
|
1821
|
+
const indexesToRemove = new Set(fences.map((fence) => fence.index));
|
|
1822
|
+
const systemPrompt = params.messages[systemIndex];
|
|
1823
|
+
const assembledSystemPrompt = {
|
|
1824
|
+
...systemPrompt,
|
|
1825
|
+
content: [
|
|
1826
|
+
systemPrompt.content,
|
|
1827
|
+
...fences.map(formatFence)
|
|
1828
|
+
].join("\n\n"),
|
|
1829
|
+
metadata: {
|
|
1830
|
+
...systemPrompt.metadata,
|
|
1831
|
+
assembledFenceKinds: fences.map((fence) => fence.message.metadata?.fenceKind).filter((kind) => typeof kind === "string")
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
return {
|
|
1835
|
+
messages: params.messages.map(
|
|
1836
|
+
(message, index) => index === systemIndex ? assembledSystemPrompt : message
|
|
1837
|
+
).filter((_, index) => !indexesToRemove.has(index)),
|
|
1838
|
+
modifiedCount: fences.length + 1
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1841
|
+
function assembleCurrentUserInput(params) {
|
|
1842
|
+
const currentUserIndex = findLastUserInputIndex(params.messages);
|
|
1843
|
+
if (currentUserIndex === -1) {
|
|
1844
|
+
return { messages: [...params.messages], modifiedCount: 0 };
|
|
1845
|
+
}
|
|
1846
|
+
const beforeFences = collectAdjacentFences({
|
|
1847
|
+
messages: params.messages,
|
|
1848
|
+
startIndex: currentUserIndex - 1,
|
|
1849
|
+
direction: -1,
|
|
1850
|
+
fenceRegistry: params.fenceRegistry,
|
|
1851
|
+
matches: (descriptor) => isUserCurrentTurnPlacement(descriptor, "before-current-user")
|
|
1852
|
+
}).reverse();
|
|
1853
|
+
const afterFences = collectAdjacentFences({
|
|
1854
|
+
messages: params.messages,
|
|
1855
|
+
startIndex: currentUserIndex + 1,
|
|
1856
|
+
direction: 1,
|
|
1857
|
+
fenceRegistry: params.fenceRegistry,
|
|
1858
|
+
matches: (descriptor) => isUserCurrentTurnPlacement(descriptor, "after-current-user")
|
|
1859
|
+
});
|
|
1860
|
+
if (beforeFences.length === 0 && afterFences.length === 0) {
|
|
1861
|
+
return { messages: [...params.messages], modifiedCount: 0 };
|
|
1862
|
+
}
|
|
1863
|
+
const indexesToRemove = /* @__PURE__ */ new Set([
|
|
1864
|
+
...beforeFences.map((fence) => fence.index),
|
|
1865
|
+
...afterFences.map((fence) => fence.index)
|
|
1866
|
+
]);
|
|
1867
|
+
const currentUser = params.messages[currentUserIndex];
|
|
1868
|
+
const assembledUser = {
|
|
1869
|
+
...currentUser,
|
|
1870
|
+
content: [
|
|
1871
|
+
...beforeFences.map(formatFence),
|
|
1872
|
+
wrapUserRequest(currentUser.content),
|
|
1873
|
+
...afterFences.map(formatFence)
|
|
1874
|
+
].join("\n\n"),
|
|
1875
|
+
metadata: {
|
|
1876
|
+
...currentUser.metadata,
|
|
1877
|
+
assembledFenceKinds: [
|
|
1878
|
+
...beforeFences.map((fence) => fence.message.metadata?.fenceKind),
|
|
1879
|
+
...afterFences.map((fence) => fence.message.metadata?.fenceKind)
|
|
1880
|
+
].filter((kind) => typeof kind === "string")
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
return {
|
|
1884
|
+
messages: params.messages.map(
|
|
1885
|
+
(message, index) => index === currentUserIndex ? assembledUser : message
|
|
1886
|
+
).filter((_, index) => !indexesToRemove.has(index)),
|
|
1887
|
+
modifiedCount: indexesToRemove.size + 1
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1890
|
+
function findLastUserInputIndex(messages) {
|
|
1891
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
1892
|
+
const message = messages[index];
|
|
1893
|
+
if (message.role === "user" && message.type === "user_input") {
|
|
1894
|
+
return index;
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
return -1;
|
|
1898
|
+
}
|
|
1899
|
+
function collectAdjacentFences(params) {
|
|
1900
|
+
const result = [];
|
|
1901
|
+
for (let index = params.startIndex; index >= 0 && index < params.messages.length; index += params.direction) {
|
|
1902
|
+
const message = params.messages[index];
|
|
1903
|
+
if (message.type !== "context_injection") {
|
|
1904
|
+
break;
|
|
1905
|
+
}
|
|
1906
|
+
const fenceKind = message.metadata?.fenceKind;
|
|
1907
|
+
if (!fenceKind) {
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
const descriptor = params.fenceRegistry.get(fenceKind);
|
|
1911
|
+
if (!descriptor || !params.matches(descriptor)) {
|
|
1912
|
+
break;
|
|
1913
|
+
}
|
|
1914
|
+
result.push({ index, message, descriptor });
|
|
1915
|
+
}
|
|
1916
|
+
return result;
|
|
1917
|
+
}
|
|
1918
|
+
function isUserCurrentTurnPlacement(descriptor, placement) {
|
|
1919
|
+
return descriptor.llmRole === "user" && descriptor.placement === placement;
|
|
1920
|
+
}
|
|
1921
|
+
function formatFence(fence) {
|
|
1922
|
+
return fence.descriptor.formatter(fence.message.content, fence.message.metadata?.fenceAttrs ?? {});
|
|
1923
|
+
}
|
|
1924
|
+
function wrapUserRequest(content) {
|
|
1925
|
+
return `<user_request>
|
|
1926
|
+
${content.trim()}
|
|
1927
|
+
</user_request>`;
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1777
1930
|
// src/context-manager/shared/providers/base.ts
|
|
1778
1931
|
var TOOL_HISTORY_OVERFLOW_ERROR_CODE = "TOOL_HISTORY_OVERFLOW";
|
|
1779
1932
|
var SUMMARIZATION_FAILED_ERROR_CODE = "SUMMARIZATION_FAILED";
|
|
@@ -2576,7 +2729,7 @@ __export(config_exports, {
|
|
|
2576
2729
|
var AGENT_CONTEXT_BUILDER_CONFIG = {
|
|
2577
2730
|
// === 绝对Token限制设置 ===
|
|
2578
2731
|
/** 默认最大Token预算上限 */
|
|
2579
|
-
DEFAULT_MAX_TOKENS:
|
|
2732
|
+
DEFAULT_MAX_TOKENS: 232e3,
|
|
2580
2733
|
/** 响应预留Token数 */
|
|
2581
2734
|
RESERVED_FOR_RESPONSE: 2400,
|
|
2582
2735
|
// === Agent专用工作记忆填充策略 ===
|
|
@@ -3189,6 +3342,7 @@ var ToolPairMatcher = class {
|
|
|
3189
3342
|
constructor(config) {
|
|
3190
3343
|
this.config = config;
|
|
3191
3344
|
}
|
|
3345
|
+
config;
|
|
3192
3346
|
/**
|
|
3193
3347
|
* 判断是否为"预处理阶段压缩的工具历史摘要消息"
|
|
3194
3348
|
* - 该类消息不再是 tool_calls/tool_output 的原始结构,而是 assistant 的自然语言记录
|
|
@@ -3369,6 +3523,7 @@ var ToolPairTruncator = class {
|
|
|
3369
3523
|
constructor(config) {
|
|
3370
3524
|
this.config = config;
|
|
3371
3525
|
}
|
|
3526
|
+
config;
|
|
3372
3527
|
/**
|
|
3373
3528
|
* 智能截断超大的工具对
|
|
3374
3529
|
*
|
|
@@ -3965,7 +4120,7 @@ var AgentWorkingMemoryProvider = class extends BaseContextProvider2 {
|
|
|
3965
4120
|
let workingMemoryTokens = coreTokens;
|
|
3966
4121
|
let processedCount = 0;
|
|
3967
4122
|
const strategiesApplied = [];
|
|
3968
|
-
const workingMemoryBudget = Math.floor(
|
|
4123
|
+
const workingMemoryBudget = Math.floor(context.totalBudget * config.WORKING_MEMORY_BUDGET_PERCENTAGE);
|
|
3969
4124
|
const remainingBudget = workingMemoryBudget - coreTokens;
|
|
3970
4125
|
if (remainingBudget <= 0 && config.MIN_TOOL_INTERACTIONS_TO_KEEP <= 0) {
|
|
3971
4126
|
this.debug("\u26A0\uFE0F \u6838\u5FC3\u4E0A\u4E0B\u6587\u5DF2\u7528\u5C3D\u9884\u7B97\uFF0C\u8DF3\u8FC7\u5DE5\u4F5C\u8BB0\u5FC6\u586B\u5145", {
|
|
@@ -4100,6 +4255,7 @@ var Logger = class {
|
|
|
4100
4255
|
constructor(moduleName) {
|
|
4101
4256
|
this.moduleName = moduleName;
|
|
4102
4257
|
}
|
|
4258
|
+
moduleName;
|
|
4103
4259
|
debug(message, data) {
|
|
4104
4260
|
this.log(0 /* DEBUG */, "debug", message, data);
|
|
4105
4261
|
}
|
|
@@ -4347,6 +4503,7 @@ var DefaultTokenizerPort = class {
|
|
|
4347
4503
|
constructor(config = {}) {
|
|
4348
4504
|
this.config = config;
|
|
4349
4505
|
}
|
|
4506
|
+
config;
|
|
4350
4507
|
estimateText(text, _modelId) {
|
|
4351
4508
|
return TokenCalculator.estimateTokens(text, {
|
|
4352
4509
|
encoding: this.config.encoding,
|
|
@@ -5106,6 +5263,7 @@ __export(orchestration_exports, {
|
|
|
5106
5263
|
var preprocessors_exports = {};
|
|
5107
5264
|
__export(preprocessors_exports, {
|
|
5108
5265
|
BasePreprocessor: () => BasePreprocessor2,
|
|
5266
|
+
CurrentTurnMessageAssembler: () => CurrentTurnMessageAssembler,
|
|
5109
5267
|
FenceLifetimePreprocessor: () => FenceLifetimePreprocessor,
|
|
5110
5268
|
HistoryPurificationPreprocessor: () => HistoryPurificationPreprocessor,
|
|
5111
5269
|
PreprocessorPipeline: () => PreprocessorPipeline,
|
|
@@ -5157,7 +5315,7 @@ var DEFAULT_KEEP_LATEST_RUNS = 1;
|
|
|
5157
5315
|
var DEFAULT_MAX_INTERACTION_GROUPS = 12;
|
|
5158
5316
|
var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
5159
5317
|
name = "ToolHistoryCompressorPreprocessor";
|
|
5160
|
-
description = "\u5DE5\u5177\u5386\u53F2\
|
|
5318
|
+
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";
|
|
5161
5319
|
priority = 0;
|
|
5162
5320
|
summarizer = createDefaultToolOutputSummarizer();
|
|
5163
5321
|
options;
|
|
@@ -5165,6 +5323,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
|
5165
5323
|
super();
|
|
5166
5324
|
this.options = {
|
|
5167
5325
|
strategy: options.strategy ?? "per-run",
|
|
5326
|
+
retentionMode: options.retentionMode ?? "drop",
|
|
5168
5327
|
keepLatestToolPairs: normalizeNonNegativeInteger4(
|
|
5169
5328
|
options.keepLatestToolPairs,
|
|
5170
5329
|
DEFAULT_KEEP_LATEST_TOOL_PAIRS
|
|
@@ -5181,7 +5340,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
|
5181
5340
|
};
|
|
5182
5341
|
}
|
|
5183
5342
|
async process(messages, context) {
|
|
5184
|
-
this.debug("\u{1F527} \u5F00\u59CB\u5DE5\u5177\u5386\u53F2\
|
|
5343
|
+
this.debug("\u{1F527} \u5F00\u59CB\u5DE5\u5177\u5386\u53F2\u4FDD\u7559\u5904\u7406", {
|
|
5185
5344
|
\u539F\u59CB\u6D88\u606F\u6570: messages.length
|
|
5186
5345
|
}, context);
|
|
5187
5346
|
const currentRunStartIndex = findCurrentRunStartIndex(messages);
|
|
@@ -5191,17 +5350,18 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
|
5191
5350
|
\u5386\u53F2\u6D88\u606F\u6570: historyMessages.length,
|
|
5192
5351
|
\u5F53\u524D\u8F6E\u6B21\u6D88\u606F\u6570: currentRunMessages.length,
|
|
5193
5352
|
\u5F53\u524D\u8F6E\u6B21\u8D77\u70B9\u7D22\u5F15: currentRunStartIndex,
|
|
5194
|
-
\u5DE5\u5177\
|
|
5353
|
+
\u5DE5\u5177\u4FDD\u7559\u7B56\u7565: this.options.strategy,
|
|
5354
|
+
\u5386\u53F2\u5DE5\u5177\u4FDD\u7559\u6A21\u5F0F: this.options.retentionMode
|
|
5195
5355
|
}, context);
|
|
5196
|
-
const
|
|
5197
|
-
const finalMessages = [...
|
|
5356
|
+
const processedHistory = this.processToolCallPairsInHistory(historyMessages, context);
|
|
5357
|
+
const finalMessages = [...processedHistory, ...currentRunMessages];
|
|
5198
5358
|
const originalCount = messages.length;
|
|
5199
|
-
const
|
|
5200
|
-
const removedCount = originalCount -
|
|
5201
|
-
const appliedStrategies = removedCount > 0 ? ["tool_history_compression"] : [];
|
|
5202
|
-
this.debug("\u2705 \u5DE5\u5177\u5386\u53F2\
|
|
5359
|
+
const processedCount = finalMessages.length;
|
|
5360
|
+
const removedCount = originalCount - processedCount;
|
|
5361
|
+
const appliedStrategies = removedCount > 0 ? [this.options.retentionMode === "compress" ? "tool_history_compression" : "tool_history_drop"] : [];
|
|
5362
|
+
this.debug("\u2705 \u5DE5\u5177\u5386\u53F2\u4FDD\u7559\u5904\u7406\u5B8C\u6210", {
|
|
5203
5363
|
\u539F\u59CB\u6D88\u606F: originalCount,
|
|
5204
|
-
\
|
|
5364
|
+
\u5904\u7406\u540E\u6D88\u606F: processedCount,
|
|
5205
5365
|
\u51CF\u5C11\u6D88\u606F: removedCount,
|
|
5206
5366
|
Token\u8282\u7701\u4F30\u8BA1: `\u7EA6${removedCount * 50}\u4E2AToken`
|
|
5207
5367
|
}, context);
|
|
@@ -5222,7 +5382,7 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
|
5222
5382
|
}
|
|
5223
5383
|
return false;
|
|
5224
5384
|
}
|
|
5225
|
-
|
|
5385
|
+
processToolCallPairsInHistory(historyMessages, context) {
|
|
5226
5386
|
if (historyMessages.length < 2) {
|
|
5227
5387
|
return historyMessages;
|
|
5228
5388
|
}
|
|
@@ -5243,8 +5403,10 @@ var ToolHistoryCompressorPreprocessor = class extends BasePreprocessor2 {
|
|
|
5243
5403
|
if (!group.isComplete || keepAnchorIds.has(group.anchorId)) {
|
|
5244
5404
|
continue;
|
|
5245
5405
|
}
|
|
5246
|
-
|
|
5247
|
-
|
|
5406
|
+
if (this.options.retentionMode === "compress") {
|
|
5407
|
+
const compressedMessage = this.compressToolInteractionGroup(group, context);
|
|
5408
|
+
replacementMap.set(group.assistantIndex, compressedMessage);
|
|
5409
|
+
}
|
|
5248
5410
|
for (const messageIndex of group.messageIndexes) {
|
|
5249
5411
|
messagesToRemove.add(messageIndex);
|
|
5250
5412
|
}
|
|
@@ -5663,6 +5825,7 @@ function createDefaultAgentPreprocessorRegistry(options = {}) {
|
|
|
5663
5825
|
registry.register(new ToolReplayProtocolGuardPreprocessor({ policy: options.providerReplay }));
|
|
5664
5826
|
registry.register(new HistoryPurificationPreprocessor({ logPrefix: "Agent-HistoryPurification" }));
|
|
5665
5827
|
if (options.fenceRegistry) {
|
|
5828
|
+
registry.register(new CurrentTurnMessageAssembler({ fenceRegistry: options.fenceRegistry }));
|
|
5666
5829
|
registry.register(new FenceLifetimePreprocessor({ fenceRegistry: options.fenceRegistry }));
|
|
5667
5830
|
}
|
|
5668
5831
|
return registry;
|
|
@@ -6778,6 +6941,18 @@ var AgentMessageOrchestrator = class {
|
|
|
6778
6941
|
tokenizer: this.options.tokenizer,
|
|
6779
6942
|
tokenizerModelId: this.resolvePreprocessorModel(request)
|
|
6780
6943
|
});
|
|
6944
|
+
return contextBuilderConfig;
|
|
6945
|
+
}
|
|
6946
|
+
resolveEffectiveContextBudget(contextBuilderConfig) {
|
|
6947
|
+
const maxTokens = contextBuilderConfig.DEFAULT_MAX_TOKENS ?? this.options.tokenBudget.maxTokens;
|
|
6948
|
+
const reservedForResponse = contextBuilderConfig.RESERVED_FOR_RESPONSE ?? this.options.tokenBudget.reservedForResponse;
|
|
6949
|
+
return {
|
|
6950
|
+
maxTokens,
|
|
6951
|
+
reservedForResponse,
|
|
6952
|
+
// 中文备注:ContextManager 接收的是“可放入上下文的输入预算”,不是模型完整窗口。
|
|
6953
|
+
// 因此单个 agent 通过 contextPolicy.budget 覆盖预算时,这里必须同步使用覆盖后的值。
|
|
6954
|
+
totalBudget: maxTokens - reservedForResponse
|
|
6955
|
+
};
|
|
6781
6956
|
}
|
|
6782
6957
|
async processAgentConversation(request, history, toolManager, callbacks, extraOptions) {
|
|
6783
6958
|
const historyCount = history.length;
|
|
@@ -6796,7 +6971,8 @@ var AgentMessageOrchestrator = class {
|
|
|
6796
6971
|
const allMessages = this.buildCompleteMessageList(request, historyMessages);
|
|
6797
6972
|
this.debug("Built complete message list", { totalCount: allMessages.length });
|
|
6798
6973
|
const contextPolicy = this.resolveContextPolicy(request);
|
|
6799
|
-
this.applyContextPolicy(request, contextPolicy);
|
|
6974
|
+
const contextBuilderConfig = this.applyContextPolicy(request, contextPolicy);
|
|
6975
|
+
const effectiveContextBudget = this.resolveEffectiveContextBudget(contextBuilderConfig);
|
|
6800
6976
|
const preprocessorPipeline = this.buildPreprocessorPipelineForRequest(toolManager, request, contextPolicy);
|
|
6801
6977
|
const modelId = this.resolvePreprocessorModel(request);
|
|
6802
6978
|
preprocessorPipeline.updateContext({
|
|
@@ -6824,7 +7000,8 @@ var AgentMessageOrchestrator = class {
|
|
|
6824
7000
|
callbacks,
|
|
6825
7001
|
void 0,
|
|
6826
7002
|
extraOptions?.generate,
|
|
6827
|
-
contextPolicy
|
|
7003
|
+
contextPolicy,
|
|
7004
|
+
effectiveContextBudget.totalBudget
|
|
6828
7005
|
);
|
|
6829
7006
|
this.debug("Context built", { afterContextCount: contextResult.messages.length });
|
|
6830
7007
|
if (this.options.processing.debugMode) {
|
|
@@ -6857,7 +7034,7 @@ var AgentMessageOrchestrator = class {
|
|
|
6857
7034
|
processedCount: contextResult.messages.length,
|
|
6858
7035
|
tokenUsage: {
|
|
6859
7036
|
estimated: contextResult.tokenUsage.used,
|
|
6860
|
-
budget:
|
|
7037
|
+
budget: effectiveContextBudget.totalBudget,
|
|
6861
7038
|
remaining: contextResult.tokenUsage.remaining
|
|
6862
7039
|
},
|
|
6863
7040
|
processingStats: contextResult.processingStats,
|
|
@@ -6877,13 +7054,13 @@ var AgentMessageOrchestrator = class {
|
|
|
6877
7054
|
async runPreprocessorPipeline(preprocessorPipeline, messages) {
|
|
6878
7055
|
return preprocessorPipeline.process(messages);
|
|
6879
7056
|
}
|
|
6880
|
-
async buildContextFromPreprocessedMessages(request, conversationSession, messages, callbacks, phaseOverride, generate, contextPolicy) {
|
|
6881
|
-
const
|
|
7057
|
+
async buildContextFromPreprocessedMessages(request, conversationSession, messages, callbacks, phaseOverride, generate, contextPolicy, totalBudget) {
|
|
7058
|
+
const resolvedTotalBudget = totalBudget ?? this.options.tokenBudget.maxTokens - this.options.tokenBudget.reservedForResponse;
|
|
6882
7059
|
const contextResult = await this.agentContextManager.buildContextFromPreprocessedMessages(
|
|
6883
7060
|
request,
|
|
6884
7061
|
conversationSession,
|
|
6885
7062
|
messages,
|
|
6886
|
-
|
|
7063
|
+
resolvedTotalBudget,
|
|
6887
7064
|
callbacks,
|
|
6888
7065
|
phaseOverride,
|
|
6889
7066
|
generate,
|
|
@@ -6964,22 +7141,33 @@ var BaseAgentTask = class {
|
|
|
6964
7141
|
});
|
|
6965
7142
|
}
|
|
6966
7143
|
messages.push(...fenceMessages["after-system"]);
|
|
7144
|
+
const currentUserIndex = findCurrentUserInputIndex(history, request.query);
|
|
7145
|
+
const historyBeforeCurrentUser = currentUserIndex === -1 ? history : history.slice(0, currentUserIndex);
|
|
7146
|
+
const currentUserMessage = currentUserIndex === -1 ? this.createCurrentUserMessage(request.query) : history[currentUserIndex];
|
|
7147
|
+
const historyAfterCurrentUser = currentUserIndex === -1 ? [] : history.slice(currentUserIndex + 1);
|
|
7148
|
+
messages.push(...historyBeforeCurrentUser);
|
|
6967
7149
|
messages.push(...fenceMessages["before-current-user"]);
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
messages.push({
|
|
6971
|
-
id: generateMessageId(),
|
|
6972
|
-
role: "user",
|
|
6973
|
-
type: "user_input",
|
|
6974
|
-
content: request.query.trim(),
|
|
6975
|
-
timestamp: Date.now()
|
|
6976
|
-
});
|
|
7150
|
+
if (currentUserMessage) {
|
|
7151
|
+
messages.push(currentUserMessage);
|
|
6977
7152
|
}
|
|
6978
7153
|
messages.push(...fenceMessages["after-current-user"]);
|
|
6979
|
-
messages.push(...
|
|
7154
|
+
messages.push(...historyAfterCurrentUser);
|
|
6980
7155
|
this.insertAfterLastToolResult(messages, fenceMessages["after-last-tool-result"]);
|
|
6981
7156
|
return messages;
|
|
6982
7157
|
}
|
|
7158
|
+
createCurrentUserMessage(query) {
|
|
7159
|
+
const content = query.trim();
|
|
7160
|
+
if (!content) {
|
|
7161
|
+
return null;
|
|
7162
|
+
}
|
|
7163
|
+
return {
|
|
7164
|
+
id: generateMessageId(),
|
|
7165
|
+
role: "user",
|
|
7166
|
+
type: "user_input",
|
|
7167
|
+
content,
|
|
7168
|
+
timestamp: Date.now()
|
|
7169
|
+
};
|
|
7170
|
+
}
|
|
6983
7171
|
createFenceMessages(fences) {
|
|
6984
7172
|
const grouped = {
|
|
6985
7173
|
"after-system": [],
|
|
@@ -7044,6 +7232,19 @@ function findLastIndex2(items, predicate) {
|
|
|
7044
7232
|
}
|
|
7045
7233
|
return -1;
|
|
7046
7234
|
}
|
|
7235
|
+
function findCurrentUserInputIndex(history, query) {
|
|
7236
|
+
const normalizedQuery = query.trim();
|
|
7237
|
+
if (!normalizedQuery) {
|
|
7238
|
+
return -1;
|
|
7239
|
+
}
|
|
7240
|
+
for (let index = history.length - 1; index >= 0; index -= 1) {
|
|
7241
|
+
const message = history[index];
|
|
7242
|
+
if (message.role === "user" && message.type === "user_input" && message.content.trim() === normalizedQuery) {
|
|
7243
|
+
return index;
|
|
7244
|
+
}
|
|
7245
|
+
}
|
|
7246
|
+
return -1;
|
|
7247
|
+
}
|
|
7047
7248
|
|
|
7048
7249
|
// src/context-manager/profiles/agent/tools/index.ts
|
|
7049
7250
|
var tools_exports2 = {};
|
|
@@ -8657,6 +8858,7 @@ exports.ChatWorkingMemoryProvider = WorkingMemoryProvider;
|
|
|
8657
8858
|
exports.ContextProviderError = ContextProviderError;
|
|
8658
8859
|
exports.ContextProviderRegistry = ContextProviderRegistry;
|
|
8659
8860
|
exports.ContextTraceCollector = ContextTraceCollector;
|
|
8861
|
+
exports.CurrentTurnMessageAssembler = CurrentTurnMessageAssembler;
|
|
8660
8862
|
exports.DEFAULT_MUST_KEEP_POLICY = DEFAULT_MUST_KEEP_POLICY;
|
|
8661
8863
|
exports.FenceLifetimePreprocessor = FenceLifetimePreprocessor;
|
|
8662
8864
|
exports.HistoryPurificationPreprocessor = HistoryPurificationPreprocessor;
|