Skip to content

Mistral Workflows integration + runtime_bridge extraction + MISTRAL_NATIVE router#954

Open
lchoquel wants to merge 100 commits into
devfrom
feature/Mistral-workflows-merge-3
Open

Mistral Workflows integration + runtime_bridge extraction + MISTRAL_NATIVE router#954
lchoquel wants to merge 100 commits into
devfrom
feature/Mistral-workflows-merge-3

Conversation

@lchoquel
Copy link
Copy Markdown
Member

@lchoquel lchoquel commented May 31, 2026

What this brings to dev

Lands the Mistral Workflows integration and its supporting runtime refactors, and reconciles the latest dev.

Headline features

  • Mistral Workflows integration extracted into a standalone package (pipelex-mistralai-workflows); the framework-agnostic core (boundary types, run_pipe_via_bridge, execution modes, ensure_pipelex_booted) is promoted to pipelex.runtime_bridge.* so any host runtime — not just Mistral Workflows — can embed Pipelex.
  • runtime_bridge.primitives extraction — activity logic (delivery, hydration, trace flush, graph assembly, submitter hydration, pipe-run-arg) lifted out of pipelex.temporal so both the Temporal track and the Mistral-native track share one body.
  • MISTRAL_NATIVE execution mode with a contextvar-backed pipe_router override on the hub, so a host runtime can turn sub-pipe calls into its own child workflows/activities.
  • Temporal IDs + observability redesignworkflow_id derived from pipeline_run_id, TypedSearchAttributes, per-activity/per-handle task-queue routing, named worker-runtime profiles, and per-call summaries in the dashboard.

dev reconciliation

Merges current dev (error-handling overhaul, dataclass/pathlib cleanups, the v0.29–v0.30.3 releases). The shared Temporal/PipeStructure work dev already shipped in v0.29.0 is deduplicated, with this branch's net-new work layered on top. Woven points worth noting:

  • Error-report propagation threads through the runtime_bridge delivery primitive (execute_delivery now forwards error_report / request_id); Temporal activities keep the @convert_pipelex_errors boundary and recover_error_report recovery.
  • Temporal config adopts dev's reviewed defaults (search_attributes off, empty queue_options, default worker-runtime profile, frozen DispatchOptions).
  • Mistral workers stay on mistralai 2.x with dev's InferenceErrorCategory / UserAction error-classification enrichment ported onto the 2.x calls.

Verification

make tb, make agent-check (ruff / plxt / pyright / mypy all clean), pipelex validate --all, make agent-test (full suite), and the Temporal error-handling integration tests all pass.

🤖 Generated with Claude Code


Summary by cubic

Extracts Mistral Workflows into pipelex-mistralai-workflows and introduces a framework‑agnostic pipelex.runtime_bridge, enabling DIRECT, Temporal, and Mistral‑native execution of Pipelex pipes with shared primitives and updated deps. Also fixes bridge scoping by preserving the caller’s library context and isolating per‑call class registries, and updates the vendored Mistral Workflows docs with corrected examples and links.

  • New Features

    • New pipelex.runtime_bridge with run_pipe_via_bridge and execution modes: direct, temporal_blocking, temporal_fire_and_forget, and mistral_native.
    • Shared primitives extracted (hydration, submitter_hydration, delivery, trace_flush, graph_assembly, pipe_classification); Temporal wrappers now thin adapters.
    • Contextvar-backed pipe_router override in the hub to route sub-pipes through a host runtime (used by mistral_native).
    • Error reports and request IDs flow through the delivery primitive for consistent webhook/storage payloads.
    • Bridge now restores the caller’s current library and scopes a per-call ClassRegistry when loading crates to prevent global Kajson leaks; tests cover library-context restore and registry isolation. mistral_list_available_models now raises when no models remain after type filtering.
  • Migration

    • Replace the removed pipelex[mistralai-workflows] extra with pip install pipelex-mistralai-workflows and import from pipelex_mistralai_workflows.*.
    • Update to mistralai>=2.4.4 (new import path mistralai.client.*) and temporalio==1.24.0.
    • Requires Python >=3.12.

Written for commit d5c90e3. Summary will update on new commits.

Review in cubic

