merge: builtin role profiles
This commit is contained in:
commit
7daecca8c5
|
|
@ -1,21 +1 @@
|
|||
default = "project:companion"
|
||||
|
||||
[profile.companion]
|
||||
description = "Companion role profile: GPT-5.5 with bundled default behavior"
|
||||
path = "profiles/companion.lua"
|
||||
|
||||
[profile.intake]
|
||||
description = "Intake role profile: GPT-5.5 with bundled default behavior"
|
||||
path = "profiles/intake.lua"
|
||||
|
||||
[profile.orchestrator]
|
||||
description = "Orchestrator role profile: GPT-5.5 with bundled default behavior"
|
||||
path = "profiles/orchestrator.lua"
|
||||
|
||||
[profile.coder]
|
||||
description = "Coder role profile: GPT-5.5 with bundled default behavior"
|
||||
path = "profiles/coder.lua"
|
||||
|
||||
[profile.reviewer]
|
||||
description = "Reviewer role profile: GPT-5.5 with bundled default behavior"
|
||||
path = "profiles/reviewer.lua"
|
||||
default = "builtin:companion"
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
local profile = require("yoi.profile")
|
||||
local scope = require("yoi.scope")
|
||||
local compact = require("yoi.compact")
|
||||
|
||||
return function(opts)
|
||||
return profile {
|
||||
slug = opts.slug,
|
||||
description = opts.description,
|
||||
|
||||
scope = opts.scope or scope.workspace_read(),
|
||||
delegation_scope = opts.delegation_scope,
|
||||
|
||||
session = {
|
||||
record_event_trace = true,
|
||||
},
|
||||
|
||||
worker = {
|
||||
reasoning = "high",
|
||||
language = opts.language or "Japanese",
|
||||
},
|
||||
|
||||
model = {
|
||||
ref = opts.model_ref,
|
||||
},
|
||||
|
||||
compaction = compact.tokens {
|
||||
threshold = 240000,
|
||||
request_threshold = 270000,
|
||||
worker_context_max_tokens = 100000,
|
||||
},
|
||||
|
||||
feature = opts.feature or {
|
||||
task = { enabled = true },
|
||||
memory = { enabled = true },
|
||||
web = { enabled = true },
|
||||
pods = { enabled = false },
|
||||
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",
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
|
@ -6,17 +6,17 @@ root = ".yoi/tickets"
|
|||
language = "Japanese"
|
||||
|
||||
[roles.intake]
|
||||
profile = "project:intake"
|
||||
profile = "builtin:intake"
|
||||
workflow = "ticket-intake-workflow"
|
||||
|
||||
[roles.orchestrator]
|
||||
profile = "project:orchestrator"
|
||||
profile = "builtin:orchestrator"
|
||||
workflow = "ticket-orchestrator-routing"
|
||||
|
||||
[roles.coder]
|
||||
profile = "project:coder"
|
||||
profile = "builtin:coder"
|
||||
workflow = "multi-agent-workflow"
|
||||
|
||||
[roles.reviewer]
|
||||
profile = "project:reviewer"
|
||||
profile = "builtin:reviewer"
|
||||
workflow = "multi-agent-workflow"
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ profile = "builtin:default"
|
|||
))
|
||||
.unwrap();
|
||||
assert_eq!(intake.role, TicketRole::Intake);
|
||||
assert_eq!(intake.profile, "builtin:default");
|
||||
assert_eq!(intake.profile, TicketRole::Intake.default_profile());
|
||||
assert_eq!(intake.workflow, TicketRole::Intake.default_workflow());
|
||||
|
||||
let orchestrator = plan_ticket_role_launch(TicketRoleLaunchContext::new(
|
||||
|
|
@ -1044,7 +1044,10 @@ profile = "builtin:default"
|
|||
))
|
||||
.unwrap();
|
||||
assert_eq!(orchestrator.role, TicketRole::Orchestrator);
|
||||
assert_eq!(orchestrator.profile, "builtin:default");
|
||||
assert_eq!(
|
||||
orchestrator.profile,
|
||||
TicketRole::Orchestrator.default_profile()
|
||||
);
|
||||
assert_eq!(
|
||||
orchestrator.workflow,
|
||||
TicketRole::Orchestrator.default_workflow()
|
||||
|
|
|
|||
|
|
@ -25,9 +25,61 @@ use crate::{
|
|||
const PROFILE_FORMAT_V1: &str = "yoi.lua-profile.v1";
|
||||
const BUILTIN_DEFAULT_PROFILE_NAME: &str = "default";
|
||||
const BUILTIN_DEFAULT_PROFILE: &str = include_str!("../../../resources/profiles/default.lua");
|
||||
const BUILTIN_COMPANION_PROFILE: &str = include_str!("../../../resources/profiles/companion.lua");
|
||||
const BUILTIN_INTAKE_PROFILE: &str = include_str!("../../../resources/profiles/intake.lua");
|
||||
const BUILTIN_ORCHESTRATOR_PROFILE: &str =
|
||||
include_str!("../../../resources/profiles/orchestrator.lua");
|
||||
const BUILTIN_CODER_PROFILE: &str = include_str!("../../../resources/profiles/coder.lua");
|
||||
const BUILTIN_REVIEWER_PROFILE: &str = include_str!("../../../resources/profiles/reviewer.lua");
|
||||
const BUILTIN_MODEL_CATALOG: &str = include_str!("../../../resources/models/builtin.toml");
|
||||
const WORKSPACE_OVERRIDE_LOCAL_FILENAME: &str = "override.local.toml";
|
||||
|
||||
struct BuiltinProfile {
|
||||
name: &'static str,
|
||||
label: &'static str,
|
||||
content: &'static str,
|
||||
description: &'static str,
|
||||
}
|
||||
|
||||
const BUILTIN_PROFILES: &[BuiltinProfile] = &[
|
||||
BuiltinProfile {
|
||||
name: BUILTIN_DEFAULT_PROFILE_NAME,
|
||||
label: "builtin:default",
|
||||
content: BUILTIN_DEFAULT_PROFILE,
|
||||
description: "Bundled default Yoi coding profile",
|
||||
},
|
||||
BuiltinProfile {
|
||||
name: "companion",
|
||||
label: "builtin:companion",
|
||||
content: BUILTIN_COMPANION_PROFILE,
|
||||
description: "Bundled Companion role profile",
|
||||
},
|
||||
BuiltinProfile {
|
||||
name: "intake",
|
||||
label: "builtin:intake",
|
||||
content: BUILTIN_INTAKE_PROFILE,
|
||||
description: "Bundled Intake role profile",
|
||||
},
|
||||
BuiltinProfile {
|
||||
name: "orchestrator",
|
||||
label: "builtin:orchestrator",
|
||||
content: BUILTIN_ORCHESTRATOR_PROFILE,
|
||||
description: "Bundled Orchestrator role profile",
|
||||
},
|
||||
BuiltinProfile {
|
||||
name: "coder",
|
||||
label: "builtin:coder",
|
||||
content: BUILTIN_CODER_PROFILE,
|
||||
description: "Bundled Coder role profile",
|
||||
},
|
||||
BuiltinProfile {
|
||||
name: "reviewer",
|
||||
label: "builtin:reviewer",
|
||||
content: BUILTIN_REVIEWER_PROFILE,
|
||||
description: "Bundled Reviewer role profile",
|
||||
},
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ProfileRegistrySource {
|
||||
|
|
@ -798,13 +850,15 @@ fn find_project_profiles_from(start: &Path) -> Option<PathBuf> {
|
|||
}
|
||||
|
||||
fn add_builtin_profiles(registry: &mut ProfileRegistry) {
|
||||
for profile in BUILTIN_PROFILES {
|
||||
registry.push_entry(ProfileRegistryEntry::embedded(
|
||||
ProfileRegistrySource::Builtin,
|
||||
BUILTIN_DEFAULT_PROFILE_NAME,
|
||||
"builtin:default",
|
||||
BUILTIN_DEFAULT_PROFILE,
|
||||
Some("Bundled default Yoi coding profile".into()),
|
||||
profile.name,
|
||||
profile.label,
|
||||
profile.content,
|
||||
Some(profile.description.into()),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_profile_ref(raw: &str) -> (Option<ProfileRegistrySource>, String) {
|
||||
|
|
@ -1010,15 +1064,18 @@ fn profile_module(lua: &Lua) -> mlua::Result<Table> {
|
|||
Ok(module)
|
||||
}
|
||||
fn import_profile_artifact(lua: &Lua, reference: &str) -> mlua::Result<LuaValue> {
|
||||
let source = match reference {
|
||||
"builtin:default" | "default" => BUILTIN_DEFAULT_PROFILE,
|
||||
other => {
|
||||
return Err(mlua::Error::RuntimeError(format!(
|
||||
"unsupported profile import `{other}`"
|
||||
)));
|
||||
}
|
||||
};
|
||||
lua.load(source).set_name(reference).eval::<LuaValue>()
|
||||
let profile = builtin_profile_by_ref(reference).ok_or_else(|| {
|
||||
mlua::Error::RuntimeError(format!("unsupported profile import `{reference}`"))
|
||||
})?;
|
||||
lua.load(profile.content)
|
||||
.set_name(profile.label)
|
||||
.eval::<LuaValue>()
|
||||
}
|
||||
fn builtin_profile_by_ref(reference: &str) -> Option<&'static BuiltinProfile> {
|
||||
let name = reference.strip_prefix("builtin:").unwrap_or(reference);
|
||||
BUILTIN_PROFILES
|
||||
.iter()
|
||||
.find(|profile| profile.name == name || profile.label == reference)
|
||||
}
|
||||
fn deep_merge_profile_json(base: &mut serde_json::Value, overrides: serde_json::Value) {
|
||||
match (base, overrides) {
|
||||
|
|
@ -1458,6 +1515,98 @@ mod tests {
|
|||
assert_eq!(default.path, None);
|
||||
assert_eq!(default.provenance, "builtin:default");
|
||||
}
|
||||
#[test]
|
||||
fn builtin_role_profiles_are_registered_and_resolve() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
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_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_pod_name("role-pod"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
resolved.profile.as_ref().unwrap().name.as_deref(),
|
||||
Some(expected)
|
||||
);
|
||||
assert_eq!(resolved.manifest.pod.name, "role-pod");
|
||||
}
|
||||
}
|
||||
|
||||
#[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_pod_name("role-pod"),
|
||||
)
|
||||
.unwrap()
|
||||
.manifest
|
||||
};
|
||||
|
||||
let companion = resolve("companion");
|
||||
assert!(!companion.feature.task.enabled);
|
||||
assert!(!companion.feature.pods.enabled);
|
||||
assert!(!companion.feature.ticket.enabled);
|
||||
assert_eq!(companion.scope.allow[0].permission, Permission::Read);
|
||||
assert!(companion.model.ref_.is_none());
|
||||
assert!(companion.web.is_none());
|
||||
|
||||
let intake = resolve("intake");
|
||||
assert!(!intake.feature.task.enabled);
|
||||
assert!(!intake.feature.pods.enabled);
|
||||
assert!(intake.feature.ticket.enabled);
|
||||
assert_eq!(intake.scope.allow[0].permission, Permission::Read);
|
||||
assert!(intake.model.ref_.is_none());
|
||||
assert!(intake.web.is_none());
|
||||
assert!(!intake.feature.ticket_orchestration.enabled);
|
||||
|
||||
let orchestrator = resolve("orchestrator");
|
||||
assert!(!orchestrator.feature.task.enabled);
|
||||
assert!(orchestrator.feature.pods.enabled);
|
||||
assert!(orchestrator.feature.ticket.enabled);
|
||||
assert!(orchestrator.feature.ticket_orchestration.enabled);
|
||||
assert_eq!(orchestrator.scope.allow[0].permission, Permission::Read);
|
||||
assert!(orchestrator.model.ref_.is_none());
|
||||
assert!(orchestrator.web.is_none());
|
||||
assert_eq!(
|
||||
orchestrator.delegation_scope.allow[0].permission,
|
||||
Permission::Write
|
||||
);
|
||||
|
||||
let coder = resolve("coder");
|
||||
assert!(!coder.feature.task.enabled);
|
||||
assert!(!coder.feature.pods.enabled);
|
||||
assert_eq!(coder.scope.allow[0].permission, Permission::Write);
|
||||
assert!(coder.model.ref_.is_none());
|
||||
assert!(coder.web.is_none());
|
||||
|
||||
let reviewer = resolve("reviewer");
|
||||
assert!(!reviewer.feature.task.enabled);
|
||||
assert!(!reviewer.feature.pods.enabled);
|
||||
assert!(!reviewer.feature.ticket.enabled);
|
||||
assert_eq!(reviewer.scope.allow[0].permission, Permission::Read);
|
||||
assert!(reviewer.model.ref_.is_none());
|
||||
assert!(reviewer.web.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_resolution_requires_runtime_pod_name() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
|
|
@ -1932,112 +2081,6 @@ language = "nested"
|
|||
assert!(matches!(err, ProfileError::UnsupportedProfileType { .. }));
|
||||
assert!(err.to_string().contains("Lua profiles must end in .lua"));
|
||||
}
|
||||
#[test]
|
||||
fn actual_project_role_profiles_resolve_explicit_feature_defaults() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let workspace = tmp.path().join("workspace");
|
||||
let profiles_dir = tmp.path().join(".yoi/profiles");
|
||||
std::fs::create_dir_all(&workspace).unwrap();
|
||||
std::fs::create_dir_all(&profiles_dir).unwrap();
|
||||
for (name, content) in [
|
||||
(
|
||||
"_base.lua",
|
||||
include_str!("../../../.yoi/profiles/_base.lua"),
|
||||
),
|
||||
(
|
||||
"coder.lua",
|
||||
include_str!("../../../.yoi/profiles/coder.lua"),
|
||||
),
|
||||
(
|
||||
"intake.lua",
|
||||
include_str!("../../../.yoi/profiles/intake.lua"),
|
||||
),
|
||||
(
|
||||
"orchestrator.lua",
|
||||
include_str!("../../../.yoi/profiles/orchestrator.lua"),
|
||||
),
|
||||
(
|
||||
"reviewer.lua",
|
||||
include_str!("../../../.yoi/profiles/reviewer.lua"),
|
||||
),
|
||||
(
|
||||
"companion.lua",
|
||||
include_str!("../../../.yoi/profiles/companion.lua"),
|
||||
),
|
||||
] {
|
||||
std::fs::write(profiles_dir.join(name), content).unwrap();
|
||||
}
|
||||
|
||||
struct Expected {
|
||||
role: &'static str,
|
||||
ticket: bool,
|
||||
ticket_orchestration: bool,
|
||||
pods: bool,
|
||||
}
|
||||
|
||||
for expected in [
|
||||
Expected {
|
||||
role: "orchestrator",
|
||||
ticket: true,
|
||||
ticket_orchestration: true,
|
||||
pods: true,
|
||||
},
|
||||
Expected {
|
||||
role: "coder",
|
||||
ticket: false,
|
||||
ticket_orchestration: false,
|
||||
pods: false,
|
||||
},
|
||||
Expected {
|
||||
role: "intake",
|
||||
ticket: true,
|
||||
ticket_orchestration: false,
|
||||
pods: false,
|
||||
},
|
||||
Expected {
|
||||
role: "reviewer",
|
||||
ticket: false,
|
||||
ticket_orchestration: false,
|
||||
pods: false,
|
||||
},
|
||||
Expected {
|
||||
role: "companion",
|
||||
ticket: false,
|
||||
ticket_orchestration: false,
|
||||
pods: false,
|
||||
},
|
||||
] {
|
||||
let resolved = ProfileResolver::new()
|
||||
.with_workspace_base(&workspace)
|
||||
.resolve(
|
||||
&ProfileSelector::path(profiles_dir.join(format!("{}.lua", expected.role))),
|
||||
ProfileResolveOptions::with_pod_name(format!("{}-pod", expected.role)),
|
||||
)
|
||||
.unwrap();
|
||||
let feature = &resolved.manifest.feature;
|
||||
assert!(
|
||||
!feature.task.enabled,
|
||||
"{} profile must explicitly keep Task tools disabled",
|
||||
expected.role
|
||||
);
|
||||
assert_eq!(
|
||||
feature.ticket.enabled, expected.ticket,
|
||||
"{} ticket feature default mismatch",
|
||||
expected.role
|
||||
);
|
||||
assert_eq!(
|
||||
feature.ticket_orchestration.enabled, expected.ticket_orchestration,
|
||||
"{} ticket orchestration feature default mismatch",
|
||||
expected.role
|
||||
);
|
||||
assert_eq!(
|
||||
feature.pods.enabled, expected.pods,
|
||||
"{} Pod feature default mismatch",
|
||||
expected.role
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn discovery_reads_user_and_project_registry_and_project_default_wins() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ use thiserror::Error;
|
|||
pub const TICKET_CONFIG_RELATIVE_PATH: &str = ".yoi/ticket.config.toml";
|
||||
/// Workspace-relative default root for the built-in local Ticket backend.
|
||||
pub const DEFAULT_TICKET_BACKEND_RELATIVE_PATH: &str = ".yoi/tickets";
|
||||
/// Concrete profile selector used by the initial Ticket role scaffold.
|
||||
pub const TICKET_CONFIG_SCAFFOLD_PROFILE: &str = "builtin:default";
|
||||
|
||||
/// Return the explicit workspace Ticket config scaffold written by `yoi ticket init`.
|
||||
///
|
||||
|
|
@ -40,7 +38,7 @@ pub fn ticket_config_scaffold() -> String {
|
|||
for role in TicketRole::ALL {
|
||||
out.push_str(&format!(
|
||||
"\n[roles.{role}]\nprofile = \"{}\"\nworkflow = \"{}\"\n",
|
||||
TICKET_CONFIG_SCAFFOLD_PROFILE,
|
||||
role.default_profile(),
|
||||
role.default_workflow()
|
||||
));
|
||||
}
|
||||
|
|
@ -234,6 +232,15 @@ impl TicketRole {
|
|||
Self::Coder | Self::Reviewer => "multi-agent-workflow",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_profile(self) -> &'static str {
|
||||
match self {
|
||||
Self::Intake => "builtin:intake",
|
||||
Self::Orchestrator => "builtin:orchestrator",
|
||||
Self::Coder => "builtin:coder",
|
||||
Self::Reviewer => "builtin:reviewer",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TicketRole {
|
||||
|
|
@ -340,15 +347,15 @@ impl Default for TicketRoleProfiles {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
||||
pub enum TicketRoleLaunchConfigError {
|
||||
#[error(
|
||||
"Ticket role `{role}` is not launch-configured; add `[roles.{role}]` with `profile = \"builtin:default\"` or another executable concrete profile selector"
|
||||
"Ticket role `{role}` is not launch-configured; add `[roles.{role}]` with the role builtin profile or another executable concrete profile selector"
|
||||
)]
|
||||
MissingRoleTable { role: TicketRole },
|
||||
#[error(
|
||||
"Ticket role `{role}` has no launch profile; set `[roles.{role}].profile` to `builtin:default` or another executable concrete profile selector"
|
||||
"Ticket role `{role}` has no launch profile; set `[roles.{role}].profile` to the role builtin profile or another executable concrete profile selector"
|
||||
)]
|
||||
MissingProfile { role: TicketRole },
|
||||
#[error(
|
||||
"Ticket role `{role}` uses `profile = \"inherit\"`; top-level Ticket role launch requires an explicit executable profile selector such as `builtin:default` or a project/user profile"
|
||||
"Ticket role `{role}` uses `profile = \"inherit\"`; top-level Ticket role launch requires an explicit executable profile selector such as the role builtin profile or a project/user profile"
|
||||
)]
|
||||
InheritProfile { role: TicketRole },
|
||||
}
|
||||
|
|
@ -752,7 +759,8 @@ workflow = "multi-agent-workflow"
|
|||
for role in TicketRole::ALL {
|
||||
assert!(scaffold.contains(&format!("[roles.{role}]")));
|
||||
assert!(scaffold.contains(&format!(
|
||||
"[roles.{role}]\nprofile = \"builtin:default\"\nworkflow = \"{}\"",
|
||||
"[roles.{role}]\nprofile = \"{}\"\nworkflow = \"{}\"",
|
||||
role.default_profile(),
|
||||
role.default_workflow()
|
||||
)));
|
||||
}
|
||||
|
|
@ -767,7 +775,7 @@ workflow = "multi-agent-workflow"
|
|||
assert_eq!(config.backend_root(), temp.path().join(".yoi/tickets"));
|
||||
for role in TicketRole::ALL {
|
||||
let role_config = config.role_launch_config(role).unwrap();
|
||||
assert_eq!(role_config.profile.as_str(), "builtin:default");
|
||||
assert_eq!(role_config.profile.as_str(), role.default_profile());
|
||||
assert_eq!(role_config.workflow.as_str(), role.default_workflow());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
local base = require("_base")
|
||||
local scope = require("yoi.scope")
|
||||
|
||||
return base {
|
||||
return yoi.profile {
|
||||
slug = "coder",
|
||||
description = "Coder role profile: GPT-5.5 with bundled default behavior",
|
||||
model_ref = "codex-oauth/gpt-5.5",
|
||||
description = "Coder role profile with bundled reusable policy",
|
||||
|
||||
scope = yoi.scope.workspace_write(),
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
@ -13,6 +12,4 @@ return base {
|
|||
ticket = { enabled = false, access = "lifecycle" },
|
||||
ticket_orchestration = { enabled = false },
|
||||
},
|
||||
language = "Japanese",
|
||||
scope = scope.workspace_write(),
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
local base = require("_base")
|
||||
|
||||
return base {
|
||||
return yoi.profile {
|
||||
slug = "companion",
|
||||
description = "Companion role profile: GPT-5.5 with bundled default behavior",
|
||||
model_ref = "codex-oauth/gpt-5.5",
|
||||
description = "Companion role profile with bundled reusable policy",
|
||||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
@ -12,5 +12,4 @@ return base {
|
|||
ticket = { enabled = false, access = "lifecycle" },
|
||||
ticket_orchestration = { enabled = false },
|
||||
},
|
||||
language = "Japanese",
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
local base = require("_base")
|
||||
|
||||
return base {
|
||||
return yoi.profile {
|
||||
slug = "intake",
|
||||
description = "Intake role profile: GPT-5.5 with bundled default behavior",
|
||||
model_ref = "codex-oauth/gpt-5.5",
|
||||
description = "Intake role profile with bundled reusable policy",
|
||||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
@ -12,5 +12,4 @@ return base {
|
|||
ticket = { enabled = true, access = "lifecycle" },
|
||||
ticket_orchestration = { enabled = false },
|
||||
},
|
||||
language = "Japanese",
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
local base = require("_base")
|
||||
local scope = require("yoi.scope")
|
||||
|
||||
return base {
|
||||
return yoi.profile {
|
||||
slug = "orchestrator",
|
||||
description = "Orchestrator role profile: GPT-5.5 with bundled default behavior",
|
||||
delegation_scope = scope.workspace_write(),
|
||||
description = "Orchestrator role profile with bundled reusable policy",
|
||||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
@ -13,6 +12,6 @@ return base {
|
|||
ticket = { enabled = true, access = "lifecycle" },
|
||||
ticket_orchestration = { enabled = true },
|
||||
},
|
||||
model_ref = "codex-oauth/gpt-5.5",
|
||||
language = "Japanese",
|
||||
|
||||
delegation_scope = yoi.scope.workspace_write(),
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
local base = require("_base")
|
||||
|
||||
return base {
|
||||
return yoi.profile {
|
||||
slug = "reviewer",
|
||||
description = "Reviewer role profile: GPT-5.5 with bundled default behavior",
|
||||
model_ref = "codex-oauth/gpt-5.5",
|
||||
description = "Reviewer role profile with bundled reusable policy",
|
||||
|
||||
scope = yoi.scope.workspace_read(),
|
||||
|
||||
feature = {
|
||||
task = { enabled = false },
|
||||
memory = { enabled = true },
|
||||
|
|
@ -12,5 +12,4 @@ return base {
|
|||
ticket = { enabled = false, access = "lifecycle" },
|
||||
ticket_orchestration = { enabled = false },
|
||||
},
|
||||
language = "Japanese",
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user