@illuma-ai/agents 1.5.1 → 2.1.1
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 +0 -62
- package/dist/cjs/agents/AgentContext.cjs +160 -259
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +12 -12
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +30 -13
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +1 -1
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/matchers.cjs +2 -2
- package/dist/cjs/hooks/matchers.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +1 -1
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -5
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +33 -61
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +1 -1
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +10 -27
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +3 -84
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/memory/citations.cjs +4 -4
- package/dist/cjs/memory/citations.cjs.map +1 -1
- package/dist/cjs/memory/constants.cjs +17 -17
- package/dist/cjs/memory/constants.cjs.map +1 -1
- package/dist/cjs/memory/mmr.cjs +1 -1
- package/dist/cjs/memory/mmr.cjs.map +1 -1
- package/dist/cjs/memory/paths.cjs +1 -1
- package/dist/cjs/memory/paths.cjs.map +1 -1
- package/dist/cjs/memory/recallTracking.cjs +3 -3
- package/dist/cjs/memory/recallTracking.cjs.map +1 -1
- package/dist/cjs/memory/temporalDecay.cjs +2 -2
- package/dist/cjs/memory/temporalDecay.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +0 -89
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +13 -71
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +11 -21
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +13 -41
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +11 -16
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +78 -13
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/memory/memoryAppendTool.cjs +1 -1
- package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/memoryGetTool.cjs +2 -2
- package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/memorySearchTool.cjs +3 -3
- package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/shared.cjs +1 -1
- package/dist/cjs/tools/memory/shared.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +3 -11
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +4 -28
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +3 -10
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +48 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +160 -259
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +12 -12
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +30 -13
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs +1 -1
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -1
- package/dist/esm/hooks/HookRegistry.mjs +1 -1
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/matchers.mjs +2 -2
- package/dist/esm/hooks/matchers.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +1 -1
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -5
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +34 -61
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +1 -1
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +10 -27
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -5
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/memory/citations.mjs +4 -4
- package/dist/esm/memory/citations.mjs.map +1 -1
- package/dist/esm/memory/constants.mjs +17 -17
- package/dist/esm/memory/constants.mjs.map +1 -1
- package/dist/esm/memory/mmr.mjs +1 -1
- package/dist/esm/memory/mmr.mjs.map +1 -1
- package/dist/esm/memory/paths.mjs +1 -1
- package/dist/esm/memory/paths.mjs.map +1 -1
- package/dist/esm/memory/recallTracking.mjs +3 -3
- package/dist/esm/memory/recallTracking.mjs.map +1 -1
- package/dist/esm/memory/temporalDecay.mjs +2 -2
- package/dist/esm/memory/temporalDecay.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +0 -89
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +13 -71
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +12 -22
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +14 -41
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +12 -17
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +78 -13
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/memory/memoryAppendTool.mjs +1 -1
- package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -1
- package/dist/esm/tools/memory/memoryGetTool.mjs +2 -2
- package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -1
- package/dist/esm/tools/memory/memorySearchTool.mjs +3 -3
- package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -1
- package/dist/esm/tools/memory/shared.mjs +1 -1
- package/dist/esm/tools/memory/shared.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +3 -11
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +4 -28
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +3 -10
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +48 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +25 -95
- package/dist/types/common/enum.d.ts +12 -12
- package/dist/types/graphs/Graph.d.ts +2 -2
- package/dist/types/graphs/phases/memoryFlushPhase.d.ts +2 -2
- package/dist/types/hooks/HookRegistry.d.ts +1 -1
- package/dist/types/hooks/matchers.d.ts +2 -2
- package/dist/types/hooks/types.d.ts +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/llm/bedrock/index.d.ts +1 -54
- package/dist/types/llm/openai/index.d.ts +1 -1
- package/dist/types/memory/citations.d.ts +4 -4
- package/dist/types/memory/constants.d.ts +17 -17
- package/dist/types/memory/mmr.d.ts +3 -3
- package/dist/types/memory/paths.d.ts +1 -1
- package/dist/types/memory/temporalDecay.d.ts +2 -2
- package/dist/types/memory/types.d.ts +3 -3
- package/dist/types/messages/format.d.ts +2 -5
- package/dist/types/tools/CodeExecutor.d.ts +0 -6
- package/dist/types/tools/ToolNode.d.ts +3 -3
- package/dist/types/tools/memory/shared.d.ts +1 -1
- package/dist/types/tools/search/test.d.ts +1 -0
- package/dist/types/tools/search/types.d.ts +5 -99
- package/dist/types/tools/search/utils.d.ts +2 -2
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +29 -0
- package/dist/types/types/graph.d.ts +30 -34
- package/dist/types/types/index.d.ts +0 -1
- package/dist/types/types/messages.d.ts +1 -1
- package/dist/types/types/run.d.ts +1 -3
- package/dist/types/types/tools.d.ts +5 -14
- package/package.json +1 -61
- package/src/agents/AgentContext.test.ts +176 -0
- package/src/agents/AgentContext.ts +179 -305
- package/src/agents/__tests__/AgentContext.test.ts +0 -632
- package/src/common/__tests__/enum.test.ts +1 -1
- package/src/common/enum.ts +12 -12
- package/src/graphs/Graph.ts +32 -13
- package/src/graphs/MultiAgentGraph.ts +1 -1
- package/src/graphs/gapFeatures.test.ts +1 -1
- package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +1 -1
- package/src/graphs/phases/memoryFlushPhase.ts +2 -2
- package/src/hooks/HookRegistry.ts +1 -1
- package/src/hooks/index.ts +1 -1
- package/src/hooks/matchers.ts +2 -2
- package/src/hooks/types.ts +1 -1
- package/src/index.ts +0 -6
- package/src/llm/anthropic/utils/message_inputs.ts +1 -10
- package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +18 -166
- package/src/llm/bedrock/index.ts +41 -116
- package/src/llm/openai/index.ts +2 -2
- package/src/llm/openai/utils/index.ts +14 -31
- package/src/memory/citations.ts +4 -4
- package/src/memory/constants.ts +17 -17
- package/src/memory/mmr.ts +3 -3
- package/src/memory/paths.ts +1 -1
- package/src/memory/recallTracking.ts +3 -3
- package/src/memory/temporalDecay.ts +2 -2
- package/src/memory/types.ts +3 -3
- package/src/messages/cache.test.ts +24 -62
- package/src/messages/cache.ts +0 -112
- package/src/messages/ensureThinkingBlock.test.ts +1 -1
- package/src/messages/format.ts +13 -92
- package/src/messages/formatAgentMessages.test.ts +1 -1
- package/src/scripts/subagent-configurable-inheritance.ts +263 -0
- package/src/scripts/subagent-event-driven-debug.ts +2 -2
- package/src/specs/anthropic.simple.test.ts +0 -61
- package/src/specs/prune.orphans.test.ts +1 -1
- package/src/tools/BashExecutor.ts +13 -37
- package/src/tools/CodeExecutor.ts +14 -59
- package/src/tools/ProgrammaticToolCalling.ts +14 -29
- package/src/tools/ToolNode.ts +75 -14
- package/src/tools/__tests__/CodeExecutor.test.ts +3 -3
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -60
- package/src/tools/__tests__/SubagentExecutor.test.ts +157 -0
- package/src/tools/memory/memoryAppendTool.ts +1 -1
- package/src/tools/memory/memoryGetTool.ts +2 -2
- package/src/tools/memory/memorySearchTool.ts +3 -3
- package/src/tools/memory/shared.ts +1 -1
- package/src/tools/search/output.md +2775 -0
- package/src/tools/search/search.ts +2 -12
- package/src/tools/search/test.html +884 -0
- package/src/tools/search/test.md +643 -0
- package/src/tools/search/test.ts +159 -0
- package/src/tools/search/tool.ts +2 -36
- package/src/tools/search/types.ts +8 -133
- package/src/tools/search/utils.ts +5 -13
- package/src/tools/subagent/SubagentExecutor.ts +78 -0
- package/src/types/graph.ts +27 -34
- package/src/types/index.ts +0 -1
- package/src/types/messages.ts +1 -1
- package/src/types/run.ts +1 -3
- package/src/types/tools.ts +5 -14
- package/dist/cjs/langchain/google-common.cjs +0 -3
- package/dist/cjs/langchain/google-common.cjs.map +0 -1
- package/dist/cjs/langchain/index.cjs +0 -86
- package/dist/cjs/langchain/index.cjs.map +0 -1
- package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
- package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
- package/dist/cjs/langchain/messages/tool.cjs +0 -3
- package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
- package/dist/cjs/langchain/messages.cjs +0 -51
- package/dist/cjs/langchain/messages.cjs.map +0 -1
- package/dist/cjs/langchain/openai.cjs +0 -3
- package/dist/cjs/langchain/openai.cjs.map +0 -1
- package/dist/cjs/langchain/prompts.cjs +0 -11
- package/dist/cjs/langchain/prompts.cjs.map +0 -1
- package/dist/cjs/langchain/runnables.cjs +0 -19
- package/dist/cjs/langchain/runnables.cjs.map +0 -1
- package/dist/cjs/langchain/tools.cjs +0 -23
- package/dist/cjs/langchain/tools.cjs.map +0 -1
- package/dist/cjs/langchain/utils/env.cjs +0 -11
- package/dist/cjs/langchain/utils/env.cjs.map +0 -1
- package/dist/cjs/llm/bedrock/cacheSupport.cjs +0 -55
- package/dist/cjs/llm/bedrock/cacheSupport.cjs.map +0 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +0 -189
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +0 -1
- package/dist/cjs/tools/search/tavily-search.cjs +0 -372
- package/dist/cjs/tools/search/tavily-search.cjs.map +0 -1
- package/dist/cjs/types/agent-cache.cjs +0 -54
- package/dist/cjs/types/agent-cache.cjs.map +0 -1
- package/dist/esm/langchain/google-common.mjs +0 -2
- package/dist/esm/langchain/google-common.mjs.map +0 -1
- package/dist/esm/langchain/index.mjs +0 -5
- package/dist/esm/langchain/index.mjs.map +0 -1
- package/dist/esm/langchain/language_models/chat_models.mjs +0 -2
- package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
- package/dist/esm/langchain/messages/tool.mjs +0 -2
- package/dist/esm/langchain/messages/tool.mjs.map +0 -1
- package/dist/esm/langchain/messages.mjs +0 -2
- package/dist/esm/langchain/messages.mjs.map +0 -1
- package/dist/esm/langchain/openai.mjs +0 -2
- package/dist/esm/langchain/openai.mjs.map +0 -1
- package/dist/esm/langchain/prompts.mjs +0 -2
- package/dist/esm/langchain/prompts.mjs.map +0 -1
- package/dist/esm/langchain/runnables.mjs +0 -2
- package/dist/esm/langchain/runnables.mjs.map +0 -1
- package/dist/esm/langchain/tools.mjs +0 -2
- package/dist/esm/langchain/tools.mjs.map +0 -1
- package/dist/esm/langchain/utils/env.mjs +0 -2
- package/dist/esm/langchain/utils/env.mjs.map +0 -1
- package/dist/esm/llm/bedrock/cacheSupport.mjs +0 -52
- package/dist/esm/llm/bedrock/cacheSupport.mjs.map +0 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +0 -186
- package/dist/esm/tools/search/tavily-scraper.mjs.map +0 -1
- package/dist/esm/tools/search/tavily-search.mjs +0 -370
- package/dist/esm/tools/search/tavily-search.mjs.map +0 -1
- package/dist/esm/types/agent-cache.mjs +0 -52
- package/dist/esm/types/agent-cache.mjs.map +0 -1
- package/dist/types/langchain/google-common.d.ts +0 -1
- package/dist/types/langchain/index.d.ts +0 -8
- package/dist/types/langchain/language_models/chat_models.d.ts +0 -1
- package/dist/types/langchain/messages/tool.d.ts +0 -1
- package/dist/types/langchain/messages.d.ts +0 -2
- package/dist/types/langchain/openai.d.ts +0 -1
- package/dist/types/langchain/prompts.d.ts +0 -1
- package/dist/types/langchain/runnables.d.ts +0 -2
- package/dist/types/langchain/tools.d.ts +0 -2
- package/dist/types/langchain/utils/env.d.ts +0 -1
- package/dist/types/llm/bedrock/cacheSupport.d.ts +0 -35
- package/dist/types/tools/search/tavily-scraper.d.ts +0 -19
- package/dist/types/tools/search/tavily-search.d.ts +0 -4
- package/dist/types/tools/subagent/types.d.ts +0 -84
- package/dist/types/types/agent-cache.d.ts +0 -71
- package/src/agents/__tests__/AgentContext.cacheTtl.live.test.ts +0 -259
- package/src/agents/__tests__/AgentContext.crossAgentTier1.live.test.ts +0 -266
- package/src/agents/__tests__/AgentContext.crossUserCache.live.test.ts +0 -342
- package/src/langchain/google-common.ts +0 -1
- package/src/langchain/index.ts +0 -8
- package/src/langchain/language_models/chat_models.ts +0 -1
- package/src/langchain/messages/tool.ts +0 -5
- package/src/langchain/messages.ts +0 -21
- package/src/langchain/openai.ts +0 -1
- package/src/langchain/prompts.ts +0 -1
- package/src/langchain/runnables.ts +0 -7
- package/src/langchain/tools.ts +0 -8
- package/src/langchain/utils/env.ts +0 -1
- package/src/llm/anthropic/utils/server-tool-inputs.test.ts +0 -436
- package/src/llm/bedrock/cacheSupport.test.ts +0 -99
- package/src/llm/bedrock/cacheSupport.ts +0 -53
- package/src/tools/search/tavily-scraper.ts +0 -235
- package/src/tools/search/tavily-search.ts +0 -424
- package/src/tools/search/tavily.test.ts +0 -965
- package/src/tools/subagent/types.test.ts +0 -70
- package/src/tools/subagent/types.ts +0 -115
- package/src/types/agent-cache.ts +0 -74
|
@@ -376,67 +376,6 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
376
376
|
);
|
|
377
377
|
});
|
|
378
378
|
|
|
379
|
-
test(`${capitalizeFirstLetter(provider)}: follow-up after assistant message with only whitespace text content`, async () => {
|
|
380
|
-
/**
|
|
381
|
-
* Regression for discussion #12806.
|
|
382
|
-
*
|
|
383
|
-
* The Anthropic API has two distinct rejection rules (verified against
|
|
384
|
-
* the live API):
|
|
385
|
-
* 1. Strict empty `text: ''` → rejected anywhere
|
|
386
|
-
* "messages: text content blocks must be non-empty"
|
|
387
|
-
* 2. Whitespace-only `text: ' '` / '\n' / '\t' → rejected when the
|
|
388
|
-
* assistant message has no other accepted blocks (no tool blocks,
|
|
389
|
-
* no non-whitespace text)
|
|
390
|
-
* "messages: text content blocks must contain non-whitespace text"
|
|
391
|
-
*
|
|
392
|
-
* Anthropic responses for some prompts include a whitespace-only text
|
|
393
|
-
* block as the sole text content. Re-sending that history on a
|
|
394
|
-
* follow-up turn triggers rule 2.
|
|
395
|
-
*
|
|
396
|
-
* The wire-send filter in `_formatContent` must drop any text block
|
|
397
|
-
* whose trimmed content is empty. The previous filter used strict
|
|
398
|
-
* `text === ''` only, which caught rule 1 but not rule 2.
|
|
399
|
-
*/
|
|
400
|
-
const llmConfig = getLLMConfig(provider);
|
|
401
|
-
const customHandlers1 = setupCustomHandlers();
|
|
402
|
-
|
|
403
|
-
const followUpRun = await Run.create<t.IState>({
|
|
404
|
-
runId: 'repro-12806-followup',
|
|
405
|
-
graphConfig: {
|
|
406
|
-
type: 'standard',
|
|
407
|
-
llmConfig,
|
|
408
|
-
instructions: 'You are a friendly AI assistant.',
|
|
409
|
-
},
|
|
410
|
-
returnContent: true,
|
|
411
|
-
skipCleanup: true,
|
|
412
|
-
customHandlers: customHandlers1,
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Build history with an assistant message whose entire content array
|
|
416
|
-
// is a single whitespace-only text block. This is the precise shape
|
|
417
|
-
// the API rejects under rule 2 above.
|
|
418
|
-
conversationHistory = [
|
|
419
|
-
new HumanMessage('hi'),
|
|
420
|
-
new (require('@langchain/core/messages').AIMessage)({
|
|
421
|
-
content: [{ type: 'text', text: ' ' }],
|
|
422
|
-
}),
|
|
423
|
-
new HumanMessage('please respond with a short greeting'),
|
|
424
|
-
];
|
|
425
|
-
|
|
426
|
-
// With the fix: `_formatContent` drops the whitespace text block,
|
|
427
|
-
// the assistant content becomes an empty array, and the API accepts.
|
|
428
|
-
// Without the fix: the whitespace block is forwarded and the API
|
|
429
|
-
// rejects with "messages: text content blocks must contain non-whitespace text".
|
|
430
|
-
const finalContentParts = await followUpRun.processStream(
|
|
431
|
-
{ messages: conversationHistory },
|
|
432
|
-
config
|
|
433
|
-
);
|
|
434
|
-
expect(finalContentParts).toBeDefined();
|
|
435
|
-
const finalMessages = followUpRun.getRunMessages();
|
|
436
|
-
expect(finalMessages).toBeDefined();
|
|
437
|
-
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
438
|
-
});
|
|
439
|
-
|
|
440
379
|
test('should handle errors appropriately', async () => {
|
|
441
380
|
// Test error scenarios
|
|
442
381
|
await expect(async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Orphan tool message repair + sanitize coverage. Ported from
|
|
1
|
+
// Orphan tool message repair + sanitize coverage. Ported from upstream's
|
|
2
2
|
// `prune.test.ts` "Tool Message Handling" + top-level `sanitizeOrphanToolBlocks`
|
|
3
3
|
// describes — kept in a dedicated file to keep the diff against illuma's
|
|
4
4
|
// existing prune.test.ts narrow.
|
|
@@ -4,23 +4,17 @@ import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
|
4
4
|
import { getEnvironmentVariable } from '@langchain/core/utils/env';
|
|
5
5
|
import { tool, DynamicStructuredTool } from '@langchain/core/tools';
|
|
6
6
|
import type * as t from '@/types';
|
|
7
|
-
import {
|
|
7
|
+
import { imageExtRegex, getCodeBaseURL } from './CodeExecutor';
|
|
8
8
|
import { Constants, EnvVar } from '@/common';
|
|
9
9
|
|
|
10
10
|
config();
|
|
11
11
|
|
|
12
|
+
const imageMessage = 'Image is already displayed to the user';
|
|
12
13
|
const otherMessage = 'File is already downloaded by the user';
|
|
13
|
-
const inheritedFileMessage =
|
|
14
|
-
'Available as an input — already known to the user';
|
|
15
14
|
const accessMessage =
|
|
16
15
|
'Note: Files from previous executions are automatically available and can be modified.';
|
|
17
16
|
const emptyOutputMessage =
|
|
18
17
|
"stdout: Empty. Ensure you're writing output explicitly.\n";
|
|
19
|
-
const inheritedFilesHeader =
|
|
20
|
-
'Available files (inputs, not generated by this execution):';
|
|
21
|
-
const generatedFilesHeader = 'Generated files:';
|
|
22
|
-
const inheritedNote =
|
|
23
|
-
'Note: Files in "Available files" are inputs the user (or a skill) already provided to the sandbox. They were not produced by this execution and you should not present them as new outputs in your response.';
|
|
24
18
|
|
|
25
19
|
export const BashExecutionToolSchema = {
|
|
26
20
|
type: 'object',
|
|
@@ -221,38 +215,20 @@ function createBashExecutionTool(
|
|
|
221
215
|
}
|
|
222
216
|
if (result.stderr) formattedOutput += `stderr:\n${result.stderr}\n`;
|
|
223
217
|
if (result.files && result.files.length > 0) {
|
|
224
|
-
|
|
225
|
-
* codeapi) from genuine generated outputs. The LLM was previously
|
|
226
|
-
* shown skill files under "Generated files:" with the message
|
|
227
|
-
* "File is already downloaded by the user", which led it to
|
|
228
|
-
* (a) believe it had just produced files it merely referenced
|
|
229
|
-
* and (b) sometimes invent paths like /mnt/user-data/uploads/
|
|
230
|
-
* trying to find the "originals". Labeling them as inputs makes
|
|
231
|
-
* the mental model accurate. */
|
|
232
|
-
const inheritedFiles = result.files.filter(
|
|
233
|
-
(f) => f.inherited === true
|
|
234
|
-
);
|
|
235
|
-
const generatedFiles = result.files.filter(
|
|
236
|
-
(f) => f.inherited !== true
|
|
237
|
-
);
|
|
218
|
+
formattedOutput += 'Generated files:\n';
|
|
238
219
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
formattedOutput += renderFileSection(
|
|
245
|
-
inheritedFilesHeader,
|
|
246
|
-
inheritedFiles,
|
|
247
|
-
inheritedFileMessage
|
|
248
|
-
);
|
|
220
|
+
const fileCount = result.files.length;
|
|
221
|
+
for (let i = 0; i < fileCount; i++) {
|
|
222
|
+
const file = result.files[i];
|
|
223
|
+
const isImage = imageExtRegex.test(file.name);
|
|
224
|
+
formattedOutput += `- /mnt/data/${file.name} | ${isImage ? imageMessage : otherMessage}`;
|
|
249
225
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (inheritedFiles.length > 0) {
|
|
254
|
-
formattedOutput += `\n\n${inheritedNote}`;
|
|
226
|
+
if (i < fileCount - 1) {
|
|
227
|
+
formattedOutput += fileCount <= 3 ? ', ' : ',\n';
|
|
228
|
+
}
|
|
255
229
|
}
|
|
230
|
+
|
|
231
|
+
formattedOutput += `\n\n${accessMessage}`;
|
|
256
232
|
return [
|
|
257
233
|
formattedOutput.trim(),
|
|
258
234
|
{
|
|
@@ -15,41 +15,10 @@ export const getCodeBaseURL = (): string =>
|
|
|
15
15
|
|
|
16
16
|
const imageMessage = 'Image is already displayed to the user';
|
|
17
17
|
const otherMessage = 'File is already downloaded by the user';
|
|
18
|
-
const inheritedFileMessage =
|
|
19
|
-
'Available as an input — already known to the user';
|
|
20
18
|
const accessMessage =
|
|
21
19
|
'Note: Files from previous executions are automatically available and can be modified.';
|
|
22
20
|
const emptyOutputMessage =
|
|
23
21
|
"stdout: Empty. Ensure you're writing output explicitly.\n";
|
|
24
|
-
const inheritedFilesHeader =
|
|
25
|
-
'Available files (inputs, not generated by this execution):';
|
|
26
|
-
const generatedFilesHeader = 'Generated files:';
|
|
27
|
-
const inheritedNote =
|
|
28
|
-
'Note: Files in "Available files" are inputs the user (or a skill) already provided to the sandbox. They were not produced by this execution and you should not present them as new outputs in your response.';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Renders one section of the post-execution file listing. Used by the
|
|
32
|
-
* code/bash tool formatters to keep generated outputs and inherited
|
|
33
|
-
* inputs visually separated. See BashExecutor for full docs.
|
|
34
|
-
*/
|
|
35
|
-
export function renderFileSection(
|
|
36
|
-
header: string,
|
|
37
|
-
files: t.FileRefs,
|
|
38
|
-
defaultMessage: string
|
|
39
|
-
): string {
|
|
40
|
-
if (files.length === 0) return '';
|
|
41
|
-
let out = `${header}\n`;
|
|
42
|
-
for (let i = 0; i < files.length; i++) {
|
|
43
|
-
const file = files[i];
|
|
44
|
-
const isImage = imageExtRegex.test(file.name);
|
|
45
|
-
out += `- /mnt/data/${file.name} | ${isImage ? imageMessage : defaultMessage}`;
|
|
46
|
-
if (i < files.length - 1) {
|
|
47
|
-
out += files.length <= 3 ? ', ' : ',\n';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
out += '\n';
|
|
51
|
-
return out;
|
|
52
|
-
}
|
|
53
22
|
|
|
54
23
|
const SUPPORTED_LANGUAGES = [
|
|
55
24
|
'py',
|
|
@@ -69,10 +38,9 @@ const SUPPORTED_LANGUAGES = [
|
|
|
69
38
|
|
|
70
39
|
// Minimal schema for raw code execution. Only what the /exec endpoint needs.
|
|
71
40
|
// Higher-level workflows (versioning, edit, store, replay) are consumer
|
|
72
|
-
// concerns —
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
// schema-stable primitive.
|
|
41
|
+
// concerns — e.g. ranger layers its own write/edit/execute schema on top via
|
|
42
|
+
// codeEditWrapper and a separate ContentStore-backed Zod schema. Keeping this
|
|
43
|
+
// tool narrow means every consumer gets a clean, schema-stable primitive.
|
|
76
44
|
export const CodeExecutionToolSchema = {
|
|
77
45
|
type: 'object',
|
|
78
46
|
properties: {
|
|
@@ -334,33 +302,20 @@ function createCodeExecutionTool(
|
|
|
334
302
|
}
|
|
335
303
|
|
|
336
304
|
if (result.files && result.files.length > 0) {
|
|
337
|
-
|
|
338
|
-
* generated outputs so the LLM doesn't conflate skill files
|
|
339
|
-
* with newly-produced artifacts. */
|
|
340
|
-
const inheritedFiles = result.files.filter(
|
|
341
|
-
(f) => f.inherited === true
|
|
342
|
-
);
|
|
343
|
-
const generatedFiles = result.files.filter(
|
|
344
|
-
(f) => f.inherited !== true
|
|
345
|
-
);
|
|
305
|
+
formattedOutput += 'Generated files:\n';
|
|
346
306
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
formattedOutput += renderFileSection(
|
|
353
|
-
inheritedFilesHeader,
|
|
354
|
-
inheritedFiles,
|
|
355
|
-
inheritedFileMessage
|
|
356
|
-
);
|
|
307
|
+
const fileCount = result.files.length;
|
|
308
|
+
for (let i = 0; i < fileCount; i++) {
|
|
309
|
+
const file = result.files[i];
|
|
310
|
+
const isImage = imageExtRegex.test(file.name);
|
|
311
|
+
formattedOutput += `- /mnt/data/${file.name} | ${isImage ? imageMessage : otherMessage}`;
|
|
357
312
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (inheritedFiles.length > 0) {
|
|
362
|
-
formattedOutput += `\n\n${inheritedNote}`;
|
|
313
|
+
if (i < fileCount - 1) {
|
|
314
|
+
formattedOutput += fileCount <= 3 ? ', ' : ',\n';
|
|
315
|
+
}
|
|
363
316
|
}
|
|
317
|
+
|
|
318
|
+
formattedOutput += `\n\n${accessMessage}`;
|
|
364
319
|
return [
|
|
365
320
|
formattedOutput.trim(),
|
|
366
321
|
{
|
|
@@ -6,7 +6,7 @@ import { getEnvironmentVariable } from '@langchain/core/utils/env';
|
|
|
6
6
|
import { tool, DynamicStructuredTool } from '@langchain/core/tools';
|
|
7
7
|
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
8
8
|
import type * as t from '@/types';
|
|
9
|
-
import {
|
|
9
|
+
import { imageExtRegex, getCodeBaseURL } from './CodeExecutor';
|
|
10
10
|
import { EnvVar, Constants } from '@/common';
|
|
11
11
|
|
|
12
12
|
config();
|
|
@@ -15,14 +15,8 @@ config();
|
|
|
15
15
|
// Constants
|
|
16
16
|
// ============================================================================
|
|
17
17
|
|
|
18
|
+
const imageMessage = 'Image is already displayed to the user';
|
|
18
19
|
const otherMessage = 'File is already downloaded by the user';
|
|
19
|
-
const inheritedFileMessage =
|
|
20
|
-
'Available as an input — already known to the user';
|
|
21
|
-
const inheritedFilesHeader =
|
|
22
|
-
'Available files (inputs, not generated by this execution):';
|
|
23
|
-
const generatedFilesHeader = 'Generated files:';
|
|
24
|
-
const inheritedNote =
|
|
25
|
-
'Note: Files in "Available files" are inputs the user (or a skill) already provided to the sandbox. They were not produced by this execution and you should not present them as new outputs in your response.';
|
|
26
20
|
const accessMessage =
|
|
27
21
|
'Note: Files from previous executions are automatically available and can be modified.';
|
|
28
22
|
const emptyOutputMessage =
|
|
@@ -569,29 +563,20 @@ export function formatCompletedResponse(
|
|
|
569
563
|
}
|
|
570
564
|
|
|
571
565
|
if (response.files && response.files.length > 0) {
|
|
572
|
-
|
|
573
|
-
* passthrough) inputs from real generated outputs so the LLM doesn't
|
|
574
|
-
* conflate skill files with newly-produced artifacts. */
|
|
575
|
-
const inheritedFiles = response.files.filter((f) => f.inherited === true);
|
|
576
|
-
const generatedFiles = response.files.filter((f) => f.inherited !== true);
|
|
577
|
-
|
|
578
|
-
formatted += renderFileSection(
|
|
579
|
-
generatedFilesHeader,
|
|
580
|
-
generatedFiles,
|
|
581
|
-
otherMessage
|
|
582
|
-
);
|
|
583
|
-
formatted += renderFileSection(
|
|
584
|
-
inheritedFilesHeader,
|
|
585
|
-
inheritedFiles,
|
|
586
|
-
inheritedFileMessage
|
|
587
|
-
);
|
|
566
|
+
formatted += 'Generated files:\n';
|
|
588
567
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
formatted +=
|
|
568
|
+
const fileCount = response.files.length;
|
|
569
|
+
for (let i = 0; i < fileCount; i++) {
|
|
570
|
+
const file = response.files[i];
|
|
571
|
+
const isImage = imageExtRegex.test(file.name);
|
|
572
|
+
formatted += `- /mnt/data/${file.name} | ${isImage ? imageMessage : otherMessage}`;
|
|
573
|
+
|
|
574
|
+
if (i < fileCount - 1) {
|
|
575
|
+
formatted += fileCount <= 3 ? ', ' : ',\n';
|
|
576
|
+
}
|
|
594
577
|
}
|
|
578
|
+
|
|
579
|
+
formatted += `\n\n${accessMessage}`;
|
|
595
580
|
}
|
|
596
581
|
|
|
597
582
|
return [
|
package/src/tools/ToolNode.ts
CHANGED
|
@@ -37,7 +37,7 @@ import type { ResolvedArgsByCallId } from '@/tools/toolOutputReferences';
|
|
|
37
37
|
/**
|
|
38
38
|
* Per-call batch context for `runTool`. Bundles every optional batch-scoped
|
|
39
39
|
* value the method needs so the signature stays at three positional params
|
|
40
|
-
* even as new context fields are added. (PR #117).
|
|
40
|
+
* even as new context fields are added. Upstream-aligned (PR #117).
|
|
41
41
|
*/
|
|
42
42
|
type RunToolBatchContext = {
|
|
43
43
|
/** Position of this call within the parent ToolNode batch. */
|
|
@@ -125,7 +125,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
125
125
|
private hookRegistry?: HookRegistry;
|
|
126
126
|
/**
|
|
127
127
|
* Tool output reference registry threaded down from Run / Graph
|
|
128
|
-
* (PR #114). When set, dispatchToolEvents resolves
|
|
128
|
+
* (upstream PR #114). When set, dispatchToolEvents resolves
|
|
129
129
|
* `{{tool<i>turn<n>}}` placeholders in args before invoking each tool
|
|
130
130
|
* and stores successful outputs under their stable reference keys for
|
|
131
131
|
* subsequent calls in the same run to pipe through.
|
|
@@ -363,7 +363,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
363
363
|
/**
|
|
364
364
|
* Runs a single tool call with error handling.
|
|
365
365
|
*
|
|
366
|
-
* @param batchContext Optional per-batch context (PR #117).
|
|
366
|
+
* @param batchContext Optional per-batch context (upstream PR #117).
|
|
367
367
|
* Threaded from `run()` for tool output reference annotation. The
|
|
368
368
|
* `batchScopeId` field carries an anonymous synthetic scope when the
|
|
369
369
|
* caller has no `run_id`, so concurrent batches don't collide on the
|
|
@@ -581,7 +581,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
581
581
|
});
|
|
582
582
|
|
|
583
583
|
/**
|
|
584
|
-
* Tool output reference metadata (PR #117). Register the
|
|
584
|
+
* Tool output reference metadata (upstream PR #117). Register the
|
|
585
585
|
* raw, untruncated content so future `{{...}}` substitutions deliver
|
|
586
586
|
* the full payload, and stamp `_refKey` / `_refScope` /
|
|
587
587
|
* `_unresolvedRefs` into `additional_kwargs` for the lazy
|
|
@@ -754,19 +754,74 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
754
754
|
}
|
|
755
755
|
}
|
|
756
756
|
|
|
757
|
-
// Field-level recovery: extract missing fields from the raw buffer
|
|
757
|
+
// Field-level recovery: extract missing fields from the raw buffer.
|
|
758
|
+
//
|
|
759
|
+
// Only attempt this when `parsedArgs` is missing top-level keys that
|
|
760
|
+
// appear at depth 0 in the raw JSON. The previous implementation walked
|
|
761
|
+
// EVERY `"key":` match the regex found — including keys nested inside
|
|
762
|
+
// arrays/objects like `steps[].options[].label` — and tried to "recover"
|
|
763
|
+
// them as top-level fields. That produced confusing log spam (false
|
|
764
|
+
// positives like `recoveredFields=[question,label,value]` for a clean
|
|
765
|
+
// multi-step `ask_user` call) and could inject stray top-level fields
|
|
766
|
+
// into `args` for downstream tool execution.
|
|
758
767
|
const parsedArgs = typeof args === 'object' ? { ...args } : {};
|
|
759
768
|
const recoveredFields: string[] = [];
|
|
760
769
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
770
|
+
/**
|
|
771
|
+
* Extract only TOP-LEVEL keys from the raw JSON. Walks the buffer
|
|
772
|
+
* tracking brace/bracket depth so nested keys are skipped.
|
|
773
|
+
*/
|
|
774
|
+
const topLevelKeys: string[] = [];
|
|
775
|
+
let depth = 0;
|
|
776
|
+
let inString = false;
|
|
777
|
+
let escaped = false;
|
|
778
|
+
let i = 0;
|
|
779
|
+
while (i < rawArgs.length) {
|
|
780
|
+
const ch = rawArgs[i];
|
|
781
|
+
if (escaped) {
|
|
782
|
+
escaped = false;
|
|
783
|
+
i++;
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
if (inString) {
|
|
787
|
+
if (ch === '\\') escaped = true;
|
|
788
|
+
else if (ch === '"') inString = false;
|
|
789
|
+
i++;
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (ch === '"') {
|
|
793
|
+
// Possible key — only count if at depth 1 (inside the outer object)
|
|
794
|
+
const start = i + 1;
|
|
795
|
+
let j = start;
|
|
796
|
+
while (j < rawArgs.length) {
|
|
797
|
+
const c = rawArgs[j];
|
|
798
|
+
if (c === '\\') {
|
|
799
|
+
j += 2;
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
if (c === '"') break;
|
|
803
|
+
j++;
|
|
804
|
+
}
|
|
805
|
+
if (j < rawArgs.length) {
|
|
806
|
+
// Skip whitespace after closing quote and check for ':'
|
|
807
|
+
let k = j + 1;
|
|
808
|
+
while (k < rawArgs.length && /\s/.test(rawArgs[k])) k++;
|
|
809
|
+
if (depth === 1 && rawArgs[k] === ':') {
|
|
810
|
+
topLevelKeys.push(rawArgs.slice(start, j));
|
|
811
|
+
}
|
|
812
|
+
i = j + 1;
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
inString = true;
|
|
816
|
+
i++;
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
819
|
+
if (ch === '{' || ch === '[') depth++;
|
|
820
|
+
else if (ch === '}' || ch === ']') depth--;
|
|
821
|
+
i++;
|
|
767
822
|
}
|
|
768
823
|
|
|
769
|
-
for (const fieldName of
|
|
824
|
+
for (const fieldName of topLevelKeys) {
|
|
770
825
|
if (
|
|
771
826
|
parsedArgs[fieldName] == null ||
|
|
772
827
|
parsedArgs[fieldName] === '' ||
|
|
@@ -991,6 +1046,12 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
991
1046
|
// Dispatch ON_RUN_STEP_COMPLETED via custom event (same path as dispatchToolEvents)
|
|
992
1047
|
const stepId = this.toolCallStepIds?.get(toolCallId) ?? '';
|
|
993
1048
|
if (!stepId) {
|
|
1049
|
+
// eslint-disable-next-line no-console
|
|
1050
|
+
console.warn(
|
|
1051
|
+
`[ToolNode.handleRunToolCompletions] missing stepId for toolCallId=${toolCallId} ` +
|
|
1052
|
+
`name=${call.name} — ON_RUN_STEP_COMPLETED skipped, output will not be persisted. ` +
|
|
1053
|
+
`If this is a resumed HITL tool call, verify Graph.resetValues preserves toolCallStepIds when keepContent=true.`
|
|
1054
|
+
);
|
|
994
1055
|
continue;
|
|
995
1056
|
}
|
|
996
1057
|
|
|
@@ -1195,7 +1256,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1195
1256
|
}
|
|
1196
1257
|
|
|
1197
1258
|
/**
|
|
1198
|
-
* Tool output reference resolution (PR #114): walk each call's
|
|
1259
|
+
* Tool output reference resolution (upstream PR #114): walk each call's
|
|
1199
1260
|
* args and substitute `{{tool<i>turn<n>}}` placeholders with the stored
|
|
1200
1261
|
* raw output. Captured here BEFORE request shaping so the substituted
|
|
1201
1262
|
* args flow through the rest of the dispatch unchanged.
|
|
@@ -1380,7 +1441,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1380
1441
|
? result.content
|
|
1381
1442
|
: JSON.stringify(result.content);
|
|
1382
1443
|
/**
|
|
1383
|
-
* Tool output reference — lazy annotation (PRs #114 + #117).
|
|
1444
|
+
* Tool output reference — lazy annotation (upstream PRs #114 + #117).
|
|
1384
1445
|
* Register the raw output under `tool<idx>turn<turn>` in the
|
|
1385
1446
|
* registry but leave `ToolMessage.content` clean. Stamp the ref
|
|
1386
1447
|
* metadata into `additional_kwargs` instead. The lazy
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Validates the execute_code tool exposes a minimal raw-execution schema —
|
|
5
5
|
* `{ lang, code, args }`. Higher-level workflows (versioning, code_id,
|
|
6
|
-
* old_str/new_str edits) are consumer concerns (e.g.
|
|
7
|
-
*
|
|
6
|
+
* old_str/new_str edits) are consumer concerns (e.g. ranger's
|
|
7
|
+
* codeEditWrapper) and must NOT appear in this schema.
|
|
8
8
|
*/
|
|
9
9
|
import {
|
|
10
10
|
CodeExecutionToolSchema,
|
|
@@ -37,7 +37,7 @@ describe('CodeExecutionToolSchema', () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('does NOT expose consumer-workflow fields (code_id, old_str, new_str, replace_all)', () => {
|
|
40
|
-
// These live in
|
|
40
|
+
// These live in ranger's codeEditWrapper Zod schema, not here.
|
|
41
41
|
const props = CodeExecutionToolSchema.properties as Record<string, unknown>;
|
|
42
42
|
expect(props.code_id).toBeUndefined();
|
|
43
43
|
expect(props.old_str).toBeUndefined();
|
|
@@ -664,66 +664,6 @@ for member in team:
|
|
|
664
664
|
expect(output).toContain('chart.png');
|
|
665
665
|
expect(output).toContain('Image is already displayed to the user');
|
|
666
666
|
});
|
|
667
|
-
|
|
668
|
-
it('splits inherited inputs from generated outputs into distinct sections', () => {
|
|
669
|
-
const response: t.ProgrammaticExecutionResponse = {
|
|
670
|
-
status: 'completed',
|
|
671
|
-
stdout: 'analysis done\n',
|
|
672
|
-
stderr: '',
|
|
673
|
-
files: [
|
|
674
|
-
{ id: 'g1', name: 'report.pdf' },
|
|
675
|
-
{ id: 'i1', name: 'pptx/SKILL.md', inherited: true },
|
|
676
|
-
{ id: 'i2', name: 'pptx/scripts/clean.py', inherited: true },
|
|
677
|
-
{ id: 'g2', name: 'chart.png' },
|
|
678
|
-
],
|
|
679
|
-
session_id: 'sess_abc123',
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
const [output, artifact] = formatCompletedResponse(response);
|
|
683
|
-
|
|
684
|
-
/* Generated section lists only outputs the run produced. */
|
|
685
|
-
const generatedIdx = output.indexOf('Generated files:');
|
|
686
|
-
const inheritedIdx = output.indexOf('Available files (inputs');
|
|
687
|
-
expect(generatedIdx).toBeGreaterThan(-1);
|
|
688
|
-
expect(inheritedIdx).toBeGreaterThan(generatedIdx);
|
|
689
|
-
|
|
690
|
-
/* Slice each section so we can assert membership without
|
|
691
|
-
* cross-talk between the two listings. */
|
|
692
|
-
const generatedSection = output.slice(generatedIdx, inheritedIdx);
|
|
693
|
-
const inheritedSection = output.slice(inheritedIdx);
|
|
694
|
-
|
|
695
|
-
expect(generatedSection).toContain('report.pdf');
|
|
696
|
-
expect(generatedSection).toContain('chart.png');
|
|
697
|
-
expect(generatedSection).not.toContain('SKILL.md');
|
|
698
|
-
|
|
699
|
-
expect(inheritedSection).toContain('pptx/SKILL.md');
|
|
700
|
-
expect(inheritedSection).toContain('pptx/scripts/clean.py');
|
|
701
|
-
expect(inheritedSection).toContain('Available as an input');
|
|
702
|
-
|
|
703
|
-
/* The artifact still carries every file so the host can still
|
|
704
|
-
* thread per-file ids through to subsequent calls. */
|
|
705
|
-
expect(artifact.files).toHaveLength(4);
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
it('omits the Generated files header when every entry is inherited', () => {
|
|
709
|
-
const response: t.ProgrammaticExecutionResponse = {
|
|
710
|
-
status: 'completed',
|
|
711
|
-
stdout: 'cat: ok\n',
|
|
712
|
-
stderr: '',
|
|
713
|
-
files: [
|
|
714
|
-
{ id: 'i1', name: 'pptx/SKILL.md', inherited: true },
|
|
715
|
-
{ id: 'i2', name: 'pptx/editing.md', inherited: true },
|
|
716
|
-
],
|
|
717
|
-
session_id: 'sess_abc123',
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
const [output] = formatCompletedResponse(response);
|
|
721
|
-
|
|
722
|
-
expect(output).not.toContain('Generated files:');
|
|
723
|
-
expect(output).toContain('Available files (inputs');
|
|
724
|
-
expect(output).toContain('pptx/SKILL.md');
|
|
725
|
-
expect(output).toContain('pptx/editing.md');
|
|
726
|
-
});
|
|
727
667
|
});
|
|
728
668
|
|
|
729
669
|
describe('createProgrammaticToolCallingTool - Manual Invocation', () => {
|