lchoquel and others added 30 commits May 6, 2026 21:37
- Updated `mistralai` dependency to version 2.4.4 in `pyproject.toml`.
- Added a new `TODOS.md` file for planning and progress tracking of Mistral Workflows integration.
- Introduced new activities and bridge for running Pipelex pipes within Mistral Workflows.
- Implemented execution modes for Pipelex pipes in Mistral Workflows.
- Added exception handling specific to Mistral Workflows.
- Updated various imports to align with the new `mistralai.client` structure.
- Enhanced type checking and error handling in workflow scripts.
- Added integration tests for the new Mistral Workflows activities.
- Introduced the `pipelex.plugins.mistralai_workflows` plugin, enabling invocation of Pipelex pipes within Mistral Workflows activities.
- Added three execution modes: `DIRECT`, `TEMPORAL_BLOCKING`, and `TEMPORAL_FIRE_AND_FORGET`, allowing flexible integration options.
- Created documentation for the new plugin and usage recipes, detailing installation and execution modes.
- Implemented integration tests for both blocking and fire-and-forget modes to ensure functionality.
- Updated `CHANGELOG.md` to reflect these additions and improvements.
- Introduced `pipelex_run_pipe_offloaded` activity to handle large payloads by leveraging Mistral's `ActivityInOutOffloadingInterceptor`, allowing seamless streaming of oversized data through blob storage.
- Updated `CHANGELOG.md` to document the new offloaded activity and its usage.
- Added integration tests for the offloaded activity to ensure correct payload handling and functionality.
- Enhanced documentation with examples for using the new offloaded activity and its configuration requirements.
- Added `pipelex_run_pipe_streaming` activity to enable real-time progress tracking of Pipelex pipes within Mistral Workflows, emitting lifecycle events (`CustomTaskStarted`, `CustomTaskInProgress`, `CustomTaskCompleted`, `CustomTaskFailed`).
- Enhanced `DIRECT` execution mode to provide per-step event updates, allowing detailed observability of pipe execution.
- Updated `CHANGELOG.md` to document the new streaming activity and its features.
- Created integration tests for the streaming activity to validate event emissions and functionality.
- Improved documentation with examples for using the new streaming variant in workflows.
- Implemented per-step event updates for the `pipelex_run_pipe_streaming` activity in `DIRECT` execution mode, allowing detailed observability of pipe execution through `CustomTaskInProgress` events.
- Updated `CHANGELOG.md` to reflect the new features and improvements in streaming support.
- Enhanced integration tests to validate the emission of per-step events during multi-step pipe executions.
- Improved documentation with examples for utilizing the new streaming features in workflows.
Remove the `output: PipelexPipeRunOutput | None = None` initializer and the
trailing `assert output is not None` in `_run_streaming_with_per_step_events`.
The narrowing was assert-based (stripped under `python -O`) and only existed
to satisfy the type checker after a `try`/`finally` cleanup block. With the
pre-init dropped, pyright narrows `output` from the `try` body alone, since
the post-`try/finally` code is only reachable on success.

Extend the drain comment to call out that the cleanup serves both the happy
path (snapshot ordering) and the failure path (publishing pending in-progress
events before `Task.__aexit__` emits `CustomTaskFailed`).
- Updated the `instructor` dependency to a new commit hash for improved functionality.
Relocate the in-tree TODOS.md to wip/mistral-workflows-sub-module.md and
add wip/mistral-workflows-plugin-extract.md outlining the extraction of
the Mistral Workflows integration into its own pip-installable plugin
package scaffolded from pipelex-starter-python.
…gration

- Introduced a new `pipelex.runtime_bridge` package with core components for executing Pipelex pipes in various modes (DIRECT, TEMPORAL_BLOCKING, TEMPORAL_FIRE_AND_FORGET).
- Added `ensure_pipelex_booted` function for idempotent initialization of Pipelex.
- Created input/output models (`PipelexPipeRunInput`, `PipelexPipeRunOutput`) for structured data handling.
- Implemented error handling with custom exceptions for runtime bridge operations.
- Developed comprehensive integration tests for the runtime bridge, covering direct execution and library crate handling.
- Updated documentation and TODOs to reflect the new structure and functionality.
- Extracted Mistral Workflows integration from `pipelex` into a new package `pipelex-mistralai-workflows`, allowing for independent installation and usage.
- Removed the `pipelex.plugins.mistralai_workflows` modules and updated the core runtime bridge to be framework-agnostic.
- Updated `CHANGELOG.md` to reflect the changes and migration instructions for users.
- Deleted outdated documentation and tests related to the previous plugin structure.
- Ensured no behavioral changes; all existing functionalities remain intact under the new package structure.
… updates and clarifying remaining tasks for plugin extraction
…ipelex.temporal

