profile: remove lua profile resolver
This commit is contained in:
parent
156f8ad044
commit
254360f1ab
102
Cargo.lock
generated
102
Cargo.lock
generated
|
|
@ -1060,17 +1060,6 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "erased-serde"
|
|
||||||
version = "0.4.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"serde_core",
|
|
||||||
"typeid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
|
|
@ -2206,25 +2195,6 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lua-src"
|
|
||||||
version = "550.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e836dc8ae16806c9bdcf42003a88da27d163433e3f9684c52f0301258004a4fb"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "luajit-src"
|
|
||||||
version = "210.6.6+707c12b"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a86cc925d4053d0526ae7f5bc765dbd0d7a5d1a63d43974f4966cb349ca63295"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"which",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mac"
|
name = "mac"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -2256,7 +2226,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"llm-engine",
|
"llm-engine",
|
||||||
"mlua",
|
|
||||||
"protocol",
|
"protocol",
|
||||||
"secrets",
|
"secrets",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -2444,39 +2413,6 @@ dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mlua"
|
|
||||||
version = "0.11.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ccd36acfa49ce6ee56d1307a061dd302c564eee757e6e4cd67eb4f7204846fab"
|
|
||||||
dependencies = [
|
|
||||||
"bstr",
|
|
||||||
"either",
|
|
||||||
"erased-serde",
|
|
||||||
"libc",
|
|
||||||
"mlua-sys",
|
|
||||||
"num-traits",
|
|
||||||
"parking_lot",
|
|
||||||
"rustc-hash",
|
|
||||||
"rustversion",
|
|
||||||
"serde",
|
|
||||||
"serde-value",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mlua-sys"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0f1c3a7fc7580227ece249fd90aa2fa3b39eb2b49d3aec5e103b3e85f2c3dfc8"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"lua-src",
|
|
||||||
"luajit-src",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
|
|
@ -2671,15 +2607,6 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ordered-float"
|
|
||||||
version = "2.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
version = "4.6.0"
|
version = "4.6.0"
|
||||||
|
|
@ -3683,16 +3610,6 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde-value"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
|
||||||
dependencies = [
|
|
||||||
"ordered-float 2.10.1",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_core"
|
name = "serde_core"
|
||||||
version = "1.0.228"
|
version = "1.0.228"
|
||||||
|
|
@ -4228,7 +4145,7 @@ dependencies = [
|
||||||
"nix",
|
"nix",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"ordered-float 4.6.0",
|
"ordered-float",
|
||||||
"pest",
|
"pest",
|
||||||
"pest_derive",
|
"pest_derive",
|
||||||
"phf 0.11.3",
|
"phf 0.11.3",
|
||||||
|
|
@ -4744,12 +4661,6 @@ dependencies = [
|
||||||
"pom",
|
"pom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typeid"
|
|
||||||
version = "1.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.19.0"
|
version = "1.19.0"
|
||||||
|
|
@ -5428,7 +5339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
|
checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ordered-float 4.6.0",
|
"ordered-float",
|
||||||
"strsim",
|
"strsim",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
"wezterm-dynamic-derive",
|
"wezterm-dynamic-derive",
|
||||||
|
|
@ -5458,15 +5369,6 @@ dependencies = [
|
||||||
"wezterm-dynamic",
|
"wezterm-dynamic",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "which"
|
|
||||||
version = "8.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "81995fafaaaf6ae47a7d0cc83c67caf92aeb7e5331650ae6ff856f7c0c60c459"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
||||||
|
|
@ -1227,7 +1227,7 @@ workflow = "ticket-review-workflow"
|
||||||
temp.path(),
|
temp.path(),
|
||||||
r#"
|
r#"
|
||||||
[roles.coder]
|
[roles.coder]
|
||||||
profile = "./coder.lua"
|
profile = "./coder.toml"
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let context = TicketRoleLaunchContext::new(temp.path(), TicketRole::Coder);
|
let context = TicketRoleLaunchContext::new(temp.path(), TicketRole::Coder);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ license.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arc-swap = "1"
|
arc-swap = "1"
|
||||||
llm-engine = { workspace = true }
|
llm-engine = { workspace = true }
|
||||||
mlua = { version = "0.11.4", features = ["lua54", "vendored", "serialize"] }
|
|
||||||
protocol = { workspace = true }
|
protocol = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -1193,9 +1193,9 @@ model_id = "claude-sonnet-4-20250514"
|
||||||
let toml = MINIMAL_REQUIRED.replace(
|
let toml = MINIMAL_REQUIRED.replace(
|
||||||
"[engine]\n",
|
"[engine]\n",
|
||||||
"[engine]\n\
|
"[engine]\n\
|
||||||
[worker.tool_output]\n\
|
[engine.tool_output]\n\
|
||||||
default_max_bytes = 8192\n\n\
|
default_max_bytes = 8192\n\n\
|
||||||
[worker.tool_output.per_tool]\n\
|
[engine.tool_output.per_tool]\n\
|
||||||
Read = 32768\n\
|
Read = 32768\n\
|
||||||
Grep = 4096\n\n\
|
Grep = 4096\n\n\
|
||||||
[engine.file_upload]\n\
|
[engine.file_upload]\n\
|
||||||
|
|
@ -1215,7 +1215,7 @@ model_id = "claude-sonnet-4-20250514"
|
||||||
let toml = MINIMAL_REQUIRED.replace(
|
let toml = MINIMAL_REQUIRED.replace(
|
||||||
"[engine]\n",
|
"[engine]\n",
|
||||||
"[engine]\n\
|
"[engine]\n\
|
||||||
[worker.tool_output]\n",
|
[engine.tool_output]\n",
|
||||||
);
|
);
|
||||||
let manifest = WorkerManifest::from_toml(&toml).unwrap();
|
let manifest = WorkerManifest::from_toml(&toml).unwrap();
|
||||||
let limits = &manifest.engine.tool_output;
|
let limits = &manifest.engine.tool_output;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -497,7 +497,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
metadata.resolved_manifest_snapshot = Some(serde_json::json!({
|
metadata.resolved_manifest_snapshot = Some(serde_json::json!({
|
||||||
"worker": { "name": "profile-worker" },
|
"worker": { "name": "profile-worker" },
|
||||||
"profile": { "source": { "kind": "path", "path": "/profiles/coder.lua" } }
|
"profile": { "source": { "kind": "path", "path": "/profiles/coder.toml" } }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let json = serde_json::to_string(&metadata).unwrap();
|
let json = serde_json::to_string(&metadata).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -526,7 +526,9 @@ impl ProfileSelectorRef {
|
||||||
if value.starts_with("path:")
|
if value.starts_with("path:")
|
||||||
|| value.starts_with('.')
|
|| value.starts_with('.')
|
||||||
|| value.contains('/')
|
|| value.contains('/')
|
||||||
|| value.ends_with(".lua")
|
|| value.ends_with(".dcdl")
|
||||||
|
|| value.ends_with(".json")
|
||||||
|
|| value.ends_with(".toml")
|
||||||
|| value.ends_with(".nix")
|
|| value.ends_with(".nix")
|
||||||
{
|
{
|
||||||
return Err("profile selector must be `inherit`, `default`, a source-qualified registry selector, or an unqualified registry selector; path selectors are not supported".to_string());
|
return Err("profile selector must be `inherit`, `default`, a source-qualified registry selector, or an unqualified registry selector; path selectors are not supported".to_string());
|
||||||
|
|
@ -1347,7 +1349,7 @@ profile = "legacy.nix"
|
||||||
temp.path(),
|
temp.path(),
|
||||||
r#"
|
r#"
|
||||||
[roles.coder]
|
[roles.coder]
|
||||||
profile = "./coder.lua"
|
profile = "./coder.toml"
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
//! let fs = ScopedFs::new(scope, PathBuf::from("/workspace")); // worker lifetime
|
//! let fs = ScopedFs::new(scope, PathBuf::from("/workspace")); // worker lifetime
|
||||||
//! let tracker = Tracker::new(); // session lifetime
|
//! let tracker = Tracker::new(); // session lifetime
|
||||||
//! let bash_outputs = PathBuf::from("/run/yoi/bash-output");
|
//! let bash_outputs = PathBuf::from("/run/yoi/bash-output");
|
||||||
//! let defs = core_builtin_tools(fs, tracker, bash_outputs, None);
|
//! let defs = core_builtin_tools(fs, tracker, bash_outputs);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use toml::Value;
|
||||||
use toml::map::Map;
|
use toml::map::Map;
|
||||||
|
|
||||||
const GENERATED_PROFILE_NAME: &str = "default";
|
const GENERATED_PROFILE_NAME: &str = "default";
|
||||||
const GENERATED_PROFILE_PATH: &str = "profiles/default.lua";
|
const GENERATED_PROFILE_PATH: &str = "profiles/default.toml";
|
||||||
const GENERATED_PROFILE_DESCRIPTION: &str = "Generated by yoi setup-model";
|
const GENERATED_PROFILE_DESCRIPTION: &str = "Generated by yoi setup-model";
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
@ -149,7 +149,7 @@ pub fn write_default_profile_config(
|
||||||
std::fs::create_dir_all(&profiles_dir)?;
|
std::fs::create_dir_all(&profiles_dir)?;
|
||||||
|
|
||||||
let profile_path = config_dir.join(GENERATED_PROFILE_PATH);
|
let profile_path = config_dir.join(GENERATED_PROFILE_PATH);
|
||||||
std::fs::write(&profile_path, generated_profile_lua(model_ref))?;
|
std::fs::write(&profile_path, generated_profile_toml(model_ref))?;
|
||||||
|
|
||||||
let registry_path = config_dir.join("profiles.toml");
|
let registry_path = config_dir.join("profiles.toml");
|
||||||
let mut document = read_registry_document(®istry_path)?;
|
let mut document = read_registry_document(®istry_path)?;
|
||||||
|
|
@ -203,65 +203,63 @@ fn set_default_profile_entry(document: &mut Value) -> Result<(), Box<dyn std::er
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generated_profile_lua(model_ref: &str) -> String {
|
fn generated_profile_toml(model_ref: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
r#"local profile = require("yoi.profile")
|
r#"slug = "default"
|
||||||
local scope = require("yoi.scope")
|
description = "Generated by yoi setup-model"
|
||||||
local compact = require("yoi.compact")
|
scope = "workspace_write"
|
||||||
|
|
||||||
return profile {{
|
[model]
|
||||||
slug = "default",
|
ref = "{}"
|
||||||
description = "Generated by yoi setup-model",
|
|
||||||
|
|
||||||
scope = scope.workspace_write(),
|
[session]
|
||||||
|
record_event_trace = true
|
||||||
|
|
||||||
session = {{
|
[engine]
|
||||||
record_event_trace = true,
|
reasoning = "high"
|
||||||
}},
|
|
||||||
|
|
||||||
worker = {{
|
[compaction]
|
||||||
reasoning = "high",
|
kind = "tokens"
|
||||||
}},
|
threshold = 240000
|
||||||
|
request_threshold = 270000
|
||||||
|
worker_context_max_tokens = 100000
|
||||||
|
|
||||||
model = {{
|
[feature.task]
|
||||||
ref = "{}",
|
enabled = true
|
||||||
}},
|
|
||||||
|
|
||||||
compaction = compact.tokens {{
|
[feature.memory]
|
||||||
threshold = 240000,
|
enabled = true
|
||||||
request_threshold = 270000,
|
|
||||||
worker_context_max_tokens = 100000,
|
|
||||||
}},
|
|
||||||
|
|
||||||
feature = {{
|
[feature.web]
|
||||||
task = {{ enabled = true }},
|
enabled = true
|
||||||
memory = {{ enabled = true }},
|
|
||||||
web = {{ enabled = true }},
|
|
||||||
workers = {{ enabled = false }},
|
|
||||||
ticket = {{ enabled = false, access = "lifecycle" }},
|
|
||||||
ticket_orchestration = {{ enabled = false }},
|
|
||||||
}},
|
|
||||||
|
|
||||||
memory = {{
|
[feature.workers]
|
||||||
extract_threshold = 50000,
|
enabled = false
|
||||||
consolidation_threshold_files = 5,
|
|
||||||
consolidation_threshold_bytes = 50000,
|
|
||||||
}},
|
|
||||||
|
|
||||||
web = {{
|
[feature.ticket]
|
||||||
enabled = true,
|
enabled = false
|
||||||
search = {{
|
access = "lifecycle"
|
||||||
provider = "brave",
|
|
||||||
api_key_secret = "web/brave/default",
|
[feature.ticket_orchestration]
|
||||||
}},
|
enabled = false
|
||||||
}},
|
|
||||||
}}
|
[memory]
|
||||||
|
extract_threshold = 50000
|
||||||
|
consolidation_threshold_files = 5
|
||||||
|
consolidation_threshold_bytes = 50000
|
||||||
|
|
||||||
|
[web]
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[web.search]
|
||||||
|
provider = "brave"
|
||||||
|
api_key_secret = "web/brave/default"
|
||||||
"#,
|
"#,
|
||||||
escape_lua_string(model_ref)
|
escape_toml_string(model_ref)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn escape_lua_string(value: &str) -> String {
|
fn escape_toml_string(value: &str) -> String {
|
||||||
value
|
value
|
||||||
.chars()
|
.chars()
|
||||||
.flat_map(|c| match c {
|
.flat_map(|c| match c {
|
||||||
|
|
@ -288,18 +286,18 @@ mod tests {
|
||||||
assert_eq!(written.registry_path, dir.path().join("profiles.toml"));
|
assert_eq!(written.registry_path, dir.path().join("profiles.toml"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
written.profile_path,
|
written.profile_path,
|
||||||
dir.path().join("profiles/default.lua")
|
dir.path().join("profiles/default.toml")
|
||||||
);
|
);
|
||||||
|
|
||||||
let registry = std::fs::read_to_string(&written.registry_path).unwrap();
|
let registry = std::fs::read_to_string(&written.registry_path).unwrap();
|
||||||
assert!(registry.contains("default = \"user:default\""));
|
assert!(registry.contains("default = \"user:default\""));
|
||||||
assert!(registry.contains("[profile.default]"));
|
assert!(registry.contains("[profile.default]"));
|
||||||
assert!(registry.contains("path = \"profiles/default.lua\""));
|
assert!(registry.contains("path = \"profiles/default.toml\""));
|
||||||
|
|
||||||
let profile = std::fs::read_to_string(&written.profile_path).unwrap();
|
let profile = std::fs::read_to_string(&written.profile_path).unwrap();
|
||||||
assert!(profile.contains("slug = \"default\""));
|
assert!(profile.contains("slug = \"default\""));
|
||||||
assert!(profile.contains("ref = \"codex-oauth/gpt-5.5\""));
|
assert!(profile.contains("ref = \"codex-oauth/gpt-5.5\""));
|
||||||
assert!(profile.contains("scope = scope.workspace_write()"));
|
assert!(profile.contains("scope = \"workspace_write\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -308,7 +306,7 @@ mod tests {
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
dir.path().join("profiles.toml"),
|
dir.path().join("profiles.toml"),
|
||||||
r#"[profile.other]
|
r#"[profile.other]
|
||||||
path = "profiles/other.lua"
|
path = "profiles/other.toml"
|
||||||
description = "keep me"
|
description = "keep me"
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
|
@ -318,13 +316,13 @@ description = "keep me"
|
||||||
|
|
||||||
let registry = std::fs::read_to_string(dir.path().join("profiles.toml")).unwrap();
|
let registry = std::fs::read_to_string(dir.path().join("profiles.toml")).unwrap();
|
||||||
assert!(registry.contains("[profile.other]"));
|
assert!(registry.contains("[profile.other]"));
|
||||||
assert!(registry.contains("path = \"profiles/other.lua\""));
|
assert!(registry.contains("path = \"profiles/other.toml\""));
|
||||||
assert!(registry.contains("[profile.default]"));
|
assert!(registry.contains("[profile.default]"));
|
||||||
assert!(registry.contains("default = \"user:default\""));
|
assert!(registry.contains("default = \"user:default\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn escape_lua_string_escapes_quotes_and_slashes() {
|
fn escape_toml_string_escapes_quotes_and_slashes() {
|
||||||
assert_eq!(escape_lua_string("a\\b\"c"), "a\\\\b\\\"c");
|
assert_eq!(escape_toml_string("a\\b\"c"), "a\\\\b\\\"c");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -664,7 +664,7 @@ mod tests {
|
||||||
r#"
|
r#"
|
||||||
default = "coder"
|
default = "coder"
|
||||||
[profile]
|
[profile]
|
||||||
coder = "profiles/coder.lua"
|
coder = "profiles/coder.toml"
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -692,7 +692,7 @@ coder = "profiles/coder.lua"
|
||||||
r#"
|
r#"
|
||||||
default = "coder"
|
default = "coder"
|
||||||
[profile.coder]
|
[profile.coder]
|
||||||
path = "profiles/coder.lua"
|
path = "profiles/coder.toml"
|
||||||
description = "Project coder"
|
description = "Project coder"
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -845,15 +845,15 @@ recursive = true
|
||||||
external.display()
|
external.display()
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let profile = tmp.path().join("profile.lua");
|
let profile = tmp.path().join("profile.toml");
|
||||||
write(
|
write(
|
||||||
&profile,
|
&profile,
|
||||||
r#"
|
r#"
|
||||||
local yoi = require("yoi")
|
slug = "override-scope"
|
||||||
return yoi.profile {
|
|
||||||
slug = "override-scope",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "test-model" },
|
scheme = "anthropic"
|
||||||
}
|
model_id = "test-model"
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let cli = Cli::try_parse_from([
|
let cli = Cli::try_parse_from([
|
||||||
|
|
@ -889,7 +889,7 @@ return yoi.profile {
|
||||||
#[test]
|
#[test]
|
||||||
fn profile_uses_selected_profile() {
|
fn profile_uses_selected_profile() {
|
||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let profile = tmp.path().join("profile.lua");
|
let profile = tmp.path().join("profile.toml");
|
||||||
let cli = Cli::try_parse_from([
|
let cli = Cli::try_parse_from([
|
||||||
"yoi worker",
|
"yoi worker",
|
||||||
"--profile",
|
"--profile",
|
||||||
|
|
@ -1223,8 +1223,14 @@ permission = "write"
|
||||||
fn profile_conflicts_with_manifest_and_restore_modes() {
|
fn profile_conflicts_with_manifest_and_restore_modes() {
|
||||||
let segment_id = session_store::new_segment_id().to_string();
|
let segment_id = session_store::new_segment_id().to_string();
|
||||||
for args in [
|
for args in [
|
||||||
vec!["yoi worker", "--profile", "p.lua", "--manifest", "m.toml"],
|
vec!["yoi worker", "--profile", "p.toml", "--manifest", "m.toml"],
|
||||||
vec!["yoi worker", "--profile", "p.lua", "--session", &segment_id],
|
vec![
|
||||||
|
"yoi worker",
|
||||||
|
"--profile",
|
||||||
|
"p.toml",
|
||||||
|
"--session",
|
||||||
|
&segment_id,
|
||||||
|
],
|
||||||
] {
|
] {
|
||||||
let err = Cli::try_parse_from(args).unwrap_err();
|
let err = Cli::try_parse_from(args).unwrap_err();
|
||||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||||
|
|
@ -1233,9 +1239,9 @@ permission = "write"
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn profile_and_worker_are_independent_startup_inputs() {
|
fn profile_and_worker_are_independent_startup_inputs() {
|
||||||
let cli =
|
let cli = Cli::try_parse_from(["yoi worker", "--profile", "p.toml", "--worker", "agent"])
|
||||||
Cli::try_parse_from(["yoi worker", "--profile", "p.lua", "--worker", "agent"]).unwrap();
|
.unwrap();
|
||||||
assert_eq!(cli.profile.as_deref(), Some("p.lua"));
|
assert_eq!(cli.profile.as_deref(), Some("p.toml"));
|
||||||
assert_eq!(cli.worker.as_deref(), Some("agent"));
|
assert_eq!(cli.worker.as_deref(), Some("agent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ impl ProtocolProviderContribution {
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum FeatureRuntimeKind {
|
pub enum FeatureRuntimeKind {
|
||||||
Builtin,
|
Builtin,
|
||||||
LuaProfile,
|
Profile,
|
||||||
ExternalPlugin,
|
ExternalPlugin,
|
||||||
ProtocolProvider,
|
ProtocolProvider,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,9 @@ fn parse_spawn_profile_selector(raw: Option<&str>) -> Result<SpawnProfileSelecto
|
||||||
|| raw.starts_with("./")
|
|| raw.starts_with("./")
|
||||||
|| raw.starts_with("../")
|
|| raw.starts_with("../")
|
||||||
|| raw.contains('/')
|
|| raw.contains('/')
|
||||||
|| raw.ends_with(".lua")
|
|| raw.ends_with(".dcdl")
|
||||||
|
|| raw.ends_with(".json")
|
||||||
|
|| raw.ends_with(".toml")
|
||||||
|| raw.ends_with(".nix")
|
|| raw.ends_with(".nix")
|
||||||
{
|
{
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
|
@ -1181,25 +1183,31 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CODER_PROFILE: &str = r#"
|
const CODER_PROFILE: &str = r#"
|
||||||
local profile = require("yoi.profile")
|
slug = "coder"
|
||||||
local scope = require("yoi.scope")
|
scope = "workspace_write"
|
||||||
return profile {
|
|
||||||
slug = "coder",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "coder-model" },
|
scheme = "anthropic"
|
||||||
engine = { instruction = "$yoi/coder", language = "Coderish", max_tokens = 2222 },
|
model_id = "coder-model"
|
||||||
scope = scope.workspace_write(),
|
|
||||||
}
|
[engine]
|
||||||
|
instruction = "$yoi/coder"
|
||||||
|
language = "Coderish"
|
||||||
|
max_tokens = 2222
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
const REVIEWER_PROFILE: &str = r#"
|
const REVIEWER_PROFILE: &str = r#"
|
||||||
local profile = require("yoi.profile")
|
slug = "reviewer"
|
||||||
local scope = require("yoi.scope")
|
scope = "workspace_write"
|
||||||
return profile {
|
|
||||||
slug = "reviewer",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "reviewer-model" },
|
scheme = "anthropic"
|
||||||
engine = { instruction = "$yoi/reviewer", language = "Reviewerish", max_tokens = 3333 },
|
model_id = "reviewer-model"
|
||||||
scope = scope.workspace_write(),
|
|
||||||
}
|
[engine]
|
||||||
|
instruction = "$yoi/reviewer"
|
||||||
|
language = "Reviewerish"
|
||||||
|
max_tokens = 3333
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1297,8 +1305,8 @@ return profile {
|
||||||
&project,
|
&project,
|
||||||
Some("reviewer"),
|
Some("reviewer"),
|
||||||
&[
|
&[
|
||||||
("coder", "coder.lua", CODER_PROFILE),
|
("coder", "coder.toml", CODER_PROFILE),
|
||||||
("reviewer", "reviewer.lua", REVIEWER_PROFILE),
|
("reviewer", "reviewer.toml", REVIEWER_PROFILE),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let parent = parent_manifest(&project, None);
|
let parent = parent_manifest(&project, None);
|
||||||
|
|
@ -1333,8 +1341,8 @@ return profile {
|
||||||
&project,
|
&project,
|
||||||
Some("coder"),
|
Some("coder"),
|
||||||
&[
|
&[
|
||||||
("coder", "coder.lua", CODER_PROFILE),
|
("coder", "coder.toml", CODER_PROFILE),
|
||||||
("reviewer", "reviewer.lua", REVIEWER_PROFILE),
|
("reviewer", "reviewer.toml", REVIEWER_PROFILE),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
let parent = parent_manifest(&project, None);
|
let parent = parent_manifest(&project, None);
|
||||||
|
|
@ -1414,7 +1422,7 @@ return profile {
|
||||||
let available = write_project_profile_registry(
|
let available = write_project_profile_registry(
|
||||||
&project,
|
&project,
|
||||||
Some("reviewer"),
|
Some("reviewer"),
|
||||||
&[("reviewer", "reviewer.lua", REVIEWER_PROFILE)],
|
&[("reviewer", "reviewer.toml", REVIEWER_PROFILE)],
|
||||||
);
|
);
|
||||||
let parent = parent_manifest(&project, None);
|
let parent = parent_manifest(&project, None);
|
||||||
let scope = vec![abs_rule(&delegated, Permission::Write)];
|
let scope = vec![abs_rule(&delegated, Permission::Write)];
|
||||||
|
|
@ -1451,7 +1459,7 @@ return profile {
|
||||||
let available = write_project_profile_registry(
|
let available = write_project_profile_registry(
|
||||||
&project,
|
&project,
|
||||||
Some("reviewer"),
|
Some("reviewer"),
|
||||||
&[("reviewer", "reviewer.lua", REVIEWER_PROFILE)],
|
&[("reviewer", "reviewer.toml", REVIEWER_PROFILE)],
|
||||||
);
|
);
|
||||||
let parent = parent_manifest(&parent_root, Some(&parent_root.join("deny")));
|
let parent = parent_manifest(&parent_root, Some(&parent_root.join("deny")));
|
||||||
let scope = vec![abs_rule(&delegated, Permission::Read)];
|
let scope = vec![abs_rule(&delegated, Permission::Read)];
|
||||||
|
|
@ -1497,12 +1505,12 @@ return profile {
|
||||||
let available = write_project_profile_registry(
|
let available = write_project_profile_registry(
|
||||||
&project,
|
&project,
|
||||||
None,
|
None,
|
||||||
&[("coder", "coder.lua", CODER_PROFILE)],
|
&[("coder", "coder.toml", CODER_PROFILE)],
|
||||||
);
|
);
|
||||||
let parent = parent_manifest(&project, None);
|
let parent = parent_manifest(&project, None);
|
||||||
let scope = vec![abs_rule(&project, Permission::Read)];
|
let scope = vec![abs_rule(&project, Permission::Read)];
|
||||||
|
|
||||||
let invalid = parse_spawn_profile_selector(Some("./reviewer.lua"))
|
let invalid = parse_spawn_profile_selector(Some("./reviewer.toml"))
|
||||||
.map_err(|msg| format!("{msg}{}", available.error_suffix()))
|
.map_err(|msg| format!("{msg}{}", available.error_suffix()))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert!(invalid.contains("Use `default`, `inherit`"));
|
assert!(invalid.contains("Use `default`, `inherit`"));
|
||||||
|
|
@ -1521,7 +1529,7 @@ return profile {
|
||||||
assert!(default_config.contains("\"name\":\"child\""));
|
assert!(default_config.contains("\"name\":\"child\""));
|
||||||
|
|
||||||
let user_config = tmp.path().join("user-profiles.toml");
|
let user_config = tmp.path().join("user-profiles.toml");
|
||||||
std::fs::write(&user_config, "[profile]\ncoder = \"user-coder.lua\"\n").unwrap();
|
std::fs::write(&user_config, "[profile]\ncoder = \"user-coder.toml\"\n").unwrap();
|
||||||
let project_config = project.join(".yoi/profiles.toml");
|
let project_config = project.join(".yoi/profiles.toml");
|
||||||
let ambiguous = AvailableProfiles {
|
let ambiguous = AvailableProfiles {
|
||||||
registry: Some(
|
registry: Some(
|
||||||
|
|
@ -1550,9 +1558,9 @@ return profile {
|
||||||
#[test]
|
#[test]
|
||||||
fn spawn_profile_selector_rejects_path_like_values() {
|
fn spawn_profile_selector_rejects_path_like_values() {
|
||||||
for raw in [
|
for raw in [
|
||||||
"./reviewer.lua",
|
"./reviewer.toml",
|
||||||
"path:./reviewer.lua",
|
"path:./reviewer.toml",
|
||||||
"/tmp/reviewer.lua",
|
"/tmp/reviewer.toml",
|
||||||
"legacy.nix",
|
"legacy.nix",
|
||||||
] {
|
] {
|
||||||
let err = parse_spawn_profile_selector(Some(raw)).unwrap_err();
|
let err = parse_spawn_profile_selector(Some(raw)).unwrap_err();
|
||||||
|
|
|
||||||
|
|
@ -1528,7 +1528,7 @@ mod tests {
|
||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"--profile".to_string(),
|
"--profile".to_string(),
|
||||||
"p.lua".to_string(),
|
"p.toml".to_string(),
|
||||||
"--session".to_string(),
|
"--session".to_string(),
|
||||||
segment_id,
|
segment_id,
|
||||||
],
|
],
|
||||||
|
|
@ -1537,7 +1537,7 @@ mod tests {
|
||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"--profile".to_string(),
|
"--profile".to_string(),
|
||||||
"p.lua".to_string(),
|
"p.toml".to_string(),
|
||||||
"--socket".to_string(),
|
"--socket".to_string(),
|
||||||
"/tmp/yoi/sock".to_string(),
|
"/tmp/yoi/sock".to_string(),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1076,34 +1076,37 @@ mod tests {
|
||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let workspace = tmp.path().join("workspace");
|
let workspace = tmp.path().join("workspace");
|
||||||
std::fs::create_dir(&workspace).unwrap();
|
std::fs::create_dir(&workspace).unwrap();
|
||||||
let profile = write_profile(tmp.path(), "mcp.lua", body);
|
let profile = write_profile(tmp.path(), "mcp.toml", body);
|
||||||
(tmp, workspace, profile)
|
(tmp, workspace, profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mcp_profile() -> String {
|
fn mcp_profile() -> String {
|
||||||
r#"
|
r#"
|
||||||
local profile = require("yoi.profile")
|
slug = "mcp-test"
|
||||||
return profile {
|
|
||||||
slug = "mcp-test",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "claude-sonnet-4-20250514" },
|
scheme = "anthropic"
|
||||||
mcp = {
|
model_id = "claude-sonnet-4-20250514"
|
||||||
stdio_server = {
|
|
||||||
{
|
[[mcp.stdio_server]]
|
||||||
name = "filesystem",
|
name = "filesystem"
|
||||||
command = "definitely-not-spawned-during-cli-inspection",
|
command = "definitely-not-spawned-during-cli-inspection"
|
||||||
args = { "--root", ".", "--token", "ARG_SECRET_DO_NOT_PRINT" },
|
args = ["--root", ".", "--token", "ARG_SECRET_DO_NOT_PRINT"]
|
||||||
env = {
|
|
||||||
inherit = { "PATH" },
|
[mcp.stdio_server.env]
|
||||||
set = {
|
inherit = ["PATH"]
|
||||||
SAFE_MODE = { kind = "literal", value = "SUPER_SECRET_LITERAL_DO_NOT_PRINT" },
|
|
||||||
API_TOKEN = { kind = "secret_ref", ref = "providers/mcp-token" },
|
[mcp.stdio_server.env.set.SAFE_MODE]
|
||||||
FROM_ENV = { kind = "env_ref", name = "SECRET_ENV_NAME_DO_NOT_PRINT" },
|
kind = "literal"
|
||||||
},
|
value = "SUPER_SECRET_LITERAL_DO_NOT_PRINT"
|
||||||
},
|
|
||||||
},
|
[mcp.stdio_server.env.set.API_TOKEN]
|
||||||
},
|
kind = "secret_ref"
|
||||||
},
|
ref = "providers/mcp-token"
|
||||||
}
|
|
||||||
|
[mcp.stdio_server.env.set.FROM_ENV]
|
||||||
|
kind = "env_ref"
|
||||||
|
name = "SECRET_ENV_NAME_DO_NOT_PRINT"
|
||||||
"#
|
"#
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
@ -1194,17 +1197,19 @@ return profile {
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_config_is_reported_as_invalid_not_silently_empty() {
|
fn invalid_config_is_reported_as_invalid_not_silently_empty() {
|
||||||
let body = r#"
|
let body = r#"
|
||||||
local profile = require("yoi.profile")
|
slug = "bad-mcp"
|
||||||
return profile {
|
|
||||||
slug = "bad-mcp",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "claude-sonnet-4-20250514" },
|
scheme = "anthropic"
|
||||||
mcp = {
|
model_id = "claude-sonnet-4-20250514"
|
||||||
stdio_server = {
|
|
||||||
{ name = "dup", command = "one" },
|
[[mcp.stdio_server]]
|
||||||
{ name = "dup", command = "two" },
|
name = "dup"
|
||||||
},
|
command = "one"
|
||||||
},
|
|
||||||
}
|
[[mcp.stdio_server]]
|
||||||
|
name = "dup"
|
||||||
|
command = "two"
|
||||||
"#;
|
"#;
|
||||||
let (_tmp, workspace, profile) = workspace_and_profile(body);
|
let (_tmp, workspace, profile) = workspace_and_profile(body);
|
||||||
let output = render_list(&args(&workspace, &profile, true)).unwrap();
|
let output = render_list(&args(&workspace, &profile, true)).unwrap();
|
||||||
|
|
@ -1218,11 +1223,11 @@ return profile {
|
||||||
#[test]
|
#[test]
|
||||||
fn human_output_distinguishes_empty_and_unavailable() {
|
fn human_output_distinguishes_empty_and_unavailable() {
|
||||||
let body = r#"
|
let body = r#"
|
||||||
local profile = require("yoi.profile")
|
slug = "empty-mcp"
|
||||||
return profile {
|
|
||||||
slug = "empty-mcp",
|
[model]
|
||||||
model = { scheme = "anthropic", model_id = "claude-sonnet-4-20250514" },
|
scheme = "anthropic"
|
||||||
}
|
model_id = "claude-sonnet-4-20250514"
|
||||||
"#;
|
"#;
|
||||||
let (_tmp, workspace, profile) = workspace_and_profile(body);
|
let (_tmp, workspace, profile) = workspace_and_profile(body);
|
||||||
let output = render_list(&args(&workspace, &profile, false)).unwrap();
|
let output = render_list(&args(&workspace, &profile, false)).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ A Profile should not contain runtime-bound fields:
|
||||||
|
|
||||||
Those fields depend on one run, one parent, or one machine. Putting them in a reusable Profile makes reuse unsafe.
|
Those fields depend on one run, one parent, or one machine. Putting them in a reusable Profile makes reuse unsafe.
|
||||||
|
|
||||||
Yoi is Lua Profile first. Lua gives project/user authors a controlled recipe layer through host-provided `require("yoi")` modules without treating Nix as runtime authoring. Nix remains useful for packaging and development records.
|
Yoi Profiles are data artifacts resolved from builtin profile definitions, `profiles.toml`, Decodal source archives, or explicit JSON/TOML artifacts. Decodal is the authoring syntax used by the Workspace profile editor and Backend Runtime archive path; JSON/TOML artifacts are the low-level resolver interchange format. Runtime launch should not depend on executable profile scripts.
|
||||||
|
|
||||||
## Manifests
|
## Manifests
|
||||||
|
|
||||||
|
|
@ -33,27 +33,32 @@ For normal Profile/default startup, a workspace may add `.yoi/override.local.tom
|
||||||
|
|
||||||
Profiles and manifest layers may declare named local stdio MCP servers under `mcp.stdio_server`. This is a typed configuration surface only. Declaring a server does not start a subprocess, discover packages, negotiate MCP capabilities, or register tools/resources/prompts.
|
Profiles and manifest layers may declare named local stdio MCP servers under `mcp.stdio_server`. This is a typed configuration surface only. Declaring a server does not start a subprocess, discover packages, negotiate MCP capabilities, or register tools/resources/prompts.
|
||||||
|
|
||||||
Example Lua Profile fragment:
|
Example TOML artifact fragment:
|
||||||
|
|
||||||
```lua
|
```toml
|
||||||
mcp = {
|
[[mcp.stdio_server]]
|
||||||
stdio_server = {
|
name = "filesystem"
|
||||||
{
|
command = "node"
|
||||||
name = "filesystem",
|
args = ["server.js", "--root", "."]
|
||||||
command = "node",
|
|
||||||
args = { "server.js", "--root", "." },
|
[mcp.stdio_server.cwd]
|
||||||
cwd = { kind = "path", path = "./mcp" },
|
kind = "path"
|
||||||
env = {
|
path = "./mcp"
|
||||||
inherit = { "PATH" },
|
|
||||||
set = {
|
[mcp.stdio_server.env]
|
||||||
SAFE_MODE = { kind = "literal", value = "1" },
|
inherit = ["PATH"]
|
||||||
API_TOKEN = { kind = "secret_ref", ref = "providers/mcp-token" },
|
|
||||||
UPSTREAM_TOKEN = { kind = "env_ref", name = "MCP_UPSTREAM_TOKEN" },
|
[mcp.stdio_server.env.set.SAFE_MODE]
|
||||||
},
|
kind = "literal"
|
||||||
},
|
value = "1"
|
||||||
},
|
|
||||||
},
|
[mcp.stdio_server.env.set.API_TOKEN]
|
||||||
}
|
kind = "secret_ref"
|
||||||
|
ref = "providers/mcp-token"
|
||||||
|
|
||||||
|
[mcp.stdio_server.env.set.UPSTREAM_TOKEN]
|
||||||
|
kind = "env_ref"
|
||||||
|
name = "MCP_UPSTREAM_TOKEN"
|
||||||
```
|
```
|
||||||
|
|
||||||
`command` is a direct executable name/path, not a shell string. `args` are passed as argv entries by future lifecycle code. `cwd.kind = "path"` is resolved relative to the Profile or manifest layer; omit `cwd` or use `{ kind = "inherit" }` when the lifecycle caller should choose. Environment handling is explicit: future spawn code should inherit only names listed in `env.inherit` and set only variables in `env.set`. `literal` values are for non-secret data; credentials should use `secret_ref` or explicit `env_ref`. Diagnostics and Debug output must redact env literal values and must not print secret plaintext.
|
`command` is a direct executable name/path, not a shell string. `args` are passed as argv entries by future lifecycle code. `cwd.kind = "path"` is resolved relative to the Profile or manifest layer; omit `cwd` or use `{ kind = "inherit" }` when the lifecycle caller should choose. Environment handling is explicit: future spawn code should inherit only names listed in `env.inherit` and set only variables in `env.set`. `literal` values are for non-secret data; credentials should use `secret_ref` or explicit `env_ref`. Diagnostics and Debug output must redact env literal values and must not print secret plaintext.
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@
|
||||||
- canonicalization/relative-path normalization;
|
- canonicalization/relative-path normalization;
|
||||||
- delegation subset checks;
|
- delegation subset checks;
|
||||||
- shared-scope add/remove/clear operations。
|
- shared-scope add/remove/clear operations。
|
||||||
- `profile.rs` は、Lua profile behavior について特に広いカバレッジを持つ:
|
- `profile.rs` は、profile artifact behavior について特に広いカバレッジを持つ:
|
||||||
- 意図された `yoi.profile` API 経由の profile registration;
|
- typed profile artifact registration;
|
||||||
- legacy/global APIs の明示的な rejection;
|
- manifest-shaped/runtime authority fields の明示的な rejection;
|
||||||
- builtin role profile defaults と tool-policy boundaries;
|
- builtin role profile defaults と tool-policy boundaries;
|
||||||
- workspace/profile override precedence;
|
- workspace/profile override precedence;
|
||||||
- `extend`、helper APIs、TOML loading、model catalog access、Lua module loading;
|
- TOML/JSON artifact loading、model catalog access;
|
||||||
- multiple-profile discovery、selector handling、ambiguity、exact/unique match behavior。
|
- multiple-profile discovery、selector handling、ambiguity、exact/unique match behavior。
|
||||||
- `paths.rs` のテストは、pure resolver functions によって XDG/Yoi directory precedence rules をカバーしており、global environment races を避けている。
|
- `paths.rs` のテストは、pure resolver functions によって XDG/Yoi directory precedence rules をカバーしており、global environment races を避けている。
|
||||||
- いくつかのテストは、単なる実装機構ではなく、重要な product decisions を regression checks として符号化している。manifest/profile semantics は durable contract なので、この crate ではそれが適切である。
|
- いくつかのテストは、単なる実装機構ではなく、重要な product decisions を regression checks として符号化している。manifest/profile semantics は durable contract なので、この crate ではそれが適切である。
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
filter = sourceFilter;
|
filter = sourceFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoHash = "sha256-Pk6pRrtQlMAw2Shl+nQyX81FHQsHlKYAsxtg0M4Ya8Y=";
|
cargoHash = "sha256-vM2ea6W3hqnmzqOXfzQo+ZYrQBoy2Kh69vz1fkU+DIs=";
|
||||||
|
|
||||||
depsExtraArgs = {
|
depsExtraArgs = {
|
||||||
# Older fetchCargoVendor utilities used crates.io's API download endpoint,
|
# Older fetchCargoVendor utilities used crates.io's API download endpoint,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
local p = yoi.profile.import("builtin:default")
|
|
||||||
|
|
||||||
p.slug = "coder"
|
|
||||||
p.description = "Coder role profile with bundled reusable policy"
|
|
||||||
p.worker.instruction = "$yoi/role/coder"
|
|
||||||
p.feature = {
|
|
||||||
task = { enabled = true },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = false },
|
|
||||||
ticket = { enabled = false, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = false },
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
local p = yoi.profile.import("builtin:default")
|
|
||||||
|
|
||||||
p.slug = "companion"
|
|
||||||
p.description = "Companion role profile with bundled reusable policy"
|
|
||||||
p.feature = {
|
|
||||||
task = { enabled = true },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = true },
|
|
||||||
ticket = { enabled = true, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = false },
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
return yoi.profile {
|
|
||||||
slug = "default",
|
|
||||||
description = "Default Yoi coding profile",
|
|
||||||
|
|
||||||
|
|
||||||
session = {
|
|
||||||
record_event_trace = true,
|
|
||||||
},
|
|
||||||
|
|
||||||
engine = {
|
|
||||||
reasoning = "high",
|
|
||||||
},
|
|
||||||
|
|
||||||
model = yoi.models.catalog("codex-oauth/gpt-5.5"),
|
|
||||||
|
|
||||||
compaction = yoi.compact.tokens {
|
|
||||||
threshold = 240000,
|
|
||||||
request_threshold = 270000,
|
|
||||||
worker_context_max_tokens = 100000,
|
|
||||||
},
|
|
||||||
|
|
||||||
feature = {
|
|
||||||
task = { enabled = true },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = true },
|
|
||||||
ticket = { enabled = false, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = false },
|
|
||||||
},
|
|
||||||
|
|
||||||
memory = {
|
|
||||||
extract_threshold = 50000,
|
|
||||||
consolidation_threshold_files = 5,
|
|
||||||
consolidation_threshold_bytes = 50000,
|
|
||||||
},
|
|
||||||
|
|
||||||
web = {
|
|
||||||
enabled = true,
|
|
||||||
search = {
|
|
||||||
provider = "brave",
|
|
||||||
api_key_secret = "web/brave/default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
local p = yoi.profile.import("builtin:default")
|
|
||||||
|
|
||||||
p.slug = "intake"
|
|
||||||
p.description = "Intake role profile with bundled reusable policy"
|
|
||||||
p.worker.instruction = "$yoi/role/intake"
|
|
||||||
p.feature = {
|
|
||||||
task = { enabled = false },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = false },
|
|
||||||
ticket = { enabled = true, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = false },
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
local p = yoi.profile.import("builtin:default")
|
|
||||||
|
|
||||||
p.slug = "orchestrator"
|
|
||||||
p.description = "Orchestrator role profile with bundled reusable policy"
|
|
||||||
p.worker.instruction = "$yoi/role/orchestrator"
|
|
||||||
p.feature = {
|
|
||||||
task = { enabled = false },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = true },
|
|
||||||
ticket = { enabled = true, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = true },
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
local p = yoi.profile.import("builtin:default")
|
|
||||||
|
|
||||||
p.slug = "reviewer"
|
|
||||||
p.description = "Reviewer role profile with bundled reusable policy"
|
|
||||||
p.worker.instruction = "$yoi/role/reviewer"
|
|
||||||
p.feature = {
|
|
||||||
task = { enabled = false },
|
|
||||||
memory = { enabled = true },
|
|
||||||
web = { enabled = true },
|
|
||||||
workers = { enabled = false },
|
|
||||||
ticket = { enabled = false, access = "lifecycle" },
|
|
||||||
ticket_orchestration = { enabled = false },
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
Loading…
Reference in New Issue
Block a user