dify-player 0.3.4__tar.gz → 0.3.6__tar.gz
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.
- {dify_player-0.3.4 → dify_player-0.3.6}/PKG-INFO +1 -1
- {dify_player-0.3.4 → dify_player-0.3.6}/README.md +29 -3
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/__init__.py +1 -1
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/__init__.py +12 -7
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/llm_azure_chat.py +23 -11
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/llm_groq_chat.py +21 -13
- dify_player-0.3.6/dify_player/provider_config.py +38 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/runtime.py +38 -1
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/workflow_engine.py +7 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/workflow_executor.py +7 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player.egg-info/PKG-INFO +1 -1
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player.egg-info/SOURCES.txt +1 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/pyproject.toml +1 -1
- {dify_player-0.3.4 → dify_player-0.3.6}/MANIFEST.in +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/__main__.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/cli.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/__init__.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/graph_parser.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/http_body_converter.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/__init__.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/assigner.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/code.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/end.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/http_request.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/if_else.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/llm.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/loop.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/start.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/template_transform.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/variable_aggregator.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/plan_serializer.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/reference_converter.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/workflow_loader.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/workflow_normalizer.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_workflow_importer.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/event_logger.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/exceptions.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/input_resolver.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/llm_cache.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/models.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/assigner.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/code.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/end.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/http.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/if_else.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/llm_xai_chat.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/start.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/template.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/nodes/variable_aggregator.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/plan_loader.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player/value_renderer.py +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player.egg-info/dependency_links.txt +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player.egg-info/requires.txt +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/dify_player.egg-info/top_level.txt +0 -0
- {dify_player-0.3.4 → dify_player-0.3.6}/setup.cfg +0 -0
|
@@ -87,9 +87,9 @@ async def run_workflow(payload: dict) -> dict:
|
|
|
87
87
|
|
|
88
88
|
`WorkflowEngine` には次の async API があります。
|
|
89
89
|
|
|
90
|
-
- `await engine.run_plan_data(plan_data=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None)`
|
|
91
|
-
- `await engine.run_plan(plan=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None)`
|
|
92
|
-
- `await engine.run_compiled_plan(compiled_plan=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None)`
|
|
90
|
+
- `await engine.run_plan_data(plan_data=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None, provider_config=None)`
|
|
91
|
+
- `await engine.run_plan(plan=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None, provider_config=None)`
|
|
92
|
+
- `await engine.run_compiled_plan(compiled_plan=..., inputs=..., run_id=None, logger=None, http_client=None, llm_cache=False, llm_cache_store=None, provider_config=None)`
|
|
93
93
|
|
|
94
94
|
使い分けは次のとおりです。
|
|
95
95
|
|
|
@@ -97,6 +97,32 @@ async def run_workflow(payload: dict) -> dict:
|
|
|
97
97
|
- `run_plan`: すでに `Plan` オブジェクトを組み立てている内部利用向け
|
|
98
98
|
- `run_compiled_plan`: 同じ plan を何度も実行する用途向け
|
|
99
99
|
|
|
100
|
+
### Provider Config
|
|
101
|
+
|
|
102
|
+
Azure OpenAI と Groq の接続設定は、実行単位で `provider_config` として渡せます。
|
|
103
|
+
優先順位は `provider_config`、`DIFY_PLAYER_*` 環境変数、既存互換の環境変数の順です。
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
result = await engine.run_compiled_plan(
|
|
107
|
+
compiled_plan=compiled_plan,
|
|
108
|
+
inputs=inputs,
|
|
109
|
+
provider_config={
|
|
110
|
+
"azure_openai_endpoint": "https://example.openai.azure.com",
|
|
111
|
+
"azure_openai_api_key": "...",
|
|
112
|
+
"azure_openai_api_version": "2024-10-21",
|
|
113
|
+
"groq_api_key": "...",
|
|
114
|
+
"groq_api_base_url": "https://api.groq.com/openai/v1",
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
対応する env fallback は次のとおりです。
|
|
120
|
+
|
|
121
|
+
- Azure OpenAI: `DIFY_PLAYER_AZURE_OPENAI_ENDPOINT`, `DIFY_PLAYER_AZURE_OPENAI_API_KEY`, `DIFY_PLAYER_AZURE_OPENAI_API_VERSION`
|
|
122
|
+
- Azure OpenAI 既存互換: `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_API_VERSION`
|
|
123
|
+
- Groq: `DIFY_PLAYER_GROQ_API_KEY`, `DIFY_PLAYER_GROQ_API_BASE_URL`
|
|
124
|
+
- Groq 既存互換: `GROQ_API_KEY`, `GROQ_API_BASE_URL`
|
|
125
|
+
|
|
100
126
|
### LLM Cache Mode
|
|
101
127
|
|
|
102
128
|
workflow 改善中だけ LLM 応答を再利用したい場合は、`llm_cache=True` と cache store を渡します。
|
|
@@ -6,6 +6,7 @@ from typing import Any
|
|
|
6
6
|
import httpx
|
|
7
7
|
from dify_player.exceptions import UnsupportedNodeError
|
|
8
8
|
from dify_player.models import Node
|
|
9
|
+
from dify_player.provider_config import ProviderConfig
|
|
9
10
|
|
|
10
11
|
from dify_player.nodes.assigner import run as run_assigner
|
|
11
12
|
from dify_player.nodes.code import run as run_code
|
|
@@ -43,14 +44,18 @@ async def run_node(
|
|
|
43
44
|
node_outputs: dict[str, dict[str, Any]],
|
|
44
45
|
resolved_inputs: dict[str, Any],
|
|
45
46
|
http_client: httpx.AsyncClient | None = None,
|
|
47
|
+
provider_config: ProviderConfig | None = None,
|
|
46
48
|
) -> dict[str, Any]:
|
|
47
49
|
executor = _EXECUTORS.get(node.kind)
|
|
48
50
|
if executor is None:
|
|
49
51
|
raise UnsupportedNodeError(f"unsupported node kind {node.kind!r}")
|
|
50
|
-
|
|
51
|
-
node
|
|
52
|
-
workflow_inputs
|
|
53
|
-
node_outputs
|
|
54
|
-
resolved_inputs
|
|
55
|
-
http_client
|
|
56
|
-
|
|
52
|
+
kwargs: dict[str, Any] = {
|
|
53
|
+
"node": node,
|
|
54
|
+
"workflow_inputs": workflow_inputs,
|
|
55
|
+
"node_outputs": node_outputs,
|
|
56
|
+
"resolved_inputs": resolved_inputs,
|
|
57
|
+
"http_client": http_client,
|
|
58
|
+
}
|
|
59
|
+
if node.kind in {"llm_azure_chat", "llm_groq_chat"}:
|
|
60
|
+
kwargs["provider_config"] = provider_config
|
|
61
|
+
return await executor(**kwargs)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import os
|
|
5
4
|
from typing import Any
|
|
6
5
|
|
|
7
6
|
import httpx
|
|
8
7
|
|
|
9
8
|
from dify_player.exceptions import AzureLLMBadStatusError, AzureLLMRequestFailedError, AzureLLMStructuredOutputError
|
|
10
9
|
from dify_player.models import Node
|
|
10
|
+
from dify_player.provider_config import ProviderConfig, resolve_provider_config_value
|
|
11
11
|
from dify_player.value_renderer import render_value
|
|
12
12
|
|
|
13
13
|
_STRUCTURED_OUTPUT_REPAIR_RETRIES = 1
|
|
@@ -20,11 +20,30 @@ async def run(
|
|
|
20
20
|
node_outputs: dict[str, dict[str, Any]],
|
|
21
21
|
resolved_inputs: dict[str, Any],
|
|
22
22
|
http_client: httpx.AsyncClient | None = None,
|
|
23
|
+
provider_config: ProviderConfig | None = None,
|
|
23
24
|
) -> dict[str, Any]:
|
|
24
25
|
_ = resolved_inputs
|
|
25
|
-
endpoint =
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
endpoint = resolve_provider_config_value(
|
|
27
|
+
provider_config=provider_config,
|
|
28
|
+
config_key="azure_openai_endpoint",
|
|
29
|
+
env_names=("DIFY_PLAYER_AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_ENDPOINT"),
|
|
30
|
+
node=node,
|
|
31
|
+
required=True,
|
|
32
|
+
)
|
|
33
|
+
api_key = resolve_provider_config_value(
|
|
34
|
+
provider_config=provider_config,
|
|
35
|
+
config_key="azure_openai_api_key",
|
|
36
|
+
env_names=("DIFY_PLAYER_AZURE_OPENAI_API_KEY", "AZURE_OPENAI_API_KEY"),
|
|
37
|
+
node=node,
|
|
38
|
+
required=True,
|
|
39
|
+
)
|
|
40
|
+
api_version = resolve_provider_config_value(
|
|
41
|
+
provider_config=provider_config,
|
|
42
|
+
config_key="azure_openai_api_version",
|
|
43
|
+
env_names=("DIFY_PLAYER_AZURE_OPENAI_API_VERSION", "AZURE_OPENAI_API_VERSION"),
|
|
44
|
+
node=node,
|
|
45
|
+
required=True,
|
|
46
|
+
)
|
|
28
47
|
|
|
29
48
|
messages = render_value(
|
|
30
49
|
node.config["messages"],
|
|
@@ -59,13 +78,6 @@ async def run(
|
|
|
59
78
|
)
|
|
60
79
|
|
|
61
80
|
|
|
62
|
-
def _require_env(name: str, *, node: Node) -> str:
|
|
63
|
-
value = os.environ.get(name)
|
|
64
|
-
if value:
|
|
65
|
-
return value
|
|
66
|
-
raise ValueError(f"llm node {node.label!r} requires environment variable {name}")
|
|
67
|
-
|
|
68
|
-
|
|
69
81
|
def _build_request_body(*, node: Node, messages: Any) -> dict[str, Any]:
|
|
70
82
|
if not isinstance(messages, list):
|
|
71
83
|
raise ValueError(f"llm node {node.label!r} config.messages must render to an array")
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import os
|
|
5
4
|
from typing import Any
|
|
6
5
|
|
|
7
6
|
import httpx
|
|
@@ -19,6 +18,7 @@ from dify_player.nodes.llm_azure_chat import (
|
|
|
19
18
|
_validate_schema,
|
|
20
19
|
_zero_usage,
|
|
21
20
|
)
|
|
21
|
+
from dify_player.provider_config import ProviderConfig, resolve_provider_config_value
|
|
22
22
|
from dify_player.value_renderer import render_value
|
|
23
23
|
|
|
24
24
|
_DEFAULT_BASE_URL = "https://api.groq.com/openai/v1"
|
|
@@ -32,10 +32,24 @@ async def run(
|
|
|
32
32
|
node_outputs: dict[str, dict[str, Any]],
|
|
33
33
|
resolved_inputs: dict[str, Any],
|
|
34
34
|
http_client: httpx.AsyncClient | None = None,
|
|
35
|
+
provider_config: ProviderConfig | None = None,
|
|
35
36
|
) -> dict[str, Any]:
|
|
36
37
|
_ = resolved_inputs
|
|
37
|
-
api_key =
|
|
38
|
-
|
|
38
|
+
api_key = resolve_provider_config_value(
|
|
39
|
+
provider_config=provider_config,
|
|
40
|
+
config_key="groq_api_key",
|
|
41
|
+
env_names=("DIFY_PLAYER_GROQ_API_KEY", "GROQ_API_KEY"),
|
|
42
|
+
node=node,
|
|
43
|
+
required=True,
|
|
44
|
+
)
|
|
45
|
+
base_url = resolve_provider_config_value(
|
|
46
|
+
provider_config=provider_config,
|
|
47
|
+
config_key="groq_api_base_url",
|
|
48
|
+
env_names=("DIFY_PLAYER_GROQ_API_BASE_URL", "GROQ_API_BASE_URL"),
|
|
49
|
+
node=node,
|
|
50
|
+
required=False,
|
|
51
|
+
default=_DEFAULT_BASE_URL,
|
|
52
|
+
)
|
|
39
53
|
|
|
40
54
|
messages = render_value(
|
|
41
55
|
node.config["messages"],
|
|
@@ -67,13 +81,6 @@ async def run(
|
|
|
67
81
|
)
|
|
68
82
|
|
|
69
83
|
|
|
70
|
-
def _require_env(name: str, *, node: Node) -> str:
|
|
71
|
-
value = os.environ.get(name)
|
|
72
|
-
if value:
|
|
73
|
-
return value
|
|
74
|
-
raise ValueError(f"llm node {node.label!r} requires environment variable {name}")
|
|
75
|
-
|
|
76
|
-
|
|
77
84
|
def _build_request_body(*, node: Node, messages: Any) -> dict[str, Any]:
|
|
78
85
|
if not isinstance(messages, list):
|
|
79
86
|
raise ValueError(f"llm node {node.label!r} config.messages must render to an array")
|
|
@@ -222,8 +229,9 @@ async def _run_structured_output_with_repair(
|
|
|
222
229
|
|
|
223
230
|
|
|
224
231
|
# Groq may return json_validate_failed as HTTP 400 even when the failure is the
|
|
225
|
-
# model's generated JSON, not a permanent request/schema error.
|
|
226
|
-
#
|
|
232
|
+
# model's generated JSON, not a permanent request/schema error. Retry through the
|
|
233
|
+
# existing repair prompt even when Groq omits failed_generation, because the next
|
|
234
|
+
# attempt can still recover from provider-side structured-output validation.
|
|
227
235
|
def _extract_groq_failed_generation(exc: GroqLLMBadStatusError) -> tuple[str, str] | None:
|
|
228
236
|
if exc.status_code != 400 or exc.response_body is None:
|
|
229
237
|
return None
|
|
@@ -242,7 +250,7 @@ def _extract_groq_failed_generation(exc: GroqLLMBadStatusError) -> tuple[str, st
|
|
|
242
250
|
return None
|
|
243
251
|
|
|
244
252
|
failed_generation = error.get("failed_generation")
|
|
245
|
-
if not isinstance(failed_generation, str)
|
|
253
|
+
if not isinstance(failed_generation, str):
|
|
246
254
|
return None
|
|
247
255
|
|
|
248
256
|
message = error.get("message")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from dify_player.models import Node
|
|
8
|
+
|
|
9
|
+
ProviderConfig = Mapping[str, Any]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def resolve_provider_config_value(
|
|
13
|
+
*,
|
|
14
|
+
provider_config: ProviderConfig | None,
|
|
15
|
+
config_key: str,
|
|
16
|
+
env_names: tuple[str, ...],
|
|
17
|
+
node: Node,
|
|
18
|
+
required: bool,
|
|
19
|
+
default: str | None = None,
|
|
20
|
+
) -> str:
|
|
21
|
+
if provider_config is not None:
|
|
22
|
+
value = provider_config.get(config_key)
|
|
23
|
+
if value:
|
|
24
|
+
if not isinstance(value, str):
|
|
25
|
+
raise ValueError(f"llm node {node.label!r} provider_config[{config_key!r}] must be a string")
|
|
26
|
+
return value
|
|
27
|
+
|
|
28
|
+
for env_name in env_names:
|
|
29
|
+
value = os.environ.get(env_name)
|
|
30
|
+
if value:
|
|
31
|
+
return value
|
|
32
|
+
|
|
33
|
+
if default is not None:
|
|
34
|
+
return default
|
|
35
|
+
if required:
|
|
36
|
+
sources = [f"provider_config[{config_key!r}]"] + [f"environment variable {env_name}" for env_name in env_names]
|
|
37
|
+
raise ValueError(f"llm node {node.label!r} requires {' or '.join(sources)}")
|
|
38
|
+
raise ValueError(f"llm node {node.label!r} provider config {config_key!r} is not configured")
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import time
|
|
4
5
|
from copy import deepcopy
|
|
5
6
|
from datetime import datetime, timezone
|
|
@@ -26,6 +27,7 @@ from dify_player.input_resolver import resolve_node_inputs
|
|
|
26
27
|
from dify_player.llm_cache import LLMCacheStore, NullLLMCacheStore, build_llm_cache_key
|
|
27
28
|
from dify_player.models import CompiledLoop, CompiledPlan, Edge, Node, NodeResult, RunResult, RunState, WorkflowError
|
|
28
29
|
from dify_player.nodes import run_node
|
|
30
|
+
from dify_player.provider_config import ProviderConfig
|
|
29
31
|
from dify_player.value_renderer import render_value
|
|
30
32
|
|
|
31
33
|
|
|
@@ -36,10 +38,12 @@ class WorkflowRuntime:
|
|
|
36
38
|
*,
|
|
37
39
|
llm_cache_enabled: bool = False,
|
|
38
40
|
llm_cache_store: LLMCacheStore | None = None,
|
|
41
|
+
provider_config: ProviderConfig | None = None,
|
|
39
42
|
) -> None:
|
|
40
43
|
self.logger = logger
|
|
41
44
|
self.llm_cache_enabled = llm_cache_enabled
|
|
42
45
|
self.llm_cache_store = llm_cache_store if llm_cache_store is not None else NullLLMCacheStore()
|
|
46
|
+
self.provider_config = provider_config
|
|
43
47
|
|
|
44
48
|
async def run(
|
|
45
49
|
self,
|
|
@@ -455,6 +459,7 @@ class WorkflowRuntime:
|
|
|
455
459
|
node_outputs=node_outputs,
|
|
456
460
|
resolved_inputs=resolved_inputs,
|
|
457
461
|
http_client=http_client,
|
|
462
|
+
provider_config=self.provider_config,
|
|
458
463
|
)
|
|
459
464
|
|
|
460
465
|
if not self._should_use_llm_cache(node=node):
|
|
@@ -528,7 +533,8 @@ class WorkflowRuntime:
|
|
|
528
533
|
node.config["messages"],
|
|
529
534
|
{"inputs": workflow_inputs, "nodes": node_outputs},
|
|
530
535
|
location=f"llm cache key for node {node.label!r} config.messages",
|
|
531
|
-
)
|
|
536
|
+
),
|
|
537
|
+
"provider_config": _cacheable_provider_config(self.provider_config),
|
|
532
538
|
}
|
|
533
539
|
return build_llm_cache_key(
|
|
534
540
|
node_kind=node.kind,
|
|
@@ -772,6 +778,37 @@ def _normalize_workflow_inputs(*, compiled_plan: CompiledPlan, inputs: dict[str,
|
|
|
772
778
|
return normalized_inputs
|
|
773
779
|
|
|
774
780
|
|
|
781
|
+
def _cacheable_provider_config(provider_config: ProviderConfig | None) -> dict[str, Any]:
|
|
782
|
+
values = {
|
|
783
|
+
"azure_openai_endpoint": _cacheable_provider_config_value(
|
|
784
|
+
provider_config=provider_config,
|
|
785
|
+
config_key="azure_openai_endpoint",
|
|
786
|
+
env_names=("DIFY_PLAYER_AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_ENDPOINT"),
|
|
787
|
+
),
|
|
788
|
+
"azure_openai_api_version": _cacheable_provider_config_value(
|
|
789
|
+
provider_config=provider_config,
|
|
790
|
+
config_key="azure_openai_api_version",
|
|
791
|
+
env_names=("DIFY_PLAYER_AZURE_OPENAI_API_VERSION", "AZURE_OPENAI_API_VERSION"),
|
|
792
|
+
),
|
|
793
|
+
}
|
|
794
|
+
return {key: value for key, value in values.items() if value}
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
def _cacheable_provider_config_value(
|
|
798
|
+
*,
|
|
799
|
+
provider_config: ProviderConfig | None,
|
|
800
|
+
config_key: str,
|
|
801
|
+
env_names: tuple[str, ...],
|
|
802
|
+
) -> Any:
|
|
803
|
+
if provider_config is not None and provider_config.get(config_key):
|
|
804
|
+
return provider_config[config_key]
|
|
805
|
+
for env_name in env_names:
|
|
806
|
+
value = os.environ.get(env_name)
|
|
807
|
+
if value:
|
|
808
|
+
return value
|
|
809
|
+
return None
|
|
810
|
+
|
|
811
|
+
|
|
775
812
|
class _LoopRuntimeError(ValueError):
|
|
776
813
|
def __init__(self, error: WorkflowError) -> None:
|
|
777
814
|
super().__init__(error.message)
|
|
@@ -9,6 +9,7 @@ from dify_player.event_logger import NullEventLogger, WorkflowLogger
|
|
|
9
9
|
from dify_player.llm_cache import LLMCacheStore
|
|
10
10
|
from dify_player.models import CompiledPlan, Plan, RunResult
|
|
11
11
|
from dify_player.plan_loader import parse_plan
|
|
12
|
+
from dify_player.provider_config import ProviderConfig
|
|
12
13
|
from dify_player.workflow_executor import WorkflowExecutor
|
|
13
14
|
|
|
14
15
|
|
|
@@ -26,6 +27,7 @@ class WorkflowEngine:
|
|
|
26
27
|
http_client: httpx.AsyncClient | None = None,
|
|
27
28
|
llm_cache: bool = False,
|
|
28
29
|
llm_cache_store: LLMCacheStore | None = None,
|
|
30
|
+
provider_config: ProviderConfig | None = None,
|
|
29
31
|
) -> RunResult:
|
|
30
32
|
effective_logger, owns_logger = _resolve_logger(run_id=run_id, logger=logger)
|
|
31
33
|
try:
|
|
@@ -36,6 +38,7 @@ class WorkflowEngine:
|
|
|
36
38
|
http_client=http_client,
|
|
37
39
|
llm_cache=llm_cache,
|
|
38
40
|
llm_cache_store=llm_cache_store,
|
|
41
|
+
provider_config=provider_config,
|
|
39
42
|
)
|
|
40
43
|
finally:
|
|
41
44
|
if owns_logger:
|
|
@@ -51,6 +54,7 @@ class WorkflowEngine:
|
|
|
51
54
|
http_client: httpx.AsyncClient | None = None,
|
|
52
55
|
llm_cache: bool = False,
|
|
53
56
|
llm_cache_store: LLMCacheStore | None = None,
|
|
57
|
+
provider_config: ProviderConfig | None = None,
|
|
54
58
|
) -> RunResult:
|
|
55
59
|
effective_logger, owns_logger = _resolve_logger(run_id=run_id, logger=logger)
|
|
56
60
|
try:
|
|
@@ -61,6 +65,7 @@ class WorkflowEngine:
|
|
|
61
65
|
http_client=http_client,
|
|
62
66
|
llm_cache=llm_cache,
|
|
63
67
|
llm_cache_store=llm_cache_store,
|
|
68
|
+
provider_config=provider_config,
|
|
64
69
|
)
|
|
65
70
|
finally:
|
|
66
71
|
if owns_logger:
|
|
@@ -76,6 +81,7 @@ class WorkflowEngine:
|
|
|
76
81
|
http_client: httpx.AsyncClient | None = None,
|
|
77
82
|
llm_cache: bool = False,
|
|
78
83
|
llm_cache_store: LLMCacheStore | None = None,
|
|
84
|
+
provider_config: ProviderConfig | None = None,
|
|
79
85
|
) -> RunResult:
|
|
80
86
|
plan = parse_plan(plan_data)
|
|
81
87
|
return await self.run_plan(
|
|
@@ -86,6 +92,7 @@ class WorkflowEngine:
|
|
|
86
92
|
http_client=http_client,
|
|
87
93
|
llm_cache=llm_cache,
|
|
88
94
|
llm_cache_store=llm_cache_store,
|
|
95
|
+
provider_config=provider_config,
|
|
89
96
|
)
|
|
90
97
|
|
|
91
98
|
|
|
@@ -13,6 +13,7 @@ from dify_player.exceptions import PlanValidationError
|
|
|
13
13
|
from dify_player.llm_cache import LLMCacheStore
|
|
14
14
|
from dify_player.models import CompiledPlan, Plan, RunResult, WorkflowError
|
|
15
15
|
from dify_player.plan_loader import compile_plan, load_input_data, load_plan_definition
|
|
16
|
+
from dify_player.provider_config import ProviderConfig
|
|
16
17
|
from dify_player.runtime import WorkflowRuntime
|
|
17
18
|
|
|
18
19
|
|
|
@@ -33,11 +34,13 @@ class WorkflowExecutor:
|
|
|
33
34
|
http_client: httpx.AsyncClient | None = None,
|
|
34
35
|
llm_cache: bool = False,
|
|
35
36
|
llm_cache_store: LLMCacheStore | None = None,
|
|
37
|
+
provider_config: ProviderConfig | None = None,
|
|
36
38
|
) -> RunResult:
|
|
37
39
|
runtime = WorkflowRuntime(
|
|
38
40
|
logger=logger,
|
|
39
41
|
llm_cache_enabled=llm_cache,
|
|
40
42
|
llm_cache_store=llm_cache_store,
|
|
43
|
+
provider_config=provider_config,
|
|
41
44
|
)
|
|
42
45
|
return await runtime.run(
|
|
43
46
|
compiled_plan=compiled_plan,
|
|
@@ -58,6 +61,7 @@ class WorkflowExecutor:
|
|
|
58
61
|
http_client: httpx.AsyncClient | None = None,
|
|
59
62
|
llm_cache: bool = False,
|
|
60
63
|
llm_cache_store: LLMCacheStore | None = None,
|
|
64
|
+
provider_config: ProviderConfig | None = None,
|
|
61
65
|
) -> RunResult:
|
|
62
66
|
try:
|
|
63
67
|
compiled_plan = compile_plan(plan)
|
|
@@ -79,6 +83,7 @@ class WorkflowExecutor:
|
|
|
79
83
|
http_client=http_client,
|
|
80
84
|
llm_cache=llm_cache,
|
|
81
85
|
llm_cache_store=llm_cache_store,
|
|
86
|
+
provider_config=provider_config,
|
|
82
87
|
)
|
|
83
88
|
|
|
84
89
|
async def run_plan_path(
|
|
@@ -90,6 +95,7 @@ class WorkflowExecutor:
|
|
|
90
95
|
http_client: httpx.AsyncClient | None = None,
|
|
91
96
|
llm_cache: bool = False,
|
|
92
97
|
llm_cache_store: LLMCacheStore | None = None,
|
|
98
|
+
provider_config: ProviderConfig | None = None,
|
|
93
99
|
) -> RunResult:
|
|
94
100
|
run_id = uuid.uuid4().hex
|
|
95
101
|
resolved_log_path = log_path if log_path is not None else build_default_log_path(run_id)
|
|
@@ -142,6 +148,7 @@ class WorkflowExecutor:
|
|
|
142
148
|
http_client=http_client,
|
|
143
149
|
llm_cache=llm_cache,
|
|
144
150
|
llm_cache_store=llm_cache_store,
|
|
151
|
+
provider_config=provider_config,
|
|
145
152
|
)
|
|
146
153
|
|
|
147
154
|
if result.status == "failed":
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/__init__.py
RENAMED
|
File without changes
|
{dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/assigner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/http_request.py
RENAMED
|
File without changes
|
{dify_player-0.3.4 → dify_player-0.3.6}/dify_player/dify_importer/node_converters/if_else.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|