mistralai-workflows-cli 1.2.2__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.2 → mistralai_workflows_cli-1.3.0}/.gitignore +19 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/Makefile +6 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/PKG-INFO +2 -2
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/pyproject.toml +1 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/SKILL.md +32 -16
- {mistralai_workflows_cli-1.2.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/limitations.mdx +11 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/rate-limiting.mdx +13 -15
- {mistralai_workflows_cli-1.2.2 → 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.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/references/guides/workflows-plugins.mdx +71 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/determinism.yaml +217 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/imports.yaml +114 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/io.yaml +116 -0
- mistralai_workflows_cli-1.3.0/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/linting/rules/structure.yaml +120 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.agents/skills/workflows/scripts/test_workflow.py +129 -78
- 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.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/Makefile +32 -1
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/README.md.jinja +14 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/pyproject.toml.jinja +1 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/worker.py +16 -1
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/workflows/hello.py +1 -1
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/uv.lock +3 -3
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/README.md +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/copier.yml +0 -0
- {mistralai_workflows_cli-1.2.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.env.jinja +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/.gitignore +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/dev.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/entrypoints/start.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → 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.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/examples/worker.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/worker.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/src/workflows/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_template/template/worker.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/_version.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/main.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/src/mistral_workflows_cli/setup.py +0 -0
- {mistralai_workflows_cli-1.2.2 → mistralai_workflows_cli-1.3.0}/tests/__init__.py +0 -0
- {mistralai_workflows_cli-1.2.2 → 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
|
|
@@ -42,6 +42,7 @@ integration-test:
|
|
|
42
42
|
$(MAKE) _test-start-examples
|
|
43
43
|
$(MAKE) _test-execute-help
|
|
44
44
|
$(MAKE) _test-execute-bad-json
|
|
45
|
+
$(MAKE) _test-make-check
|
|
45
46
|
$(MAKE) _test-wheel-contents
|
|
46
47
|
@echo ""
|
|
47
48
|
@echo "All integration tests passed."
|
|
@@ -124,3 +125,8 @@ _test-wheel-contents:
|
|
|
124
125
|
| grep -q "entrypoints/worker.py" \
|
|
125
126
|
&& echo "OK: wheel contains entrypoints package" \
|
|
126
127
|
|| (echo "FAIL: wheel is missing the entrypoints package" && exit 1)
|
|
128
|
+
|
|
129
|
+
_test-make-check:
|
|
130
|
+
@echo "--- test: 'make check' (ruff, mypy, workflow lint) passes on the generated project"
|
|
131
|
+
cd $(GENERATED_PROJECT) && $(MAKE) check
|
|
132
|
+
@echo "OK: make check passes on the generated project"
|
|
@@ -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:
|
|
@@ -76,22 +78,43 @@ The documentation is organized into several categories:
|
|
|
76
78
|
- **[Connectors](references/guides/connectors.mdx)**: Call third-party tools (GitHub, Notion, Slack, ...) from a workflow or give them to an agent, without holding the service's credentials
|
|
77
79
|
- **[Conversational Workflows](references/guides/assist-workflows.mdx)**: InteractiveWorkflow, HITL, ChatInput/FormInput, Canvas editing, Rich UI components, Tool UI states
|
|
78
80
|
- **[Local Execution](references/guides/local-execution.mdx)**: No-infra dev mode with Pydantic model params
|
|
79
|
-
- **[Limitations](references/guides/limitations.mdx)**: System constraints and limits
|
|
80
|
-
- **[Workflows Plugins](references/guides/workflows-plugins.mdx)**: Mistral AI plugin, Webhook plugin, Nuage plugin, custom plugins
|
|
81
|
+
- **[Limitations](references/guides/limitations.mdx)**: System constraints, determinism rules, sandbox import restrictions (module-level non-deterministic imports + `imports_passed_through`), I/O and heavy work belongs in activities, execution-history limits
|
|
82
|
+
- **[Workflows Plugins](references/guides/workflows-plugins.mdx)**: Mistral AI plugin (calling chat / structured-output / embeddings / OCR models), Webhook plugin, Nuage plugin, custom plugins
|
|
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
|
-
|
|
91
|
+
### Internal References
|
|
92
|
+
|
|
93
|
+
These are additional patterns and utilities not covered in the official docs:
|
|
94
|
+
|
|
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
|
|
100
|
+
|
|
101
|
+
Run the project's static checks before reporting a workflow as done. Three static checks are available:
|
|
102
|
+
|
|
103
|
+
- `make lint` — Ruff: style, imports, and common errors (`make format` auto-fixes most)
|
|
104
|
+
- `make typecheck` — mypy static type checking
|
|
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)
|
|
106
|
+
|
|
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
|
+
|
|
90
111
|
```bash
|
|
91
|
-
python .agents/skills/workflows/scripts/test_workflow.py <workflow_file> --input '{"key": "value"}' [--timeout 30]
|
|
112
|
+
uv run python .agents/skills/workflows/scripts/test_workflow.py <workflow_file> --input '{"key": "value"}' [--timeout 30]
|
|
92
113
|
```
|
|
93
114
|
|
|
94
|
-
|
|
115
|
+
`ruff`, `mypy`, and `semgrep` are the project's dev dependencies; `make check` invokes them through `uv run`.
|
|
116
|
+
|
|
117
|
+
Use timeouts to keep the feedback loop tight. A hanging test wastes more time than a false timeout. Defaults:
|
|
95
118
|
|
|
96
119
|
| Context | Recommended timeout | When to increase |
|
|
97
120
|
|---|---|---|
|
|
@@ -99,15 +122,9 @@ python .agents/skills/workflows/scripts/test_workflow.py <workflow_file> --input
|
|
|
99
122
|
| `execution_timeout` (pytest) | `timedelta(seconds=10)` | Known long-running workflow |
|
|
100
123
|
| `asyncio.wait_for` (pytest) | `15` seconds | Should always be slightly above `execution_timeout` |
|
|
101
124
|
|
|
102
|
-
If a workflow is known to be long-running (e.g. multi-step agent, large data processing), increase timeouts proportionally
|
|
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.
|
|
103
126
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
These are additional patterns and utilities not covered in the official docs:
|
|
107
|
-
|
|
108
|
-
- **[Execution IDs](references/execution_ids.md)**: Generate deterministic execution IDs for child workflows
|
|
109
|
-
- **[Pipeline Pattern](references/pipeline_pattern.md)**: Build multi-step workflows with declarative StepSpec definitions
|
|
110
|
-
- **[Workflow Testing](references/workflow_testing.md)**: Ensure workflow classes are properly registered in workers
|
|
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.
|
|
111
128
|
|
|
112
129
|
## When to Use This Skill
|
|
113
130
|
|
|
@@ -139,4 +156,3 @@ Use this skill when you need to:
|
|
|
139
156
|
- **Durable agents**: AI agents with MCP support, multi-agent handoffs, and persistent state
|
|
140
157
|
- **Connectors**: Call external services with platform-managed credentials avoiding secrets in the workflow code
|
|
141
158
|
- **Scalability**: Designed to handle complex, distributed applications
|
|
142
|
-
|
|
@@ -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:
|
|
@@ -144,6 +144,17 @@ if os.getenv("ENV") == "prod":
|
|
|
144
144
|
|
|
145
145
|
must be performed in activities. While activities themselves can produce different outputs for the same inputs (as they might contain non-deterministic operations), the workflow code must behave deterministically based on the activity results it receives.
|
|
146
146
|
|
|
147
|
+
### Imports must be deterministic too
|
|
148
|
+
|
|
149
|
+
The sandbox also validates **imports**. A module-level `import` of a non-deterministic library (`httpx`, `requests`, `aiohttp`, the raw `mistralai` client, etc.) in a workflow file won't work in the sandbox — the worker rejects it while validating the workflow at startup, so the workflow never becomes runnable. Keep such imports **inside the activity** that uses them, or — when a top-level import is unavoidable (e.g. shared type hints) — wrap it so the sandbox lets it through:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
with workflows.workflow.unsafe.imports_passed_through():
|
|
153
|
+
import httpx
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Only pass through imports you know are side-effect-free (no import-time I/O or global-state mutation).
|
|
157
|
+
|
|
147
158
|
### Maximum Execution History
|
|
148
159
|
|
|
149
160
|
The execution history for each workflow is capped at 51,200 events or 50MB per workflow execution. This is a hard limit of the durable execution engine. In order to avoid hitting this limit, we recommend using `workflows.execute_activities_in_parallel`, that allows you to execute large amounts of activities in parallel, while having the lowest footprint on the execution history. [Learn more about concurrency patterns](concurrency).
|
|
@@ -28,32 +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 import Mistral, Messages
|
|
32
31
|
from mistralai.workflows import Depends
|
|
33
32
|
from pydantic import BaseModel
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
client
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
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
|
+
|
|
41
41
|
|
|
42
42
|
class CompletionParams(BaseModel):
|
|
43
43
|
model: str
|
|
44
|
-
messages:
|
|
44
|
+
messages: list[dict]
|
|
45
|
+
|
|
45
46
|
|
|
46
47
|
@workflows.activity(rate_limit=workflows.RateLimit(time_window_in_sec=1, max_calls=100))
|
|
47
|
-
async def generate_chat_response(
|
|
48
|
-
|
|
49
|
-
client: Mistral = Depends(get_mistral_client)
|
|
50
|
-
):
|
|
51
|
-
"""Generates a chat response using a shared client"""
|
|
52
|
-
# This activity can be called from multiple workflows
|
|
53
|
-
# 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."""
|
|
54
50
|
return await client.chat.complete_async(model=params.model, messages=params.messages)
|
|
55
51
|
```
|
|
56
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
|
+
|
|
57
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.
|
|
58
56
|
|
|
59
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
|
+
```
|
|
@@ -78,6 +78,77 @@ class SummarizeWorkflow:
|
|
|
78
78
|
return result.choices[0].message.content
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
**Example — structured output:** to get a validated Pydantic object back instead of a string, define a model and build the same `ChatCompletionRequest` as above, then swap the final call for `chat_parse_to_model`:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from pydantic import BaseModel
|
|
85
|
+
from mistralai.workflows.plugins.mistralai import chat_parse_to_model
|
|
86
|
+
|
|
87
|
+
class Sentiment(BaseModel):
|
|
88
|
+
label: str
|
|
89
|
+
score: float
|
|
90
|
+
|
|
91
|
+
# inside the entrypoint, with `request` built as in the chat example above:
|
|
92
|
+
sentiment = await chat_parse_to_model(Sentiment, request)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For the raw response instead of a parsed model, call `mistralai_chat_parse(request, response_format)` directly.
|
|
96
|
+
|
|
97
|
+
**Example — embeddings** (call from inside an entrypoint or activity):
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from mistralai.workflows.plugins.mistralai import (
|
|
101
|
+
MistralEmbeddingsParams,
|
|
102
|
+
mistralai_embeddings,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
response = await mistralai_embeddings(
|
|
106
|
+
MistralEmbeddingsParams(model="mistral-embed", inputs=["first text", "second text"]),
|
|
107
|
+
)
|
|
108
|
+
vectors = [item.embedding for item in response.data]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Example — OCR** extracts text from a document or image URL:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from mistralai.workflows import activity
|
|
115
|
+
from mistralai.workflows.plugins.mistralai import OCRRequest, mistralai_ocr
|
|
116
|
+
|
|
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]
|
|
129
|
+
```
|
|
130
|
+
|
|
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:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import os
|
|
135
|
+
from mistralai.workflows import activity
|
|
136
|
+
|
|
137
|
+
@activity()
|
|
138
|
+
async def summarize(text: str) -> str:
|
|
139
|
+
# Import inside the activity so the workflow sandbox doesn't reject it.
|
|
140
|
+
from mistralai.client import Mistral # NOT `from mistralai import Mistral`
|
|
141
|
+
|
|
142
|
+
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
|
|
143
|
+
resp = await client.chat.complete_async(
|
|
144
|
+
model="mistral-small-latest",
|
|
145
|
+
messages=[{"role": "user", "content": text}],
|
|
146
|
+
)
|
|
147
|
+
return resp.choices[0].message.content
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Model calls and other I/O must run inside an activity, never in the workflow body; see [Limitations](./limitations) for the determinism and import rules.
|
|
151
|
+
|
|
81
152
|
For full documentation on `Agent`, `Runner`, sessions, MCP, and multi-agent handoffs, see the [Durable Agents guide](./durable-agents).
|
|
82
153
|
|
|
83
154
|
### Webhook Plugin
|