mirror of
https://github.com/langgenius/dify.git
synced 2026-11-10 21:35:45 +08:00
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:
215 files changed
+1582
-1738
No files matched your search
@@ -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,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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- '3.12'
|
||||
- '3.13'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- '3.12'
|
||||
- '3.13'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- '3.12'
|
||||
- '3.13'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -491,8 +491,6 @@ def streamablehttp_client(
|
||||
ClientToServerQueue, # Queue for sending messages TO server
|
||||
GetSessionIdCallback,
|
||||
],
|
||||
None,
|
||||
None,
|
||||
]:
|
||||
"""
|
||||
Client transport for StreamableHTTP.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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
Reference in new issue
Block a user