Move pipe_run_arg, hydration, submitter_hydration into a new
pipelex.runtime_bridge.primitives package and extract framework-agnostic
cores for graph assembly, delivery, and trace flushing. Add
pipe_classification.is_controller_pipe / is_leaf_pipe helpers.

The Temporal activity wrappers in pipelex.temporal.tprl_pipe now delegate
to the shared primitives, so the upcoming Mistral-native execution mode
can reuse the same bodies without coupling the plugin to pipelex.temporal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surface the new mode in PipelexExecutionMode + add the bridge dispatch
branch (raises MissingMistralWorkflowsPluginError with an install hint
until the plugin primitives land in the next phase).

The branch lazy-imports pipelex_mistralai_workflows.primitives.pipe_run
so the pipelex package itself stays free of the optional plugin dep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lets host runtimes (e.g. Mistral-native mode) install a custom pipe
router for the duration of a controller body without touching the
process-wide hub state. Tracked under primitives.md §10.5 — accepted
option (b).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…leaves

Pin the controller/leaf branching used by both pipelex.temporal and the
mistral-native plugin to dispatch pipes correctly. Covers all four
controller types (PipeSequence, PipeBatch, PipeCondition, PipeParallel)
and four leaf operators (PipeLLM, PipeCompose, PipeFunc, PipeImgGen)
via spec'd MagicMocks, since the classifier only inspects the type MRO.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove the entire "text then object" mechanism from PipeLLM down through cogt
and Temporal layers. The StructuringMethod.PRELIMINARY_TEXT enum value stays
so a future implementation can opt in; selecting it at runtime now raises
NotImplementedError. Rename make_object_direct -> make_object and
make_object_list_direct -> make_object_list since the "_direct" suffix only
existed to contrast with the deleted text-then-object variants.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Audit confirms today's per-workflow uniqueness invariant holds for the
collapse refactor: every operator-side ContentGeneratorProtocol method
is invoked at most once per WfPipeRouter execution (mutually-exclusive
branches in PipeLLM/PipeImgGen, single unconditional call in PipeExtract,
no calls from PipeCompose/StructuredContentComposer). Strategy (i) is
adopted with two mitigations for Phase 1: split the duplicate
"craft-image" default between make_single_image/make_image_list, and
construct distinct activity_ids inside make_extract_pages for its two
inner activity dispatches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lchoquel and others added 24 commits May 12, 2026 00:27
…hild-spawn paths

Phase 5 of the Temporal IDs/Naming redesign: replace deprecated dict-based
search attributes with TypedSearchAttributes throughout the workflow layer.
Adds five module-level SearchAttributeKey constants in observability.py and
flips the type annotations on the WorkflowExecutor surface. As a follow-up,
unifies the last raw workflow.execute_child_workflow call in wf_pipe_run.py
to route through WorkflowExecutor.execute_child_workflow, matching the
pattern already used by TemporalPipeRouter's child branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ath test

- Replace catch-all except Exception in workflow_caller.py with named SDK
  exceptions (WorkflowAlreadyStartedError, RPCError, WorkflowFailureError
  on the client path; ChildWorkflowError-only on the child path).
- Add failure-path integration test for WfPipeRun pinning the
  exception-type shift from ChildWorkflowError to WorkflowExecutionError
  introduced by the Phase 5 child-spawn-path unification.
- Fix latent production hang: register WorkflowExecutionError via
  workflow_failure_exception_types on the production Worker (and the
  test Worker). Without this, any workflow re-raising
  WorkflowExecutionError triggers indefinite workflow-task retry
  instead of failing terminally, because WorkflowExecutionError is not
  a temporalio.exceptions.FailureError subclass.
- Fix TODOS.md doc path: docs/under-the-hood/temporal-deployment.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captures the deferred design work to make WorkflowExecutionError inherit
from temporalio.exceptions.ApplicationError, which would remove the
workflow_failure_exception_types Worker-side registration added in
117bbe0. Documents scope, open questions, and trigger conditions for
the eventual cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…up CLI

