ofiere-openclaw-plugin 4.54.2 → 4.55.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/README.md +104 -104
- package/dist/src/prompt.js +130 -130
- package/dist/src/staffPersona.js +3 -1
- package/dist/src/tools.js +111 -0
- package/index.ts +105 -105
- package/package.json +12 -2
- package/src/agent-resolver.ts +90 -90
- package/src/agent-tier.ts +192 -192
- package/src/attach-token.ts +106 -106
- package/src/attachments.ts +601 -601
- package/src/cli.ts +247 -247
- package/src/config.ts +78 -78
- package/src/prompt.ts +267 -267
- package/src/sop-render.ts +216 -216
- package/src/staffPersona.ts +299 -289
- package/src/supabase.ts +13 -13
- package/src/tools.ts +112 -0
- package/src/types/openclaw.d.ts +8 -8
- package/src/types.ts +10 -10
package/src/staffPersona.ts
CHANGED
|
@@ -1,289 +1,299 @@
|
|
|
1
|
-
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
-
|
|
3
|
-
export interface SubagentRow {
|
|
4
|
-
id: string;
|
|
5
|
-
chief_agent_id: string;
|
|
6
|
-
name: string;
|
|
7
|
-
role: string | null;
|
|
8
|
-
codename: string | null;
|
|
9
|
-
system_prompt: string | null;
|
|
10
|
-
mission: string | null;
|
|
11
|
-
responsibilities: string | null;
|
|
12
|
-
instructions: string | null;
|
|
13
|
-
primary_model: string | null;
|
|
14
|
-
coding_model: string | null;
|
|
15
|
-
tool_call_model: string | null;
|
|
16
|
-
function_call_model: string | null;
|
|
17
|
-
vision_model: string | null;
|
|
18
|
-
mcp_server_ids: string[] | null;
|
|
19
|
-
attached_sop_ids: string[] | null;
|
|
20
|
-
attached_framework_ids: string[] | null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function loadSubagentRow(
|
|
24
|
-
supabase: SupabaseClient,
|
|
25
|
-
userId: string,
|
|
26
|
-
subagentId: string,
|
|
27
|
-
): Promise<SubagentRow | null> {
|
|
28
|
-
const { data, error } = await supabase
|
|
29
|
-
.from("agent_subagents")
|
|
30
|
-
.select(
|
|
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",
|
|
32
|
-
)
|
|
33
|
-
.eq("user_id", userId)
|
|
34
|
-
.eq("id", subagentId)
|
|
35
|
-
.maybeSingle();
|
|
36
|
-
if (error || !data) return null;
|
|
37
|
-
return data as SubagentRow;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Cycle 7b — pluck subagent_id from dispatch metadata only. Plain user chats
|
|
41
|
-
// must NOT trigger the staff persona swap or report emission, so we deliberately
|
|
42
|
-
// do not consult ctx.subagentId / ctx.subagent_id at the top level.
|
|
43
|
-
export function readDispatchSubagentId(ctx: any, event?: any): string | null {
|
|
44
|
-
const candidates: Array<unknown> = [
|
|
45
|
-
ctx?.metadata?.subagent_id,
|
|
46
|
-
ctx?.metadata?.dispatch?.subagent_id,
|
|
47
|
-
ctx?.params?.metadata?.subagent_id,
|
|
48
|
-
ctx?.payload?.metadata?.subagent_id,
|
|
49
|
-
ctx?.request?.metadata?.subagent_id,
|
|
50
|
-
ctx?.options?.metadata?.subagent_id,
|
|
51
|
-
ctx?.attachments?.subagent_id,
|
|
52
|
-
ctx?.dispatch?.subagent_id,
|
|
53
|
-
event?.metadata?.subagent_id,
|
|
54
|
-
event?.context?.metadata?.subagent_id,
|
|
55
|
-
];
|
|
56
|
-
for (const c of candidates) {
|
|
57
|
-
if (typeof c === "string" && c.length) return c;
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Cycle 7b BUGSHOOT-1 (BUG 2) — DB-backed dispatch context fallback.
|
|
63
|
-
// OpenClaw gateway core rejects unknown root key `metadata` on chat.send, so
|
|
64
|
-
// the task-dispatcher edge function can't ride dispatch metadata through the
|
|
65
|
-
// wire. The dispatcher writes a row to public.dispatch_context keyed by
|
|
66
|
-
// (user_id, session_key) before chat.send fires; this loader reads it back
|
|
67
|
-
// during before_prompt_build when the metadata path comes up empty.
|
|
68
|
-
//
|
|
69
|
-
// Returns the dispatch context for the most recent matching row, or null if
|
|
70
|
-
// none exists. The metadata path is preferred so a future gateway upgrade
|
|
71
|
-
// that natively accepts metadata keeps working with no flag day.
|
|
72
|
-
export interface DispatchContextRow {
|
|
73
|
-
subagent_id: string | null;
|
|
74
|
-
attached_sop_ids: string[];
|
|
75
|
-
attached_framework_ids: string[];
|
|
76
|
-
task_id: string | null;
|
|
77
|
-
conversation_id: string | null;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
:
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
out[slot] =
|
|
239
|
-
out.source[slot] = "
|
|
240
|
-
} else {
|
|
241
|
-
out[slot] =
|
|
242
|
-
out.source[slot] = "
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
|
|
3
|
+
export interface SubagentRow {
|
|
4
|
+
id: string;
|
|
5
|
+
chief_agent_id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
role: string | null;
|
|
8
|
+
codename: string | null;
|
|
9
|
+
system_prompt: string | null;
|
|
10
|
+
mission: string | null;
|
|
11
|
+
responsibilities: string | null;
|
|
12
|
+
instructions: string | null;
|
|
13
|
+
primary_model: string | null;
|
|
14
|
+
coding_model: string | null;
|
|
15
|
+
tool_call_model: string | null;
|
|
16
|
+
function_call_model: string | null;
|
|
17
|
+
vision_model: string | null;
|
|
18
|
+
mcp_server_ids: string[] | null;
|
|
19
|
+
attached_sop_ids: string[] | null;
|
|
20
|
+
attached_framework_ids: string[] | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function loadSubagentRow(
|
|
24
|
+
supabase: SupabaseClient,
|
|
25
|
+
userId: string,
|
|
26
|
+
subagentId: string,
|
|
27
|
+
): Promise<SubagentRow | null> {
|
|
28
|
+
const { data, error } = await supabase
|
|
29
|
+
.from("agent_subagents")
|
|
30
|
+
.select(
|
|
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",
|
|
32
|
+
)
|
|
33
|
+
.eq("user_id", userId)
|
|
34
|
+
.eq("id", subagentId)
|
|
35
|
+
.maybeSingle();
|
|
36
|
+
if (error || !data) return null;
|
|
37
|
+
return data as SubagentRow;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Cycle 7b — pluck subagent_id from dispatch metadata only. Plain user chats
|
|
41
|
+
// must NOT trigger the staff persona swap or report emission, so we deliberately
|
|
42
|
+
// do not consult ctx.subagentId / ctx.subagent_id at the top level.
|
|
43
|
+
export function readDispatchSubagentId(ctx: any, event?: any): string | null {
|
|
44
|
+
const candidates: Array<unknown> = [
|
|
45
|
+
ctx?.metadata?.subagent_id,
|
|
46
|
+
ctx?.metadata?.dispatch?.subagent_id,
|
|
47
|
+
ctx?.params?.metadata?.subagent_id,
|
|
48
|
+
ctx?.payload?.metadata?.subagent_id,
|
|
49
|
+
ctx?.request?.metadata?.subagent_id,
|
|
50
|
+
ctx?.options?.metadata?.subagent_id,
|
|
51
|
+
ctx?.attachments?.subagent_id,
|
|
52
|
+
ctx?.dispatch?.subagent_id,
|
|
53
|
+
event?.metadata?.subagent_id,
|
|
54
|
+
event?.context?.metadata?.subagent_id,
|
|
55
|
+
];
|
|
56
|
+
for (const c of candidates) {
|
|
57
|
+
if (typeof c === "string" && c.length) return c;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Cycle 7b BUGSHOOT-1 (BUG 2) — DB-backed dispatch context fallback.
|
|
63
|
+
// OpenClaw gateway core rejects unknown root key `metadata` on chat.send, so
|
|
64
|
+
// the task-dispatcher edge function can't ride dispatch metadata through the
|
|
65
|
+
// wire. The dispatcher writes a row to public.dispatch_context keyed by
|
|
66
|
+
// (user_id, session_key) before chat.send fires; this loader reads it back
|
|
67
|
+
// during before_prompt_build when the metadata path comes up empty.
|
|
68
|
+
//
|
|
69
|
+
// Returns the dispatch context for the most recent matching row, or null if
|
|
70
|
+
// none exists. The metadata path is preferred so a future gateway upgrade
|
|
71
|
+
// that natively accepts metadata keeps working with no flag day.
|
|
72
|
+
export interface DispatchContextRow {
|
|
73
|
+
subagent_id: string | null;
|
|
74
|
+
attached_sop_ids: string[];
|
|
75
|
+
attached_framework_ids: string[];
|
|
76
|
+
task_id: string | null;
|
|
77
|
+
conversation_id: string | null;
|
|
78
|
+
// FIX-A2A-LATE-REPLY: source_agent_id + a2a_pair_id are set ONLY for direct
|
|
79
|
+
// chief↔chief A2A relays. When both are present and subagent_id + task_id
|
|
80
|
+
// are null, the agent_end hook in tools.ts routes the run as an A2A late
|
|
81
|
+
// reply (insert into conversation_messages + POST chief_reply webhook).
|
|
82
|
+
source_agent_id: string | null;
|
|
83
|
+
a2a_pair_id: string | null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function loadDispatchContextBySession(
|
|
87
|
+
supabase: SupabaseClient,
|
|
88
|
+
userId: string,
|
|
89
|
+
sessionKey: string,
|
|
90
|
+
): Promise<DispatchContextRow | null> {
|
|
91
|
+
if (!sessionKey) return null;
|
|
92
|
+
const { data, error } = await supabase
|
|
93
|
+
.from("dispatch_context")
|
|
94
|
+
.select(
|
|
95
|
+
"subagent_id, attached_sop_ids, attached_framework_ids, task_id, conversation_id, source_agent_id, a2a_pair_id",
|
|
96
|
+
)
|
|
97
|
+
.eq("user_id", userId)
|
|
98
|
+
.eq("session_key", sessionKey)
|
|
99
|
+
.order("created_at", { ascending: false })
|
|
100
|
+
.limit(1)
|
|
101
|
+
.maybeSingle();
|
|
102
|
+
if (error || !data) return null;
|
|
103
|
+
return {
|
|
104
|
+
subagent_id: (data.subagent_id as string | null) ?? null,
|
|
105
|
+
attached_sop_ids: Array.isArray(data.attached_sop_ids)
|
|
106
|
+
? (data.attached_sop_ids as unknown[]).filter((x): x is string => typeof x === "string")
|
|
107
|
+
: [],
|
|
108
|
+
attached_framework_ids: Array.isArray(data.attached_framework_ids)
|
|
109
|
+
? (data.attached_framework_ids as unknown[]).filter((x): x is string => typeof x === "string")
|
|
110
|
+
: [],
|
|
111
|
+
task_id: (data.task_id as string | null) ?? null,
|
|
112
|
+
conversation_id: (data.conversation_id as string | null) ?? null,
|
|
113
|
+
source_agent_id: (data.source_agent_id as string | null) ?? null,
|
|
114
|
+
a2a_pair_id: (data.a2a_pair_id as string | null) ?? null,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type StaffModelSlot =
|
|
119
|
+
| "primary_model"
|
|
120
|
+
| "coding_model"
|
|
121
|
+
| "tool_call_model"
|
|
122
|
+
| "function_call_model"
|
|
123
|
+
| "vision_model";
|
|
124
|
+
|
|
125
|
+
export interface ChiefStaffDefaultsRow {
|
|
126
|
+
chief_agent_id: string;
|
|
127
|
+
primary_model: string | null;
|
|
128
|
+
coding_model: string | null;
|
|
129
|
+
tool_call_model: string | null;
|
|
130
|
+
function_call_model: string | null;
|
|
131
|
+
vision_model: string | null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface ResolvedStaffModels {
|
|
135
|
+
primary_model: string | null;
|
|
136
|
+
coding_model: string | null;
|
|
137
|
+
tool_call_model: string | null;
|
|
138
|
+
function_call_model: string | null;
|
|
139
|
+
vision_model: string | null;
|
|
140
|
+
source: Record<StaffModelSlot, "staff" | "chief_default" | "chief_primary" | "chief_fallback" | null>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const SLOTS: StaffModelSlot[] = [
|
|
144
|
+
"primary_model",
|
|
145
|
+
"coding_model",
|
|
146
|
+
"tool_call_model",
|
|
147
|
+
"function_call_model",
|
|
148
|
+
"vision_model",
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
// Cycle 7b BUGSHOOT-3 — chief's own ofie_agent_config row, used as the third
|
|
152
|
+
// fallback tier when neither the staff slot nor the chief STAFF MODEL slot is
|
|
153
|
+
// set. Mirrors the dispatcher's loadStaffPrimaryModel chain.
|
|
154
|
+
export interface ChiefAgentConfigRow {
|
|
155
|
+
agent_id: string;
|
|
156
|
+
primary_model: string | null;
|
|
157
|
+
coding_model: string | null;
|
|
158
|
+
tool_call_model: string | null;
|
|
159
|
+
vision_model: string | null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function loadChiefStaffDefaults(
|
|
163
|
+
supabase: SupabaseClient,
|
|
164
|
+
userId: string,
|
|
165
|
+
chiefAgentId: string,
|
|
166
|
+
): Promise<ChiefStaffDefaultsRow | null> {
|
|
167
|
+
const { data, error } = await supabase
|
|
168
|
+
.from("chief_staff_defaults")
|
|
169
|
+
.select(
|
|
170
|
+
"chief_agent_id, primary_model, coding_model, tool_call_model, function_call_model, vision_model",
|
|
171
|
+
)
|
|
172
|
+
.eq("user_id", userId)
|
|
173
|
+
.eq("chief_agent_id", chiefAgentId)
|
|
174
|
+
.maybeSingle();
|
|
175
|
+
if (error || !data) return null;
|
|
176
|
+
return data as ChiefStaffDefaultsRow;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function loadChiefAgentConfig(
|
|
180
|
+
supabase: SupabaseClient,
|
|
181
|
+
userId: string,
|
|
182
|
+
chiefAgentId: string,
|
|
183
|
+
): Promise<ChiefAgentConfigRow | null> {
|
|
184
|
+
const { data, error } = await supabase
|
|
185
|
+
.from("ofie_agent_config")
|
|
186
|
+
.select("agent_id, primary_model, coding_model, tool_call_model, vision_model")
|
|
187
|
+
.eq("user_id", userId)
|
|
188
|
+
.eq("agent_id", chiefAgentId)
|
|
189
|
+
.maybeSingle();
|
|
190
|
+
if (error || !data) return null;
|
|
191
|
+
return data as ChiefAgentConfigRow;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Resolution chain at delegate_to_staff time (BUGSHOOT-3):
|
|
196
|
+
* 1. staff.<slot> (per-staff override)
|
|
197
|
+
* 2. chief_staff_defaults.<slot> (chief-level STAFF MODEL)
|
|
198
|
+
* 3. ofie_agent_config.<slot> (chief's OWN slot, NEW)
|
|
199
|
+
* 4. ofie_agent_config.primary_model (chief's primary, last-resort sub)
|
|
200
|
+
* 5. null (gateway picks gateway default)
|
|
201
|
+
*
|
|
202
|
+
* Tier 3 was added in BUGSHOOT-3 because the prior chain stopped at tier 2 and
|
|
203
|
+
* relied on an implicit "gateway default" — which is opaque and led to BUG 10
|
|
204
|
+
* when the staff override held a model id the gateway rejected. With tier 3,
|
|
205
|
+
* an empty staff slot deterministically inherits the chief's actual model.
|
|
206
|
+
*
|
|
207
|
+
* Tier 4 (slot → primary_model fallback) handles the common case where chief
|
|
208
|
+
* has only a primary_model set and no per-slot routing — a staff with
|
|
209
|
+
* coding_model blank still inherits chief's primary_model rather than null.
|
|
210
|
+
*/
|
|
211
|
+
export function resolveStaffModels(
|
|
212
|
+
staff: SubagentRow,
|
|
213
|
+
chiefDefaults: ChiefStaffDefaultsRow | null,
|
|
214
|
+
chiefConfig?: ChiefAgentConfigRow | null,
|
|
215
|
+
): ResolvedStaffModels {
|
|
216
|
+
const out: ResolvedStaffModels = {
|
|
217
|
+
primary_model: null,
|
|
218
|
+
coding_model: null,
|
|
219
|
+
tool_call_model: null,
|
|
220
|
+
function_call_model: null,
|
|
221
|
+
vision_model: null,
|
|
222
|
+
source: {
|
|
223
|
+
primary_model: null,
|
|
224
|
+
coding_model: null,
|
|
225
|
+
tool_call_model: null,
|
|
226
|
+
function_call_model: null,
|
|
227
|
+
vision_model: null,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
const chiefPrimary = typeof chiefConfig?.primary_model === "string" && chiefConfig.primary_model.trim()
|
|
231
|
+
? chiefConfig.primary_model.trim()
|
|
232
|
+
: null;
|
|
233
|
+
for (const slot of SLOTS) {
|
|
234
|
+
const staffVal = (staff as any)[slot] as string | null | undefined;
|
|
235
|
+
const chiefVal = chiefDefaults ? (chiefDefaults as any)[slot] as string | null | undefined : null;
|
|
236
|
+
const chiefSlotVal = chiefConfig ? (chiefConfig as any)[slot] as string | null | undefined : null;
|
|
237
|
+
if (staffVal && staffVal.trim()) {
|
|
238
|
+
out[slot] = staffVal;
|
|
239
|
+
out.source[slot] = "staff";
|
|
240
|
+
} else if (chiefVal && chiefVal.trim()) {
|
|
241
|
+
out[slot] = chiefVal;
|
|
242
|
+
out.source[slot] = "chief_default";
|
|
243
|
+
} else if (chiefSlotVal && chiefSlotVal.trim()) {
|
|
244
|
+
out[slot] = chiefSlotVal;
|
|
245
|
+
out.source[slot] = "chief_primary";
|
|
246
|
+
} else if (chiefPrimary) {
|
|
247
|
+
// Sub-fallback: chief has a primary_model but no per-slot override.
|
|
248
|
+
out[slot] = chiefPrimary;
|
|
249
|
+
out.source[slot] = "chief_primary";
|
|
250
|
+
} else {
|
|
251
|
+
out[slot] = null;
|
|
252
|
+
out.source[slot] = "chief_fallback";
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function buildStaffPersonaBlock(
|
|
259
|
+
staff: SubagentRow,
|
|
260
|
+
resolved?: ResolvedStaffModels,
|
|
261
|
+
): string {
|
|
262
|
+
const lines: string[] = [];
|
|
263
|
+
lines.push(`# STAFF IDENTITY`);
|
|
264
|
+
lines.push(
|
|
265
|
+
`You are **${staff.name}**${staff.role ? ` (${staff.role})` : ""}, a staff member reporting to chief \`${staff.chief_agent_id}\`.`,
|
|
266
|
+
);
|
|
267
|
+
lines.push(
|
|
268
|
+
`You are NOT the chief. Execute the assigned task, then return a structured report. Do not adopt the chief's persona.`,
|
|
269
|
+
);
|
|
270
|
+
if (staff.system_prompt?.trim()) {
|
|
271
|
+
lines.push(``, `## Persona`, staff.system_prompt.trim());
|
|
272
|
+
}
|
|
273
|
+
if (staff.mission?.trim()) {
|
|
274
|
+
lines.push(``, `## Mission`, staff.mission.trim());
|
|
275
|
+
}
|
|
276
|
+
if (staff.responsibilities?.trim()) {
|
|
277
|
+
lines.push(``, `## Responsibilities`, staff.responsibilities.trim());
|
|
278
|
+
}
|
|
279
|
+
if (staff.instructions?.trim()) {
|
|
280
|
+
lines.push(``, `## Operating Instructions`, staff.instructions.trim());
|
|
281
|
+
}
|
|
282
|
+
if (resolved && (resolved.primary_model || resolved.coding_model || resolved.tool_call_model || resolved.function_call_model || resolved.vision_model)) {
|
|
283
|
+
const sourceLabel = (s: "staff" | "chief_default" | "chief_primary" | "chief_fallback" | null) =>
|
|
284
|
+
s === "staff" ? "per-staff override"
|
|
285
|
+
: s === "chief_default" ? "chief STAFF MODEL"
|
|
286
|
+
: s === "chief_primary" ? "chief's own model"
|
|
287
|
+
: "inherits chief (gateway default)";
|
|
288
|
+
const rows: string[] = [];
|
|
289
|
+
if (resolved.primary_model) rows.push(`- primary: \`${resolved.primary_model}\` (${sourceLabel(resolved.source.primary_model)})`);
|
|
290
|
+
if (resolved.coding_model) rows.push(`- coding: \`${resolved.coding_model}\` (${sourceLabel(resolved.source.coding_model)})`);
|
|
291
|
+
if (resolved.tool_call_model) rows.push(`- tool_call: \`${resolved.tool_call_model}\` (${sourceLabel(resolved.source.tool_call_model)})`);
|
|
292
|
+
if (resolved.function_call_model) rows.push(`- function_call: \`${resolved.function_call_model}\` (${sourceLabel(resolved.source.function_call_model)})`);
|
|
293
|
+
if (resolved.vision_model) rows.push(`- vision: \`${resolved.vision_model}\` (${sourceLabel(resolved.source.vision_model)})`);
|
|
294
|
+
if (rows.length) {
|
|
295
|
+
lines.push(``, `## Configured Models`, ...rows);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return lines.join("\n");
|
|
299
|
+
}
|
package/src/supabase.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { createClient, type SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
-
|
|
3
|
-
let _client: SupabaseClient | null = null;
|
|
4
|
-
|
|
5
|
-
export function getSupabase(supabaseUrl: string, serviceRoleKey: string): SupabaseClient {
|
|
6
|
-
if (_client) return _client;
|
|
7
|
-
|
|
8
|
-
_client = createClient(supabaseUrl, serviceRoleKey, {
|
|
9
|
-
auth: { persistSession: false },
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
return _client;
|
|
13
|
-
}
|
|
1
|
+
import { createClient, type SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
|
|
3
|
+
let _client: SupabaseClient | null = null;
|
|
4
|
+
|
|
5
|
+
export function getSupabase(supabaseUrl: string, serviceRoleKey: string): SupabaseClient {
|
|
6
|
+
if (_client) return _client;
|
|
7
|
+
|
|
8
|
+
_client = createClient(supabaseUrl, serviceRoleKey, {
|
|
9
|
+
auth: { persistSession: false },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return _client;
|
|
13
|
+
}
|