@aipack-ai/multi-agent 0.0.1 → 0.0.2
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/dist/index.js +46 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -768,6 +768,24 @@ function isContextOverflow(message, contextWindow) {
|
|
|
768
768
|
return true;
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
|
+
if (message.stopReason === "length" && message.content) {
|
|
772
|
+
const blocks = Array.isArray(message.content) ? message.content : null;
|
|
773
|
+
if (blocks) {
|
|
774
|
+
const hasMeaningfulText = blocks.some(
|
|
775
|
+
(b) => b.type === "text" && typeof b.text === "string" && b.text.trim().length > 0
|
|
776
|
+
);
|
|
777
|
+
const hasToolCall = blocks.some((b) => b.type === "toolCall");
|
|
778
|
+
const hasThinking = blocks.some((b) => b.type === "thinking");
|
|
779
|
+
if (!hasMeaningfulText && !hasToolCall && hasThinking) {
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (message.maxTokens && message.maxTokens > 0 && message.stopReason === "length" && message.usage) {
|
|
785
|
+
if (message.usage.output >= Math.floor(message.maxTokens * 0.95)) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
771
789
|
return false;
|
|
772
790
|
}
|
|
773
791
|
|
|
@@ -1863,12 +1881,14 @@ ${text}`,
|
|
|
1863
1881
|
/**
|
|
1864
1882
|
* 单回合模型调用 + 上下文溢出自动恢复闭环。
|
|
1865
1883
|
*
|
|
1866
|
-
* 检测(isContextOverflow,统一传入 model.contextWindow
|
|
1867
|
-
* 静默溢出 /
|
|
1868
|
-
* →
|
|
1884
|
+
* 检测(isContextOverflow,统一传入 model.contextWindow / content / maxTokens,
|
|
1885
|
+
* 覆盖显式错误 / 静默溢出 / 输入截断溢出 / 输出 thinking 耗尽 / 输出打满 五模式)
|
|
1886
|
+
* → 丢弃失败的 assistant 消息 → 截断会话历史 → 同回合重试(不消耗回合数,
|
|
1887
|
+
* 上限 OVERFLOW_RECOVERY_LIMIT):
|
|
1869
1888
|
*
|
|
1870
|
-
* - 显式错误 /
|
|
1871
|
-
* error chunk
|
|
1889
|
+
* - 显式错误 / 零产出截断溢出 / thinking 耗尽溢出 / 输出打满溢出:丢弃失败
|
|
1890
|
+
* 消息后重试;流式路径吞掉可恢复的 error chunk(消费者看不到瞬态错误),
|
|
1891
|
+
* 不可恢复时补发。
|
|
1872
1892
|
* - 静默溢出(stop + 有完整产出):保留回复,仅压缩旧上下文供后续轮次。
|
|
1873
1893
|
* - 恢复耗尽或单请求超窗(无可丢弃):返回最后一次错误消息,维持旧行为。
|
|
1874
1894
|
*
|
|
@@ -1877,14 +1897,22 @@ ${text}`,
|
|
|
1877
1897
|
*/
|
|
1878
1898
|
async *modelTurnWithRecovery(compilation, signal, sessionKey, stream) {
|
|
1879
1899
|
const contextWindow = this._model.contextWindow;
|
|
1900
|
+
const maxTokens = this._model.maxTokens;
|
|
1880
1901
|
let recoveries = 0;
|
|
1902
|
+
const toProbe = (m) => ({
|
|
1903
|
+
stopReason: m.stopReason,
|
|
1904
|
+
errorMessage: m.errorMessage,
|
|
1905
|
+
usage: m.usage,
|
|
1906
|
+
content: m.content,
|
|
1907
|
+
maxTokens
|
|
1908
|
+
});
|
|
1881
1909
|
while (true) {
|
|
1882
1910
|
let assistant = null;
|
|
1883
1911
|
let suppressed = null;
|
|
1884
1912
|
for await (const event of this.streamModelEvents(compilation, signal, stream)) {
|
|
1885
1913
|
if (event.type === "error") {
|
|
1886
1914
|
const msg = event.message;
|
|
1887
|
-
if (recoveries < OVERFLOW_RECOVERY_LIMIT && isContextOverflow(msg, contextWindow)) {
|
|
1915
|
+
if (recoveries < OVERFLOW_RECOVERY_LIMIT && isContextOverflow(toProbe(msg), contextWindow)) {
|
|
1888
1916
|
suppressed = msg;
|
|
1889
1917
|
continue;
|
|
1890
1918
|
}
|
|
@@ -1899,13 +1927,22 @@ ${text}`,
|
|
|
1899
1927
|
}
|
|
1900
1928
|
const final = assistant ?? suppressed;
|
|
1901
1929
|
if (!final) return null;
|
|
1902
|
-
if (isContextOverflow(final, contextWindow)) {
|
|
1903
|
-
const
|
|
1930
|
+
if (isContextOverflow(toProbe(final), contextWindow)) {
|
|
1931
|
+
const output = final.usage?.output ?? 0;
|
|
1932
|
+
const blocks = Array.isArray(final.content) ? final.content : null;
|
|
1933
|
+
const hasMeaningfulText = blocks?.some(
|
|
1934
|
+
(b) => b.type === "text" && "text" in b && typeof b.text === "string" && b.text.trim().length > 0
|
|
1935
|
+
);
|
|
1936
|
+
const hasToolCall = blocks?.some((b) => b.type === "toolCall");
|
|
1937
|
+
const thinkingOnly = blocks ? !hasMeaningfulText && !hasToolCall && blocks.some((b) => b.type === "thinking") : false;
|
|
1938
|
+
const outputFull = maxTokens > 0 && output >= Math.floor(maxTokens * 0.95);
|
|
1939
|
+
const failed = final.stopReason === "error" || output === 0 || thinkingOnly || outputFull;
|
|
1904
1940
|
if (failed && recoveries < OVERFLOW_RECOVERY_LIMIT) {
|
|
1905
1941
|
recoveries += 1;
|
|
1906
1942
|
if (await this.recoverFromOverflow(compilation, recoveries, sessionKey, signal)) {
|
|
1943
|
+
const reason = thinkingOnly ? "thinking \u8017\u5C3D" : outputFull ? "output \u6253\u6EE1" : final.stopReason;
|
|
1907
1944
|
console.warn(
|
|
1908
|
-
`[Runtime] \u4E0A\u4E0B\u6587\u6EA2\u51FA\uFF0C\u5DF2\u538B\u7F29\u5386\u53F2\
|
|
1945
|
+
`[Runtime] \u4E0A\u4E0B\u6587\u6EA2\u51FA\uFF08${reason}\uFF09\uFF0C\u5DF2\u538B\u7F29\u5386\u53F2\u5E76\u540C\u56DE\u5408\u91CD\u8BD5\uFF08${recoveries}/${OVERFLOW_RECOVERY_LIMIT}\uFF09`
|
|
1909
1946
|
);
|
|
1910
1947
|
await this.emitTelemetry("onRetry", {
|
|
1911
1948
|
traceId: compilation.traceId,
|