Flip the Temporal search-attribute boot check from warn-and-continue to
hard-fail on reachable namespaces — the previous framing was dishonest
because real clusters reject every workflow start that references an
unregistered attribute. Add a [temporal.search_attributes] config block
(master enabled toggle + opt-in subset of the five built-ins), and a new
`pipelex setup-temporal-namespace` CLI that wraps the registration via
the same connection config the worker uses, with a permission-denied
fallback runbook for Temporal Cloud namespaces.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TODOS.md, the WfPipeRun failure-path test docstring, the worker
workflow_failure_exception_types comment, and the WorkflowExecutor
child-spawn wrapper docstrings still described the briefly-unified
state from the Phase 5 follow-up. The Phase 6 follow-up (commit
ac8e233) reverted that unification for replay-determinism reasons —
WorkflowExecutorFactory.create_executor seeds config-derived options
that would be baked into the recorded StartChildWorkflowExecution
command — but the surrounding prose was not updated to match.

Updated narrative to reflect the current state: both child-spawn
sites call workflow.execute_child_workflow(...) directly and wrap
ChildWorkflowError as WorkflowExecutionError in-place; the unused
WorkflowExecutor.execute_child_workflow / start_child_workflow
wrapper methods now carry warnings explaining the in-workflow
replay-determinism trap. No code-behavior changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…the rest

Move plans for shipped work (id-and-naming-plan pre-checkpoints, collapse-content-generation v2 plan+analysis+HTML, per-activity-queue-routing-v1, queue-options-and-worker-profiles plan+design, text-then-object brief, operators-as-activities analysis, workflow-and-activity-ids problem statement) into wip/archive/. Renumber the four surviving files with sortable prefixes: 00-temporal-id-primitives (evergreen reference), 01-id-and-naming-design (refreshed status: "Implemented"), 02-id-and-naming-plan (formerly top-level TODOS.md; refreshed status: "Phases 1-6 shipped"), 03-temporal-error-handling-revamp (the only deferred open item).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng, point at Worker Versioning

Document the rejected `TemporalDispatchSnapshot` approach (architectural
inversion, payload bloat, defeats central-config purpose, not
Temporal-idiomatic) and the three-option roadmap (docs+replay test /
Worker Versioning / thin search-attrs-only snapshot) so future readers
don't re-attempt the same wrong-shaped fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… claim, contradictory escape-hatch example, skill allowed-tools gaps + unbounded worker-start waits

- docs/distributed-execution/task-routing.md: correct activity_queues path to [temporal.worker_config.activity_queues.*] throughout (per-activity routing, per-handle overlays, resolution-order list)
- docs/under-the-hood/pipe-routing-and-execution.md: replace stale act_llm_gen_text-only claim with current resolve_dispatch behavior across all content-generation activities
- wip/temporal-primitives/id-and-naming.html: flip escape-hatch example to enabled=false so it matches the "turn off custom attributes entirely" header
- .claude/skills/temporal-e2e-validate/SKILL.md: add timeout/pkill/sleep/echo/tail/seq to allowed-tools; replace unbounded `until ... grep ...; do sleep 1; done` with bounded 30s waits that dump last 50 lines and exit 1 on timeout (both two-scoped-workers and single-worker blocks)
- wip/temporal-next/01-deferred-items.md: cross-cite cubic-dev-ai on the replay-determinism deferral so both reviewers' flags are visible
…p with shared helper

The _cv_job_iter helper was copy-pasted from pipe_job_from_library but dropped the
open_registry/close_registry bracket and let build_pipe_job mint its own random
pipeline_run_id, so --pipe-run-mode live runs would fail in reporting.

Extended pipe_job_from_library with an optional working_memory_builder hook, deleted
the duplicate, and routed cv_batch_screening_job through the single source of truth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	TODOS.md
#	docs/building-methods/pipes/pipe-operators/PipeLLM.md
#	pipelex/cogt/templating/template_preprocessor.py
#	tests/unit/pipelex/cogt/templating/test_template_preprocessor.py
#	tests/unit/pipelex/pipe_operators/pipe_llm/test_llm_prompt_blueprint.py
#	tests/unit/pipelex/pipe_operators/pipe_llm/test_pipe_llm_blueprint.py
…xtract / ReasoningEffort fields

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…to feature/Mistral-workflows-merge-2

# Conflicts:
#	CHANGELOG.md
#	TODOS.md
#	pipelex/temporal/tprl_pipe/temporal_pipe_router.py
#	pipelex/temporal/tprl_pipe/wf_pipe_run.py
#	tests/unit/pipelex/runtime_bridge/primitives/test_temporal_pipe_router_child_observability.py
…ows-merge-2

