Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 .github/workflows/quality-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ jobs:
- name: Run workflow-nodes tests
run: cargo test -p workflow-nodes --lib

- name: Run embedded runtime unit tests
run: cargo test -p pantograph-embedded-runtime --lib
- name: Run runtime registry contract tests
run: cargo test -p pantograph-runtime-registry
- name: Run task summary contract tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ use crate::dependency_inventory_system_package_source::SystemPackageProviderSour
use crate::package_readiness_provider::PackageReadinessProbeRunner;
use crate::python_package_readiness_probe::ProcessPythonPackageReadinessProbeRunner;

/// Provider-owned diagnostic details; request attribution remains with the observer.
#[cfg(any(test, feature = "standalone"))]
pub(crate) struct DependencyInventoryDiagnosticInput {
pub code: pantograph_dependency_planning::DependencyPlanningDiagnosticCode,
pub message: String,
pub field_path: &'static str,
}

/// Request context passed from the snapshot producer to dependency inventory.
#[derive(Debug, Clone)]
pub(crate) struct DependencyInventoryRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ use pantograph_dependency_planning::{
};

use crate::dependency_inventory::{
DependencyInventoryObservation, DependencyInventoryProvider, DependencyInventoryRequest,
DependencyInventoryDiagnosticInput, DependencyInventoryObservation,
DependencyInventoryProvider, DependencyInventoryRequest,
};
use crate::dependency_inventory_device_toolchain_source::DeviceToolchainProviderSource;

