mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: replace pre-commit with prek, add PEP 723 script deps, clean up dev dependencies (#3748)
* python: replace pre-commit with prek, add PEP 723 script deps, clean up dev dependencies - Replace pre-commit with prek (Rust-native, faster pre-commit alternative) - Move supported hooks to repo: builtin for zero-clone speed - Add new builtin hooks: trailing-whitespace, check-merge-conflict, detect-private-key, check-added-large-files - Update all hook versions to latest (pre-commit-hooks v6, pyupgrade v3.21.2, bandit 1.9.3, uv-pre-commit 0.10.0) - Add PEP 723 inline script metadata to 34 samples with external deps - Remove autogen-agentchat/autogen-ext from dev deps (now declared per-sample) - Remove unused dev deps: pytest-env, tomli-w - Add agent-framework-core>=1.0.0b260130 lower bound to all 21 packages - Update CI workflow to use j178/prek-action - Update docs: DEV_SETUP.md, AGENTS.md, CODING_STANDARD.md, SAMPLE_GUIDELINES.md * updated lock * python: fix prek config paths for local execution and CI workflow Remove global 'files: ^python/' filter and strip python/ prefix from all path patterns in .pre-commit-config.yaml so prek finds files when run from the python/ directory. Update CI workflow to use --cd python instead of --config path. Include trailing whitespace fixes and dev dependency cleanup. * python: move helper scripts to scripts/ folder and exclude from checks * python: exclude AGENTS.md from prek markdown code lint * python: exclude AGENTS.md and azure_ai_search sample from markdown lint * fix m365 sample * python: ignore CPY rule for samples with PEP 723 headers * fix in dev_setup * python: replace aiofiles with regular open in samples * python: suppress reportUnusedImport in markdown code block checker * python: use samples pyright config for markdown code block checker Write a temp pyrightconfig.json matching pyrightconfig.samples.json rules (typeCheckingMode=off, only reportMissingImports and reportAttributeAccessIssue). Filter output to only fail on these rules since syntax-level errors (top-level await, undefined vars) are expected in README documentation snippets. * python: use markdown-code-lint with fixed globs instead of prek file list The prek-markdown-code-lint task received all changed files including non-README markdown and files with pre-existing broken imports. Replace with the standard markdown-code-lint task which uses the correct glob patterns (README.md, packages/**/README.md, samples/**/*.md). * python: exclude READMEs with pre-existing broken imports from markdown lint * python: fix broken README code snippets instead of excluding them - ag-ui: replace TextContent (removed) with content.type == 'text' - durabletask: fix import path to durabletask.worker.TaskHubGrpcWorker - orchestrations: use constructor params instead of .participants() method - observability: mark deprecated code blocks as plain text, filter reportMissingImports to agent_framework modules only - remove README excludes from markdown-code-lint task * add revision to gaia download * feat(python): parallelize checks across packages Run (package × task) cross-product in parallel using ThreadPoolExecutor and subprocesses. Key changes: - Add scripts/task_runner.py with shared parallel execution engine - Update run_tasks_in_packages_if_exists.py to accept multiple tasks - Update run_tasks_in_changed_packages.py with --files flag and parallel support - Add check-packages poe task (fmt+lint+pyright+mypy in parallel) - Add prek-markdown-code-lint and prek-samples-check with change detection - Split CI code quality workflow into parallel prek and mypy jobs - Update DEV_SETUP.md to document new parallel behavior Core package changes still trigger checks on all packages. * feat(ci): split code quality into 4 parallel jobs Split the single prek job into parallel jobs: - pre-commit-hooks: lightweight hooks (SKIP=poe-check) - package-checks: fmt/lint/pyright/mypy via check-packages - samples-markdown: samples-lint, samples-syntax, markdown-code-lint - mypy: change-detected mypy checks All 4 jobs run concurrently (×2 Python versions = 8 runners). * feat(ci): use only Python 3.10 for code quality checks * refactor(python): add future annotations and remove quoted types Add `from __future__ import annotations` to 93 package files that used quoted string annotations, then run pyupgrade --py310-plus to remove the now-unnecessary quotes. Fixes https://github.com/microsoft/agent-framework/issues/3578
This commit is contained in:
committed by
GitHub
Unverified
parent
ad0dac3c86
commit
977c3adfb2
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Callable, Mapping
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import MutableMapping
|
||||
from contextvars import ContextVar
|
||||
@@ -101,7 +103,7 @@ class Property(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "Property":
|
||||
) -> Property:
|
||||
"""Create a Property instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Property class
|
||||
if cls is not Property:
|
||||
@@ -211,7 +213,7 @@ class PropertySchema(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "PropertySchema":
|
||||
) -> PropertySchema:
|
||||
"""Create a PropertySchema instance from a dictionary, filtering out 'kind' field."""
|
||||
# Filter out 'kind', 'type', 'name', and 'description' fields that may appear in YAML
|
||||
# but aren't PropertySchema params
|
||||
@@ -491,7 +493,7 @@ class AgentDefinition(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "AgentDefinition":
|
||||
) -> AgentDefinition:
|
||||
"""Create an AgentDefinition instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base AgentDefinition class
|
||||
if cls is not AgentDefinition:
|
||||
@@ -537,7 +539,7 @@ class Tool(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls: type[TTool], value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "TTool":
|
||||
) -> TTool:
|
||||
"""Create a Tool instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Tool class
|
||||
if cls is not Tool:
|
||||
@@ -867,7 +869,7 @@ class Resource(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "Resource":
|
||||
) -> Resource:
|
||||
"""Create a Resource instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Resource class
|
||||
if cls is not Resource:
|
||||
|
||||
+4
-2
@@ -7,6 +7,8 @@ This module implements handlers for:
|
||||
- InvokePromptAgent: Invoke a local prompt-based agent
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import Any, cast
|
||||
@@ -185,7 +187,7 @@ def _build_messages_from_state(ctx: ActionContext) -> list[ChatMessage]:
|
||||
|
||||
|
||||
@action_handler("InvokeAzureAgent")
|
||||
async def handle_invoke_azure_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_invoke_azure_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Invoke a hosted Azure AI agent.
|
||||
|
||||
Supports both Python-style and .NET-style YAML schemas:
|
||||
@@ -523,7 +525,7 @@ def _normalize_variable_path(variable: str) -> str:
|
||||
|
||||
|
||||
@action_handler("InvokePromptAgent")
|
||||
async def handle_invoke_prompt_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_invoke_prompt_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Invoke a local prompt-based agent (similar to InvokeAzureAgent but for local agents).
|
||||
|
||||
Action schema:
|
||||
|
||||
+17
-15
@@ -16,6 +16,8 @@ network calls. The `return; yield` pattern makes a function an async generator w
|
||||
actually yielding any events.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
@@ -37,7 +39,7 @@ logger = get_logger("agent_framework.declarative.workflows.actions")
|
||||
|
||||
|
||||
@action_handler("SetValue")
|
||||
async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a value in the workflow state.
|
||||
|
||||
Action schema:
|
||||
@@ -63,7 +65,7 @@ async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent,
|
||||
|
||||
|
||||
@action_handler("SetVariable")
|
||||
async def handle_set_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a variable in the workflow state (.NET workflow format).
|
||||
|
||||
This is an alias for SetValue with 'variable' instead of 'path'.
|
||||
@@ -113,7 +115,7 @@ def _normalize_variable_path(variable: str) -> str:
|
||||
|
||||
|
||||
@action_handler("AppendValue")
|
||||
async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Append a value to a list in the workflow state.
|
||||
|
||||
Action schema:
|
||||
@@ -139,7 +141,7 @@ async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEven
|
||||
|
||||
|
||||
@action_handler("SendActivity")
|
||||
async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Send text or attachments to the user.
|
||||
|
||||
Action schema (object form):
|
||||
@@ -189,7 +191,7 @@ async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEve
|
||||
|
||||
|
||||
@action_handler("EmitEvent")
|
||||
async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Emit a custom workflow event.
|
||||
|
||||
Action schema:
|
||||
@@ -213,7 +215,7 @@ async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent,
|
||||
yield CustomEvent(name=name, data=evaluated_data)
|
||||
|
||||
|
||||
def _evaluate_dict_values(d: dict[str, Any], state: "WorkflowState") -> dict[str, Any]:
|
||||
def _evaluate_dict_values(d: dict[str, Any], state: WorkflowState) -> dict[str, Any]:
|
||||
"""Recursively evaluate PowerFx expressions in a dictionary.
|
||||
|
||||
Args:
|
||||
@@ -245,7 +247,7 @@ def _evaluate_dict_values(d: dict[str, Any], state: "WorkflowState") -> dict[str
|
||||
|
||||
|
||||
@action_handler("SetTextVariable")
|
||||
async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a text variable with string interpolation support.
|
||||
|
||||
This is similar to SetVariable but supports multi-line text with
|
||||
@@ -281,7 +283,7 @@ async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[Workflo
|
||||
|
||||
|
||||
@action_handler("SetMultipleVariables")
|
||||
async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set multiple variables at once.
|
||||
|
||||
Action schema:
|
||||
@@ -313,7 +315,7 @@ async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[Wo
|
||||
|
||||
|
||||
@action_handler("ResetVariable")
|
||||
async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Reset a variable to its default/blank state.
|
||||
|
||||
Action schema:
|
||||
@@ -336,7 +338,7 @@ async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEv
|
||||
|
||||
|
||||
@action_handler("ClearAllVariables")
|
||||
async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Clear all turn-scoped variables.
|
||||
|
||||
Action schema:
|
||||
@@ -350,7 +352,7 @@ async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[Workf
|
||||
|
||||
|
||||
@action_handler("CreateConversation")
|
||||
async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Create a new conversation context.
|
||||
|
||||
Action schema (.NET style):
|
||||
@@ -399,7 +401,7 @@ async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[Workf
|
||||
|
||||
|
||||
@action_handler("AddConversationMessage")
|
||||
async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Add a message to a conversation.
|
||||
|
||||
Action schema:
|
||||
@@ -451,7 +453,7 @@ async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[
|
||||
|
||||
|
||||
@action_handler("CopyConversationMessages")
|
||||
async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Copy messages from one conversation to another.
|
||||
|
||||
Action schema:
|
||||
@@ -506,7 +508,7 @@ async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerato
|
||||
|
||||
|
||||
@action_handler("RetrieveConversationMessages")
|
||||
async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Retrieve messages from a conversation and store in a variable.
|
||||
|
||||
Action schema:
|
||||
@@ -547,7 +549,7 @@ async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGene
|
||||
yield # Make it a generator
|
||||
|
||||
|
||||
def _interpolate_string(text: str, state: "WorkflowState") -> str:
|
||||
def _interpolate_string(text: str, state: WorkflowState) -> str:
|
||||
"""Interpolate {Variable.Path} references in a string.
|
||||
|
||||
Args:
|
||||
|
||||
+4
-2
@@ -7,6 +7,8 @@ This module implements handlers for:
|
||||
- TryCatch: Try-catch-finally error handling
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from dataclasses import dataclass
|
||||
|
||||
@@ -44,7 +46,7 @@ class ErrorEvent(WorkflowEvent):
|
||||
|
||||
|
||||
@action_handler("ThrowException")
|
||||
async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Raise an exception that can be caught by TryCatch.
|
||||
|
||||
Action schema:
|
||||
@@ -67,7 +69,7 @@ async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowE
|
||||
|
||||
|
||||
@action_handler("TryCatch")
|
||||
async def handle_try_catch(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_try_catch(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Try-catch-finally error handling.
|
||||
|
||||
Action schema:
|
||||
|
||||
+4
-2
@@ -23,6 +23,8 @@ the full RecalcEngine API. We work around this by:
|
||||
See: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PowerFx/
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
@@ -148,7 +150,7 @@ class DeclarativeWorkflowState:
|
||||
"""
|
||||
self._state = state
|
||||
|
||||
def initialize(self, inputs: "Mapping[str, Any] | None" = None) -> None:
|
||||
def initialize(self, inputs: Mapping[str, Any] | None = None) -> None:
|
||||
"""Initialize the declarative state with inputs.
|
||||
|
||||
Args:
|
||||
@@ -814,7 +816,7 @@ class DeclarativeActionExecutor(Executor):
|
||||
|
||||
async def _ensure_state_initialized(
|
||||
self,
|
||||
ctx: "WorkflowContext[Any, Any]",
|
||||
ctx: WorkflowContext[Any, Any],
|
||||
trigger: Any,
|
||||
) -> DeclarativeWorkflowState:
|
||||
"""Ensure declarative state is initialized.
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ action definitions and creates a proper workflow graph with:
|
||||
- Loop edges for foreach
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from agent_framework._workflows import (
|
||||
|
||||
@@ -10,6 +10,8 @@ Each YAML action becomes a real Executor node in the workflow graph,
|
||||
enabling checkpointing, visualization, and pause/resume capabilities.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
@@ -506,7 +508,7 @@ class WorkflowFactory:
|
||||
f"Invalid agent definition. Expected 'file', 'kind', or 'connection': {agent_def}"
|
||||
)
|
||||
|
||||
def register_agent(self, name: str, agent: SupportsAgentRun | AgentExecutor) -> "WorkflowFactory":
|
||||
def register_agent(self, name: str, agent: SupportsAgentRun | AgentExecutor) -> WorkflowFactory:
|
||||
"""Register an agent instance with the factory for use in workflows.
|
||||
|
||||
Registered agents are available to InvokeAzureAgent actions by name.
|
||||
@@ -552,7 +554,7 @@ class WorkflowFactory:
|
||||
self._agents[name] = agent
|
||||
return self
|
||||
|
||||
def register_binding(self, name: str, func: Any) -> "WorkflowFactory":
|
||||
def register_binding(self, name: str, func: Any) -> WorkflowFactory:
|
||||
"""Register a function binding with the factory for use in workflow actions.
|
||||
|
||||
Bindings allow workflow actions to invoke Python functions by name.
|
||||
|
||||
@@ -7,6 +7,8 @@ workflow actions defined in YAML. Each action type (InvokeAzureAgent, Foreach, e
|
||||
has a corresponding handler registered via the @action_handler decorator.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
|
||||
@@ -27,13 +29,13 @@ class ActionContext:
|
||||
for executing nested actions (for control flow constructs like Foreach).
|
||||
"""
|
||||
|
||||
state: "WorkflowState"
|
||||
state: WorkflowState
|
||||
"""The current workflow state with variables and agent results."""
|
||||
|
||||
action: dict[str, Any]
|
||||
"""The action definition from the YAML."""
|
||||
|
||||
execute_actions: "ExecuteActionsFn"
|
||||
execute_actions: ExecuteActionsFn
|
||||
"""Function to execute a list of nested actions (for Foreach, If, etc.)."""
|
||||
|
||||
agents: dict[str, Any]
|
||||
@@ -150,7 +152,7 @@ class ActionHandler(Protocol):
|
||||
def __call__(
|
||||
self,
|
||||
ctx: ActionContext,
|
||||
) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Execute the action and yield events.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -8,6 +8,8 @@ This module implements handlers for human input patterns:
|
||||
- ExternalLoop processing: Loop while waiting for external input
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
@@ -75,7 +77,7 @@ class ExternalLoopEvent(WorkflowEvent):
|
||||
|
||||
|
||||
@action_handler("Question")
|
||||
async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle Question action - request human input with optional validation.
|
||||
|
||||
Action schema:
|
||||
@@ -140,7 +142,7 @@ async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, N
|
||||
|
||||
|
||||
@action_handler("RequestExternalInput")
|
||||
async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle RequestExternalInput action - request input from external system.
|
||||
|
||||
Action schema:
|
||||
@@ -197,7 +199,7 @@ async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[Wo
|
||||
|
||||
|
||||
@action_handler("WaitForInput")
|
||||
async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle WaitForInput action - pause and wait for external input.
|
||||
|
||||
Action schema:
|
||||
@@ -231,7 +233,7 @@ async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEv
|
||||
|
||||
def process_external_loop(
|
||||
input_config: dict[str, Any],
|
||||
state: "WorkflowState",
|
||||
state: WorkflowState,
|
||||
) -> tuple[bool, str | None]:
|
||||
"""Process the externalLoop.when pattern from action input.
|
||||
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ These functions can be used as fallbacks when PowerFx is not available,
|
||||
or registered with the PowerFx engine when it is available.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ This module provides state management for declarative workflows, handling:
|
||||
- Agent results and context
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, cast
|
||||
|
||||
@@ -624,7 +626,7 @@ class WorkflowState:
|
||||
"""Reset the agent result for a new agent invocation."""
|
||||
self._agent.clear()
|
||||
|
||||
def clone(self) -> "WorkflowState":
|
||||
def clone(self) -> WorkflowState:
|
||||
"""Create a shallow copy of the state.
|
||||
|
||||
Returns:
|
||||
|
||||
Reference in New Issue
Block a user