# Conflicts:
#	docs/building-methods/pipes/pipe-operators/PipeLLM.md
Reconcile dev into the Mistral Workflows feature branch. dev carried the
review-driven refinements of the shared Temporal/PipeStructure work (released
in v0.29.0) plus the error-handling overhaul, dataclass/pathlib cleanups, and
the v0.29-v0.30.3 releases; this branch carries the Mistral Workflows
integration, the runtime_bridge.primitives extraction, the MISTRAL_NATIVE
contextvar router, and the Temporal IDs/observability redesign.

Conflict resolution:
- Temporal config (pipelex.toml x3 + config_temporal.py): adopt dev's reviewed
  defaults (search_attributes off, empty queue_options, default worker-runtime
  profile, frozen DispatchOptions); drop HEAD's shipped rate-cap block and its
  guard test.
- Interpreter/core: take dev's relocated BundleElaboratorError; keep HEAD's
  hub.py contextvar pipe-router override (MISTRAL_NATIVE).
- Temporal runtime (workflow_caller, temporal_error, wf_pipe_*, act_*): weave
  HEAD's runtime_bridge.primitives extraction with dev's ErrorReport propagation
  (recover_error_report, convert_pipelex_errors, per-workflow WorkflowLog
  request_id). The execute_delivery primitive now forwards error_report and
  request_id end-to-end.
- Error-handling: adopt dev (observe-and-reraise in pipe_run, CogtError
  propagation in the router protocol, JobMetadata.request_id, jinja2.exceptions
  rename, relocated json error classes).
- Mistral workers: keep mistralai 2.x imports/structure; port dev's
  InferenceErrorCategory/UserAction enrichment onto the 2.x calls. Repoint
  dev-only tests and mistral_factory off the 1.x SDK paths.
