feat(api): pass app_id to model plugins for provider-side cost attribution#35859
Conversation
Pyrefly Diffbase → PR--- /tmp/pyrefly_base.txt 2026-07-06 08:41:05.066004883 +0000
+++ /tmp/pyrefly_pr.txt 2026-07-06 08:40:52.730022451 +0000
@@ -2521,79 +2521,81 @@
ERROR Class member `DummyRunner._organize_prompt_messages` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
--> tests/unit_tests/core/agent/test_cot_agent_runner.py:24:9
ERROR `None` is not assignable to attribute `agent_callback` with type `DifyAgentCallbackHandler` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:80:29
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:81:29
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:83:5
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:84:5
ERROR Missing required key `action` for TypedDict `ActionDict` [bad-typed-dict-key]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:113:44
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:114:44
ERROR Missing required key `action_input` for TypedDict `ActionDict` [bad-typed-dict-key]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:113:44
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:114:44
ERROR Key `invalid` is not defined in TypedDict `ActionDict` [bad-typed-dict-key]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:113:45
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:114:45
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:167:55
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:168:55
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:180:55
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:181:55
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:204:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:205:35
ERROR `None` is not assignable to attribute `agent_callback` with type `DifyAgentCallbackHandler` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:223:33
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:224:33
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:226:29
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:227:29
ERROR Object of class `NoneType` has no attribute `max_iteration` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:229:9
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:230:9
ERROR `None` is not assignable to attribute `agent_callback` with type `DifyAgentCallbackHandler` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:245:33
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:246:33
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:248:29
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:249:29
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:259:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:260:35
ERROR Object of class `NoneType` has no attribute `max_iteration` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:263:9
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:264:9
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:275:29
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:276:29
ERROR Object of class `NoneType` has no attribute `max_iteration` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:280:9
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:281:9
ERROR `Literal[1]` is not assignable to attribute `prompt_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:286:32
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:287:32
ERROR `Literal[1]` is not assignable to attribute `completion_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:287:36
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:288:36
ERROR `Literal[2]` is not assignable to attribute `total_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:288:31
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:289:31
ERROR `Literal[1]` is not assignable to attribute `prompt_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:294:32
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:295:32
ERROR `Literal[1]` is not assignable to attribute `completion_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:295:36
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:296:36
ERROR `Literal[2]` is not assignable to attribute `total_price` with type `Decimal` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:296:31
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:297:31
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:324:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:325:35
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:343:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:344:35
+ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:345:16
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:357:25
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:359:25
ERROR Object of class `NoneType` has no attribute `max_iteration` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:377:9
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:379:9
ERROR `None` is not assignable to attribute `agent_callback` with type `DifyAgentCallbackHandler` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:385:33
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:387:33
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:387:25
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:389:25
ERROR `list[str]` is not assignable to attribute `_agent_scratchpad` with type `list[AgentScratchpadUnit]` [bad-assignment]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:417:36
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:419:36
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:439:55
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:441:55
ERROR Object of class `FunctionType` has no attribute `assert_called` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:443:9
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:445:9
ERROR Class member `BadValue.__str__` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:453:17
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:455:17
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:509:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:511:35
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:523:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:525:35
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:537:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:539:35
ERROR Object of class `DummyRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_cot_agent_runner.py:552:35
+ --> tests/unit_tests/core/agent/test_cot_agent_runner.py:554:35
ERROR `list[DummyTool]` is not assignable to attribute `_prompt_messages_tools` with type `Sequence[PromptMessageTool]` [bad-assignment]
--> tests/unit_tests/core/agent/test_cot_chat_agent_runner.py:49:37
ERROR `DummyGenerateEntity` is not assignable to attribute `application_generate_entity` with type `AgentChatAppGenerateEntity` [bad-assignment]
@@ -2617,53 +2619,55 @@
ERROR `Literal[0]` is not assignable to attribute `total_price` with type `Decimal` [bad-assignment]
--> tests/unit_tests/core/agent/test_fc_agent_runner.py:32:25
ERROR Missing argument `session` in function `core.agent.base_agent_runner.BaseAgentRunner.__init__` [missing-argument]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:102:37
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:103:37
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:133:5
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:134:5
ERROR Argument `DummyChunk` is not assignable to parameter `llm_result_chunk` with type `LLMResultChunk` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner.check_tool_calls` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:153:40
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:154:40
ERROR Argument `DummyResult` is not assignable to parameter `llm_result` with type `LLMResult` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner.check_blocking_tool_calls` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:158:49
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:159:49
ERROR Argument `DummyChunk` is not assignable to parameter `llm_result_chunk` with type `LLMResultChunk` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner.extract_tool_calls` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:174:43
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:175:43
ERROR Argument `DummyChunk` is not assignable to parameter `llm_result_chunk` with type `LLMResultChunk` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner.extract_tool_calls` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:185:43
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:186:43
ERROR Argument `DummyResult` is not assignable to parameter `llm_result` with type `LLMResult` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner.extract_blocking_tool_calls` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:196:52
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:197:52
ERROR Argument `None` is not assignable to parameter `query` with type `str` in function `core.agent.fc_agent_runner.FunctionCallAgentRunner._organize_user_query` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:232:46
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:233:46
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:300:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:301:35
+ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:303:16
ERROR Object of class `FunctionType` has no attribute `assert_called` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:302:9
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:304:9
ERROR Object of class `FunctionType` has no attribute `call_args_list` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:304:23
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:306:23
ERROR Argument `list[TextPromptMessageContent]` is not assignable to parameter `content` with type `str | None` in function `DummyMessage.__init__` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:312:57
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:314:57
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:319:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:321:35
ERROR Argument `list[TextPromptMessageContent]` is not assignable to parameter `content` with type `str | None` in function `DummyMessage.__init__` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:332:57
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:334:57
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:342:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:344:35
ERROR Argument `list[TextPromptMessageContent]` is not assignable to parameter `content` with type `str | None` in function `DummyMessage.__init__` [bad-argument-type]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:348:46
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:350:46
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:353:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:355:35
ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:355:16
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:357:16
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:382:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:384:35
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:400:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:402:35
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:429:35
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:431:35
ERROR Object of class `FunctionType` has no attribute `call_args_list` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:435:25
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:437:25
ERROR Object of class `NoneType` has no attribute `max_iteration` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:439:9
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:441:9
ERROR Object of class `FunctionCallAgentRunner` has no attribute `session` [missing-attribute]
- --> tests/unit_tests/core/agent/test_fc_agent_runner.py:454:29
+ --> tests/unit_tests/core/agent/test_fc_agent_runner.py:456:29
ERROR Missing argument `description` in function `core.agent.plugin_entities.AgentStrategyEntity.__init__` [missing-argument]
--> tests/unit_tests/core/agent/test_plugin_entities.py:281:32
ERROR Invalid key for TypedDict `AppParametersDict`, got `Unknown` [bad-typed-dict-key]
@@ -4571,33 +4575,33 @@
ERROR Argument `None` is not assignable to parameter `project` with type `str` in function `core.ops.utils.validate_project_name` [bad-argument-type]
--> tests/unit_tests/core/ops/test_utils.py:136:40
ERROR Missing required key `content` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:452:19
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:19
ERROR Missing required key `content_type` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:452:19
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:19
ERROR Key `type` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:452:20
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:20
ERROR Key `value` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:452:36
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:36
ERROR Missing required key `content` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:453:19
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:19
ERROR Missing required key `content_type` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:453:19
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:19
ERROR Key `type` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:453:20
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:20
ERROR Key `value` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:453:37
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:37
ERROR Missing required key `content` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:17
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:492:17
ERROR Missing required key `content_type` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:17
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:492:17
ERROR Key `type` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:472:18
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:492:18
ERROR Missing required key `content` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:18
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:493:18
ERROR Missing required key `content_type` for TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:18
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:493:18
ERROR Key `type` is not defined in TypedDict `MultimodalRerankInput` [bad-typed-dict-key]
- --> tests/unit_tests/core/plugin/impl/test_model_client.py:473:19
+ --> tests/unit_tests/core/plugin/impl/test_model_client.py:493:19
ERROR Argument `werkzeug.wrappers.request.Request` is not assignable to parameter `request` with type `flask.wrappers.Request` in function `core.plugin.impl.trigger.PluginTriggerClient.invoke_trigger_event` [bad-argument-type]
--> tests/unit_tests/core/plugin/impl/test_trigger_client.py:127:21
ERROR Argument `werkzeug.wrappers.request.Request` is not assignable to parameter `request` with type `flask.wrappers.Request` in function `core.plugin.impl.trigger.PluginTriggerClient.invoke_trigger_event` [bad-argument-type]
@@ -6581,15 +6585,15 @@
ERROR `SimpleNamespace` is not assignable to attribute `_dify_context` with type `DifyRunContext` [bad-assignment]
--> tests/unit_tests/core/workflow/test_node_factory.py:487:33
ERROR Argument `SimpleNamespace` is not assignable to parameter `node_data` with type `LLMNodeData | ParameterExtractorNodeData | QuestionClassifierNodeData` in function `core.workflow.node_factory.DifyNodeFactory._wrap_model_instance_for_node` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_factory.py:780:23
+ --> tests/unit_tests/core/workflow/test_node_factory.py:781:23
ERROR Argument `_ModelInstanceStub` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_factory.DifyNodeFactory._wrap_model_instance_for_node` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_factory.py:781:28
+ --> tests/unit_tests/core/workflow/test_node_factory.py:782:28
ERROR `SimpleNamespace` is not assignable to attribute `graph_runtime_state` with type `GraphRuntimeState` [bad-assignment]
- --> tests/unit_tests/core/workflow/test_node_factory.py:998:39
+ --> tests/unit_tests/core/workflow/test_node_factory.py:999:39
ERROR `SimpleNamespace` is not assignable to attribute `_dify_context` with type `DifyRunContext` [bad-assignment]
- --> tests/unit_tests/core/workflow/test_node_factory.py:1128:33
+ --> tests/unit_tests/core/workflow/test_node_factory.py:1129:33
ERROR `SimpleNamespace` is not assignable to attribute `graph_runtime_state` with type `GraphRuntimeState` [bad-assignment]
- --> tests/unit_tests/core/workflow/test_node_factory.py:1129:39
+ --> tests/unit_tests/core/workflow/test_node_factory.py:1130:39
ERROR `object | None` is not assignable to attribute `model_runtime` with type `LLMModelRuntime` [bad-assignment]
--> tests/unit_tests/core/workflow/test_node_runtime.py:68:30
ERROR Class member `_ModelTypeInstanceStub.get_model_schema` overrides parent class `LargeLanguageModel` in an inconsistent manner [bad-override-param-name]
@@ -6603,41 +6607,41 @@
ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
--> tests/unit_tests/core/workflow/test_node_runtime.py:193:5
ERROR Argument `_ModelInstanceStub` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_runtime.DifyPreparedLLM.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:206:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:207:32
ERROR Argument `_ModelInstanceStub` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_runtime.DifyPreparedLLM.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:214:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:215:32
ERROR Argument `SimpleNamespace` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_runtime.DifyPreparedLLM.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:240:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:241:32
ERROR Argument `_ModelInstanceStub` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_runtime.DifyPreparedPollingLLM.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:265:39
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:266:39
ERROR Argument `_ModelInstanceStub` is not assignable to parameter `model_instance` with type `ModelInstance` in function `core.workflow.node_runtime.DifyPreparedPollingLLM.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:322:39
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:323:39
ERROR Argument `Literal['chat']` is not assignable to parameter `model_mode` with type `LLMMode` in function `core.workflow.node_runtime.DifyPromptMessageSerializer.serialize` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:339:20
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:340:20
ERROR Argument `SimpleNamespace` is not assignable to parameter `file_reference_factory` with type `FileReferenceFactoryProtocol` in function `core.workflow.node_runtime.DifyRetrieverAttachmentLoader.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:374:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:375:32
ERROR Object of class `NoneType` has no attribute `storage_key` [missing-attribute]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:385:12
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:386:12
ERROR Argument `SimpleNamespace` is not assignable to parameter `file_reference_factory` with type `FileReferenceFactoryProtocol` in function `core.workflow.node_runtime.DifyRetrieverAttachmentLoader.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:450:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:451:32
ERROR Argument `SimpleNamespace` is not assignable to parameter `file_reference_factory` with type `FileReferenceFactoryProtocol` in function `core.workflow.node_runtime.DifyRetrieverAttachmentLoader.__init__` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:476:32
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:477:32
ERROR Argument `object` is not assignable to parameter `variable_pool` with type `VariablePool | None` in function `core.workflow.node_runtime.DifyToolNodeRuntime.get_runtime` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:574:23
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:575:23
ERROR Object of class `object` has no attribute `tool` [missing-attribute]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:578:12
-ERROR Object of class `object` has no attribute `parent_trace_context` [missing-attribute]
--> tests/unit_tests/core/workflow/test_node_runtime.py:579:12
+ERROR Object of class `object` has no attribute `parent_trace_context` [missing-attribute]
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:580:12
ERROR Object of class `object` has no attribute `trace_session_id` [missing-attribute]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:602:5
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:603:5
ERROR Argument `object` is not assignable to parameter `variable_pool` with type `VariablePool | None` in function `core.workflow.node_runtime.DifyToolNodeRuntime.get_runtime` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:619:23
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:620:23
ERROR Object of class `object` has no attribute `trace_session_id` [missing-attribute]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:623:12
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:624:12
ERROR Argument `object` is not assignable to parameter `variable_pool` with type `VariablePool | None` in function `core.workflow.node_runtime.DifyToolNodeRuntime.get_runtime` [bad-argument-type]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:651:23
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:652:23
ERROR Object of class `object` has no attribute `tool` [missing-attribute]
- --> tests/unit_tests/core/workflow/test_node_runtime.py:654:12
+ --> tests/unit_tests/core/workflow/test_node_runtime.py:655:12
ERROR Argument `TestWorkflowEntry.test_single_step_run_injects_code_limits.StubWorkflow` is not assignable to parameter `workflow` with type `Workflow` in function `core.workflow.workflow_entry.WorkflowEntry.single_step_run` [bad-argument-type]
--> tests/unit_tests/core/workflow/test_workflow_entry.py:145:22
ERROR Object of class `_FakeModelNodeMixin` has no attribute `node_data` [missing-attribute]
|
WH-2099
left a comment
There was a problem hiding this comment.
Thanks for the contribution. However, I think using Context for implicit prop drilling here might impose a certain burden on future state management and maintainability.
I would prefer to use an explicit prop-passing (explicit parameter) approach instead.
|
Thanks @WH-2099 — agreed, and I'd like to move toward explicit passing on the host side rather than defend the ContextVar approach. Let me confirm the plan and one design choice with you. Where app_id has to travel (host side): The two middle hops live in the external Proposed approach (my recommendation):
Why not constructor injection (the way SDK side (dify-plugin-sdks#313) is the one place I'd keep ContextVar. There One thing I need your call on: are you OK with a companion PR against |
|
@ryuta-kobayashi-ug Thanks for the detailed breakdown. I completely agree with your rationale. Threading an context object is indeed the cleanest, most extensible design here, and keeping the SDK side backward-compatible via ContextVar makes perfect sense. Let's go with your proposed approach. Modifying graphon to achieve the ideal implementation is definitely the right move. Please go ahead and open the companion PR against langgenius/graphon alongside your reworked PR here. I'll follow up and keep an eye on both. Looking forward to your PRs! |
|
@ryuta-kobayashi-ug Hi, I haven't seen any new progress on this task yet. To avoid duplicating our efforts, I wanted to check if you're still working on it. If you haven't started yet, I'm happy to take over from here and finish the rest. |
|
@WH-2099 Thanks for the go-ahead, and sorry for the quiet stretch on my end — yes, I'm still on it and starting today. Plan for the next push:
I'll link the graphon PR here as soon as it's up so you can track both together. Thanks for your patience, and for offering to take it on. |
|
@WH-2099 Quick update: the graphon companion PR is up — langgenius/graphon#191. It threads the existing Next I'll rework this PR on top of it: drop the ContextVar bridge and pass I'll push the reworked branch here once I've extended coverage to the agent and workflow call sites (not just chat/completion), and will bump the graphon pin once #191 is released. Thanks! |
|
@WH-2099 Thanks for merging langgenius/graphon#191 (and for renaming the parameter to The Dify-side rework is ready on my end: ContextVar bridge removed, and One sequencing question before I push, though: What's the plan for moving Dify to graphon 0.6.0? Is a migration already in progress (so I can rebase this PR on top once it lands), or would you prefer I hold until then? Happy to follow whichever path you prefer — I just don't want to bundle an unrelated 0.6.0 migration into this PR. |
|
Thanks for the work so far. I will take over the remaining work on this PR and rework it according to the agreed direction. I will keep the change focused and follow up with updates once it is ready for review. |
8459051 to
a07788c
Compare
Pyrefly Type Coverage
|
f3084a7 to
fa022d6
Compare
|
Thanks @WH-2099 for taking this over the finish line and for the reworks — great to see it land on |
|
@ryuta-kobayashi-ug I apologize that the implementation of this feature may have taken a little longer than expected, but I believe the final implementation here is a more robust version for future maintenance and long-term evolution. Thank you for your patience and contribution. There's a minor follow-up issue: the new support has been merged into the dify-plugin-sdk mainline (langgenius/dify-plugin-sdks#313). |
|
@WH-2099 Thank you again, and no worries at all about the timeline — I fully agree the final design is more robust and well worth the extra iterations. On the release question: if it's feasible on your side, I'd gently advocate for releasing That said, I don't want to rush anything — if it's cleaner to fold this into your normal release cadence, that's completely fine by me. And I'm glad to help with the |
Fixes #35772
Summary
Pass
app_idto model plugins so they can tag LLM requests with the originating Dify app for provider-side cost attribution (e.g., BedrockrequestMetadata, OpenAImetadata, Vertex AIlabels).Changes
app_context.pywithContextVar-basedget_current_app_id()/set_current_app_id()app_idin all app runners (chat, completion, agent_chat, advanced_chat, workflow) before LLM invocationPluginModelRuntime.invoke_llm()readsget_current_app_id()and passes it toPluginModelClientPluginModelClientincludesapp_idin the HTTP payload to plugin daemonapp_idisNonewhen called outside app context (RAG routing, title generation, etc.)Design
Uses
contextvars.ContextVarbecausePluginModelRuntimeis created at tenant scope (before app execution), and graphon sits between the app runner andPluginModelRuntimewith a fixed interface that cannot passapp_idas an argument.Testing
_dispatch_payloadwith/withoutapp_idapp_idcorrectlyChecklist