Expand Down Expand Up @@ -128,9 +129,12 @@ fn observe_device_toolchain_binding(
binding.binding_id.clone(),
DependencyInventoryObservationState::Missing,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::ArtifactMissing,
"Device-toolchain source facts are missing for the requested toolchain.",
"dependency_environment.device_toolchain.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactMissing,
message: "Device-toolchain source facts are missing for the requested toolchain."
.into(),
field_path: "dependency_environment.device_toolchain.source",
},
ready_alternatives(&snapshot.rows),
);
}
Expand Down Expand Up @@ -225,9 +229,11 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Unavailable,
DependencyEnvironmentValidationState::Stale,
DependencyPlanningDiagnosticCode::ArtifactStale,
"Device-toolchain source facts are stale.",
"dependency_environment.device_toolchain.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactStale,
message: "Device-toolchain source facts are stale.".into(),
field_path: "dependency_environment.device_toolchain.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Ready, _) => row(
Expand All @@ -242,19 +248,23 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Missing,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::ArtifactMissing,
"Device-toolchain source facts are missing.",
"dependency_environment.device_toolchain.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactMissing,
message: "Device-toolchain source facts are missing.".into(),
field_path: "dependency_environment.device_toolchain.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Failed, _) => observation_with_diagnostic(
item,
binding_id,
DependencyInventoryObservationState::Failed,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::RuntimeUnavailable,
"Device-toolchain source reported a failure.",
"dependency_environment.device_toolchain.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::RuntimeUnavailable,
message: "Device-toolchain source reported a failure.".into(),
field_path: "dependency_environment.device_toolchain.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Unsupported, _)
Expand All @@ -267,9 +277,11 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Unavailable,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::RuntimeUnavailable,
"Device-toolchain source is not ready for the requested toolchain.",
"dependency_environment.device_toolchain.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::RuntimeUnavailable,
message: "Device-toolchain source is not ready for the requested toolchain.".into(),
field_path: "dependency_environment.device_toolchain.source",
},
source_row.alternatives.clone(),
),
}
Expand Down Expand Up @@ -336,9 +348,11 @@ fn invalid_row(
binding_id,
DependencyInventoryObservationState::Invalid,
DependencyEnvironmentValidationState::Invalid,
DependencyPlanningDiagnosticCode::InvalidRequest,
message,
field_path,
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::InvalidRequest,
message: message.into(),
field_path,
},
Vec::new(),
)
}
Expand All @@ -348,12 +362,15 @@ fn observation_with_diagnostic(
binding_id: DependencyBindingId,
state: DependencyInventoryObservationState,
validation_state: DependencyEnvironmentValidationState,
code: DependencyPlanningDiagnosticCode,
message: impl Into<String>,
field_path: &'static str,
diagnostic_input: DependencyInventoryDiagnosticInput,
alternatives: Vec<pantograph_dependency_planning::DependencyProviderSourceAlternative>,
) -> DependencyInventoryObservationRow {
let diagnostic = diagnostic(item, code, message.into(), field_path);
let DependencyInventoryDiagnosticInput {
code,
message,
field_path,
} = diagnostic_input;
let diagnostic = diagnostic(item, code, message, field_path);
row(
binding_id,
state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl DependencyInventoryProvider for NotImplementedDependencyInventoryProvider {
let failure = PackageReadinessProbeFailure::new(
PackageReadinessProviderDiagnosticCode::ProbeNotImplemented,
None,
CapabilityAvailabilityReason::parse(&not_implemented_reason(&request.payload))
CapabilityAvailabilityReason::parse(not_implemented_reason(&request.payload))
.expect("inventory provider not implemented reason is valid"),
);
let (rows, diagnostics) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ use pantograph_dependency_planning::{
};

use crate::dependency_inventory::{
DependencyInventoryObservation, DependencyInventoryProvider, DependencyInventoryRequest,
DependencyInventoryDiagnosticInput, DependencyInventoryObservation,
DependencyInventoryProvider, DependencyInventoryRequest,
};
use crate::dependency_inventory_system_package_source::{
SystemPackageProviderSource, SystemPackageProviderSourceError,
Expand Down Expand Up @@ -135,9 +136,12 @@ fn observe_system_package_binding(
binding.binding_id.clone(),
DependencyInventoryObservationState::Missing,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::ArtifactMissing,
"System-package source facts are missing for the requested package.",
"dependency_environment.system_package.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactMissing,
message: "System-package source facts are missing for the requested package."
.into(),
field_path: "dependency_environment.system_package.source",
},
ready_alternatives(&snapshot.rows),
);
}
Expand Down Expand Up @@ -240,9 +244,11 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Unavailable,
DependencyEnvironmentValidationState::Stale,
DependencyPlanningDiagnosticCode::ArtifactStale,
"System-package source facts are stale.",
"dependency_environment.system_package.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactStale,
message: "System-package source facts are stale.".into(),
field_path: "dependency_environment.system_package.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Ready, _) => row(
Expand All @@ -257,19 +263,23 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Missing,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::ArtifactMissing,
"System-package source facts are missing.",
"dependency_environment.system_package.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::ArtifactMissing,
message: "System-package source facts are missing.".into(),
field_path: "dependency_environment.system_package.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Failed, _) => observation_with_diagnostic(
item,
binding_id,
DependencyInventoryObservationState::Failed,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::RuntimeUnavailable,
"System-package source reported a failure.",
"dependency_environment.system_package.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::RuntimeUnavailable,
message: "System-package source reported a failure.".into(),
field_path: "dependency_environment.system_package.source",
},
source_row.alternatives.clone(),
),
(DependencyProviderSourceState::Unsupported, _)
Expand All @@ -282,9 +292,11 @@ fn observation_from_source_row(
binding_id,
DependencyInventoryObservationState::Unavailable,
DependencyEnvironmentValidationState::Valid,
DependencyPlanningDiagnosticCode::RuntimeUnavailable,
"System-package source is not ready for the requested package.",
"dependency_environment.system_package.source",
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::RuntimeUnavailable,
message: "System-package source is not ready for the requested package.".into(),
field_path: "dependency_environment.system_package.source",
},
source_row.alternatives.clone(),
),
}
Expand Down Expand Up @@ -380,9 +392,11 @@ fn invalid_row(
binding_id,
DependencyInventoryObservationState::Invalid,
DependencyEnvironmentValidationState::Invalid,
DependencyPlanningDiagnosticCode::InvalidRequest,
message,
field_path,
DependencyInventoryDiagnosticInput {
code: DependencyPlanningDiagnosticCode::InvalidRequest,
message: message.into(),
field_path,
},
Vec::new(),
)
}
Expand All @@ -392,12 +406,15 @@ fn observation_with_diagnostic(
binding_id: DependencyBindingId,
state: DependencyInventoryObservationState,
validation_state: DependencyEnvironmentValidationState,
code: DependencyPlanningDiagnosticCode,
message: impl Into<String>,
field_path: &'static str,
diagnostic_input: DependencyInventoryDiagnosticInput,
alternatives: Vec<pantograph_dependency_planning::DependencyProviderSourceAlternative>,
) -> DependencyInventoryObservationRow {
let diagnostic = diagnostic(item, code, message.into(), field_path);
let DependencyInventoryDiagnosticInput {
code,
message,
field_path,
} = diagnostic_input;
let diagnostic = diagnostic(item, code, message, field_path);
row(
binding_id,
state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,31 @@ async fn inventory_service_routes_device_toolchain_payloads_with_alternatives()
device_toolchain_status.state,
DependencyBindingStatusState::Unavailable
);
assert_eq!(
device_toolchain_status.diagnostics,
vec![
pantograph_dependency_planning::DependencyPlanningDiagnostic {
code: DependencyPlanningDiagnosticCode::RuntimeUnavailable,
severity: pantograph_dependency_planning::DependencyPlanningSeverity::Error,
message: "Device-toolchain source is not ready for the requested toolchain."
.to_string(),
model_id: Some(request.as_request().identity_key.model_ref.model_id.clone()),
runtime_id: request
.as_request()
.identity_key
.scheduler_intent
.requested_runtime_id
.clone(),
device_id: request
.as_request()
.identity_key
.scheduler_intent
.requested_device_id
.clone(),
field_path: Some("dependency_environment.device_toolchain.source".to_string()),
}
]
);
assert_eq!(device_toolchain_status.alternatives.len(), 1);
assert_eq!(
device_toolchain_status.alternatives[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ mod tests {

let facts = resolver_facts_from_sources(
PumasDispatchPackageFactsBridgeOutcome::Projected {
facts: package,
facts: Box::new(package),
diagnostics: Vec::new(),
},
&runtime,
Expand Down Expand Up @@ -388,7 +388,7 @@ mod tests {
fn missing_runtime_facts_keep_capability_but_publish_no_runtime_availability() {
let facts = resolver_facts_from_sources(
PumasDispatchPackageFactsBridgeOutcome::Projected {
facts: projected_package_facts(),
facts: Box::new(projected_package_facts()),
diagnostics: Vec::new(),
},
&RuntimeDispatchCapabilityFactsOutcome::Unavailable {
Expand Down
3 changes: 2 additions & 1 deletion crates/pantograph-embedded-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ pub use task_executor::{runtime_extension_keys, TauriTaskExecutor as PantographT
pub(crate) use workflow_scheduler_diagnostics::EmbeddedWorkflowSchedulerDiagnosticsProvider;
pub use workflow_service_composition::{
EmbeddedHostedStartupCompositionInput, EmbeddedHostedStartupCompositionOutput,
EmbeddedHostedStartupPumasSelectorSource, EmbeddedWorkflowServiceComposition,
EmbeddedHostedStartupConfig, EmbeddedHostedStartupPumasSelectorSource,
EmbeddedWorkflowServiceComposition,
};

pub type SharedWorkflowService = Arc<WorkflowService>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ use pantograph_inference_interface_contracts::{
use pantograph_runtime_attribution::WorkflowVersionRecord;
use pantograph_runtime_host_contracts::{
ReservationLifecycleApplication, ReservationLifecycleApplicationState,
ReservationLifecycleEvent, ReservationLifecycleOutcome, ReservationLifecyclePort,
ReservationLifecyclePortError, RESERVATION_LIFECYCLE_CONTRACT_VERSION,
RUNTIME_SESSION_LOAD_PROOF_CONTRACT_VERSION,
ReservationLifecycleDiagnostic, ReservationLifecycleDiagnosticCode,
ReservationLifecycleDiagnosticSeverity, ReservationLifecycleEvent, ReservationLifecycleOutcome,
ReservationLifecyclePort, ReservationLifecyclePortError,
RESERVATION_LIFECYCLE_CONTRACT_VERSION, RUNTIME_SESSION_LOAD_PROOF_CONTRACT_VERSION,
};
use pantograph_scheduler::{
SchedulerDispatchCandidateId, SchedulerEstimateHint, SchedulerEstimateHintKind,
Expand Down Expand Up @@ -239,17 +240,41 @@ async fn workflow_execution_session_dispatches_through_production_embedded_image
assert_eq!(body.response.media_type, "image/png");
assert_eq!(dependency_readiness_work_queue.len(), 1);
assert_eq!(source_refresher.model_refs(), vec![MODEL_ID.to_string()]);
let lifecycle_events = reservation_lifecycle_port.events();
assert_eq!(
reservation_lifecycle_port
.events()
lifecycle_events
.iter()
.map(|event| &event.outcome)
.collect::<Vec<_>>(),
vec![
&ReservationLifecycleOutcome::DispatchStarted,
&ReservationLifecycleOutcome::RuntimeHostCompleted,
&ReservationLifecycleOutcome::RetryDeferred,
]
);
let deferred = &lifecycle_events[1];
assert_eq!(
deferred.reservation_lease_id,
lifecycle_events[0].reservation_lease_id
);
assert_eq!(
deferred.reservation_lease_id.as_str(),
"reservation.embedded_runtime_session_test.infer"
);
assert_eq!(
deferred.workflow_run_id,
lifecycle_events[0].workflow_run_id
);
assert_eq!(deferred.task_id, lifecycle_events[0].task_id);
assert_eq!(deferred.candidate_id, lifecycle_events[0].candidate_id);
assert_eq!(
deferred.diagnostics,
vec![ReservationLifecycleDiagnostic {
severity: ReservationLifecycleDiagnosticSeverity::Info,
code: ReservationLifecycleDiagnosticCode::RetryDeferred,
message: "embedded runtime-host image batch member completed".to_string(),
hint: None,
}]
);
assert_eq!(host.runtime_load_attempts.load(Ordering::SeqCst), 0);
assert_eq!(host.run_attempts.load(Ordering::SeqCst), 0);
}
Expand Down
Loading
Loading