@everworker/oneringai 0.4.0 → 0.4.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/README.md +5 -1
- package/dist/{IProvider-BUbU5UwV.d.ts → IProvider-B6hqVVq8.d.ts} +1 -1
- package/dist/{IProvider-Br817mKc.d.cts → IProvider-CNJqZItJ.d.cts} +1 -1
- package/dist/{ImageModel-zh19LiVM.d.cts → ImageModel-B64HX3lN.d.cts} +1 -1
- package/dist/{ImageModel-B2KUs-ps.d.ts → ImageModel-DU-y_WOb.d.ts} +1 -1
- package/dist/capabilities/agents/index.d.cts +2 -2
- package/dist/capabilities/agents/index.d.ts +2 -2
- package/dist/capabilities/images/index.d.cts +2 -2
- package/dist/capabilities/images/index.d.ts +2 -2
- package/dist/{index-CR5PHkck.d.cts → index-9VOnAX17.d.ts} +47 -7
- package/dist/{index-Cb7N9QIj.d.ts → index-BMjyFNJQ.d.cts} +47 -7
- package/dist/index.cjs +854 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +214 -12
- package/dist/index.d.ts +214 -12
- package/dist/index.js +852 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -11943,6 +11943,9 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
11943
11943
|
}
|
|
11944
11944
|
};
|
|
11945
11945
|
|
|
11946
|
+
// src/core/context-nextgen/AgentContextNextGen.ts
|
|
11947
|
+
init_Logger();
|
|
11948
|
+
|
|
11946
11949
|
// src/core/Vendor.ts
|
|
11947
11950
|
var Vendor = {
|
|
11948
11951
|
OpenAI: "openai",
|
|
@@ -13316,6 +13319,7 @@ var ContentType = /* @__PURE__ */ ((ContentType2) => {
|
|
|
13316
13319
|
ContentType2["OUTPUT_TEXT"] = "output_text";
|
|
13317
13320
|
ContentType2["TOOL_USE"] = "tool_use";
|
|
13318
13321
|
ContentType2["TOOL_RESULT"] = "tool_result";
|
|
13322
|
+
ContentType2["THINKING"] = "thinking";
|
|
13319
13323
|
return ContentType2;
|
|
13320
13324
|
})(ContentType || {});
|
|
13321
13325
|
|
|
@@ -13578,6 +13582,11 @@ var BasePluginNextGen = class {
|
|
|
13578
13582
|
}
|
|
13579
13583
|
};
|
|
13580
13584
|
|
|
13585
|
+
// src/core/context-nextgen/snapshot.ts
|
|
13586
|
+
function formatPluginDisplayName(name) {
|
|
13587
|
+
return name.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
13588
|
+
}
|
|
13589
|
+
|
|
13581
13590
|
// src/core/context-nextgen/AgentContextNextGen.ts
|
|
13582
13591
|
init_Connector();
|
|
13583
13592
|
|
|
@@ -14505,7 +14514,7 @@ var PRIORITY_VALUES = {
|
|
|
14505
14514
|
};
|
|
14506
14515
|
var DEFAULT_CONFIG = {
|
|
14507
14516
|
maxEntries: 20,
|
|
14508
|
-
maxTotalTokens:
|
|
14517
|
+
maxTotalTokens: 4e4,
|
|
14509
14518
|
defaultPriority: "normal",
|
|
14510
14519
|
showTimestamps: false
|
|
14511
14520
|
};
|
|
@@ -16256,8 +16265,11 @@ var AlgorithmicCompactionStrategy = class {
|
|
|
16256
16265
|
* Emergency compaction when context exceeds threshold.
|
|
16257
16266
|
*
|
|
16258
16267
|
* Strategy:
|
|
16259
|
-
* 1. Run consolidate() first to move tool results to memory
|
|
16268
|
+
* 1. Run consolidate() first to move tool results to memory (if working memory available)
|
|
16260
16269
|
* 2. If still need space, apply rolling window (remove oldest messages)
|
|
16270
|
+
*
|
|
16271
|
+
* Gracefully degrades: if working memory plugin is not registered,
|
|
16272
|
+
* skips step 1 and only uses rolling window compaction.
|
|
16261
16273
|
*/
|
|
16262
16274
|
async compact(context, targetToFree) {
|
|
16263
16275
|
const log = [];
|
|
@@ -16270,7 +16282,7 @@ var AlgorithmicCompactionStrategy = class {
|
|
|
16270
16282
|
tokensFreed += Math.abs(consolidateResult.tokensChanged);
|
|
16271
16283
|
log.push(...consolidateResult.actions);
|
|
16272
16284
|
}
|
|
16273
|
-
|
|
16285
|
+
const remaining = targetToFree - tokensFreed;
|
|
16274
16286
|
if (remaining > 0 && context.conversation.length > 0) {
|
|
16275
16287
|
log.push(`Rolling window: need to free ~${remaining} more tokens`);
|
|
16276
16288
|
const result = await this.applyRollingWindow(context, remaining, log);
|
|
@@ -16284,8 +16296,11 @@ var AlgorithmicCompactionStrategy = class {
|
|
|
16284
16296
|
* Post-cycle consolidation.
|
|
16285
16297
|
*
|
|
16286
16298
|
* 1. Find all tool pairs in conversation
|
|
16287
|
-
* 2. Move large tool results (> threshold) to Working Memory
|
|
16299
|
+
* 2. Move large tool results (> threshold) to Working Memory (if available)
|
|
16288
16300
|
* 3. Limit remaining tool pairs to maxToolPairs
|
|
16301
|
+
*
|
|
16302
|
+
* Gracefully degrades: if working memory is not available, skips step 2
|
|
16303
|
+
* and only limits tool pairs + removes excess via rolling window.
|
|
16289
16304
|
*/
|
|
16290
16305
|
async consolidate(context) {
|
|
16291
16306
|
const log = [];
|
|
@@ -16296,23 +16311,25 @@ var AlgorithmicCompactionStrategy = class {
|
|
|
16296
16311
|
return { performed: false, tokensChanged: 0, actions: [] };
|
|
16297
16312
|
}
|
|
16298
16313
|
const indicesToRemove = [];
|
|
16299
|
-
|
|
16300
|
-
|
|
16301
|
-
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16308
|
-
indicesToRemove.
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
indicesToRemove.
|
|
16314
|
+
if (memory) {
|
|
16315
|
+
for (const pair of toolPairs) {
|
|
16316
|
+
if (pair.resultSizeBytes > this.toolResultSizeThreshold) {
|
|
16317
|
+
const key = this.generateKey(pair.toolName, pair.toolUseId);
|
|
16318
|
+
const desc = this.generateDescription(pair.toolName, pair.toolArgs);
|
|
16319
|
+
await memory.store(key, desc, pair.resultContent, {
|
|
16320
|
+
tier: "raw",
|
|
16321
|
+
priority: "normal"
|
|
16322
|
+
});
|
|
16323
|
+
if (!indicesToRemove.includes(pair.toolUseIndex)) {
|
|
16324
|
+
indicesToRemove.push(pair.toolUseIndex);
|
|
16325
|
+
}
|
|
16326
|
+
if (!indicesToRemove.includes(pair.toolResultIndex)) {
|
|
16327
|
+
indicesToRemove.push(pair.toolResultIndex);
|
|
16328
|
+
}
|
|
16329
|
+
log.push(
|
|
16330
|
+
`Moved ${pair.toolName} result (${this.formatBytes(pair.resultSizeBytes)}) to memory: ${key}`
|
|
16331
|
+
);
|
|
16312
16332
|
}
|
|
16313
|
-
log.push(
|
|
16314
|
-
`Moved ${pair.toolName} result (${this.formatBytes(pair.resultSizeBytes)}) to memory: ${key}`
|
|
16315
|
-
);
|
|
16316
16333
|
}
|
|
16317
16334
|
}
|
|
16318
16335
|
const remainingPairs = toolPairs.filter(
|
|
@@ -16341,15 +16358,12 @@ var AlgorithmicCompactionStrategy = class {
|
|
|
16341
16358
|
};
|
|
16342
16359
|
}
|
|
16343
16360
|
/**
|
|
16344
|
-
* Get the Working Memory plugin from context.
|
|
16345
|
-
*
|
|
16361
|
+
* Get the Working Memory plugin from context, or null if not available.
|
|
16362
|
+
* When null, the strategy degrades gracefully (skips memory operations).
|
|
16346
16363
|
*/
|
|
16347
16364
|
getWorkingMemory(context) {
|
|
16348
16365
|
const plugin = context.plugins.find((p) => p.name === "working_memory");
|
|
16349
|
-
|
|
16350
|
-
throw new Error("AlgorithmicCompactionStrategy requires working_memory plugin");
|
|
16351
|
-
}
|
|
16352
|
-
return plugin;
|
|
16366
|
+
return plugin ? plugin : null;
|
|
16353
16367
|
}
|
|
16354
16368
|
/**
|
|
16355
16369
|
* Find all tool_use/tool_result pairs in conversation.
|
|
@@ -16690,7 +16704,7 @@ var StrategyRegistry = class {
|
|
|
16690
16704
|
// src/core/context-nextgen/types.ts
|
|
16691
16705
|
var DEFAULT_FEATURES = {
|
|
16692
16706
|
workingMemory: true,
|
|
16693
|
-
inContextMemory:
|
|
16707
|
+
inContextMemory: true,
|
|
16694
16708
|
persistentInstructions: false,
|
|
16695
16709
|
userInfo: false
|
|
16696
16710
|
};
|
|
@@ -16734,6 +16748,8 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
16734
16748
|
_storage;
|
|
16735
16749
|
/** Destroyed flag */
|
|
16736
16750
|
_destroyed = false;
|
|
16751
|
+
/** Last thinking/reasoning content from the most recent assistant response */
|
|
16752
|
+
_lastThinking = null;
|
|
16737
16753
|
/** Cached budget from last prepare() call */
|
|
16738
16754
|
_cachedBudget = null;
|
|
16739
16755
|
/** Callback for beforeCompaction hook (set by Agent) */
|
|
@@ -16821,15 +16837,16 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
16821
16837
|
}
|
|
16822
16838
|
/**
|
|
16823
16839
|
* Validate that a strategy's required plugins are registered.
|
|
16824
|
-
*
|
|
16840
|
+
* Logs a warning if required plugins are missing — the strategy should degrade gracefully.
|
|
16825
16841
|
*/
|
|
16826
16842
|
validateStrategyDependencies(strategy) {
|
|
16827
16843
|
if (!strategy.requiredPlugins?.length) return;
|
|
16828
16844
|
const availablePlugins = new Set(this._plugins.keys());
|
|
16829
16845
|
const missing = strategy.requiredPlugins.filter((name) => !availablePlugins.has(name));
|
|
16830
16846
|
if (missing.length > 0) {
|
|
16831
|
-
|
|
16832
|
-
|
|
16847
|
+
exports.logger.warn(
|
|
16848
|
+
{ strategy: strategy.name, missing, available: Array.from(availablePlugins) },
|
|
16849
|
+
`Strategy '${strategy.name}' recommends plugins that are not registered: ${missing.join(", ")}. Strategy will degrade gracefully.`
|
|
16833
16850
|
);
|
|
16834
16851
|
}
|
|
16835
16852
|
}
|
|
@@ -16945,6 +16962,13 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
16945
16962
|
get storage() {
|
|
16946
16963
|
return this._storage ?? null;
|
|
16947
16964
|
}
|
|
16965
|
+
/**
|
|
16966
|
+
* Get the last thinking/reasoning content from the most recent assistant response.
|
|
16967
|
+
* Updated on every assistant response, always available regardless of persistence setting.
|
|
16968
|
+
*/
|
|
16969
|
+
get lastThinking() {
|
|
16970
|
+
return this._lastThinking;
|
|
16971
|
+
}
|
|
16948
16972
|
/** Get max context tokens */
|
|
16949
16973
|
get maxContextTokens() {
|
|
16950
16974
|
return this._maxContextTokens;
|
|
@@ -17126,6 +17150,7 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
17126
17150
|
}
|
|
17127
17151
|
const id = this.generateId();
|
|
17128
17152
|
const contentArray = [];
|
|
17153
|
+
let thinkingText = null;
|
|
17129
17154
|
for (const item of output) {
|
|
17130
17155
|
if (item.type === "message" && "content" in item) {
|
|
17131
17156
|
const msg = item;
|
|
@@ -17137,12 +17162,19 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
17137
17162
|
});
|
|
17138
17163
|
} else if (c.type === "tool_use" /* TOOL_USE */) {
|
|
17139
17164
|
contentArray.push(c);
|
|
17165
|
+
} else if (c.type === "thinking" /* THINKING */) {
|
|
17166
|
+
const thinking = c;
|
|
17167
|
+
thinkingText = thinking.thinking;
|
|
17168
|
+
if (thinking.persistInHistory) {
|
|
17169
|
+
contentArray.push(c);
|
|
17170
|
+
}
|
|
17140
17171
|
}
|
|
17141
17172
|
}
|
|
17142
17173
|
} else if (item.type === "compaction" || item.type === "reasoning") {
|
|
17143
17174
|
continue;
|
|
17144
17175
|
}
|
|
17145
17176
|
}
|
|
17177
|
+
this._lastThinking = thinkingText;
|
|
17146
17178
|
if (contentArray.length > 0) {
|
|
17147
17179
|
const message = {
|
|
17148
17180
|
type: "message",
|
|
@@ -17241,6 +17273,7 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
17241
17273
|
*/
|
|
17242
17274
|
async prepare() {
|
|
17243
17275
|
this.assertNotDestroyed();
|
|
17276
|
+
this._lastThinking = null;
|
|
17244
17277
|
const compactionLog = [];
|
|
17245
17278
|
const toolsTokens = this.calculateToolsTokens();
|
|
17246
17279
|
const availableForContent = this._maxContextTokens - this._config.responseReserve - toolsTokens;
|
|
@@ -17453,6 +17486,8 @@ ${content}`);
|
|
|
17453
17486
|
total += this._estimateImageTokens();
|
|
17454
17487
|
}
|
|
17455
17488
|
}
|
|
17489
|
+
} else if (c.type === "thinking" /* THINKING */) {
|
|
17490
|
+
total += this._estimator.estimateTokens(c.thinking || "");
|
|
17456
17491
|
} else if (c.type === "input_image_url" /* INPUT_IMAGE_URL */) {
|
|
17457
17492
|
const imgContent = c;
|
|
17458
17493
|
const detail = imgContent.image_url?.detail;
|
|
@@ -17950,6 +17985,188 @@ ${content}`);
|
|
|
17950
17985
|
get strategy() {
|
|
17951
17986
|
return this._compactionStrategy.name;
|
|
17952
17987
|
}
|
|
17988
|
+
/**
|
|
17989
|
+
* Get a complete, serializable snapshot of the context state.
|
|
17990
|
+
*
|
|
17991
|
+
* Returns all data needed by UI "Look Inside" panels without reaching
|
|
17992
|
+
* into plugin internals. Plugin data is auto-discovered from the plugin
|
|
17993
|
+
* registry — new/custom plugins appear automatically.
|
|
17994
|
+
*
|
|
17995
|
+
* @param toolStats - Optional tool usage stats (from ToolManager.getStats())
|
|
17996
|
+
* @returns Serializable context snapshot
|
|
17997
|
+
*/
|
|
17998
|
+
async getSnapshot(toolStats) {
|
|
17999
|
+
const resolveContents = async (raw) => {
|
|
18000
|
+
const resolved = raw instanceof Promise ? await raw : raw;
|
|
18001
|
+
if (resolved instanceof Map) return Array.from(resolved.values());
|
|
18002
|
+
return resolved;
|
|
18003
|
+
};
|
|
18004
|
+
if (this._destroyed) {
|
|
18005
|
+
const emptyBudget = this._cachedBudget ?? {
|
|
18006
|
+
maxTokens: this._maxContextTokens,
|
|
18007
|
+
responseReserve: this._config.responseReserve,
|
|
18008
|
+
systemMessageTokens: 0,
|
|
18009
|
+
toolsTokens: 0,
|
|
18010
|
+
conversationTokens: 0,
|
|
18011
|
+
currentInputTokens: 0,
|
|
18012
|
+
totalUsed: 0,
|
|
18013
|
+
available: this._maxContextTokens - this._config.responseReserve,
|
|
18014
|
+
utilizationPercent: 0,
|
|
18015
|
+
breakdown: {
|
|
18016
|
+
systemPrompt: 0,
|
|
18017
|
+
persistentInstructions: 0,
|
|
18018
|
+
pluginInstructions: 0,
|
|
18019
|
+
pluginContents: {},
|
|
18020
|
+
tools: 0,
|
|
18021
|
+
conversation: 0,
|
|
18022
|
+
currentInput: 0
|
|
18023
|
+
}
|
|
18024
|
+
};
|
|
18025
|
+
return {
|
|
18026
|
+
available: false,
|
|
18027
|
+
agentId: this._agentId,
|
|
18028
|
+
model: this._config.model,
|
|
18029
|
+
features: this._config.features,
|
|
18030
|
+
budget: emptyBudget,
|
|
18031
|
+
strategy: this._compactionStrategy.name,
|
|
18032
|
+
messagesCount: 0,
|
|
18033
|
+
toolCallsCount: 0,
|
|
18034
|
+
systemPrompt: null,
|
|
18035
|
+
plugins: [],
|
|
18036
|
+
tools: []
|
|
18037
|
+
};
|
|
18038
|
+
}
|
|
18039
|
+
const budget = await this.calculateBudget();
|
|
18040
|
+
const plugins = [];
|
|
18041
|
+
for (const plugin of this._plugins.values()) {
|
|
18042
|
+
let formattedContent = null;
|
|
18043
|
+
try {
|
|
18044
|
+
formattedContent = await plugin.getContent();
|
|
18045
|
+
} catch {
|
|
18046
|
+
}
|
|
18047
|
+
plugins.push({
|
|
18048
|
+
name: plugin.name,
|
|
18049
|
+
displayName: formatPluginDisplayName(plugin.name),
|
|
18050
|
+
enabled: true,
|
|
18051
|
+
tokenSize: plugin.getTokenSize(),
|
|
18052
|
+
instructionsTokenSize: plugin.getInstructionsTokenSize(),
|
|
18053
|
+
compactable: plugin.isCompactable(),
|
|
18054
|
+
contents: await resolveContents(plugin.getContents()),
|
|
18055
|
+
formattedContent
|
|
18056
|
+
});
|
|
18057
|
+
}
|
|
18058
|
+
const usageCounts = /* @__PURE__ */ new Map();
|
|
18059
|
+
if (toolStats?.mostUsed) {
|
|
18060
|
+
for (const { name, count } of toolStats.mostUsed) {
|
|
18061
|
+
usageCounts.set(name, count);
|
|
18062
|
+
}
|
|
18063
|
+
}
|
|
18064
|
+
const tools = [];
|
|
18065
|
+
for (const toolName of this._tools.list()) {
|
|
18066
|
+
const reg = this._tools.getRegistration(toolName);
|
|
18067
|
+
if (!reg) continue;
|
|
18068
|
+
tools.push({
|
|
18069
|
+
name: toolName,
|
|
18070
|
+
description: reg.tool.definition.function.description || "",
|
|
18071
|
+
enabled: reg.enabled,
|
|
18072
|
+
callCount: reg.metadata.usageCount ?? usageCounts.get(toolName) ?? 0,
|
|
18073
|
+
namespace: reg.namespace || void 0
|
|
18074
|
+
});
|
|
18075
|
+
}
|
|
18076
|
+
let toolCallsCount = 0;
|
|
18077
|
+
for (const item of this._conversation) {
|
|
18078
|
+
if (item.type === "message" && item.role === "assistant" /* ASSISTANT */) {
|
|
18079
|
+
for (const c of item.content) {
|
|
18080
|
+
if (c.type === "tool_use" /* TOOL_USE */) toolCallsCount++;
|
|
18081
|
+
}
|
|
18082
|
+
}
|
|
18083
|
+
}
|
|
18084
|
+
return {
|
|
18085
|
+
available: true,
|
|
18086
|
+
agentId: this._agentId,
|
|
18087
|
+
model: this._config.model,
|
|
18088
|
+
features: this._config.features,
|
|
18089
|
+
budget,
|
|
18090
|
+
strategy: this._compactionStrategy.name,
|
|
18091
|
+
messagesCount: this._conversation.length,
|
|
18092
|
+
toolCallsCount,
|
|
18093
|
+
systemPrompt: this._systemPrompt ?? null,
|
|
18094
|
+
plugins,
|
|
18095
|
+
tools
|
|
18096
|
+
};
|
|
18097
|
+
}
|
|
18098
|
+
/**
|
|
18099
|
+
* Get a human-readable breakdown of the prepared context.
|
|
18100
|
+
*
|
|
18101
|
+
* Calls `prepare()` internally, then maps each InputItem to a named
|
|
18102
|
+
* component with content text and token estimate. Used by "View Full Context" UIs.
|
|
18103
|
+
*
|
|
18104
|
+
* @returns View context data with components and raw text for "Copy All"
|
|
18105
|
+
*/
|
|
18106
|
+
async getViewContext() {
|
|
18107
|
+
if (this._destroyed) {
|
|
18108
|
+
return { available: false, components: [], totalTokens: 0, rawContext: "" };
|
|
18109
|
+
}
|
|
18110
|
+
const { input, budget } = await this.prepare();
|
|
18111
|
+
const components = [];
|
|
18112
|
+
let rawParts = [];
|
|
18113
|
+
for (const item of input) {
|
|
18114
|
+
if (item.type === "compaction") {
|
|
18115
|
+
components.push({
|
|
18116
|
+
name: "Compaction Block",
|
|
18117
|
+
content: "[Compacted content]",
|
|
18118
|
+
tokenEstimate: 0
|
|
18119
|
+
});
|
|
18120
|
+
continue;
|
|
18121
|
+
}
|
|
18122
|
+
const msg = item;
|
|
18123
|
+
const roleName = msg.role === "developer" /* DEVELOPER */ ? "System Message" : msg.role === "user" /* USER */ ? "User Message" : "Assistant Message";
|
|
18124
|
+
for (const block of msg.content) {
|
|
18125
|
+
let name = roleName;
|
|
18126
|
+
let text = "";
|
|
18127
|
+
switch (block.type) {
|
|
18128
|
+
case "input_text" /* INPUT_TEXT */:
|
|
18129
|
+
text = block.text;
|
|
18130
|
+
break;
|
|
18131
|
+
case "output_text" /* OUTPUT_TEXT */:
|
|
18132
|
+
text = block.text;
|
|
18133
|
+
break;
|
|
18134
|
+
case "tool_use" /* TOOL_USE */:
|
|
18135
|
+
name = `Tool Call: ${block.name}`;
|
|
18136
|
+
text = `${block.name}(${block.arguments})`;
|
|
18137
|
+
break;
|
|
18138
|
+
case "tool_result" /* TOOL_RESULT */:
|
|
18139
|
+
name = `Tool Result: ${block.tool_use_id}`;
|
|
18140
|
+
text = typeof block.content === "string" ? block.content : JSON.stringify(block.content, null, 2);
|
|
18141
|
+
if (block.error) text = `[Error] ${block.error}
|
|
18142
|
+
${text}`;
|
|
18143
|
+
break;
|
|
18144
|
+
case "input_image_url" /* INPUT_IMAGE_URL */:
|
|
18145
|
+
name = "Image Input";
|
|
18146
|
+
text = `[Image: ${block.image_url.url.substring(0, 100)}...]`;
|
|
18147
|
+
break;
|
|
18148
|
+
case "input_file" /* INPUT_FILE */:
|
|
18149
|
+
name = "File Input";
|
|
18150
|
+
text = `[File: ${block.file_id}]`;
|
|
18151
|
+
break;
|
|
18152
|
+
case "thinking" /* THINKING */:
|
|
18153
|
+
name = "Thinking";
|
|
18154
|
+
text = block.thinking || "";
|
|
18155
|
+
break;
|
|
18156
|
+
}
|
|
18157
|
+
const tokenEstimate = this._estimator.estimateTokens(text);
|
|
18158
|
+
components.push({ name, content: text, tokenEstimate });
|
|
18159
|
+
rawParts.push(`--- ${name} ---
|
|
18160
|
+
${text}`);
|
|
18161
|
+
}
|
|
18162
|
+
}
|
|
18163
|
+
return {
|
|
18164
|
+
available: true,
|
|
18165
|
+
components,
|
|
18166
|
+
totalTokens: budget.totalUsed,
|
|
18167
|
+
rawContext: rawParts.join("\n\n")
|
|
18168
|
+
};
|
|
18169
|
+
}
|
|
17953
18170
|
// ============================================================================
|
|
17954
18171
|
// Utilities
|
|
17955
18172
|
// ============================================================================
|
|
@@ -18208,6 +18425,13 @@ var BaseTextProvider = class extends BaseProvider {
|
|
|
18208
18425
|
}
|
|
18209
18426
|
return textParts.join("\n");
|
|
18210
18427
|
}
|
|
18428
|
+
/**
|
|
18429
|
+
* List available models from the provider's API.
|
|
18430
|
+
* Default returns empty array; providers override when they have SDK support.
|
|
18431
|
+
*/
|
|
18432
|
+
async listModels() {
|
|
18433
|
+
return [];
|
|
18434
|
+
}
|
|
18211
18435
|
/**
|
|
18212
18436
|
* Clean up provider resources (circuit breaker listeners, etc.)
|
|
18213
18437
|
* Should be called when the provider is no longer needed.
|
|
@@ -18360,12 +18584,21 @@ var OpenAIResponsesConverter = class {
|
|
|
18360
18584
|
} else if (item.type === "reasoning") {
|
|
18361
18585
|
const reasoning = item;
|
|
18362
18586
|
if (reasoning.summary) {
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
}
|
|
18587
|
+
let summaryText;
|
|
18588
|
+
if (typeof reasoning.summary === "string") {
|
|
18589
|
+
summaryText = reasoning.summary;
|
|
18590
|
+
} else if (Array.isArray(reasoning.summary)) {
|
|
18591
|
+
summaryText = reasoning.summary.map((s) => s.text || "").filter(Boolean).join("\n");
|
|
18592
|
+
} else {
|
|
18593
|
+
summaryText = "";
|
|
18594
|
+
}
|
|
18595
|
+
if (summaryText) {
|
|
18596
|
+
content.push({
|
|
18597
|
+
type: "thinking" /* THINKING */,
|
|
18598
|
+
thinking: summaryText,
|
|
18599
|
+
persistInHistory: false
|
|
18600
|
+
});
|
|
18601
|
+
}
|
|
18369
18602
|
}
|
|
18370
18603
|
}
|
|
18371
18604
|
}
|
|
@@ -18388,10 +18621,20 @@ var OpenAIResponsesConverter = class {
|
|
|
18388
18621
|
}
|
|
18389
18622
|
],
|
|
18390
18623
|
output_text: outputText,
|
|
18624
|
+
// Extract thinking text from content for convenience field
|
|
18625
|
+
...(() => {
|
|
18626
|
+
const thinkingTexts = content.filter((c) => c.type === "thinking" /* THINKING */).map((c) => c.thinking).filter(Boolean);
|
|
18627
|
+
return thinkingTexts.length > 0 ? { thinking: thinkingTexts.join("\n") } : {};
|
|
18628
|
+
})(),
|
|
18391
18629
|
usage: {
|
|
18392
18630
|
input_tokens: response.usage?.input_tokens || 0,
|
|
18393
18631
|
output_tokens: response.usage?.output_tokens || 0,
|
|
18394
|
-
total_tokens: response.usage?.total_tokens || 0
|
|
18632
|
+
total_tokens: response.usage?.total_tokens || 0,
|
|
18633
|
+
...response.usage?.output_tokens_details?.reasoning_tokens != null && {
|
|
18634
|
+
output_tokens_details: {
|
|
18635
|
+
reasoning_tokens: response.usage.output_tokens_details.reasoning_tokens
|
|
18636
|
+
}
|
|
18637
|
+
}
|
|
18395
18638
|
}
|
|
18396
18639
|
};
|
|
18397
18640
|
}
|
|
@@ -18496,6 +18739,8 @@ var StreamEventType = /* @__PURE__ */ ((StreamEventType2) => {
|
|
|
18496
18739
|
StreamEventType2["TOOL_EXECUTION_START"] = "response.tool_execution.start";
|
|
18497
18740
|
StreamEventType2["TOOL_EXECUTION_DONE"] = "response.tool_execution.done";
|
|
18498
18741
|
StreamEventType2["ITERATION_COMPLETE"] = "response.iteration.complete";
|
|
18742
|
+
StreamEventType2["REASONING_DELTA"] = "response.reasoning.delta";
|
|
18743
|
+
StreamEventType2["REASONING_DONE"] = "response.reasoning.done";
|
|
18499
18744
|
StreamEventType2["RESPONSE_COMPLETE"] = "response.complete";
|
|
18500
18745
|
StreamEventType2["ERROR"] = "response.error";
|
|
18501
18746
|
return StreamEventType2;
|
|
@@ -18515,6 +18760,12 @@ function isToolCallArgumentsDelta(event) {
|
|
|
18515
18760
|
function isToolCallArgumentsDone(event) {
|
|
18516
18761
|
return event.type === "response.tool_call_arguments.done" /* TOOL_CALL_ARGUMENTS_DONE */;
|
|
18517
18762
|
}
|
|
18763
|
+
function isReasoningDelta(event) {
|
|
18764
|
+
return event.type === "response.reasoning.delta" /* REASONING_DELTA */;
|
|
18765
|
+
}
|
|
18766
|
+
function isReasoningDone(event) {
|
|
18767
|
+
return event.type === "response.reasoning.done" /* REASONING_DONE */;
|
|
18768
|
+
}
|
|
18518
18769
|
function isResponseComplete(event) {
|
|
18519
18770
|
return event.type === "response.complete" /* RESPONSE_COMPLETE */;
|
|
18520
18771
|
}
|
|
@@ -18532,6 +18783,8 @@ var OpenAIResponsesStreamConverter = class {
|
|
|
18532
18783
|
let sequenceNumber = 0;
|
|
18533
18784
|
const activeItems = /* @__PURE__ */ new Map();
|
|
18534
18785
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
18786
|
+
const reasoningBuffers = /* @__PURE__ */ new Map();
|
|
18787
|
+
const reasoningDoneEmitted = /* @__PURE__ */ new Set();
|
|
18535
18788
|
for await (const event of stream) {
|
|
18536
18789
|
if (process.env.DEBUG_OPENAI) {
|
|
18537
18790
|
console.error("[DEBUG] Responses API event:", event.type);
|
|
@@ -18553,6 +18806,12 @@ var OpenAIResponsesStreamConverter = class {
|
|
|
18553
18806
|
activeItems.set(addedEvent.output_index.toString(), {
|
|
18554
18807
|
type: item.type
|
|
18555
18808
|
});
|
|
18809
|
+
if (item.type === "reasoning") {
|
|
18810
|
+
activeItems.set(addedEvent.output_index.toString(), {
|
|
18811
|
+
type: "reasoning"
|
|
18812
|
+
});
|
|
18813
|
+
reasoningBuffers.set(addedEvent.output_index.toString(), []);
|
|
18814
|
+
}
|
|
18556
18815
|
if (item.type === "function_call") {
|
|
18557
18816
|
const functionCall = item;
|
|
18558
18817
|
const toolCallId = functionCall.call_id;
|
|
@@ -18610,9 +18869,53 @@ var OpenAIResponsesStreamConverter = class {
|
|
|
18610
18869
|
}
|
|
18611
18870
|
break;
|
|
18612
18871
|
}
|
|
18872
|
+
case "response.reasoning_summary_text.delta":
|
|
18873
|
+
case "response.reasoning_text.delta": {
|
|
18874
|
+
const reasoningEvent = event;
|
|
18875
|
+
const outputIdx = reasoningEvent.output_index?.toString();
|
|
18876
|
+
const buffer = outputIdx ? reasoningBuffers.get(outputIdx) : void 0;
|
|
18877
|
+
if (buffer) {
|
|
18878
|
+
buffer.push(reasoningEvent.delta || "");
|
|
18879
|
+
}
|
|
18880
|
+
yield {
|
|
18881
|
+
type: "response.reasoning.delta" /* REASONING_DELTA */,
|
|
18882
|
+
response_id: responseId,
|
|
18883
|
+
item_id: reasoningEvent.item_id || `reasoning_${responseId}`,
|
|
18884
|
+
delta: reasoningEvent.delta || "",
|
|
18885
|
+
sequence_number: sequenceNumber++
|
|
18886
|
+
};
|
|
18887
|
+
break;
|
|
18888
|
+
}
|
|
18889
|
+
case "response.reasoning_text.done": {
|
|
18890
|
+
const doneEvent = event;
|
|
18891
|
+
const outputIdx = doneEvent.output_index.toString();
|
|
18892
|
+
const rBuf = reasoningBuffers.get(outputIdx);
|
|
18893
|
+
const thinkingText = rBuf ? rBuf.join("") : doneEvent.text || "";
|
|
18894
|
+
reasoningDoneEmitted.add(outputIdx);
|
|
18895
|
+
yield {
|
|
18896
|
+
type: "response.reasoning.done" /* REASONING_DONE */,
|
|
18897
|
+
response_id: responseId,
|
|
18898
|
+
item_id: doneEvent.item_id || `reasoning_${responseId}`,
|
|
18899
|
+
thinking: thinkingText
|
|
18900
|
+
};
|
|
18901
|
+
break;
|
|
18902
|
+
}
|
|
18613
18903
|
case "response.output_item.done": {
|
|
18614
18904
|
const doneEvent = event;
|
|
18615
18905
|
const item = doneEvent.item;
|
|
18906
|
+
if (item.type === "reasoning") {
|
|
18907
|
+
const outputIdx = doneEvent.output_index.toString();
|
|
18908
|
+
if (!reasoningDoneEmitted.has(outputIdx)) {
|
|
18909
|
+
const rBuf = reasoningBuffers.get(outputIdx);
|
|
18910
|
+
const thinkingText = rBuf ? rBuf.join("") : "";
|
|
18911
|
+
yield {
|
|
18912
|
+
type: "response.reasoning.done" /* REASONING_DONE */,
|
|
18913
|
+
response_id: responseId,
|
|
18914
|
+
item_id: item.id || `reasoning_${responseId}`,
|
|
18915
|
+
thinking: thinkingText
|
|
18916
|
+
};
|
|
18917
|
+
}
|
|
18918
|
+
}
|
|
18616
18919
|
if (item.type === "function_call") {
|
|
18617
18920
|
const functionCall = item;
|
|
18618
18921
|
const buffer = toolCallBuffers.get(functionCall.call_id);
|
|
@@ -18644,7 +18947,12 @@ var OpenAIResponsesStreamConverter = class {
|
|
|
18644
18947
|
usage: {
|
|
18645
18948
|
input_tokens: response.usage?.input_tokens || 0,
|
|
18646
18949
|
output_tokens: response.usage?.output_tokens || 0,
|
|
18647
|
-
total_tokens: response.usage?.total_tokens || 0
|
|
18950
|
+
total_tokens: response.usage?.total_tokens || 0,
|
|
18951
|
+
...response.usage?.output_tokens_details?.reasoning_tokens != null && {
|
|
18952
|
+
output_tokens_details: {
|
|
18953
|
+
reasoning_tokens: response.usage.output_tokens_details.reasoning_tokens
|
|
18954
|
+
}
|
|
18955
|
+
}
|
|
18648
18956
|
},
|
|
18649
18957
|
iterations: 1
|
|
18650
18958
|
};
|
|
@@ -18685,6 +18993,26 @@ function resolveMaxContextTokens(model, fallback) {
|
|
|
18685
18993
|
return info ? info.features.input.tokens : fallback;
|
|
18686
18994
|
}
|
|
18687
18995
|
|
|
18996
|
+
// src/infrastructure/providers/shared/validateThinkingConfig.ts
|
|
18997
|
+
function validateThinkingConfig(thinking) {
|
|
18998
|
+
if (!thinking.enabled) return;
|
|
18999
|
+
if (thinking.budgetTokens !== void 0) {
|
|
19000
|
+
if (typeof thinking.budgetTokens !== "number" || thinking.budgetTokens < 1) {
|
|
19001
|
+
throw new Error(
|
|
19002
|
+
`Invalid thinking budgetTokens: ${thinking.budgetTokens}. Must be a positive number.`
|
|
19003
|
+
);
|
|
19004
|
+
}
|
|
19005
|
+
}
|
|
19006
|
+
if (thinking.effort !== void 0) {
|
|
19007
|
+
const validEfforts = ["low", "medium", "high"];
|
|
19008
|
+
if (!validEfforts.includes(thinking.effort)) {
|
|
19009
|
+
throw new Error(
|
|
19010
|
+
`Invalid thinking effort: '${thinking.effort}'. Must be one of: ${validEfforts.join(", ")}`
|
|
19011
|
+
);
|
|
19012
|
+
}
|
|
19013
|
+
}
|
|
19014
|
+
}
|
|
19015
|
+
|
|
18688
19016
|
// src/infrastructure/providers/openai/OpenAITextProvider.ts
|
|
18689
19017
|
var OpenAITextProvider = class extends BaseTextProvider {
|
|
18690
19018
|
name = "openai";
|
|
@@ -18752,6 +19080,7 @@ var OpenAITextProvider = class extends BaseTextProvider {
|
|
|
18752
19080
|
},
|
|
18753
19081
|
...options.metadata && { metadata: options.metadata }
|
|
18754
19082
|
};
|
|
19083
|
+
this.applyReasoningConfig(params, options);
|
|
18755
19084
|
const response = await this.client.responses.create(params);
|
|
18756
19085
|
return this.converter.convertResponse(response);
|
|
18757
19086
|
} catch (error) {
|
|
@@ -18793,6 +19122,7 @@ var OpenAITextProvider = class extends BaseTextProvider {
|
|
|
18793
19122
|
...options.metadata && { metadata: options.metadata },
|
|
18794
19123
|
stream: true
|
|
18795
19124
|
};
|
|
19125
|
+
this.applyReasoningConfig(params, options);
|
|
18796
19126
|
const stream = await this.client.responses.create(params);
|
|
18797
19127
|
yield* this.streamConverter.convertStream(stream);
|
|
18798
19128
|
} catch (error) {
|
|
@@ -18814,6 +19144,27 @@ var OpenAITextProvider = class extends BaseTextProvider {
|
|
|
18814
19144
|
maxOutputTokens: 16384
|
|
18815
19145
|
});
|
|
18816
19146
|
}
|
|
19147
|
+
/**
|
|
19148
|
+
* List available models from the OpenAI API
|
|
19149
|
+
*/
|
|
19150
|
+
async listModels() {
|
|
19151
|
+
const models = [];
|
|
19152
|
+
for await (const model of this.client.models.list()) {
|
|
19153
|
+
models.push(model.id);
|
|
19154
|
+
}
|
|
19155
|
+
return models.sort();
|
|
19156
|
+
}
|
|
19157
|
+
/**
|
|
19158
|
+
* Apply reasoning config from unified thinking option to request params
|
|
19159
|
+
*/
|
|
19160
|
+
applyReasoningConfig(params, options) {
|
|
19161
|
+
if (options.thinking?.enabled) {
|
|
19162
|
+
validateThinkingConfig(options.thinking);
|
|
19163
|
+
params.reasoning = {
|
|
19164
|
+
effort: options.thinking.effort || "medium"
|
|
19165
|
+
};
|
|
19166
|
+
}
|
|
19167
|
+
}
|
|
18817
19168
|
/**
|
|
18818
19169
|
* Handle OpenAI-specific errors
|
|
18819
19170
|
*/
|
|
@@ -18856,6 +19207,7 @@ function buildLLMResponse(options) {
|
|
|
18856
19207
|
}
|
|
18857
19208
|
];
|
|
18858
19209
|
const outputText = extractTextFromContent(content);
|
|
19210
|
+
const thinking = extractThinkingFromContent(content);
|
|
18859
19211
|
return {
|
|
18860
19212
|
id: responseId,
|
|
18861
19213
|
object: "response",
|
|
@@ -18864,6 +19216,7 @@ function buildLLMResponse(options) {
|
|
|
18864
19216
|
model,
|
|
18865
19217
|
output,
|
|
18866
19218
|
output_text: outputText,
|
|
19219
|
+
...thinking && { thinking },
|
|
18867
19220
|
usage: {
|
|
18868
19221
|
input_tokens: usage.inputTokens,
|
|
18869
19222
|
output_tokens: usage.outputTokens,
|
|
@@ -18876,6 +19229,10 @@ function extractTextFromContent(content) {
|
|
|
18876
19229
|
(c) => c.type === "output_text" /* OUTPUT_TEXT */
|
|
18877
19230
|
).map((c) => c.text).join("\n");
|
|
18878
19231
|
}
|
|
19232
|
+
function extractThinkingFromContent(content) {
|
|
19233
|
+
const thinkingTexts = content.filter((c) => c.type === "thinking" /* THINKING */).map((c) => c.thinking).filter(Boolean);
|
|
19234
|
+
return thinkingTexts.length > 0 ? thinkingTexts.join("\n") : void 0;
|
|
19235
|
+
}
|
|
18879
19236
|
function createTextContent(text) {
|
|
18880
19237
|
return {
|
|
18881
19238
|
type: "output_text" /* OUTPUT_TEXT */,
|
|
@@ -19125,7 +19482,15 @@ var AnthropicConverter = class extends BaseConverter {
|
|
|
19125
19482
|
if (tools && tools.length > 0) {
|
|
19126
19483
|
params.tools = tools;
|
|
19127
19484
|
}
|
|
19128
|
-
if (options.
|
|
19485
|
+
if (options.thinking?.enabled) {
|
|
19486
|
+
validateThinkingConfig(options.thinking);
|
|
19487
|
+
const budgetTokens = options.thinking.budgetTokens || 1e4;
|
|
19488
|
+
params.thinking = {
|
|
19489
|
+
type: "enabled",
|
|
19490
|
+
budget_tokens: budgetTokens
|
|
19491
|
+
};
|
|
19492
|
+
params.temperature = 1;
|
|
19493
|
+
} else if (options.temperature !== void 0) {
|
|
19129
19494
|
params.temperature = options.temperature;
|
|
19130
19495
|
}
|
|
19131
19496
|
return params;
|
|
@@ -19171,6 +19536,14 @@ var AnthropicConverter = class extends BaseConverter {
|
|
|
19171
19536
|
content.push(this.createText(block.text));
|
|
19172
19537
|
} else if (block.type === "tool_use") {
|
|
19173
19538
|
content.push(this.createToolUse(block.id, block.name, block.input));
|
|
19539
|
+
} else if (block.type === "thinking") {
|
|
19540
|
+
const thinkingBlock = block;
|
|
19541
|
+
content.push({
|
|
19542
|
+
type: "thinking" /* THINKING */,
|
|
19543
|
+
thinking: thinkingBlock.thinking || "",
|
|
19544
|
+
signature: thinkingBlock.signature,
|
|
19545
|
+
persistInHistory: true
|
|
19546
|
+
});
|
|
19174
19547
|
}
|
|
19175
19548
|
}
|
|
19176
19549
|
return content;
|
|
@@ -19249,6 +19622,17 @@ var AnthropicConverter = class extends BaseConverter {
|
|
|
19249
19622
|
});
|
|
19250
19623
|
break;
|
|
19251
19624
|
}
|
|
19625
|
+
case "thinking" /* THINKING */: {
|
|
19626
|
+
const thinkingContent = c;
|
|
19627
|
+
if (thinkingContent.signature) {
|
|
19628
|
+
blocks.push({
|
|
19629
|
+
type: "thinking",
|
|
19630
|
+
thinking: thinkingContent.thinking,
|
|
19631
|
+
signature: thinkingContent.signature
|
|
19632
|
+
});
|
|
19633
|
+
}
|
|
19634
|
+
break;
|
|
19635
|
+
}
|
|
19252
19636
|
}
|
|
19253
19637
|
}
|
|
19254
19638
|
if (blocks.length === 1 && blocks[0]?.type === "text") {
|
|
@@ -19381,6 +19765,8 @@ var BaseStreamConverter = class {
|
|
|
19381
19765
|
usage = { inputTokens: 0, outputTokens: 0 };
|
|
19382
19766
|
/** Buffers for accumulating tool call arguments */
|
|
19383
19767
|
toolCallBuffers = /* @__PURE__ */ new Map();
|
|
19768
|
+
/** Buffer for accumulating reasoning/thinking content */
|
|
19769
|
+
reasoningBuffer = "";
|
|
19384
19770
|
// ==========================================================================
|
|
19385
19771
|
// Public API
|
|
19386
19772
|
// ==========================================================================
|
|
@@ -19415,6 +19801,7 @@ var BaseStreamConverter = class {
|
|
|
19415
19801
|
this.sequenceNumber = 0;
|
|
19416
19802
|
this.usage = { inputTokens: 0, outputTokens: 0 };
|
|
19417
19803
|
this.toolCallBuffers.clear();
|
|
19804
|
+
this.reasoningBuffer = "";
|
|
19418
19805
|
}
|
|
19419
19806
|
/**
|
|
19420
19807
|
* Reset converter state for a new stream
|
|
@@ -19469,6 +19856,33 @@ var BaseStreamConverter = class {
|
|
|
19469
19856
|
sequence_number: this.nextSequence()
|
|
19470
19857
|
};
|
|
19471
19858
|
}
|
|
19859
|
+
/**
|
|
19860
|
+
* Create REASONING_DELTA event and accumulate reasoning buffer
|
|
19861
|
+
*/
|
|
19862
|
+
emitReasoningDelta(delta, itemId) {
|
|
19863
|
+
this.reasoningBuffer += delta;
|
|
19864
|
+
return {
|
|
19865
|
+
type: "response.reasoning.delta" /* REASONING_DELTA */,
|
|
19866
|
+
response_id: this.responseId,
|
|
19867
|
+
item_id: itemId || `reasoning_${this.responseId}`,
|
|
19868
|
+
delta,
|
|
19869
|
+
sequence_number: this.nextSequence()
|
|
19870
|
+
};
|
|
19871
|
+
}
|
|
19872
|
+
/**
|
|
19873
|
+
* Create REASONING_DONE event with accumulated reasoning
|
|
19874
|
+
*/
|
|
19875
|
+
emitReasoningDone(itemId) {
|
|
19876
|
+
const id = itemId || `reasoning_${this.responseId}`;
|
|
19877
|
+
const thinking = this.reasoningBuffer;
|
|
19878
|
+
this.reasoningBuffer = "";
|
|
19879
|
+
return {
|
|
19880
|
+
type: "response.reasoning.done" /* REASONING_DONE */,
|
|
19881
|
+
response_id: this.responseId,
|
|
19882
|
+
item_id: id,
|
|
19883
|
+
thinking
|
|
19884
|
+
};
|
|
19885
|
+
}
|
|
19472
19886
|
/**
|
|
19473
19887
|
* Create TOOL_CALL_START event
|
|
19474
19888
|
*/
|
|
@@ -19613,7 +20027,10 @@ var AnthropicStreamConverter = class extends BaseStreamConverter {
|
|
|
19613
20027
|
handleContentBlockStart(event) {
|
|
19614
20028
|
const index = event.index;
|
|
19615
20029
|
const block = event.content_block;
|
|
19616
|
-
if (block.type === "
|
|
20030
|
+
if (block.type === "thinking") {
|
|
20031
|
+
this.contentBlockIndex.set(index, { type: "thinking" });
|
|
20032
|
+
return [];
|
|
20033
|
+
} else if (block.type === "text") {
|
|
19617
20034
|
this.contentBlockIndex.set(index, { type: "text" });
|
|
19618
20035
|
return [];
|
|
19619
20036
|
} else if (block.type === "tool_use") {
|
|
@@ -19634,7 +20051,12 @@ var AnthropicStreamConverter = class extends BaseStreamConverter {
|
|
|
19634
20051
|
const delta = event.delta;
|
|
19635
20052
|
const blockInfo = this.contentBlockIndex.get(index);
|
|
19636
20053
|
if (!blockInfo) return [];
|
|
19637
|
-
if (delta.type === "
|
|
20054
|
+
if (delta.type === "thinking_delta") {
|
|
20055
|
+
const thinkingDelta = delta;
|
|
20056
|
+
return [
|
|
20057
|
+
this.emitReasoningDelta(thinkingDelta.thinking || "", `thinking_${this.responseId}`)
|
|
20058
|
+
];
|
|
20059
|
+
} else if (delta.type === "text_delta") {
|
|
19638
20060
|
return [
|
|
19639
20061
|
this.emitTextDelta(delta.text, {
|
|
19640
20062
|
itemId: `msg_${this.responseId}`,
|
|
@@ -19654,6 +20076,9 @@ var AnthropicStreamConverter = class extends BaseStreamConverter {
|
|
|
19654
20076
|
const index = event.index;
|
|
19655
20077
|
const blockInfo = this.contentBlockIndex.get(index);
|
|
19656
20078
|
if (!blockInfo) return [];
|
|
20079
|
+
if (blockInfo.type === "thinking") {
|
|
20080
|
+
return [this.emitReasoningDone(`thinking_${this.responseId}`)];
|
|
20081
|
+
}
|
|
19657
20082
|
if (blockInfo.type === "tool_use") {
|
|
19658
20083
|
return [this.emitToolCallArgsDone(blockInfo.id || "", blockInfo.name)];
|
|
19659
20084
|
}
|
|
@@ -19752,6 +20177,16 @@ var AnthropicTextProvider = class extends BaseTextProvider {
|
|
|
19752
20177
|
caps.supportsJSONSchema = false;
|
|
19753
20178
|
return caps;
|
|
19754
20179
|
}
|
|
20180
|
+
/**
|
|
20181
|
+
* List available models from the Anthropic API
|
|
20182
|
+
*/
|
|
20183
|
+
async listModels() {
|
|
20184
|
+
const models = [];
|
|
20185
|
+
for await (const model of this.client.models.list()) {
|
|
20186
|
+
models.push(model.id);
|
|
20187
|
+
}
|
|
20188
|
+
return models.sort();
|
|
20189
|
+
}
|
|
19755
20190
|
/**
|
|
19756
20191
|
* Handle Anthropic-specific errors
|
|
19757
20192
|
*/
|
|
@@ -19930,6 +20365,11 @@ var GoogleConverter = class {
|
|
|
19930
20365
|
request.generationConfig.thinkingConfig = {
|
|
19931
20366
|
thinkingLevel: options.vendorOptions.thinkingLevel
|
|
19932
20367
|
};
|
|
20368
|
+
} else if (options.thinking?.enabled) {
|
|
20369
|
+
validateThinkingConfig(options.thinking);
|
|
20370
|
+
request.generationConfig.thinkingConfig = {
|
|
20371
|
+
thinkingBudget: options.thinking.budgetTokens || 8192
|
|
20372
|
+
};
|
|
19933
20373
|
}
|
|
19934
20374
|
if (tools && tools.length > 0) {
|
|
19935
20375
|
request.generationConfig.allowCodeExecution = false;
|
|
@@ -20145,7 +20585,13 @@ var GoogleConverter = class {
|
|
|
20145
20585
|
convertGeminiPartsToContent(parts) {
|
|
20146
20586
|
const content = [];
|
|
20147
20587
|
for (const part of parts) {
|
|
20148
|
-
if ("text" in part && part.text) {
|
|
20588
|
+
if ("thought" in part && part.thought === true && "text" in part && part.text) {
|
|
20589
|
+
content.push({
|
|
20590
|
+
type: "thinking" /* THINKING */,
|
|
20591
|
+
thinking: part.text,
|
|
20592
|
+
persistInHistory: false
|
|
20593
|
+
});
|
|
20594
|
+
} else if ("text" in part && part.text) {
|
|
20149
20595
|
content.push(createTextContent(part.text));
|
|
20150
20596
|
} else if ("functionCall" in part && part.functionCall) {
|
|
20151
20597
|
const toolId = generateToolCallId("google");
|
|
@@ -20223,6 +20669,8 @@ var GoogleStreamConverter = class {
|
|
|
20223
20669
|
isFirst = true;
|
|
20224
20670
|
toolCallBuffers = /* @__PURE__ */ new Map();
|
|
20225
20671
|
hadToolCalls = false;
|
|
20672
|
+
reasoningBuffer = "";
|
|
20673
|
+
wasThinking = false;
|
|
20226
20674
|
// External storage for thought signatures (shared with GoogleConverter)
|
|
20227
20675
|
thoughtSignatureStorage = null;
|
|
20228
20676
|
// External storage for tool call ID → name mapping (shared with GoogleConverter)
|
|
@@ -20250,6 +20698,8 @@ var GoogleStreamConverter = class {
|
|
|
20250
20698
|
this.isFirst = true;
|
|
20251
20699
|
this.toolCallBuffers.clear();
|
|
20252
20700
|
this.hadToolCalls = false;
|
|
20701
|
+
this.reasoningBuffer = "";
|
|
20702
|
+
this.wasThinking = false;
|
|
20253
20703
|
let lastUsage = {
|
|
20254
20704
|
input_tokens: 0,
|
|
20255
20705
|
output_tokens: 0,
|
|
@@ -20275,6 +20725,16 @@ var GoogleStreamConverter = class {
|
|
|
20275
20725
|
yield event;
|
|
20276
20726
|
}
|
|
20277
20727
|
}
|
|
20728
|
+
if (this.wasThinking && this.reasoningBuffer) {
|
|
20729
|
+
yield {
|
|
20730
|
+
type: "response.reasoning.done" /* REASONING_DONE */,
|
|
20731
|
+
response_id: this.responseId,
|
|
20732
|
+
item_id: `thinking_${this.responseId}`,
|
|
20733
|
+
thinking: this.reasoningBuffer
|
|
20734
|
+
};
|
|
20735
|
+
this.reasoningBuffer = "";
|
|
20736
|
+
this.wasThinking = false;
|
|
20737
|
+
}
|
|
20278
20738
|
if (this.toolCallBuffers.size > 0) {
|
|
20279
20739
|
for (const [toolCallId, buffer] of this.toolCallBuffers) {
|
|
20280
20740
|
yield {
|
|
@@ -20314,7 +20774,28 @@ var GoogleStreamConverter = class {
|
|
|
20314
20774
|
const candidate = chunk.candidates?.[0];
|
|
20315
20775
|
if (!candidate?.content?.parts) return events;
|
|
20316
20776
|
for (const part of candidate.content.parts) {
|
|
20317
|
-
|
|
20777
|
+
const isThought = "thought" in part && part.thought === true;
|
|
20778
|
+
if (isThought && part.text) {
|
|
20779
|
+
this.wasThinking = true;
|
|
20780
|
+
this.reasoningBuffer += part.text;
|
|
20781
|
+
events.push({
|
|
20782
|
+
type: "response.reasoning.delta" /* REASONING_DELTA */,
|
|
20783
|
+
response_id: this.responseId,
|
|
20784
|
+
item_id: `thinking_${this.responseId}`,
|
|
20785
|
+
delta: part.text,
|
|
20786
|
+
sequence_number: this.sequenceNumber++
|
|
20787
|
+
});
|
|
20788
|
+
} else if (part.text) {
|
|
20789
|
+
if (this.wasThinking) {
|
|
20790
|
+
this.wasThinking = false;
|
|
20791
|
+
events.push({
|
|
20792
|
+
type: "response.reasoning.done" /* REASONING_DONE */,
|
|
20793
|
+
response_id: this.responseId,
|
|
20794
|
+
item_id: `thinking_${this.responseId}`,
|
|
20795
|
+
thinking: this.reasoningBuffer
|
|
20796
|
+
});
|
|
20797
|
+
this.reasoningBuffer = "";
|
|
20798
|
+
}
|
|
20318
20799
|
events.push({
|
|
20319
20800
|
type: "response.output_text.delta" /* OUTPUT_TEXT_DELTA */,
|
|
20320
20801
|
response_id: this.responseId,
|
|
@@ -20413,6 +20894,8 @@ var GoogleStreamConverter = class {
|
|
|
20413
20894
|
this.isFirst = true;
|
|
20414
20895
|
this.toolCallBuffers.clear();
|
|
20415
20896
|
this.hadToolCalls = false;
|
|
20897
|
+
this.reasoningBuffer = "";
|
|
20898
|
+
this.wasThinking = false;
|
|
20416
20899
|
}
|
|
20417
20900
|
/**
|
|
20418
20901
|
* Reset converter state for a new stream
|
|
@@ -20542,6 +21025,18 @@ var GoogleTextProvider = class extends BaseTextProvider {
|
|
|
20542
21025
|
maxOutputTokens: 65536
|
|
20543
21026
|
});
|
|
20544
21027
|
}
|
|
21028
|
+
/**
|
|
21029
|
+
* List available models from the Google Gemini API
|
|
21030
|
+
*/
|
|
21031
|
+
async listModels() {
|
|
21032
|
+
const models = [];
|
|
21033
|
+
const pager = await this.client.models.list();
|
|
21034
|
+
for await (const model of pager) {
|
|
21035
|
+
const name = model.name?.replace(/^models\//, "") ?? "";
|
|
21036
|
+
if (name) models.push(name);
|
|
21037
|
+
}
|
|
21038
|
+
return models.sort();
|
|
21039
|
+
}
|
|
20545
21040
|
/**
|
|
20546
21041
|
* Handle Google-specific errors
|
|
20547
21042
|
*/
|
|
@@ -20649,6 +21144,18 @@ var VertexAITextProvider = class extends BaseTextProvider {
|
|
|
20649
21144
|
maxOutputTokens: 65536
|
|
20650
21145
|
});
|
|
20651
21146
|
}
|
|
21147
|
+
/**
|
|
21148
|
+
* List available models from the Vertex AI API
|
|
21149
|
+
*/
|
|
21150
|
+
async listModels() {
|
|
21151
|
+
const models = [];
|
|
21152
|
+
const pager = await this.client.models.list();
|
|
21153
|
+
for await (const model of pager) {
|
|
21154
|
+
const name = model.name?.replace(/^models\//, "") ?? "";
|
|
21155
|
+
if (name) models.push(name);
|
|
21156
|
+
}
|
|
21157
|
+
return models.sort();
|
|
21158
|
+
}
|
|
20652
21159
|
/**
|
|
20653
21160
|
* Handle Vertex AI-specific errors
|
|
20654
21161
|
*/
|
|
@@ -20694,6 +21201,23 @@ var GenericOpenAIProvider = class extends OpenAITextProvider {
|
|
|
20694
21201
|
};
|
|
20695
21202
|
}
|
|
20696
21203
|
}
|
|
21204
|
+
/**
|
|
21205
|
+
* Override API key validation for generic providers.
|
|
21206
|
+
* Services like Ollama don't require authentication, so accept any key including mock/placeholder keys.
|
|
21207
|
+
*/
|
|
21208
|
+
validateApiKey() {
|
|
21209
|
+
return { isValid: true };
|
|
21210
|
+
}
|
|
21211
|
+
/**
|
|
21212
|
+
* Override listModels for error safety — some OpenAI-compatible APIs may not support /v1/models
|
|
21213
|
+
*/
|
|
21214
|
+
async listModels() {
|
|
21215
|
+
try {
|
|
21216
|
+
return await super.listModels();
|
|
21217
|
+
} catch {
|
|
21218
|
+
return [];
|
|
21219
|
+
}
|
|
21220
|
+
}
|
|
20697
21221
|
/**
|
|
20698
21222
|
* Override model capabilities for generic providers (registry-driven with conservative defaults)
|
|
20699
21223
|
*/
|
|
@@ -21138,6 +21662,34 @@ var BaseAgent = class extends eventemitter3.EventEmitter {
|
|
|
21138
21662
|
return tool.definition;
|
|
21139
21663
|
});
|
|
21140
21664
|
}
|
|
21665
|
+
// ===== Model Discovery =====
|
|
21666
|
+
/**
|
|
21667
|
+
* List available models from the provider's API.
|
|
21668
|
+
* Useful for discovering models dynamically (e.g., Ollama local models).
|
|
21669
|
+
*/
|
|
21670
|
+
async listModels() {
|
|
21671
|
+
return this._provider.listModels();
|
|
21672
|
+
}
|
|
21673
|
+
// ===== Snapshot / Inspection =====
|
|
21674
|
+
/**
|
|
21675
|
+
* Get a complete, serializable snapshot of the agent's context state.
|
|
21676
|
+
*
|
|
21677
|
+
* Convenience method that auto-wires tool usage stats from ToolManager.
|
|
21678
|
+
* Used by UI "Look Inside" panels.
|
|
21679
|
+
*/
|
|
21680
|
+
async getSnapshot() {
|
|
21681
|
+
const stats = this._agentContext.tools.getStats();
|
|
21682
|
+
return this._agentContext.getSnapshot({ mostUsed: stats.mostUsed });
|
|
21683
|
+
}
|
|
21684
|
+
/**
|
|
21685
|
+
* Get a human-readable breakdown of the prepared context.
|
|
21686
|
+
*
|
|
21687
|
+
* Convenience method that delegates to AgentContextNextGen.
|
|
21688
|
+
* Used by "View Full Context" UI panels.
|
|
21689
|
+
*/
|
|
21690
|
+
async getViewContext() {
|
|
21691
|
+
return this._agentContext.getViewContext();
|
|
21692
|
+
}
|
|
21141
21693
|
// ===== Direct LLM Access (Bypasses AgentContext) =====
|
|
21142
21694
|
/**
|
|
21143
21695
|
* Get the provider for LLM calls.
|
|
@@ -21901,6 +22453,8 @@ var StreamState = class {
|
|
|
21901
22453
|
createdAt;
|
|
21902
22454
|
// Text accumulation: item_id -> text chunks
|
|
21903
22455
|
textBuffers;
|
|
22456
|
+
// Reasoning accumulation: item_id -> reasoning chunks
|
|
22457
|
+
reasoningBuffers;
|
|
21904
22458
|
// Tool call accumulation: tool_call_id -> buffer
|
|
21905
22459
|
toolCallBuffers;
|
|
21906
22460
|
// Completed tool calls
|
|
@@ -21922,6 +22476,7 @@ var StreamState = class {
|
|
|
21922
22476
|
this.model = model;
|
|
21923
22477
|
this.createdAt = createdAt || Date.now();
|
|
21924
22478
|
this.textBuffers = /* @__PURE__ */ new Map();
|
|
22479
|
+
this.reasoningBuffers = /* @__PURE__ */ new Map();
|
|
21925
22480
|
this.toolCallBuffers = /* @__PURE__ */ new Map();
|
|
21926
22481
|
this.completedToolCalls = [];
|
|
21927
22482
|
this.toolResults = /* @__PURE__ */ new Map();
|
|
@@ -21965,6 +22520,39 @@ var StreamState = class {
|
|
|
21965
22520
|
}
|
|
21966
22521
|
return allText.join("");
|
|
21967
22522
|
}
|
|
22523
|
+
/**
|
|
22524
|
+
* Accumulate reasoning delta for a specific item
|
|
22525
|
+
*/
|
|
22526
|
+
accumulateReasoningDelta(itemId, delta) {
|
|
22527
|
+
if (!this.reasoningBuffers.has(itemId)) {
|
|
22528
|
+
this.reasoningBuffers.set(itemId, []);
|
|
22529
|
+
}
|
|
22530
|
+
this.reasoningBuffers.get(itemId).push(delta);
|
|
22531
|
+
this.totalChunks++;
|
|
22532
|
+
}
|
|
22533
|
+
/**
|
|
22534
|
+
* Get complete accumulated reasoning for an item
|
|
22535
|
+
*/
|
|
22536
|
+
getCompleteReasoning(itemId) {
|
|
22537
|
+
const chunks = this.reasoningBuffers.get(itemId);
|
|
22538
|
+
return chunks ? chunks.join("") : "";
|
|
22539
|
+
}
|
|
22540
|
+
/**
|
|
22541
|
+
* Get all accumulated reasoning (all items concatenated)
|
|
22542
|
+
*/
|
|
22543
|
+
getAllReasoning() {
|
|
22544
|
+
const allReasoning = [];
|
|
22545
|
+
for (const chunks of this.reasoningBuffers.values()) {
|
|
22546
|
+
allReasoning.push(chunks.join(""));
|
|
22547
|
+
}
|
|
22548
|
+
return allReasoning.join("");
|
|
22549
|
+
}
|
|
22550
|
+
/**
|
|
22551
|
+
* Check if stream has any accumulated reasoning
|
|
22552
|
+
*/
|
|
22553
|
+
hasReasoning() {
|
|
22554
|
+
return this.reasoningBuffers.size > 0;
|
|
22555
|
+
}
|
|
21968
22556
|
/**
|
|
21969
22557
|
* Start accumulating tool call arguments
|
|
21970
22558
|
*/
|
|
@@ -22133,6 +22721,7 @@ var StreamState = class {
|
|
|
22133
22721
|
*/
|
|
22134
22722
|
clear() {
|
|
22135
22723
|
this.textBuffers.clear();
|
|
22724
|
+
this.reasoningBuffers.clear();
|
|
22136
22725
|
this.toolCallBuffers.clear();
|
|
22137
22726
|
this.completedToolCalls = [];
|
|
22138
22727
|
this.toolResults.clear();
|
|
@@ -22146,6 +22735,7 @@ var StreamState = class {
|
|
|
22146
22735
|
model: this.model,
|
|
22147
22736
|
createdAt: this.createdAt,
|
|
22148
22737
|
textBuffers: new Map(this.textBuffers),
|
|
22738
|
+
reasoningBuffers: new Map(this.reasoningBuffers),
|
|
22149
22739
|
toolCallBuffers: new Map(this.toolCallBuffers),
|
|
22150
22740
|
completedToolCalls: [...this.completedToolCalls],
|
|
22151
22741
|
toolResults: new Map(this.toolResults),
|
|
@@ -22575,6 +23165,20 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
22575
23165
|
_addStreamingAssistantMessage(streamState, toolCalls) {
|
|
22576
23166
|
const assistantText = streamState.getAllText();
|
|
22577
23167
|
const assistantContent = [];
|
|
23168
|
+
if (streamState.hasReasoning()) {
|
|
23169
|
+
const reasoning = streamState.getAllReasoning();
|
|
23170
|
+
if (reasoning) {
|
|
23171
|
+
const isAnthropic = this.connector.vendor === Vendor.Anthropic;
|
|
23172
|
+
assistantContent.push({
|
|
23173
|
+
type: "thinking" /* THINKING */,
|
|
23174
|
+
thinking: reasoning,
|
|
23175
|
+
// Streaming doesn't carry Anthropic signatures, so signature is undefined here.
|
|
23176
|
+
// Non-streaming responses (via convertResponse) capture signatures correctly.
|
|
23177
|
+
signature: void 0,
|
|
23178
|
+
persistInHistory: isAnthropic
|
|
23179
|
+
});
|
|
23180
|
+
}
|
|
23181
|
+
}
|
|
22578
23182
|
if (assistantText && assistantText.trim()) {
|
|
22579
23183
|
assistantContent.push({
|
|
22580
23184
|
type: "output_text" /* OUTPUT_TEXT */,
|
|
@@ -22813,6 +23417,7 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
22813
23417
|
tools: this.getEnabledToolDefinitions(),
|
|
22814
23418
|
tool_choice: "auto",
|
|
22815
23419
|
temperature: this._config.temperature,
|
|
23420
|
+
thinking: this._config.thinking,
|
|
22816
23421
|
vendorOptions: this._config.vendorOptions
|
|
22817
23422
|
};
|
|
22818
23423
|
const beforeLLM = await this.hookManager.executeHooks("before:llm", {
|
|
@@ -22878,6 +23483,7 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
22878
23483
|
tools: this.getEnabledToolDefinitions(),
|
|
22879
23484
|
tool_choice: "auto",
|
|
22880
23485
|
temperature: this._config.temperature,
|
|
23486
|
+
thinking: this._config.thinking,
|
|
22881
23487
|
vendorOptions: this._config.vendorOptions
|
|
22882
23488
|
};
|
|
22883
23489
|
await this.hookManager.executeHooks("before:llm", {
|
|
@@ -22895,7 +23501,9 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
22895
23501
|
});
|
|
22896
23502
|
try {
|
|
22897
23503
|
for await (const event of this._provider.streamGenerate(generateOptions)) {
|
|
22898
|
-
if (event
|
|
23504
|
+
if (isReasoningDelta(event)) {
|
|
23505
|
+
streamState.accumulateReasoningDelta(event.item_id, event.delta);
|
|
23506
|
+
} else if (event.type === "response.output_text.delta" /* OUTPUT_TEXT_DELTA */) {
|
|
22899
23507
|
streamState.accumulateTextDelta(event.item_id, event.delta);
|
|
22900
23508
|
} else if (event.type === "response.tool_call.start" /* TOOL_CALL_START */) {
|
|
22901
23509
|
streamState.startToolCall(event.tool_call_id, event.tool_name);
|
|
@@ -23931,6 +24539,12 @@ function defaultTaskPrompt(task) {
|
|
|
23931
24539
|
}
|
|
23932
24540
|
parts.push("");
|
|
23933
24541
|
}
|
|
24542
|
+
if (task.dependsOn.length > 0) {
|
|
24543
|
+
parts.push("Note: Results from prerequisite tasks are available in your live context.");
|
|
24544
|
+
parts.push("Small results appear directly; larger results are in working memory \u2014 use memory_retrieve to access them.");
|
|
24545
|
+
parts.push("Review the plan overview and dependency results before starting.");
|
|
24546
|
+
parts.push("");
|
|
24547
|
+
}
|
|
23934
24548
|
parts.push("After completing the work, store key results in memory once, then respond with a text summary (no more tool calls).");
|
|
23935
24549
|
return parts.join("\n");
|
|
23936
24550
|
}
|
|
@@ -24014,6 +24628,127 @@ async function collectValidationContext(agent, responseText) {
|
|
|
24014
24628
|
toolCallLog
|
|
24015
24629
|
};
|
|
24016
24630
|
}
|
|
24631
|
+
function estimateTokens(text) {
|
|
24632
|
+
return Math.ceil(text.length / 4);
|
|
24633
|
+
}
|
|
24634
|
+
function buildPlanOverview(execution, definition, currentTaskId) {
|
|
24635
|
+
const parts = [];
|
|
24636
|
+
const progress = execution.progress ?? 0;
|
|
24637
|
+
parts.push(`Routine: ${definition.name}`);
|
|
24638
|
+
if (definition.description) {
|
|
24639
|
+
parts.push(`Goal: ${definition.description}`);
|
|
24640
|
+
}
|
|
24641
|
+
parts.push(`Progress: ${Math.round(progress * 100)}%`);
|
|
24642
|
+
parts.push("");
|
|
24643
|
+
parts.push("Tasks:");
|
|
24644
|
+
for (const task of execution.plan.tasks) {
|
|
24645
|
+
let statusIcon;
|
|
24646
|
+
switch (task.status) {
|
|
24647
|
+
case "completed":
|
|
24648
|
+
statusIcon = "[x]";
|
|
24649
|
+
break;
|
|
24650
|
+
case "in_progress":
|
|
24651
|
+
statusIcon = "[>]";
|
|
24652
|
+
break;
|
|
24653
|
+
case "failed":
|
|
24654
|
+
statusIcon = "[!]";
|
|
24655
|
+
break;
|
|
24656
|
+
case "skipped":
|
|
24657
|
+
statusIcon = "[-]";
|
|
24658
|
+
break;
|
|
24659
|
+
default:
|
|
24660
|
+
statusIcon = "[ ]";
|
|
24661
|
+
}
|
|
24662
|
+
let line = `${statusIcon} ${task.name}`;
|
|
24663
|
+
if (task.dependsOn.length > 0) {
|
|
24664
|
+
const depNames = task.dependsOn.map((depId) => execution.plan.tasks.find((t) => t.id === depId)?.name ?? depId).join(", ");
|
|
24665
|
+
line += ` (after: ${depNames})`;
|
|
24666
|
+
}
|
|
24667
|
+
if (task.id === currentTaskId) {
|
|
24668
|
+
line += " \u2190 CURRENT";
|
|
24669
|
+
}
|
|
24670
|
+
parts.push(line);
|
|
24671
|
+
}
|
|
24672
|
+
return parts.join("\n");
|
|
24673
|
+
}
|
|
24674
|
+
async function injectRoutineContext(agent, execution, definition, currentTask) {
|
|
24675
|
+
const icmPlugin = agent.context.getPlugin("in_context_memory");
|
|
24676
|
+
const wmPlugin = agent.context.memory;
|
|
24677
|
+
if (!icmPlugin && !wmPlugin) {
|
|
24678
|
+
exports.logger.warn("injectRoutineContext: No ICM or WM plugin available \u2014 skipping context injection");
|
|
24679
|
+
return;
|
|
24680
|
+
}
|
|
24681
|
+
const planOverview = buildPlanOverview(execution, definition, currentTask.id);
|
|
24682
|
+
if (icmPlugin) {
|
|
24683
|
+
icmPlugin.set("__routine_plan", "Routine plan overview with task statuses", planOverview, "high");
|
|
24684
|
+
}
|
|
24685
|
+
if (icmPlugin) {
|
|
24686
|
+
for (const entry of icmPlugin.list()) {
|
|
24687
|
+
if (entry.key.startsWith("__dep_result_") || entry.key === "__routine_deps") {
|
|
24688
|
+
icmPlugin.delete(entry.key);
|
|
24689
|
+
}
|
|
24690
|
+
}
|
|
24691
|
+
}
|
|
24692
|
+
if (wmPlugin) {
|
|
24693
|
+
const { entries: wmEntries } = await wmPlugin.query();
|
|
24694
|
+
for (const entry of wmEntries) {
|
|
24695
|
+
if (entry.key.startsWith("__dep_result_") || entry.key.startsWith("findings/__dep_result_")) {
|
|
24696
|
+
await wmPlugin.delete(entry.key);
|
|
24697
|
+
}
|
|
24698
|
+
}
|
|
24699
|
+
}
|
|
24700
|
+
if (currentTask.dependsOn.length === 0) return;
|
|
24701
|
+
const inContextDeps = [];
|
|
24702
|
+
const workingMemoryDeps = [];
|
|
24703
|
+
for (const depId of currentTask.dependsOn) {
|
|
24704
|
+
const depTask = execution.plan.tasks.find((t) => t.id === depId);
|
|
24705
|
+
if (!depTask?.result?.output) continue;
|
|
24706
|
+
const output = typeof depTask.result.output === "string" ? depTask.result.output : JSON.stringify(depTask.result.output);
|
|
24707
|
+
const tokens = estimateTokens(output);
|
|
24708
|
+
const depKey = `__dep_result_${depId}`;
|
|
24709
|
+
const depLabel = `Result from task "${depTask.name}"`;
|
|
24710
|
+
if (tokens < 5e3 && icmPlugin) {
|
|
24711
|
+
icmPlugin.set(depKey, depLabel, output, "high");
|
|
24712
|
+
inContextDeps.push(depTask.name);
|
|
24713
|
+
} else if (wmPlugin) {
|
|
24714
|
+
await wmPlugin.store(depKey, depLabel, output, { tier: "findings" });
|
|
24715
|
+
workingMemoryDeps.push(depTask.name);
|
|
24716
|
+
} else if (icmPlugin) {
|
|
24717
|
+
const truncated = output.slice(0, 2e4) + "\n... (truncated, full result not available)";
|
|
24718
|
+
icmPlugin.set(depKey, depLabel, truncated, "high");
|
|
24719
|
+
inContextDeps.push(depTask.name + " (truncated)");
|
|
24720
|
+
}
|
|
24721
|
+
}
|
|
24722
|
+
if (icmPlugin && (inContextDeps.length > 0 || workingMemoryDeps.length > 0)) {
|
|
24723
|
+
const summaryParts = ["Dependency results available:"];
|
|
24724
|
+
if (inContextDeps.length > 0) {
|
|
24725
|
+
summaryParts.push(`In context (visible now): ${inContextDeps.join(", ")}`);
|
|
24726
|
+
}
|
|
24727
|
+
if (workingMemoryDeps.length > 0) {
|
|
24728
|
+
summaryParts.push(`In working memory (use memory_retrieve): ${workingMemoryDeps.join(", ")}`);
|
|
24729
|
+
}
|
|
24730
|
+
icmPlugin.set("__routine_deps", "Dependency results location guide", summaryParts.join("\n"), "high");
|
|
24731
|
+
}
|
|
24732
|
+
}
|
|
24733
|
+
async function cleanupRoutineContext(agent) {
|
|
24734
|
+
const icmPlugin = agent.context.getPlugin("in_context_memory");
|
|
24735
|
+
const wmPlugin = agent.context.memory;
|
|
24736
|
+
if (icmPlugin) {
|
|
24737
|
+
for (const entry of icmPlugin.list()) {
|
|
24738
|
+
if (entry.key.startsWith("__routine_") || entry.key.startsWith("__dep_result_")) {
|
|
24739
|
+
icmPlugin.delete(entry.key);
|
|
24740
|
+
}
|
|
24741
|
+
}
|
|
24742
|
+
}
|
|
24743
|
+
if (wmPlugin) {
|
|
24744
|
+
const { entries: wmEntries } = await wmPlugin.query();
|
|
24745
|
+
for (const entry of wmEntries) {
|
|
24746
|
+
if (entry.key.startsWith("__dep_result_") || entry.key.startsWith("findings/__dep_result_")) {
|
|
24747
|
+
await wmPlugin.delete(entry.key);
|
|
24748
|
+
}
|
|
24749
|
+
}
|
|
24750
|
+
}
|
|
24751
|
+
}
|
|
24017
24752
|
async function validateTaskCompletion(agent, task, responseText, validationPromptBuilder) {
|
|
24018
24753
|
const hasExplicitValidation = task.validation?.skipReflection === false && task.validation?.completionCriteria && task.validation.completionCriteria.length > 0;
|
|
24019
24754
|
if (!hasExplicitValidation) {
|
|
@@ -24150,7 +24885,7 @@ async function executeRoutine(options) {
|
|
|
24150
24885
|
execution.lastUpdatedAt = Date.now();
|
|
24151
24886
|
onTaskStarted?.(execution.plan.tasks[taskIndex], execution);
|
|
24152
24887
|
let taskCompleted = false;
|
|
24153
|
-
const maxTaskIterations = task.execution?.maxIterations ??
|
|
24888
|
+
const maxTaskIterations = task.execution?.maxIterations ?? 50;
|
|
24154
24889
|
const iterationLimiter = async (ctx) => {
|
|
24155
24890
|
if (ctx.iteration >= maxTaskIterations) {
|
|
24156
24891
|
agent.cancel(`Task "${task.name}" exceeded max iterations (${maxTaskIterations})`);
|
|
@@ -24159,6 +24894,7 @@ async function executeRoutine(options) {
|
|
|
24159
24894
|
};
|
|
24160
24895
|
agent.registerHook("pause:check", iterationLimiter);
|
|
24161
24896
|
const getTask = () => execution.plan.tasks[taskIndex];
|
|
24897
|
+
await injectRoutineContext(agent, execution, definition, getTask());
|
|
24162
24898
|
while (!taskCompleted) {
|
|
24163
24899
|
try {
|
|
24164
24900
|
const taskPrompt = buildTaskPrompt(getTask());
|
|
@@ -24261,6 +24997,10 @@ async function executeRoutine(options) {
|
|
|
24261
24997
|
);
|
|
24262
24998
|
return execution;
|
|
24263
24999
|
} finally {
|
|
25000
|
+
try {
|
|
25001
|
+
await cleanupRoutineContext(agent);
|
|
25002
|
+
} catch {
|
|
25003
|
+
}
|
|
24264
25004
|
for (const { name, hook } of registeredHooks) {
|
|
24265
25005
|
try {
|
|
24266
25006
|
agent.unregisterHook(name, hook);
|
|
@@ -38788,6 +39528,42 @@ var StreamHelpers = class {
|
|
|
38788
39528
|
}
|
|
38789
39529
|
return chunks.join("");
|
|
38790
39530
|
}
|
|
39531
|
+
/**
|
|
39532
|
+
* Get only reasoning/thinking deltas from stream
|
|
39533
|
+
* Filters out all other event types
|
|
39534
|
+
*/
|
|
39535
|
+
static async *thinkingOnly(stream) {
|
|
39536
|
+
for await (const event of stream) {
|
|
39537
|
+
if (isReasoningDelta(event)) {
|
|
39538
|
+
yield event.delta;
|
|
39539
|
+
}
|
|
39540
|
+
}
|
|
39541
|
+
}
|
|
39542
|
+
/**
|
|
39543
|
+
* Get both text and thinking deltas from stream
|
|
39544
|
+
* Yields tagged objects so consumers can distinguish them
|
|
39545
|
+
*/
|
|
39546
|
+
static async *textAndThinking(stream) {
|
|
39547
|
+
for await (const event of stream) {
|
|
39548
|
+
if (isOutputTextDelta(event)) {
|
|
39549
|
+
yield { type: "text", delta: event.delta };
|
|
39550
|
+
} else if (isReasoningDelta(event)) {
|
|
39551
|
+
yield { type: "thinking", delta: event.delta };
|
|
39552
|
+
}
|
|
39553
|
+
}
|
|
39554
|
+
}
|
|
39555
|
+
/**
|
|
39556
|
+
* Accumulate all thinking/reasoning content from stream into a single string
|
|
39557
|
+
*/
|
|
39558
|
+
static async accumulateThinking(stream) {
|
|
39559
|
+
const chunks = [];
|
|
39560
|
+
for await (const event of stream) {
|
|
39561
|
+
if (isReasoningDelta(event)) {
|
|
39562
|
+
chunks.push(event.delta);
|
|
39563
|
+
}
|
|
39564
|
+
}
|
|
39565
|
+
return chunks.join("");
|
|
39566
|
+
}
|
|
38791
39567
|
/**
|
|
38792
39568
|
* Buffer stream events into batches
|
|
38793
39569
|
*/
|
|
@@ -38847,6 +39623,11 @@ var StreamHelpers = class {
|
|
|
38847
39623
|
case "response.output_text.delta" /* OUTPUT_TEXT_DELTA */:
|
|
38848
39624
|
state.accumulateTextDelta(event.item_id, event.delta);
|
|
38849
39625
|
break;
|
|
39626
|
+
case "response.reasoning.delta" /* REASONING_DELTA */:
|
|
39627
|
+
state.accumulateReasoningDelta(event.item_id, event.delta);
|
|
39628
|
+
break;
|
|
39629
|
+
case "response.reasoning.done" /* REASONING_DONE */:
|
|
39630
|
+
break;
|
|
38850
39631
|
case "response.tool_call.start" /* TOOL_CALL_START */:
|
|
38851
39632
|
state.startToolCall(event.tool_call_id, event.tool_name);
|
|
38852
39633
|
break;
|
|
@@ -38877,21 +39658,36 @@ var StreamHelpers = class {
|
|
|
38877
39658
|
*/
|
|
38878
39659
|
static reconstructLLMResponse(state) {
|
|
38879
39660
|
const output = [];
|
|
39661
|
+
const contentParts = [];
|
|
39662
|
+
let thinkingText;
|
|
39663
|
+
if (state.hasReasoning()) {
|
|
39664
|
+
const reasoning = state.getAllReasoning();
|
|
39665
|
+
if (reasoning) {
|
|
39666
|
+
thinkingText = reasoning;
|
|
39667
|
+
contentParts.push({
|
|
39668
|
+
type: "thinking" /* THINKING */,
|
|
39669
|
+
thinking: reasoning,
|
|
39670
|
+
persistInHistory: false
|
|
39671
|
+
// Vendor-agnostic default; caller can adjust
|
|
39672
|
+
});
|
|
39673
|
+
}
|
|
39674
|
+
}
|
|
38880
39675
|
if (state.hasText()) {
|
|
38881
39676
|
const textContent = state.getAllText();
|
|
38882
39677
|
if (textContent) {
|
|
38883
|
-
|
|
38884
|
-
type: "
|
|
38885
|
-
|
|
38886
|
-
content: [
|
|
38887
|
-
{
|
|
38888
|
-
type: "output_text" /* OUTPUT_TEXT */,
|
|
38889
|
-
text: textContent
|
|
38890
|
-
}
|
|
38891
|
-
]
|
|
39678
|
+
contentParts.push({
|
|
39679
|
+
type: "output_text" /* OUTPUT_TEXT */,
|
|
39680
|
+
text: textContent
|
|
38892
39681
|
});
|
|
38893
39682
|
}
|
|
38894
39683
|
}
|
|
39684
|
+
if (contentParts.length > 0) {
|
|
39685
|
+
output.push({
|
|
39686
|
+
type: "message",
|
|
39687
|
+
role: "assistant" /* ASSISTANT */,
|
|
39688
|
+
content: contentParts
|
|
39689
|
+
});
|
|
39690
|
+
}
|
|
38895
39691
|
const toolCalls = state.getCompletedToolCalls();
|
|
38896
39692
|
if (toolCalls.length > 0) {
|
|
38897
39693
|
const toolUseContent = toolCalls.map((tc) => ({
|
|
@@ -38920,6 +39716,7 @@ var StreamHelpers = class {
|
|
|
38920
39716
|
model: state.model,
|
|
38921
39717
|
output,
|
|
38922
39718
|
output_text: outputText,
|
|
39719
|
+
thinking: thinkingText,
|
|
38923
39720
|
usage: state.usage
|
|
38924
39721
|
};
|
|
38925
39722
|
}
|
|
@@ -50368,6 +51165,7 @@ exports.findConnectorByServiceTypes = findConnectorByServiceTypes;
|
|
|
50368
51165
|
exports.forPlan = forPlan;
|
|
50369
51166
|
exports.forTasks = forTasks;
|
|
50370
51167
|
exports.formatAttendees = formatAttendees;
|
|
51168
|
+
exports.formatPluginDisplayName = formatPluginDisplayName;
|
|
50371
51169
|
exports.formatRecipients = formatRecipients;
|
|
50372
51170
|
exports.generateEncryptionKey = generateEncryptionKey;
|
|
50373
51171
|
exports.generateSimplePlan = generateSimplePlan;
|
|
@@ -50436,6 +51234,8 @@ exports.isErrorEvent = isErrorEvent;
|
|
|
50436
51234
|
exports.isExcludedExtension = isExcludedExtension;
|
|
50437
51235
|
exports.isKnownService = isKnownService;
|
|
50438
51236
|
exports.isOutputTextDelta = isOutputTextDelta;
|
|
51237
|
+
exports.isReasoningDelta = isReasoningDelta;
|
|
51238
|
+
exports.isReasoningDone = isReasoningDone;
|
|
50439
51239
|
exports.isResponseComplete = isResponseComplete;
|
|
50440
51240
|
exports.isSimpleScope = isSimpleScope;
|
|
50441
51241
|
exports.isStreamEvent = isStreamEvent;
|