@event4u/agent-config 9.27.0 → 9.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +13 -12
- package/CHANGELOG.md +165 -0
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +55 -24
- package/dist/agent-src/commands/analyze/conformance.md +24 -0
- package/dist/agent-src/commands/cost/report.md +2 -2
- package/dist/agent-src/commands/team/adversarial.md +8 -7
- package/dist/agent-src/commands/team/delegate.md +13 -12
- package/dist/agent-src/commands/team/review.md +9 -8
- package/dist/agent-src/commands/team/status.md +9 -8
- package/dist/agent-src/commands/team.md +29 -19
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +88 -2
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +29 -21
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +26 -15
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +28 -3
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +54 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +13 -11
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +25 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -3
- package/dist/agent-src/rules/artifact-engagement-recording.md +4 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +33 -6
- package/dist/agent-src/rules/context-hygiene.md +3 -1
- package/dist/agent-src/rules/council-availability.md +93 -0
- package/dist/agent-src/rules/cross-source-consistency.md +3 -0
- package/dist/agent-src/rules/delegation-policy.md +38 -10
- package/dist/agent-src/rules/design-fidelity.md +3 -0
- package/dist/agent-src/rules/evaluator-independence.md +2 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +2 -1
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +1 -1
- package/dist/agent-src/rules/history-discipline.md +3 -1
- package/dist/agent-src/rules/legal-safety-floor.md +1 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +3 -1
- package/dist/agent-src/rules/onboarding-gate.md +3 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +4 -1
- package/dist/agent-src/rules/role-mode-adherence.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +3 -1
- package/dist/agent-src/rules/self-repair-loop.md +103 -0
- package/dist/agent-src/rules/session-canary.md +2 -1
- package/dist/agent-src/rules/settings-ask-protocol.md +8 -7
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/token-budget-discipline.md +4 -2
- package/dist/agent-src/rules/tool-safety.md +5 -1
- package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/forensics-report/SKILL.md +114 -0
- package/dist/agent-src/skills/forensics-report/evals/triggers.json +17 -0
- package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
- package/dist/agent-src/skills/premortem/SKILL.md +30 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -1
- package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +7 -5
- package/dist/agent-src/skills/subagent-orchestration/schemas/subagent-status.json +61 -3
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/templates/AGENTS.md +8 -12
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +23 -0
- package/dist/cli/registry.js +7 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-66OVWGB5.js +270 -0
- package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-LCFJIQ4J.js} +89 -7
- package/dist/cli-delegate/{chunk-VSYT7OHO.js → chunk-LVRYBKTI.js} +31 -2
- package/dist/cli-delegate/{chunk-DVRS2KVR.js → chunk-MMXA5GY7.js} +10 -17
- package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-MP3JT3IU.js} +3 -3
- package/dist/cli-delegate/{chunk-3KJIMFTB.js → chunk-NZ5N2XQL.js} +467 -305
- package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-OJM3MBJM.js} +1 -1
- package/dist/cli-delegate/{chunk-BCPIOAGV.js → chunk-RCIA67XN.js} +117 -96
- package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +134 -0
- package/dist/cli-delegate/cmd_conformance.js +10 -47
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +10 -6
- package/dist/cli-delegate/cmd_explain.js +80 -330
- package/dist/cli-delegate/cmd_export.js +6 -6
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +3 -3
- package/dist/cli-delegate/cmd_mcp_available.js +433 -0
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +153 -0
- package/dist/cli-delegate/cmd_preflight.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +6 -6
- package/dist/cli-delegate/cmd_route_audit.js +8 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_settings_get.js +266 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
- package/dist/cli-delegate/cmd_settings_set.js +8 -2968
- package/dist/cli-delegate/cmd_sync.js +6 -6
- package/dist/cli-delegate/cmd_uninstall.js +6 -6
- package/dist/cli-delegate/cmd_update.js +4 -4
- package/dist/cli-delegate/cmd_upgrade.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +6 -6
- package/dist/cli-delegate/cmd_versions.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +164 -55
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +44 -5
- package/dist/discovery/trust-report.md +11 -11
- package/dist/discovery/workspaces.json +16 -6
- package/dist/hooks/dispatch.js +9341 -6131
- package/dist/install/install.mjs +739 -524
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +777 -281
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +134 -15
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/condense.js +147 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +6 -7
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/settingsCarveOut.js +0 -9
- package/dist/shared/settingsCarveOut.js.map +1 -1
- package/dist/shared/settingsClasses.js +11 -9
- package/dist/shared/settingsClasses.js.map +1 -1
- package/dist/ui/assets/{index-DmR0mbk4.js → index-JDAF00bC.js} +2 -2
- package/dist/ui/assets/{index-DmR0mbk4.js.map → index-JDAF00bC.js.map} +1 -1
- package/dist/ui/index.html +1 -1
- package/docs/contracts/settings-classes.md +68 -17
- package/docs/guidelines/agent-infra/memory-access.md +14 -3
- package/package.json +1 -1
- package/src/agent-src/templates/AGENTS.md +8 -12
- package/src/config/agent-settings.template.yml +52 -66
- package/src/config/budgets.yml +29 -0
- package/src/config/discovery/packs.yml +11 -0
- package/src/config/discovery/workspaces.yml +1 -1
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +26 -0
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/scripts/_cli/cmd_brand_status.ts +174 -0
- package/src/scripts/_cli/cmd_conformance.ts +14 -42
- package/src/scripts/_cli/cmd_doctor.ts +65 -48
- package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
- package/src/scripts/_cli/cmd_packs_active.ts +225 -0
- package/src/scripts/_cli/cmd_settings_get.ts +324 -0
- package/src/scripts/_dispatch.bash +57 -0
- package/src/scripts/_lib/agent_settings.ts +140 -16
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +1 -1
- package/src/scripts/_lib/auto_dispatch.ts +23 -18
- package/src/scripts/_lib/capsule_trigger.ts +124 -0
- package/src/scripts/_lib/carrier_divergence.ts +135 -0
- package/src/scripts/_lib/host_capability.ts +144 -4
- package/src/scripts/_lib/judgment_ladder.ts +382 -0
- package/src/scripts/_lib/orchestration_gate.ts +8 -0
- package/src/scripts/_lib/orchestration_record.ts +37 -0
- package/src/scripts/_lib/orchestration_savings.ts +1 -1
- package/src/scripts/_lib/prompt_shape.ts +88 -0
- package/src/scripts/_lib/review_skipped_record.ts +102 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
- package/src/scripts/_lib/self_repair.ts +489 -0
- package/src/scripts/_lib/self_repair_store.ts +128 -0
- package/src/scripts/_lib/subagent_capsule.ts +182 -0
- package/src/scripts/_lib/subagent_response.ts +19 -0
- package/src/scripts/_lib/subagent_spawn.ts +13 -0
- package/src/scripts/_lib/subagent_steering.ts +9 -4
- package/src/scripts/_lib/tier_budget_routing.ts +6 -1
- package/src/scripts/_lib/transcript_entry.ts +80 -0
- package/src/scripts/_lib/worker_budget.ts +37 -2
- package/src/scripts/ai_council/clients.ts +76 -54
- package/src/scripts/ai_council/config.ts +94 -6
- package/src/scripts/ai_council/handoff.ts +113 -0
- package/src/scripts/ai_council/modes.ts +19 -4
- package/src/scripts/ai_council/orchestrator.ts +105 -0
- package/src/scripts/ai_council/quorum.ts +84 -0
- package/src/scripts/ai_council/session.ts +44 -0
- package/src/scripts/ai_council/transport_resolver.ts +127 -1
- package/src/scripts/ai_team/availability.ts +110 -0
- package/src/scripts/ai_team/config.ts +34 -14
- package/src/scripts/ai_team/team_dispatch.ts +71 -29
- package/src/scripts/bench_critic_protocol.ts +396 -0
- package/src/scripts/check_branch_freshness.ts +255 -0
- package/src/scripts/check_council_config_location.ts +125 -1
- package/src/scripts/check_detector_corpus.ts +202 -0
- package/src/scripts/check_hook_bundle_freshness.ts +4 -1
- package/src/scripts/check_standing_rule_delivery.ts +314 -0
- package/src/scripts/condense.ts +162 -2
- package/src/scripts/config/profiles.ts +13 -3
- package/src/scripts/conformance_scan.ts +272 -24
- package/src/scripts/council_availability_hook.ts +188 -0
- package/src/scripts/council_cli.ts +527 -32
- package/src/scripts/forensics_report.ts +333 -0
- package/src/scripts/hook_manifest.yaml +107 -26
- package/src/scripts/hooks/block_no_verify.ts +39 -2
- package/src/scripts/hooks/block_unauthorized_git.ts +156 -7
- package/src/scripts/hooks/concern_registry.ts +10 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +484 -0
- package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
- package/src/scripts/install.ts +151 -0
- package/src/scripts/language_mirror_hook.ts +30 -37
- package/src/scripts/lint_discovery_vocabulary.ts +2 -0
- package/src/scripts/lint_never_silent.ts +276 -0
- package/src/scripts/lint_no_activation_gates.ts +271 -0
- package/src/scripts/measure_scope_dedup.ts +19 -13
- package/src/scripts/onboarding_gate_hook.ts +40 -1
- package/src/scripts/orchestration_record.ts +12 -1
- package/src/scripts/preamble_byte_census.ts +9 -20
- package/src/scripts/rebuild_hook_bundle.ts +177 -0
- package/src/scripts/release.ts +74 -2
- package/src/scripts/report_carrier_divergence.ts +364 -0
- package/src/scripts/report_skill_activation.ts +257 -0
- package/src/scripts/report_skill_obligation_violations.ts +579 -0
- package/src/scripts/routing_doctor.ts +95 -39
- package/src/scripts/score_skill_selection.ts +19 -5
- package/src/scripts/self_repair_cli.ts +470 -0
- package/src/scripts/self_repair_hook.ts +241 -0
- package/src/scripts/team_events_spike.ts +271 -0
- package/src/scripts/team_review_gate_hook.ts +31 -9
- package/src/server/schemas/settings.ts +10 -17
- package/src/shared/settingsCarveOut.ts +0 -10
- package/src/shared/settingsClasses.ts +11 -9
package/dist/mcp/server.mjs
CHANGED
|
@@ -129,6 +129,7 @@ __export(agent_settings_exports, {
|
|
|
129
129
|
PROJECT_ROOT_ENV: () => PROJECT_ROOT_ENV,
|
|
130
130
|
ProjectRootError: () => ProjectRootError,
|
|
131
131
|
ROOT_OVERRIDE_ENV: () => ROOT_OVERRIDE_ENV,
|
|
132
|
+
USER_GLOBAL_CANONICAL_RELATIVE: () => USER_GLOBAL_CANONICAL_RELATIVE,
|
|
132
133
|
USER_GLOBAL_FILENAME: () => USER_GLOBAL_FILENAME,
|
|
133
134
|
canonical_settings_write_path: () => canonical_settings_write_path,
|
|
134
135
|
enumerate_modules: () => enumerate_modules,
|
|
@@ -140,7 +141,8 @@ __export(agent_settings_exports, {
|
|
|
140
141
|
load_agent_settings: () => load_agent_settings,
|
|
141
142
|
logger: () => logger,
|
|
142
143
|
project_settings_path: () => project_settings_path,
|
|
143
|
-
resolve_project_root: () => resolve_project_root
|
|
144
|
+
resolve_project_root: () => resolve_project_root,
|
|
145
|
+
user_global_settings_paths: () => user_global_settings_paths
|
|
144
146
|
});
|
|
145
147
|
import { createRequire } from "node:module";
|
|
146
148
|
import * as fs3 from "node:fs";
|
|
@@ -192,12 +194,20 @@ function canonical_settings_write_path(project_root) {
|
|
|
192
194
|
function DEFAULT_USER_GLOBAL_FILE() {
|
|
193
195
|
return write_target(USER_GLOBAL_FILENAME);
|
|
194
196
|
}
|
|
195
|
-
function
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
function user_global_settings_paths() {
|
|
198
|
+
const paths = [];
|
|
199
|
+
const flat = resolve_with_fallback(USER_GLOBAL_FILENAME);
|
|
200
|
+
if (flat !== null) {
|
|
201
|
+
paths.push(flat);
|
|
199
202
|
}
|
|
200
|
-
|
|
203
|
+
const canonical = resolve_with_fallback(USER_GLOBAL_CANONICAL_RELATIVE);
|
|
204
|
+
if (canonical !== null) {
|
|
205
|
+
paths.push(canonical);
|
|
206
|
+
}
|
|
207
|
+
if (paths.length === 0) {
|
|
208
|
+
paths.push(DEFAULT_USER_GLOBAL_FILE());
|
|
209
|
+
}
|
|
210
|
+
return paths;
|
|
201
211
|
}
|
|
202
212
|
function _exists(p) {
|
|
203
213
|
try {
|
|
@@ -442,7 +452,10 @@ function load_agent_settings(options = {}) {
|
|
|
442
452
|
const user_global_path = options.user_global_path ?? null;
|
|
443
453
|
const verbose = options.verbose ?? false;
|
|
444
454
|
const cwd = options.cwd ?? null;
|
|
445
|
-
const user_global_raw =
|
|
455
|
+
const user_global_raw = {};
|
|
456
|
+
for (const p of user_global_path ? [user_global_path] : user_global_settings_paths()) {
|
|
457
|
+
_deep_merge(user_global_raw, _read_yaml(p) ?? {});
|
|
458
|
+
}
|
|
446
459
|
const [user_global_filtered, ignored] = _filter_whitelist(user_global_raw, MERGEABLE_KEYS);
|
|
447
460
|
if (verbose && ignored.length > 0) {
|
|
448
461
|
logger.info(
|
|
@@ -459,8 +472,32 @@ function load_agent_settings(options = {}) {
|
|
|
459
472
|
_deep_merge(merged, layer);
|
|
460
473
|
}
|
|
461
474
|
}
|
|
475
|
+
_warn_removed_always_on_keys(merged);
|
|
462
476
|
return merged;
|
|
463
477
|
}
|
|
478
|
+
function _readDottedSettingsPath(root, dotted) {
|
|
479
|
+
let node = root;
|
|
480
|
+
for (const part of dotted.split(".")) {
|
|
481
|
+
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
482
|
+
return void 0;
|
|
483
|
+
}
|
|
484
|
+
node = node[part];
|
|
485
|
+
}
|
|
486
|
+
return node;
|
|
487
|
+
}
|
|
488
|
+
function _warn_removed_always_on_keys(merged) {
|
|
489
|
+
for (const key of REMOVED_ALWAYS_ON_KEYS) {
|
|
490
|
+
if (_warnedRemovedAlwaysOnKeys.has(key)) {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
if (_readDottedSettingsPath(merged, key) === void 0) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
_warnedRemovedAlwaysOnKeys.add(key);
|
|
497
|
+
process.stderr.write(`${key} was removed (always-on orchestration); ignored.
|
|
498
|
+
`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
464
501
|
function get_modules_config(options = {}) {
|
|
465
502
|
const project_root = options.project_root ?? null;
|
|
466
503
|
const team_path = options.team_path ?? null;
|
|
@@ -595,12 +632,11 @@ function* iter_setting_overrides(options = {}) {
|
|
|
595
632
|
const project_path = options.project_path ?? null;
|
|
596
633
|
const user_global_path = options.user_global_path ?? null;
|
|
597
634
|
const cwd = options.cwd ?? null;
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
yield [key, _get_dotted(user_global_filtered, key), user_global_path_resolved];
|
|
635
|
+
for (const p of user_global_path ? [user_global_path] : user_global_settings_paths()) {
|
|
636
|
+
const raw = _read_yaml(p) ?? {};
|
|
637
|
+
const [filtered] = _filter_whitelist(raw, MERGEABLE_KEYS);
|
|
638
|
+
for (const key of _leaf_paths(filtered)) {
|
|
639
|
+
yield [key, _get_dotted(filtered, key), p];
|
|
604
640
|
}
|
|
605
641
|
}
|
|
606
642
|
for (const p of _resolve_cascade_paths(cwd, project_path)) {
|
|
@@ -741,7 +777,7 @@ function _relative_to(child, root) {
|
|
|
741
777
|
function _posix_join(a, b) {
|
|
742
778
|
return `${a.split(path3.sep).join("/")}/${b}`;
|
|
743
779
|
}
|
|
744
|
-
var _require, Logger, logger, DEFAULT_PROJECT_FILE, LOCAL_PROJECT_FILE, LOCAL_PROJECT_SUBDIR, DEFAULT_TEAM_FILE, USER_GLOBAL_FILENAME, MERGEABLE_KEYS, _DEFAULTS, MODULES_DEFAULTS, ANCHOR_AGENT_SETTINGS, ANCHOR_AGENTS_DIR, ANCHOR_GIT, _AGENTS_DIR_MARKERS, _LEGACY_ANCHOR_ENV, ORIGIN_ROOT_FLAG, ORIGIN_EXPLICIT, ORIGIN_ENV, ORIGIN_CWD_FALLBACK, PROJECT_ROOT_ENV, ROOT_OVERRIDE_ENV, ProjectRootError;
|
|
780
|
+
var _require, Logger, logger, DEFAULT_PROJECT_FILE, LOCAL_PROJECT_FILE, LOCAL_PROJECT_SUBDIR, DEFAULT_TEAM_FILE, USER_GLOBAL_FILENAME, USER_GLOBAL_CANONICAL_RELATIVE, MERGEABLE_KEYS, _DEFAULTS, MODULES_DEFAULTS, ANCHOR_AGENT_SETTINGS, ANCHOR_AGENTS_DIR, ANCHOR_GIT, _AGENTS_DIR_MARKERS, _LEGACY_ANCHOR_ENV, ORIGIN_ROOT_FLAG, ORIGIN_EXPLICIT, ORIGIN_ENV, ORIGIN_CWD_FALLBACK, PROJECT_ROOT_ENV, ROOT_OVERRIDE_ENV, ProjectRootError, REMOVED_ALWAYS_ON_KEYS, _warnedRemovedAlwaysOnKeys;
|
|
745
781
|
var init_agent_settings = __esm({
|
|
746
782
|
"src/scripts/_lib/agent_settings.ts"() {
|
|
747
783
|
"use strict";
|
|
@@ -763,12 +799,27 @@ var init_agent_settings = __esm({
|
|
|
763
799
|
LOCAL_PROJECT_SUBDIR = ["agents", "settings"];
|
|
764
800
|
DEFAULT_TEAM_FILE = ".agent-project-settings.yml";
|
|
765
801
|
USER_GLOBAL_FILENAME = "agent-settings.yml";
|
|
802
|
+
USER_GLOBAL_CANONICAL_RELATIVE = "settings/.agent-settings.yml";
|
|
766
803
|
MERGEABLE_KEYS = [
|
|
804
|
+
// `name`, `ide` and `personal.bot_icon` are the PRE-MIGRATION spellings.
|
|
805
|
+
// `install.ts` migrates `ide` → `personal.ide` and `pr_comment_bot_icon`
|
|
806
|
+
// into its `personal.` home, and this list was never moved with them — so
|
|
807
|
+
// the whitelist named keys the template does not have while the keys it
|
|
808
|
+
// does have were filtered out silently. A user setting either preference
|
|
809
|
+
// user-globally got no error, no warning, and no effect
|
|
810
|
+
// (road-to-capability-answerability 4.3, ADR-219).
|
|
811
|
+
//
|
|
812
|
+
// Both spellings are listed rather than replaced: a legacy file that still
|
|
813
|
+
// uses the old name keeps working, and nothing that resolved before
|
|
814
|
+
// resolves differently. `name` has no reader anywhere and no template key;
|
|
815
|
+
// it is kept only so this change stays purely additive.
|
|
767
816
|
"name",
|
|
768
817
|
"ide",
|
|
818
|
+
"personal.ide",
|
|
769
819
|
"rule_loading_tier",
|
|
770
820
|
"memory.cadence",
|
|
771
821
|
"personal.bot_icon",
|
|
822
|
+
"personal.pr_comment_bot_icon",
|
|
772
823
|
"personal.autonomy",
|
|
773
824
|
"telegraph.speak_scope",
|
|
774
825
|
// Knowledge-card global cross-project sharing is a USER-GLOBAL setting
|
|
@@ -816,6 +867,14 @@ var init_agent_settings = __esm({
|
|
|
816
867
|
this.name = "ProjectRootError";
|
|
817
868
|
}
|
|
818
869
|
};
|
|
870
|
+
REMOVED_ALWAYS_ON_KEYS = [
|
|
871
|
+
"subagents.enabled",
|
|
872
|
+
"subagents.auto",
|
|
873
|
+
"subagents.host_capabilities",
|
|
874
|
+
"subagents.budget_routing",
|
|
875
|
+
"ai_team.enabled"
|
|
876
|
+
];
|
|
877
|
+
_warnedRemovedAlwaysOnKeys = /* @__PURE__ */ new Set();
|
|
819
878
|
}
|
|
820
879
|
});
|
|
821
880
|
|
|
@@ -23814,8 +23873,19 @@ ${user_prompt}`;
|
|
|
23814
23873
|
"429",
|
|
23815
23874
|
"usage limit"
|
|
23816
23875
|
];
|
|
23817
|
-
|
|
23876
|
+
/**
|
|
23877
|
+
* `identity` carries the subclass constants (`name`, `default_binary`)
|
|
23878
|
+
* that construction validates against. They are passed explicitly rather
|
|
23879
|
+
* than read off `this.name` / `this.default_binary` because subclass
|
|
23880
|
+
* instance-field initializers (`override default_binary = 'claude'`,
|
|
23881
|
+
* declared in the subclass body) run only AFTER this `super()` call
|
|
23882
|
+
* returns — reading them here, before that happens, would always see the
|
|
23883
|
+
* base class's own field defaults (`''`), not the subclass override.
|
|
23884
|
+
*/
|
|
23885
|
+
constructor(opts, identity) {
|
|
23818
23886
|
super();
|
|
23887
|
+
this.name = identity.name;
|
|
23888
|
+
this.default_binary = identity.default_binary;
|
|
23819
23889
|
this.model = opts.model;
|
|
23820
23890
|
this.timeout_seconds = opts.timeout_seconds ?? DEFAULT_CLI_TIMEOUT_SECONDS;
|
|
23821
23891
|
this.max_calls_per_day = opts.max_calls_per_day ?? null;
|
|
@@ -24020,18 +24090,19 @@ ${user_prompt}`;
|
|
|
24020
24090
|
}
|
|
24021
24091
|
};
|
|
24022
24092
|
AnthropicCliClient = class extends CliClient {
|
|
24023
|
-
name = "anthropic";
|
|
24024
|
-
default_binary = "claude";
|
|
24025
24093
|
subscription_label = "claude-pro";
|
|
24026
24094
|
constructor(opts = {}) {
|
|
24027
|
-
super(
|
|
24028
|
-
|
|
24029
|
-
|
|
24030
|
-
|
|
24031
|
-
|
|
24032
|
-
|
|
24033
|
-
|
|
24034
|
-
|
|
24095
|
+
super(
|
|
24096
|
+
{
|
|
24097
|
+
model: opts.model ?? DEFAULT_ANTHROPIC_CLI_MODEL,
|
|
24098
|
+
binary: opts.binary,
|
|
24099
|
+
timeout_seconds: opts.timeout_seconds,
|
|
24100
|
+
max_calls_per_day: opts.max_calls_per_day,
|
|
24101
|
+
warn_at: opts.warn_at,
|
|
24102
|
+
cli_calls_path: opts.cli_calls_path
|
|
24103
|
+
},
|
|
24104
|
+
{ name: "anthropic", default_binary: "claude" }
|
|
24105
|
+
);
|
|
24035
24106
|
}
|
|
24036
24107
|
_build_command(system_prompt, user_prompt, max_tokens) {
|
|
24037
24108
|
void user_prompt;
|
|
@@ -24091,8 +24162,6 @@ ${user_prompt}`;
|
|
|
24091
24162
|
}
|
|
24092
24163
|
};
|
|
24093
24164
|
OpenAICliClient = class extends CliClient {
|
|
24094
|
-
name = "openai";
|
|
24095
|
-
default_binary = "codex";
|
|
24096
24165
|
subscription_label = "chatgpt-plus";
|
|
24097
24166
|
static _AUTH_FAILURE_PATTERNS = [
|
|
24098
24167
|
...CliClient._AUTH_FAILURE_PATTERNS,
|
|
@@ -24101,14 +24170,17 @@ ${user_prompt}`;
|
|
|
24101
24170
|
"401"
|
|
24102
24171
|
];
|
|
24103
24172
|
constructor(opts = {}) {
|
|
24104
|
-
super(
|
|
24105
|
-
|
|
24106
|
-
|
|
24107
|
-
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
|
|
24111
|
-
|
|
24173
|
+
super(
|
|
24174
|
+
{
|
|
24175
|
+
model: opts.model ?? DEFAULT_OPENAI_CLI_MODEL,
|
|
24176
|
+
binary: opts.binary,
|
|
24177
|
+
timeout_seconds: opts.timeout_seconds,
|
|
24178
|
+
max_calls_per_day: opts.max_calls_per_day,
|
|
24179
|
+
warn_at: opts.warn_at,
|
|
24180
|
+
cli_calls_path: opts.cli_calls_path
|
|
24181
|
+
},
|
|
24182
|
+
{ name: "openai", default_binary: "codex" }
|
|
24183
|
+
);
|
|
24112
24184
|
}
|
|
24113
24185
|
_build_command(system_prompt, user_prompt, max_tokens) {
|
|
24114
24186
|
void max_tokens;
|
|
@@ -24197,8 +24269,6 @@ ${user_prompt}`;
|
|
|
24197
24269
|
}
|
|
24198
24270
|
};
|
|
24199
24271
|
GeminiCliClient = class extends CliClient {
|
|
24200
|
-
name = "gemini";
|
|
24201
|
-
default_binary = "gemini";
|
|
24202
24272
|
subscription_label = "gemini-pro";
|
|
24203
24273
|
static _AUTH_FAILURE_PATTERNS = [
|
|
24204
24274
|
...CliClient._AUTH_FAILURE_PATTERNS,
|
|
@@ -24207,14 +24277,17 @@ ${user_prompt}`;
|
|
|
24207
24277
|
"oauth"
|
|
24208
24278
|
];
|
|
24209
24279
|
constructor(opts = {}) {
|
|
24210
|
-
super(
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24217
|
-
|
|
24280
|
+
super(
|
|
24281
|
+
{
|
|
24282
|
+
model: opts.model ?? DEFAULT_GEMINI_CLI_MODEL,
|
|
24283
|
+
binary: opts.binary,
|
|
24284
|
+
timeout_seconds: opts.timeout_seconds,
|
|
24285
|
+
max_calls_per_day: opts.max_calls_per_day,
|
|
24286
|
+
warn_at: opts.warn_at,
|
|
24287
|
+
cli_calls_path: opts.cli_calls_path
|
|
24288
|
+
},
|
|
24289
|
+
{ name: "gemini", default_binary: "gemini" }
|
|
24290
|
+
);
|
|
24218
24291
|
}
|
|
24219
24292
|
_build_command(system_prompt, user_prompt, max_tokens) {
|
|
24220
24293
|
void user_prompt;
|
|
@@ -24289,8 +24362,6 @@ ${user_prompt}`;
|
|
|
24289
24362
|
}
|
|
24290
24363
|
};
|
|
24291
24364
|
XAICliClient = class extends CliClient {
|
|
24292
|
-
name = "xai";
|
|
24293
|
-
default_binary = "grok";
|
|
24294
24365
|
billable = true;
|
|
24295
24366
|
// community CLI consumes an API key — billable applies
|
|
24296
24367
|
static _AUTH_FAILURE_PATTERNS = [
|
|
@@ -24300,14 +24371,17 @@ ${user_prompt}`;
|
|
|
24300
24371
|
"unauthorized"
|
|
24301
24372
|
];
|
|
24302
24373
|
constructor(opts = {}) {
|
|
24303
|
-
super(
|
|
24304
|
-
|
|
24305
|
-
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
|
|
24309
|
-
|
|
24310
|
-
|
|
24374
|
+
super(
|
|
24375
|
+
{
|
|
24376
|
+
model: opts.model ?? DEFAULT_XAI_MODEL,
|
|
24377
|
+
binary: opts.binary,
|
|
24378
|
+
timeout_seconds: opts.timeout_seconds,
|
|
24379
|
+
max_calls_per_day: opts.max_calls_per_day,
|
|
24380
|
+
warn_at: opts.warn_at,
|
|
24381
|
+
cli_calls_path: opts.cli_calls_path
|
|
24382
|
+
},
|
|
24383
|
+
{ name: "xai", default_binary: "grok" }
|
|
24384
|
+
);
|
|
24311
24385
|
}
|
|
24312
24386
|
_build_command(system_prompt, user_prompt, max_tokens) {
|
|
24313
24387
|
void system_prompt;
|
|
@@ -24333,8 +24407,6 @@ ${user_prompt}`;
|
|
|
24333
24407
|
}
|
|
24334
24408
|
};
|
|
24335
24409
|
PerplexityCliClient = class extends CliClient {
|
|
24336
|
-
name = "perplexity";
|
|
24337
|
-
default_binary = "perplexity";
|
|
24338
24410
|
billable = true;
|
|
24339
24411
|
// community CLI consumes an API key — billable applies
|
|
24340
24412
|
static _AUTH_FAILURE_PATTERNS = [
|
|
@@ -24344,14 +24416,17 @@ ${user_prompt}`;
|
|
|
24344
24416
|
"unauthorized"
|
|
24345
24417
|
];
|
|
24346
24418
|
constructor(opts = {}) {
|
|
24347
|
-
super(
|
|
24348
|
-
|
|
24349
|
-
|
|
24350
|
-
|
|
24351
|
-
|
|
24352
|
-
|
|
24353
|
-
|
|
24354
|
-
|
|
24419
|
+
super(
|
|
24420
|
+
{
|
|
24421
|
+
model: opts.model ?? DEFAULT_PERPLEXITY_MODEL,
|
|
24422
|
+
binary: opts.binary,
|
|
24423
|
+
timeout_seconds: opts.timeout_seconds,
|
|
24424
|
+
max_calls_per_day: opts.max_calls_per_day,
|
|
24425
|
+
warn_at: opts.warn_at,
|
|
24426
|
+
cli_calls_path: opts.cli_calls_path
|
|
24427
|
+
},
|
|
24428
|
+
{ name: "perplexity", default_binary: "perplexity" }
|
|
24429
|
+
);
|
|
24355
24430
|
}
|
|
24356
24431
|
_build_command(system_prompt, user_prompt, max_tokens) {
|
|
24357
24432
|
void system_prompt;
|
|
@@ -24804,6 +24879,7 @@ function _build_config(raw, source_path) {
|
|
|
24804
24879
|
const cli_call_budget = _build_cli_call_budget(
|
|
24805
24880
|
_asDict(_getOr(raw, "cli_call_budget", {}))
|
|
24806
24881
|
);
|
|
24882
|
+
const quorum = _build_quorum(_get(raw, "quorum", "majority"));
|
|
24807
24883
|
const necessity_classifier = _build_necessity_classifier(
|
|
24808
24884
|
_asDict(_getOr(raw, "necessity_classifier", {}))
|
|
24809
24885
|
);
|
|
@@ -24829,6 +24905,7 @@ function _build_config(raw, source_path) {
|
|
|
24829
24905
|
"debate_gates"
|
|
24830
24906
|
);
|
|
24831
24907
|
const restate = _build_restate(_asDict(_getOr(raw, "restate", {})), "restate");
|
|
24908
|
+
const critic_protocol = _build_critic_protocol(_getOr(raw, "critic_protocol", "legacy"));
|
|
24832
24909
|
const decision_resolution = _build_decision_resolution(
|
|
24833
24910
|
_asDict(_getOr(raw, "decision_resolution", {}))
|
|
24834
24911
|
);
|
|
@@ -24850,6 +24927,7 @@ function _build_config(raw, source_path) {
|
|
|
24850
24927
|
advisors,
|
|
24851
24928
|
consensus_scoring: consensus,
|
|
24852
24929
|
cli_call_budget,
|
|
24930
|
+
quorum,
|
|
24853
24931
|
necessity_classifier,
|
|
24854
24932
|
model_downgrade,
|
|
24855
24933
|
debate,
|
|
@@ -24858,6 +24936,7 @@ function _build_config(raw, source_path) {
|
|
|
24858
24936
|
chairman,
|
|
24859
24937
|
debate_gates,
|
|
24860
24938
|
restate,
|
|
24939
|
+
critic_protocol,
|
|
24861
24940
|
decision_resolution,
|
|
24862
24941
|
routing,
|
|
24863
24942
|
low_impact,
|
|
@@ -25059,6 +25138,15 @@ function _build_restate(d, scope) {
|
|
|
25059
25138
|
}
|
|
25060
25139
|
return { enabled: Boolean(enabled) };
|
|
25061
25140
|
}
|
|
25141
|
+
function _build_critic_protocol(v) {
|
|
25142
|
+
if (v === void 0 || v === null) return "legacy";
|
|
25143
|
+
if (!(_isStr(v) && _VALID_CRITIC_PROTOCOLS.has(v))) {
|
|
25144
|
+
throw new CouncilConfigError(
|
|
25145
|
+
`\`critic_protocol\`=${_pyRepr6(v)} not in ${_sortedListRepr(_VALID_CRITIC_PROTOCOLS)}.`
|
|
25146
|
+
);
|
|
25147
|
+
}
|
|
25148
|
+
return v;
|
|
25149
|
+
}
|
|
25062
25150
|
function _build_decision_resolution(d) {
|
|
25063
25151
|
if (!_isDict(d)) {
|
|
25064
25152
|
throw new CouncilConfigError("`decision_resolution` must be a mapping.");
|
|
@@ -25310,7 +25398,7 @@ function _build_defaults(d) {
|
|
|
25310
25398
|
if (!_isDict(d)) {
|
|
25311
25399
|
throw new CouncilConfigError("`defaults` must be a mapping.");
|
|
25312
25400
|
}
|
|
25313
|
-
const mode = _get(d, "mode", "
|
|
25401
|
+
const mode = _get(d, "mode", "auto");
|
|
25314
25402
|
if (!(_isStr(mode) && _VALID_MODES.has(mode))) {
|
|
25315
25403
|
throw new CouncilConfigError(
|
|
25316
25404
|
`defaults.mode=${_pyRepr6(mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
|
|
@@ -25471,7 +25559,7 @@ function _build_cost_budget(d) {
|
|
|
25471
25559
|
}
|
|
25472
25560
|
return cb;
|
|
25473
25561
|
}
|
|
25474
|
-
function _build_member(name, cfg, default_mode = "
|
|
25562
|
+
function _build_member(name, cfg, default_mode = "auto") {
|
|
25475
25563
|
if (!_VALID_PROVIDERS.has(name)) {
|
|
25476
25564
|
throw new CouncilConfigError(
|
|
25477
25565
|
`members.${name}: unknown provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
|
|
@@ -25599,6 +25687,9 @@ function _build_cli_call_budget(d) {
|
|
|
25599
25687
|
);
|
|
25600
25688
|
}
|
|
25601
25689
|
const caps = /* @__PURE__ */ new Map();
|
|
25690
|
+
for (const provider of _VALID_PROVIDERS) {
|
|
25691
|
+
caps.set(provider, _DEFAULT_CLI_CALLS_PER_DAY);
|
|
25692
|
+
}
|
|
25602
25693
|
for (const [provider, value] of Object.entries(raw_caps)) {
|
|
25603
25694
|
if (!_VALID_PROVIDERS.has(provider)) {
|
|
25604
25695
|
throw new CouncilConfigError(
|
|
@@ -25626,6 +25717,17 @@ function _build_cli_call_budget(d) {
|
|
|
25626
25717
|
}
|
|
25627
25718
|
return { max_calls_per_day: caps, warn_at };
|
|
25628
25719
|
}
|
|
25720
|
+
function _build_quorum(raw) {
|
|
25721
|
+
if (raw === "majority") {
|
|
25722
|
+
return "majority";
|
|
25723
|
+
}
|
|
25724
|
+
if (_isInt(raw) && !_isBool(raw) && raw >= 1) {
|
|
25725
|
+
return raw;
|
|
25726
|
+
}
|
|
25727
|
+
throw new CouncilConfigError(
|
|
25728
|
+
`\`quorum\`=${_pyRepr6(raw)} must be 'majority' or an integer >= 1 (got ${_pyTypeName(raw)}).`
|
|
25729
|
+
);
|
|
25730
|
+
}
|
|
25629
25731
|
function _build_advisor(name, cfg) {
|
|
25630
25732
|
if (!_isDict(cfg)) {
|
|
25631
25733
|
throw new CouncilConfigError(`advisors.${name}: must be a mapping.`);
|
|
@@ -25746,7 +25848,7 @@ function _pyTruthy3(value) {
|
|
|
25746
25848
|
}
|
|
25747
25849
|
return Object.keys(value).length > 0;
|
|
25748
25850
|
}
|
|
25749
|
-
var import_yaml5, _VALID_PROVIDERS, _VALID_MODES, _RAW_KEY_PREFIXES, CouncilConfigError, _Float, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _DEFAULT_RESOLUTION_MODES, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES;
|
|
25851
|
+
var import_yaml5, _VALID_PROVIDERS, _VALID_MODES, _RAW_KEY_PREFIXES, CouncilConfigError, _Float, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_CRITIC_PROTOCOLS, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _DEFAULT_RESOLUTION_MODES, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES, _DEFAULT_CLI_CALLS_PER_DAY;
|
|
25750
25852
|
var init_config = __esm({
|
|
25751
25853
|
"src/scripts/ai_council/config.ts"() {
|
|
25752
25854
|
"use strict";
|
|
@@ -25796,6 +25898,7 @@ var init_config = __esm({
|
|
|
25796
25898
|
COUNCIL_CONFIG_RELNAME = ".ai-council.yml";
|
|
25797
25899
|
COUNCIL_CONFIG_USER_GLOBAL_REL = "settings/.ai-council.yml";
|
|
25798
25900
|
COUNCIL_CONFIG_ENV = "AI_COUNCIL_CONFIG";
|
|
25901
|
+
_VALID_CRITIC_PROTOCOLS = /* @__PURE__ */ new Set(["legacy", "load_bearing"]);
|
|
25799
25902
|
_VALID_RESOLUTION_MODES = /* @__PURE__ */ new Set([
|
|
25800
25903
|
"agent",
|
|
25801
25904
|
"council",
|
|
@@ -25821,6 +25924,7 @@ var init_config = __esm({
|
|
|
25821
25924
|
};
|
|
25822
25925
|
_VALID_MEMBER_MODES = /* @__PURE__ */ new Set(["cli", "api"]);
|
|
25823
25926
|
_VALID_DISPATCH_MODES = /* @__PURE__ */ new Set(["full", "single"]);
|
|
25927
|
+
_DEFAULT_CLI_CALLS_PER_DAY = 50;
|
|
25824
25928
|
}
|
|
25825
25929
|
});
|
|
25826
25930
|
|
|
@@ -26132,6 +26236,112 @@ var init_environment_detector = __esm({
|
|
|
26132
26236
|
}
|
|
26133
26237
|
});
|
|
26134
26238
|
|
|
26239
|
+
// src/scripts/ai_council/modes.ts
|
|
26240
|
+
function _sortedValidModes() {
|
|
26241
|
+
return Array.from(VALID_MODES).sort();
|
|
26242
|
+
}
|
|
26243
|
+
function _normalise(value) {
|
|
26244
|
+
if (value === null || value === void 0) {
|
|
26245
|
+
return null;
|
|
26246
|
+
}
|
|
26247
|
+
if (typeof value !== "string") {
|
|
26248
|
+
return null;
|
|
26249
|
+
}
|
|
26250
|
+
const s = value.trim().toLowerCase();
|
|
26251
|
+
return s || null;
|
|
26252
|
+
}
|
|
26253
|
+
function _validate2(mode, source) {
|
|
26254
|
+
if (mode === null) {
|
|
26255
|
+
return null;
|
|
26256
|
+
}
|
|
26257
|
+
if (!VALID_MODES.has(mode)) {
|
|
26258
|
+
throw new InvalidModeError(
|
|
26259
|
+
`${source} requested mode=${_pyRepr7(mode)}; expected one of: ${_pyReprList2(_sortedValidModes())}`
|
|
26260
|
+
);
|
|
26261
|
+
}
|
|
26262
|
+
return mode;
|
|
26263
|
+
}
|
|
26264
|
+
function _pyRepr7(s) {
|
|
26265
|
+
return `'${s}'`;
|
|
26266
|
+
}
|
|
26267
|
+
function _pyReprList2(items) {
|
|
26268
|
+
return `[${items.map((i) => _pyRepr7(i)).join(", ")}]`;
|
|
26269
|
+
}
|
|
26270
|
+
function resolve_global_mode(aiBlock) {
|
|
26271
|
+
if (aiBlock === null || aiBlock === void 0) {
|
|
26272
|
+
return null;
|
|
26273
|
+
}
|
|
26274
|
+
const flat = _normalise(_settingsGet(aiBlock, "mode"));
|
|
26275
|
+
if (flat !== null) {
|
|
26276
|
+
return flat;
|
|
26277
|
+
}
|
|
26278
|
+
const defaults = _settingsGet(aiBlock, "defaults");
|
|
26279
|
+
if (defaults === null || defaults === void 0) {
|
|
26280
|
+
return null;
|
|
26281
|
+
}
|
|
26282
|
+
if (!(defaults instanceof Map) && typeof defaults !== "object") {
|
|
26283
|
+
return null;
|
|
26284
|
+
}
|
|
26285
|
+
if (Array.isArray(defaults)) {
|
|
26286
|
+
return null;
|
|
26287
|
+
}
|
|
26288
|
+
return _normalise(
|
|
26289
|
+
_settingsGet(defaults, "mode")
|
|
26290
|
+
);
|
|
26291
|
+
}
|
|
26292
|
+
function _settingsGet(settings, key) {
|
|
26293
|
+
if (settings === null || settings === void 0) {
|
|
26294
|
+
return void 0;
|
|
26295
|
+
}
|
|
26296
|
+
if (settings instanceof Map) {
|
|
26297
|
+
return settings.get(key);
|
|
26298
|
+
}
|
|
26299
|
+
return settings[key];
|
|
26300
|
+
}
|
|
26301
|
+
function resolve_mode(memberName, opts = {}) {
|
|
26302
|
+
const invocationMode = opts.invocationMode ?? null;
|
|
26303
|
+
const memberSettings = opts.memberSettings ?? null;
|
|
26304
|
+
const globalMode = opts.globalMode ?? null;
|
|
26305
|
+
const inv = _validate2(
|
|
26306
|
+
_normalise(invocationMode),
|
|
26307
|
+
`/council mode= for ${_pyRepr7(memberName)}`
|
|
26308
|
+
);
|
|
26309
|
+
if (inv !== null) {
|
|
26310
|
+
return inv;
|
|
26311
|
+
}
|
|
26312
|
+
let memberModeRaw = null;
|
|
26313
|
+
if (memberSettings !== null) {
|
|
26314
|
+
const v = _settingsGet(memberSettings, "mode");
|
|
26315
|
+
memberModeRaw = v === void 0 ? null : v;
|
|
26316
|
+
}
|
|
26317
|
+
const member = _validate2(
|
|
26318
|
+
_normalise(memberModeRaw),
|
|
26319
|
+
`ai_council.members.${memberName}.mode`
|
|
26320
|
+
);
|
|
26321
|
+
if (member !== null) {
|
|
26322
|
+
return member;
|
|
26323
|
+
}
|
|
26324
|
+
const glob2 = _validate2(_normalise(globalMode), "ai_council.mode");
|
|
26325
|
+
if (glob2 !== null) {
|
|
26326
|
+
return glob2;
|
|
26327
|
+
}
|
|
26328
|
+
return DEFAULT_MODE;
|
|
26329
|
+
}
|
|
26330
|
+
var VALID_MODES, DEFAULT_MODE, InvalidModeError;
|
|
26331
|
+
var init_modes = __esm({
|
|
26332
|
+
"src/scripts/ai_council/modes.ts"() {
|
|
26333
|
+
"use strict";
|
|
26334
|
+
VALID_MODES = /* @__PURE__ */ new Set(["api", "manual", "cli", "auto"]);
|
|
26335
|
+
DEFAULT_MODE = "manual";
|
|
26336
|
+
InvalidModeError = class extends Error {
|
|
26337
|
+
constructor(message) {
|
|
26338
|
+
super(message);
|
|
26339
|
+
this.name = "InvalidModeError";
|
|
26340
|
+
}
|
|
26341
|
+
};
|
|
26342
|
+
}
|
|
26343
|
+
});
|
|
26344
|
+
|
|
26135
26345
|
// src/scripts/ai_council/transport_resolver.ts
|
|
26136
26346
|
function hasSource(report2, provider, allowed) {
|
|
26137
26347
|
return report2.auth.some((a) => a.provider === provider && allowed.has(a.source));
|
|
@@ -26166,7 +26376,8 @@ function resolveTransport(opts) {
|
|
|
26166
26376
|
billing,
|
|
26167
26377
|
authSource,
|
|
26168
26378
|
makesProviderCall: false,
|
|
26169
|
-
reason: null
|
|
26379
|
+
reason: null,
|
|
26380
|
+
absentReason: null
|
|
26170
26381
|
};
|
|
26171
26382
|
}
|
|
26172
26383
|
if (mode === "api" || mode === "cli") {
|
|
@@ -26176,7 +26387,8 @@ function resolveTransport(opts) {
|
|
|
26176
26387
|
billing,
|
|
26177
26388
|
authSource,
|
|
26178
26389
|
makesProviderCall: true,
|
|
26179
|
-
reason: null
|
|
26390
|
+
reason: null,
|
|
26391
|
+
absentReason: null
|
|
26180
26392
|
};
|
|
26181
26393
|
}
|
|
26182
26394
|
if (mode !== "auto") {
|
|
@@ -26196,7 +26408,8 @@ function resolveTransport(opts) {
|
|
|
26196
26408
|
billing,
|
|
26197
26409
|
authSource,
|
|
26198
26410
|
makesProviderCall: true,
|
|
26199
|
-
reason: null
|
|
26411
|
+
reason: null,
|
|
26412
|
+
absentReason: null
|
|
26200
26413
|
};
|
|
26201
26414
|
}
|
|
26202
26415
|
const keyPresent = opts.apiKeyPresent ?? hasSource(report2, provider, KEY_AUTH_SOURCES);
|
|
@@ -26207,12 +26420,36 @@ function resolveTransport(opts) {
|
|
|
26207
26420
|
billing,
|
|
26208
26421
|
authSource,
|
|
26209
26422
|
makesProviderCall: true,
|
|
26210
|
-
reason: null
|
|
26423
|
+
reason: null,
|
|
26424
|
+
absentReason: null
|
|
26211
26425
|
};
|
|
26212
26426
|
}
|
|
26213
|
-
return unavailable(
|
|
26427
|
+
return unavailable(
|
|
26428
|
+
provider,
|
|
26429
|
+
billing,
|
|
26430
|
+
autoUnavailableReason(provider, binary, cliAuthed),
|
|
26431
|
+
classifyStaticAbsentReason(binary)
|
|
26432
|
+
);
|
|
26433
|
+
}
|
|
26434
|
+
function resolveMemberTransport(opts) {
|
|
26435
|
+
const configuredMode = resolve_mode(opts.provider, {
|
|
26436
|
+
invocationMode: opts.invocationMode ?? null,
|
|
26437
|
+
memberSettings: opts.memberSettings ?? null,
|
|
26438
|
+
globalMode: opts.globalMode ?? null
|
|
26439
|
+
});
|
|
26440
|
+
const resolved = resolveTransport({
|
|
26441
|
+
provider: opts.provider,
|
|
26442
|
+
mode: configuredMode,
|
|
26443
|
+
report: opts.report,
|
|
26444
|
+
binaryOverride: opts.binaryOverride ?? null,
|
|
26445
|
+
// `exactOptionalPropertyTypes` rejects an explicit `undefined` for an
|
|
26446
|
+
// optional-boolean field, so the key is omitted entirely rather than
|
|
26447
|
+
// forwarded as `apiKeyPresent: undefined`.
|
|
26448
|
+
...opts.apiKeyPresent !== void 0 ? { apiKeyPresent: opts.apiKeyPresent } : {}
|
|
26449
|
+
});
|
|
26450
|
+
return { ...resolved, configuredMode };
|
|
26214
26451
|
}
|
|
26215
|
-
function unavailable(_provider, billing, reason) {
|
|
26452
|
+
function unavailable(_provider, billing, reason, absentReason = null) {
|
|
26216
26453
|
return {
|
|
26217
26454
|
available: false,
|
|
26218
26455
|
transport: null,
|
|
@@ -26221,9 +26458,13 @@ function unavailable(_provider, billing, reason) {
|
|
|
26221
26458
|
billing,
|
|
26222
26459
|
authSource: null,
|
|
26223
26460
|
makesProviderCall: false,
|
|
26224
|
-
reason
|
|
26461
|
+
reason,
|
|
26462
|
+
absentReason
|
|
26225
26463
|
};
|
|
26226
26464
|
}
|
|
26465
|
+
function classifyStaticAbsentReason(binary) {
|
|
26466
|
+
return binary === null ? "no_binary" : "no_auth";
|
|
26467
|
+
}
|
|
26227
26468
|
function autoUnavailableReason(provider, binary, cliAuthed) {
|
|
26228
26469
|
const expected = PROVIDER_CLI_META[provider]?.[0] ?? provider;
|
|
26229
26470
|
if (binary === null && !cliAuthed) {
|
|
@@ -26234,11 +26475,40 @@ function autoUnavailableReason(provider, binary, cliAuthed) {
|
|
|
26234
26475
|
}
|
|
26235
26476
|
return `no transport available: \`${expected}\` is on PATH but not authenticated and no key resolves \u2014 log in to the CLI, or add an api_key_ref`;
|
|
26236
26477
|
}
|
|
26478
|
+
function classifyCliFailure(raw) {
|
|
26479
|
+
const s = raw.trim().toLowerCase();
|
|
26480
|
+
if (s === "binary_missing" || s === "file_not_found") return "binary_missing";
|
|
26481
|
+
if (s === "auth_expired" || s === "auth_rejected" || s === "unauthorized") {
|
|
26482
|
+
return "auth_rejected";
|
|
26483
|
+
}
|
|
26484
|
+
if (s === "cli_unsupported" || s === "unsupported" || s === "parse_failed") {
|
|
26485
|
+
return "cli_unsupported";
|
|
26486
|
+
}
|
|
26487
|
+
if (s === "timeout") return "timeout";
|
|
26488
|
+
if (s === "cli_quota_exhausted" || s === "quota_exhausted") return "quota_exhausted";
|
|
26489
|
+
if (/^exit_5\d\d$/.test(s) || s === "server_error" || s === "os") return "server_error";
|
|
26490
|
+
return "other";
|
|
26491
|
+
}
|
|
26492
|
+
function absentReasonFromCliFailure(failure) {
|
|
26493
|
+
switch (failure) {
|
|
26494
|
+
case "binary_missing":
|
|
26495
|
+
return "no_binary";
|
|
26496
|
+
case "auth_rejected":
|
|
26497
|
+
return "no_auth";
|
|
26498
|
+
case "timeout":
|
|
26499
|
+
return "timeout";
|
|
26500
|
+
case "quota_exhausted":
|
|
26501
|
+
return "quota";
|
|
26502
|
+
default:
|
|
26503
|
+
return null;
|
|
26504
|
+
}
|
|
26505
|
+
}
|
|
26237
26506
|
var VALID_TRANSPORT_MODES, CLI_AUTH_SOURCES, KEY_AUTH_SOURCES;
|
|
26238
26507
|
var init_transport_resolver = __esm({
|
|
26239
26508
|
"src/scripts/ai_council/transport_resolver.ts"() {
|
|
26240
26509
|
"use strict";
|
|
26241
26510
|
init_environment_detector();
|
|
26511
|
+
init_modes();
|
|
26242
26512
|
VALID_TRANSPORT_MODES = /* @__PURE__ */ new Set([
|
|
26243
26513
|
"api",
|
|
26244
26514
|
"manual",
|
|
@@ -26512,7 +26782,6 @@ var init_config2 = __esm({
|
|
|
26512
26782
|
max_consecutive_blocks: 3
|
|
26513
26783
|
});
|
|
26514
26784
|
AI_TEAM_DEFAULTS = Object.freeze({
|
|
26515
|
-
enabled: false,
|
|
26516
26785
|
model: "auto",
|
|
26517
26786
|
allow_delegate: false,
|
|
26518
26787
|
max_calls_per_day: 50,
|
|
@@ -26925,8 +27194,10 @@ __export(cmd_doctor_exports, {
|
|
|
26925
27194
|
_scan_foreign: () => _scan_foreign,
|
|
26926
27195
|
_settings_layer_chain: () => _settings_layer_chain,
|
|
26927
27196
|
_skipped_manifest_check: () => _skipped_manifest_check,
|
|
27197
|
+
_team_codex_binary_name: () => _team_codex_binary_name,
|
|
26928
27198
|
_wizard_state_path: () => _wizard_state_path,
|
|
26929
|
-
main: () => main15
|
|
27199
|
+
main: () => main15,
|
|
27200
|
+
shutilWhich: () => shutilWhich
|
|
26930
27201
|
});
|
|
26931
27202
|
import * as crypto6 from "node:crypto";
|
|
26932
27203
|
import * as fs45 from "node:fs";
|
|
@@ -28343,6 +28614,13 @@ function osErrorStr2(exc) {
|
|
|
28343
28614
|
}
|
|
28344
28615
|
return String(exc);
|
|
28345
28616
|
}
|
|
28617
|
+
function _effectiveMemberMode(member, cfg) {
|
|
28618
|
+
return member.mode ?? cfg.defaults.mode;
|
|
28619
|
+
}
|
|
28620
|
+
function _mayRunOverCli(member, cfg) {
|
|
28621
|
+
const mode = _effectiveMemberMode(member, cfg);
|
|
28622
|
+
return mode === "cli" || mode === "auto";
|
|
28623
|
+
}
|
|
28346
28624
|
function _check_council_cli(project_root) {
|
|
28347
28625
|
const { load_cli_call_counts: load_cli_call_counts2 } = clients_exports;
|
|
28348
28626
|
const { load_council_config: load_council_config2, resolve_config_path: resolve_config_path2 } = config_exports;
|
|
@@ -28368,7 +28646,7 @@ function _check_council_cli(project_root) {
|
|
|
28368
28646
|
}
|
|
28369
28647
|
const cli_members = [];
|
|
28370
28648
|
for (const [name, m] of cfg.members.entries()) {
|
|
28371
|
-
if (m.enabled && m
|
|
28649
|
+
if (m.enabled && _mayRunOverCli(m, cfg) && name in _CLI_PROVIDER_META) {
|
|
28372
28650
|
cli_members.push([name, m]);
|
|
28373
28651
|
}
|
|
28374
28652
|
}
|
|
@@ -28467,18 +28745,11 @@ function _team_codex_binary_name(project_root) {
|
|
|
28467
28745
|
return default_bin;
|
|
28468
28746
|
}
|
|
28469
28747
|
const member = cfg.members.get("openai");
|
|
28470
|
-
if (member && member.enabled && member
|
|
28748
|
+
if (member && member.enabled && _mayRunOverCli(member, cfg) && member.binary) {
|
|
28471
28749
|
return member.binary;
|
|
28472
28750
|
}
|
|
28473
28751
|
return default_bin;
|
|
28474
28752
|
}
|
|
28475
|
-
function _settings_flag(val) {
|
|
28476
|
-
if (typeof val === "boolean") return val;
|
|
28477
|
-
if (typeof val === "string") {
|
|
28478
|
-
return ["true", "yes", "on", "1"].includes(val.trim().toLowerCase());
|
|
28479
|
-
}
|
|
28480
|
-
return false;
|
|
28481
|
-
}
|
|
28482
28753
|
function _jwt_exp(token) {
|
|
28483
28754
|
if (typeof token !== "string") return null;
|
|
28484
28755
|
const parts = token.split(".");
|
|
@@ -28642,31 +28913,14 @@ function _check_detection(project_root) {
|
|
|
28642
28913
|
}
|
|
28643
28914
|
function _check_team(project_root) {
|
|
28644
28915
|
const ai_team = _read_ai_team_block(project_root);
|
|
28645
|
-
const enabled = _settings_flag(ai_team["enabled"]);
|
|
28646
28916
|
const gateRaw = ai_team["review_gate"];
|
|
28647
28917
|
const gate = typeof gateRaw === "object" && gateRaw !== null && !Array.isArray(gateRaw) ? gateRaw : {};
|
|
28648
|
-
const gate_managed = _settings_flag(gate["managed"]);
|
|
28649
|
-
if (!enabled) {
|
|
28650
|
-
if (gate_managed) {
|
|
28651
|
-
return {
|
|
28652
|
-
id: "team",
|
|
28653
|
-
status: "warn",
|
|
28654
|
-
message: "half-configured: ai_team.review_gate.managed is on but ai_team.enabled is false \u2014 the gate never runs",
|
|
28655
|
-
remedy: "set `ai_team.enabled: true` in .agent-settings.yml, or remove `ai_team.review_gate.managed`"
|
|
28656
|
-
};
|
|
28657
|
-
}
|
|
28658
|
-
return {
|
|
28659
|
-
id: "team",
|
|
28660
|
-
status: "ok",
|
|
28661
|
-
message: "team mode not configured (default-off)",
|
|
28662
|
-
remedy: "opt in via `ai_team.enabled: true` in .agent-settings.yml, then re-run `agent-config doctor --check team`"
|
|
28663
|
-
};
|
|
28664
|
-
}
|
|
28665
28918
|
const remedies = [];
|
|
28666
28919
|
const binary_name = _team_codex_binary_name(project_root);
|
|
28667
28920
|
const binary_resolved = shutilWhich(binary_name);
|
|
28668
28921
|
const binary_glyph = binary_resolved !== null ? "\u2705" : "\u274C";
|
|
28669
|
-
|
|
28922
|
+
const binary_missing = binary_resolved === null;
|
|
28923
|
+
if (binary_missing) {
|
|
28670
28924
|
remedies.push("install the codex CLI: `npm install -g @openai/codex`");
|
|
28671
28925
|
}
|
|
28672
28926
|
const auth_path = path43.join(_codex_home(), "auth.json");
|
|
@@ -28707,6 +28961,14 @@ function _check_team(project_root) {
|
|
|
28707
28961
|
const gate_str = gate_signal.gate_str;
|
|
28708
28962
|
remedies.push(...gate_signal.remedies);
|
|
28709
28963
|
const detail = `codex binary ${binary_glyph} (${binary_name}) \xB7 ${auth_str} \xB7 ${plugin_str} \xB7 ${gate_str}`;
|
|
28964
|
+
if (binary_missing && !authed) {
|
|
28965
|
+
return {
|
|
28966
|
+
id: "team",
|
|
28967
|
+
status: "ok",
|
|
28968
|
+
message: `team unavailable (default) \u2014 codex CLI not installed \xB7 ${detail}`,
|
|
28969
|
+
remedy: remedies.join("; ")
|
|
28970
|
+
};
|
|
28971
|
+
}
|
|
28710
28972
|
if (remedies.length > 0) {
|
|
28711
28973
|
return {
|
|
28712
28974
|
id: "team",
|
|
@@ -28718,7 +28980,7 @@ function _check_team(project_root) {
|
|
|
28718
28980
|
return {
|
|
28719
28981
|
id: "team",
|
|
28720
28982
|
status: "ok",
|
|
28721
|
-
message: `team
|
|
28983
|
+
message: `team available \xB7 ${detail}`,
|
|
28722
28984
|
remedy: ""
|
|
28723
28985
|
};
|
|
28724
28986
|
}
|
|
@@ -29983,7 +30245,7 @@ function _check_host_manifest(projectRoot) {
|
|
|
29983
30245
|
return {
|
|
29984
30246
|
id: "host-manifest",
|
|
29985
30247
|
status: "ok",
|
|
29986
|
-
message: `no .agent-settings.yml \u2014
|
|
30248
|
+
message: `no .agent-settings.yml \u2014 host capability is always probe/registry-resolved (${detectedNote})`,
|
|
29987
30249
|
remedy: ""
|
|
29988
30250
|
};
|
|
29989
30251
|
}
|
|
@@ -30004,44 +30266,14 @@ function _check_host_manifest(projectRoot) {
|
|
|
30004
30266
|
return {
|
|
30005
30267
|
id: "host-manifest",
|
|
30006
30268
|
status: "ok",
|
|
30007
|
-
message: `no host_capabilities override \u2014
|
|
30269
|
+
message: `no host_capabilities override \u2014 host capability is always probe/registry-resolved (${detectedNote})`,
|
|
30008
30270
|
remedy: ""
|
|
30009
30271
|
};
|
|
30010
30272
|
}
|
|
30011
|
-
if (typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
30012
|
-
return {
|
|
30013
|
-
id: "host-manifest",
|
|
30014
|
-
status: "fail",
|
|
30015
|
-
message: "subagents.host_capabilities is not a mapping",
|
|
30016
|
-
remedy: "use the four boolean fields from the host-capability manifest contract"
|
|
30017
|
-
};
|
|
30018
|
-
}
|
|
30019
|
-
const problems = [];
|
|
30020
|
-
for (const [key, value] of Object.entries(manifest)) {
|
|
30021
|
-
if (!HOST_MANIFEST_KEYS.has(key)) {
|
|
30022
|
-
problems.push(`unknown key '${key}'`);
|
|
30023
|
-
continue;
|
|
30024
|
-
}
|
|
30025
|
-
if (key === "schema_version") {
|
|
30026
|
-
if (value !== 1) problems.push(`schema_version must be 1 (got ${JSON.stringify(value)})`);
|
|
30027
|
-
continue;
|
|
30028
|
-
}
|
|
30029
|
-
if (typeof value !== "boolean") {
|
|
30030
|
-
problems.push(`'${key}' must be boolean (got ${JSON.stringify(value)})`);
|
|
30031
|
-
}
|
|
30032
|
-
}
|
|
30033
|
-
if (problems.length > 0) {
|
|
30034
|
-
return {
|
|
30035
|
-
id: "host-manifest",
|
|
30036
|
-
status: "fail",
|
|
30037
|
-
message: `host_capabilities malformed: ${problems.slice(0, 4).join("; ")}`,
|
|
30038
|
-
remedy: "only schema_version:1 + four boolean capability fields are valid"
|
|
30039
|
-
};
|
|
30040
|
-
}
|
|
30041
30273
|
return {
|
|
30042
30274
|
id: "host-manifest",
|
|
30043
30275
|
status: "ok",
|
|
30044
|
-
message: `host_capabilities
|
|
30276
|
+
message: `subagents.host_capabilities is deprecated and ignored \u2014 host capability is always probe/registry-resolved (${detectedNote})`,
|
|
30045
30277
|
remedy: ""
|
|
30046
30278
|
};
|
|
30047
30279
|
}
|
|
@@ -30198,7 +30430,7 @@ function _isCliEntry16() {
|
|
|
30198
30430
|
return false;
|
|
30199
30431
|
}
|
|
30200
30432
|
}
|
|
30201
|
-
var YAML6, _HERE13, PACKAGE_ROOT2, CONFORMANCE_CHECK_IDS, THIN_STUB_MARKER,
|
|
30433
|
+
var YAML6, _HERE13, PACKAGE_ROOT2, CONFORMANCE_CHECK_IDS, THIN_STUB_MARKER, USAGE3;
|
|
30202
30434
|
var init_cmd_conformance = __esm({
|
|
30203
30435
|
"src/scripts/_cli/cmd_conformance.ts"() {
|
|
30204
30436
|
"use strict";
|
|
@@ -30220,13 +30452,6 @@ var init_cmd_conformance = __esm({
|
|
|
30220
30452
|
"host-manifest"
|
|
30221
30453
|
];
|
|
30222
30454
|
THIN_STUB_MARKER = "Routed rule \u2014 load the body on trigger-match";
|
|
30223
|
-
HOST_MANIFEST_KEYS = /* @__PURE__ */ new Set([
|
|
30224
|
-
"schema_version",
|
|
30225
|
-
"subagent_spawn",
|
|
30226
|
-
"parallel_spawn",
|
|
30227
|
-
"status_polling",
|
|
30228
|
-
"separate_quota_pool"
|
|
30229
|
-
]);
|
|
30230
30455
|
USAGE3 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher]\n";
|
|
30231
30456
|
if (_isCliEntry16() || process16.argv[1] === _HERE13) {
|
|
30232
30457
|
try {
|
|
@@ -31496,12 +31721,12 @@ function _enforceSize(text, mode) {
|
|
|
31496
31721
|
const n = _utf8Len(text);
|
|
31497
31722
|
if (n > MAX_BUNDLE_BYTES) {
|
|
31498
31723
|
throw new BundleTooLarge(
|
|
31499
|
-
`Bundle for ${
|
|
31724
|
+
`Bundle for ${_pyRepr8(mode)} mode is ${n} bytes (> ${MAX_BUNDLE_BYTES} hard ceiling). Narrow the scope (smaller diff, fewer files, shorter prompt).`
|
|
31500
31725
|
);
|
|
31501
31726
|
}
|
|
31502
31727
|
return text;
|
|
31503
31728
|
}
|
|
31504
|
-
function
|
|
31729
|
+
function _pyRepr8(s) {
|
|
31505
31730
|
const hasSingle = s.includes("'");
|
|
31506
31731
|
const hasDouble = s.includes('"');
|
|
31507
31732
|
const quote = hasSingle && !hasDouble ? '"' : "'";
|
|
@@ -31651,7 +31876,7 @@ function _pyReprStr2(s) {
|
|
|
31651
31876
|
}
|
|
31652
31877
|
return `${quote}${body}${quote}`;
|
|
31653
31878
|
}
|
|
31654
|
-
function
|
|
31879
|
+
function _pyRepr9(value) {
|
|
31655
31880
|
return value === null ? "None" : _pyReprStr2(value);
|
|
31656
31881
|
}
|
|
31657
31882
|
function _splitlines8(text) {
|
|
@@ -31683,7 +31908,7 @@ function synthesis_template(mode) {
|
|
|
31683
31908
|
Object.keys(_INPUT_MODE_TO_SYNTHESIS_KEY)
|
|
31684
31909
|
);
|
|
31685
31910
|
throw new Error(
|
|
31686
|
-
`Unknown synthesis mode ${
|
|
31911
|
+
`Unknown synthesis mode ${_pyRepr9(mode)}. Expected one of: [${expected.map((m) => _pyReprStr2(m)).join(", ")}]`
|
|
31687
31912
|
);
|
|
31688
31913
|
}
|
|
31689
31914
|
function _strip_host_identity(text) {
|
|
@@ -31733,7 +31958,7 @@ function system_prompt_for(mode, opts = {}) {
|
|
|
31733
31958
|
if (!_hasKey(_MODE_TABLE, mode)) {
|
|
31734
31959
|
const expected = Object.keys(_MODE_TABLE).sort();
|
|
31735
31960
|
throw new Error(
|
|
31736
|
-
`Unknown council mode ${
|
|
31961
|
+
`Unknown council mode ${_pyRepr9(mode)}. Expected one of: [${expected.map((m) => _pyReprStr2(m)).join(", ")}]`
|
|
31737
31962
|
);
|
|
31738
31963
|
}
|
|
31739
31964
|
const head = handoff_preamble(project, original_ask);
|
|
@@ -32413,109 +32638,30 @@ var init_solo_dispatch = __esm({
|
|
|
32413
32638
|
}
|
|
32414
32639
|
});
|
|
32415
32640
|
|
|
32416
|
-
// src/scripts/ai_council/
|
|
32417
|
-
function
|
|
32418
|
-
|
|
32419
|
-
|
|
32420
|
-
|
|
32421
|
-
if (value === null || value === void 0) {
|
|
32422
|
-
return null;
|
|
32423
|
-
}
|
|
32424
|
-
if (typeof value !== "string") {
|
|
32425
|
-
return null;
|
|
32426
|
-
}
|
|
32427
|
-
const s = value.trim().toLowerCase();
|
|
32428
|
-
return s || null;
|
|
32429
|
-
}
|
|
32430
|
-
function _validate2(mode, source) {
|
|
32431
|
-
if (mode === null) {
|
|
32432
|
-
return null;
|
|
32433
|
-
}
|
|
32434
|
-
if (!VALID_MODES.has(mode)) {
|
|
32435
|
-
throw new InvalidModeError(
|
|
32436
|
-
`${source} requested mode=${_pyRepr9(mode)}; expected one of: ${_pyReprList2(_sortedValidModes())}`
|
|
32641
|
+
// src/scripts/ai_council/quorum.ts
|
|
32642
|
+
function resolveQuorumThreshold(total, setting = "majority") {
|
|
32643
|
+
if (!Number.isInteger(total) || total < 0) {
|
|
32644
|
+
throw new RangeError(
|
|
32645
|
+
`resolveQuorumThreshold: total must be a non-negative integer (got ${total}).`
|
|
32437
32646
|
);
|
|
32438
32647
|
}
|
|
32439
|
-
|
|
32440
|
-
|
|
32441
|
-
function _pyRepr9(s) {
|
|
32442
|
-
return `'${s}'`;
|
|
32443
|
-
}
|
|
32444
|
-
function _pyReprList2(items) {
|
|
32445
|
-
return `[${items.map((i) => _pyRepr9(i)).join(", ")}]`;
|
|
32446
|
-
}
|
|
32447
|
-
function resolve_global_mode(aiBlock) {
|
|
32448
|
-
if (aiBlock === null || aiBlock === void 0) {
|
|
32449
|
-
return null;
|
|
32450
|
-
}
|
|
32451
|
-
const flat = _normalise(_settingsGet(aiBlock, "mode"));
|
|
32452
|
-
if (flat !== null) {
|
|
32453
|
-
return flat;
|
|
32454
|
-
}
|
|
32455
|
-
const defaults = _settingsGet(aiBlock, "defaults");
|
|
32456
|
-
if (defaults === null || defaults === void 0) {
|
|
32457
|
-
return null;
|
|
32458
|
-
}
|
|
32459
|
-
if (!(defaults instanceof Map) && typeof defaults !== "object") {
|
|
32460
|
-
return null;
|
|
32648
|
+
if (total === 0) {
|
|
32649
|
+
return 0;
|
|
32461
32650
|
}
|
|
32462
|
-
if (
|
|
32463
|
-
return
|
|
32651
|
+
if (setting === "majority") {
|
|
32652
|
+
return Math.ceil(total / 2);
|
|
32464
32653
|
}
|
|
32465
|
-
return
|
|
32466
|
-
_settingsGet(defaults, "mode")
|
|
32467
|
-
);
|
|
32654
|
+
return Math.min(Math.max(setting, 1), total);
|
|
32468
32655
|
}
|
|
32469
|
-
function
|
|
32470
|
-
|
|
32471
|
-
|
|
32472
|
-
|
|
32473
|
-
|
|
32474
|
-
return settings.get(key);
|
|
32475
|
-
}
|
|
32476
|
-
return settings[key];
|
|
32656
|
+
function evaluateQuorum(total, present, setting = "majority") {
|
|
32657
|
+
const threshold = resolveQuorumThreshold(total, setting);
|
|
32658
|
+
const clampedPresent = Math.min(Math.max(present, 0), total);
|
|
32659
|
+
const status3 = clampedPresent >= threshold ? "concluded" : "inconclusive";
|
|
32660
|
+
return { status: status3, threshold, total, present: clampedPresent };
|
|
32477
32661
|
}
|
|
32478
|
-
|
|
32479
|
-
|
|
32480
|
-
const memberSettings = opts.memberSettings ?? null;
|
|
32481
|
-
const globalMode = opts.globalMode ?? null;
|
|
32482
|
-
const inv = _validate2(
|
|
32483
|
-
_normalise(invocationMode),
|
|
32484
|
-
`/council mode= for ${_pyRepr9(memberName)}`
|
|
32485
|
-
);
|
|
32486
|
-
if (inv !== null) {
|
|
32487
|
-
return inv;
|
|
32488
|
-
}
|
|
32489
|
-
let memberModeRaw = null;
|
|
32490
|
-
if (memberSettings !== null) {
|
|
32491
|
-
const v = _settingsGet(memberSettings, "mode");
|
|
32492
|
-
memberModeRaw = v === void 0 ? null : v;
|
|
32493
|
-
}
|
|
32494
|
-
const member = _validate2(
|
|
32495
|
-
_normalise(memberModeRaw),
|
|
32496
|
-
`ai_council.members.${memberName}.mode`
|
|
32497
|
-
);
|
|
32498
|
-
if (member !== null) {
|
|
32499
|
-
return member;
|
|
32500
|
-
}
|
|
32501
|
-
const glob2 = _validate2(_normalise(globalMode), "ai_council.mode");
|
|
32502
|
-
if (glob2 !== null) {
|
|
32503
|
-
return glob2;
|
|
32504
|
-
}
|
|
32505
|
-
return DEFAULT_MODE;
|
|
32506
|
-
}
|
|
32507
|
-
var VALID_MODES, DEFAULT_MODE, InvalidModeError;
|
|
32508
|
-
var init_modes = __esm({
|
|
32509
|
-
"src/scripts/ai_council/modes.ts"() {
|
|
32662
|
+
var init_quorum = __esm({
|
|
32663
|
+
"src/scripts/ai_council/quorum.ts"() {
|
|
32510
32664
|
"use strict";
|
|
32511
|
-
VALID_MODES = /* @__PURE__ */ new Set(["api", "manual", "cli", "auto"]);
|
|
32512
|
-
DEFAULT_MODE = "manual";
|
|
32513
|
-
InvalidModeError = class extends Error {
|
|
32514
|
-
constructor(message) {
|
|
32515
|
-
super(message);
|
|
32516
|
-
this.name = "InvalidModeError";
|
|
32517
|
-
}
|
|
32518
|
-
};
|
|
32519
32665
|
}
|
|
32520
32666
|
});
|
|
32521
32667
|
|
|
@@ -34977,6 +35123,37 @@ One sentence, and the single strongest reason.`;
|
|
|
34977
35123
|
}
|
|
34978
35124
|
});
|
|
34979
35125
|
|
|
35126
|
+
// src/scripts/ai_council/handoff.ts
|
|
35127
|
+
function isEmptyHandoff(h) {
|
|
35128
|
+
return h.decision === null && h.rejected_alternatives === null && h.constraints === null;
|
|
35129
|
+
}
|
|
35130
|
+
function buildHandoffFromStanceTally(tally) {
|
|
35131
|
+
if (tally === null || tally.consensus === null) {
|
|
35132
|
+
return EMPTY_HANDOFF;
|
|
35133
|
+
}
|
|
35134
|
+
const winner = tally.consensus;
|
|
35135
|
+
const rejected = tally.options.filter((o) => o !== winner).map((o) => ({
|
|
35136
|
+
option: o.label,
|
|
35137
|
+
reason: `backed by ${o.backers.length} member(s), weight ${o.weight.toFixed(2)} of ${tally.threshold.toFixed(2)} needed to conclude`
|
|
35138
|
+
}));
|
|
35139
|
+
return {
|
|
35140
|
+
decision: winner.label,
|
|
35141
|
+
rejected_alternatives: rejected.length > 0 ? rejected : null,
|
|
35142
|
+
constraints: null
|
|
35143
|
+
};
|
|
35144
|
+
}
|
|
35145
|
+
var EMPTY_HANDOFF;
|
|
35146
|
+
var init_handoff = __esm({
|
|
35147
|
+
"src/scripts/ai_council/handoff.ts"() {
|
|
35148
|
+
"use strict";
|
|
35149
|
+
EMPTY_HANDOFF = {
|
|
35150
|
+
decision: null,
|
|
35151
|
+
rejected_alternatives: null,
|
|
35152
|
+
constraints: null
|
|
35153
|
+
};
|
|
35154
|
+
}
|
|
35155
|
+
});
|
|
35156
|
+
|
|
34980
35157
|
// src/scripts/ai_council/orchestrator.ts
|
|
34981
35158
|
var orchestrator_exports = {};
|
|
34982
35159
|
__export(orchestrator_exports, {
|
|
@@ -35956,11 +36133,58 @@ ${body}`;
|
|
|
35956
36133
|
blocks.push(`## Convergence / Divergence
|
|
35957
36134
|
|
|
35958
36135
|
${body}`);
|
|
36136
|
+
if (opts.handoff && !isEmptyHandoff(opts.handoff)) {
|
|
36137
|
+
blocks.push(_render_handoff(opts.handoff));
|
|
36138
|
+
}
|
|
35959
36139
|
if (blind !== null) {
|
|
35960
36140
|
blocks.push(render_deanonymization_block("### De-anonymization map", blind.label_to_source));
|
|
35961
36141
|
}
|
|
36142
|
+
if (opts.quorum) {
|
|
36143
|
+
blocks.push(_render_quorum_line(opts.quorum));
|
|
36144
|
+
}
|
|
36145
|
+
const absent = opts.absent_members ?? [];
|
|
36146
|
+
if (absent.length > 0) {
|
|
36147
|
+
blocks.push(_render_absent_members(absent));
|
|
36148
|
+
}
|
|
35962
36149
|
return blocks.join("\n\n---\n\n");
|
|
35963
36150
|
}
|
|
36151
|
+
function _render_quorum_line(q) {
|
|
36152
|
+
const verdict = q.status === "concluded" ? "concluded" : "INCONCLUSIVE \u2014 release gate holds";
|
|
36153
|
+
return `**Quorum:** ${q.present}/${q.total} present, needed ${q.threshold} \u2014 ${verdict}.`;
|
|
36154
|
+
}
|
|
36155
|
+
function _render_absent_members(absent) {
|
|
36156
|
+
const lines = ["### Absent Members", ""];
|
|
36157
|
+
for (const a of absent) {
|
|
36158
|
+
const tag = a.reason !== null ? ` (${a.reason})` : "";
|
|
36159
|
+
lines.push(`- **${a.member}**${tag} \u2014 ${a.detail}`);
|
|
36160
|
+
}
|
|
36161
|
+
return lines.join("\n");
|
|
36162
|
+
}
|
|
36163
|
+
function _render_handoff(h) {
|
|
36164
|
+
const lines = ["### Handoff", ""];
|
|
36165
|
+
lines.push(`**Decision:** ${h.decision ?? "none recorded \u2014 no structured verdict this pass."}`);
|
|
36166
|
+
lines.push("");
|
|
36167
|
+
if (h.rejected_alternatives !== null && h.rejected_alternatives.length > 0) {
|
|
36168
|
+
lines.push("**Rejected alternatives:**");
|
|
36169
|
+
lines.push("");
|
|
36170
|
+
for (const alt of h.rejected_alternatives) {
|
|
36171
|
+
lines.push(`- **${alt.option}** \u2014 ${alt.reason}`);
|
|
36172
|
+
}
|
|
36173
|
+
} else {
|
|
36174
|
+
lines.push("**Rejected alternatives:** none recorded.");
|
|
36175
|
+
}
|
|
36176
|
+
lines.push("");
|
|
36177
|
+
if (h.constraints !== null && h.constraints.length > 0) {
|
|
36178
|
+
lines.push("**Constraints:**");
|
|
36179
|
+
lines.push("");
|
|
36180
|
+
for (const c of h.constraints) {
|
|
36181
|
+
lines.push(`- ${c}`);
|
|
36182
|
+
}
|
|
36183
|
+
} else {
|
|
36184
|
+
lines.push("**Constraints:** none recorded.");
|
|
36185
|
+
}
|
|
36186
|
+
return lines.join("\n");
|
|
36187
|
+
}
|
|
35964
36188
|
function _render_peer_review(peer_review) {
|
|
35965
36189
|
const lines = ["## Peer-Review (Karpathy)"];
|
|
35966
36190
|
let label_idx = 0;
|
|
@@ -36085,6 +36309,7 @@ var init_orchestrator = __esm({
|
|
|
36085
36309
|
init_debate_gates();
|
|
36086
36310
|
init_stance_tally();
|
|
36087
36311
|
init_blind_review();
|
|
36312
|
+
init_handoff();
|
|
36088
36313
|
CostBudget = class {
|
|
36089
36314
|
max_input_tokens;
|
|
36090
36315
|
max_output_tokens;
|
|
@@ -37669,6 +37894,7 @@ __export(council_cli_exports, {
|
|
|
37669
37894
|
CouncilDisabledError: () => CouncilDisabledError,
|
|
37670
37895
|
_parse_model_overrides: () => _parse_model_overrides,
|
|
37671
37896
|
_parse_siblings_overrides: () => _parse_siblings_overrides,
|
|
37897
|
+
_postRunQuorum: () => _postRunQuorum,
|
|
37672
37898
|
_synthesize_ai_council_block: () => _synthesize_ai_council_block,
|
|
37673
37899
|
build_members: () => build_members,
|
|
37674
37900
|
build_question: () => build_question,
|
|
@@ -37679,6 +37905,7 @@ __export(council_cli_exports, {
|
|
|
37679
37905
|
cmd_replay: () => cmd_replay,
|
|
37680
37906
|
cmd_run: () => cmd_run,
|
|
37681
37907
|
cmd_shadow_report: () => cmd_shadow_report,
|
|
37908
|
+
cmd_status: () => cmd_status,
|
|
37682
37909
|
format_estimate_table: () => format_estimate_table,
|
|
37683
37910
|
load_settings: () => load_settings,
|
|
37684
37911
|
main: () => main17
|
|
@@ -37969,6 +38196,13 @@ function _synthesize_ai_council_block(cfg) {
|
|
|
37969
38196
|
max_calls_per_day: _mapToObject(cfg.cli_call_budget.max_calls_per_day),
|
|
37970
38197
|
warn_at: cfg.cli_call_budget.warn_at
|
|
37971
38198
|
},
|
|
38199
|
+
// Phase 3.3 (road-to-always-on-orchestration): was validated by
|
|
38200
|
+
// `_build_config`/`_build_quorum` but never forwarded into the
|
|
38201
|
+
// synthesized block, so `build_members` always saw `undefined` and
|
|
38202
|
+
// silently fell back to `'majority'` regardless of the user's
|
|
38203
|
+
// configured `quorum: <k>`. Additive key — callers that never read
|
|
38204
|
+
// it observe no change.
|
|
38205
|
+
quorum: cfg.quorum,
|
|
37972
38206
|
necessity_classifier: {
|
|
37973
38207
|
enabled: cfg.necessity_classifier.enabled,
|
|
37974
38208
|
mode: cfg.necessity_classifier.mode,
|
|
@@ -38007,15 +38241,63 @@ function _mapToObject(m) {
|
|
|
38007
38241
|
}
|
|
38008
38242
|
return out;
|
|
38009
38243
|
}
|
|
38244
|
+
function _member_api_key_present(cfg) {
|
|
38245
|
+
const ref = cfg["api_key_ref"];
|
|
38246
|
+
if (typeof ref !== "string" || ref.trim() === "") {
|
|
38247
|
+
return void 0;
|
|
38248
|
+
}
|
|
38249
|
+
try {
|
|
38250
|
+
resolve_api_key(ref);
|
|
38251
|
+
return true;
|
|
38252
|
+
} catch {
|
|
38253
|
+
return false;
|
|
38254
|
+
}
|
|
38255
|
+
}
|
|
38256
|
+
function _quorum_setting_from(ai) {
|
|
38257
|
+
const raw = ai["quorum"];
|
|
38258
|
+
if (raw === "majority") {
|
|
38259
|
+
return "majority";
|
|
38260
|
+
}
|
|
38261
|
+
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 1) {
|
|
38262
|
+
return raw;
|
|
38263
|
+
}
|
|
38264
|
+
return "majority";
|
|
38265
|
+
}
|
|
38266
|
+
function _postRunQuorum(members, responses, ai_cfg) {
|
|
38267
|
+
const absent = [];
|
|
38268
|
+
let present = 0;
|
|
38269
|
+
for (let i = 0; i < members.length; i++) {
|
|
38270
|
+
const m = members[i];
|
|
38271
|
+
const r = responses[i];
|
|
38272
|
+
if (r !== void 0 && !r.error) {
|
|
38273
|
+
present += 1;
|
|
38274
|
+
continue;
|
|
38275
|
+
}
|
|
38276
|
+
const raw = r?.error ?? "no response";
|
|
38277
|
+
const failure = classifyCliFailure(raw);
|
|
38278
|
+
absent.push({
|
|
38279
|
+
member: m.name,
|
|
38280
|
+
reason: absentReasonFromCliFailure(failure) ?? "unavailable",
|
|
38281
|
+
detail: raw
|
|
38282
|
+
});
|
|
38283
|
+
}
|
|
38284
|
+
return { quorum: evaluateQuorum(members.length, present, _quorum_setting_from(ai_cfg)), absent };
|
|
38285
|
+
}
|
|
38286
|
+
function _format_quorum_line(q) {
|
|
38287
|
+
const verdict = q.status === "concluded" ? "concluded" : "INCONCLUSIVE \u2014 release gate holds";
|
|
38288
|
+
return `council:quorum \xB7 ${q.present}/${q.total} present, needed ${q.threshold} \u2014 ${verdict}.`;
|
|
38289
|
+
}
|
|
38010
38290
|
function build_members(settings, opts = {}) {
|
|
38011
38291
|
const invocation_mode = opts.invocation_mode ?? null;
|
|
38012
38292
|
const model_overrides = opts.model_overrides ?? null;
|
|
38013
38293
|
const siblings_overrides = opts.siblings_overrides ?? null;
|
|
38014
38294
|
const skipped = opts.skipped ?? null;
|
|
38295
|
+
const quorum_out = opts.quorum_out ?? null;
|
|
38296
|
+
const report2 = opts.environment_report ?? detectEnvironment();
|
|
38015
38297
|
const ai = _isDict3(settings) ? settings["ai_council"] || {} : {};
|
|
38016
38298
|
if (!_pyBool2(ai["enabled"])) {
|
|
38017
38299
|
throw new CouncilDisabledError(
|
|
38018
|
-
|
|
38300
|
+
`enabled is false in the council config (${COUNCIL_CONFIG_USER_GLOBAL_REL} under the user-global agent-config root) \u2014 flip it on before invoking council:* commands. This config is NEVER project-local (ADR-104), so do not look for it, or create it, in the project tree. \`agent-config council:status\` prints the resolved path.`
|
|
38019
38301
|
);
|
|
38020
38302
|
}
|
|
38021
38303
|
const members_cfg = ai["members"] || {};
|
|
@@ -38045,25 +38327,36 @@ function build_members(settings, opts = {}) {
|
|
|
38045
38327
|
);
|
|
38046
38328
|
}
|
|
38047
38329
|
const members = [];
|
|
38330
|
+
let total_enabled = 0;
|
|
38331
|
+
let absent_count = 0;
|
|
38048
38332
|
for (const name of Object.keys(members_cfg)) {
|
|
38049
38333
|
const cfg = members_cfg[name] || {};
|
|
38050
38334
|
if (!_pyBool2(cfg["enabled"])) {
|
|
38051
38335
|
if (name in siblings) {
|
|
38052
38336
|
throw new CouncilDisabledError(
|
|
38053
|
-
`--siblings targets member ${_pyReprStr5(name)} but it is not enabled in
|
|
38337
|
+
`--siblings targets member ${_pyReprStr5(name)} but it is not enabled in the council config (members.${name}.enabled in ${COUNCIL_CONFIG_USER_GLOBAL_REL} under the user-global root).`
|
|
38054
38338
|
);
|
|
38055
38339
|
}
|
|
38056
38340
|
continue;
|
|
38057
38341
|
}
|
|
38058
|
-
|
|
38342
|
+
total_enabled += 1;
|
|
38343
|
+
const api_key_present = _member_api_key_present(cfg);
|
|
38344
|
+
const resolved = resolveMemberTransport({
|
|
38345
|
+
provider: name,
|
|
38346
|
+
report: report2,
|
|
38059
38347
|
invocationMode: invocation_mode,
|
|
38060
38348
|
memberSettings: cfg,
|
|
38061
|
-
globalMode: global_mode ?? null
|
|
38349
|
+
globalMode: global_mode ?? null,
|
|
38350
|
+
binaryOverride: cfg["binary"] ?? null,
|
|
38351
|
+
// `exactOptionalPropertyTypes` rejects an explicit `undefined` —
|
|
38352
|
+
// see `resolveMemberTransport`'s own forwarding call for the
|
|
38353
|
+
// same pattern.
|
|
38354
|
+
...api_key_present !== void 0 ? { apiKeyPresent: api_key_present } : {}
|
|
38062
38355
|
});
|
|
38063
38356
|
if (name in siblings) {
|
|
38064
|
-
if (
|
|
38357
|
+
if (resolved.transport !== "api") {
|
|
38065
38358
|
throw new CouncilDisabledError(
|
|
38066
|
-
`--siblings requires mode=api for member ${_pyReprStr5(name)} (
|
|
38359
|
+
`--siblings requires mode=api for member ${_pyReprStr5(name)} (configured mode=${_pyReprStr5(resolved.configuredMode)}, resolved transport=${_pyReprStr5(resolved.transport ?? "none")}).`
|
|
38067
38360
|
);
|
|
38068
38361
|
}
|
|
38069
38362
|
const api_key_ref = cfg["api_key_ref"] ?? null;
|
|
@@ -38080,19 +38373,49 @@ function build_members(settings, opts = {}) {
|
|
|
38080
38373
|
}
|
|
38081
38374
|
continue;
|
|
38082
38375
|
}
|
|
38376
|
+
if (resolved.transport === null) {
|
|
38377
|
+
const detail = resolved.reason ?? `member ${name} has no available transport`;
|
|
38378
|
+
const entry = {
|
|
38379
|
+
member: name,
|
|
38380
|
+
reason: resolved.absentReason ?? "unavailable",
|
|
38381
|
+
detail
|
|
38382
|
+
};
|
|
38383
|
+
absent_count += 1;
|
|
38384
|
+
if (skipped !== null) {
|
|
38385
|
+
skipped.push(entry);
|
|
38386
|
+
}
|
|
38387
|
+
_stderr2(`[council] SKIP ${name}: ${detail}
|
|
38388
|
+
`);
|
|
38389
|
+
continue;
|
|
38390
|
+
}
|
|
38083
38391
|
const model = overrides[name] || cfg["model"] || null;
|
|
38084
|
-
if (
|
|
38085
|
-
|
|
38086
|
-
|
|
38087
|
-
|
|
38088
|
-
|
|
38089
|
-
|
|
38090
|
-
|
|
38091
|
-
|
|
38092
|
-
|
|
38093
|
-
|
|
38094
|
-
|
|
38095
|
-
|
|
38392
|
+
if (resolved.transport === "api" && _API_PROVIDERS.has(name)) {
|
|
38393
|
+
try {
|
|
38394
|
+
members.push(
|
|
38395
|
+
_construct_api_member(name, model, {
|
|
38396
|
+
api_key_ref: cfg["api_key_ref"] ?? null,
|
|
38397
|
+
// Council opts in explicitly (client-default OFF); on unless
|
|
38398
|
+
// the operator sets `prompt_cache: false`.
|
|
38399
|
+
enable_prompt_cache: cfg["prompt_cache"] !== false,
|
|
38400
|
+
// road-to-cache-economy Phase 4 — see the siblings branch above.
|
|
38401
|
+
prompt_cache_ttl: cfg["prompt_cache_ttl"] ?? void 0
|
|
38402
|
+
})
|
|
38403
|
+
);
|
|
38404
|
+
} catch (exc) {
|
|
38405
|
+
if (!(exc instanceof CouncilDisabledError)) {
|
|
38406
|
+
throw exc;
|
|
38407
|
+
}
|
|
38408
|
+
const detail = exc.message;
|
|
38409
|
+
const entry = { member: name, reason: "no_auth", detail };
|
|
38410
|
+
absent_count += 1;
|
|
38411
|
+
if (skipped !== null) {
|
|
38412
|
+
skipped.push(entry);
|
|
38413
|
+
}
|
|
38414
|
+
_stderr2(`[council] SKIP ${name}: ${detail}
|
|
38415
|
+
`);
|
|
38416
|
+
continue;
|
|
38417
|
+
}
|
|
38418
|
+
} else if (resolved.transport === "cli" && _CLI_PROVIDERS.has(name)) {
|
|
38096
38419
|
try {
|
|
38097
38420
|
members.push(
|
|
38098
38421
|
_construct_cli_member(name, model, {
|
|
@@ -38112,6 +38435,7 @@ function build_members(settings, opts = {}) {
|
|
|
38112
38435
|
reason: "binary_missing",
|
|
38113
38436
|
detail
|
|
38114
38437
|
};
|
|
38438
|
+
absent_count += 1;
|
|
38115
38439
|
if (skipped !== null) {
|
|
38116
38440
|
skipped.push(entry);
|
|
38117
38441
|
}
|
|
@@ -38119,22 +38443,22 @@ function build_members(settings, opts = {}) {
|
|
|
38119
38443
|
`);
|
|
38120
38444
|
continue;
|
|
38121
38445
|
}
|
|
38122
|
-
} else if (
|
|
38446
|
+
} else if (resolved.transport === "cli") {
|
|
38123
38447
|
throw new CouncilDisabledError(
|
|
38124
38448
|
`member ${_pyReprStr5(name)} resolves to mode=cli but no CLI client is wired (known: ${_pyReprStrList(_pySortedStr(_CLI_PROVIDERS))}).`
|
|
38125
38449
|
);
|
|
38126
|
-
} else if (
|
|
38450
|
+
} else if (resolved.transport === "manual") {
|
|
38127
38451
|
members.push(new ManualClient({ name, model: model || "manual" }));
|
|
38128
|
-
} else if (mode === "playwright") {
|
|
38129
|
-
throw new CouncilDisabledError(
|
|
38130
|
-
`member ${_pyReprStr5(name)} resolves to mode=playwright (Phase 2c, not wired).`
|
|
38131
|
-
);
|
|
38132
38452
|
} else {
|
|
38133
38453
|
throw new CouncilDisabledError(
|
|
38134
|
-
`member ${_pyReprStr5(name)} has no transport \u2014 mode=${
|
|
38454
|
+
`member ${_pyReprStr5(name)} has no transport \u2014 resolved=${_pyReprStr5(resolved.transport)}, configured mode=${_pyReprStr5(resolved.configuredMode)}, name not in ${_pyReprStrList(_pySortedStr(_API_PROVIDERS))}.`
|
|
38135
38455
|
);
|
|
38136
38456
|
}
|
|
38137
38457
|
}
|
|
38458
|
+
if (quorum_out !== null) {
|
|
38459
|
+
const present = total_enabled - absent_count;
|
|
38460
|
+
quorum_out.result = evaluateQuorum(total_enabled, present, _quorum_setting_from(ai));
|
|
38461
|
+
}
|
|
38138
38462
|
if (members.length === 0) {
|
|
38139
38463
|
if (skipped && skipped.length > 0) {
|
|
38140
38464
|
const names = skipped.map((s) => String(s["member"])).join(", ");
|
|
@@ -38143,7 +38467,7 @@ function build_members(settings, opts = {}) {
|
|
|
38143
38467
|
);
|
|
38144
38468
|
}
|
|
38145
38469
|
throw new CouncilDisabledError(
|
|
38146
|
-
|
|
38470
|
+
`no council member has \`enabled: true\` \u2014 enable at least one under members.* in ${COUNCIL_CONFIG_USER_GLOBAL_REL} (user-global root; never the project tree, ADR-104). \`agent-config council:status\` prints the resolved path.`
|
|
38147
38471
|
);
|
|
38148
38472
|
}
|
|
38149
38473
|
return members;
|
|
@@ -38571,6 +38895,59 @@ function _objToMap(o) {
|
|
|
38571
38895
|
}
|
|
38572
38896
|
return m;
|
|
38573
38897
|
}
|
|
38898
|
+
function _deserialise_handoff(data) {
|
|
38899
|
+
if (!_isDict3(data)) {
|
|
38900
|
+
return null;
|
|
38901
|
+
}
|
|
38902
|
+
const d = data;
|
|
38903
|
+
const decision = typeof d["decision"] === "string" ? d["decision"] : null;
|
|
38904
|
+
const rawAlts = d["rejected_alternatives"];
|
|
38905
|
+
const alts = Array.isArray(rawAlts) ? rawAlts.filter(
|
|
38906
|
+
(a) => _isDict3(a) && typeof a["option"] === "string" && typeof a["reason"] === "string"
|
|
38907
|
+
).map((a) => ({ option: a["option"], reason: a["reason"] })) : [];
|
|
38908
|
+
const rawConstraints = d["constraints"];
|
|
38909
|
+
const constraints = Array.isArray(rawConstraints) ? rawConstraints.filter((c) => typeof c === "string") : [];
|
|
38910
|
+
return {
|
|
38911
|
+
decision,
|
|
38912
|
+
rejected_alternatives: alts.length > 0 ? alts : null,
|
|
38913
|
+
constraints: constraints.length > 0 ? constraints : null
|
|
38914
|
+
};
|
|
38915
|
+
}
|
|
38916
|
+
function _deserialise_absent_members(data) {
|
|
38917
|
+
if (!Array.isArray(data)) {
|
|
38918
|
+
return null;
|
|
38919
|
+
}
|
|
38920
|
+
const out = [];
|
|
38921
|
+
for (const entry of data) {
|
|
38922
|
+
if (!_isDict3(entry)) {
|
|
38923
|
+
continue;
|
|
38924
|
+
}
|
|
38925
|
+
const d = entry;
|
|
38926
|
+
const member = d["member"];
|
|
38927
|
+
const detail = d["detail"];
|
|
38928
|
+
if (typeof member !== "string" || typeof detail !== "string") {
|
|
38929
|
+
continue;
|
|
38930
|
+
}
|
|
38931
|
+
const raw = d["reason"];
|
|
38932
|
+
const reason = typeof raw === "string" && _VALID_ABSENT_REASONS.has(raw) ? raw : null;
|
|
38933
|
+
out.push({ member, reason, detail });
|
|
38934
|
+
}
|
|
38935
|
+
return out.length > 0 ? out : null;
|
|
38936
|
+
}
|
|
38937
|
+
function _deserialise_quorum(data) {
|
|
38938
|
+
if (!_isDict3(data)) {
|
|
38939
|
+
return null;
|
|
38940
|
+
}
|
|
38941
|
+
const d = data;
|
|
38942
|
+
const status3 = d["status"];
|
|
38943
|
+
const threshold = d["threshold"];
|
|
38944
|
+
const total = d["total"];
|
|
38945
|
+
const present = d["present"];
|
|
38946
|
+
if (status3 !== "concluded" && status3 !== "inconclusive" || typeof threshold !== "number" || typeof total !== "number" || typeof present !== "number") {
|
|
38947
|
+
return null;
|
|
38948
|
+
}
|
|
38949
|
+
return { status: status3, threshold, total, present };
|
|
38950
|
+
}
|
|
38574
38951
|
function _resolve_rounds(args, ai_cfg) {
|
|
38575
38952
|
if (_getattr3(args, "rounds", null) !== null) {
|
|
38576
38953
|
return _pyInt6(args.rounds);
|
|
@@ -38608,12 +38985,14 @@ function cmd_estimate(args, opts = {}) {
|
|
|
38608
38985
|
const advisor_plans = _build_advisor_plans(ai_cfg, REPO_ROOT3);
|
|
38609
38986
|
const explicit_overrides = _parse_model_overrides(_getattr3(args, "model", null));
|
|
38610
38987
|
const skipped = [];
|
|
38988
|
+
const quorum_out = { result: null };
|
|
38611
38989
|
if (members === null) {
|
|
38612
38990
|
members = build_members(settings, {
|
|
38613
38991
|
invocation_mode: args.mode_override,
|
|
38614
38992
|
model_overrides: _advisor_model_overrides(advisor_plans, explicit_overrides),
|
|
38615
38993
|
siblings_overrides: _parse_siblings_overrides(_getattr3(args, "siblings", null)),
|
|
38616
|
-
skipped
|
|
38994
|
+
skipped,
|
|
38995
|
+
quorum_out
|
|
38617
38996
|
});
|
|
38618
38997
|
}
|
|
38619
38998
|
if (table === null) {
|
|
@@ -38649,6 +39028,9 @@ function cmd_estimate(args, opts = {}) {
|
|
|
38649
39028
|
if (skipped.length > 0) {
|
|
38650
39029
|
_stdout2(format_install_hints(skipped) + "\n");
|
|
38651
39030
|
}
|
|
39031
|
+
if (quorum_out.result !== null) {
|
|
39032
|
+
_stdout2(_format_quorum_line(quorum_out.result) + "\n");
|
|
39033
|
+
}
|
|
38652
39034
|
_stdout2(
|
|
38653
39035
|
format_estimate_table(billable, estimates, {
|
|
38654
39036
|
consensus_delta_usd: extra_usd,
|
|
@@ -39027,6 +39409,75 @@ function _emit_shadow_slo_banner() {
|
|
|
39027
39409
|
return;
|
|
39028
39410
|
}
|
|
39029
39411
|
}
|
|
39412
|
+
function cmd_status(args, opts = {}) {
|
|
39413
|
+
const env = opts.env ?? process.env;
|
|
39414
|
+
const override = env[COUNCIL_CONFIG_ENV];
|
|
39415
|
+
const path_ = resolve_config_path(REPO_ROOT3, { env });
|
|
39416
|
+
const exists3 = fs56.existsSync(String(path_));
|
|
39417
|
+
const provenance = override ? `${COUNCIL_CONFIG_ENV} override` : "user-global";
|
|
39418
|
+
let cfg = null;
|
|
39419
|
+
let parse_error = null;
|
|
39420
|
+
if (exists3) {
|
|
39421
|
+
try {
|
|
39422
|
+
cfg = load_council_config(path_);
|
|
39423
|
+
} catch (exc) {
|
|
39424
|
+
parse_error = exc instanceof Error ? exc.message : String(exc);
|
|
39425
|
+
}
|
|
39426
|
+
}
|
|
39427
|
+
const enabledMembers = cfg === null ? [] : [...cfg.members.entries()].filter(([, m]) => m.enabled);
|
|
39428
|
+
const configured = cfg !== null && cfg.enabled && enabledMembers.length > 0;
|
|
39429
|
+
if (_getattr3(args, "json", false)) {
|
|
39430
|
+
_stdout2(
|
|
39431
|
+
`${JSON.stringify({
|
|
39432
|
+
configured,
|
|
39433
|
+
path: String(path_),
|
|
39434
|
+
exists: exists3,
|
|
39435
|
+
provenance,
|
|
39436
|
+
enabled: cfg?.enabled ?? null,
|
|
39437
|
+
members_total: cfg === null ? null : cfg.members.size,
|
|
39438
|
+
members_enabled: cfg === null ? null : enabledMembers.length,
|
|
39439
|
+
member_names: enabledMembers.map(([n]) => n),
|
|
39440
|
+
parse_error,
|
|
39441
|
+
project_tree_consulted: false
|
|
39442
|
+
})}
|
|
39443
|
+
`
|
|
39444
|
+
);
|
|
39445
|
+
return 0;
|
|
39446
|
+
}
|
|
39447
|
+
_stdout2(`council:status \xB7 ${configured ? "CONFIGURED" : "NOT CONFIGURED"}
|
|
39448
|
+
`);
|
|
39449
|
+
_stdout2(` config path ${String(path_)}
|
|
39450
|
+
`);
|
|
39451
|
+
_stdout2(` resolved by ${provenance}
|
|
39452
|
+
`);
|
|
39453
|
+
_stdout2(` file exists ${exists3 ? "yes" : "no"}
|
|
39454
|
+
`);
|
|
39455
|
+
if (parse_error !== null) {
|
|
39456
|
+
_stdout2(` parse error ${parse_error}
|
|
39457
|
+
`);
|
|
39458
|
+
}
|
|
39459
|
+
if (cfg !== null) {
|
|
39460
|
+
_stdout2(` enabled ${cfg.enabled ? "yes" : "no"}
|
|
39461
|
+
`);
|
|
39462
|
+
_stdout2(` members ${enabledMembers.length} enabled of ${cfg.members.size}
|
|
39463
|
+
`);
|
|
39464
|
+
if (enabledMembers.length > 0) {
|
|
39465
|
+
_stdout2(` ${enabledMembers.map(([n]) => n).join(", ")}
|
|
39466
|
+
`);
|
|
39467
|
+
}
|
|
39468
|
+
}
|
|
39469
|
+
_stdout2("\n");
|
|
39470
|
+
_stdout2(" The project tree is NEVER consulted (ADR-104). No project file \u2014\n");
|
|
39471
|
+
_stdout2(" `.agent-settings.yml` included \u2014 indicates council availability in\n");
|
|
39472
|
+
_stdout2(" either direction. Do not infer it from one; run this instead.\n");
|
|
39473
|
+
if (!configured) {
|
|
39474
|
+
_stdout2(`
|
|
39475
|
+
To configure: write ${COUNCIL_CONFIG_USER_GLOBAL_REL} under the user-global
|
|
39476
|
+
`);
|
|
39477
|
+
_stdout2(" agent-config root, with `enabled: true` and at least one enabled member.\n");
|
|
39478
|
+
}
|
|
39479
|
+
return 0;
|
|
39480
|
+
}
|
|
39030
39481
|
function _apply_solo_dispatch(members) {
|
|
39031
39482
|
let cfg;
|
|
39032
39483
|
try {
|
|
@@ -39087,12 +39538,14 @@ function cmd_run(args, opts = {}) {
|
|
|
39087
39538
|
const advisor_plans = _build_advisor_plans(ai_cfg, REPO_ROOT3);
|
|
39088
39539
|
const explicit_overrides = _parse_model_overrides(_getattr3(args, "model", null));
|
|
39089
39540
|
const skipped = [];
|
|
39541
|
+
const quorum_out = { result: null };
|
|
39090
39542
|
if (members === null) {
|
|
39091
39543
|
members = build_members(settings, {
|
|
39092
39544
|
invocation_mode: args.mode_override,
|
|
39093
39545
|
model_overrides: _advisor_model_overrides(advisor_plans, explicit_overrides),
|
|
39094
39546
|
siblings_overrides: _parse_siblings_overrides(_getattr3(args, "siblings", null)),
|
|
39095
|
-
skipped
|
|
39547
|
+
skipped,
|
|
39548
|
+
quorum_out
|
|
39096
39549
|
});
|
|
39097
39550
|
}
|
|
39098
39551
|
if (_getattr3(args, "single", false)) {
|
|
@@ -39152,6 +39605,9 @@ function cmd_run(args, opts = {}) {
|
|
|
39152
39605
|
if (skipped.length > 0) {
|
|
39153
39606
|
_stdout2(format_install_hints(skipped) + "\n");
|
|
39154
39607
|
}
|
|
39608
|
+
if (quorum_out.result !== null) {
|
|
39609
|
+
_stdout2(_format_quorum_line(quorum_out.result) + "\n");
|
|
39610
|
+
}
|
|
39155
39611
|
_stdout2(
|
|
39156
39612
|
format_estimate_table(billable, estimates, {
|
|
39157
39613
|
consensus_delta_usd: extra_usd,
|
|
@@ -39226,6 +39682,14 @@ function cmd_run(args, opts = {}) {
|
|
|
39226
39682
|
stance_repairs.push(r);
|
|
39227
39683
|
}
|
|
39228
39684
|
});
|
|
39685
|
+
const post_run = _postRunQuorum(members, responses, ai_cfg);
|
|
39686
|
+
quorum_out.result = post_run.quorum;
|
|
39687
|
+
skipped.push(...post_run.absent);
|
|
39688
|
+
const handoff = buildHandoffFromStanceTally(
|
|
39689
|
+
stance_tally_on ? tally_stances(
|
|
39690
|
+
responses.filter((r) => !r.error).map((r) => ({ member: `${r.provider}:${r.model}`, text: r.text }))
|
|
39691
|
+
) : null
|
|
39692
|
+
);
|
|
39229
39693
|
const persona_labels = build_persona_labels(advisor_plans, billable);
|
|
39230
39694
|
const peer_review = _maybe_run_peer_review(
|
|
39231
39695
|
ai_cfg,
|
|
@@ -39300,6 +39764,13 @@ function cmd_run(args, opts = {}) {
|
|
|
39300
39764
|
if (blind_review_map !== null) {
|
|
39301
39765
|
payload["blind_review_map"] = _mapToObject(blind_review_map);
|
|
39302
39766
|
}
|
|
39767
|
+
if (quorum_out.result !== null) {
|
|
39768
|
+
payload["quorum"] = quorum_out.result;
|
|
39769
|
+
}
|
|
39770
|
+
if (skipped.length > 0) {
|
|
39771
|
+
payload["absent_members"] = skipped;
|
|
39772
|
+
}
|
|
39773
|
+
payload["handoff"] = handoff;
|
|
39303
39774
|
const out_path = _validate_council_output_path(args.output, {
|
|
39304
39775
|
kind: "responses",
|
|
39305
39776
|
subcommand: "run"
|
|
@@ -39653,7 +40124,10 @@ function cmd_render(args) {
|
|
|
39653
40124
|
stance_tally: payload["stance_tally"] === true,
|
|
39654
40125
|
chairman_fields: payload["chairman_fields"] === true,
|
|
39655
40126
|
blind: _isDict3(blind_map_raw) ? { label_to_source: _objToMap(blind_map_raw) } : null,
|
|
39656
|
-
chairman: _isDict3(payload["chairman"]) ? payload["chairman"] : null
|
|
40127
|
+
chairman: _isDict3(payload["chairman"]) ? payload["chairman"] : null,
|
|
40128
|
+
handoff: _deserialise_handoff(payload["handoff"]),
|
|
40129
|
+
absent_members: _deserialise_absent_members(payload["absent_members"]),
|
|
40130
|
+
quorum: _deserialise_quorum(payload["quorum"])
|
|
39657
40131
|
});
|
|
39658
40132
|
if (_getattr3(args, "output", null)) {
|
|
39659
40133
|
const out_path = _validate_council_output_path(args.output, {
|
|
@@ -39862,7 +40336,8 @@ function _defaultArgs() {
|
|
|
39862
40336
|
low_impact_stats: false,
|
|
39863
40337
|
reset: null,
|
|
39864
40338
|
log: null,
|
|
39865
|
-
window_days: 7
|
|
40339
|
+
window_days: 7,
|
|
40340
|
+
json: false
|
|
39866
40341
|
};
|
|
39867
40342
|
}
|
|
39868
40343
|
function _usageFor(cmd) {
|
|
@@ -39979,6 +40454,12 @@ function _specsFor(cmd) {
|
|
|
39979
40454
|
],
|
|
39980
40455
|
requiredOpts: []
|
|
39981
40456
|
};
|
|
40457
|
+
case "status":
|
|
40458
|
+
return {
|
|
40459
|
+
positionals: [],
|
|
40460
|
+
opts: [{ flag: "--json", takesValue: false, apply: (o) => o.json = true }],
|
|
40461
|
+
requiredOpts: []
|
|
40462
|
+
};
|
|
39982
40463
|
default:
|
|
39983
40464
|
return { positionals: [], opts: [], requiredOpts: [] };
|
|
39984
40465
|
}
|
|
@@ -40152,6 +40633,9 @@ function main17(argv = null) {
|
|
|
40152
40633
|
if (args.cmd === "shadow-report") {
|
|
40153
40634
|
return cmd_shadow_report(args);
|
|
40154
40635
|
}
|
|
40636
|
+
if (args.cmd === "status") {
|
|
40637
|
+
return cmd_status(args);
|
|
40638
|
+
}
|
|
40155
40639
|
} catch (exc) {
|
|
40156
40640
|
if (exc instanceof CouncilDisabledError) {
|
|
40157
40641
|
_stderr2(`\u274C council:${args.cmd}: ${exc.message}
|
|
@@ -40183,12 +40667,13 @@ function _isCliEntry17() {
|
|
|
40183
40667
|
return false;
|
|
40184
40668
|
}
|
|
40185
40669
|
}
|
|
40186
|
-
var _ArgExit2, ArgumentTypeError, _PROG9, SCHEMA_VERSION8, _API_PROVIDERS, _CLI_PROVIDERS, _HERE15, REPO_ROOT3, SETTINGS_FILE2, AI_COUNCIL_FILE, COUNCIL_CANONICAL_DIRS, CouncilDisabledError, _CLI_FACTORY, ValueError4, FileNotFoundError3, _SUBCOMMANDS, _TOP_USAGE2;
|
|
40670
|
+
var _ArgExit2, ArgumentTypeError, _PROG9, SCHEMA_VERSION8, _API_PROVIDERS, _CLI_PROVIDERS, _HERE15, REPO_ROOT3, SETTINGS_FILE2, AI_COUNCIL_FILE, COUNCIL_CANONICAL_DIRS, CouncilDisabledError, _CLI_FACTORY, ValueError4, _VALID_ABSENT_REASONS, FileNotFoundError3, _SUBCOMMANDS, _TOP_USAGE2;
|
|
40187
40671
|
var init_council_cli = __esm({
|
|
40188
40672
|
"src/scripts/council_cli.ts"() {
|
|
40189
40673
|
"use strict";
|
|
40190
40674
|
init_agent_settings();
|
|
40191
40675
|
init_agent_settings();
|
|
40676
|
+
init_environment_detector();
|
|
40192
40677
|
init_bundler();
|
|
40193
40678
|
init_chairman();
|
|
40194
40679
|
init_text_similarity();
|
|
@@ -40199,6 +40684,9 @@ var init_council_cli = __esm({
|
|
|
40199
40684
|
init_config();
|
|
40200
40685
|
init_solo_dispatch();
|
|
40201
40686
|
init_modes();
|
|
40687
|
+
init_transport_resolver();
|
|
40688
|
+
init_transport_resolver();
|
|
40689
|
+
init_quorum();
|
|
40202
40690
|
init_events_log();
|
|
40203
40691
|
init_necessity();
|
|
40204
40692
|
init_orchestrator();
|
|
@@ -40209,6 +40697,8 @@ var init_council_cli = __esm({
|
|
|
40209
40697
|
init_shadow_dispatch();
|
|
40210
40698
|
init_low_impact();
|
|
40211
40699
|
init_blind_review();
|
|
40700
|
+
init_stance_tally();
|
|
40701
|
+
init_handoff();
|
|
40212
40702
|
_ArgExit2 = class extends Error {
|
|
40213
40703
|
};
|
|
40214
40704
|
ArgumentTypeError = class extends Error {
|
|
@@ -40249,11 +40739,17 @@ var init_council_cli = __esm({
|
|
|
40249
40739
|
};
|
|
40250
40740
|
ValueError4 = class extends Error {
|
|
40251
40741
|
};
|
|
40742
|
+
_VALID_ABSENT_REASONS = /* @__PURE__ */ new Set([
|
|
40743
|
+
"no_binary",
|
|
40744
|
+
"no_auth",
|
|
40745
|
+
"timeout",
|
|
40746
|
+
"quota"
|
|
40747
|
+
]);
|
|
40252
40748
|
FileNotFoundError3 = class extends Error {
|
|
40253
40749
|
};
|
|
40254
|
-
_SUBCOMMANDS = ["estimate", "run", "debate", "render", "replay", "quota", "shadow-report"];
|
|
40750
|
+
_SUBCOMMANDS = ["estimate", "run", "debate", "render", "replay", "quota", "shadow-report", "status"];
|
|
40255
40751
|
_TOP_USAGE2 = `usage: ${_PROG9} [-h]
|
|
40256
|
-
{estimate,run,debate,render,replay,quota,shadow-report}
|
|
40752
|
+
{estimate,run,debate,render,replay,quota,shadow-report,status}
|
|
40257
40753
|
...
|
|
40258
40754
|
`;
|
|
40259
40755
|
if (_isCliEntry17()) {
|