- Docs/CHANGELOG: union; [Unreleased] = dev's entries plus the Mistral Workflows
  entry (the Temporal/PipeStructure entries stay under dev's v0.29.0 release).
- uv.lock regenerated against the merged pyproject (mistralai 2.4.4).

Verified: make tb, make agent-check (ruff/pyright/mypy clean), pipelex validate
--all, make agent-test (full suite), and the Temporal error-handling integration
tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 31, 2026

Greptile Summary

This PR adds runtime bridge support and a Mistral-native execution path. The main changes are:

  • Extracted shared runtime bridge types, bootstrap helpers, and execution modes.
  • Moved Temporal pipe-run primitives into pipelex.runtime_bridge.primitives.
  • Added context-scoped pipe router overrides for host runtimes.
  • Updated Temporal pipe workflows for shared delivery, hydration, tracing, and error-report handling.
  • Ported Mistral plugin code to the Mistral SDK 2.x import surface and reasoning controls.

Confidence Score: 2/5

These issues should be fixed before merging.

  • Library context can be cleared after crate-backed bridge and workflow runs.
  • Temporal pipe-run options can be silently ignored for both blocking and fire-and-forget starts.
  • Mistral text prompts can be sent with system instructions after user content.

Focus on pipelex/runtime_bridge/bridge.py, pipelex/temporal/tprl_pipe/wf_pipe_router.py, pipelex/temporal/tprl_pipe/temporal_pipe_run.py, and pipelex/plugins/mistral/mistral_factory.py.

Important Files Changed

Filename Overview
pipelex/runtime_bridge/bridge.py Adds the host-runtime bridge entry point and scoped library handling for crate-backed runs.
pipelex/temporal/tprl_pipe/temporal_pipe_run.py Wraps Pipelex pipe execution in Temporal workflows for blocking and fire-and-forget modes.
pipelex/temporal/tprl_pipe/wf_pipe_router.py Runs pipe-router child workflows with per-workflow libraries and buffered graph tracing.
pipelex/plugins/mistral/mistral_factory.py Builds Mistral SDK clients, chat messages, OCR inputs, and OCR outputs.

Comments Outside Diff (4)

  1. pipelex/temporal/tprl_pipe/wf_pipe_router.py, line 173-177 (link)

    P1 Preserve workflow library

    The workflow opens a crate-backed library and then always tears down the current library context. If this child workflow code is entered while another library context is already active, that outer context is erased after the pipe finishes. Any later code in the same workflow task that depends on the previous current library can fail lookups or run without the intended library.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pipelex/temporal/tprl_pipe/wf_pipe_router.py
    Line: 173-177
    
    Comment:
    **Preserve workflow library**
    
    The workflow opens a crate-backed library and then always tears down the current library context. If this child workflow code is entered while another library context is already active, that outer context is erased after the pipe finishes. Any later code in the same workflow task that depends on the previous current library can fail lookups or run without the intended library.
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. pipelex/temporal/tprl_pipe/temporal_pipe_run.py, line 71-75 (link)

    P1 Forward run options

    TemporalPipeRun stores workflow_execution_timeout and retry_policy, and the factory passes config defaults into the instance, but this executor creation drops those stored values. A caller that overrides the timeout or retry policy through make_temporal_pipe_run(...) will still start WfPipeRun with the factory defaults, so required deadlines or retry behavior are silently misapplied.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pipelex/temporal/tprl_pipe/temporal_pipe_run.py
    Line: 71-75
    
    Comment:
    **Forward run options**
    
    `TemporalPipeRun` stores `workflow_execution_timeout` and `retry_policy`, and the factory passes config defaults into the instance, but this executor creation drops those stored values. A caller that overrides the timeout or retry policy through `make_temporal_pipe_run(...)` will still start `WfPipeRun` with the factory defaults, so required deadlines or retry behavior are silently misapplied.
    
    How can I resolve this? If you propose a fix, please make it concise.
  3. pipelex/temporal/tprl_pipe/temporal_pipe_run.py, line 112-116 (link)

    P1 Forward start options

    The fire-and-forget path has the same option drop as the blocking path. start() builds a new executor without forwarding the timeout and retry settings stored on this TemporalPipeRun, so async pipe runs can ignore the configured workflow deadline or retry policy even though the instance was constructed with those values.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pipelex/temporal/tprl_pipe/temporal_pipe_run.py
    Line: 112-116
    
    Comment:
    **Forward start options**
    
    The fire-and-forget path has the same option drop as the blocking path. `start()` builds a new executor without forwarding the timeout and retry settings stored on this `TemporalPipeRun`, so async pipe runs can ignore the configured workflow deadline or retry policy even though the instance was constructed with those values.
    
    How can I resolve this? If you propose a fix, please make it concise.
  4. pipelex/plugins/mistral/mistral_factory.py, line 86-90 (link)

    P1 Send system first

    This builds Mistral chat messages with the user message before the system message. The structured-generation path in this same file sends the system message first, and chat providers commonly validate or prioritize messages by role order. For prompts with both system_text and user content, text generation can receive a different prompt shape than object generation, leading to provider errors or ignored system instructions.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pipelex/plugins/mistral/mistral_factory.py
    Line: 86-90
    
    Comment:
    **Send system first**
    
    This builds Mistral chat messages with the user message before the system message. The structured-generation path in this same file sends the system message first, and chat providers commonly validate or prioritize messages by role order. For prompts with both `system_text` and user content, text generation can receive a different prompt shape than object generation, leading to provider errors or ignored system instructions.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 5 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 5
pipelex/runtime_bridge/bridge.py:227-236
**Restore library context**

This scoped helper clears the current library instead of restoring the one that was active before the bridge call. When a host runtime invokes `run_pipe_via_bridge` with a `library_crate_dump` from inside an already scoped library, the bridge returns with no current library set. Later pipe or concept lookups in the same async context can then raise `RuntimeError("No current library set...")` or run against the wrong library state.

```suggestion
    library_manager = get_library_manager()
    library_id = f"runtime_bridge_{uuid4().hex[:8]}"
    prev_library_id = get_current_library_id_or_none()
    library_manager.open_library(library_id=library_id)
    set_current_library(library_id=library_id)
    try:
        library_manager.load_from_crate(library_id=library_id, crate=library_crate)
        yield library_id
    finally:
        library_manager.teardown(library_id=library_id)
        if prev_library_id is not None:
            set_current_library(library_id=prev_library_id)
        else:
            teardown_current_library()
```

### Issue 2 of 5
pipelex/temporal/tprl_pipe/wf_pipe_router.py:173-177
**Preserve workflow library**

The workflow opens a crate-backed library and then always tears down the current library context. If this child workflow code is entered while another library context is already active, that outer context is erased after the pipe finishes. Any later code in the same workflow task that depends on the previous current library can fail lookups or run without the intended library.

### Issue 3 of 5
pipelex/temporal/tprl_pipe/temporal_pipe_run.py:71-75
**Forward run options**

`TemporalPipeRun` stores `workflow_execution_timeout` and `retry_policy`, and the factory passes config defaults into the instance, but this executor creation drops those stored values. A caller that overrides the timeout or retry policy through `make_temporal_pipe_run(...)` will still start `WfPipeRun` with the factory defaults, so required deadlines or retry behavior are silently misapplied.

### Issue 4 of 5
pipelex/temporal/tprl_pipe/temporal_pipe_run.py:112-116
**Forward start options**

The fire-and-forget path has the same option drop as the blocking path. `start()` builds a new executor without forwarding the timeout and retry settings stored on this `TemporalPipeRun`, so async pipe runs can ignore the configured workflow deadline or retry policy even though the instance was constructed with those values.

### Issue 5 of 5
pipelex/plugins/mistral/mistral_factory.py:86-90
**Send system first**

This builds Mistral chat messages with the user message before the system message. The structured-generation path in this same file sends the system message first, and chat providers commonly validate or prioritize messages by role order. For prompts with both `system_text` and user content, text generation can receive a different prompt shape than object generation, leading to provider errors or ignored system instructions.

```suggestion
        if system_text := llm_job.llm_prompt.system_text:
            messages.append(SystemMessage(content=system_text))

        if user_content:
            messages.append(UserMessage(content=user_content))
```

Reviews (1): Last reviewed commit: "Merge branch 'dev' into feature/Mistral-..." | Re-trigger Greptile

Comment thread pipelex/runtime_bridge/bridge.py Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1db5ecb987

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pipelex/runtime_bridge/bridge.py Outdated
Comment thread pipelex/runtime_bridge/bridge.py Outdated
Comment thread pyproject.toml
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

24 issues found across 114 files

You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".claude/skills/workflows/references/getting-started/value-proposition.mdx">

<violation number="1" location=".claude/skills/workflows/references/getting-started/value-proposition.mdx:111">
P2: Broken link: `../appendices/streaming` points to a non-existent `appendices/` directory. Readers will get a 404.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.

Re-trigger cubic

Comment thread .claude/skills/workflows/references/guides/rate-limiting.mdx Outdated
Comment thread .claude/skills/workflows/references/guides/observability.mdx
Comment thread .claude/skills/workflows/references/getting-started/your-first-workflow.mdx Outdated
Comment thread .claude/skills/workflows/references/guides/streaming.mdx
Comment thread .claude/skills/workflows/references/guides/activities.mdx Outdated
Comment thread .claude/skills/workflows/references/getting-started/python-sdk.mdx Outdated
Comment thread pipelex/hub.py
Comment thread .claude/skills/workflows/references/getting-started/value-proposition.mdx Outdated
Comment thread .claude/skills/workflows/references/getting-started/value-proposition.mdx Outdated
Comment thread .claude/skills/workflows/references/getting-started/value-proposition.mdx Outdated
lchoquel and others added 2 commits May 31, 2026 16:18
…bridge crate path

Address unresolved review-agent findings on PR #954:

- _scoped_library_for_crate now uses hub.scoped_current_library() to
  capture and restore the caller's current-library ContextVar instead of
  unconditionally clearing it, so a bridge call made from within an
  already-scoped library no longer clobbers the caller's context.
- Seed a per-call ClassRegistry pre-loaded from the global registry and
  attach it to the scoped library before load_from_crate, so classes
  generated from a crate's inline structured concepts no longer leak into
  or collide in the global Kajson registry across crate versions. Mirrors
  the Temporal worker hydration path in wf_pipe_router.py.
- mistral_list_available_models raises MistralModelListingError when the
  type-filtered model list is empty, matching its two prior empty checks.

Adds regression tests for library-context restore and global-registry isolation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… Mistral Workflows docs

Triage of cubic-dev-ai review comments on PR #954 (verified against installed
mistralai 2.4.4):

- rate-limiting: import Mistral from mistralai.client, Depends from
  mistralai.workflows; drop non-existent Messages, type messages concretely
- scheduling: add workflows import + entrypoint decorator; SchedulePolicy
  fields catchup_window_seconds/overlap (all occurrences)
- activities: from datetime import timedelta (was datetime.timedelta)
- streaming: inject llm via Depends so snippets don't NameError
- python-sdk: add import os; fix "synchronous" mislabel
- your-first-workflow: valid JSON input example
- links: repoint payload-encoding/task-events to existing pages; remove
  dangling appendices/ links (streaming-architecture, worker-versioning,
  configuration-reference) across the references tree

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant