ofiere-openclaw-plugin 4.50.1 → 4.52.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/dist/src/attachments.js +41 -1
- package/dist/src/tools.js +15 -6
- package/openclaw.plugin.json +80 -80
- package/package.json +50 -50
- package/src/attachments.ts +40 -2
- package/src/tools.ts +15 -6
- package/tsconfig.json +23 -23
package/dist/src/attachments.js
CHANGED
|
@@ -16,7 +16,7 @@ function ok(data) {
|
|
|
16
16
|
function err(message) {
|
|
17
17
|
return { content: [{ type: "text", text: `Error: ${message}` }] };
|
|
18
18
|
}
|
|
19
|
-
const VALID_TARGETS = ["conversation", "task", "scheduler_event"];
|
|
19
|
+
const VALID_TARGETS = ["conversation", "task", "scheduler_event", "subagent"];
|
|
20
20
|
function isValidTargetKind(v) {
|
|
21
21
|
return typeof v === "string" && VALID_TARGETS.includes(v);
|
|
22
22
|
}
|
|
@@ -77,10 +77,50 @@ async function applyAttachmentWrite(args) {
|
|
|
77
77
|
return { ok: false, error: writeErr.message };
|
|
78
78
|
return { ok: true };
|
|
79
79
|
}
|
|
80
|
+
// Cycle 11 — subagent target_kind. Writes profile-level defaults that apply
|
|
81
|
+
// across EVERY dispatch to the staff (unioned with per-task ids at dispatch
|
|
82
|
+
// time in task-dispatcher edge fn via loadStaffDefaultAttachments).
|
|
83
|
+
if (targetKind === "subagent") {
|
|
84
|
+
const col = docKind === "sop" ? "attached_sop_ids" : "attached_framework_ids";
|
|
85
|
+
const { data: cur, error: readErr } = await supabase
|
|
86
|
+
.from("agent_subagents")
|
|
87
|
+
.select(col)
|
|
88
|
+
.eq("user_id", userId)
|
|
89
|
+
.eq("id", targetId)
|
|
90
|
+
.maybeSingle();
|
|
91
|
+
if (readErr)
|
|
92
|
+
return { ok: false, error: readErr.message };
|
|
93
|
+
const existing = (cur?.[col]) || [];
|
|
94
|
+
const merged = Array.from(new Set([...existing, ...docIds]));
|
|
95
|
+
const { error: writeErr } = await supabase
|
|
96
|
+
.from("agent_subagents")
|
|
97
|
+
.update({ [col]: merged })
|
|
98
|
+
.eq("user_id", userId)
|
|
99
|
+
.eq("id", targetId);
|
|
100
|
+
if (writeErr)
|
|
101
|
+
return { ok: false, error: writeErr.message };
|
|
102
|
+
return { ok: true };
|
|
103
|
+
}
|
|
80
104
|
return { ok: false, error: "unsupported target_kind" };
|
|
81
105
|
}
|
|
82
106
|
async function loadTargetIdentity(args) {
|
|
83
107
|
const { supabase, userId, targetKind, targetId } = args;
|
|
108
|
+
// Cycle 11 — subagent target: identity is { agentId: chief_agent_id, subagentId: row.id }.
|
|
109
|
+
// resolveTargetTier sees subagentId set → returns "staff" tier without a chief lookup.
|
|
110
|
+
if (targetKind === "subagent") {
|
|
111
|
+
const { data } = await supabase
|
|
112
|
+
.from("agent_subagents")
|
|
113
|
+
.select("id, chief_agent_id")
|
|
114
|
+
.eq("user_id", userId)
|
|
115
|
+
.eq("id", targetId)
|
|
116
|
+
.maybeSingle();
|
|
117
|
+
if (!data)
|
|
118
|
+
return null;
|
|
119
|
+
return {
|
|
120
|
+
agentId: data.chief_agent_id ?? null,
|
|
121
|
+
subagentId: data.id ?? null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
84
124
|
const tbl = targetKind === "conversation" ? "conversations" :
|
|
85
125
|
targetKind === "task" ? "tasks" : "scheduler_events";
|
|
86
126
|
const { data } = await supabase
|
package/dist/src/tools.js
CHANGED
|
@@ -665,7 +665,16 @@ async function handleCreateTask(supabase, userId, resolveAgent, params, fallback
|
|
|
665
665
|
// INSERTed the raw input then reassigned insertData.start_date afterward,
|
|
666
666
|
// which left the DB row with the unconverted value and the response with
|
|
667
667
|
// the converted one — confusing and unsafe for the scheduler.
|
|
668
|
-
|
|
668
|
+
//
|
|
669
|
+
// Cycle 12 fix: when delegating to a staff (subagent_id present) without
|
|
670
|
+
// an explicit start_date, default to now + 5s so the scheduler_event auto-
|
|
671
|
+
// create branch below kicks in. Without this, the task sat PENDING forever
|
|
672
|
+
// because processDirectTasks' date-string filter also skips it (separate
|
|
673
|
+
// bug, fixed in task-dispatcher v21). The 5s buffer ensures the safety
|
|
674
|
+
// net at line ~805 doesn't trip and shift the run to +60s.
|
|
675
|
+
const explicitStartDate = params.start_date || null;
|
|
676
|
+
const rawStartDate = explicitStartDate
|
|
677
|
+
?? (params.subagent_id ? new Date(Date.now() + 5_000).toISOString() : null);
|
|
669
678
|
const normalized = rawStartDate
|
|
670
679
|
? normalizeStartDate(rawStartDate, params.scheduled_time, TZ_OFFSET_HOURS)
|
|
671
680
|
: null;
|
|
@@ -4943,9 +4952,9 @@ function registerSOPOps(api, supabase, userId, resolveAgent) {
|
|
|
4943
4952
|
`- "delete": Remove SOP. Required: sop_id\n` +
|
|
4944
4953
|
`- "list_subagents": List subagents for a chief. Required: chief_agent_id. (Provided here for convenience when scoping SOP authoring; team management lives in OFIERE_AGENT_OPS.)\n` +
|
|
4945
4954
|
`- "apply_template": Create SOP from template. Required: agent_id, template_id. Optional: title, department\n` +
|
|
4946
|
-
`- "propose_attach": Propose attaching SOPs to a
|
|
4955
|
+
`- "propose_attach": Propose attaching SOPs to a target (conversation/task/scheduler_event/subagent). Returns token cost + confirmation_token. Required: target_kind, target_id, doc_ids[]. The user MUST be asked to approve before commit. Use target_kind="subagent" to attach SOPs to the staff PROFILE itself (applies to every dispatch); use task/conversation/scheduler_event for one-off run-scoped attach.\n` +
|
|
4947
4956
|
`- "commit_attach": Commit a proposed attachment. Required: target_kind, target_id, doc_ids[], confirmation_token (from propose_attach). Only call AFTER user approves the token cost.\n` +
|
|
4948
|
-
`Tier rule: SOPs only attach to targets whose assigned agent is Staff. Use OFIERE_FRAMEWORK_OPS for c-suite targets.\n\n` +
|
|
4957
|
+
`Tier rule: SOPs only attach to targets whose assigned agent is Staff (or to a subagent profile directly). Use OFIERE_FRAMEWORK_OPS for c-suite targets.\n\n` +
|
|
4949
4958
|
`sop_data structure (JSON object):\n` +
|
|
4950
4959
|
`{\n` +
|
|
4951
4960
|
` title: string,\n` +
|
|
@@ -4970,8 +4979,8 @@ function registerSOPOps(api, supabase, userId, resolveAgent) {
|
|
|
4970
4979
|
agent_id: { type: "string", description: "Agent ID (required for create, list filter, apply_template)" },
|
|
4971
4980
|
chief_agent_id: { type: "string", description: "Chief agent ID (required for list_subagents)" },
|
|
4972
4981
|
template_id: { type: "string", description: "Template ID (required for apply_template)" },
|
|
4973
|
-
target_kind: { type: "string", enum: ["conversation", "task", "scheduler_event"], description: "
|
|
4974
|
-
target_id: { type: "string", description: "
|
|
4982
|
+
target_kind: { type: "string", enum: ["conversation", "task", "scheduler_event", "subagent"], description: "Target kind (for propose_attach/commit_attach). 'subagent' writes to staff PROFILE (persists across all dispatches); others are run-scoped." },
|
|
4983
|
+
target_id: { type: "string", description: "Target id (for propose_attach/commit_attach). For target_kind='subagent', this is the agent_subagents row id." },
|
|
4975
4984
|
doc_ids: { type: "array", items: { type: "string" }, description: "SOP ids to attach (for propose_attach/commit_attach)" },
|
|
4976
4985
|
confirmation_token: { type: "string", description: "Token returned by propose_attach. Required for commit_attach." },
|
|
4977
4986
|
title: { type: "string", description: "SOP title" },
|
|
@@ -5498,7 +5507,7 @@ function registerFrameworkOps(api, supabase, userId, resolveAgent) {
|
|
|
5498
5507
|
`- "get": Get full framework details. Required: framework_id\n` +
|
|
5499
5508
|
`- "update": Modify framework. Required: framework_id. Optional: title, content, status, department, category\n` +
|
|
5500
5509
|
`- "delete": Remove framework. Required: framework_id\n` +
|
|
5501
|
-
`- "propose_attach": Propose attaching Frameworks to a
|
|
5510
|
+
`- "propose_attach": Propose attaching Frameworks to a target (conversation/task/scheduler_event). Returns token cost + confirmation_token. Required: target_kind, target_id, doc_ids[]. The user MUST be asked to approve before commit. Frameworks are c-suite only — they cannot be attached to staff subagents.\n` +
|
|
5502
5511
|
`- "commit_attach": Commit a proposed attachment. Required: target_kind, target_id, doc_ids[], confirmation_token (from propose_attach). Only call AFTER user approves the token cost.\n` +
|
|
5503
5512
|
`Tier rule: Frameworks only attach to targets whose assigned agent is C-Suite. Use OFIERE_SOP_OPS for staff targets.\n\n` +
|
|
5504
5513
|
`content: A JSON string containing the full framework body. Example:\n` +
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "ofiere",
|
|
3
|
-
"name": "Ofiere PM",
|
|
4
|
-
"description": "Manage Ofiere PM tasks, agents, and projects directly from the agent. The agent can create tasks, update progress, list work items, and more — all synced to the Ofiere dashboard in real time.",
|
|
5
|
-
"configSchema": {
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"enabled": {
|
|
10
|
-
"type": "boolean",
|
|
11
|
-
"description": "Enable or disable the Ofiere PM integration"
|
|
12
|
-
},
|
|
13
|
-
"supabaseUrl": {
|
|
14
|
-
"type": "string",
|
|
15
|
-
"description": "Your Supabase project URL (e.g. https://xxx.supabase.co)"
|
|
16
|
-
},
|
|
17
|
-
"serviceRoleKey": {
|
|
18
|
-
"type": "string",
|
|
19
|
-
"description": "Supabase service role key for full database access"
|
|
20
|
-
},
|
|
21
|
-
"userId": {
|
|
22
|
-
"type": "string",
|
|
23
|
-
"description": "Your Ofiere user ID (UUID from auth.users)"
|
|
24
|
-
},
|
|
25
|
-
"agentId": {
|
|
26
|
-
"type": "string",
|
|
27
|
-
"description": "This agent's ID in Ofiere (e.g. 'sasha', 'ivy', 'thalia')"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"hooks": {
|
|
32
|
-
"allowConversationAccess": true
|
|
33
|
-
},
|
|
34
|
-
"contracts": {
|
|
35
|
-
"tools": [
|
|
36
|
-
"OFIERE_TASK_OPS",
|
|
37
|
-
"OFIERE_AGENT_OPS",
|
|
38
|
-
"OFIERE_PROJECT_OPS",
|
|
39
|
-
"OFIERE_SCHEDULE_OPS",
|
|
40
|
-
"OFIERE_KNOWLEDGE_OPS",
|
|
41
|
-
"OFIERE_WORKFLOW_OPS",
|
|
42
|
-
"OFIERE_NOTIFY_OPS",
|
|
43
|
-
"OFIERE_MEMORY_OPS",
|
|
44
|
-
"OFIERE_PROMPT_OPS",
|
|
45
|
-
"OFIERE_CONSTELLATION_OPS",
|
|
46
|
-
"OFIERE_FILE_OPS",
|
|
47
|
-
"OFIERE_PLAN_OPS",
|
|
48
|
-
"OFIERE_SOP_OPS",
|
|
49
|
-
"OFIERE_FRAMEWORK_OPS",
|
|
50
|
-
"OFIERE_BRAIN_OPS",
|
|
51
|
-
"OFIERE_TALENT_OPS"
|
|
52
|
-
]
|
|
53
|
-
},
|
|
54
|
-
"activation": {
|
|
55
|
-
"onStartup": true
|
|
56
|
-
},
|
|
57
|
-
"uiHints": {
|
|
58
|
-
"enabled": {
|
|
59
|
-
"label": "Enable Ofiere PM",
|
|
60
|
-
"help": "Enable or disable the Ofiere PM integration"
|
|
61
|
-
},
|
|
62
|
-
"supabaseUrl": {
|
|
63
|
-
"label": "Supabase URL",
|
|
64
|
-
"help": "Your Supabase project URL"
|
|
65
|
-
},
|
|
66
|
-
"serviceRoleKey": {
|
|
67
|
-
"label": "Service Role Key",
|
|
68
|
-
"help": "Supabase service role key (keep secret!)",
|
|
69
|
-
"sensitive": true
|
|
70
|
-
},
|
|
71
|
-
"userId": {
|
|
72
|
-
"label": "User ID",
|
|
73
|
-
"help": "Your user UUID from the Ofiere dashboard"
|
|
74
|
-
},
|
|
75
|
-
"agentId": {
|
|
76
|
-
"label": "Agent ID",
|
|
77
|
-
"help": "This agent's ID (e.g. 'sasha')"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "ofiere",
|
|
3
|
+
"name": "Ofiere PM",
|
|
4
|
+
"description": "Manage Ofiere PM tasks, agents, and projects directly from the agent. The agent can create tasks, update progress, list work items, and more — all synced to the Ofiere dashboard in real time.",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"enabled": {
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"description": "Enable or disable the Ofiere PM integration"
|
|
12
|
+
},
|
|
13
|
+
"supabaseUrl": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Your Supabase project URL (e.g. https://xxx.supabase.co)"
|
|
16
|
+
},
|
|
17
|
+
"serviceRoleKey": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Supabase service role key for full database access"
|
|
20
|
+
},
|
|
21
|
+
"userId": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Your Ofiere user ID (UUID from auth.users)"
|
|
24
|
+
},
|
|
25
|
+
"agentId": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "This agent's ID in Ofiere (e.g. 'sasha', 'ivy', 'thalia')"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"hooks": {
|
|
32
|
+
"allowConversationAccess": true
|
|
33
|
+
},
|
|
34
|
+
"contracts": {
|
|
35
|
+
"tools": [
|
|
36
|
+
"OFIERE_TASK_OPS",
|
|
37
|
+
"OFIERE_AGENT_OPS",
|
|
38
|
+
"OFIERE_PROJECT_OPS",
|
|
39
|
+
"OFIERE_SCHEDULE_OPS",
|
|
40
|
+
"OFIERE_KNOWLEDGE_OPS",
|
|
41
|
+
"OFIERE_WORKFLOW_OPS",
|
|
42
|
+
"OFIERE_NOTIFY_OPS",
|
|
43
|
+
"OFIERE_MEMORY_OPS",
|
|
44
|
+
"OFIERE_PROMPT_OPS",
|
|
45
|
+
"OFIERE_CONSTELLATION_OPS",
|
|
46
|
+
"OFIERE_FILE_OPS",
|
|
47
|
+
"OFIERE_PLAN_OPS",
|
|
48
|
+
"OFIERE_SOP_OPS",
|
|
49
|
+
"OFIERE_FRAMEWORK_OPS",
|
|
50
|
+
"OFIERE_BRAIN_OPS",
|
|
51
|
+
"OFIERE_TALENT_OPS"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"activation": {
|
|
55
|
+
"onStartup": true
|
|
56
|
+
},
|
|
57
|
+
"uiHints": {
|
|
58
|
+
"enabled": {
|
|
59
|
+
"label": "Enable Ofiere PM",
|
|
60
|
+
"help": "Enable or disable the Ofiere PM integration"
|
|
61
|
+
},
|
|
62
|
+
"supabaseUrl": {
|
|
63
|
+
"label": "Supabase URL",
|
|
64
|
+
"help": "Your Supabase project URL"
|
|
65
|
+
},
|
|
66
|
+
"serviceRoleKey": {
|
|
67
|
+
"label": "Service Role Key",
|
|
68
|
+
"help": "Supabase service role key (keep secret!)",
|
|
69
|
+
"sensitive": true
|
|
70
|
+
},
|
|
71
|
+
"userId": {
|
|
72
|
+
"label": "User ID",
|
|
73
|
+
"help": "Your user UUID from the Ofiere dashboard"
|
|
74
|
+
},
|
|
75
|
+
"agentId": {
|
|
76
|
+
"label": "Agent ID",
|
|
77
|
+
"help": "This agent's ID (e.g. 'sasha')"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ofiere-openclaw-plugin",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"type": "module",
|
|
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
|
-
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
|
7
|
-
"homepage": "https://github.com/gilanggemar/Ofiere",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "https://github.com/gilanggemar/Ofiere.git"
|
|
11
|
-
},
|
|
12
|
-
"license": "MIT",
|
|
13
|
-
"main": "./dist/index.js",
|
|
14
|
-
"files": [
|
|
15
|
-
"index.ts",
|
|
16
|
-
"src",
|
|
17
|
-
"dist",
|
|
18
|
-
"openclaw.plugin.json",
|
|
19
|
-
"README.md",
|
|
20
|
-
"tsconfig.json"
|
|
21
|
-
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"typecheck": "tsc --noEmit",
|
|
24
|
-
"build": "tsc",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
26
|
-
},
|
|
27
|
-
"openclaw": {
|
|
28
|
-
"extensions": [
|
|
29
|
-
"./index.ts"
|
|
30
|
-
],
|
|
31
|
-
"runtimeExtensions": [
|
|
32
|
-
"./dist/index.js"
|
|
33
|
-
],
|
|
34
|
-
"compat": {
|
|
35
|
-
"pluginApi": ">=2026.3.24-beta.2",
|
|
36
|
-
"minGatewayVersion": "2026.3.24-beta.2"
|
|
37
|
-
},
|
|
38
|
-
"build": {
|
|
39
|
-
"openclawVersion": "2026.3.24-beta.2",
|
|
40
|
-
"pluginSdkVersion": "2026.3.24-beta.2"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"@supabase/supabase-js": "^2.98.0",
|
|
45
|
-
"zod": "^3.25.11"
|
|
46
|
-
},
|
|
47
|
-
"devDependencies": {
|
|
48
|
-
"typescript": "^5.6.0"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "ofiere-openclaw-plugin",
|
|
3
|
+
"version": "4.52.0",
|
|
4
|
+
"type": "module",
|
|
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
|
+
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
|
7
|
+
"homepage": "https://github.com/gilanggemar/Ofiere",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/gilanggemar/Ofiere.git"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"files": [
|
|
15
|
+
"index.ts",
|
|
16
|
+
"src",
|
|
17
|
+
"dist",
|
|
18
|
+
"openclaw.plugin.json",
|
|
19
|
+
"README.md",
|
|
20
|
+
"tsconfig.json"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"openclaw": {
|
|
28
|
+
"extensions": [
|
|
29
|
+
"./index.ts"
|
|
30
|
+
],
|
|
31
|
+
"runtimeExtensions": [
|
|
32
|
+
"./dist/index.js"
|
|
33
|
+
],
|
|
34
|
+
"compat": {
|
|
35
|
+
"pluginApi": ">=2026.3.24-beta.2",
|
|
36
|
+
"minGatewayVersion": "2026.3.24-beta.2"
|
|
37
|
+
},
|
|
38
|
+
"build": {
|
|
39
|
+
"openclawVersion": "2026.3.24-beta.2",
|
|
40
|
+
"pluginSdkVersion": "2026.3.24-beta.2"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@supabase/supabase-js": "^2.98.0",
|
|
45
|
+
"zod": "^3.25.11"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"typescript": "^5.6.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/attachments.ts
CHANGED
|
@@ -27,10 +27,10 @@ function err(message: string): ToolResult {
|
|
|
27
27
|
return { content: [{ type: "text" as const, text: `Error: ${message}` }] };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export type TargetKind = "conversation" | "task" | "scheduler_event";
|
|
30
|
+
export type TargetKind = "conversation" | "task" | "scheduler_event" | "subagent";
|
|
31
31
|
export type DocKind = "sop" | "framework";
|
|
32
32
|
|
|
33
|
-
const VALID_TARGETS: ReadonlyArray<TargetKind> = ["conversation", "task", "scheduler_event"];
|
|
33
|
+
const VALID_TARGETS: ReadonlyArray<TargetKind> = ["conversation", "task", "scheduler_event", "subagent"];
|
|
34
34
|
function isValidTargetKind(v: unknown): v is TargetKind {
|
|
35
35
|
return typeof v === "string" && (VALID_TARGETS as readonly string[]).includes(v);
|
|
36
36
|
}
|
|
@@ -97,6 +97,29 @@ async function applyAttachmentWrite(args: {
|
|
|
97
97
|
return { ok: true };
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
// Cycle 11 — subagent target_kind. Writes profile-level defaults that apply
|
|
101
|
+
// across EVERY dispatch to the staff (unioned with per-task ids at dispatch
|
|
102
|
+
// time in task-dispatcher edge fn via loadStaffDefaultAttachments).
|
|
103
|
+
if (targetKind === "subagent") {
|
|
104
|
+
const col = docKind === "sop" ? "attached_sop_ids" : "attached_framework_ids";
|
|
105
|
+
const { data: cur, error: readErr } = await supabase
|
|
106
|
+
.from("agent_subagents")
|
|
107
|
+
.select(col)
|
|
108
|
+
.eq("user_id", userId)
|
|
109
|
+
.eq("id", targetId)
|
|
110
|
+
.maybeSingle();
|
|
111
|
+
if (readErr) return { ok: false, error: readErr.message };
|
|
112
|
+
const existing = ((cur as Record<string, string[] | undefined> | null)?.[col]) || [];
|
|
113
|
+
const merged = Array.from(new Set([...existing, ...docIds]));
|
|
114
|
+
const { error: writeErr } = await supabase
|
|
115
|
+
.from("agent_subagents")
|
|
116
|
+
.update({ [col]: merged })
|
|
117
|
+
.eq("user_id", userId)
|
|
118
|
+
.eq("id", targetId);
|
|
119
|
+
if (writeErr) return { ok: false, error: writeErr.message };
|
|
120
|
+
return { ok: true };
|
|
121
|
+
}
|
|
122
|
+
|
|
100
123
|
return { ok: false, error: "unsupported target_kind" };
|
|
101
124
|
}
|
|
102
125
|
|
|
@@ -113,6 +136,21 @@ async function loadTargetIdentity(args: {
|
|
|
113
136
|
targetId: string;
|
|
114
137
|
}): Promise<TargetIdentity | null> {
|
|
115
138
|
const { supabase, userId, targetKind, targetId } = args;
|
|
139
|
+
// Cycle 11 — subagent target: identity is { agentId: chief_agent_id, subagentId: row.id }.
|
|
140
|
+
// resolveTargetTier sees subagentId set → returns "staff" tier without a chief lookup.
|
|
141
|
+
if (targetKind === "subagent") {
|
|
142
|
+
const { data } = await supabase
|
|
143
|
+
.from("agent_subagents")
|
|
144
|
+
.select("id, chief_agent_id")
|
|
145
|
+
.eq("user_id", userId)
|
|
146
|
+
.eq("id", targetId)
|
|
147
|
+
.maybeSingle();
|
|
148
|
+
if (!data) return null;
|
|
149
|
+
return {
|
|
150
|
+
agentId: (data.chief_agent_id as string | null) ?? null,
|
|
151
|
+
subagentId: (data.id as string | null) ?? null,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
116
154
|
const tbl =
|
|
117
155
|
targetKind === "conversation" ? "conversations" :
|
|
118
156
|
targetKind === "task" ? "tasks" : "scheduler_events";
|
package/src/tools.ts
CHANGED
|
@@ -748,7 +748,16 @@ async function handleCreateTask(
|
|
|
748
748
|
// INSERTed the raw input then reassigned insertData.start_date afterward,
|
|
749
749
|
// which left the DB row with the unconverted value and the response with
|
|
750
750
|
// the converted one — confusing and unsafe for the scheduler.
|
|
751
|
-
|
|
751
|
+
//
|
|
752
|
+
// Cycle 12 fix: when delegating to a staff (subagent_id present) without
|
|
753
|
+
// an explicit start_date, default to now + 5s so the scheduler_event auto-
|
|
754
|
+
// create branch below kicks in. Without this, the task sat PENDING forever
|
|
755
|
+
// because processDirectTasks' date-string filter also skips it (separate
|
|
756
|
+
// bug, fixed in task-dispatcher v21). The 5s buffer ensures the safety
|
|
757
|
+
// net at line ~805 doesn't trip and shift the run to +60s.
|
|
758
|
+
const explicitStartDate = (params.start_date as string) || null;
|
|
759
|
+
const rawStartDate = explicitStartDate
|
|
760
|
+
?? (params.subagent_id ? new Date(Date.now() + 5_000).toISOString() : null);
|
|
752
761
|
const normalized = rawStartDate
|
|
753
762
|
? normalizeStartDate(rawStartDate, params.scheduled_time as string | undefined, TZ_OFFSET_HOURS)
|
|
754
763
|
: null;
|
|
@@ -5116,9 +5125,9 @@ function registerSOPOps(
|
|
|
5116
5125
|
`- "delete": Remove SOP. Required: sop_id\n` +
|
|
5117
5126
|
`- "list_subagents": List subagents for a chief. Required: chief_agent_id. (Provided here for convenience when scoping SOP authoring; team management lives in OFIERE_AGENT_OPS.)\n` +
|
|
5118
5127
|
`- "apply_template": Create SOP from template. Required: agent_id, template_id. Optional: title, department\n` +
|
|
5119
|
-
`- "propose_attach": Propose attaching SOPs to a
|
|
5128
|
+
`- "propose_attach": Propose attaching SOPs to a target (conversation/task/scheduler_event/subagent). Returns token cost + confirmation_token. Required: target_kind, target_id, doc_ids[]. The user MUST be asked to approve before commit. Use target_kind="subagent" to attach SOPs to the staff PROFILE itself (applies to every dispatch); use task/conversation/scheduler_event for one-off run-scoped attach.\n` +
|
|
5120
5129
|
`- "commit_attach": Commit a proposed attachment. Required: target_kind, target_id, doc_ids[], confirmation_token (from propose_attach). Only call AFTER user approves the token cost.\n` +
|
|
5121
|
-
`Tier rule: SOPs only attach to targets whose assigned agent is Staff. Use OFIERE_FRAMEWORK_OPS for c-suite targets.\n\n` +
|
|
5130
|
+
`Tier rule: SOPs only attach to targets whose assigned agent is Staff (or to a subagent profile directly). Use OFIERE_FRAMEWORK_OPS for c-suite targets.\n\n` +
|
|
5122
5131
|
`sop_data structure (JSON object):\n` +
|
|
5123
5132
|
`{\n` +
|
|
5124
5133
|
` title: string,\n` +
|
|
@@ -5143,8 +5152,8 @@ function registerSOPOps(
|
|
|
5143
5152
|
agent_id: { type: "string", description: "Agent ID (required for create, list filter, apply_template)" },
|
|
5144
5153
|
chief_agent_id: { type: "string", description: "Chief agent ID (required for list_subagents)" },
|
|
5145
5154
|
template_id: { type: "string", description: "Template ID (required for apply_template)" },
|
|
5146
|
-
target_kind: { type: "string", enum: ["conversation", "task", "scheduler_event"], description: "
|
|
5147
|
-
target_id: { type: "string", description: "
|
|
5155
|
+
target_kind: { type: "string", enum: ["conversation", "task", "scheduler_event", "subagent"], description: "Target kind (for propose_attach/commit_attach). 'subagent' writes to staff PROFILE (persists across all dispatches); others are run-scoped." },
|
|
5156
|
+
target_id: { type: "string", description: "Target id (for propose_attach/commit_attach). For target_kind='subagent', this is the agent_subagents row id." },
|
|
5148
5157
|
doc_ids: { type: "array", items: { type: "string" }, description: "SOP ids to attach (for propose_attach/commit_attach)" },
|
|
5149
5158
|
confirmation_token: { type: "string", description: "Token returned by propose_attach. Required for commit_attach." },
|
|
5150
5159
|
title: { type: "string", description: "SOP title" },
|
|
@@ -5656,7 +5665,7 @@ function registerFrameworkOps(
|
|
|
5656
5665
|
`- "get": Get full framework details. Required: framework_id\n` +
|
|
5657
5666
|
`- "update": Modify framework. Required: framework_id. Optional: title, content, status, department, category\n` +
|
|
5658
5667
|
`- "delete": Remove framework. Required: framework_id\n` +
|
|
5659
|
-
`- "propose_attach": Propose attaching Frameworks to a
|
|
5668
|
+
`- "propose_attach": Propose attaching Frameworks to a target (conversation/task/scheduler_event). Returns token cost + confirmation_token. Required: target_kind, target_id, doc_ids[]. The user MUST be asked to approve before commit. Frameworks are c-suite only — they cannot be attached to staff subagents.\n` +
|
|
5660
5669
|
`- "commit_attach": Commit a proposed attachment. Required: target_kind, target_id, doc_ids[], confirmation_token (from propose_attach). Only call AFTER user approves the token cost.\n` +
|
|
5661
5670
|
`Tier rule: Frameworks only attach to targets whose assigned agent is C-Suite. Use OFIERE_SOP_OPS for staff targets.\n\n` +
|
|
5662
5671
|
`content: A JSON string containing the full framework body. Example:\n` +
|
package/tsconfig.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"lib": ["ES2022"],
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"forceConsistentCasingInFileNames": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"noImplicitAny": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"noEmit": false,
|
|
14
|
-
"outDir": "dist",
|
|
15
|
-
"rootDir": ".",
|
|
16
|
-
"declaration": false,
|
|
17
|
-
"sourceMap": false,
|
|
18
|
-
"allowImportingTsExtensions": false,
|
|
19
|
-
"isolatedModules": true
|
|
20
|
-
},
|
|
21
|
-
"include": ["index.ts", "src/**/*.ts"],
|
|
22
|
-
"exclude": ["node_modules", "dist"]
|
|
23
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"noEmit": false,
|
|
14
|
+
"outDir": "dist",
|
|
15
|
+
"rootDir": ".",
|
|
16
|
+
"declaration": false,
|
|
17
|
+
"sourceMap": false,
|
|
18
|
+
"allowImportingTsExtensions": false,
|
|
19
|
+
"isolatedModules": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["index.ts", "src/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules", "dist"]
|
|
23
|
+
}
|