@songsid/agend 2.0.11-beta.16 → 2.0.11-beta.18

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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared config validation for fleet.yaml and classicBot.yaml.
3
+ *
4
+ * Pure functions with no fleet-manager / filesystem dependencies so both the
5
+ * CLI (`agend validate`) and the Settings API can import them. `errors` block a
6
+ * write (they break the fleet); `warnings` are advisory (write is allowed).
7
+ */
8
+ export interface ValidationIssue {
9
+ path: string;
10
+ message: string;
11
+ }
12
+ export interface ValidationResult {
13
+ valid: boolean;
14
+ errors: ValidationIssue[];
15
+ warnings: ValidationIssue[];
16
+ }
17
+ /** Backends the factory can instantiate (keep in sync with backend/factory.ts). */
18
+ export declare const KNOWN_BACKENDS: string[];
19
+ export declare function validateFleetConfig(config: unknown): ValidationResult;
20
+ export declare function validateClassicBotConfig(config: unknown): ValidationResult;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Shared config validation for fleet.yaml and classicBot.yaml.
3
+ *
4
+ * Pure functions with no fleet-manager / filesystem dependencies so both the
5
+ * CLI (`agend validate`) and the Settings API can import them. `errors` block a
6
+ * write (they break the fleet); `warnings` are advisory (write is allowed).
7
+ */
8
+ /** Backends the factory can instantiate (keep in sync with backend/factory.ts). */
9
+ export const KNOWN_BACKENDS = ["claude-code", "gemini-cli", "codex", "opencode", "kiro-cli", "antigravity", "mock"];
10
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
11
+ /** Every value is a non-empty string or a number (Telegram/Discord ids). */
12
+ function isIdArray(v) {
13
+ return Array.isArray(v) && v.every(x => (typeof x === "string" && x.length > 0) || typeof x === "number");
14
+ }
15
+ /** The adapter id used to bind instances: explicit `id`, else `type`. */
16
+ function channelIdOf(ch) {
17
+ const id = ch.id ?? ch.type;
18
+ return typeof id === "string" && id ? id : undefined;
19
+ }
20
+ export function validateFleetConfig(config) {
21
+ const errors = [];
22
+ const warnings = [];
23
+ const err = (path, message) => errors.push({ path, message });
24
+ const warn = (path, message) => warnings.push({ path, message });
25
+ if (!isObj(config)) {
26
+ return { valid: false, errors: [{ path: "", message: "config must be a mapping" }], warnings: [] };
27
+ }
28
+ // ── Channels ──────────────────────────────────────────────
29
+ // Accept either `channels: []` (multi) or a single `channel:`.
30
+ const channelList = [];
31
+ if (Array.isArray(config.channels)) {
32
+ config.channels.forEach((ch, i) => {
33
+ if (!isObj(ch)) {
34
+ err(`channels[${i}]`, "must be a mapping");
35
+ return;
36
+ }
37
+ channelList.push(ch);
38
+ });
39
+ }
40
+ else if (config.channels !== undefined) {
41
+ err("channels", "must be a list");
42
+ }
43
+ if (isObj(config.channel))
44
+ channelList.push(config.channel);
45
+ else if (config.channel !== undefined)
46
+ err("channel", "must be a mapping");
47
+ if (channelList.length === 0) {
48
+ warn("channels", "no channel configured — the fleet has no Telegram/Discord adapter");
49
+ }
50
+ const channelIds = new Set();
51
+ const multi = channelList.length > 1;
52
+ channelList.forEach((ch, i) => {
53
+ const at = Array.isArray(config.channels) && i < config.channels.length ? `channels[${i}]` : "channel";
54
+ if (typeof ch.type !== "string" || !ch.type)
55
+ err(`${at}.type`, "required (e.g. \"telegram\" or \"discord\")");
56
+ if (typeof ch.bot_token_env !== "string" || !ch.bot_token_env)
57
+ err(`${at}.bot_token_env`, "required — the env var holding the bot token");
58
+ // With multiple channels an explicit id is needed to disambiguate bindings.
59
+ if (multi && (ch.id === undefined || ch.id === null || ch.id === "")) {
60
+ warn(`${at}.id`, "multiple channels present — set a unique `id` so instances can bind to this adapter");
61
+ }
62
+ const cid = channelIdOf(ch);
63
+ if (cid) {
64
+ if (channelIds.has(cid))
65
+ err(`${at}.id`, `duplicate channel id "${cid}"`);
66
+ channelIds.add(cid);
67
+ }
68
+ if (isObj(ch.access) && ch.access.allowed_users !== undefined && !isIdArray(ch.access.allowed_users)) {
69
+ err(`${at}.access.allowed_users`, "must be an array of strings/numbers");
70
+ }
71
+ });
72
+ // ── Defaults ──────────────────────────────────────────────
73
+ if (config.defaults !== undefined && !isObj(config.defaults)) {
74
+ err("defaults", "must be a mapping");
75
+ }
76
+ else if (isObj(config.defaults)) {
77
+ const b = config.defaults.backend;
78
+ if (b !== undefined && (typeof b !== "string" || !KNOWN_BACKENDS.includes(b))) {
79
+ err("defaults.backend", `unknown backend "${String(b)}" (known: ${KNOWN_BACKENDS.join(", ")})`);
80
+ }
81
+ }
82
+ // ── Instances ─────────────────────────────────────────────
83
+ let generalCount = 0;
84
+ if (config.instances !== undefined && !isObj(config.instances)) {
85
+ err("instances", "must be a mapping");
86
+ }
87
+ else if (isObj(config.instances)) {
88
+ for (const [name, inst] of Object.entries(config.instances)) {
89
+ if (!isObj(inst)) {
90
+ err(`instances.${name}`, "must be a mapping");
91
+ continue;
92
+ }
93
+ if (inst.general_topic === true)
94
+ generalCount++;
95
+ // channel_id must reference a real channel id.
96
+ if (inst.channel_id !== undefined && inst.channel_id !== null && inst.channel_id !== "") {
97
+ const ref = String(inst.channel_id);
98
+ if (!channelIds.has(ref)) {
99
+ err(`instances.${name}.channel_id`, `references unknown channel "${ref}" (known: ${[...channelIds].join(", ") || "none"})`);
100
+ }
101
+ }
102
+ const b = inst.backend;
103
+ if (b !== undefined && (typeof b !== "string" || !KNOWN_BACKENDS.includes(b))) {
104
+ err(`instances.${name}.backend`, `unknown backend "${String(b)}" (known: ${KNOWN_BACKENDS.join(", ")})`);
105
+ }
106
+ if (inst.working_directory !== undefined && typeof inst.working_directory !== "string") {
107
+ err(`instances.${name}.working_directory`, "must be a string path");
108
+ }
109
+ }
110
+ }
111
+ if (generalCount === 0) {
112
+ warn("instances", "no general_topic instance — there is no general dispatcher to receive un-topic'd messages");
113
+ }
114
+ return { valid: errors.length === 0, errors, warnings };
115
+ }
116
+ export function validateClassicBotConfig(config) {
117
+ const errors = [];
118
+ const warnings = [];
119
+ const err = (path, message) => errors.push({ path, message });
120
+ // An empty / absent classicBot.yaml is valid (classic bot is optional).
121
+ if (config === null || config === undefined)
122
+ return { valid: true, errors, warnings };
123
+ if (!isObj(config)) {
124
+ return { valid: false, errors: [{ path: "", message: "config must be a mapping" }], warnings: [] };
125
+ }
126
+ if (config.defaults !== undefined && !isObj(config.defaults)) {
127
+ err("defaults", "must be a mapping");
128
+ }
129
+ else if (isObj(config.defaults)) {
130
+ const d = config.defaults;
131
+ const b = d.backend;
132
+ if (b !== undefined && (typeof b !== "string" || !KNOWN_BACKENDS.includes(b))) {
133
+ err("defaults.backend", `unknown backend "${String(b)}" (known: ${KNOWN_BACKENDS.join(", ")})`);
134
+ }
135
+ for (const key of ["allowed_guilds", "admin_users", "allowed_groups", "allowed_users"]) {
136
+ if (d[key] !== undefined && !isIdArray(d[key])) {
137
+ err(`defaults.${key}`, "must be an array of strings/numbers");
138
+ }
139
+ }
140
+ }
141
+ if (config.channels !== undefined && !isObj(config.channels)) {
142
+ err("channels", "must be a mapping (keyed by channelId or channelId#adapterId)");
143
+ }
144
+ return { valid: errors.length === 0, errors, warnings };
145
+ }
146
+ //# sourceMappingURL=config-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-validator.js","sourceRoot":"","sources":["../src/config-validator.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,7 @@ import { StatuslineWatcher } from "./statusline-watcher.js";
34
34
  import { outboundHandlers } from "./outbound-handlers.js";
