mistralai-workflows-cli 1.2.3__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/.gitignore +19 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/PKG-INFO +2 -2
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/pyproject.toml +1 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/SKILL.md +28 -21
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/value-proposition.mdx +1 -1
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/activities.mdx +4 -2
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/concurrency.mdx +20 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/connectors.mdx +0 -1
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/diagnostics.md +2 -2
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/durable-agents.mdx +106 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/rate-limiting.mdx +13 -16
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/testing.md +13 -3
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/workflows-plugins.mdx +14 -9
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/test_workflow.py +71 -63
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.dockerignore +17 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.vibe/check_hooks.py +56 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.vibe/hooks.toml +9 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/Dockerfile +26 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/Makefile +11 -1
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/README.md.jinja +14 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/worker.py +16 -1
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/workflows/hello.py +1 -1
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/uv.lock +3 -3
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/Makefile +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/README.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/copier.yml +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/execution_ids.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/core-concepts.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/installation.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/introduction.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/python-sdk.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/getting-started/your-first-workflow.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/_deployment-patterns.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/assist-workflows.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/dependency-injection.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/error-codes.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/handling-large-data.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/limitations.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/local-execution.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/migration-v2-to-v3.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/observability.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/payload-encoding.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/scheduling.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/signals-queries-updates.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/streaming-consumption.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/streaming.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/workflows-exception.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/workflows.mdx +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/pipeline_pattern.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/workflow_testing.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/determinism.yaml +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/imports.yaml +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/io.yaml +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/structure.yaml +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.env.jinja +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.gitignore +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/pyproject.toml.jinja +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/dev.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/start.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/README.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/activities.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/models.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/sample_data/shipping_doc_anomaly.png +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/sample_data/shipping_doc_normal.png +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/cargo_release/workflow.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/README.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/activities.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/models.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/sample_data/legacy_repo/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/sample_data/legacy_repo/api_client.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/sample_data/legacy_repo/processor.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/sample_data/legacy_repo/utils.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/sub_workflow.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/code_modernization/workflow.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/README.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/activities.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/models.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/claim_high_severity.json +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/claim_low_severity.json +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/claim_medium_severity.json +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/photos/CREDITS.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/photos/claim_high_totaled_front.jpg +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/photos/claim_high_totaled_side.jpg +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/photos/claim_low_scratch_door.jpg +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/sample_data/photos/claim_medium_dent_rear.jpg +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/insurance_claims/workflow.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/linear_summarization/README.md +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/linear_summarization/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/linear_summarization/linear_activities.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/linear_summarization/summary_activity.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/linear_summarization/workflow.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/worker.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/worker.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/workflows/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/worker.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_version.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/main.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/setup.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/tests/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.3 → mistralai_workflows_cli-1.3.0}/tests/test_setup.py +0 -0
|
@@ -79,6 +79,9 @@ target/
|
|
|
79
79
|
# Ruff
|
|
80
80
|
.ruff_cache/
|
|
81
81
|
|
|
82
|
+
# import-linter
|
|
83
|
+
.import_linter_cache/
|
|
84
|
+
|
|
82
85
|
# Jupyter Notebook
|
|
83
86
|
.ipynb_checkpoints
|
|
84
87
|
|
|
@@ -128,6 +131,7 @@ celerybeat.pid
|
|
|
128
131
|
.env.local
|
|
129
132
|
.envrc
|
|
130
133
|
.venv
|
|
134
|
+
.run-vcw/
|
|
131
135
|
env/
|
|
132
136
|
venv/
|
|
133
137
|
ENV/
|
|
@@ -222,6 +226,21 @@ jobs/run/checkpoints/test/consolidated/params.json
|
|
|
222
226
|
|
|
223
227
|
# Agent plans (scratch planning docs)
|
|
224
228
|
.agents/plans/
|
|
229
|
+
|
|
230
|
+
# Playwright MCP accessibility snapshots (local browser-debug artifacts)
|
|
231
|
+
.playwright-mcp/
|
|
232
|
+
.playwright-cli/
|
|
233
|
+
|
|
225
234
|
tsconfig.tsbuildinfo
|
|
226
235
|
|
|
227
236
|
.vscode-test/
|
|
237
|
+
infra/local/docker-compose.override.yaml
|
|
238
|
+
|
|
239
|
+
# Atlas overlap-scan generated fixtures
|
|
240
|
+
ts/packages/workflow-graph/tests/fixtures/overlap-views.json
|
|
241
|
+
|
|
242
|
+
# Go build output (go/Makefile "build" target); already in go/.dockerignore
|
|
243
|
+
go/bin/
|
|
244
|
+
|
|
245
|
+
# GHA→Buildkite migration tracker (local working ledger, not version-controlled)
|
|
246
|
+
tools/buildkite-pipeline/MIGRATION_STATUS.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflows
|
|
3
|
-
description:
|
|
3
|
+
description: Use when writing, editing, or debugging Mistral Workflows code (`mistralai.workflows`): workflows and activities, background jobs, multi-step pipelines, scheduled tasks, durable LLM agents, and any process needing fault tolerance, retries, or long-running execution. Covers the determinism and import rules, the Mistral AI plugin API, activity timeouts and retries, signals and HITL, and a pre-flight check to run before finishing.
|
|
4
4
|
license: Complete terms in LICENSE.txt
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -44,6 +44,8 @@ Focused snippets may use `from mistralai.workflows import workflow, activity, ..
|
|
|
44
44
|
|
|
45
45
|
Call activities directly (`await my_activity(args)`); timeouts and retries live on the `@activity(...)` decorator, not at the call site.
|
|
46
46
|
|
|
47
|
+
**Calling Mistral plugins:** prefer the plugin activities (`mistralai_chat_complete`, `mistralai_ocr`, `mistralai_embeddings`, `chat_parse_to_model`, …; see [Workflows Plugins](references/guides/workflows-plugins.mdx)) — they are sandbox-safe. Use the raw `mistralai.client.Mistral` only when no plugin fits, and import it inside the activity that uses it: a module-level import pulls in `httpx`, which the sandbox rejects at worker startup (see [Limitations](references/guides/limitations.mdx)). Hoist it to module scope only under `workflow.unsafe.imports_passed_through()`.
|
|
48
|
+
|
|
47
49
|
## Documentation Structure
|
|
48
50
|
|
|
49
51
|
The documentation is organized into several categories:
|
|
@@ -81,43 +83,48 @@ The documentation is organized into several categories:
|
|
|
81
83
|
- **[Deployment Patterns](references/guides/_deployment-patterns.mdx)**: Best practices for deploying workflows
|
|
82
84
|
- **[Migration v2 to v3](references/guides/migration-v2-to-v3.mdx)**: Breaking changes and upgrade steps from SDK v2 through v3.4.0
|
|
83
85
|
|
|
84
|
-
### Testing
|
|
86
|
+
### Testing & Diagnostics
|
|
85
87
|
|
|
86
88
|
- **[Testing Workflows](references/guides/testing.md)**: Integration testing with `create_test_worker`, hang prevention, sandbox pitfalls
|
|
87
89
|
- **[Diagnostics](references/guides/diagnostics.md)**: Run `wf-diagnose` locally or on Kubernetes to collect a diagnostic report for support triage
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
python .agents/skills/workflows/scripts/test_workflow.py <workflow_file> --input '{"key": "value"}' [--timeout 30]
|
|
92
|
-
```
|
|
91
|
+
### Internal References
|
|
93
92
|
|
|
94
|
-
|
|
93
|
+
These are additional patterns and utilities not covered in the official docs:
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
- **[Execution IDs](references/execution_ids.md)**: Generate deterministic execution IDs for child workflows
|
|
96
|
+
- **[Pipeline Pattern](references/pipeline_pattern.md)**: Build multi-step workflows with declarative StepSpec definitions
|
|
97
|
+
- **[Workflow Testing](references/workflow_testing.md)**: Ensure workflow classes are properly registered in workers
|
|
98
|
+
|
|
99
|
+
## Testing
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
Run the project's static checks before reporting a workflow as done. Three static checks are available:
|
|
103
102
|
|
|
104
|
-
**Lint & check** — validate your code before running it. Three checks are available:
|
|
105
103
|
- `make lint` — Ruff: style, imports, and common errors (`make format` auto-fixes most)
|
|
106
104
|
- `make typecheck` — mypy static type checking
|
|
107
105
|
- `make lint-workflows` — Semgrep workflow rules: determinism violations, I/O outside activities, missing return-type annotations, unsafe imports (advisory — reports but does not block)
|
|
108
106
|
|
|
109
|
-
|
|
107
|
+
And `make check` runs all three.
|
|
108
|
+
|
|
109
|
+
To start the workflow and do a test run with sample inputs, use the `test_workflow.py` script:
|
|
110
|
+
|
|
110
111
|
```bash
|
|
111
|
-
|
|
112
|
+
uv run python .agents/skills/workflows/scripts/test_workflow.py <workflow_file> --input '{"key": "value"}' [--timeout 30]
|
|
112
113
|
```
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
`ruff`, `mypy`, and `semgrep` are the project's dev dependencies; `make check` invokes them through `uv run`.
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
Use timeouts to keep the feedback loop tight. A hanging test wastes more time than a false timeout. Defaults:
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
| Context | Recommended timeout | When to increase |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `--timeout` (quick-test script) | `15` seconds | Workflow makes multiple LLM calls or heavy I/O |
|
|
122
|
+
| `execution_timeout` (pytest) | `timedelta(seconds=10)` | Known long-running workflow |
|
|
123
|
+
| `asyncio.wait_for` (pytest) | `15` seconds | Should always be slightly above `execution_timeout` |
|
|
124
|
+
|
|
125
|
+
If a workflow is known to be long-running (e.g. multi-step agent, large data processing), increase timeouts proportionally. Start short and only raise them when you see legitimate timeout failures, not preemptively.
|
|
126
|
+
|
|
127
|
+
> **You must run the static checks and a test run before reporting a workflow as done.** This ensures that the workflow is deterministic, free of I/O outside activities, and passes basic integration tests. Failure to do so will result in failing workflows and wasted time for the developer. Never forget this.
|
|
121
128
|
|
|
122
129
|
## When to Use This Skill
|
|
123
130
|
|
|
@@ -59,7 +59,7 @@ result = await my_activity(name) # Just call it
|
|
|
59
59
|
|
|
60
60
|
### 2. Configuration on Decorators
|
|
61
61
|
|
|
62
|
-
- Activities: `@activity(start_to_close_timeout
|
|
62
|
+
- Activities: `@activity(start_to_close_timeout=timedelta(seconds=30), retry_policy_max_attempts=3, name="fetch_data")`, where `start_to_close_timeout` takes a `datetime.timedelta`
|
|
63
63
|
- Workflows: `@workflow.define(name=..., workflow_display_name=..., workflow_description=...)`
|
|
64
64
|
- Configure once on the decorator instead of at every call site
|
|
65
65
|
|
|
@@ -72,13 +72,15 @@ Customize activity identification with:
|
|
|
72
72
|
Configure execution time limits to prevent runaway activities:
|
|
73
73
|
|
|
74
74
|
```python
|
|
75
|
-
from datetime import
|
|
75
|
+
from datetime import timedelta
|
|
76
76
|
|
|
77
77
|
@workflows.activity(
|
|
78
|
-
start_to_close_timeout=
|
|
78
|
+
start_to_close_timeout=timedelta(minutes=10),
|
|
79
79
|
)
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
+
`start_to_close_timeout` and the other `*_timeout` params must be a `datetime.timedelta`. Passing an int or a string raises at activity-definition time.
|
|
83
|
+
|
|
82
84
|
[Learn more about timeouts](#)
|
|
83
85
|
|
|
84
86
|
### 3. Retry Policies
|
|
@@ -26,6 +26,26 @@ All patterns are built on the platform's workflow continuation primitives, provi
|
|
|
26
26
|
- **Fault Tolerance**: Built-in error handling and retry mechanisms
|
|
27
27
|
- **Progress Tracking**: Monitor execution progress through built-in observability features
|
|
28
28
|
|
|
29
|
+
## Small Batches: `asyncio.gather`
|
|
30
|
+
|
|
31
|
+
The patterns described in the other sections add continue-as-new, per-item progress, retry, and scale past a few thousand items. For fewer items, `asyncio.gather` is enough. Activities are awaitables, so gathering them runs concurrently with no bookkeeping, and you stay under the 51,200-event history limit that continue-as-new exists to manage.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import asyncio
|
|
35
|
+
|
|
36
|
+
# Named, heterogeneous calls:
|
|
37
|
+
a, b, c = await asyncio.gather(
|
|
38
|
+
fetch(user_a),
|
|
39
|
+
fetch(user_b),
|
|
40
|
+
fetch(user_c),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# A collection you hold in full:
|
|
44
|
+
results = await asyncio.gather(*[process_item(item) for item in params.items])
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use `execute_activities_in_parallel` past a few thousand items, or when you need continue-as-new, progress tracking, or per-item retry.
|
|
48
|
+
|
|
29
49
|
## List Executor Pattern
|
|
30
50
|
|
|
31
51
|
### Use Case
|
|
@@ -121,7 +121,6 @@ class GitHubIssueCreatorWorkflow:
|
|
|
121
121
|
Fall back to worker credentials (omit `on_behalf_of`) when there's no triggering user or you deliberately want one shared identity. Caveats (platform-enforced):
|
|
122
122
|
|
|
123
123
|
- **Needs a triggering user.** Starting an `on_behalf_of=True` workflow without a user session is rejected (`403 "On-behalf-of workflows require user identity"`). For the same reason it **can't be combined with `schedules`** — the SDK raises at definition time, since a scheduled run has no triggering user.
|
|
124
|
-
- **Restricted to Mistral-internal orgs.** Registering an `on_behalf_of=True` workflow returns `403 "on_behalf workflows are currently restricted to Mistral-internal organizations"` unless the org is internal or the `ON_BEHALF_WORKFLOWS_ENABLED` feature flag is enabled.
|
|
125
124
|
|
|
126
125
|
## Connectors in durable agents
|
|
127
126
|
|
|
@@ -11,13 +11,13 @@ sidebar_position: 21
|
|
|
11
11
|
## Running Locally
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
wf-diagnose
|
|
14
|
+
uv run wf-diagnose
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Or via module:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
python -m mistralai.workflows.scripts.diagnose
|
|
20
|
+
uv run python -m mistralai.workflows.scripts.diagnose
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Running on a Kubernetes Cluster
|
|
@@ -225,6 +225,31 @@ agent = Agent(
|
|
|
225
225
|
)
|
|
226
226
|
```
|
|
227
227
|
|
|
228
|
+
#### Forwarding credentials to a stdio server
|
|
229
|
+
|
|
230
|
+
Some stdio MCP servers need credentials (e.g. a bot token) to authenticate. Use
|
|
231
|
+
`env_mapping` to inject them from the worker's environment into the subprocess.
|
|
232
|
+
The mapping goes from **subprocess variable name** to **worker variable name**:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
mcp_config = MCPStdioConfig(
|
|
236
|
+
command="npx",
|
|
237
|
+
args=["-y", "@notionhq/notion-mcp-server"],
|
|
238
|
+
name="notion_bot_a",
|
|
239
|
+
env_mapping={"NOTION_TOKEN": "NOTION_TOKEN_BOT_A"},
|
|
240
|
+
)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Why pass a mapping instead of the raw values? Activity inputs are persisted to
|
|
244
|
+
the Temporal event history, so loading secrets from the worker's environment and
|
|
245
|
+
passing them directly would expose them there. With `env_mapping`, only the
|
|
246
|
+
mapping names are serialized into activity params and event history; the secret
|
|
247
|
+
values are read from the worker's environment inside the activity and never leave
|
|
248
|
+
it. This also lets you run several instances of the same server with different
|
|
249
|
+
credentials (e.g. `NOTION_TOKEN_BOT_A` and `NOTION_TOKEN_BOT_B`) on one worker.
|
|
250
|
+
If a declared worker variable is missing from the environment, the activity
|
|
251
|
+
fails fast.
|
|
252
|
+
|
|
228
253
|
### SSE MCP Server
|
|
229
254
|
|
|
230
255
|
For remote MCP servers over Server-Sent Events:
|
|
@@ -247,6 +272,87 @@ agent = workflows_mistralai.Agent(
|
|
|
247
272
|
)
|
|
248
273
|
```
|
|
249
274
|
|
|
275
|
+
### Streamable HTTP MCP Server
|
|
276
|
+
|
|
277
|
+
For remote MCP servers that speak the Streamable HTTP transport (`--transport http`),
|
|
278
|
+
such as a self-hosted server behind an HTTP endpoint:
|
|
279
|
+
|
|
280
|
+
> **Requires `mistralai>=2.8.0`.** The Streamable HTTP client ships in the `mistralai`
|
|
281
|
+
> client from 2.8.0 (client-python#592). This plugin keeps a permissive floor
|
|
282
|
+
> (`mistralai>=2.0.0`), so if you use `MCPStreamableHTTPConfig`, pin
|
|
283
|
+
> `mistralai>=2.8.0` in your own project's dependencies.
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
from mistralai.workflows.plugins.mistralai import MCPStreamableHTTPConfig
|
|
287
|
+
|
|
288
|
+
mcp_config = MCPStreamableHTTPConfig(
|
|
289
|
+
url="https://your-mcp-server.com/mcp",
|
|
290
|
+
name="remote-tools",
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
agent = Agent(
|
|
294
|
+
model="mistral-medium-latest",
|
|
295
|
+
name="streamable-http-mcp-agent",
|
|
296
|
+
description="Agent with access to a Streamable HTTP MCP server",
|
|
297
|
+
mcp_clients=[mcp_config],
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### Forwarding credentials to a Streamable HTTP server
|
|
302
|
+
|
|
303
|
+
A Streamable HTTP server usually needs credentials on every request: a bearer token
|
|
304
|
+
gating the endpoint and/or a per-request integration token. Set them from the
|
|
305
|
+
worker's environment so no secret is ever serialized into the Temporal event history
|
|
306
|
+
(the same reasoning as `env_mapping` above).
|
|
307
|
+
|
|
308
|
+
Use `auth_token_env` for the endpoint bearer. The SDK reads the raw token from that
|
|
309
|
+
worker variable inside the activity and sends it as `Authorization: Bearer <value>`,
|
|
310
|
+
so store the raw token in your secret manager and let the SDK add the scheme:
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
mcp_config = MCPStreamableHTTPConfig(
|
|
314
|
+
url="https://your-mcp-server.com/mcp",
|
|
315
|
+
name="remote-tools",
|
|
316
|
+
auth_token_env="MCP_ENDPOINT_TOKEN",
|
|
317
|
+
)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Use `header_mapping` for any other per-request secret header. Like `env_mapping`,
|
|
321
|
+
each entry maps an **HTTP header name** to a **worker variable name**, and only the
|
|
322
|
+
names are serialized; the values are read from the worker's environment inside the
|
|
323
|
+
activity:
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
mcp_config = MCPStreamableHTTPConfig(
|
|
327
|
+
url="https://your-mcp-server.com/mcp",
|
|
328
|
+
name="notion",
|
|
329
|
+
auth_token_env="MCP_ENDPOINT_TOKEN", # -> Authorization: Bearer <value>
|
|
330
|
+
header_mapping={"Notion-Token": "NOTION_TOKEN_BOT_A"}, # header <- whole env value
|
|
331
|
+
)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Only put non-secret values in the static `headers` field, since those are serialized
|
|
335
|
+
into activity params. As with `env_mapping`, a declared worker variable that is
|
|
336
|
+
missing from the environment makes the activity fail fast. A fresh client is opened
|
|
337
|
+
per call, so different callers or tokens never share a session.
|
|
338
|
+
|
|
339
|
+
**Redirects**
|
|
340
|
+
|
|
341
|
+
By default the client does **not** follow HTTP redirects (`follow_redirects=False`).
|
|
342
|
+
On a redirect, `httpx` only strips the `Authorization` header on cross-origin hops,
|
|
343
|
+
so the per-request secret headers above (e.g. `Notion-Token`) would be resent to the
|
|
344
|
+
redirect target, letting a compromised or open-redirecting MCP exfiltrate them. If
|
|
345
|
+
your MCP server relies on redirects (for example `/mcp` -> `/mcp/`) and you trust
|
|
346
|
+
every host it can redirect to, opt in:
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
mcp_config = MCPStreamableHTTPConfig(
|
|
350
|
+
url="https://your-mcp-server.com/mcp",
|
|
351
|
+
name="remote-tools",
|
|
352
|
+
follow_redirects=True,
|
|
353
|
+
)
|
|
354
|
+
```
|
|
355
|
+
|
|
250
356
|
## Built-in Tools
|
|
251
357
|
|
|
252
358
|
Use Mistral's built-in tools alongside activities:
|
|
@@ -28,33 +28,30 @@ When **a key is provided**, multiple different activities that use the same key
|
|
|
28
28
|
|
|
29
29
|
```python
|
|
30
30
|
import mistralai.workflows as workflows
|
|
31
|
-
from mistralai.client import Mistral
|
|
32
|
-
from mistralai.client.models import ChatCompletionRequestMessage
|
|
33
31
|
from mistralai.workflows import Depends
|
|
34
32
|
from pydantic import BaseModel
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
client
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return
|
|
34
|
+
|
|
35
|
+
def get_mistral_client():
|
|
36
|
+
"""Shared Mistral client wired with workflows tracking + OBO interceptors."""
|
|
37
|
+
from mistralai.workflows.plugins.mistralai import get_mistral_client as _get_client
|
|
38
|
+
|
|
39
|
+
return _get_client()
|
|
40
|
+
|
|
42
41
|
|
|
43
42
|
class CompletionParams(BaseModel):
|
|
44
43
|
model: str
|
|
45
|
-
messages: list[
|
|
44
|
+
messages: list[dict]
|
|
45
|
+
|
|
46
46
|
|
|
47
47
|
@workflows.activity(rate_limit=workflows.RateLimit(time_window_in_sec=1, max_calls=100))
|
|
48
|
-
async def generate_chat_response(
|
|
49
|
-
|
|
50
|
-
client: Mistral = Depends(get_mistral_client)
|
|
51
|
-
):
|
|
52
|
-
"""Generates a chat response using a shared client"""
|
|
53
|
-
# This activity can be called from multiple workflows
|
|
54
|
-
# but will share the same rate limit across all of them
|
|
48
|
+
async def generate_chat_response(params: CompletionParams, client=Depends(get_mistral_client)):
|
|
49
|
+
"""Generate a chat response using the shared client."""
|
|
55
50
|
return await client.chat.complete_async(model=params.model, messages=params.messages)
|
|
56
51
|
```
|
|
57
52
|
|
|
53
|
+
The `mistralai.workflows.plugins.mistralai` import lives inside `get_mistral_client`, not at module scope. Imported at the top of a workflow file, it pulls in `httpx`, which the determinism sandbox rejects at startup.
|
|
54
|
+
|
|
58
55
|
**Behavior**: All workflows calling `generate_chat_response` share the same 100 calls/sec limit. If Workflow A makes 60 calls and Workflow B makes 50 calls in the same second, they compete for the same pool.
|
|
59
56
|
|
|
60
57
|
**With a key**: Add `key="mistral_api"` to share this limit across multiple activities (e.g., `generate_chat_response`, `generate_embeddings`, `moderate_content`).
|
|
@@ -11,7 +11,7 @@ sidebar_position: 20
|
|
|
11
11
|
The fastest way to verify a workflow works end-to-end. No test files, no conftest, no pytest:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
python .agents/skills/workflows/scripts/test_workflow.py src/workflows/my_workflow.py \
|
|
14
|
+
uv run python .agents/skills/workflows/scripts/test_workflow.py src/workflows/my_workflow.py \
|
|
15
15
|
--input '{"key": "value"}' \
|
|
16
16
|
--timeout 30
|
|
17
17
|
```
|
|
@@ -19,7 +19,7 @@ python .agents/skills/workflows/scripts/test_workflow.py src/workflows/my_workfl
|
|
|
19
19
|
For interactive workflows that use `wait_for_input()`, provide `--interactions`:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
python .agents/skills/workflows/scripts/test_workflow.py src/workflows/my_workflow.py \
|
|
22
|
+
uv run python .agents/skills/workflows/scripts/test_workflow.py src/workflows/my_workflow.py \
|
|
23
23
|
--input '{}' \
|
|
24
24
|
--interactions '[{"choice": "WFL"}]' \
|
|
25
25
|
--timeout 60
|
|
@@ -40,6 +40,7 @@ Options:
|
|
|
40
40
|
- `--timeout` (default 30): max seconds before the workflow is killed
|
|
41
41
|
- `--workflow-name`: select a specific workflow if the file contains multiple
|
|
42
42
|
- `--interactions`: JSON array of responses for interactive workflows
|
|
43
|
+
- `DEPLOYMENT_NAME` (env): deployment the worker registers under; defaults to `"default"`
|
|
43
44
|
|
|
44
45
|
Because the script uses a real worker, you get full worker logs (activity errors, retries, HTTP failures) in real time on stderr. No time-skipping — activities execute with real network calls.
|
|
45
46
|
|
|
@@ -115,7 +116,7 @@ Always use both.
|
|
|
115
116
|
### `start_to_close_timeout` must be a `timedelta`
|
|
116
117
|
|
|
117
118
|
```python
|
|
118
|
-
# WRONG —
|
|
119
|
+
# WRONG — raises AttributeError: 'int' object has no attribute 'total_seconds'
|
|
119
120
|
@activity(start_to_close_timeout=60)
|
|
120
121
|
|
|
121
122
|
# RIGHT
|
|
@@ -148,3 +149,12 @@ The test client returns raw dicts. Access fields directly: `result["message"]`,
|
|
|
148
149
|
### Don't add `_emit_*` activities manually
|
|
149
150
|
|
|
150
151
|
`create_test_worker` already registers all workflow-lifecycle event activities. Adding them again causes duplicate-activity registration errors.
|
|
152
|
+
|
|
153
|
+
### `AMBIGUOUS_WORKFLOW` error
|
|
154
|
+
|
|
155
|
+
Happens when multiple deployments register the same workflow name and the API can't tell which worker should run it. Set `DEPLOYMENT_NAME` to match the deployment your worker should register under:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
DEPLOYMENT_NAME=my-deployment python .agents/skills/workflows/scripts/test_workflow.py \
|
|
159
|
+
src/workflows/my_workflow.py --input '{}'
|
|
160
|
+
```
|
|
@@ -111,19 +111,24 @@ vectors = [item.embedding for item in response.data]
|
|
|
111
111
|
**Example — OCR** extracts text from a document or image URL:
|
|
112
112
|
|
|
113
113
|
```python
|
|
114
|
-
from mistralai.
|
|
114
|
+
from mistralai.workflows import activity
|
|
115
115
|
from mistralai.workflows.plugins.mistralai import OCRRequest, mistralai_ocr
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
117
|
+
|
|
118
|
+
@activity()
|
|
119
|
+
async def extract_text(document_url: str) -> list[str]:
|
|
120
|
+
from mistralai.client.models import DocumentURLChunk
|
|
121
|
+
|
|
122
|
+
result = await mistralai_ocr(
|
|
123
|
+
OCRRequest(
|
|
124
|
+
model="mistral-ocr-latest",
|
|
125
|
+
document=DocumentURLChunk(document_url=document_url),
|
|
126
|
+
),
|
|
127
|
+
)
|
|
128
|
+
return [page.markdown for page in result.pages]
|
|
124
129
|
```
|
|
125
130
|
|
|
126
|
-
**Raw client (when a plugin activity isn't enough):** call the Mistral API directly from inside an activity
|
|
131
|
+
**Raw client (when a plugin activity isn't enough):** call the Mistral API directly from inside an activity, and keep the `from mistralai.client import Mistral` import inside the activity function. A module-level import of the raw client pulls in `httpx`, which the determinism sandbox rejects while validating the workflow at startup (see [Limitations](./limitations)). `mistralai` is a namespace package, so the path is `mistralai.client`; `from mistralai import Mistral` does not work:
|
|
127
132
|
|
|
128
133
|
```python
|
|
129
134
|
import os
|