chore(api): bump minimum supported Python to 3.13 (#43022)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-10-09 10:47:03 +00:00
1 parent da5ce5e4f6
commit 50f66b43c8
215 files changed
+1582 -1738

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/devcontainers/python:3.12-bookworm
FROM mcr.microsoft.com/devcontainers/python:3.13-bookworm
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install libgmp-dev libmpfr-dev libmpc-dev
+1 -1
View File
@@ -1,7 +1,7 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/anaconda
{
"name": "Python 3.12",
"name": "Python 3.13",
"build": {
"context": "..",
"dockerfile": "Dockerfile"
+1 -1
View File
@@ -57,7 +57,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: |
api/uv.lock
+9 -9
View File
@@ -25,7 +25,7 @@ jobs:
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: '3.12'
python-version: '3.13'
enable-cache: false
- name: Download shared timing baseline
# Public statistics are independent of PR refs and require no credentials.
@@ -72,7 +72,7 @@ jobs:
fail-fast: false
matrix:
python-version:
- '3.12'
- '3.13'
shardIndex:
- 1
- 2
@@ -152,11 +152,11 @@ jobs:
retention-days: 1
api-controllers:
name: API Controller Tests (3.12)
name: API Controller Tests (3.13)
runs-on: depot-ubuntu-24.04
env:
PYTHONUNBUFFERED: '1'
COVERAGE_FILE: coverage-controllers-3.12
COVERAGE_FILE: coverage-controllers-3.13
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -167,7 +167,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: api/uv.lock
- name: Check UV lockfile
@@ -192,7 +192,7 @@ jobs:
if: ${{ !cancelled() }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: api-test-results-controllers-3.12
name: api-test-results-controllers-3.13
path: test-results/*.xml
if-no-files-found: warn
retention-days: 7
@@ -200,7 +200,7 @@ jobs:
- name: Upload controller coverage data
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: api-coverage-controllers-3.12
name: api-coverage-controllers-3.13
path: ${{ env.COVERAGE_FILE }}
if-no-files-found: error
retention-days: 1
@@ -220,7 +220,7 @@ jobs:
fail-fast: false
matrix:
python-version:
- '3.12'
- '3.13'
steps:
- name: Checkout code
@@ -286,7 +286,7 @@ jobs:
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: '3.12'
python-version: '3.13'
- name: Download coverage data
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
+1 -1
View File
@@ -61,7 +61,7 @@ jobs:
- if: github.event_name != 'merge_group' && (steps.docker-compose-changes.outputs.any_changed == 'true' || steps.api-changes.outputs.any_changed == 'true' || steps.frontend-contract-changes.outputs.any_changed == 'true' || steps.dify-agent-changes.outputs.any_changed == 'true')
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.11'
python-version: '3.13'
- if: github.event_name != 'merge_group' && (steps.api-changes.outputs.any_changed == 'true' || steps.frontend-contract-changes.outputs.any_changed == 'true' || steps.dify-agent-changes.outputs.any_changed == 'true')
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
+2 -2
View File
@@ -22,7 +22,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: api/uv.lock
- name: Install dependencies
@@ -72,7 +72,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: api/uv.lock
- name: Install dependencies
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
python-version:
- '3.12'
- '3.13'
steps:
- name: Checkout code
+1 -1
View File
@@ -64,7 +64,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: false
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: |
api/uv.lock
dify-agent/uv.lock
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
strategy:
matrix:
python-version:
- '3.12'
- '3.13'
steps:
- name: Checkout code
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
python-version:
- '3.12'
- '3.13'
steps:
- name: Checkout code
+3 -3
View File
@@ -118,7 +118,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: api/uv.lock
# API and web installs are independent, so overlap them; the browser
@@ -196,7 +196,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: api/uv.lock
# API and web installs are independent, so overlap them; the browser
@@ -268,7 +268,7 @@ jobs:
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
python-version: '3.13'
cache-dependency-glob: |
api/uv.lock
dify-agent/uv.lock
+1 -1
View File
@@ -1,5 +1,5 @@
# base image
FROM python:3.12-slim-bookworm AS base
FROM python:3.13-slim-bookworm AS base
WORKDIR /app/api
+2 -2
View File
@@ -94,7 +94,7 @@ class ExecutionContext:
return self._user
@contextmanager
def enter(self) -> Generator[None, None, None]:
def enter(self) -> Generator[None]:
"""Enter this execution context."""
if self._context_vars:
for var, val in self._context_vars.items():
@@ -145,7 +145,7 @@ class NullAppContext(AppContext):
@contextmanager
@override
def enter(self) -> Generator[None, None, None]:
def enter(self) -> Generator[None]:
"""Enter null context (no-op)."""
yield
+2 -2
View File
@@ -42,7 +42,7 @@ class FlaskAppContext(AppContext):
@contextmanager
@override
def enter(self) -> Generator[None, None, None]:
def enter(self) -> Generator[None]:
"""Enter Flask app context."""
with self._flask_app.app_context():
yield
@@ -159,7 +159,7 @@ class FlaskExecutionContext:
cm.__exit__(*args)
@contextmanager
def enter(self) -> Generator[None, None, None]:
def enter(self) -> Generator[None]:
"""Enter Flask execution context as context manager."""
# Restore non-Flask context variables to avoid leaking Flask tokens across threads
for var, val in self._context_vars.items():
@@ -14,7 +14,7 @@ from services.auth.resource_access_token_contracts import (
@contextmanager
def resource_access_token_errors() -> Generator[None, None, None]:
def resource_access_token_errors() -> Generator[None]:
try:
yield
except ResourceAccessTokenInputError as error:
+2 -2
View File
@@ -473,7 +473,7 @@ def _create_build_chat_finalization_message(
return {"result": "success"}, 200
def _drain_streaming_generate_response(response: RateLimitGenerator | Generator[str, None, None]) -> None:
def _drain_streaming_generate_response(response: RateLimitGenerator | Generator[str]) -> None:
"""Consume a streamed app-generate response until a terminal message event arrives.
Finalize keeps the normal Agent App streaming path so the existing queue,
@@ -631,7 +631,7 @@ def _raise_agent_stream_error_before_response(response):
return _prepend_stream_chunks(buffered, chunk, iterator)
def _prepend_stream_chunks(buffered: list[Any], first: Any, iterator: Iterator[Any]) -> Generator[Any, None, None]:
def _prepend_stream_chunks(buffered: list[Any], first: Any, iterator: Iterator[Any]) -> Generator[Any]:
yield from buffered
yield first
yield from iterator
+1 -1
View File
@@ -602,7 +602,7 @@ class WorkflowGenerateStreamApi(Resource):
if guard is not None:
return guard
def generate() -> Generator[str, None, None]:
def generate() -> Generator[str]:
try:
for event_name, payload in WorkflowGeneratorService.generate_workflow_graph_stream(
tenant_id=current_tenant_id,
+1 -1
View File
@@ -85,7 +85,7 @@ def _parse_file_upload() -> tuple[FileStorage, str, Literal["datasets"] | None]:
@contextmanager
def _file_upload_errors() -> Generator[None, None, None]:
def _file_upload_errors() -> Generator[None]:
try:
yield
except services.errors.file.FileTooLargeError as file_too_large_error:
+1 -1
View File
@@ -198,7 +198,7 @@ class ConsoleWorkflowEventsApi(Resource):
payload = response.model_dump(mode="json")
payload["event"] = response.event.value
def _generate_finished_events() -> Generator[str, None, None]:
def _generate_finished_events() -> Generator[str]:
yield f"data: {json.dumps(payload)}\n\n"
event_generator = _generate_finished_events
+1 -1
View File
@@ -73,7 +73,7 @@ class AgentLLMInvokeApi(Resource):
status_code=400,
) from exc
def generate() -> Generator[str, None, None]:
def generate() -> Generator[str]:
try:
for chunk in service.invoke(prepared):
envelope = {"code": 0, "message": "", "data": chunk.model_dump(mode="json")}
+1 -1
View File
@@ -62,7 +62,7 @@ def _wanted_event(chunk: str, event: str) -> dict[str, Any] | None:
return parsed
def attach_stream_hints(events: Iterable[str], *, event: str, build: HintBuilder) -> Generator[str, None, None]:
def attach_stream_hints(events: Iterable[str], *, event: str, build: HintBuilder) -> Generator[str]:
"""Yield the source SSE chunks, adding a top-level `hints` list to every `event` that `build` hints.
`event: ping` chunks, other event kinds, events `build` returns nothing for, and events
+5 -5
View File
@@ -91,7 +91,7 @@ _INVALID_RUN_INPUT: Final = "invalid run input"
@contextmanager
def _translate_service_errors() -> Generator[None, None, None]:
def _translate_service_errors() -> Generator[None]:
try:
yield
except WorkflowNotFoundError as ex:
@@ -191,7 +191,7 @@ class _ChatMessageEnd(MessageEndStreamResponse):
conversation_id: str
def with_reply_hints(events: Iterable[str], *, op: str, app_id: str) -> Generator[str, None, None]:
def with_reply_hints(events: Iterable[str], *, op: str, app_id: str) -> Generator[str]:
def build(event: Mapping[str, Any]) -> list[Hint]:
end = _ChatMessageEnd.model_validate(event)
return [
@@ -205,14 +205,14 @@ def with_reply_hints(events: Iterable[str], *, op: str, app_id: str) -> Generato
return attach_stream_hints(events, event=StreamEvent.MESSAGE_END.value, build=build)
HintLayer = Callable[[Iterable[str], str, str], Generator[str, None, None]]
HintLayer = Callable[[Iterable[str], str, str], Generator[str]]
def _reply_layer(events: Iterable[str], op: str, app_id: str) -> Generator[str, None, None]:
def _reply_layer(events: Iterable[str], op: str, app_id: str) -> Generator[str]:
return with_reply_hints(events, op=op, app_id=app_id)
def _form_layer(events: Iterable[str], op: str, app_id: str) -> Generator[str, None, None]:
def _form_layer(events: Iterable[str], op: str, app_id: str) -> Generator[str]:
return with_form_hints(events, app_id=app_id)
+1 -1
View File
@@ -219,7 +219,7 @@ def form_hints(*, op: str, app_id: str, response: HumanInputRequiredResponse) ->
]
def with_form_hints(events: Iterable[str], *, app_id: str) -> Generator[str, None, None]:
def with_form_hints(events: Iterable[str], *, app_id: str) -> Generator[str]:
"""A run stream whose `human_input_required` events carry hints that target the submit route above."""
op = op_of(OpenApiWorkflowHumanInputFormSubmitApi.post)
+1 -1
View File
@@ -118,7 +118,7 @@ class OpenApiWorkflowEventsApi(Resource):
payload = response.model_dump(mode="json")
payload["event"] = response.event.value
def _generate_finished_events() -> Generator[str, None, None]:
def _generate_finished_events() -> Generator[str]:
yield f"data: {json.dumps(payload)}\n\n"
event_generator = _generate_finished_events
@@ -128,7 +128,7 @@ class WorkflowEventsApi(Resource):
payload = response.model_dump(mode="json")
payload["event"] = response.event.value
def _generate_finished_events() -> Generator[str, None, None]:
def _generate_finished_events() -> Generator[str]:
yield f"data: {json.dumps(payload)}\n\n"
event_generator = _generate_finished_events
@@ -315,7 +315,7 @@ class PipelineRunApi(DatasetApiResource):
rag_pipeline_service = RagPipelineService(session)
pipeline = rag_pipeline_service.get_pipeline(tenant_id=tenant_id, dataset_id=dataset_id_str)
try:
response: dict[Any, Any] | Generator[str, Any, None] = PipelineGenerateService.generate(
response: dict[Any, Any] | Generator[str, Any] = PipelineGenerateService.generate(
generator=application_services().knowledge.pipeline_generator,
session=session,
pipeline=pipeline,
+1 -1
View File
@@ -69,7 +69,7 @@ class WorkflowEventsApi(WebApiResource):
payload = response.model_dump(mode="json")
payload["event"] = response.event.value
def _generate_finished_events() -> Generator[str, None, None]:
def _generate_finished_events() -> Generator[str]:
yield f"data: {json.dumps(payload)}\n\n"
event_generator = _generate_finished_events
+2 -4
View File
@@ -100,9 +100,7 @@ class FunctionCallAgentRunner(BaseAgentRunner):
return prompt_message_contents
def run(
self, session: Session, message: Message, query: str, **kwargs: Any
) -> Generator[LLMResultChunk, None, None]:
def run(self, session: Session, message: Message, query: str, **kwargs: Any) -> Generator[LLMResultChunk]:
"""
Run FunctionCall agent application
"""
@@ -175,7 +173,7 @@ class FunctionCallAgentRunner(BaseAgentRunner):
"created_by": CreditUsageCreatedBy.APP,
}
chunks: Union[Generator[LLMResultChunk, None, None], LLMResult] = model_instance.invoke_llm(
chunks: Union[Generator[LLMResultChunk], LLMResult] = model_instance.invoke_llm(
prompt_messages=prompt_messages,
model_parameters=app_generate_entity.model_conf.parameters,
tools=prompt_messages_tools,
@@ -10,8 +10,8 @@ from graphon.model_runtime.entities.llm_entities import LLMResultChunk
class CotAgentOutputParser:
@classmethod
def handle_react_stream_output(
cls, llm_response: Generator[LLMResultChunk, None, None], usage_dict: dict[str, Any]
) -> Generator[Union[str, AgentScratchpadUnit.Action], None, None]:
cls, llm_response: Generator[LLMResultChunk], usage_dict: dict[str, Any]
) -> Generator[Union[str, AgentScratchpadUnit.Action]]:
def parse_action(action) -> Union[str, AgentScratchpadUnit.Action]:
action_name = None
action_input = None
+2 -2
View File
@@ -20,7 +20,7 @@ class BaseAgentStrategy(ABC):
app_id: str | None = None,
message_id: str | None = None,
credentials: InvokeCredentials | None = None,
) -> Generator[AgentInvokeMessage, None, None]:
) -> Generator[AgentInvokeMessage]:
"""
Invoke the agent strategy.
"""
@@ -41,5 +41,5 @@ class BaseAgentStrategy(ABC):
app_id: str | None = None,
message_id: str | None = None,
credentials: InvokeCredentials | None = None,
) -> Generator[AgentInvokeMessage, None, None]:
) -> Generator[AgentInvokeMessage]:
pass
+1 -1
View File
@@ -44,7 +44,7 @@ class PluginAgentStrategy(BaseAgentStrategy):
app_id: str | None = None,
message_id: str | None = None,
credentials: InvokeCredentials | None = None,
) -> Generator[AgentInvokeMessage, None, None]:
) -> Generator[AgentInvokeMessage]:
"""
Invoke the agent strategy.
"""
@@ -103,7 +103,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
pause_state_config: PauseStateLayerConfig | None = None,
*,
session: Session,
) -> Generator[Mapping | str, None, None]: ...
) -> Generator[Mapping | str]: ...
@overload
def generate(
@@ -118,7 +118,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
pause_state_config: PauseStateLayerConfig | None = None,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping, None, None]: ...
) -> Mapping[str, Any] | Generator[str | Mapping]: ...
def generate(
self,
@@ -132,7 +132,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
pause_state_config: PauseStateLayerConfig | None = None,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping, None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping]:
"""
Generate App response.
@@ -327,7 +327,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -422,7 +422,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -523,7 +523,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
graph_runtime_state: GraphRuntimeState | None = None,
graph_engine_layers: Sequence[GraphEngineLayer] = (),
response_stream_filter: ResponseStreamFilter | None = None,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -760,11 +760,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
user: Account | EndUser,
draft_var_saver_factory: DraftVariableSaverFactory,
stream: bool = False,
) -> (
ChatbotAppBlockingResponse
| AdvancedChatPausedBlockingResponse
| Generator[ChatbotAppStreamResponse, None, None]
):
) -> ChatbotAppBlockingResponse | AdvancedChatPausedBlockingResponse | Generator[ChatbotAppStreamResponse]:
"""
Handle response.
:param application_generate_entity: application generate entity
@@ -80,8 +80,8 @@ class AdvancedChatAppGenerateResponseConverter(
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, Any, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str, Any]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -112,8 +112,8 @@ class AdvancedChatAppGenerateResponseConverter(
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, Any, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str, Any]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -222,7 +222,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
) -> Union[
ChatbotAppBlockingResponse,
AdvancedChatPausedBlockingResponse,
Generator[ChatbotAppStreamResponse, None, None],
Generator[ChatbotAppStreamResponse],
]:
"""
Process generate task pipeline.
@@ -242,7 +242,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
return self._to_blocking_response(generator)
def _to_blocking_response(
self, generator: Generator[StreamResponse, None, None]
self, generator: Generator[StreamResponse]
) -> Union[ChatbotAppBlockingResponse, AdvancedChatPausedBlockingResponse]:
"""
Process blocking response.
@@ -330,9 +330,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
),
)
def _to_stream_response(
self, generator: Generator[StreamResponse, None, None]
) -> Generator[ChatbotAppStreamResponse, Any, None]:
def _to_stream_response(self, generator: Generator[StreamResponse]) -> Generator[ChatbotAppStreamResponse, Any]:
"""
To stream response.
:return:
@@ -359,7 +357,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _wrapper_process_stream_response(
self, trace_manager: TraceQueueManager | None = None
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
tts_publisher = None
task_id = self._application_generate_entity.task_id
tenant_id = self._application_generate_entity.app_config.tenant_id
@@ -430,11 +428,11 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if not self._workflow_run_id:
raise ValueError("workflow run not initialized.")
def _handle_ping_event(self, event: QueuePingEvent, **kwargs) -> Generator[PingStreamResponse, None, None]:
def _handle_ping_event(self, event: QueuePingEvent, **kwargs) -> Generator[PingStreamResponse]:
"""Handle ping events."""
yield self._base_task_pipeline.ping_stream_response()
def _handle_error_event(self, event: QueueErrorEvent, **kwargs) -> Generator[ErrorStreamResponse, None, None]:
def _handle_error_event(self, event: QueueErrorEvent, **kwargs) -> Generator[ErrorStreamResponse]:
"""Handle error events."""
with self._database_session() as session:
err = self._base_task_pipeline.handle_error(event=event, session=session, message_id=self._message_id)
@@ -444,7 +442,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
event: QueueWorkflowStartedEvent,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow started events."""
runtime_state = self._resolve_graph_runtime_state()
run_id = self._extract_workflow_run_id(runtime_state)
@@ -462,7 +460,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
yield workflow_start_resp
def _handle_node_retry_event(self, event: QueueNodeRetryEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_node_retry_event(self, event: QueueNodeRetryEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node retry events."""
self._ensure_workflow_initialized()
@@ -474,9 +472,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if node_retry_resp:
yield node_retry_resp
def _handle_node_started_event(
self, event: QueueNodeStartedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_node_started_event(self, event: QueueNodeStartedEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node started events."""
self._ensure_workflow_initialized()
@@ -488,9 +484,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if node_start_resp:
yield node_start_resp
def _handle_node_succeeded_event(
self, event: QueueNodeSucceededEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_node_succeeded_event(self, event: QueueNodeSucceededEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node succeeded events."""
# Record files if it's an answer node or end node
if event.node_type in [BuiltinNodeTypes.ANSWER, BuiltinNodeTypes.END, BuiltinNodeTypes.LLM]:
@@ -523,7 +517,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
event: Union[QueueNodeFailedEvent, QueueNodeExceptionEvent],
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle various node failure events."""
node_finish_resp = self._workflow_response_converter.workflow_node_finish_to_stream_response(
event=event,
@@ -543,7 +537,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
tts_publisher: AppGeneratorTTSPublisher | None = None,
queue_message: Union[WorkflowQueueMessage, MessageQueueMessage] | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle text chunk events."""
delta_text = event.text
if delta_text is None:
@@ -571,9 +565,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
answer=delta_text, message_id=self._message_id, from_variable_selector=event.from_variable_selector
)
def _handle_reasoning_chunk_event(
self, event: QueueReasoningChunkEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_reasoning_chunk_event(self, event: QueueReasoningChunkEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle out-of-band reasoning chunk events.
Pure emit: reasoning is streamed on its own channel and never written to the
@@ -592,9 +584,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
),
)
def _handle_iteration_start_event(
self, event: QueueIterationStartEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_iteration_start_event(self, event: QueueIterationStartEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle iteration start events."""
self._ensure_workflow_initialized()
@@ -605,9 +595,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield iter_start_resp
def _handle_iteration_next_event(
self, event: QueueIterationNextEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_iteration_next_event(self, event: QueueIterationNextEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle iteration next events."""
self._ensure_workflow_initialized()
@@ -620,7 +608,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_iteration_completed_event(
self, event: QueueIterationCompletedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle iteration completed events."""
self._ensure_workflow_initialized()
@@ -631,7 +619,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield iter_finish_resp
def _handle_loop_start_event(self, event: QueueLoopStartEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_loop_start_event(self, event: QueueLoopStartEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop start events."""
self._ensure_workflow_initialized()
@@ -642,7 +630,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield loop_start_resp
def _handle_loop_next_event(self, event: QueueLoopNextEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_loop_next_event(self, event: QueueLoopNextEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop next events."""
self._ensure_workflow_initialized()
@@ -653,9 +641,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield loop_next_resp
def _handle_loop_completed_event(
self, event: QueueLoopCompletedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_loop_completed_event(self, event: QueueLoopCompletedEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop completed events."""
self._ensure_workflow_initialized()
@@ -672,7 +658,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow succeeded events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -695,7 +681,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow partial success events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -717,7 +703,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
event: QueueWorkflowPausedEvent,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow paused events."""
validated_state = self._ensure_graph_runtime_initialized()
responses = self._workflow_response_converter.workflow_pause_to_stream_response(
@@ -749,7 +735,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow failed events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -778,7 +764,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
graph_runtime_state: GraphRuntimeState | None = None,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle stop events."""
_ = trace_manager
resolved_state = None
@@ -818,7 +804,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
graph_runtime_state: GraphRuntimeState | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle advanced chat message end events."""
resolved_state = self._ensure_graph_runtime_initialized(graph_runtime_state)
@@ -842,28 +828,24 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_retriever_resources_event(
self, event: QueueRetrieverResourcesEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle retriever resources events."""
self._message_cycle_manager.handle_retriever_resources(event)
yield from ()
def _handle_annotation_reply_event(
self, event: QueueAnnotationReplyEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_annotation_reply_event(self, event: QueueAnnotationReplyEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle annotation reply events."""
with self._database_session() as session:
self._message_cycle_manager.handle_annotation_reply(event, session)
yield from ()
def _handle_message_replace_event(
self, event: QueueMessageReplaceEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_message_replace_event(self, event: QueueMessageReplaceEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle message replace events."""
yield self._message_cycle_manager.message_replace_to_stream_response(answer=event.text, reason=event.reason)
def _handle_human_input_form_filled_event(
self, event: QueueHumanInputFormFilledEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle human input form filled events."""
self._persist_human_input_extra_content(node_id=event.node_id)
yield self._workflow_response_converter.human_input_form_filled_to_stream_response(
@@ -872,7 +854,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_human_input_form_timeout_event(
self, event: QueueHumanInputFormTimeoutEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle human input form timeout events."""
yield self._workflow_response_converter.human_input_form_timeout_to_stream_response(
event=event, task_id=self._application_generate_entity.task_id
@@ -920,7 +902,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
return None
return form.id
def _handle_agent_log_event(self, event: QueueAgentLogEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_agent_log_event(self, event: QueueAgentLogEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle agent log events."""
yield self._workflow_response_converter.handle_agent_log(
task_id=self._application_generate_entity.task_id, event=event
@@ -971,7 +953,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
tts_publisher: AppGeneratorTTSPublisher | None = None,
trace_manager: TraceQueueManager | None = None,
queue_message: Union[WorkflowQueueMessage, MessageQueueMessage] | None = None,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Dispatch events using elegant pattern matching."""
handlers = self._get_event_handlers()
event_type = type(event)
@@ -1009,7 +991,7 @@ class AdvancedChatAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
tts_publisher: AppGeneratorTTSPublisher | None = None,
trace_manager: TraceQueueManager | None = None,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""
Process stream response using elegant Fluent Python patterns.
Maintains exact same functionality as original 57-if-statement version.
+1 -1
View File
@@ -85,7 +85,7 @@ class AgentAppGenerator(MessageBasedAppGenerator):
invoke_from: InvokeFrom,
session: Session,
streaming: bool = True,
) -> Mapping[str, Any] | Generator[Mapping | str, None, None]:
) -> Mapping[str, Any] | Generator[Mapping | str]:
if not streaming:
raise AgentAppGeneratorError("Agent App only supports streaming mode")
@@ -57,7 +57,7 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
invoke_from: InvokeFrom,
streaming: Literal[True],
session: Session,
) -> Generator[Mapping | str, None, None]: ...
) -> Generator[Mapping | str]: ...
@overload
def generate(
@@ -69,7 +69,7 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
invoke_from: InvokeFrom,
streaming: bool,
session: Session,
) -> Mapping | Generator[Mapping | str, None, None]: ...
) -> Mapping | Generator[Mapping | str]: ...
def generate(
self,
@@ -80,7 +80,7 @@ class AgentChatAppGenerator(MessageBasedAppGenerator):
invoke_from: InvokeFrom,
streaming: bool = True,
session: Session,
) -> Mapping | Generator[Mapping | str, None, None]:
) -> Mapping | Generator[Mapping | str]:
"""
Generate App response.
@@ -58,8 +58,8 @@ class AgentChatAppGenerateResponseConverter(AppGenerateResponseConverter[Chatbot
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -90,8 +90,8 @@ class AgentChatAppGenerateResponseConverter(AppGenerateResponseConverter[Chatbot
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -23,14 +23,14 @@ class AppGenerateResponseConverter[TBlockingResponse: AppBlockingResponse](ABC):
@classmethod
def convert(
cls, response: Union[AppBlockingResponse, Generator[AppStreamResponse, Any, None]], invoke_from: InvokeFrom
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], Any, None]:
cls, response: Union[AppBlockingResponse, Generator[AppStreamResponse, Any]], invoke_from: InvokeFrom
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], Any]:
if invoke_from in {InvokeFrom.DEBUGGER, InvokeFrom.SERVICE_API, InvokeFrom.OPENAPI}:
if isinstance(response, AppBlockingResponse):
return cls.convert_blocking_full_response(cls._cast_blocking_response(response))
else:
def _generate_full_response() -> Generator[dict[str, Any] | str, Any, None]:
def _generate_full_response() -> Generator[dict[str, Any] | str, Any]:
yield from cls.convert_stream_full_response(response)
return _generate_full_response()
@@ -39,7 +39,7 @@ class AppGenerateResponseConverter[TBlockingResponse: AppBlockingResponse](ABC):
return cls.convert_blocking_simple_response(cls._cast_blocking_response(response))
else:
def _generate_simple_response() -> Generator[dict[str, Any] | str, Any, None]:
def _generate_simple_response() -> Generator[dict[str, Any] | str, Any]:
yield from cls.convert_stream_simple_response(response)
return _generate_simple_response()
@@ -57,15 +57,15 @@ class AppGenerateResponseConverter[TBlockingResponse: AppBlockingResponse](ABC):
@classmethod
@abstractmethod
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
raise NotImplementedError
@classmethod
@abstractmethod
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
raise NotImplementedError
@classmethod
+3 -3
View File
@@ -94,9 +94,9 @@ class BaseAppGenerator:
@staticmethod
def _wrap_stream_with_worker_thread_join[ResponseT](
response_stream: Generator[ResponseT, None, None],
response_stream: Generator[ResponseT],
worker_thread: threading.Thread,
) -> Generator[ResponseT, None, None]:
) -> Generator[ResponseT]:
"""Keep the producer owned by the response stream until both finish."""
try:
yield from response_stream
@@ -310,7 +310,7 @@ class BaseAppGenerator:
return value
@classmethod
def convert_to_event_stream(cls, generator: Union[Mapping, Generator[Mapping | str, None, None]]):
def convert_to_event_stream(cls, generator: Union[Mapping, Generator[Mapping | str]]):
"""
Convert messages into event stream
"""
+2 -2
View File
@@ -214,7 +214,7 @@ class AppRunner:
def _handle_invoke_result(
self,
invoke_result: Union[LLMResult, Generator[Any, None, None]],
invoke_result: Union[LLMResult, Generator[Any]],
queue_manager: AppQueueManager,
stream: bool,
agent: bool = False,
@@ -275,7 +275,7 @@ class AppRunner:
def _handle_invoke_result_stream(
self,
invoke_result: Generator[LLMResultChunk, None, None],
invoke_result: Generator[LLMResultChunk],
queue_manager: AppQueueManager,
agent: bool,
message_id: str | None = None,
+3 -3
View File
@@ -45,7 +45,7 @@ class ChatAppGenerator(MessageBasedAppGenerator):
streaming: Literal[True],
*,
session: Session,
) -> Generator[Mapping | str, None, None]: ...
) -> Generator[Mapping | str]: ...
@overload
def generate(
@@ -69,7 +69,7 @@ class ChatAppGenerator(MessageBasedAppGenerator):
streaming: bool,
*,
session: Session,
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str, None, None]: ...
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str]: ...
def generate(
self,
@@ -80,7 +80,7 @@ class ChatAppGenerator(MessageBasedAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str, None, None]:
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str]:
"""
Generate App response.
@@ -58,8 +58,8 @@ class ChatAppGenerateResponseConverter(AppGenerateResponseConverter[ChatbotAppBl
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -90,8 +90,8 @@ class ChatAppGenerateResponseConverter(AppGenerateResponseConverter[ChatbotAppBl
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -46,7 +46,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
streaming: Literal[True],
*,
session: Session,
) -> Generator[str | Mapping[str, Any], None, None]: ...
) -> Generator[str | Mapping[str, Any]]: ...
@overload
def generate(
@@ -70,7 +70,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
streaming: bool = False,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]: ...
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]: ...
def generate(
self,
@@ -81,7 +81,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -280,7 +280,7 @@ class CompletionAppGenerator(MessageBasedAppGenerator):
stream: bool = True,
*,
session: Session,
) -> Mapping | Generator[Mapping | str, None, None]:
) -> Mapping | Generator[Mapping | str]:
"""
Generate App response.
@@ -57,8 +57,8 @@ class CompletionAppGenerateResponseConverter(AppGenerateResponseConverter[Comple
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -88,8 +88,8 @@ class CompletionAppGenerateResponseConverter(AppGenerateResponseConverter[Comple
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -59,7 +59,7 @@ class MessageBasedAppGenerator(BaseAppGenerator):
) -> Union[
ChatbotAppBlockingResponse,
CompletionAppBlockingResponse,
Generator[Union[ChatbotAppStreamResponse, CompletionAppStreamResponse], None, None],
Generator[Union[ChatbotAppStreamResponse, CompletionAppStreamResponse]],
]:
"""
Handle response.
@@ -321,7 +321,7 @@ class MessageBasedAppGenerator(BaseAppGenerator):
workflow_run_id: str,
idle_timeout=300,
on_subscribe: Callable[[], None] | None = None,
) -> Generator[Mapping | str, None, None]:
) -> Generator[Mapping | str]:
topic = cls.get_response_topic(app_mode, workflow_run_id)
subscriber = topic.as_subscriber()
subscription = (
+1 -1
View File
@@ -28,7 +28,7 @@ class MessageGenerator:
ping_interval: float = 10.0,
on_subscribe: Callable[[], None] | None = None,
terminal_events: Iterable[str | StreamEvent] | None = None,
) -> Generator[Mapping | str, None, None]:
) -> Generator[Mapping | str]:
topic = cls.get_response_topic(app_mode, workflow_run_id)
subscriber = topic.as_subscriber()
subscription = (
@@ -37,8 +37,8 @@ class WorkflowAppGenerateResponseConverter(AppGenerateResponseConverter[Workflow
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -71,8 +71,8 @@ class WorkflowAppGenerateResponseConverter(AppGenerateResponseConverter[Workflow
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -78,7 +78,7 @@ class PipelineGenerator(BaseAppGenerator):
call_depth: int,
workflow_thread_pool_id: str | None,
is_retry: bool = False,
) -> Generator[Mapping | str, None, None]: ...
) -> Generator[Mapping | str]: ...
@overload
def generate(
@@ -110,7 +110,7 @@ class PipelineGenerator(BaseAppGenerator):
call_depth: int,
workflow_thread_pool_id: str | None,
is_retry: bool = False,
) -> Mapping[str, Any] | Generator[Mapping | str, None, None]: ...
) -> Mapping[str, Any] | Generator[Mapping | str]: ...
def generate(
self,
@@ -125,7 +125,7 @@ class PipelineGenerator(BaseAppGenerator):
call_depth: int = 0,
workflow_thread_pool_id: str | None = None,
is_retry: bool = False,
) -> Mapping[str, Any] | Generator[Mapping | str, None, None] | None:
) -> Mapping[str, Any] | Generator[Mapping | str] | None:
# Add null check for dataset
dataset = self._documents.get_pipeline_dataset(pipeline, session=session)
@@ -306,7 +306,7 @@ class PipelineGenerator(BaseAppGenerator):
streaming: bool = True,
variable_loader: VariableLoader = DUMMY_VARIABLE_LOADER,
workflow_thread_pool_id: str | None = None,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -388,7 +388,7 @@ class PipelineGenerator(BaseAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -490,7 +490,7 @@ class PipelineGenerator(BaseAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -668,11 +668,7 @@ class PipelineGenerator(BaseAppGenerator):
user: Account | EndUser,
draft_var_saver_factory: DraftVariableSaverFactory,
stream: bool = False,
) -> (
WorkflowAppBlockingResponse
| WorkflowAppPausedBlockingResponse
| Generator[WorkflowAppStreamResponse, None, None]
):
) -> WorkflowAppBlockingResponse | WorkflowAppPausedBlockingResponse | Generator[WorkflowAppStreamResponse]:
"""
Handle response.
:param application_generate_entity: application generate entity
+1 -1
View File
@@ -17,7 +17,7 @@ def stream_topic_events(
ping_interval: float | None = None,
on_subscribe: Callable[[], None] | None = None,
terminal_events: Iterable[str | StreamEvent] | None = None,
) -> Generator[Mapping[str, Any] | str, None, None]:
) -> Generator[Mapping[str, Any] | str]:
# send a PING event immediately to prevent the connection staying in pending state for a long time.
#
# This simplify the debugging process as the DevTools in Chrome does not
+8 -12
View File
@@ -105,7 +105,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
root_node_id: str | None = None,
graph_engine_layers: Sequence[GraphEngineLayer] = (),
pause_state_config: PauseStateLayerConfig | None = None,
) -> Generator[Mapping[str, Any] | str, None, None]: ...
) -> Generator[Mapping[str, Any] | str]: ...
@overload
def generate(
@@ -141,7 +141,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
root_node_id: str | None = None,
graph_engine_layers: Sequence[GraphEngineLayer] = (),
pause_state_config: PauseStateLayerConfig | None = None,
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str, None, None]: ...
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str]: ...
def generate(
self,
@@ -158,7 +158,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
root_node_id: str | None = None,
graph_engine_layers: Sequence[GraphEngineLayer] = (),
pause_state_config: PauseStateLayerConfig | None = None,
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str, None, None]:
) -> Mapping[str, Any] | Generator[Mapping[str, Any] | str]:
with self._bind_file_access_scope(tenant_id=app_model.tenant_id, user=user, invoke_from=invoke_from):
files: Sequence[Mapping[str, Any]] = args.get("files") or []
@@ -283,7 +283,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
pause_state_config: PauseStateLayerConfig | None = None,
variable_loader: VariableLoader = DUMMY_VARIABLE_LOADER,
response_stream_filter: ResponseStreamFilter | None = None,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Resume a paused workflow execution using the persisted runtime state.
@@ -333,7 +333,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
graph_runtime_state: GraphRuntimeState | None = None,
pause_state_config: PauseStateLayerConfig | None = None,
response_stream_filter: ResponseStreamFilter | None = None,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -436,7 +436,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -530,7 +530,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
streaming: bool = True,
*,
session: Session,
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any], None, None]:
) -> Mapping[str, Any] | Generator[str | Mapping[str, Any]]:
"""
Generate App response.
@@ -710,11 +710,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
user: Account | EndUser,
draft_var_saver_factory: DraftVariableSaverFactory,
stream: bool = False,
) -> (
WorkflowAppBlockingResponse
| WorkflowAppPausedBlockingResponse
| Generator[WorkflowAppStreamResponse, None, None]
):
) -> WorkflowAppBlockingResponse | WorkflowAppPausedBlockingResponse | Generator[WorkflowAppStreamResponse]:
"""
Handle response.
:param application_generate_entity: application generate entity
@@ -44,8 +44,8 @@ class WorkflowAppGenerateResponseConverter(
@classmethod
@override
def convert_stream_full_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream full response.
:param stream_response: stream response
@@ -78,8 +78,8 @@ class WorkflowAppGenerateResponseConverter(
@classmethod
@override
def convert_stream_simple_response(
cls, stream_response: Generator[AppStreamResponse, None, None]
) -> Generator[dict[str, Any] | str, None, None]:
cls, stream_response: Generator[AppStreamResponse]
) -> Generator[dict[str, Any] | str]:
"""
Convert stream simple response.
:param stream_response: stream response
@@ -124,9 +124,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def process(
self,
) -> Union[
WorkflowAppBlockingResponse, WorkflowAppPausedBlockingResponse, Generator[WorkflowAppStreamResponse, None, None]
]:
) -> Union[WorkflowAppBlockingResponse, WorkflowAppPausedBlockingResponse, Generator[WorkflowAppStreamResponse]]:
"""
Process generate task pipeline.
:return:
@@ -138,7 +136,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
return self._to_blocking_response(generator)
def _to_blocking_response(
self, generator: Generator[StreamResponse, None, None]
self, generator: Generator[StreamResponse]
) -> Union[WorkflowAppBlockingResponse, WorkflowAppPausedBlockingResponse]:
"""
To blocking response.
@@ -227,9 +225,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
),
)
def _to_stream_response(
self, generator: Generator[StreamResponse, None, None]
) -> Generator[WorkflowAppStreamResponse, None, None]:
def _to_stream_response(self, generator: Generator[StreamResponse]) -> Generator[WorkflowAppStreamResponse]:
"""
To stream response.
:return:
@@ -255,7 +251,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _wrapper_process_stream_response(
self, trace_manager: TraceQueueManager | None = None
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
tts_publisher = None
task_id = self._application_generate_entity.task_id
tenant_id = self._application_generate_entity.app_config.tenant_id
@@ -321,18 +317,16 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if not self._workflow_execution_id:
raise ValueError("workflow run not initialized.")
def _handle_ping_event(self, event: QueuePingEvent, **kwargs) -> Generator[PingStreamResponse, None, None]:
def _handle_ping_event(self, event: QueuePingEvent, **kwargs) -> Generator[PingStreamResponse]:
"""Handle ping events."""
yield self._base_task_pipeline.ping_stream_response()
def _handle_error_event(self, event: QueueErrorEvent, **kwargs) -> Generator[ErrorStreamResponse, None, None]:
def _handle_error_event(self, event: QueueErrorEvent, **kwargs) -> Generator[ErrorStreamResponse]:
"""Handle error events."""
err = self._base_task_pipeline.handle_error(event=event)
yield self._base_task_pipeline.error_to_stream_response(err)
def _handle_workflow_started_event(
self, event: QueueWorkflowStartedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_workflow_started_event(self, event: QueueWorkflowStartedEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle workflow started events."""
runtime_state = self._resolve_graph_runtime_state()
@@ -351,7 +345,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield start_resp
def _handle_node_retry_event(self, event: QueueNodeRetryEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_node_retry_event(self, event: QueueNodeRetryEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node retry events."""
self._ensure_workflow_initialized()
@@ -363,9 +357,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if response:
yield response
def _handle_node_started_event(
self, event: QueueNodeStartedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_node_started_event(self, event: QueueNodeStartedEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node started events."""
self._ensure_workflow_initialized()
@@ -377,9 +369,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if node_start_response:
yield node_start_response
def _handle_node_succeeded_event(
self, event: QueueNodeSucceededEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_node_succeeded_event(self, event: QueueNodeSucceededEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle node succeeded events."""
node_success_response = self._workflow_response_converter.workflow_node_finish_to_stream_response(
event=event,
@@ -395,7 +385,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
event: Union[QueueNodeFailedEvent, QueueNodeExceptionEvent],
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle various node failure events."""
node_failed_response = self._workflow_response_converter.workflow_node_finish_to_stream_response(
event=event,
@@ -408,9 +398,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
if node_failed_response:
yield node_failed_response
def _handle_iteration_start_event(
self, event: QueueIterationStartEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_iteration_start_event(self, event: QueueIterationStartEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle iteration start events."""
self._ensure_workflow_initialized()
@@ -421,9 +409,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield iter_start_resp
def _handle_iteration_next_event(
self, event: QueueIterationNextEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_iteration_next_event(self, event: QueueIterationNextEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle iteration next events."""
self._ensure_workflow_initialized()
@@ -436,7 +422,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_iteration_completed_event(
self, event: QueueIterationCompletedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle iteration completed events."""
self._ensure_workflow_initialized()
@@ -447,7 +433,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield iter_finish_resp
def _handle_loop_start_event(self, event: QueueLoopStartEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_loop_start_event(self, event: QueueLoopStartEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop start events."""
self._ensure_workflow_initialized()
@@ -458,7 +444,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield loop_start_resp
def _handle_loop_next_event(self, event: QueueLoopNextEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_loop_next_event(self, event: QueueLoopNextEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop next events."""
self._ensure_workflow_initialized()
@@ -469,9 +455,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
)
yield loop_next_resp
def _handle_loop_completed_event(
self, event: QueueLoopCompletedEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_loop_completed_event(self, event: QueueLoopCompletedEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle loop completed events."""
self._ensure_workflow_initialized()
@@ -488,7 +472,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow succeeded events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -508,7 +492,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow partial success events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -526,7 +510,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
event: QueueWorkflowPausedEvent,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow paused events."""
self._ensure_workflow_initialized()
validated_state = self._ensure_graph_runtime_initialized()
@@ -543,7 +527,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
*,
trace_manager: TraceQueueManager | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle workflow failed and stop events."""
_ = trace_manager
self._ensure_workflow_initialized()
@@ -574,7 +558,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
tts_publisher: AppGeneratorTTSPublisher | None = None,
queue_message: Union[WorkflowQueueMessage, MessageQueueMessage] | None = None,
**kwargs,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle text chunk events."""
delta_text = event.text
if delta_text is None:
@@ -586,9 +570,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
yield self._text_chunk_to_stream_response(delta_text, from_variable_selector=event.from_variable_selector)
def _handle_reasoning_chunk_event(
self, event: QueueReasoningChunkEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
def _handle_reasoning_chunk_event(self, event: QueueReasoningChunkEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle reasoning chunk events."""
# is_final with empty reasoning is still forwarded as the "thinking finished" signal
if not event.reasoning and not event.is_final:
@@ -602,7 +584,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
),
)
def _handle_agent_log_event(self, event: QueueAgentLogEvent, **kwargs) -> Generator[StreamResponse, None, None]:
def _handle_agent_log_event(self, event: QueueAgentLogEvent, **kwargs) -> Generator[StreamResponse]:
"""Handle agent log events."""
yield self._workflow_response_converter.handle_agent_log(
task_id=self._application_generate_entity.task_id, event=event
@@ -610,7 +592,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_human_input_form_filled_event(
self, event: QueueHumanInputFormFilledEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle human input form filled events."""
yield self._workflow_response_converter.human_input_form_filled_to_stream_response(
event=event, task_id=self._application_generate_entity.task_id
@@ -618,7 +600,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
def _handle_human_input_form_timeout_event(
self, event: QueueHumanInputFormTimeoutEvent, **kwargs
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Handle human input form timeout events."""
yield self._workflow_response_converter.human_input_form_timeout_to_stream_response(
event=event, task_id=self._application_generate_entity.task_id
@@ -662,7 +644,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
tts_publisher: AppGeneratorTTSPublisher | None = None,
trace_manager: TraceQueueManager | None = None,
queue_message: Union[WorkflowQueueMessage, MessageQueueMessage] | None = None,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""Dispatch events using elegant pattern matching."""
handlers = self._get_event_handlers()
event_type = type(event)
@@ -710,7 +692,7 @@ class WorkflowAppGenerateTaskPipeline(GraphRuntimeStateSupport):
self,
tts_publisher: AppGeneratorTTSPublisher | None = None,
trace_manager: TraceQueueManager | None = None,
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""
Process stream response using elegant Fluent Python patterns.
Maintains exact same functionality as original 44-if-statement version.
@@ -99,7 +99,7 @@ class RateLimit:
def gen_request_key() -> str:
return str(uuid.uuid4())
def generate(self, generator: Union[Generator[str, None, None], Mapping[str, Any]], request_id: str):
def generate(self, generator: Union[Generator[str], Mapping[str, Any]], request_id: str):
if isinstance(generator, Mapping):
return generator
else:
@@ -119,7 +119,7 @@ def rate_limit_context(rate_limit: RateLimit, request_id: str | None):
class RateLimitGenerator:
def __init__(self, rate_limit: RateLimit, generator: Generator[str, None, None], request_id: str):
def __init__(self, rate_limit: RateLimit, generator: Generator[str], request_id: str):
self.rate_limit = rate_limit
self.generator = generator
self.request_id = request_id
+1 -1
View File
@@ -108,7 +108,7 @@ def is_retriever_segment_access_granted(segment_id: str) -> bool:
@contextmanager
def bind_file_access_scope(scope: FileAccessScope) -> Generator[None, None, None]:
def bind_file_access_scope(scope: FileAccessScope) -> Generator[None]:
token = _current_file_access_scope.set(scope)
try:
yield
@@ -120,7 +120,7 @@ class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline[EasyUIAppGenerat
) -> (
ChatbotAppBlockingResponse
| CompletionAppBlockingResponse
| Generator[ChatbotAppStreamResponse | CompletionAppStreamResponse, None, None]
| Generator[ChatbotAppStreamResponse | CompletionAppStreamResponse]
):
if self._application_generate_entity.app_config.app_mode != AppMode.COMPLETION:
# start generate conversation name thread
@@ -137,7 +137,7 @@ class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline[EasyUIAppGenerat
return self._to_blocking_response(generator)
def _to_blocking_response(
self, generator: Generator[StreamResponse, None, None]
self, generator: Generator[StreamResponse]
) -> ChatbotAppBlockingResponse | CompletionAppBlockingResponse:
"""
Process blocking response.
@@ -185,8 +185,8 @@ class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline[EasyUIAppGenerat
raise RuntimeError("queue listening stopped unexpectedly.")
def _to_stream_response(
self, generator: Generator[StreamResponse, None, None]
) -> Generator[ChatbotAppStreamResponse | CompletionAppStreamResponse, None, None]:
self, generator: Generator[StreamResponse]
) -> Generator[ChatbotAppStreamResponse | CompletionAppStreamResponse]:
"""
To stream response.
:return:
@@ -220,7 +220,7 @@ class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline[EasyUIAppGenerat
def _wrapper_process_stream_response(
self, trace_manager: TraceQueueManager | None = None
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
tenant_id = self._application_generate_entity.app_config.tenant_id
task_id = self._application_generate_entity.task_id
publisher = None
@@ -273,7 +273,7 @@ class EasyUIBasedGenerateTaskPipeline(BasedGenerateTaskPipeline[EasyUIAppGenerat
def _process_stream_response(
self, publisher: AppGeneratorTTSPublisher | None, trace_manager: TraceQueueManager | None = None
) -> Generator[StreamResponse, None, None]:
) -> Generator[StreamResponse]:
"""
Process stream response.
:return:
+3 -3
View File
@@ -148,9 +148,9 @@ class AudioStream(Iterator[bytes]):
"""Own a MIME-checked stream, including resources opened while peeking."""
def __init__(
self, chunks: Generator[bytes, None, None], *, source: Iterable[_AudioChunk], iterator: Iterator[_AudioChunk]
self, chunks: Generator[bytes], *, source: Iterable[_AudioChunk], iterator: Iterator[_AudioChunk]
) -> None:
self._chunks: Generator[bytes, None, None] = chunks
self._chunks: Generator[bytes] = chunks
self._source: Iterable[_AudioChunk] = source
self._iterator: Iterator[_AudioChunk] = iterator
self._closed: bool = False
@@ -209,7 +209,7 @@ def inspect_audio_stream(
close_stream(audio_stream)
raise
def validated_stream() -> Generator[bytes, None, None]:
def validated_stream() -> Generator[bytes]:
for chunk in chain(leading_chunks, iterator):
audio, chunk_mime_type = _extract_audio_chunk(chunk)
normalized_chunk_mime_type = _normalize_reported_mime_type(chunk_mime_type, "chunk")
@@ -18,7 +18,7 @@ class DifyWorkflowCallbackHandler(DifyAgentCallbackHandler):
message_id: str | None = None,
timer: Any | None = None,
trace_manager: TraceQueueManager | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
for tool_output in tool_outputs:
if dify_config.DEBUG:
print_text("\n[on_tool_execution]\n", color=self.color)
+2 -2
View File
@@ -169,7 +169,7 @@ class DatasourceManager:
doc_runtime.runtime.credentials = dict(credentials)
if datasource_param is None:
raise ValueError("datasource_param is required for ONLINE_DOCUMENT streaming")
inner_gen: Generator[DatasourceMessage, None, None] = doc_runtime.get_online_document_page_content(
inner_gen: Generator[DatasourceMessage] = doc_runtime.get_online_document_page_content(
user_id=user_id,
datasource_parameters=GetOnlineDocumentPageContentRequest(
workspace_id=datasource_param.workspace_id,
@@ -216,7 +216,7 @@ class DatasourceManager:
variable_pool: Any,
datasource_param: DatasourceParameter | None = None,
online_drive_request: OnlineDriveDownloadFileParam | None = None,
) -> Generator[StreamChunkEvent | StreamCompletedEvent, None, None]:
) -> Generator[StreamChunkEvent | StreamCompletedEvent]:
ds_type = DatasourceProviderType.value_of(datasource_type)
messages = cls.stream_online_results(
@@ -36,7 +36,7 @@ class OnlineDocumentDatasourcePlugin(DatasourcePlugin):
user_id: str,
datasource_parameters: dict[str, Any],
provider_type: str,
) -> Generator[OnlineDocumentPagesMessage, None, None]:
) -> Generator[OnlineDocumentPagesMessage]:
manager = PluginDatasourceManager()
return manager.get_online_document_pages(
@@ -54,7 +54,7 @@ class OnlineDocumentDatasourcePlugin(DatasourcePlugin):
user_id: str,
datasource_parameters: GetOnlineDocumentPageContentRequest,
provider_type: str,
) -> Generator[DatasourceMessage, None, None]:
) -> Generator[DatasourceMessage]:
manager = PluginDatasourceManager()
return manager.get_online_document_page_content(
@@ -37,7 +37,7 @@ class OnlineDriveDatasourcePlugin(DatasourcePlugin):
user_id: str,
request: OnlineDriveBrowseFilesRequest,
provider_type: str,
) -> Generator[OnlineDriveBrowseFilesResponse, None, None]:
) -> Generator[OnlineDriveBrowseFilesResponse]:
manager = PluginDatasourceManager()
return manager.online_drive_browse_files(
@@ -55,7 +55,7 @@ class OnlineDriveDatasourcePlugin(DatasourcePlugin):
user_id: str,
request: OnlineDriveDownloadFileRequest,
provider_type: str,
) -> Generator[DatasourceMessage, None, None]:
) -> Generator[DatasourceMessage]:
manager = PluginDatasourceManager()
return manager.online_drive_download_file(
@@ -15,11 +15,11 @@ class DatasourceFileMessageTransformer:
@classmethod
def transform_datasource_invoke_messages(
cls,
messages: Generator[DatasourceMessage, None, None],
messages: Generator[DatasourceMessage],
user_id: str,
tenant_id: str,
conversation_id: str | None = None,
) -> Generator[DatasourceMessage, None, None]:
) -> Generator[DatasourceMessage]:
"""
Transform datasource message and handle file download
"""
@@ -34,7 +34,7 @@ class WebsiteCrawlDatasourcePlugin(DatasourcePlugin):
user_id: str,
datasource_parameters: Mapping[str, Any],
provider_type: str,
) -> Generator[WebsiteCrawlMessage, None, None]:
) -> Generator[WebsiteCrawlMessage]:
manager = PluginDatasourceManager()
return manager.get_website_crawl(
@@ -57,7 +57,7 @@ def invoke_llm_with_structured_output(
stream: Literal[True],
callbacks: list[Callback] | None = None,
request_metadata: Mapping[str, object] | None = None,
) -> Generator[LLMResultChunkWithStructuredOutput, None, None]: ...
) -> Generator[LLMResultChunkWithStructuredOutput]: ...
@overload
def invoke_llm_with_structured_output(
*,
@@ -87,7 +87,7 @@ def invoke_llm_with_structured_output(
stream: bool = True,
callbacks: list[Callback] | None = None,
request_metadata: Mapping[str, object] | None = None,
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput, None, None]: ...
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput]: ...
def invoke_llm_with_structured_output(
*,
provider: str,
@@ -101,7 +101,7 @@ def invoke_llm_with_structured_output(
stream: bool = True,
callbacks: list[Callback] | None = None,
request_metadata: Mapping[str, object] | None = None,
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput, None, None]:
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput]:
"""
Invoke large language model with structured output
1. This method invokes model_instance.invoke_llm with json_schema
@@ -162,7 +162,7 @@ def invoke_llm_with_structured_output(
)
else:
def generator() -> Generator[LLMResultChunkWithStructuredOutput, None, None]:
def generator() -> Generator[LLMResultChunkWithStructuredOutput]:
result_text: str = ""
prompt_messages: Sequence[PromptMessage] = []
system_fingerprint: str | None = None
+2 -2
View File
@@ -261,7 +261,7 @@ def sse_client(
headers: dict[str, Any] | None = None,
timeout: float = 5.0,
sse_read_timeout: float = 1 * 60,
) -> Generator[tuple[ReadQueue, WriteQueue], None, None]:
) -> Generator[tuple[ReadQueue, WriteQueue]]:
"""
Client transport for SSE.
`sse_read_timeout` determines how long (in seconds) the client will wait for a new
@@ -352,7 +352,7 @@ def send_message(http_client: httpx.Client, endpoint_url: str, session_message:
def read_messages(
sse_client: SSEClient,
) -> Generator[SessionMessage | Exception, None, None]:
) -> Generator[SessionMessage | Exception]:
"""
Read messages from the SSE client.
-2
View File
@@ -491,8 +491,6 @@ def streamablehttp_client(
ClientToServerQueue, # Queue for sending messages TO server
GetSessionIdCallback,
],
None,
None,
]:
"""
Client transport for StreamableHTTP.
+1 -3
View File
@@ -127,9 +127,7 @@ def ssrf_proxy_sse_connect(url: str, **kwargs) -> AbstractContextManager[httpx_s
raise
def create_mcp_error_response(
request_id: int | str | None, code: int, message: str, data=None
) -> Generator[bytes, None, None]:
def create_mcp_error_response(request_id: int | str | None, code: int, message: str, data=None) -> Generator[bytes]:
"""Create MCP error response"""
error_data = ErrorData(code=code, message=message, data=data)
json_response = JSONRPCError(
+1 -1
View File
@@ -21,7 +21,7 @@ def get_credit_usage_metadata() -> Mapping[str, object] | None:
@contextmanager
def use_credit_usage_metadata(metadata: Mapping[str, object] | None) -> Generator[None, None, None]:
def use_credit_usage_metadata(metadata: Mapping[str, object] | None) -> Generator[None]:
if metadata is None:
yield
return
+1 -1
View File
@@ -803,7 +803,7 @@ class QuotaManagedModelInstance(ModelInstance):
content_text: str,
voice: str,
request_metadata: Mapping[str, object] | None = None,
) -> Generator[bytes, None, None]:
) -> Generator[bytes]:
effective_request_metadata = self._resolve_request_metadata(request_metadata)
reservation = self._reserve_quota_for_request(effective_request_metadata)
try:
+4 -4
View File
@@ -79,7 +79,7 @@ class PluginAppBackwardsInvocation(BaseBackwardsInvocation):
files: list[dict],
session: Session,
end_users: AppScopedEndUserProvisioner,
) -> Generator[Mapping | str, None, None] | Mapping:
) -> Generator[Mapping | str] | Mapping:
"""
invoke app
"""
@@ -122,7 +122,7 @@ class PluginAppBackwardsInvocation(BaseBackwardsInvocation):
inputs: Mapping,
files: list[dict],
session: Session,
) -> Generator[Mapping | str, None, None] | Mapping:
) -> Generator[Mapping | str] | Mapping:
"""
invoke chat app
"""
@@ -193,7 +193,7 @@ class PluginAppBackwardsInvocation(BaseBackwardsInvocation):
stream: bool,
inputs: Mapping,
files: list[dict],
) -> Generator[Mapping | str, None, None] | Mapping:
) -> Generator[Mapping | str] | Mapping:
"""
invoke workflow app
"""
@@ -222,7 +222,7 @@ class PluginAppBackwardsInvocation(BaseBackwardsInvocation):
inputs: Mapping,
files: list[dict],
session: Session,
) -> Generator[Mapping | str, None, None] | Mapping:
) -> Generator[Mapping | str] | Mapping:
"""
invoke completion app
"""
+1 -1
View File
@@ -5,7 +5,7 @@ from pydantic import BaseModel
class BaseBackwardsInvocation:
@classmethod
def convert_to_event_stream(cls, response: Generator[BaseModel | Mapping | str, None, None] | BaseModel | Mapping):
def convert_to_event_stream(cls, response: Generator[BaseModel | Mapping | str] | BaseModel | Mapping):
if isinstance(response, Generator):
try:
for chunk in response:
@@ -58,7 +58,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
@classmethod
def invoke_llm(
cls, user_id: str, tenant: Tenant, payload: RequestInvokeLLM
) -> Generator[LLMResultChunk, None, None] | LLMResult:
) -> Generator[LLMResultChunk] | LLMResult:
"""
invoke llm
"""
@@ -81,7 +81,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
if isinstance(response, Generator):
def handle() -> Generator[LLMResultChunk, None, None]:
def handle() -> Generator[LLMResultChunk]:
for chunk in response:
chunk.prompt_messages = []
yield chunk
@@ -89,7 +89,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
return handle()
else:
def handle_non_streaming(response: LLMResult) -> Generator[LLMResultChunk, None, None]:
def handle_non_streaming(response: LLMResult) -> Generator[LLMResultChunk]:
yield LLMResultChunk(
model=response.model,
prompt_messages=[],
@@ -138,7 +138,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
if isinstance(response, Generator):
def handle() -> Generator[LLMResultChunkWithStructuredOutput, None, None]:
def handle() -> Generator[LLMResultChunkWithStructuredOutput]:
for chunk in response:
chunk.prompt_messages = []
yield chunk
@@ -148,7 +148,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
def handle_non_streaming(
response: LLMResultWithStructuredOutput,
) -> Generator[LLMResultChunkWithStructuredOutput, None, None]:
) -> Generator[LLMResultChunkWithStructuredOutput]:
yield LLMResultChunkWithStructuredOutput(
model=response.model,
prompt_messages=[],
@@ -218,7 +218,7 @@ class PluginModelBackwardsInvocation(BaseBackwardsInvocation):
model=payload.model,
)
def handle() -> Generator[dict[str, Any], None, None]:
def handle() -> Generator[dict[str, Any]]:
response = model_instance.invoke_tts(content_text=payload.content_text, voice=payload.voice)
audio_stream, mime_type = inspect_audio_stream(response, get_model_audio_mime_type(model_instance))
for chunk in audio_stream:
+1 -1
View File
@@ -27,7 +27,7 @@ class PluginToolBackwardsInvocation(BaseBackwardsInvocation):
tool_name: str,
tool_parameters: dict[str, Any],
credential_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
invoke tool
"""
+1 -1
View File
@@ -86,7 +86,7 @@ class PluginAgentClient(BasePluginClient):
app_id: str | None = None,
message_id: str | None = None,
context: PluginInvokeContext | None = None,
) -> Generator[AgentInvokeMessage, None, None]:
) -> Generator[AgentInvokeMessage]:
"""
Invoke the agent with the given tenant, user, plugin, provider, name and parameters.
"""
+4 -4
View File
@@ -79,7 +79,7 @@ _httpx_client: httpx.Client = get_pooled_http_client(
@contextmanager
def use_plugin_daemon_request_timeout(timeout_seconds: float) -> Generator[None, None, None]:
def use_plugin_daemon_request_timeout(timeout_seconds: float) -> Generator[None]:
"""Temporarily shorten plugin-daemon requests made in the current context."""
if timeout_seconds <= 0:
raise ValueError("timeout_seconds must be greater than zero")
@@ -227,7 +227,7 @@ class BasePluginClient:
headers: dict[str, str] | None = None,
data: bytes | dict[str, Any] | None = None,
files: dict[str, Any] | None = None,
) -> Generator[str, None, None]:
) -> Generator[str]:
"""
Make a stream request to the plugin daemon inner API
"""
@@ -270,7 +270,7 @@ class BasePluginClient:
data: bytes | dict[str, Any] | None = None,
params: dict[str, Any] | None = None,
files: dict[str, Any] | None = None,
) -> Generator[T, None, None]:
) -> Generator[T]:
"""
Make a stream request to the plugin daemon inner API and yield the response as a model.
"""
@@ -358,7 +358,7 @@ class BasePluginClient:
data: bytes | dict[str, Any] | None = None,
params: dict[str, Any] | None = None,
files: dict[str, Any] | None = None,
) -> Generator[T, None, None]:
) -> Generator[T]:
"""
Make a stream request to the plugin daemon inner API and yield the response as a model.
"""
+5 -5
View File
@@ -144,7 +144,7 @@ class PluginDatasourceManager(BasePluginClient):
credentials: dict[str, Any],
datasource_parameters: Mapping[str, Any],
provider_type: str,
) -> Generator[WebsiteCrawlMessage, None, None]:
) -> Generator[WebsiteCrawlMessage]:
"""
Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
@@ -179,7 +179,7 @@ class PluginDatasourceManager(BasePluginClient):
credentials: dict[str, Any],
datasource_parameters: Mapping[str, Any],
provider_type: str,
) -> Generator[OnlineDocumentPagesMessage, None, None]:
) -> Generator[OnlineDocumentPagesMessage]:
"""
Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
@@ -214,7 +214,7 @@ class PluginDatasourceManager(BasePluginClient):
credentials: dict[str, Any],
datasource_parameters: GetOnlineDocumentPageContentRequest,
provider_type: str,
) -> Generator[DatasourceMessage, None, None]:
) -> Generator[DatasourceMessage]:
"""
Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
@@ -249,7 +249,7 @@ class PluginDatasourceManager(BasePluginClient):
credentials: dict[str, Any],
request: OnlineDriveBrowseFilesRequest,
provider_type: str,
) -> Generator[OnlineDriveBrowseFilesResponse, None, None]:
) -> Generator[OnlineDriveBrowseFilesResponse]:
"""
Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
@@ -285,7 +285,7 @@ class PluginDatasourceManager(BasePluginClient):
credentials: dict[str, Any],
request: OnlineDriveDownloadFileRequest,
provider_type: str,
) -> Generator[DatasourceMessage, None, None]:
) -> Generator[DatasourceMessage]:
"""
Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
+2 -2
View File
@@ -181,7 +181,7 @@ class PluginModelClient(BasePluginClient):
stop: list[str] | None = None,
stream: bool = True,
app_id: str | None = None,
) -> Generator[LLMResultChunk, None, None]:
) -> Generator[LLMResultChunk]:
"""
Invoke llm
"""
@@ -582,7 +582,7 @@ class PluginModelClient(BasePluginClient):
credentials: dict[str, Any],
content_text: str,
voice: str,
) -> Generator[TTSAudioChunk, None, None]:
) -> Generator[TTSAudioChunk]:
"""
Invoke tts
"""
+5 -5
View File
@@ -77,7 +77,7 @@ class _PluginStructuredOutputModelInstance:
stop: Sequence[str] | None = None,
stream: bool = True,
callbacks: object | None = None,
) -> LLMResult | Generator[LLMResultChunk, None, None]:
) -> LLMResult | Generator[LLMResultChunk]:
del callbacks
if stream:
return self._runtime.invoke_llm(
@@ -303,7 +303,7 @@ class PluginModelRuntime(ModelRuntime):
stop: Sequence[str] | None,
stream: Literal[True],
request_metadata: Mapping[str, object] | None = None,
) -> Generator[LLMResultChunk, None, None]: ...
) -> Generator[LLMResultChunk]: ...
@override
def invoke_llm(
@@ -318,7 +318,7 @@ class PluginModelRuntime(ModelRuntime):
stop: Sequence[str] | None,
stream: bool,
request_metadata: Mapping[str, object] | None = None,
) -> LLMResult | Generator[LLMResultChunk, None, None]:
) -> LLMResult | Generator[LLMResultChunk]:
app_id = request_metadata.get("app_id") if request_metadata else None
if not isinstance(app_id, str):
app_id = None
@@ -387,7 +387,7 @@ class PluginModelRuntime(ModelRuntime):
prompt_messages: Sequence[PromptMessage],
stop: Sequence[str] | None,
stream: Literal[True],
) -> Generator[LLMResultChunkWithStructuredOutput, None, None]: ...
) -> Generator[LLMResultChunkWithStructuredOutput]: ...
@override
def invoke_llm_with_structured_output(
@@ -401,7 +401,7 @@ class PluginModelRuntime(ModelRuntime):
prompt_messages: Sequence[PromptMessage],
stop: Sequence[str] | None,
stream: bool,
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput, None, None]:
) -> LLMResultWithStructuredOutput | Generator[LLMResultChunkWithStructuredOutput]:
model_schema = self.get_model_schema(
provider=provider,
model_type=ModelType.LLM,
+1 -1
View File
@@ -94,7 +94,7 @@ class PluginToolManager(BasePluginClient):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Invoke the tool with the given tenant, user, plugin, provider, name, credentials and parameters.
"""
+5 -5
View File
@@ -95,7 +95,7 @@ class PluginTriggerClient(BasePluginClient):
Invoke a trigger with the given parameters.
"""
provider_id = TriggerProviderID(provider)
response: Generator[TriggerInvokeEventResponse, None, None] = self._request_with_plugin_daemon_response_stream(
response: Generator[TriggerInvokeEventResponse] = self._request_with_plugin_daemon_response_stream(
method="POST",
path=f"plugin/{tenant_id}/dispatch/trigger/invoke_event",
type_=TriggerInvokeEventResponse,
@@ -130,7 +130,7 @@ class PluginTriggerClient(BasePluginClient):
Validate the credentials of the trigger provider.
"""
provider_id = TriggerProviderID(provider)
response: Generator[TriggerValidateProviderCredentialsResponse, None, None] = (
response: Generator[TriggerValidateProviderCredentialsResponse] = (
self._request_with_plugin_daemon_response_stream(
method="POST",
path=f"plugin/{tenant_id}/dispatch/trigger/validate_credentials",
@@ -205,7 +205,7 @@ class PluginTriggerClient(BasePluginClient):
Subscribe to a trigger.
"""
provider_id = TriggerProviderID(provider)
response: Generator[TriggerSubscriptionResponse, None, None] = self._request_with_plugin_daemon_response_stream(
response: Generator[TriggerSubscriptionResponse] = self._request_with_plugin_daemon_response_stream(
method="POST",
path=f"plugin/{tenant_id}/dispatch/trigger/subscribe",
type_=TriggerSubscriptionResponse,
@@ -243,7 +243,7 @@ class PluginTriggerClient(BasePluginClient):
Unsubscribe from a trigger.
"""
provider_id = TriggerProviderID(provider)
response: Generator[TriggerSubscriptionResponse, None, None] = self._request_with_plugin_daemon_response_stream(
response: Generator[TriggerSubscriptionResponse] = self._request_with_plugin_daemon_response_stream(
method="POST",
path=f"plugin/{tenant_id}/dispatch/trigger/unsubscribe",
type_=TriggerSubscriptionResponse,
@@ -280,7 +280,7 @@ class PluginTriggerClient(BasePluginClient):
Refresh a trigger subscription.
"""
provider_id = TriggerProviderID(provider)
response: Generator[TriggerSubscriptionResponse, None, None] = self._request_with_plugin_daemon_response_stream(
response: Generator[TriggerSubscriptionResponse] = self._request_with_plugin_daemon_response_stream(
method="POST",
path=f"plugin/{tenant_id}/dispatch/trigger/refresh",
type_=TriggerSubscriptionResponse,
+2 -2
View File
@@ -20,10 +20,10 @@ class FileChunk:
def merge_blob_chunks[T: ToolInvokeMessage | AgentInvokeMessage](
response: Generator[T, None, None],
response: Generator[T],
max_file_size: int = 30 * 1024 * 1024,
max_chunk_size: int = 8192,
) -> Generator[T, None, None]:
) -> Generator[T]:
"""
Merge streaming blob chunks into complete blob messages.
+1 -1
View File
@@ -77,7 +77,7 @@ class Blob(BaseModel):
raise ValueError(f"Unable to get bytes for blob {self}")
@contextlib.contextmanager
def as_bytes_io(self) -> Generator[BytesIO | BufferedReader, None, None]:
def as_bytes_io(self) -> Generator[BytesIO | BufferedReader]:
"""Read data as a byte stream."""
match self.data:
case bytes():
@@ -123,7 +123,7 @@ class WaterCrawlProvider:
def _get_results(
self, crawl_request_id: str, query_params: dict[str, Any] | None = None
) -> Generator[WatercrawlDocumentData, None, None]:
) -> Generator[WatercrawlDocumentData]:
page = 0
page_size = 100
@@ -1,6 +1,5 @@
"""Abstract interface for document loader implementations."""
import cgi
import logging
import mimetypes
import os
@@ -13,6 +12,7 @@ from urllib.parse import unquote, urlparse
import httpx
from sqlalchemy import select
from sqlalchemy.orm import Session
from werkzeug.http import parse_options_header
from configs import dify_config
from core.entities.knowledge_entities import PreviewDetail
@@ -278,10 +278,10 @@ class BaseIndexProcessor(ABC):
content_disposition = response.headers.get("content-disposition")
if content_disposition:
_, params = cgi.parse_header(content_disposition)
_, params = parse_options_header(content_disposition)
if "filename" in params:
# Werkzeug decodes filename*; preserve literal percent escapes in the result.
filename = params["filename"]
filename = unquote(filename)
if not filename:
parsed_url = urlparse(image_url)
+1 -1
View File
@@ -1643,7 +1643,7 @@ class DatasetRetrieval:
try:
# handle invoke result
invoke_result = cast(
Generator[LLMResult, None, None],
Generator[LLMResult],
model_instance.invoke_llm(
prompt_messages=prompt_messages,
model_parameters=model_config.parameters,
@@ -160,7 +160,7 @@ class ReactMultiDatasetRouter:
model_type=ModelType.LLM,
model=model_instance.model_name,
)
invoke_result: Generator[LLMResult, None, None] = bound_model_instance.invoke_llm(
invoke_result: Generator[LLMResult] = bound_model_instance.invoke_llm(
prompt_messages=prompt_messages,
model_parameters=completion_param,
stop=stop,
+3 -3
View File
@@ -72,13 +72,13 @@ class Tool(ABC):
match result:
case ToolInvokeMessage():
def single_generator() -> Generator[ToolInvokeMessage, None, None]:
def single_generator() -> Generator[ToolInvokeMessage]:
yield result
return single_generator()
case list():
def generator() -> Generator[ToolInvokeMessage, None, None]:
def generator() -> Generator[ToolInvokeMessage]:
yield from result
return generator()
@@ -106,7 +106,7 @@ class Tool(ABC):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> ToolInvokeMessage | list[ToolInvokeMessage] | Generator[ToolInvokeMessage, None, None]:
) -> ToolInvokeMessage | list[ToolInvokeMessage] | Generator[ToolInvokeMessage]:
pass
def get_runtime_parameters(
@@ -28,7 +28,7 @@ class ASRTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
if not self.runtime:
raise ValueError("Runtime is required")
runtime = self.runtime
@@ -26,7 +26,7 @@ class TTSTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
if not self.runtime:
raise ValueError("Runtime is required")
runtime = self.runtime
@@ -19,7 +19,7 @@ class SimpleCode(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
invoke simple code
"""
@@ -19,7 +19,7 @@ class CurrentTimeTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
invoke tools
"""
@@ -20,7 +20,7 @@ class LocaltimeToTimestampTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Convert localtime to timestamp
"""
@@ -20,7 +20,7 @@ class TimestampToLocaltimeTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Convert timestamp to localtime
"""
@@ -20,7 +20,7 @@ class TimezoneConversionTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Convert time to equivalent time zone
"""
@@ -19,7 +19,7 @@ class WeekdayTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Calculate the day of the week for a given date
"""
@@ -19,7 +19,7 @@ class WebscraperTool(BuiltinTool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
invoke tools
"""
+1 -1
View File
@@ -387,7 +387,7 @@ class ApiTool(Tool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
invoke http request
"""
+4 -4
View File
@@ -74,7 +74,7 @@ class MCPTool(Tool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
result = self.invoke_remote_mcp_tool(tool_parameters, user_id=user_id, app_id=app_id)
# Extract usage metadata from MCP protocol's _meta field
@@ -111,7 +111,7 @@ class MCPTool(Tool):
elif result.structuredContent:
yield self.create_json_message(result.structuredContent)
def _process_text_content(self, content: TextContent) -> Generator[ToolInvokeMessage, None, None]:
def _process_text_content(self, content: TextContent) -> Generator[ToolInvokeMessage]:
"""Process text content and yield appropriate messages."""
# Check if content looks like JSON before attempting to parse
text = content.text.strip()
@@ -126,7 +126,7 @@ class MCPTool(Tool):
# If not JSON or parsing failed, treat as plain text
yield self.create_text_message(content.text)
def _process_json_content(self, content_json: Any) -> Generator[ToolInvokeMessage, None, None]:
def _process_json_content(self, content_json: Any) -> Generator[ToolInvokeMessage]:
"""Process JSON content based on its type."""
match content_json:
case dict():
@@ -137,7 +137,7 @@ class MCPTool(Tool):
# For primitive types (str, int, bool, etc.), convert to string
yield self.create_text_message(str(content_json))
def _process_json_list(self, json_list: list) -> Generator[ToolInvokeMessage, None, None]:
def _process_json_list(self, json_list: list) -> Generator[ToolInvokeMessage]:
"""Process a list of JSON items."""
if any(not isinstance(item, dict) for item in json_list):
# If the list contains any non-dict item, treat the entire list as a text message.
+1 -1
View File
@@ -35,7 +35,7 @@ class PluginTool(Tool):
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
manager = PluginToolManager()
tool_parameters = convert_parameters_to_plugin_format(tool_parameters)
+4 -4
View File
@@ -88,7 +88,7 @@ class ToolEngine:
def message_callback(
invocation_meta_dict: dict[str, ToolInvokeMeta],
messages: Generator[ToolInvokeMessage | ToolInvokeMeta, None, None],
messages: Generator[ToolInvokeMessage | ToolInvokeMeta],
):
for message in messages:
if isinstance(message, ToolInvokeMeta):
@@ -167,7 +167,7 @@ class ToolEngine:
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
) -> Generator[ToolInvokeMessage]:
"""
Workflow invokes the tool with the given arguments.
"""
@@ -211,7 +211,7 @@ class ToolEngine:
conversation_id: str | None = None,
app_id: str | None = None,
message_id: str | None = None,
) -> Generator[ToolInvokeMessage | ToolInvokeMeta, None, None]:
) -> Generator[ToolInvokeMessage | ToolInvokeMeta]:
"""
Invoke the tool with the given arguments.
"""
@@ -288,7 +288,7 @@ class ToolEngine:
@staticmethod
def _extract_tool_response_binary_and_text(
tool_response: list[ToolInvokeMessage],
) -> Generator[ToolInvokeMessageBinary, None, None]:
) -> Generator[ToolInvokeMessageBinary]:
"""
Extract tool response binary
"""
+2 -2
View File
@@ -606,7 +606,7 @@ class ToolManager:
@classmethod
def list_builtin_providers(
cls, tenant_id: str
) -> Generator[BuiltinToolProviderController | PluginToolProviderController, None, None]:
) -> Generator[BuiltinToolProviderController | PluginToolProviderController]:
"""
list all the builtin providers
"""
@@ -615,7 +615,7 @@ class ToolManager:
yield from cls.list_plugin_providers(tenant_id)
@classmethod
def _list_hardcoded_providers(cls) -> Generator[BuiltinToolProviderController, None, None]:
def _list_hardcoded_providers(cls) -> Generator[BuiltinToolProviderController]:
"""
list all the builtin providers
"""
Loaded 100 of 215 files, more files were not shown because too many files have changed in this diff. Show more