35
35
  import { handleWebRequest, broadcastSseEvent } from "./web-api.js";
36
36
  import { handleViewRequest, isViewPath } from "./view-api.js";
37
+ import { handleSettingsRequest } from "./settings-api.js";
37
38
  import { handleAgentRequest } from "./agent-endpoint.js";
38
39
  import { ClassicChannelManager } from "./classic-channel-manager.js";
39
40
  import { getTmuxSession } from "./config.js";
@@ -516,8 +517,9 @@ export class FleetManager {
516
517
  // Rotate classic channel chat logs daily (piggyback on daily summary timer)
517
518
  this.classicChannels?.rotateLogs();
518
519
  this.rotateInboxes();
519
- // Auto-create general instance(s)one per adapter that lacks a general
520
+ // Auto-create/adopt a general dispatcherONLY for the primary adapter.
520
521
  const channelConfigs = fleet.channels ?? (fleet.channel ? [fleet.channel] : []);
522
+ const primaryAdapterId = channelConfigs[0] ? (channelConfigs[0].id ?? channelConfigs[0].type) : undefined;
521
523
  const generalInstances = Object.entries(fleet.instances).filter(([, inst]) => inst.general_topic === true);
522
524
  let generalsCreated = false;
523
525
  // Collect unbound generals (no channel_id set) for auto-assignment
@@ -526,6 +528,14 @@ export class FleetManager {
526
528
  const needsGeneral = [];
527
529
  for (const ch of channelConfigs) {
528
530
  const adapterId = ch.id ?? ch.type;
531
+ // Only the primary adapter gets an auto-general. Secondary (persona) bots
532
+ // answer for their explicitly-bound instances only — they don't need or
533
+ // auto-claim a general dispatcher, and must never adopt the primary's
534
+ // unbound general. A general a user manually bound to a secondary
535
+ // (channel_id: <persona>) is left untouched — the auto logic just won't
536
+ // create or reassign bindings for non-primary adapters.
537
+ if (adapterId !== primaryAdapterId)
538
+ continue;
529
539
  // Check if any general is explicitly bound to this adapter
530
540
  if (generalInstances.some(([, inst]) => inst.channel_id === adapterId))
531
541
  continue;
@@ -4279,6 +4289,8 @@ When users create specialized instances, suggest these configurations:
4279
4289
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
4280
4290
  if (handleViewRequest(req, res, url, this))
4281
4291
  return;
4292
+ if (handleSettingsRequest(req, res, url, this))
4293
+ return;
4282
4294
  if (handleWebRequest(req, res, url, this))
4283
4295
  return;
4284
4296
  res.writeHead(404);