ofiere-openclaw-plugin 4.43.0 → 4.45.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofiere-openclaw-plugin",
3
- "version": "4.43.0",
3
+ "version": "4.45.0",
4
4
  "type": "module",
5
5
  "description": "OpenClaw plugin for Ofiere PM - 16 meta-tools covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, constellation, space file management, execution plan builder, SOP management, agent brain, talent management, and corporate frameworks",
6
6
  "keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
@@ -15,7 +15,7 @@ import {
15
15
  invalidateAgentTier,
16
16
  } from "./agent-tier.js";
17
17
  import { issueAttachmentToken, verifyAttachmentToken } from "./attach-token.js";
18
- import { loadSubagentRow, buildStaffPersonaBlock, readDispatchSubagentId, type SubagentRow } from "./staffPersona.js";
18
+ import { loadSubagentRow, buildStaffPersonaBlock, readDispatchSubagentId, loadChiefStaffDefaults, resolveStaffModels, type SubagentRow } from "./staffPersona.js";
19
19
 
20
20
  interface ToolResult {
21
21
  content: Array<{ type: "text"; text: string }>;
@@ -433,9 +433,11 @@ export function registerAttachmentContextHook(args: {
433
433
  if (subagentId) {
434
434
  staffRow = await loadSubagentRow(supabase, userId, subagentId);
435
435
  if (staffRow && staffRow.chief_agent_id === resolvedAgentId) {
436
- staffPrefix = buildStaffPersonaBlock(staffRow) + "\n\n---\n\n";
436
+ const chiefDefaults = await loadChiefStaffDefaults(supabase, userId, staffRow.chief_agent_id).catch(() => null);
437
+ const resolved = resolveStaffModels(staffRow, chiefDefaults);
438
+ staffPrefix = buildStaffPersonaBlock(staffRow, resolved) + "\n\n---\n\n";
437
439
  api.logger?.debug?.(
438
- `[ofiere-staff] subagent ${subagentId} (${staffRow.name}) reporting to ${resolvedAgentId} — persona injected`,
440
+ `[ofiere-staff] subagent ${subagentId} (${staffRow.name}) reporting to ${resolvedAgentId} — persona injected; resolved models: ${JSON.stringify(resolved)}`,
439
441
  );
440
442
  } else if (staffRow) {
441
443
  api.logger?.warn?.(
@@ -16,6 +16,8 @@ export interface SubagentRow {
16
16
  function_call_model: string | null;
17
17
  vision_model: string | null;
18
18
  mcp_server_ids: string[] | null;
19
+ attached_sop_ids: string[] | null;
20
+ attached_framework_ids: string[] | null;
19
21
  }
20
22
 
21
23
  export async function loadSubagentRow(
@@ -26,7 +28,7 @@ export async function loadSubagentRow(
26
28
  const { data, error } = await supabase
27
29
  .from("agent_subagents")
28
30
  .select(
29
- "id, chief_agent_id, name, role, codename, system_prompt, mission, responsibilities, instructions, primary_model, coding_model, tool_call_model, function_call_model, vision_model, mcp_server_ids",
31
+ "id, chief_agent_id, name, role, codename, system_prompt, mission, responsibilities, instructions, primary_model, coding_model, tool_call_model, function_call_model, vision_model, mcp_server_ids, attached_sop_ids, attached_framework_ids",
30
32
  )
31
33
  .eq("user_id", userId)
32
34
  .eq("id", subagentId)
@@ -57,7 +59,105 @@ export function readDispatchSubagentId(ctx: any, event?: any): string | null {
57
59
  return null;
58
60
  }
59
61
 
60
- export function buildStaffPersonaBlock(staff: SubagentRow): string {
62
+ export type StaffModelSlot =
63
+ | "primary_model"
64
+ | "coding_model"
65
+ | "tool_call_model"
66
+ | "function_call_model"
67
+ | "vision_model";
68
+
69
+ export interface ChiefStaffDefaultsRow {
70
+ chief_agent_id: string;
71
+ primary_model: string | null;
72
+ coding_model: string | null;
73
+ tool_call_model: string | null;
74
+ function_call_model: string | null;
75
+ vision_model: string | null;
76
+ }
77
+
78
+ export interface ResolvedStaffModels {
79
+ primary_model: string | null;
80
+ coding_model: string | null;
81
+ tool_call_model: string | null;
82
+ function_call_model: string | null;
83
+ vision_model: string | null;
84
+ source: Record<StaffModelSlot, "staff" | "chief_default" | "chief_fallback" | null>;
85
+ }
86
+
87
+ const SLOTS: StaffModelSlot[] = [
88
+ "primary_model",
89
+ "coding_model",
90
+ "tool_call_model",
91
+ "function_call_model",
92
+ "vision_model",
93
+ ];
94
+
95
+ export async function loadChiefStaffDefaults(
96
+ supabase: SupabaseClient,
97
+ userId: string,
98
+ chiefAgentId: string,
99
+ ): Promise<ChiefStaffDefaultsRow | null> {
100
+ const { data, error } = await supabase
101
+ .from("chief_staff_defaults")
102
+ .select(
103
+ "chief_agent_id, primary_model, coding_model, tool_call_model, function_call_model, vision_model",
104
+ )
105
+ .eq("user_id", userId)
106
+ .eq("chief_agent_id", chiefAgentId)
107
+ .maybeSingle();
108
+ if (error || !data) return null;
109
+ return data as ChiefStaffDefaultsRow;
110
+ }
111
+
112
+ /**
113
+ * Resolution chain at delegate_to_staff time:
114
+ * staff.<slot> (per-staff override on agent_subagents)
115
+ * ?? chief_staff_defaults.<slot> (chief-level "STAFF MODEL")
116
+ * ?? null (caller falls back to the chief's own model — that lookup
117
+ * happens in the OpenClaw runtime, not here).
118
+ *
119
+ * The chief's own model is intentionally not touched. Empty staff slot +
120
+ * empty chief STAFF MODEL = inherit chief's primary_model (gateway default).
121
+ */
122
+ export function resolveStaffModels(
123
+ staff: SubagentRow,
124
+ chiefDefaults: ChiefStaffDefaultsRow | null,
125
+ ): ResolvedStaffModels {
126
+ const out: ResolvedStaffModels = {
127
+ primary_model: null,
128
+ coding_model: null,
129
+ tool_call_model: null,
130
+ function_call_model: null,
131
+ vision_model: null,
132
+ source: {
133
+ primary_model: null,
134
+ coding_model: null,
135
+ tool_call_model: null,
136
+ function_call_model: null,
137
+ vision_model: null,
138
+ },
139
+ };
140
+ for (const slot of SLOTS) {
141
+ const staffVal = (staff as any)[slot] as string | null | undefined;
142
+ const chiefVal = chiefDefaults ? (chiefDefaults as any)[slot] as string | null | undefined : null;
143
+ if (staffVal && staffVal.trim()) {
144
+ out[slot] = staffVal;
145
+ out.source[slot] = "staff";
146
+ } else if (chiefVal && chiefVal.trim()) {
147
+ out[slot] = chiefVal;
148
+ out.source[slot] = "chief_default";
149
+ } else {
150
+ out[slot] = null;
151
+ out.source[slot] = "chief_fallback";
152
+ }
153
+ }
154
+ return out;
155
+ }
156
+
157
+ export function buildStaffPersonaBlock(
158
+ staff: SubagentRow,
159
+ resolved?: ResolvedStaffModels,
160
+ ): string {
61
161
  const lines: string[] = [];
62
162
  lines.push(`# STAFF IDENTITY`);
63
163
  lines.push(
@@ -78,5 +178,18 @@ export function buildStaffPersonaBlock(staff: SubagentRow): string {
78
178
  if (staff.instructions?.trim()) {
79
179
  lines.push(``, `## Operating Instructions`, staff.instructions.trim());
80
180
  }
181
+ if (resolved && (resolved.primary_model || resolved.coding_model || resolved.tool_call_model || resolved.function_call_model || resolved.vision_model)) {
182
+ const sourceLabel = (s: "staff" | "chief_default" | "chief_fallback" | null) =>
183
+ s === "staff" ? "per-staff override" : s === "chief_default" ? "chief STAFF MODEL" : "inherits chief";
184
+ const rows: string[] = [];
185
+ if (resolved.primary_model) rows.push(`- primary: \`${resolved.primary_model}\` (${sourceLabel(resolved.source.primary_model)})`);
186
+ if (resolved.coding_model) rows.push(`- coding: \`${resolved.coding_model}\` (${sourceLabel(resolved.source.coding_model)})`);
187
+ if (resolved.tool_call_model) rows.push(`- tool_call: \`${resolved.tool_call_model}\` (${sourceLabel(resolved.source.tool_call_model)})`);
188
+ if (resolved.function_call_model) rows.push(`- function_call: \`${resolved.function_call_model}\` (${sourceLabel(resolved.source.function_call_model)})`);
189
+ if (resolved.vision_model) rows.push(`- vision: \`${resolved.vision_model}\` (${sourceLabel(resolved.source.vision_model)})`);
190
+ if (rows.length) {
191
+ lines.push(``, `## Configured Models`, ...rows);
192
+ }
193
+ }
81
194
  return lines.join("\n");
82
195
  }