mirror of
https://github.com/langgenius/dify.git
synced 2026-08-28 19:38:30 +08:00
fix(agent-v2): make workflow context value truncation length configurable
The Agent v2 node hard-coded a 2000-character cutoff for previous node output values embedded in the workflow context prompt, silently dropping content beyond that length. Move the limit to WORKFLOW_AGENT_V2_CONTEXT_VALUE_MAX_LENGTH (default 400000, matching TEMPLATE_TRANSFORM_MAX_LENGTH) so long outputs are no longer truncated by default and the limit can be tuned when needed. Fixes #40729
This commit is contained in:
parent
b9248690b0
commit
6676425e2f
@ -897,6 +897,14 @@ class WorkflowConfig(BaseSettings):
|
||||
default=5,
|
||||
)
|
||||
|
||||
WORKFLOW_AGENT_V2_CONTEXT_VALUE_MAX_LENGTH: PositiveInt = Field(
|
||||
description=(
|
||||
"Maximum number of characters for a previous node output value included "
|
||||
"in an Agent node's workflow context before it is truncated"
|
||||
),
|
||||
default=400_000,
|
||||
)
|
||||
|
||||
MAX_VARIABLE_SIZE: PositiveInt = Field(
|
||||
description="Maximum size in bytes for a single variable in workflows. Default to 200 KB.",
|
||||
default=200 * 1024,
|
||||
|
||||
@ -436,8 +436,9 @@ class WorkflowAgentRuntimeRequestBuilder:
|
||||
return json.dumps(prompt_payload, ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
text = str(value)
|
||||
if len(text) > 2000:
|
||||
return text[:2000] + "...[truncated]"
|
||||
max_length = dify_config.WORKFLOW_AGENT_V2_CONTEXT_VALUE_MAX_LENGTH
|
||||
if len(text) > max_length:
|
||||
return text[:max_length] + "...[truncated]"
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -1398,6 +1398,47 @@ def test_previous_node_remote_url_file_mapping_is_not_truncated_in_workflow_cont
|
||||
assert "...[truncated]" not in _workflow_user_prompt(result)
|
||||
|
||||
|
||||
def test_previous_node_long_text_output_is_not_truncated_under_default_limit():
|
||||
long_text = "a" * 2500
|
||||
|
||||
class LongTextVariablePool(FakeVariablePool):
|
||||
def get(self, selector):
|
||||
if list(selector) == ["previous-node", "text"]:
|
||||
return StringSegment(value=long_text)
|
||||
return super().get(selector)
|
||||
|
||||
context = replace(_context(), variable_pool=LongTextVariablePool())
|
||||
context.binding.node_job_config = WorkflowNodeJobConfig.model_validate(
|
||||
{
|
||||
"workflow_prompt": "Review {{#previous-node.text#}} before responding.",
|
||||
}
|
||||
)
|
||||
|
||||
result = WorkflowAgentRuntimeRequestBuilder(credentials_provider=FakeCredentialsProvider()).build(context)
|
||||
|
||||
user_prompt = _workflow_user_prompt(result)
|
||||
assert f" - previous-node.text: {long_text}" in user_prompt
|
||||
assert "...[truncated]" not in user_prompt
|
||||
|
||||
|
||||
def test_previous_node_text_output_respects_configured_max_length(monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"core.workflow.nodes.agent_v2.runtime_request_builder.dify_config.WORKFLOW_AGENT_V2_CONTEXT_VALUE_MAX_LENGTH",
|
||||
10,
|
||||
)
|
||||
context = _context()
|
||||
context.binding.node_job_config = WorkflowNodeJobConfig.model_validate(
|
||||
{
|
||||
"workflow_prompt": "Review {{#previous-node.text#}} before responding.",
|
||||
}
|
||||
)
|
||||
|
||||
result = WorkflowAgentRuntimeRequestBuilder(credentials_provider=FakeCredentialsProvider()).build(context)
|
||||
|
||||
user_prompt = _workflow_user_prompt(result)
|
||||
assert " - previous-node.text: Previous r...[truncated]" in user_prompt
|
||||
|
||||
|
||||
# ── Agent config declaration layer ────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
@ -201,6 +201,7 @@ TEMPLATE_TRANSFORM_MAX_LENGTH=400000
|
||||
WORKFLOW_MAX_EXECUTION_STEPS=500
|
||||
WORKFLOW_MAX_EXECUTION_TIME=1200
|
||||
WORKFLOW_CALL_MAX_DEPTH=5
|
||||
WORKFLOW_AGENT_V2_CONTEXT_VALUE_MAX_LENGTH=400000
|
||||
MAX_VARIABLE_SIZE=204800
|
||||
WORKFLOW_GENERATOR_NODE_BUILDER_MAX_WORKERS=6
|
||||
WORKFLOW_FILE_UPLOAD_LIMIT=10
|
||||
|
||||
Loading…
Reference in New Issue
Block a user