test: remove duplicated resource content assertions
This commit is contained in:
@@ -67,30 +67,4 @@ mod tests {
|
||||
assert_eq!(selected.revision, source.revision);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coder_review_preserves_branch_policy_and_hands_approval_to_orchestrator() {
|
||||
let source =
|
||||
builtin_flow_source(CODER_REVIEW_FLOW_SLUG).expect("coder-review Flow must exist");
|
||||
|
||||
for required in [
|
||||
"detached HEAD",
|
||||
"work/<ticket-id>-<slug>",
|
||||
"explicitly authorized",
|
||||
"git add",
|
||||
"git commit",
|
||||
"Workdir is clean",
|
||||
"current head commit",
|
||||
"same Ticket work branch",
|
||||
"new revision",
|
||||
] {
|
||||
assert!(
|
||||
source.content.contains(required),
|
||||
"coder-review Flow must preserve branch/commit policy token {required:?}"
|
||||
);
|
||||
}
|
||||
assert!(source.content.contains("hand off to the Orchestrator"));
|
||||
assert!(source.content.contains("Do not call MergeRequestComplete"));
|
||||
assert!(!source.content.contains("Call MergeRequestComplete with"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,108 +373,57 @@ mod tests {
|
||||
use super::*;
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
fn builtin_has_four_providers() {
|
||||
let entries = load_builtin_providers().unwrap();
|
||||
let ids: Vec<&str> = entries.iter().map(|e| e.id.as_str()).collect();
|
||||
assert_eq!(
|
||||
ids,
|
||||
vec!["anthropic", "ollama-local", "codex-oauth", "openrouter"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_provider_default_capability_present() {
|
||||
let entries = load_builtin_providers().unwrap();
|
||||
let anthropic = entries.iter().find(|e| e.id == "anthropic").unwrap();
|
||||
assert!(anthropic.default_capability.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_models_cover_each_provider() {
|
||||
let entries = load_builtin_models().unwrap();
|
||||
let providers: std::collections::BTreeSet<&str> =
|
||||
entries.iter().map(|m| m.provider.as_str()).collect();
|
||||
for p in ["anthropic", "ollama-local", "codex-oauth", "openrouter"] {
|
||||
assert!(
|
||||
providers.contains(p),
|
||||
"model catalog should cover provider `{p}`"
|
||||
);
|
||||
}
|
||||
fn test_catalogs() -> (Vec<ProviderEntry>, Vec<ModelEntry>) {
|
||||
(
|
||||
vec![ProviderEntry {
|
||||
id: "test-provider".to_string(),
|
||||
display_name: "Test Provider".to_string(),
|
||||
scheme: SchemeKind::OpenaiChat,
|
||||
base_url: Some("https://example.invalid/v1".to_string()),
|
||||
auth_hint: AuthHint::None,
|
||||
default_capability: None,
|
||||
default_context_window: Some(100_000),
|
||||
}],
|
||||
vec![ModelEntry {
|
||||
id: "test-model".to_string(),
|
||||
provider: "test-provider".to_string(),
|
||||
context_window: Some(100_000),
|
||||
max_context_window: Some(80_000),
|
||||
capability: None,
|
||||
}],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_ref_merges_provider_and_model_catalog() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("anthropic/claude-sonnet-4-6".into()),
|
||||
ref_: Some("test-provider/test-model".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.scheme, SchemeKind::Anthropic);
|
||||
assert_eq!(cfg.model_id, "claude-sonnet-4-6");
|
||||
assert_eq!(cfg.base_url.as_deref(), Some("https://api.anthropic.com"));
|
||||
match cfg.auth {
|
||||
AuthRef::SecretRef { ref_ } => {
|
||||
assert_eq!(ref_, "providers/anthropic/default");
|
||||
}
|
||||
_ => panic!("expected SecretRef auth from provider hint"),
|
||||
}
|
||||
assert!(
|
||||
cfg.capability.is_some(),
|
||||
"model catalog should provide capability"
|
||||
);
|
||||
assert_eq!(cfg.context_window, 1_000_000);
|
||||
assert_eq!(cfg.scheme, SchemeKind::OpenaiChat);
|
||||
assert_eq!(cfg.model_id, "test-model");
|
||||
assert_eq!(cfg.base_url.as_deref(), Some("https://example.invalid/v1"));
|
||||
assert!(matches!(cfg.auth, AuthRef::None));
|
||||
assert_eq!(cfg.context_window, 80_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn context_window_manifest_overrides_catalog() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("anthropic/claude-sonnet-4-6".into()),
|
||||
context_window: Some(123_456),
|
||||
ref_: Some("test-provider/test-model".into()),
|
||||
context_window: Some(70_000),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.context_window, 123_456);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_gpt56_sol_catalog_clamps_public_window_to_backend_limit() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("codex-oauth/gpt-5.6-sol".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.model_id, "gpt-5.6-sol");
|
||||
assert_eq!(cfg.context_window, 272_000);
|
||||
assert_eq!(cfg.max_context_window, Some(272_000));
|
||||
let capability = cfg.capability.expect("catalog capability");
|
||||
assert!(capability.vision);
|
||||
assert!(capability.reasoning.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_gpt55_catalog_records_effective_context_window() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("codex-oauth/gpt-5.5".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.context_window, 272_000);
|
||||
assert_eq!(cfg.max_context_window, None);
|
||||
assert_eq!(cfg.context_window, 70_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_context_window_is_clamped_by_manifest_backend_max() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
scheme: Some(SchemeKind::Anthropic),
|
||||
model_id: Some("custom".into()),
|
||||
@@ -490,25 +439,23 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn manifest_backend_max_clamps_ref_context_override() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("codex-oauth/gpt-5.5".into()),
|
||||
context_window: Some(1_000_000),
|
||||
max_context_window: Some(500_000),
|
||||
ref_: Some("test-provider/test-model".into()),
|
||||
context_window: Some(100_000),
|
||||
max_context_window: Some(50_000),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.context_window, 500_000);
|
||||
assert_eq!(cfg.max_context_window, Some(500_000));
|
||||
assert_eq!(cfg.context_window, 50_000);
|
||||
assert_eq!(cfg.max_context_window, Some(50_000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_ref_with_inline_overrides() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("anthropic/claude-sonnet-4-6".into()),
|
||||
ref_: Some("test-provider/test-model".into()),
|
||||
auth: Some(AuthRef::ApiKey {
|
||||
file: Some(PathBuf::from("/tmp/sk-ant")),
|
||||
}),
|
||||
@@ -525,22 +472,26 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn resolve_ref_with_nested_model_id() {
|
||||
// OpenRouter: `<router>/<provider>/<model>` 形式の model_id を持つ
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, mut models) = test_catalogs();
|
||||
models.push(ModelEntry {
|
||||
id: "namespace/model".to_string(),
|
||||
provider: "test-provider".to_string(),
|
||||
context_window: None,
|
||||
max_context_window: None,
|
||||
capability: None,
|
||||
});
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("openrouter/anthropic/claude-sonnet-4.6".into()),
|
||||
ref_: Some("test-provider/namespace/model".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.scheme, SchemeKind::OpenaiChat);
|
||||
assert_eq!(cfg.model_id, "anthropic/claude-sonnet-4.6");
|
||||
assert_eq!(cfg.model_id, "namespace/model");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_ref_unknown_provider_is_hard_error() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("nope/some-model".into()),
|
||||
..Default::default()
|
||||
@@ -551,21 +502,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn resolve_ref_unknown_model_is_warn_not_error() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("anthropic/some-future-claude".into()),
|
||||
ref_: Some("test-provider/unknown-model".into()),
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
|
||||
assert_eq!(cfg.model_id, "some-future-claude");
|
||||
assert!(cfg.capability.is_some(), "should use provider default");
|
||||
assert_eq!(cfg.model_id, "unknown-model");
|
||||
assert!(cfg.capability.is_none(), "should use provider default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_inline_full_form() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
scheme: Some(SchemeKind::Anthropic),
|
||||
model_id: Some("claude-sonnet-4-6".into()),
|
||||
@@ -583,8 +532,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn resolve_inline_context_window_override() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
scheme: Some(SchemeKind::Anthropic),
|
||||
model_id: Some("claude-sonnet-4-6".into()),
|
||||
@@ -600,8 +548,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn resolve_inline_missing_auth_errors() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
scheme: Some(SchemeKind::Anthropic),
|
||||
model_id: Some("claude".into()),
|
||||
@@ -613,8 +560,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn malformed_ref_errors() {
|
||||
let providers = load_builtin_providers().unwrap();
|
||||
let models = load_builtin_models().unwrap();
|
||||
let (providers, models) = test_catalogs();
|
||||
let manifest = ModelManifest {
|
||||
ref_: Some("noslash".into()),
|
||||
..Default::default()
|
||||
@@ -711,6 +657,6 @@ auth_hint = { kind = "none" }
|
||||
// override ファイルは作らない
|
||||
let _g = ConfigDirGuard::new(dir.path());
|
||||
let entries = load_providers().unwrap();
|
||||
assert_eq!(entries.len(), 4);
|
||||
assert!(!entries.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,179 +1282,23 @@ mod tests {
|
||||
let registry = ProfileDiscovery::with_sources(None, None)
|
||||
.discover()
|
||||
.unwrap();
|
||||
for expected in ["companion", "intake", "orchestrator", "coder", "reviewer"] {
|
||||
let entry = registry
|
||||
.select(&ProfileSelector::source_named(
|
||||
ProfileRegistrySource::Builtin,
|
||||
expected,
|
||||
))
|
||||
.unwrap();
|
||||
assert!(!registry.entries().is_empty());
|
||||
for entry in registry.entries() {
|
||||
assert_eq!(entry.source, ProfileRegistrySource::Builtin);
|
||||
assert_eq!(entry.path, None);
|
||||
assert_eq!(entry.provenance, format!("builtin:{expected}"));
|
||||
|
||||
let resolved = ProfileResolver::new()
|
||||
.with_workspace_base(tmp.path())
|
||||
.resolve(
|
||||
&ProfileSelector::source_named(ProfileRegistrySource::Builtin, expected),
|
||||
ProfileResolveOptions::with_worker_name("role-worker"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resolved.profile.as_ref().unwrap().name.as_deref(),
|
||||
Some(expected)
|
||||
);
|
||||
assert_eq!(resolved.manifest.worker.name, "role-worker");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_memory_consolidation_profile_enables_staging_by_feature() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let resolved = ProfileResolver::new()
|
||||
.with_workspace_base(tmp.path())
|
||||
.resolve(
|
||||
&ProfileSelector::source_named(
|
||||
ProfileRegistrySource::Builtin,
|
||||
"memory-consolidation",
|
||||
entry.name.as_str(),
|
||||
),
|
||||
ProfileResolveOptions::with_worker_name("arbitrary-worker-name"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
resolved.profile.as_ref().unwrap().name.as_deref(),
|
||||
Some("memory-consolidation")
|
||||
);
|
||||
assert_eq!(resolved.manifest.worker.name, "arbitrary-worker-name");
|
||||
assert!(resolved.manifest.feature.memory.enabled);
|
||||
assert!(resolved.manifest.feature.memory.staging);
|
||||
assert!(!resolved.manifest.feature.objective.enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_role_profiles_preserve_role_tool_policy() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let resolve = |role: &str| {
|
||||
ProfileResolver::new()
|
||||
.with_workspace_base(tmp.path())
|
||||
.resolve(
|
||||
&ProfileSelector::source_named(ProfileRegistrySource::Builtin, role),
|
||||
ProfileResolveOptions::with_worker_name("role-worker"),
|
||||
)
|
||||
.unwrap()
|
||||
.manifest
|
||||
};
|
||||
|
||||
let companion = resolve("companion");
|
||||
assert!(companion.feature.task.enabled);
|
||||
assert!(companion.feature.sub_worker.enabled);
|
||||
assert!(companion.feature.worker.enabled);
|
||||
assert!(companion.scope.allow.is_empty());
|
||||
assert!(companion.scope.deny.is_empty());
|
||||
assert!(companion.delegation_scope.allow.is_empty());
|
||||
assert_eq!(companion.model.ref_.as_deref(), Some("codex-oauth/gpt-5.5"));
|
||||
assert!(companion.web.is_some());
|
||||
assert!(companion.feature.ticket.enabled);
|
||||
assert!(companion.feature.ticket.authoring);
|
||||
assert!(companion.feature.ticket.thread);
|
||||
assert!(companion.feature.objective.enabled);
|
||||
assert!(!companion.feature.ticket.intake);
|
||||
assert!(!companion.feature.orchestration.enabled);
|
||||
assert_eq!(
|
||||
companion.compaction.as_ref().unwrap().threshold,
|
||||
Some(240000)
|
||||
);
|
||||
assert_eq!(
|
||||
companion.compaction.as_ref().unwrap().request_threshold,
|
||||
Some(270000)
|
||||
);
|
||||
assert_eq!(
|
||||
companion
|
||||
.compaction
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.worker_context_max_tokens,
|
||||
100000
|
||||
);
|
||||
|
||||
let intake = resolve("intake");
|
||||
assert!(intake.feature.task.enabled);
|
||||
assert!(!intake.feature.sub_worker.enabled);
|
||||
assert!(!intake.feature.worker.enabled);
|
||||
assert!(intake.feature.ticket.enabled);
|
||||
assert!(intake.feature.ticket.enabled);
|
||||
assert!(intake.feature.ticket.authoring);
|
||||
assert!(intake.feature.ticket.thread);
|
||||
assert!(intake.feature.objective.enabled);
|
||||
assert!(!intake.feature.manage_workdir.enabled);
|
||||
assert!(intake.feature.ticket.intake);
|
||||
assert!(!intake.feature.orchestration.enabled);
|
||||
assert!(intake.scope.allow.is_empty());
|
||||
assert!(intake.delegation_scope.allow.is_empty());
|
||||
assert_eq!(intake.model.ref_.as_deref(), Some("codex-oauth/gpt-5.5"));
|
||||
assert!(intake.web.is_some());
|
||||
assert!(intake.compaction.is_some());
|
||||
|
||||
let orchestrator = resolve("orchestrator");
|
||||
assert!(orchestrator.feature.task.enabled);
|
||||
assert!(!orchestrator.feature.sub_worker.enabled);
|
||||
assert!(orchestrator.feature.worker.enabled);
|
||||
assert!(!orchestrator.feature.worker.direct_spawn);
|
||||
assert!(orchestrator.feature.ticket.enabled);
|
||||
assert!(orchestrator.feature.ticket.enabled);
|
||||
assert!(!orchestrator.feature.ticket.authoring);
|
||||
assert!(orchestrator.feature.ticket.thread);
|
||||
assert!(orchestrator.feature.objective.enabled);
|
||||
assert!(orchestrator.feature.manage_workdir.enabled);
|
||||
assert!(!orchestrator.feature.ticket.intake);
|
||||
assert!(orchestrator.feature.ticket.workflow);
|
||||
assert!(orchestrator.feature.orchestration.enabled);
|
||||
assert!(orchestrator.scope.allow.is_empty());
|
||||
assert!(orchestrator.delegation_scope.allow.is_empty());
|
||||
assert_eq!(
|
||||
orchestrator.model.ref_.as_deref(),
|
||||
Some("codex-oauth/gpt-5.5")
|
||||
);
|
||||
assert!(orchestrator.web.is_some());
|
||||
assert!(orchestrator.compaction.is_some());
|
||||
|
||||
let coder = resolve("coder");
|
||||
assert!(coder.feature.task.enabled);
|
||||
assert!(coder.feature.sub_worker.enabled);
|
||||
assert!(coder.feature.flow.enabled);
|
||||
assert!(!coder.feature.worker.enabled);
|
||||
assert!(coder.scope.allow.is_empty());
|
||||
assert!(coder.delegation_scope.allow.is_empty());
|
||||
assert_eq!(coder.model.ref_.as_deref(), Some("codex-oauth/gpt-5.5"));
|
||||
assert!(coder.web.is_some());
|
||||
assert!(coder.compaction.is_some());
|
||||
assert!(coder.feature.ticket.enabled);
|
||||
assert!(coder.feature.ticket.enabled);
|
||||
assert!(!coder.feature.ticket.authoring);
|
||||
assert!(coder.feature.ticket.thread);
|
||||
assert!(coder.feature.objective.enabled);
|
||||
assert!(!coder.feature.manage_workdir.enabled);
|
||||
assert!(!coder.feature.ticket.intake);
|
||||
assert!(!coder.feature.orchestration.enabled);
|
||||
let reviewer = resolve("reviewer");
|
||||
assert!(reviewer.feature.task.enabled);
|
||||
assert!(!reviewer.feature.sub_worker.enabled);
|
||||
assert!(!reviewer.feature.flow.enabled);
|
||||
assert!(!reviewer.feature.worker.enabled);
|
||||
assert!(reviewer.feature.ticket.enabled);
|
||||
assert!(reviewer.feature.ticket.enabled);
|
||||
assert!(!reviewer.feature.ticket.authoring);
|
||||
assert!(reviewer.feature.ticket.thread);
|
||||
assert!(reviewer.feature.objective.enabled);
|
||||
assert!(!reviewer.feature.manage_workdir.enabled);
|
||||
assert!(!reviewer.feature.ticket.intake);
|
||||
assert!(!reviewer.feature.orchestration.enabled);
|
||||
assert!(reviewer.scope.allow.is_empty());
|
||||
assert!(reviewer.delegation_scope.allow.is_empty());
|
||||
assert_eq!(reviewer.model.ref_.as_deref(), Some("codex-oauth/gpt-5.5"));
|
||||
assert!(reviewer.web.is_some());
|
||||
assert!(reviewer.compaction.is_some());
|
||||
.unwrap();
|
||||
assert_eq!(resolved.manifest.worker.name, "role-worker");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1695,40 +1539,6 @@ worker_context_max_tokens = 68000
|
||||
assert!(err.to_string().contains("model.auth.file"));
|
||||
}
|
||||
#[test]
|
||||
fn builtin_companion_resolves_without_external_evaluator() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let resolved = ProfileResolver::new()
|
||||
.with_workspace_base(tmp.path())
|
||||
.resolve(
|
||||
&ProfileSelector::source_named(ProfileRegistrySource::Builtin, "companion"),
|
||||
ProfileResolveOptions::with_worker_name("runtime-workspace"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(resolved.manifest.worker.name, "runtime-workspace");
|
||||
assert_eq!(
|
||||
resolved.manifest.model.ref_.as_deref(),
|
||||
Some("codex-oauth/gpt-5.5")
|
||||
);
|
||||
assert!(resolved.manifest.feature.ticket.enabled);
|
||||
assert!(resolved.manifest.feature.ticket.authoring);
|
||||
assert!(resolved.manifest.feature.ticket.thread);
|
||||
assert!(!resolved.manifest.feature.ticket.intake);
|
||||
assert!(!resolved.manifest.feature.orchestration.enabled);
|
||||
assert_eq!(
|
||||
resolved.profile.as_ref().unwrap().name.as_deref(),
|
||||
Some("companion")
|
||||
);
|
||||
assert_eq!(
|
||||
resolved.source,
|
||||
ProfileSource::Registry {
|
||||
source: ProfileRegistrySource::Builtin,
|
||||
name: "companion".into(),
|
||||
path: None,
|
||||
provenance: Some("builtin:companion".into()),
|
||||
}
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn unsupported_profile_extension_has_clear_diagnostic() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let path = write_profile(tmp.path(), "legacy.txt", "{}");
|
||||
|
||||
@@ -766,21 +766,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_source_names_the_worker_observation_contract() {
|
||||
let catalog = crate::PromptCatalog::builtins_only().unwrap();
|
||||
let source = &catalog.projection().templates["common.worker_observation"];
|
||||
for token in [
|
||||
"WorkerList",
|
||||
"ViewSessionOverview",
|
||||
"SearchSessionEntries",
|
||||
"ReadSessionEntry",
|
||||
"SessionEntryRef",
|
||||
] {
|
||||
assert!(source.contains(token), "missing {token}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_observation_requires_worker_control_service() {
|
||||
let provider = Arc::new(FakeProvider {
|
||||
|
||||
@@ -506,66 +506,9 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn builtin_dcdl_catalog_covers_worker_prompts() {
|
||||
fn builtin_dcdl_catalog_loads() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
for prompt in WorkerPrompt::ALL {
|
||||
assert!(catalog.projection.templates.contains_key(prompt.key()));
|
||||
}
|
||||
assert!(catalog.projection.templates.contains_key("default"));
|
||||
assert!(
|
||||
catalog
|
||||
.projection
|
||||
.templates
|
||||
.contains_key("common.workspace")
|
||||
);
|
||||
assert!(catalog.projection.templates.contains_key("role.coder"));
|
||||
assert!(
|
||||
catalog
|
||||
.projection
|
||||
.templates
|
||||
.contains_key("panel.orchestrator_idle_queue_notice")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_capable_roles_classify_commits_by_change_type() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
assert!(catalog.projection.templates.contains_key("common.git"));
|
||||
let context = Value::from_serialize(serde_json::json!({
|
||||
"cwd": "/workspace",
|
||||
"date": "2026-08-16",
|
||||
"language": "match the user's language",
|
||||
"tool_capabilities": {
|
||||
"memory_any": false,
|
||||
"memory_mutation": false,
|
||||
"memory_query": false,
|
||||
"memory_read_document": false
|
||||
}
|
||||
}));
|
||||
|
||||
for prompt in ["default", "role.coder", "role.orchestrator"] {
|
||||
let rendered = catalog.render_name(prompt, context.clone()).unwrap();
|
||||
assert!(rendered.contains("use the change type as the subject prefix"));
|
||||
assert!(rendered.contains("A change made because review"));
|
||||
assert!(rendered.contains("Do not keep reusing a domain prefix"));
|
||||
assert!(rendered.contains("fix: scope merge request foreign key checks"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_render_resolves_catalog_root_dotted_includes() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
let source = &catalog.projection.templates["default"];
|
||||
assert!(source.contains("{% include \"common.workspace\" %}"));
|
||||
assert!(source.contains("{% include \"common.tool_usage\" %}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schema_is_closed_and_materializes_builtin_defaults() {
|
||||
let source = prompt_schema_source().unwrap();
|
||||
assert!(source.starts_with("{ prompts = {"));
|
||||
assert!(source.contains("compact_system = String default"));
|
||||
assert!(source.contains("role = {"));
|
||||
assert!(!catalog.projection.templates.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -591,7 +534,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn workspace_projection_digest_is_stable_and_verified() {
|
||||
let templates = builtin_prompt_templates().unwrap();
|
||||
let templates = BTreeMap::from([
|
||||
("first".to_string(), "FIRST".to_string()),
|
||||
("second".to_string(), "SECOND".to_string()),
|
||||
]);
|
||||
let projection = EffectivePromptCatalog::new(templates, 42, "schema", "toolchain").unwrap();
|
||||
projection.verify_digest().unwrap();
|
||||
let mut tampered = projection.clone();
|
||||
@@ -606,70 +552,38 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn catalog_source_preserves_workspace_projection_for_subworkers() {
|
||||
let mut templates = builtin_prompt_templates().unwrap();
|
||||
templates.insert("common.workspace".into(), "CHILD OVERRIDE".into());
|
||||
let templates = BTreeMap::from([("template".to_string(), "OVERRIDE".to_string())]);
|
||||
let catalog = PromptCatalog::from_projection(
|
||||
EffectivePromptCatalog::new(templates, 9, "schema", "toolchain").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let child = PromptCatalog::load(&catalog.source()).unwrap();
|
||||
assert_eq!(child.projection.config_revision, 9);
|
||||
assert_eq!(
|
||||
child.projection.templates["common.workspace"],
|
||||
"CHILD OVERRIDE"
|
||||
);
|
||||
assert_eq!(child.projection.templates["template"], "OVERRIDE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn orchestrator_role_keeps_review_routing_owned_by_coder() {
|
||||
fn internal_prompt_helpers_load_and_render_arguments() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
let prompt = &catalog.projection.templates["role.orchestrator"];
|
||||
assert!(prompt.contains("assigned Coder owns its review/fix loop"));
|
||||
assert!(prompt.contains("then use `SpawnTicketCoder`"));
|
||||
assert!(prompt.contains("verify its current assignment names that Coder"));
|
||||
assert!(prompt.contains("never route implementation to an unassigned Coder"));
|
||||
assert!(prompt.contains(
|
||||
"Do not spawn, restore, assign, or route work to Backend/Runtime Reviewer Workers"
|
||||
));
|
||||
assert!(prompt.contains("never compensate by creating an independent Reviewer Worker"));
|
||||
assert!(
|
||||
prompt.contains("current linked Merge Request as implementation-completion authority")
|
||||
);
|
||||
assert!(prompt.contains("do not require an `implementation_report`"));
|
||||
assert!(prompt.contains("only the Orchestrator may call `MergeRequestComplete`"));
|
||||
let coder = &catalog.projection.templates["role.coder"];
|
||||
assert!(coder.contains("hand off to the Orchestrator"));
|
||||
assert!(coder.contains("Do not call `MergeRequestComplete`"));
|
||||
assert!(!prompt.contains("sibling Coder/Reviewer Workers"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn existing_internal_prompt_render_contracts_are_preserved() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
assert!(catalog.compact_system().unwrap().contains("write_summary"));
|
||||
catalog.compact_system().unwrap();
|
||||
assert!(
|
||||
catalog
|
||||
.memory_extract_system("Japanese")
|
||||
.memory_extract_system("LANGUAGE_MARKER")
|
||||
.unwrap()
|
||||
.contains("`language`: `Japanese`")
|
||||
.contains("LANGUAGE_MARKER")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.notify_wrapper("changed")
|
||||
.notify_wrapper("NOTIFICATION_MARKER")
|
||||
.unwrap()
|
||||
.contains("changed")
|
||||
.contains("NOTIFICATION_MARKER")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.working_boundaries_section("Readable: /a")
|
||||
.working_boundaries_section("BOUNDARY_MARKER")
|
||||
.unwrap()
|
||||
.contains("Readable: /a")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.worker_orchestration_guidance_section()
|
||||
.unwrap()
|
||||
.contains("## SubWorker orchestration")
|
||||
.contains("BOUNDARY_MARKER")
|
||||
);
|
||||
catalog.worker_orchestration_guidance_section().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
#[cfg(test)]
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::{DateTime, SecondsFormat, Utc};
|
||||
@@ -26,8 +24,6 @@ use thiserror::Error;
|
||||
|
||||
use crate::feature::{FeatureInstructionDeclaration, dedupe_instruction_contributions};
|
||||
use crate::prompt::catalog::{CatalogError, PromptCatalog};
|
||||
#[cfg(test)]
|
||||
use crate::prompt::catalog::{EffectivePromptCatalog, builtin_prompt_templates};
|
||||
use crate::prompt::source::PromptCatalogSource;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@@ -319,76 +315,6 @@ fn append_trailing_section(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::TimeZone;
|
||||
use manifest::{Permission, ScopeConfig, ScopeRule};
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn fixed_now() -> DateTime<Utc> {
|
||||
Utc.with_ymd_and_hms(2026, 4, 15, 9, 30, 0).unwrap()
|
||||
}
|
||||
|
||||
fn build_scope(dir: &Path) -> Scope {
|
||||
Scope::from_config(&ScopeConfig {
|
||||
allow: vec![ScopeRule {
|
||||
target: dir.to_path_buf(),
|
||||
permission: Permission::Write,
|
||||
recursive: true,
|
||||
}],
|
||||
deny: Vec::new(),
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn context<'a>(
|
||||
cwd: &'a Path,
|
||||
scope: &'a Scope,
|
||||
prompts: &'a PromptCatalog,
|
||||
) -> SystemPromptContext<'a> {
|
||||
SystemPromptContext {
|
||||
now: fixed_now(),
|
||||
cwd: cwd.to_string_lossy(),
|
||||
tool_names: vec!["Read".into(), "Write".into()],
|
||||
scope,
|
||||
agents_md: Some("PROJECT RULES".into()),
|
||||
resident_summary: Some("DURABLE MEMORY"),
|
||||
language: "Japanese",
|
||||
feature_instructions: &[],
|
||||
prompts,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exact_catalog_name_renders_once_with_trailing_sections() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let scope = build_scope(tmp.path());
|
||||
let prompts = PromptCatalog::builtins_only().unwrap();
|
||||
let template =
|
||||
SystemPromptTemplate::parse("default", PromptCatalogSource::builtins_only()).unwrap();
|
||||
let rendered = template
|
||||
.render(&context(tmp.path(), &scope, &prompts))
|
||||
.unwrap();
|
||||
assert!(rendered.contains("2026-08-14") || rendered.contains("2026-04-15"));
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
assert!(rendered.contains("PROJECT RULES"));
|
||||
assert!(rendered.contains("DURABLE MEMORY"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_override_is_visible_through_builtin_static_include() {
|
||||
let mut templates = builtin_prompt_templates().unwrap();
|
||||
templates.insert("common.workspace".into(), "WORKSPACE OVERRIDE".into());
|
||||
let projection = EffectivePromptCatalog::new(templates, 9, "schema", "toolchain").unwrap();
|
||||
let loader =
|
||||
PromptCatalogSource::builtins_only().with_effective_catalog(projection.clone());
|
||||
let prompts = PromptCatalog::from_projection(projection).unwrap();
|
||||
let template = SystemPromptTemplate::parse("default", loader).unwrap();
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let scope = build_scope(tmp.path());
|
||||
let rendered = template
|
||||
.render(&context(tmp.path(), &scope, &prompts))
|
||||
.unwrap();
|
||||
assert!(rendered.contains("WORKSPACE OVERRIDE"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_legacy_prefix_relative_and_missing_names() {
|
||||
@@ -399,20 +325,4 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn role_templates_are_selected_without_filesystem_resolution() {
|
||||
let loader = PromptCatalogSource::builtins_only();
|
||||
for role in [
|
||||
"role.coder",
|
||||
"role.intake",
|
||||
"role.orchestrator",
|
||||
"role.reviewer",
|
||||
] {
|
||||
assert!(
|
||||
SystemPromptTemplate::parse(role, loader.clone()).is_ok(),
|
||||
"{role}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6955,7 +6955,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(rendered.contains("## Resident memory summary"));
|
||||
assert!(rendered.contains("summary body for resident prompt"));
|
||||
assert!(!rendered.contains("updated_at: 2026-01-01T00:00:00Z"));
|
||||
assert!(!rendered.contains("---\nupdated_at"));
|
||||
@@ -6974,7 +6973,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.contains("disabled summary body"));
|
||||
}
|
||||
|
||||
@@ -6987,7 +6985,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.contains("memory-disabled summary body"));
|
||||
}
|
||||
|
||||
@@ -7000,8 +6997,7 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.trim().is_empty());
|
||||
assert!(!rendered.contains("bad summary body"));
|
||||
}
|
||||
|
||||
@@ -7015,7 +7011,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!prompt.contains("Resident memory summary"));
|
||||
assert!(!prompt.contains("resident summary marker"));
|
||||
}
|
||||
|
||||
|
||||
@@ -176,10 +176,7 @@ async fn template_is_not_materialised_before_first_run() {
|
||||
#[tokio::test]
|
||||
async fn materialise_on_first_turn_populates_worker() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, pwd) = make_worker_with_body(
|
||||
"date={{ date }} cwd={{ cwd }} tools={{ tools | join(',') }}",
|
||||
client,
|
||||
)
|
||||
let (mut worker, pwd) = make_worker_with_body("date={{ date }}", client)
|
||||
.await
|
||||
.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
@@ -189,19 +186,14 @@ async fn materialise_on_first_turn_populates_worker() {
|
||||
.expect("system prompt materialised")
|
||||
.to_string();
|
||||
assert!(rendered.contains("date="));
|
||||
assert!(rendered.contains("cwd="));
|
||||
assert!(rendered.contains(&pwd.display().to_string()));
|
||||
assert!(rendered.starts_with("date="));
|
||||
// Trailing fixed section must be appended.
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_start_state_captures_rendered_prompt() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, pwd) = make_worker_with_body("hello cwd={{ cwd }}", client)
|
||||
.await
|
||||
.unwrap();
|
||||
let (mut worker, pwd) = make_worker_with_body("hello", client).await.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
|
||||
let entries = worker
|
||||
@@ -212,9 +204,8 @@ async fn session_start_state_captures_rendered_prompt() {
|
||||
match first {
|
||||
LogEntry::SegmentStart { system_prompt, .. } => {
|
||||
let sp = system_prompt.as_deref().expect("system prompt set");
|
||||
assert!(sp.starts_with("hello cwd="));
|
||||
assert!(sp.starts_with("hello"));
|
||||
assert!(sp.contains(&pwd.display().to_string()));
|
||||
assert!(sp.contains("## Working boundaries"));
|
||||
}
|
||||
other => panic!("expected SegmentStart as first entry, got {other:?}"),
|
||||
}
|
||||
@@ -253,21 +244,10 @@ async fn agents_md_is_injected_as_trailing_section_when_present() {
|
||||
worker.run_text("hi").await.unwrap();
|
||||
let rendered = worker.engine().get_system_prompt().unwrap().to_string();
|
||||
assert!(rendered.starts_with("BODY"));
|
||||
assert!(rendered.contains("## Project instructions (AGENTS.md)"));
|
||||
assert!(rendered.contains("# project rules"));
|
||||
assert!(rendered.contains("be kind"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn agents_md_absent_omits_trailing_section() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, _pwd) = make_worker_with_body("BODY", client).await.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
let rendered = worker.engine().get_system_prompt().unwrap().to_string();
|
||||
assert!(!rendered.contains("## Project instructions"));
|
||||
assert!(!rendered.contains("AGENTS.md"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn agents_md_not_reread_after_compact() {
|
||||
let client = MockClient::new(vec![
|
||||
|
||||
@@ -4217,13 +4217,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_orchestrator_profile_enables_workdir_and_worker_authority() {
|
||||
fn embedded_builtin_decodal_profiles_resolve_through_archive() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let broker = BackendResourceBroker::default();
|
||||
let runtime_id = "runtime-test";
|
||||
let selector = ProfileSelector::Builtin("builtin:orchestrator".to_string());
|
||||
let bundle = builtin_profile_config_bundle(
|
||||
&selector,
|
||||
&ProfileSelector::Builtin("builtin:companion".to_string()),
|
||||
"workspace-test",
|
||||
Some(runtime_id),
|
||||
&broker,
|
||||
@@ -4231,6 +4230,7 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
let handle = bundle.profile_source_archive_handle.as_ref().unwrap();
|
||||
assert!(bundle.profile_source_archive.is_none());
|
||||
let response = broker
|
||||
.fetch_profile_source_archive(worker_runtime::resource::BackendResourceFetchRequest {
|
||||
handle: handle.clone(),
|
||||
@@ -4244,85 +4244,12 @@ mod tests {
|
||||
.unwrap()
|
||||
.verify()
|
||||
.unwrap();
|
||||
assert!(!archive.reference().source_graph.entrypoints.is_empty());
|
||||
for selector_key in archive.reference().source_graph.entrypoints.keys() {
|
||||
let manifest = archive
|
||||
.resolve_profile("builtin:orchestrator", root.path(), "embedded-orchestrator")
|
||||
.unwrap();
|
||||
|
||||
assert!(manifest.feature.manage_workdir.enabled);
|
||||
assert!(!manifest.feature.sub_worker.enabled);
|
||||
assert!(manifest.feature.worker.enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_companion_profile_enables_worker_management() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let selector = ProfileSelector::Builtin("builtin:companion".to_string());
|
||||
let archive = builtin_profile_source_archive(&selector)
|
||||
.unwrap()
|
||||
.verify()
|
||||
.unwrap();
|
||||
let manifest = archive
|
||||
.resolve_profile("builtin:companion", root.path(), "companion-test-worker")
|
||||
.unwrap();
|
||||
|
||||
assert!(manifest.feature.worker.enabled);
|
||||
assert!(manifest.feature.sub_worker.enabled);
|
||||
assert!(!manifest.feature.manage_workdir.enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_builtin_decodal_profiles_resolve_through_archive() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let broker = BackendResourceBroker::default();
|
||||
let runtime_id = "runtime-test";
|
||||
for selector in [
|
||||
ProfileSelector::Builtin("builtin:companion".to_string()),
|
||||
ProfileSelector::Builtin("builtin:intake".to_string()),
|
||||
ProfileSelector::Builtin("builtin:orchestrator".to_string()),
|
||||
ProfileSelector::Builtin("builtin:coder".to_string()),
|
||||
ProfileSelector::Builtin("builtin:reviewer".to_string()),
|
||||
ProfileSelector::Builtin("builtin:memory-consolidation".to_string()),
|
||||
] {
|
||||
let bundle = builtin_profile_config_bundle(
|
||||
&selector,
|
||||
"workspace-test",
|
||||
Some(runtime_id),
|
||||
&broker,
|
||||
ProfileSourceArchiveTransport::BackendResourceHandle,
|
||||
)
|
||||
.unwrap();
|
||||
let handle = bundle.profile_source_archive_handle.as_ref().unwrap();
|
||||
assert!(bundle.profile_source_archive.is_none());
|
||||
let response = broker
|
||||
.fetch_profile_source_archive(
|
||||
worker_runtime::resource::BackendResourceFetchRequest {
|
||||
handle: handle.clone(),
|
||||
runtime_id: runtime_id.to_string(),
|
||||
worker_id: None,
|
||||
audit_correlation_id: handle.audit_correlation_id.clone(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let archive =
|
||||
worker_runtime::resource::profile_source_archive_from_response(handle, response)
|
||||
.unwrap()
|
||||
.verify()
|
||||
.unwrap();
|
||||
let selector_key = match &selector {
|
||||
ProfileSelector::Builtin(name) | ProfileSelector::Named(name) => name.clone(),
|
||||
};
|
||||
let manifest = archive
|
||||
.resolve_profile(&selector_key, root.path(), "embedded-test-worker")
|
||||
.resolve_profile(selector_key, root.path(), "embedded-test-worker")
|
||||
.unwrap();
|
||||
assert_eq!(manifest.worker.name, "embedded-test-worker");
|
||||
assert_eq!(
|
||||
manifest.model.ref_.as_deref(),
|
||||
Some("codex-oauth/gpt-5.6-sol")
|
||||
);
|
||||
if selector_key == "builtin:memory-consolidation" {
|
||||
assert!(manifest.feature.memory.enabled);
|
||||
assert!(manifest.feature.memory.staging);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -740,32 +740,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_config_projection_is_builtin_only_by_default() {
|
||||
let state = virtual_state(vec![
|
||||
config_source::ConfigEntry::new(
|
||||
VirtualPath::parse("main.dcdl").unwrap(),
|
||||
ConfigContentType::Decodal,
|
||||
"{}",
|
||||
)
|
||||
.unwrap(),
|
||||
]);
|
||||
let projection = project_profiles_from_workspace_config("workspace-test", &state).unwrap();
|
||||
assert_eq!(
|
||||
projection.settings.default_profile.as_deref(),
|
||||
Some("builtin:companion")
|
||||
);
|
||||
assert_eq!(projection.settings.config_revision, Some(7));
|
||||
assert!(projection.settings.projection_digest.is_some());
|
||||
assert!(
|
||||
projection
|
||||
.settings
|
||||
.profiles
|
||||
.iter()
|
||||
.all(|item| !item.editable)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_config_projection_builds_archive_from_active_revision() {
|
||||
let state = virtual_state(vec![
|
||||
@@ -795,8 +769,7 @@ mod tests {
|
||||
assert_eq!(projection.settings.config_revision, Some(7));
|
||||
let prompt_catalog = bundle.prompt_catalog.as_ref().unwrap();
|
||||
assert_eq!(prompt_catalog.config_revision, 7);
|
||||
assert!(prompt_catalog.templates.contains_key("default"));
|
||||
assert!(prompt_catalog.templates.contains_key("common.workspace"));
|
||||
assert!(!prompt_catalog.templates.is_empty());
|
||||
assert!(
|
||||
bundle
|
||||
.metadata
|
||||
|
||||
@@ -115,12 +115,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn workspace_override_deep_patches_builtin_and_preserves_other_leaves() {
|
||||
let baseline = project_prompts_from_workspace_config(&state("{}")).unwrap();
|
||||
let state = state(r#"{ prompts = { common = { language = "OVERRIDE"; }; }; }"#);
|
||||
let catalog = project_prompts_from_workspace_config(&state).unwrap();
|
||||
assert_eq!(catalog.config_revision, 7);
|
||||
assert_eq!(catalog.templates["common.language"], "OVERRIDE");
|
||||
assert!(!catalog.templates["common.workspace"].is_empty());
|
||||
assert!(catalog.templates["default"].contains("common.workspace"));
|
||||
for (key, value) in baseline.templates {
|
||||
if key != "common.language" {
|
||||
assert_eq!(catalog.templates.get(&key), Some(&value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user