mirror of
https://github.com/langgenius/dify.git
synced 2026-03-26 00:38:03 +08:00
feat: add LLM quota deduction functionality and enhance model configuration handling in llm_utils.py; update test cases for LLM node context handling
This commit is contained in:
@ -22,6 +22,7 @@ from dify_graph.model_runtime.entities import (
|
||||
TextPromptMessageContent,
|
||||
ToolPromptMessage,
|
||||
)
|
||||
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
|
||||
from dify_graph.model_runtime.entities.message_entities import (
|
||||
AssistantPromptMessage,
|
||||
PromptMessageContentUnionTypes,
|
||||
@ -37,7 +38,7 @@ from dify_graph.runtime import VariablePool
|
||||
from dify_graph.variables import ArrayFileSegment, FileSegment
|
||||
from dify_graph.variables.segments import ArrayAnySegment, NoneSegment, StringSegment
|
||||
|
||||
from .entities import LLMNodeChatModelMessage, LLMNodeCompletionModelPromptTemplate
|
||||
from .entities import LLMNodeChatModelMessage, LLMNodeCompletionModelPromptTemplate, ModelConfig
|
||||
from .exc import (
|
||||
InvalidVariableTypeError,
|
||||
MemoryRolePrefixRequiredError,
|
||||
@ -47,9 +48,7 @@ from .exc import (
|
||||
from .protocols import TemplateRenderer
|
||||
|
||||
|
||||
def fetch_model_config(
|
||||
*, tenant_id: str, node_data_model: ModelConfig
|
||||
) -> tuple[ModelInstance, Any]:
|
||||
def fetch_model_config(*, tenant_id: str, node_data_model: ModelConfig) -> tuple[ModelInstance, Any]:
|
||||
from core.app.llm.model_access import build_dify_model_access
|
||||
from core.app.llm.model_access import fetch_model_config as _fetch
|
||||
|
||||
@ -61,6 +60,12 @@ def fetch_model_config(
|
||||
)
|
||||
|
||||
|
||||
def deduct_llm_quota(*, tenant_id: str, model_instance: ModelInstance, usage: LLMUsage) -> None:
|
||||
from core.app.llm.quota import deduct_llm_quota as _deduct
|
||||
|
||||
_deduct(tenant_id=tenant_id, model_instance=model_instance, usage=usage)
|
||||
|
||||
|
||||
def fetch_model_schema(*, model_instance: ModelInstance) -> AIModelEntity:
|
||||
model_schema = cast(LargeLanguageModel, model_instance.model_type_instance).get_model_schema(
|
||||
model_instance.model_name,
|
||||
|
||||
@ -35,7 +35,14 @@ def patch_deduct_llm_quota(monkeypatch):
|
||||
def _make_llm_node(reasoning_format: str) -> LLMNode:
|
||||
node = LLMNode.__new__(LLMNode)
|
||||
object.__setattr__(node, "_node_data", types.SimpleNamespace(reasoning_format=reasoning_format, tools=[]))
|
||||
object.__setattr__(node, "tenant_id", "tenant")
|
||||
object.__setattr__(
|
||||
node,
|
||||
"_run_context",
|
||||
{"_dify": types.SimpleNamespace(
|
||||
tenant_id="tenant", app_id="app", user_id="user",
|
||||
user_from="account", invoke_from="debugger",
|
||||
)},
|
||||
)
|
||||
return node
|
||||
|
||||
|
||||
|
||||
@ -799,7 +799,8 @@
|
||||
"nodes.llm.computerUse.title": "Computer Use",
|
||||
"nodes.llm.computerUse.tooltip": "Enable the model to interact with a computer desktop environment",
|
||||
"nodes.llm.context": "context",
|
||||
"nodes.llm.contextMissing": "Context is missing",
|
||||
"nodes.llm.contextBlock": "Context Block",
|
||||
"nodes.llm.contextMissing": "Context missing: {{nodeName}}",
|
||||
"nodes.llm.contextTooltip": "You can import Knowledge as context",
|
||||
"nodes.llm.contextUnknownNode": "Unknown node",
|
||||
"nodes.llm.files": "Files",
|
||||
@ -943,17 +944,22 @@
|
||||
"nodes.templateTransform.codeSupportTip": "Only supports Jinja2",
|
||||
"nodes.templateTransform.inputVars": "Input Variables",
|
||||
"nodes.templateTransform.outputVars.output": "Transformed content",
|
||||
"nodes.tool.agentPlaceholder": "Select an agent...",
|
||||
"nodes.tool.agentPlaceholder": "Enter value for {{paramKey}}...",
|
||||
"nodes.tool.agentPopupHeader": "Select Agent",
|
||||
"nodes.tool.assembleVariables": "Assemble Variables",
|
||||
"nodes.tool.authorizationRequired": "Authorization required",
|
||||
"nodes.tool.authorize": "Authorize",
|
||||
"nodes.tool.contextGenerate.apply": "Apply",
|
||||
"nodes.tool.contextGenerate.code": "Code",
|
||||
"nodes.tool.contextGenerate.codeBlock": "Code Block",
|
||||
"nodes.tool.contextGenerate.codeLanguage.javascript": "JavaScript",
|
||||
"nodes.tool.contextGenerate.codeLanguage.python3": "Python 3",
|
||||
"nodes.tool.contextGenerate.defaultAssistantMessage": "I'll help you generate the context code.",
|
||||
"nodes.tool.contextGenerate.generatedCode": "Generated Code",
|
||||
"nodes.tool.contextGenerate.generating": "Generating...",
|
||||
"nodes.tool.contextGenerate.initPlaceholder": "Describe what you want to generate...",
|
||||
"nodes.tool.contextGenerate.inputPlaceholder": "Type your message...",
|
||||
"nodes.tool.contextGenerate.instruction": "Instruction",
|
||||
"nodes.tool.contextGenerate.output": "Output",
|
||||
"nodes.tool.contextGenerate.resizeHandle": "Resize",
|
||||
"nodes.tool.contextGenerate.rightSidePlaceholder": "Generated content will appear here",
|
||||
@ -1173,6 +1179,7 @@
|
||||
"panel.scrollToSelectedNode": "Scroll to selected node",
|
||||
"panel.selectNextStep": "Select Next Step",
|
||||
"panel.startNode": "Start Node",
|
||||
"panel.ungroup": "Ungroup",
|
||||
"panel.userInputField": "User Input Field",
|
||||
"publishLimit.startNodeDesc": "You’ve reached the limit of 2 triggers per workflow for this plan. Upgrade to publish this workflow.",
|
||||
"publishLimit.startNodeTitlePrefix": "Upgrade to",
|
||||
@ -1193,7 +1200,7 @@
|
||||
"singleRun.reRun": "Re-run",
|
||||
"singleRun.running": "Running",
|
||||
"singleRun.startRun": "Start Run",
|
||||
"singleRun.subgraph.nullOutputError": "Subgraph returned null output",
|
||||
"singleRun.subgraph.nullOutputError": "Sub-graph returned null for output: {{output}}",
|
||||
"singleRun.testRun": "Test Run",
|
||||
"singleRun.testRunIteration": "Test Run Iteration",
|
||||
"singleRun.testRunLoop": "Test Run Loop",
|
||||
@ -1238,7 +1245,7 @@
|
||||
"skillEditor.previewUnavailable": "Preview unavailable",
|
||||
"skillEditor.referenceFiles": "Reference Files",
|
||||
"skillEditor.toolMissing": "Tool Missing",
|
||||
"skillEditor.toolMissingDesc": "The referenced tool is missing or has been removed",
|
||||
"skillEditor.toolMissingDesc": "The referenced tool is missing. Go to <Plugins>Plugins</Plugins> to install it.",
|
||||
"skillEditor.unsupportedPreview": "Unsupported file type for preview",
|
||||
"skillEditor.uploadFiles": "Upload Files",
|
||||
"skillEditor.uploadIn": "Upload in",
|
||||
@ -1306,16 +1313,22 @@
|
||||
"skillSidebar.uploadSuccess": "Upload successful",
|
||||
"skillSidebar.uploadSuccessDetail": "{{count}} files uploaded",
|
||||
"skillSidebar.uploadingItems": "Uploading {{count}} items...",
|
||||
"subGraphModal.canvasPlaceholder": "Select a node to view its details",
|
||||
"subGraphModal.defaultValueHint": "Default value will be used when output is null",
|
||||
"subGraphModal.internalStructure": "Internal Structure",
|
||||
"subGraphModal.internalStructureDesc": "View the internal workflow structure of this sub-graph",
|
||||
"subGraphModal.internalStructureDesc": "View the internal workflow structure of {{name}}",
|
||||
"subGraphModal.lastRun": "Last Run",
|
||||
"subGraphModal.noRunHistory": "No run history",
|
||||
"subGraphModal.outputVariables": "Output Variables",
|
||||
"subGraphModal.settings": "Settings",
|
||||
"subGraphModal.sourceNode": "Source Node",
|
||||
"subGraphModal.title": "Sub-Graph Details",
|
||||
"subGraphModal.whenOutputIsNone": "When Output is None",
|
||||
"subGraphModal.whenOutputNone.default": "Use Default",
|
||||
"subGraphModal.whenOutputNone.defaultDesc": "Use a default value when sub-graph output is null",
|
||||
"subGraphModal.whenOutputNone.error": "Throw Error",
|
||||
"subGraphModal.whenOutputNone.errorDesc": "Throw an error when sub-graph output is null",
|
||||
"subGraphModal.whenOutputNone.skip": "Skip",
|
||||
"tabs.-": "Default",
|
||||
"tabs.addAll": "Add all",
|
||||
"tabs.agent": "Agent Strategy",
|
||||
@ -1350,7 +1363,7 @@
|
||||
"tabs.usePlugin": "Select tool",
|
||||
"tabs.utilities": "Utilities",
|
||||
"tabs.workflowTool": "Workflow",
|
||||
"toolGroup.actionsEnabled": "{{count}} actions enabled",
|
||||
"toolGroup.actionsEnabled": "{{num}} actions enabled",
|
||||
"toolGroup.byAuthor": "By {{author}}",
|
||||
"tracing.stopBy": "Stop by {{user}}",
|
||||
"triggerStatus.disabled": "TRIGGER • DISABLED",
|
||||
@ -1364,7 +1377,7 @@
|
||||
"versionHistory.action.deleteFailure": "Failed to delete version",
|
||||
"versionHistory.action.deleteSuccess": "Version deleted",
|
||||
"versionHistory.action.restoreFailure": "Failed to restore version",
|
||||
"versionHistory.action.restoreInProgress": "Restoring...",
|
||||
"versionHistory.action.restoreInProgress": "{{userName}} is restoring version {{versionName}}...",
|
||||
"versionHistory.action.restoreSuccess": "Version restored",
|
||||
"versionHistory.action.updateFailure": "Failed to update version",
|
||||
"versionHistory.action.updateSuccess": "Version updated",
|
||||
|
||||
@ -799,7 +799,8 @@
|
||||
"nodes.llm.computerUse.title": "计算机操作",
|
||||
"nodes.llm.computerUse.tooltip": "允许模型与计算机桌面环境交互",
|
||||
"nodes.llm.context": "上下文",
|
||||
"nodes.llm.contextMissing": "缺少上下文",
|
||||
"nodes.llm.contextBlock": "上下文块",
|
||||
"nodes.llm.contextMissing": "缺少上下文:{{nodeName}}",
|
||||
"nodes.llm.contextTooltip": "您可以导入知识库作为上下文",
|
||||
"nodes.llm.contextUnknownNode": "未知节点",
|
||||
"nodes.llm.files": "文件",
|
||||
@ -943,17 +944,22 @@
|
||||
"nodes.templateTransform.codeSupportTip": "只支持 Jinja2",
|
||||
"nodes.templateTransform.inputVars": "输入变量",
|
||||
"nodes.templateTransform.outputVars.output": "转换后内容",
|
||||
"nodes.tool.agentPlaceholder": "选择 Agent...",
|
||||
"nodes.tool.agentPlaceholder": "输入 {{paramKey}} 的值...",
|
||||
"nodes.tool.agentPopupHeader": "选择 Agent",
|
||||
"nodes.tool.assembleVariables": "组装变量",
|
||||
"nodes.tool.authorizationRequired": "需要授权",
|
||||
"nodes.tool.authorize": "授权",
|
||||
"nodes.tool.contextGenerate.apply": "应用",
|
||||
"nodes.tool.contextGenerate.code": "代码",
|
||||
"nodes.tool.contextGenerate.codeBlock": "代码块",
|
||||
"nodes.tool.contextGenerate.codeLanguage.javascript": "JavaScript",
|
||||
"nodes.tool.contextGenerate.codeLanguage.python3": "Python 3",
|
||||
"nodes.tool.contextGenerate.defaultAssistantMessage": "我将帮你生成上下文代码。",
|
||||
"nodes.tool.contextGenerate.generatedCode": "生成的代码",
|
||||
"nodes.tool.contextGenerate.generating": "生成中...",
|
||||
"nodes.tool.contextGenerate.initPlaceholder": "描述你想要生成的内容...",
|
||||
"nodes.tool.contextGenerate.inputPlaceholder": "输入消息...",
|
||||
"nodes.tool.contextGenerate.instruction": "指令",
|
||||
"nodes.tool.contextGenerate.output": "输出",
|
||||
"nodes.tool.contextGenerate.resizeHandle": "调整大小",
|
||||
"nodes.tool.contextGenerate.rightSidePlaceholder": "生成的内容将显示在这里",
|
||||
@ -1173,6 +1179,7 @@
|
||||
"panel.scrollToSelectedNode": "滚动至选中节点",
|
||||
"panel.selectNextStep": "选择下一个节点",
|
||||
"panel.startNode": "开始节点",
|
||||
"panel.ungroup": "取消分组",
|
||||
"panel.userInputField": "用户输入字段",
|
||||
"publishLimit.startNodeDesc": "您已达到此计划上每个工作流最多 2 个触发器的限制。请升级后再发布此工作流。",
|
||||
"publishLimit.startNodeTitlePrefix": "升级以",
|
||||
@ -1193,7 +1200,7 @@
|
||||
"singleRun.reRun": "重新运行",
|
||||
"singleRun.running": "运行中",
|
||||
"singleRun.startRun": "开始运行",
|
||||
"singleRun.subgraph.nullOutputError": "子图返回了空输出",
|
||||
"singleRun.subgraph.nullOutputError": "子图的输出 {{output}} 返回了空值",
|
||||
"singleRun.testRun": "测试运行",
|
||||
"singleRun.testRunIteration": "测试运行迭代",
|
||||
"singleRun.testRunLoop": "测试运行循环",
|
||||
@ -1238,7 +1245,7 @@
|
||||
"skillEditor.previewUnavailable": "预览不可用",
|
||||
"skillEditor.referenceFiles": "引用文件",
|
||||
"skillEditor.toolMissing": "工具缺失",
|
||||
"skillEditor.toolMissingDesc": "引用的工具缺失或已被移除",
|
||||
"skillEditor.toolMissingDesc": "引用的工具缺失或已被移除。前往<Plugins>插件</Plugins>安装。",
|
||||
"skillEditor.unsupportedPreview": "不支持预览的文件类型",
|
||||
"skillEditor.uploadFiles": "上传文件",
|
||||
"skillEditor.uploadIn": "上传至",
|
||||
@ -1306,16 +1313,22 @@
|
||||
"skillSidebar.uploadSuccess": "上传成功",
|
||||
"skillSidebar.uploadSuccessDetail": "已上传 {{count}} 个文件",
|
||||
"skillSidebar.uploadingItems": "正在上传 {{count}} 个项目...",
|
||||
"subGraphModal.canvasPlaceholder": "选择一个节点以查看其详情",
|
||||
"subGraphModal.defaultValueHint": "输出为空时将使用默认值",
|
||||
"subGraphModal.internalStructure": "内部结构",
|
||||
"subGraphModal.internalStructureDesc": "查看此子图的内部工作流结构",
|
||||
"subGraphModal.internalStructureDesc": "查看 {{name}} 的内部工作流结构",
|
||||
"subGraphModal.lastRun": "上次运行",
|
||||
"subGraphModal.noRunHistory": "暂无运行历史",
|
||||
"subGraphModal.outputVariables": "输出变量",
|
||||
"subGraphModal.settings": "设置",
|
||||
"subGraphModal.sourceNode": "源节点",
|
||||
"subGraphModal.title": "子图详情",
|
||||
"subGraphModal.whenOutputIsNone": "当输出为空时",
|
||||
"subGraphModal.whenOutputNone.default": "使用默认值",
|
||||
"subGraphModal.whenOutputNone.defaultDesc": "当子图输出为空时使用默认值",
|
||||
"subGraphModal.whenOutputNone.error": "抛出错误",
|
||||
"subGraphModal.whenOutputNone.errorDesc": "当子图输出为空时抛出错误",
|
||||
"subGraphModal.whenOutputNone.skip": "跳过",
|
||||
"tabs.-": "默认",
|
||||
"tabs.addAll": "添加全部",
|
||||
"tabs.agent": "Agent 策略",
|
||||
@ -1350,7 +1363,7 @@
|
||||
"tabs.usePlugin": "选择工具",
|
||||
"tabs.utilities": "工具",
|
||||
"tabs.workflowTool": "工作流",
|
||||
"toolGroup.actionsEnabled": "已启用 {{count}} 个操作",
|
||||
"toolGroup.actionsEnabled": "已启用 {{num}} 个操作",
|
||||
"toolGroup.byAuthor": "作者 {{author}}",
|
||||
"tracing.stopBy": "由{{user}}终止",
|
||||
"triggerStatus.disabled": "触发器 • 已禁用",
|
||||
@ -1364,7 +1377,7 @@
|
||||
"versionHistory.action.deleteFailure": "删除失败",
|
||||
"versionHistory.action.deleteSuccess": "版本已删除",
|
||||
"versionHistory.action.restoreFailure": "回滚失败",
|
||||
"versionHistory.action.restoreInProgress": "恢复中...",
|
||||
"versionHistory.action.restoreInProgress": "{{userName}} 正在恢复版本 {{versionName}}...",
|
||||
"versionHistory.action.restoreSuccess": "回滚成功",
|
||||
"versionHistory.action.updateFailure": "更新失败",
|
||||
"versionHistory.action.updateSuccess": "版本信息已更新",
|
||||
|
||||
Reference in New Issue
Block a user