You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by da...@apache.org on 2026/10/14 08:08:27 UTC

(airflow) branch dabla/durable-operators/01-common-compat-resumable-job-mixin updated (e8749611405 -> 8c33841b41f)

This is an automated email from the ASF dual-hosted git repository.

dabla pushed a change to branch dabla/durable-operators/01-common-compat-resumable-job-mixin
in repository https://gitbox.apache.org/repos/asf/airflow.git


    omit e8749611405 Use one ResumableJobMixin fallback from common.compat in providers
     add d8efc66ea76 Add a Model tab to the task-instance page for `common.ai` (#74334)
     add cd9f233f6d4 Add support for forwarding CeleryExecutor task logs to stdout (#69597)
     add dac956c667c Document hosted OpenAI-compatible services for common.ai (#74620)
     add 3a08e9b11e3 Document Managed Agents as a first-party feature (#72306)
     add 21c858eb67b Fix missing task.queued_duration metric in Airflow 3 (#67592)
     add eee6e2a4a50 Resume Strands agents from their last checkpoint when a task retries (#74404)
     add 06c7f338f95 Decode base64 for bytes-typed `HookToolset` parameters (#70433)
     add f46a370a95b Stop the secrets backend lookup from importing the task runner outside tasks (#74641)
     add c5c2f194b57 Add Boat backend for sandbox tools (#71725)
     add c192bdad5fd Show serializer schema in Dag version diff only when it differs (#74683)
     add 51f1b5b16d8 TS SDK: Reject triggerDagRun tasks in dag.if and dag.switch (#74492)
     add 09b4b6307fc Document agent memory across Dag runs for `common.ai` (#74681)
     add 75455fda1ba Explain why common.ai is built on Pydantic AI (#74680)
     add 945b7949328 Fix deprecated provider lookup in Amazon AWS hooks (#74480)
     add 861ca7ffc18 Bump the fab-ui-package-updates group across 1 directory with 3 updates (#74670)
     add 96da58058ef Add Islo backend for sandbox tools (#71672)
     add 68a4c3177f9 Add AirflowDurability capability for durable agent replay across task retries (#74385)
     add 3cf3f4b2a9d Refuse a HITL response for a request the task has since replaced (#74688)
     add 1461ddfdf8a Grant Keycloak SuperAdmin access to teamless resources (#74640)
     add 142f12bd2b9 Update remaining FAB Website permissions rows for Airflow 3 (#74653)
     add 2212818399e Graduate Common AI features to stable ahead of 1.0 (#74679)
     add a73ffaedbf1 Add scoped Execution API access for Dag processors (#74370)
     add 275aa6959f3 Support `abfs://` and `abfss://` URIs in DataFusion Azure Blob Storage (#74228)
     add 8c33841b41f Use one ResumableJobMixin fallback from common.compat in providers

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (e8749611405)
            \
             N -- N -- N   refs/heads/dabla/durable-operators/01-common-compat-resumable-job-mixin (8c33841b41f)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 airflow-core/docs/migrations-ref.rst               |    4 +-
 .../docs/security/jwt_token_authentication.rst     |  129 +-
 airflow-core/docs/security/security_model.rst      |    9 +-
 airflow-core/docs/tutorial/hitl.rst                |    6 +-
 airflow-core/newsfragments/67592.bugfix.rst        |    1 +
 airflow-core/newsfragments/69597.feature.rst       |    1 +
 .../src/airflow/api/common/airflow_health.py       |    4 +-
 .../api_fastapi/core_api/datamodels/hitl.py        |   11 +-
 .../core_api/openapi/v2-rest-api-generated.yaml    |   11 +
 .../api_fastapi/core_api/routes/public/hitl.py     |   11 +
 .../airflow/api_fastapi/execution_api/AGENTS.md    |    2 +-
 .../src/airflow/api_fastapi/execution_api/app.py   |   16 +-
 .../execution_api/dag_processor_tokens.py          |  116 ++
 .../api_fastapi/execution_api/datamodels/job.py    |   94 ++
 .../api_fastapi/execution_api/datamodels/token.py  |   90 +-
 .../api_fastapi/execution_api/routes/__init__.py   |    2 +
 .../execution_api/routes/connections.py            |   14 +-
 .../api_fastapi/execution_api/routes/dag_runs.py   |   15 +-
 .../api_fastapi/execution_api/routes/jobs.py       |  317 +++++
 .../execution_api/routes/task_instances.py         |   53 +-
 .../api_fastapi/execution_api/routes/variables.py  |   26 +-
 .../api_fastapi/execution_api/routes/xcoms.py      |   58 +-
 .../airflow/api_fastapi/execution_api/security.py  |  223 +++-
 .../api_fastapi/execution_api/versions/__init__.py |    2 +
 .../versions/{v2025_09_23.py => v2027_02_28.py}    |   15 +-
 airflow-core/src/airflow/cli/cli_config.py         |   34 +
 .../airflow/cli/commands/dag_processor_command.py  |    4 +-
 .../cli/commands/dag_processor_token_command.py    |  109 ++
 .../src/airflow/config_templates/config.yml        |   14 +
 .../src/airflow/dag_processing/api_client.py       |  413 +++++++
 .../src/airflow/dag_processing/bundles/manager.py  |    7 +-
 .../src/airflow/executors/base_executor.py         |    7 +-
 airflow-core/src/airflow/jobs/job.py               |    7 +-
 ...odel.py => 0147_3_5_0_add_session_id_to_job.py} |   34 +-
 .../airflow/ui/openapi-gen/requests/schemas.gen.ts |   13 +
 .../airflow/ui/openapi-gen/requests/types.gen.ts   |    4 +
 .../src/airflow/ui/public/i18n/locales/ca/dag.json |    4 +-
 .../src/airflow/ui/public/i18n/locales/de/dag.json |    4 +-
 .../src/airflow/ui/public/i18n/locales/el/dag.json |    4 +-
 .../src/airflow/ui/public/i18n/locales/en/dag.json |    5 +-
 .../src/airflow/ui/public/i18n/locales/fr/dag.json |    6 +-
 .../src/airflow/ui/public/i18n/locales/ko/dag.json |    4 +-
 .../src/airflow/ui/public/i18n/locales/pl/dag.json |    8 +-
 .../airflow/ui/public/i18n/locales/zh-TW/dag.json  |    4 +-
 .../src/components/HITLReview/HITLReviewDetail.tsx |    8 +-
 .../pages/Dag/Versions/VersionDiff.i18n.test.tsx   |   26 +-
 .../ui/src/pages/Dag/Versions/VersionDiff.tsx      |   14 +-
 .../HITLTaskInstances/HITLResponseForm.test.tsx    |   36 +-
 .../pages/HITLTaskInstances/HITLResponseForm.tsx   |    6 +-
 .../ui/src/pages/TaskInstance/HITLResponse.tsx     |    2 +-
 .../airflow/ui/src/queries/useUpdateHITLDetail.ts  |   12 +-
 airflow-core/src/airflow/ui/src/utils/hitl.ts      |    2 +
 airflow-core/src/airflow/utils/db.py               |    1 +
 .../tests/unit/always/test_example_dags.py         |    2 +
 .../core_api/routes/public/test_hitl.py            |   89 ++
 .../core_api/routes/public/test_plugins.py         |   11 +-
 .../unit/api_fastapi/execution_api/test_app.py     |    4 +-
 .../execution_api/test_dag_processor_client.py     |  373 ++++++
 .../execution_api/test_dag_processor_tokens.py     |   93 ++
 .../api_fastapi/execution_api/test_security.py     |  772 +++++++++++-
 .../execution_api/test_token_scope_boundaries.py   |  127 +-
 .../execution_api/versions/head/test_jobs.py       |  470 +++++++
 .../execution_api/versions/head/test_router.py     |   19 +
 .../versions/head/test_task_instances.py           |  390 +++++-
 .../execution_api/versions/head/test_xcoms.py      |   66 +-
 .../versions/v2026_10_30/test_task_instances.py    |    4 +-
 .../versions/v2027_02_28}/__init__.py              |    0
 .../versions/v2027_02_28/test_jobs.py              |   76 ++
 .../cli/commands/test_dag_processor_command.py     |    4 +-
 .../commands/test_dag_processor_token_command.py   |  237 ++++
 .../bundles/test_dag_bundle_manager.py             |   21 +-
 .../tests/unit/dag_processing/test_api_client.py   |  952 +++++++++++++++
 .../tests/unit/executors/test_base_executor.py     |   46 +
 .../tests/unit/plugins/test_plugins_manager.py     |    2 +-
 .../src/airflowctl/api/datamodels/generated.py     |    7 +
 docs/spelling_wordlist.txt                         |    6 +
 generated/known_sdk_imports_in_core.txt            |    1 +
 .../airflow/providers/amazon/aws/hooks/base_aws.py |    7 +-
 .../tests/unit/amazon/aws/hooks/test_base_aws.py   |    5 +
 .../airflow/providers/anthropic/hooks/anthropic.py |    8 +-
 providers/celery/docs/celery_executor.rst          |   51 +
 providers/celery/provider.yaml                     |   14 +
 .../celery/executors/celery_executor_utils.py      |   27 +-
 .../airflow/providers/celery/get_provider_info.py  |    7 +
 .../unit/celery/executors/test_celery_executor.py  |  124 +-
 providers/common/ai/README.rst                     |    3 +-
 providers/common/ai/docs/capabilities.rst          |   18 +-
 providers/common/ai/docs/durable_execution.rst     |  331 +++--
 providers/common/ai/docs/features.rst              |    3 +
 providers/common/ai/docs/frameworks/adk.rst        |    4 +-
 providers/common/ai/docs/frameworks/index.rst      |   33 +-
 providers/common/ai/docs/frameworks/strands.rst    |  133 +-
 providers/common/ai/docs/index.rst                 |   14 +-
 providers/common/ai/docs/installation.rst          |    7 +-
 providers/common/ai/docs/memory.rst                |  163 +++
 providers/common/ai/docs/model_providers.rst       |   17 +
 providers/common/ai/docs/observability.rst         |   15 +
 providers/common/ai/docs/operators/agent.rst       |   24 +-
 providers/common/ai/docs/operators/llm_batch.rst   |   11 +-
 .../common/ai/docs/operators/llm_file_analysis.rst |    5 -
 .../ai/docs/operators/llm_schema_compare.rst       |    5 -
 providers/common/ai/docs/operators/llm_sql.rst     |    5 -
 providers/common/ai/docs/sandbox/backends.rst      |  258 +++-
 providers/common/ai/docs/sandbox/configuration.rst |   16 +-
 providers/common/ai/docs/sandbox/index.rst         |   58 +-
 providers/common/ai/docs/stability.rst             |  124 +-
 providers/common/ai/docs/toolsets/hook.rst         |   30 +-
 providers/common/ai/docs/toolsets/index.rst        |   12 +-
 .../common/ai/docs/toolsets/object_storage.rst     |    5 -
 providers/common/ai/docs/toolsets/skills.rst       |    7 +-
 providers/common/ai/docs/troubleshooting.rst       |   26 +-
 providers/common/ai/provider.yaml                  |    8 +
 providers/common/ai/pyproject.toml                 |   24 +-
 .../providers/common/ai/decorators/llm_batch.py    |    5 -
 .../common/ai/decorators/llm_file_analysis.py      |    5 -
 .../common/ai/decorators/llm_schema_compare.py     |    5 -
 .../providers/common/ai/decorators/llm_sql.py      |    5 -
 .../providers/common/ai/durable/__init__.py        |   19 +
 .../airflow/providers/common/ai/durable/base.py    |   59 +-
 .../providers/common/ai/durable/caching_model.py   |  226 ----
 .../providers/common/ai/durable/caching_toolset.py |  141 ---
 .../providers/common/ai/durable/capability.py      |  532 ++++++++
 .../providers/common/ai/durable/fingerprint.py     |    9 +-
 .../airflow/providers/common/ai/durable/journal.py |  551 +++++++++
 .../providers/common/ai/durable/replay_usage.py    |  149 ++-
 .../providers/common/ai/durable/step_counter.py    |   52 -
 .../airflow/providers/common/ai/durable/storage.py |  140 +--
 .../airflow/providers/common/ai/durable/strands.py |  209 ++++
 .../providers/common/ai/durable/strands_storage.py |  137 +++
 .../common/ai/durable/task_state_store.py          |  155 +--
 .../ai/example_dags/example_agent_durable.py       |   35 +-
 .../common/ai/example_dags/example_agent_memory.py |  135 +++
 ...strands_agent.py => example_strands_durable.py} |   66 +-
 .../src/airflow/providers/common/ai/exceptions.py  |   10 +
 .../providers/common/ai/get_provider_info.py       |    8 +-
 .../airflow/providers/common/ai/operators/agent.py |  325 ++---
 .../providers/common/ai/operators/llm_batch.py     |    5 -
 .../common/ai/operators/llm_file_analysis.py       |    5 -
 .../common/ai/operators/llm_schema_compare.py      |    5 -
 .../providers/common/ai/operators/llm_sql.py       |    5 -
 .../providers/common/ai/plugins/_plugin_urls.py    |   50 +
 .../providers/common/ai/plugins/hitl_review.py     |   36 +-
 .../providers/common/ai/plugins/model_panel.py     |   97 ++
 .../providers/common/ai/plugins/www/package.json   |    3 +-
 .../providers/common/ai/plugins/www/pnpm-lock.yaml |   12 +
 .../ai/plugins/www/src/components/ModelPanel.tsx   |  142 +++
 .../components/{NoSession.tsx => NoModelInfo.tsx}  |   48 +-
 .../ai/plugins/www/src/components}/Tooltip.tsx     |    1 -
 .../ai/plugins/www/src/hooks/useModelInfo.ts       |   67 +
 .../common/ai/plugins/www/src/model-api.ts         |   83 ++
 .../ai/plugins/www/src/{main.tsx => model.tsx}     |   60 +-
 .../common/ai/plugins/www/src/types/model.ts       |   12 +-
 .../providers/common/ai/plugins/www/vite.config.ts |   23 +-
 .../providers/common/ai/sandbox/__init__.py        |    8 +
 .../airflow/providers/common/ai/sandbox/base.py    |    2 +-
 .../airflow/providers/common/ai/sandbox/boat.py    |  697 +++++++++++
 .../airflow/providers/common/ai/sandbox/islo.py    |  757 ++++++++++++
 .../src/airflow/providers/common/ai/sandbox/sbx.py |    3 +-
 .../airflow/providers/common/ai/tools/__init__.py  |    6 -
 .../src/airflow/providers/common/ai/tools/adk.py   |    2 +-
 .../airflow/providers/common/ai/tools/strands.py   |   12 +-
 .../airflow/providers/common/ai/tools/tracing.py   |    2 +-
 .../airflow/providers/common/ai/toolsets/hook.py   |  112 +-
 .../providers/common/ai/toolsets/managed_agent.py  |    6 +-
 .../providers/common/ai/toolsets/object_storage.py |    5 -
 .../providers/common/ai/triggers/llm_batch.py      |    5 -
 .../providers/common/ai/utils/tool_definition.py   |   12 +
 .../providers/common/ai/utils/toolset_base.py      |    5 +
 .../common/ai/tests/system/common/ai/README.md     |   33 +
 .../common/ai/example_sandbox_toolset_boat.py      |  234 ++++
 ...nsandbox.py => example_sandbox_toolset_islo.py} |   24 +-
 .../ai/tests/unit/common/ai/durable/conftest.py    |   10 +-
 .../tests/unit/common/ai/durable/memory_storage.py |   58 +
 .../ai/tests/unit/common/ai/durable/test_base.py   |   15 +-
 .../unit/common/ai/durable/test_caching_model.py   |  432 -------
 .../unit/common/ai/durable/test_caching_toolset.py |  268 ----
 .../unit/common/ai/durable/test_capability.py      |  855 +++++++++++++
 .../unit/common/ai/durable/test_fingerprint.py     |   12 +
 .../tests/unit/common/ai/durable/test_journal.py   |  427 +++++++
 .../unit/common/ai/durable/test_replay_cost.py     |  231 ++--
 .../common/ai/durable/test_replay_verification.py  |  138 ---
 .../unit/common/ai/durable/test_step_counter.py    |   38 -
 .../tests/unit/common/ai/durable/test_storage.py   |  227 +---
 .../tests/unit/common/ai/durable/test_strands.py   |  314 +++++
 .../unit/common/ai/durable/test_strands_storage.py |  156 +++
 .../common/ai/durable/test_task_state_store.py     |  212 +---
 .../tests/unit/common/ai/operators/test_agent.py   |  603 ++++-----
 .../unit/common/ai/plugins/test__plugin_urls.py    |   46 +
 .../unit/common/ai/plugins/test_hitl_review.py     |   11 -
 .../unit/common/ai/plugins/test_model_panel.py     |   72 ++
 ...review_compat.py => test_model_panel_compat.py} |   28 +-
 .../ai/tests/unit/common/ai/sandbox/test_boat.py   | 1184 ++++++++++++++++++
 .../ai/tests/unit/common/ai/sandbox/test_islo.py   | 1276 ++++++++++++++++++++
 .../ai/tests/unit/common/ai/tools/test_strands.py  |   54 +-
 .../ai/tests/unit/common/ai/toolsets/test_hook.py  |  250 +++-
 .../unit/common/ai/utils/test_tool_metrics.py      |   61 +-
 providers/common/sql/docs/operators.rst            |   18 +-
 .../sql/src/airflow/providers/common/sql/config.py |   19 +-
 .../providers/common/sql/datafusion/base.py        |    9 +
 .../providers/common/sql/datafusion/engine.py      |   23 +-
 .../sql/datafusion/object_storage_provider.py      |   70 +-
 .../unit/common/sql/datafusion/test_engine.py      |  100 +-
 .../sql/datafusion/test_object_storage_provider.py |  153 +++
 .../sql/tests/unit/common/sql/test_config.py       |    2 +
 providers/fab/docs/auth-manager/access-control.rst |   78 +-
 .../fab/src/airflow/providers/fab/www/package.json |    6 +-
 .../src/airflow/providers/fab/www/pnpm-lock.yaml   |  830 +++++++------
 .../keycloak/auth_manager/cli/commands.py          |    2 +-
 .../keycloak/auth_manager/cli/test_commands.py     |    2 +-
 pyproject.toml                                     |    8 +
 scripts/ci/prek/update_providers_dependencies.py   |    8 +-
 scripts/in_container/run_agent_framework_tests.sh  |   14 +-
 .../in_container/run_provider_yaml_files_check.py  |    3 -
 .../src/airflow/sdk/api/datamodels/_generated.py   |  132 +-
 .../sdk/execution_time/callback_supervisor.py      |    2 +
 .../src/airflow/sdk/execution_time/supervisor.py   |   27 +-
 .../execution_time/test_callback_supervisor.py     |   14 +
 .../tests/task_sdk/execution_time/test_secrets.py  |   20 +
 .../task_sdk/execution_time/test_supervisor.py     |   54 +
 ts-sdk/src/sdk/dag.ts                              |   18 +-
 ts-sdk/tests/hitl/operator.test.ts                 |   11 +
 ts-sdk/tests/sdk/trigger-dag-run.test.ts           |   13 +
 uv.lock                                            |  594 ++++-----
 223 files changed, 17885 insertions(+), 4276 deletions(-)
 create mode 100644 airflow-core/newsfragments/67592.bugfix.rst
 create mode 100644 airflow-core/newsfragments/69597.feature.rst
 create mode 100644 airflow-core/src/airflow/api_fastapi/execution_api/dag_processor_tokens.py
 create mode 100644 airflow-core/src/airflow/api_fastapi/execution_api/datamodels/job.py
 create mode 100644 airflow-core/src/airflow/api_fastapi/execution_api/routes/jobs.py
 copy airflow-core/src/airflow/api_fastapi/execution_api/versions/{v2025_09_23.py => v2027_02_28.py} (64%)
 create mode 100644 airflow-core/src/airflow/cli/commands/dag_processor_token_command.py
 create mode 100644 airflow-core/src/airflow/dag_processing/api_client.py
 copy airflow-core/src/airflow/migrations/versions/{0141_3_4_0_add_timetable_asset_gated_to_dagmodel.py => 0147_3_5_0_add_session_id_to_job.py} (50%)
 create mode 100644 airflow-core/tests/unit/api_fastapi/execution_api/test_dag_processor_client.py
 create mode 100644 airflow-core/tests/unit/api_fastapi/execution_api/test_dag_processor_tokens.py
 create mode 100644 airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_jobs.py
 copy airflow-core/{src/airflow/_shared => tests/unit/api_fastapi/execution_api/versions/v2027_02_28}/__init__.py (100%)
 create mode 100644 airflow-core/tests/unit/api_fastapi/execution_api/versions/v2027_02_28/test_jobs.py
 create mode 100644 airflow-core/tests/unit/cli/commands/test_dag_processor_token_command.py
 create mode 100644 airflow-core/tests/unit/dag_processing/test_api_client.py
 create mode 100644 providers/common/ai/docs/memory.rst
 delete mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/caching_model.py
 delete mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/caching_toolset.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/capability.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/journal.py
 delete mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/step_counter.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/strands.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/durable/strands_storage.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/example_dags/example_agent_memory.py
 copy providers/common/ai/src/airflow/providers/common/ai/example_dags/{example_strands_agent.py => example_strands_durable.py} (54%)
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/plugins/_plugin_urls.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/plugins/model_panel.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/components/ModelPanel.tsx
 copy providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/components/{NoSession.tsx => NoModelInfo.tsx} (57%)
 copy {airflow-core/src/airflow/ui/src/system-components => providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/components}/Tooltip.tsx (95%)
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/hooks/useModelInfo.ts
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/model-api.ts
 copy providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/{main.tsx => model.tsx} (52%)
 copy dev/react-plugin-tools/react_plugin_template/src/global.d.ts => providers/common/ai/src/airflow/providers/common/ai/plugins/www/src/types/model.ts (75%)
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/sandbox/boat.py
 create mode 100644 providers/common/ai/src/airflow/providers/common/ai/sandbox/islo.py
 create mode 100644 providers/common/ai/tests/system/common/ai/example_sandbox_toolset_boat.py
 copy providers/common/ai/tests/system/common/ai/{example_sandbox_toolset_opensandbox.py => example_sandbox_toolset_islo.py} (87%)
 copy airflow-core/tests/unit/listeners/slow_listener.py => providers/common/ai/tests/unit/common/ai/durable/conftest.py (83%)
 create mode 100644 providers/common/ai/tests/unit/common/ai/durable/memory_storage.py
 delete mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_caching_model.py
 delete mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_caching_toolset.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_capability.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_journal.py
 delete mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_replay_verification.py
 delete mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_step_counter.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_strands.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/durable/test_strands_storage.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/plugins/test__plugin_urls.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/plugins/test_model_panel.py
 copy providers/common/ai/tests/unit/common/ai/plugins/{test_hitl_review_compat.py => test_model_panel_compat.py} (51%)
 create mode 100644 providers/common/ai/tests/unit/common/ai/sandbox/test_boat.py
 create mode 100644 providers/common/ai/tests/unit/common/ai/sandbox/test_islo.py