Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8d58cce
feat(plugin): add native API v2 LLM dispatch
bbednarski9 Jul 30, 2026
934d2b2
fix(plugin): bound native API v2 provider streams
bbednarski9 Jul 30, 2026
1e15451
fix(plugin): harden native API v2 streams
bbednarski9 Jul 30, 2026
59f59d7
refactor(plugin): use targeted HTTP LLM dispatch
bbednarski9 Jul 31, 2026
de3fd45
refactor(plugin): clarify LLM continuation types
bbednarski9 Jul 31, 2026
a455841
refactor(plugin): move targeted LLM dispatch into core
bbednarski9 Jul 31, 2026
79d6d1c
fix(plugin): harden targeted LLM continuations
bbednarski9 Jul 31, 2026
c960ec9
feat(plugin): add safe native API v2 continuations
bbednarski9 Aug 1, 2026
2025301
docs(plugin): document safe native API v2 facade
bbednarski9 Aug 1, 2026
43589ea
fix(runtime): use registered targeted dispatch log target
bbednarski9 Aug 1, 2026
ec26390
fix(plugin): avoid safe callback thread-local teardown
bbednarski9 Aug 1, 2026
1821bc4
test(plugin): cover safe v2 failure paths
bbednarski9 Aug 1, 2026
007b19b
test(plugin): harden native v2 host failure paths
bbednarski9 Aug 1, 2026
59ca422
refactor(plugin): narrow continuation transport contract
bbednarski9 Aug 1, 2026
38a11fb
refactor(plugin): poll native v2 callbacks cooperatively
bbednarski9 Aug 2, 2026
6b470b0
docs(plugin): require executor-neutral native futures
bbednarski9 Aug 2, 2026
c14057b
refactor(plugin): simplify targeted LLM continuations
bbednarski9 Aug 2, 2026
fc02743
refactor(plugin): remove native v2 continuation duplication
bbednarski9 Aug 2, 2026
53ba86a
refactor(plugin): trim native v2 policy surface
bbednarski9 Aug 2, 2026
5bbbce1
fix(plugin): preserve targets across continuation hops
bbednarski9 Aug 2, 2026
ad2f60e
docs(plugin): clarify cooperative continuation semantics
bbednarski9 Aug 2, 2026
3861d63
fix(runtime): bound targeted buffered responses
bbednarski9 Aug 2, 2026
82141cf
refactor(plugin): share bounded native stream capacity
bbednarski9 Aug 2, 2026
85e72ed
fix(plugin): address native API v2 review findings
bbednarski9 Aug 3, 2026
cbd9943
fix(core): bound and preserve targeted SSE frames
bbednarski9 Aug 3, 2026
a83f142
fix(plugin): correct 32-bit host table assertions
bbednarski9 Aug 3, 2026
5918f8c
docs(plugin): clarify native API v2 compatibility
bbednarski9 Aug 3, 2026
ec8f9cd
test(plugin): cover native stream error cleanup
bbednarski9 Aug 3, 2026
a5acddf
test(plugin): reconcile native lifecycle coverage
bbednarski9 Aug 3, 2026
6dac757
test(plugin): gate Unix-only native callbacks
bbednarski9 Aug 3, 2026
6598e0c
test(plugin): split native layout assertions
bbednarski9 Aug 3, 2026
3a8f8f0
test(plugin): split native failure assertions
bbednarski9 Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ tokio = { version = "1", default-features = false, features = ["rt", "rt-multi-t
tokio-stream = { version = "0.1", default-features = false, features = ["sync"] }
typed-builder = "0.23.2"
futures-util = "0.3"
async-stream = "0.3"
opentelemetry = { workspace = true, features = ["trace"] }
opentelemetry-semantic-conventions.workspace = true
opentelemetry_sdk = { workspace = true, features = ["trace", "internal-logs"] }
Expand Down
15 changes: 12 additions & 3 deletions crates/core/src/api/llm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use crate::api::runtime::subscriber_dispatcher::{
use crate::api::runtime::{
EventSubscriberFn, LlmCollectorFn, LlmExecutionNextFn, LlmFinalizerFn, LlmJsonStream,
LlmSanitizeRequestContext, LlmSanitizeResponseContext, LlmStreamExecutionNextFn,
MiddlewareContinuationContext, with_active_event_uuid,
MiddlewareContinuationContext, targeted_llm_execution, targeted_llm_stream_execution,
with_active_event_uuid,
};
use crate::api::runtime::{ScopeStackHandle, current_scope_stack};
use crate::api::scope::event;
Expand Down Expand Up @@ -1494,7 +1495,11 @@ pub async fn llm_call_execute(params: LlmCallExecuteParams) -> Result<Json> {
let state = context
.read()
.map_err(|error| FlowError::Internal(error.to_string()))?;
state.llm_build_execution_chain(&execution_name, func, &scope_locals)
state.llm_build_execution_chain(
&execution_name,
targeted_llm_execution(func),
&scope_locals,
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};
execution(intercepted_request).await
}),
Expand Down Expand Up @@ -1703,7 +1708,11 @@ pub async fn llm_stream_call_execute(params: LlmStreamCallExecuteParams) -> Resu
let state = context
.read()
.map_err(|error| FlowError::Internal(error.to_string()))?;
state.llm_stream_build_execution_chain(&execution_name, func, &scope_locals)
state.llm_stream_build_execution_chain(
&execution_name,
targeted_llm_stream_execution(func),
&scope_locals,
)
};
let execution_context = MiddlewareContinuationContext::capture();
execution(intercepted_request)
Expand Down
6 changes: 6 additions & 0 deletions crates/core/src/api/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
pub mod callbacks;
mod continuation_context;
pub mod global;
mod llm_dispatch_context;
pub mod scope_stack;
pub mod state;
pub mod subscriber_dispatcher;
Expand All @@ -23,6 +24,11 @@ pub use continuation_context::MiddlewareContinuationContext;
#[cfg(test)]
pub(crate) use continuation_context::MiddlewareContinuationLease;
pub use global::global_context;
#[cfg(test)]
pub(crate) use llm_dispatch_context::current_llm_dispatch_target;
pub(crate) use llm_dispatch_context::{
LlmDispatchTargetContext, targeted_llm_execution, targeted_llm_stream_execution,
};
pub use scope_stack::{
PropagationContext, ScopeStack, ScopeStackHandle, TASK_SCOPE_STACK, ThreadScopeStackBinding,
capture_propagation_context, capture_propagation_context_with_root, capture_thread_scope_stack,
Expand Down
36 changes: 33 additions & 3 deletions crates/core/src/api/runtime/continuation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use std::future::Future;
use crate::api::optimization::{
LlmOptimizationRecorder, current_llm_optimization_recorder, scope_llm_optimization_recorder,
};
use crate::api::runtime::llm_dispatch_context::{
LlmDispatchTargetContext, current_llm_dispatch_target, scope_llm_dispatch_target,
};
use crate::api::runtime::scope_stack::{
ScopeStackHandle, TASK_SCOPE_STACK, active_event_uuid, current_context_scope_stack,
current_scope_stack, scope_stack_active, snapshot_scope_stack, with_active_event_uuid,
Expand All @@ -31,6 +34,7 @@ pub struct MiddlewareContinuationContext {
publication_context: Option<PublicationContext>,
publication_buffer: Option<PublicationBuffer>,
optimization_recorder: Option<LlmOptimizationRecorder>,
llm_dispatch_target: Option<LlmDispatchTargetContext>,
}

impl MiddlewareContinuationContext {
Expand All @@ -44,6 +48,7 @@ impl MiddlewareContinuationContext {
publication_context: capture_publication_context(),
publication_buffer: capture_nested_publication_buffer(),
optimization_recorder: current_llm_optimization_recorder(),
llm_dispatch_target: current_llm_dispatch_target(),
}
}

Expand All @@ -69,6 +74,7 @@ impl MiddlewareContinuationContext {
publication_context: self.publication_context.clone(),
publication_buffer: self.publication_buffer.clone(),
optimization_recorder: self.optimization_recorder.clone(),
llm_dispatch_target: self.llm_dispatch_target.clone(),
})
}

Expand Down Expand Up @@ -97,12 +103,36 @@ impl MiddlewareContinuationContext {
None => published.await,
}
};
match &self.optimization_recorder {
Some(recorder) => scope_llm_optimization_recorder(recorder.clone(), active).await,
None => active.await,
let optimized = async {
match &self.optimization_recorder {
Some(recorder) => scope_llm_optimization_recorder(recorder.clone(), active).await,
None => active.await,
}
};
match &self.llm_dispatch_target {
Some(target) => {
scope_llm_dispatch_target(self.active_event_uuid, target.clone(), optimized).await
}
None => optimized.await,
}
}

/// Invoke a callback and poll its future with the captured Relay context and typed LLM target.
#[doc(hidden)]
pub(crate) async fn invoke_with_llm_dispatch_target<C, F>(
&self,
target: LlmDispatchTargetContext,
callback: C,
) -> F::Output
where
C: FnOnce() -> F,
F: Future,
{
let mut context = self.clone();
context.llm_dispatch_target = Some(target);
context.invoke(callback).await
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// Invoke a callback and poll its future with the captured Relay context.
///
/// The callback itself can inspect Relay task state before constructing its
Expand Down
Loading
Loading