use std::fmt;
use crate::root_envelopes::{RootEnvelopeMode, serialize_named_json_output};
use fallow_types::envelope::{ElapsedMs, ToolVersion};
use serde::{Deserialize, Serialize};
pub const SIMILAR_CODE_SCHEMA_VERSION: u32 = 1;
pub const SIMILAR_CODE_INSPECT_SCHEMA_VERSION: u32 = 1;
pub const SIMILAR_CODE_REVIEW_SCHEMA_VERSION: u32 = 1;
pub const SIMILAR_CODE_STATUS_SCHEMA_VERSION: u32 = 1;
pub const SIMILAR_CODE_CACHE_CLEAR_SCHEMA_VERSION: u32 = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeInspectSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeReviewSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeStatusSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeCacheClearSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeStatusOutput {
pub schema_version: SimilarCodeStatusSchemaVersion,
pub version: ToolVersion,
pub protocol_version: u32,
pub embedding_semantics_version: u32,
pub companion_version: String,
pub model_ready: bool,
pub model_id: String,
pub model_revision: String,
pub dimensions: u32,
pub max_tokens: u32,
pub license: String,
pub cache_dir: String,
pub download_bytes: u64,
pub analysis_offline: bool,
pub integrity_verified: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub problem: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub downloaded: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeCacheClearOutput {
pub schema_version: SimilarCodeCacheClearSchemaVersion,
pub version: ToolVersion,
pub removed: bool,
pub model_removed: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SimilarCodeVerdictSchemaVersion {
#[serde(rename = "1")]
V1,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeProviderProvenance {
pub provider: SimilarCodeProvider,
pub companion_version: String,
pub protocol_version: u32,
pub source_left_machine: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeProvider {
OfficialLocalCompanion,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeModelProvenance {
pub model_id: String,
pub revision: String,
pub artifact_sha256: String,
pub license: String,
pub dimensions: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeGenerationParameters {
pub dtype: String,
pub pooling: String,
pub normalized: bool,
pub batch_size: u32,
pub max_tokens: u32,
pub parameter_sha256: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeScopeProvenance {
pub active: bool,
pub paths: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeGeneration {
pub extraction_semantics_version: u32,
pub embedding_semantics_version: u32,
pub provider: SimilarCodeProviderProvenance,
pub model: SimilarCodeModelProvenance,
pub parameters: SimilarCodeGenerationParameters,
pub scope: SimilarCodeScopeProvenance,
pub threshold: f64,
pub min_lines: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeLocation {
pub path: String,
pub name: String,
pub start_line: u32,
pub start_column: u32,
pub end_line: u32,
pub end_column: u32,
pub source_sha256: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeSimilarityBand {
Moderate,
High,
VeryHigh,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeVerificationStatus {
Unverified,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeEnrichmentState {
Available,
Unavailable,
NotRequested,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeEnrichmentAvailability {
pub graph_relationship: SimilarCodeEnrichmentState,
pub entry_point_reachability: SimilarCodeEnrichmentState,
pub callers: SimilarCodeEnrichmentState,
pub callees: SimilarCodeEnrichmentState,
pub ownership: SimilarCodeEnrichmentState,
pub churn: SimilarCodeEnrichmentState,
pub tests: SimilarCodeEnrichmentState,
pub deterministic_clone_coverage: SimilarCodeEnrichmentState,
pub runtime: SimilarCodeEnrichmentState,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeAction {
pub action: SimilarCodeActionType,
pub description: String,
pub read_only: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeActionType {
Inspect,
Review,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeCandidate {
pub candidate_id: String,
pub review_key: String,
pub left: SimilarCodeLocation,
pub right: SimilarCodeLocation,
pub similarity: f64,
pub similarity_band: SimilarCodeSimilarityBand,
pub verification_status: SimilarCodeVerificationStatus,
pub enrichment: SimilarCodeEnrichmentAvailability,
pub actions: Vec<SimilarCodeAction>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodePhase {
Discovery,
Extraction,
Cache,
Embedding,
Validation,
Comparison,
Enrichment,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodePhaseStatus {
Complete,
Partial,
Skipped,
TimedOut,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodePhaseCompletion {
pub phase: SimilarCodePhase,
pub status: SimilarCodePhaseStatus,
pub processed: u64,
pub total: Option<u64>,
pub reason: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeLimits {
pub max_files: u64,
pub max_functions: u64,
pub max_source_bytes: u64,
pub max_function_bytes: u64,
pub max_batch_size: u64,
pub max_vector_bytes: u64,
pub max_comparisons: u64,
pub max_candidates: u64,
pub max_neighbors_per_function: u64,
pub timeout_ms: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeSkipReason {
BelowMinimumLines,
UnsupportedFunction,
GeneratedSource,
FunctionTooLarge,
InputLimit,
SourceBytesLimit,
VectorMemoryLimit,
ComparisonLimit,
CandidateLimit,
NeighborLimit,
Timeout,
ProviderFailure,
TokenTruncation,
EnrichmentUnavailable,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeSkip {
pub phase: SimilarCodePhase,
pub reason: SimilarCodeSkipReason,
pub count: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeCacheStatus {
Disabled,
Hit,
Miss,
Mixed,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeCacheSummary {
pub status: SimilarCodeCacheStatus,
pub hits: u64,
pub misses: u64,
pub writes: u64,
pub invalid_entries: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeCompletionStatus {
Complete,
Partial,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeCompletion {
pub status: SimilarCodeCompletionStatus,
pub phases: Vec<SimilarCodePhaseCompletion>,
pub limits: SimilarCodeLimits,
pub skips: Vec<SimilarCodeSkip>,
pub cache: SimilarCodeCacheSummary,
pub provider_inference_ms: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeDiagnosticDomain {
Workspace,
Extraction,
Provider,
Cache,
Enrichment,
Review,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeDiagnostic {
pub domain: SimilarCodeDiagnosticDomain,
pub code: String,
pub message: String,
pub path: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeOutput {
pub schema_version: SimilarCodeSchemaVersion,
pub version: ToolVersion,
pub elapsed_ms: ElapsedMs,
pub generation: SimilarCodeGeneration,
pub candidates: Vec<SimilarCodeCandidate>,
pub completion: SimilarCodeCompletion,
pub diagnostics: Vec<SimilarCodeDiagnostic>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct SimilarCodeOutputWire {
schema_version: SimilarCodeSchemaVersion,
version: String,
elapsed_ms: u64,
generation: SimilarCodeGeneration,
candidates: Vec<SimilarCodeCandidate>,
completion: SimilarCodeCompletion,
diagnostics: Vec<SimilarCodeDiagnostic>,
}
impl<'de> Deserialize<'de> for SimilarCodeOutput {
fn deserialize<Deserializer>(deserializer: Deserializer) -> Result<Self, Deserializer::Error>
where
Deserializer: serde::Deserializer<'de>,
{
let wire = SimilarCodeOutputWire::deserialize(deserializer)?;
Ok(Self {
schema_version: wire.schema_version,
version: ToolVersion(wire.version),
elapsed_ms: ElapsedMs(wire.elapsed_ms),
generation: wire.generation,
candidates: wire.candidates,
completion: wire.completion,
diagnostics: wire.diagnostics,
})
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct SimilarCodeCandidateSnapshot {
pub schema_version: SimilarCodeSchemaVersion,
pub generation: SimilarCodeGeneration,
pub candidate: SimilarCodeCandidate,
pub completion: SimilarCodeCompletion,
pub diagnostics: Vec<SimilarCodeDiagnostic>,
}
#[cfg(feature = "schema")]
impl SimilarCodeCandidateSnapshot {
#[must_use]
pub fn json_schema() -> serde_json::Value {
serde_json::to_value(schemars::schema_for!(SimilarCodeCandidateSnapshot))
.unwrap_or_default()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeNamedReference {
pub path: String,
pub name: String,
pub line: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeSideEffectHint {
PureLooking,
MayHaveSideEffects,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeSideEvidence {
pub source_window: Option<String>,
pub parameter_count: Option<u32>,
pub is_async: Option<bool>,
pub is_generator: Option<bool>,
pub has_await: Option<bool>,
pub has_throw: Option<bool>,
pub side_effect_hint: Option<SimilarCodeSideEffectHint>,
pub entry_point_reachable: Option<bool>,
pub callers: Vec<SimilarCodeNamedReference>,
pub callees: Vec<SimilarCodeNamedReference>,
pub owners: Vec<String>,
pub churn_commits: Option<u64>,
pub tests: Vec<String>,
pub deterministic_clone_coverage: Option<f64>,
pub runtime_observations: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeInspectPacket {
pub candidate_id: String,
pub review_key: String,
pub availability: SimilarCodeEnrichmentAvailability,
pub graph_relationship: Option<String>,
pub left: SimilarCodeSideEvidence,
pub right: SimilarCodeSideEvidence,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeInspectOutput {
pub schema_version: SimilarCodeInspectSchemaVersion,
pub version: ToolVersion,
pub elapsed_ms: ElapsedMs,
pub generation: SimilarCodeGeneration,
pub candidate: SimilarCodeCandidate,
pub packet: SimilarCodeInspectPacket,
pub completion: SimilarCodeCompletion,
pub diagnostics: Vec<SimilarCodeDiagnostic>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct SimilarCodeInspectOutputWire {
schema_version: SimilarCodeInspectSchemaVersion,
version: String,
elapsed_ms: u64,
generation: SimilarCodeGeneration,
candidate: SimilarCodeCandidate,
packet: SimilarCodeInspectPacket,
completion: SimilarCodeCompletion,
diagnostics: Vec<SimilarCodeDiagnostic>,
}
impl<'de> Deserialize<'de> for SimilarCodeInspectOutput {
fn deserialize<Deserializer>(deserializer: Deserializer) -> Result<Self, Deserializer::Error>
where
Deserializer: serde::Deserializer<'de>,
{
let wire = SimilarCodeInspectOutputWire::deserialize(deserializer)?;
Ok(Self {
schema_version: wire.schema_version,
version: ToolVersion(wire.version),
elapsed_ms: ElapsedMs(wire.elapsed_ms),
generation: wire.generation,
candidate: wire.candidate,
packet: wire.packet,
completion: wire.completion,
diagnostics: wire.diagnostics,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct SimilarCodeVerdict {
pub candidate_id: String,
pub review_key: String,
pub candidate_worthy: Option<bool>,
pub behaviorally_equivalent: Option<bool>,
pub refactor_safe: Option<bool>,
pub outcome: SimilarCodeDomainOutcome,
pub rationale: String,
}
impl SimilarCodeVerdict {
pub fn validate(&self) -> Result<(), SimilarCodeVerdictValidationError> {
if self.refactor_safe == Some(true) && self.behaviorally_equivalent != Some(true) {
return Err(SimilarCodeVerdictValidationError::RefactorSafetyRequiresEquivalence);
}
if self.behaviorally_equivalent == Some(true) && self.candidate_worthy != Some(true) {
return Err(SimilarCodeVerdictValidationError::EquivalenceRequiresCandidate);
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimilarCodeVerdictValidationError {
RefactorSafetyRequiresEquivalence,
EquivalenceRequiresCandidate,
}
impl fmt::Display for SimilarCodeVerdictValidationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::RefactorSafetyRequiresEquivalence => {
formatter.write_str("refactor_safe=true requires behaviorally_equivalent=true")
}
Self::EquivalenceRequiresCandidate => {
formatter.write_str("behaviorally_equivalent=true requires candidate_worthy=true")
}
}
}
}
impl std::error::Error for SimilarCodeVerdictValidationError {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeDomainOutcome {
SameResponsibility,
RelatedButDistinct,
IntentionalDuplication,
Unrelated,
NeedsHumanReview,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct SimilarCodeVerdictInput {
pub schema_version: SimilarCodeVerdictSchemaVersion,
pub verdicts: Vec<SimilarCodeVerdict>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
pub enum SimilarCodeVerdictMatch {
CandidateId,
ReviewKey,
Unverified,
AmbiguousReviewKey,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeReviewedCandidate {
pub candidate: SimilarCodeCandidate,
pub verdict: Option<SimilarCodeVerdict>,
pub verdict_match: SimilarCodeVerdictMatch,
pub outcome: SimilarCodeDomainOutcome,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeReviewProvenance {
pub candidates_sha256: String,
pub verdicts_sha256: String,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SimilarCodeReviewOutput {
pub schema_version: SimilarCodeReviewSchemaVersion,
pub version: ToolVersion,
pub elapsed_ms: ElapsedMs,
pub generation: SimilarCodeGeneration,
pub review: SimilarCodeReviewProvenance,
pub candidates: Vec<SimilarCodeReviewedCandidate>,
pub completion: SimilarCodeCompletion,
pub diagnostics: Vec<SimilarCodeDiagnostic>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct SimilarCodeReviewOutputWire {
schema_version: SimilarCodeReviewSchemaVersion,
version: String,
elapsed_ms: u64,
generation: SimilarCodeGeneration,
review: SimilarCodeReviewProvenance,
candidates: Vec<SimilarCodeReviewedCandidate>,
completion: SimilarCodeCompletion,
diagnostics: Vec<SimilarCodeDiagnostic>,
}
impl<'de> Deserialize<'de> for SimilarCodeReviewOutput {
fn deserialize<Deserializer>(deserializer: Deserializer) -> Result<Self, Deserializer::Error>
where
Deserializer: serde::Deserializer<'de>,
{
let wire = SimilarCodeReviewOutputWire::deserialize(deserializer)?;
Ok(Self {
schema_version: wire.schema_version,
version: ToolVersion(wire.version),
elapsed_ms: ElapsedMs(wire.elapsed_ms),
generation: wire.generation,
review: wire.review,
candidates: wire.candidates,
completion: wire.completion,
diagnostics: wire.diagnostics,
})
}
}
pub fn serialize_similar_code_json_output(
output: SimilarCodeOutput,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "similar-code", mode)
}
pub fn serialize_similar_code_inspect_json_output(
output: SimilarCodeInspectOutput,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "similar-code-inspect", mode)
}
pub fn serialize_similar_code_review_json_output(
output: SimilarCodeReviewOutput,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "similar-code-review", mode)
}
pub fn serialize_similar_code_status_json_output(
output: SimilarCodeStatusOutput,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "similar-code-status", mode)
}
pub fn serialize_similar_code_cache_clear_json_output(
output: SimilarCodeCacheClearOutput,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "similar-code-cache-clear", mode)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn verdict_axes_remain_independent_but_enforce_implication() {
let verdict = SimilarCodeVerdict {
candidate_id: "sc_123".to_string(),
review_key: "scr_456".to_string(),
candidate_worthy: Some(true),
behaviorally_equivalent: Some(false),
refactor_safe: Some(true),
outcome: SimilarCodeDomainOutcome::RelatedButDistinct,
rationale: "Same domain, different behavior.".to_string(),
};
assert_eq!(
verdict.validate(),
Err(SimilarCodeVerdictValidationError::RefactorSafetyRequiresEquivalence)
);
}
#[test]
fn raw_serializer_adds_only_the_similar_code_kind() {
let output = raw_output();
let value = serialize_similar_code_json_output(output, RootEnvelopeMode::Tagged)
.expect("similar-code output should serialize");
assert_eq!(value["kind"], "similar-code");
assert_eq!(value["schema_version"], "1");
assert!(value.get("severity").is_none());
assert!(value.get("gate").is_none());
assert!(value.get("fixes").is_none());
}
#[test]
fn raw_output_round_trips_for_review_input() {
let value = serde_json::to_value(raw_output()).expect("raw output should serialize");
let decoded: SimilarCodeOutput =
serde_json::from_value(value).expect("raw output should deserialize");
assert_eq!(decoded.schema_version, SimilarCodeSchemaVersion::V1);
assert_eq!(decoded.version.0, "3.9.0");
assert_eq!(
decoded.completion.status,
SimilarCodeCompletionStatus::Complete
);
}
#[test]
fn verdict_input_rejects_unknown_fields() {
let value = serde_json::json!({
"schema_version": "1",
"verdicts": [],
"unexpected": true
});
assert!(serde_json::from_value::<SimilarCodeVerdictInput>(value).is_err());
}
#[test]
fn review_preserves_null_judgments() {
let verdict = SimilarCodeVerdict {
candidate_id: "sc_123".to_string(),
review_key: "scr_456".to_string(),
candidate_worthy: None,
behaviorally_equivalent: None,
refactor_safe: None,
outcome: SimilarCodeDomainOutcome::NeedsHumanReview,
rationale: "Insufficient evidence.".to_string(),
};
let value = serde_json::to_value(verdict).expect("verdict should serialize");
assert!(value["candidate_worthy"].is_null());
assert!(value["behaviorally_equivalent"].is_null());
assert!(value["refactor_safe"].is_null());
}
fn generation() -> SimilarCodeGeneration {
SimilarCodeGeneration {
extraction_semantics_version: 1,
embedding_semantics_version: 1,
provider: SimilarCodeProviderProvenance {
provider: SimilarCodeProvider::OfficialLocalCompanion,
companion_version: "3.9.0".to_string(),
protocol_version: 2,
source_left_machine: false,
},
model: SimilarCodeModelProvenance {
model_id: "example/model".to_string(),
revision: "immutable-revision".to_string(),
artifact_sha256: "abc".to_string(),
license: "Apache-2.0".to_string(),
dimensions: 384,
},
parameters: SimilarCodeGenerationParameters {
dtype: "fp32".to_string(),
pooling: "mean".to_string(),
normalized: true,
batch_size: 8,
max_tokens: 1024,
parameter_sha256: "def".to_string(),
},
scope: SimilarCodeScopeProvenance {
active: true,
paths: vec!["src/a.ts".to_string()],
},
threshold: 0.8,
min_lines: 3,
}
}
fn raw_output() -> SimilarCodeOutput {
SimilarCodeOutput {
schema_version: SimilarCodeSchemaVersion::V1,
version: ToolVersion("3.9.0".to_string()),
elapsed_ms: ElapsedMs(4),
generation: generation(),
candidates: Vec::new(),
completion: completion(),
diagnostics: Vec::new(),
}
}
fn completion() -> SimilarCodeCompletion {
SimilarCodeCompletion {
status: SimilarCodeCompletionStatus::Complete,
phases: Vec::new(),
limits: SimilarCodeLimits {
max_files: 10,
max_functions: 100,
max_source_bytes: 1_000_000,
max_function_bytes: 10_000,
max_batch_size: 8,
max_vector_bytes: 1_000_000,
max_comparisons: 1_000,
max_candidates: 10,
max_neighbors_per_function: 3,
timeout_ms: 30_000,
},
skips: Vec::new(),
cache: SimilarCodeCacheSummary {
status: SimilarCodeCacheStatus::Miss,
hits: 0,
misses: 0,
writes: 0,
invalid_entries: 0,
},
provider_inference_ms: 0,
}
}
}