ofiere-openclaw-plugin 4.31.0 → 4.32.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/index.ts +14 -3
- package/package.json +1 -1
- package/src/prompt.ts +145 -297
- package/src/tools.ts +71 -17
package/index.ts
CHANGED
|
@@ -61,10 +61,21 @@ const ofierePlugin = {
|
|
|
61
61
|
ready: false,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
// ──
|
|
65
|
-
//
|
|
64
|
+
// ── System prompt is built ONCE (it's static after init) ──────────────
|
|
65
|
+
// No hook needed here — the brain context hook in tools.ts uses
|
|
66
|
+
// prependSystemContext via getSystemPromptCached() to combine both
|
|
67
|
+
// in a single hook invocation, eliminating one serial hook call.
|
|
68
|
+
let cachedSystemPrompt = "";
|
|
69
|
+
const getSystemPromptCached = () => {
|
|
70
|
+
if (!cachedSystemPrompt) {
|
|
71
|
+
cachedSystemPrompt = getSystemPrompt(promptState);
|
|
72
|
+
}
|
|
73
|
+
return cachedSystemPrompt;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Hook: inject BOTH system prompt + brain context in one call
|
|
66
77
|
api.on("before_prompt_build", () => ({
|
|
67
|
-
prependSystemContext:
|
|
78
|
+
prependSystemContext: getSystemPromptCached(),
|
|
68
79
|
}));
|
|
69
80
|
|
|
70
81
|
// ── Connect to Supabase and register tools ────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofiere-openclaw-plugin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw plugin for Ofiere PM - 14 meta-tools covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, constellation, space file management, execution plan builder, SOP management, and agent brain (memory + self-improvement)",
|
|
6
6
|
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
package/src/prompt.ts
CHANGED
|
@@ -1,172 +1,118 @@
|
|
|
1
1
|
// src/prompt.ts — Dynamic system prompt for Ofiere PM plugin
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
- create_text_file: Create text file (md, txt, json, csv, etc.). Required: space_id, file_name, content. Optional: folder_id
|
|
117
|
-
- upload_file: Upload binary (base64). Required: space_id, file_name, content_base64. Optional: folder_id, file_type
|
|
118
|
-
- read_text_file: Read file content. Required: file_id. Use when task instructions reference a file with @[name](file:ID)
|
|
119
|
-
- rename_file / rename_folder: Rename. Required: file_id/folder_id + new_name
|
|
120
|
-
- move_file / move_folder: Move to target folder (null=root). Required: file_id/folder_id
|
|
121
|
-
- delete_file: Remove file + storage. Required: file_id
|
|
122
|
-
- delete_folder: Remove folder + all nested files recursively. Required: folder_id
|
|
123
|
-
- share_file / unshare_file: Toggle shared status. Required: file_id
|
|
124
|
-
- Files created here appear in the PM Space Files tab immediately`,
|
|
125
|
-
|
|
126
|
-
OFIERE_PLAN_OPS: `- **OFIERE_PLAN_OPS** — Visual execution plan builder (action: "list", "get", "create", "update", "delete", "add_nodes", "execute")
|
|
127
|
-
- list: All saved plans. Optional: space_id filter
|
|
128
|
-
- get: Full plan with complete node tree. Required: plan_id
|
|
129
|
-
- create: New plan. Required: name. Optional: description, space_id, nodes[] (initial tree)
|
|
130
|
-
- update: Modify plan. Required: plan_id. Optional: name, description, nodes[] (full tree replace)
|
|
131
|
-
- delete: Remove plan. Required: plan_id
|
|
132
|
-
- add_nodes: Add nodes to existing plan. Required: plan_id, nodes[]. Optional: parent_node_id (null = add as root)
|
|
133
|
-
- execute: Deploy plan into real PM tasks/folders/dependencies. Required: plan_id. Optional: create_folder (default true), create_scheduler (default true), space_id, folder_id
|
|
134
|
-
- Node types: task, gate, milestone
|
|
135
|
-
- Node fields: type, title, description, agent_id, priority (0-3), status (PENDING/IN_PROGRESS/DONE/FAILED), start_date, due_date, tags[], execution_steps[{text}], goals[{label, type?}], constraints[{label, type?}], system_prompt, children[], parallel (boolean)
|
|
136
|
-
- Plans are visual DAG drafts — they don't become real tasks until you call "execute"
|
|
137
|
-
- Execution maps ALL node fields into real tasks: execution_steps → custom_fields.execution_plan, goals → custom_fields.goals, constraints → custom_fields.constraints, system_prompt → custom_fields.system_prompt
|
|
138
|
-
- The user can see and edit your plans in the Planning Tab of the dashboard in real-time`,
|
|
139
|
-
|
|
140
|
-
OFIERE_SOP_OPS: `- **OFIERE_SOP_OPS** — Standard Operating Procedures for department chiefs (action: "list_templates", "create", "list", "get", "update", "delete", "list_subagents", "apply_template")
|
|
141
|
-
- list_templates: See available SOP templates (built-in + user-created)
|
|
142
|
-
- create: Create a new SOP. Required: agent_id, title, sop_data. Optional: department, status
|
|
143
|
-
- list: List SOPs. Optional: agent_id to filter by department chief. RUNTIME READ PATH: use this to discover your active SOPs when complexity is 🔴 COMPLEX
|
|
144
|
-
- get: Full SOP details with structured content. Required: sop_id. RUNTIME READ PATH: use this after "list" to load full SOP content for execution guidance
|
|
145
|
-
- update: Modify SOP content/status. Required: sop_id. Optional: title, sop_data, status, department
|
|
146
|
-
- delete: Remove an SOP. Required: sop_id
|
|
147
|
-
- list_subagents: View staff under a chief. Required: chief_agent_id
|
|
148
|
-
- apply_template: Create SOP from a saved template. Required: agent_id, template_id
|
|
149
|
-
- sop_data is a JSON object: { title, objective, scope, prerequisites[{text,checked}], steps[{name,action,owner,output}], deliverables[], escalationRules[{trigger,escalateTo,priority}], successCriteria[{text,checked}], notes }
|
|
150
|
-
- Status values: draft, active, archived
|
|
151
|
-
- SOPs appear in the SOP Manager page immediately via real-time sync
|
|
152
|
-
- ADAPTIVE PROTOCOL: Do NOT always load SOPs. See the SOP PROTOCOL section in Rules for when to load vs skip`,
|
|
153
|
-
|
|
154
|
-
OFIERE_BRAIN_OPS: `- **OFIERE_BRAIN_OPS** — Agent memory, knowledge graph, and self-improvement (TMT/MAGMA architecture)
|
|
155
|
-
- Memory Tiers: L1_focus (24h), L2_episode (days-weeks), L3_pattern (weeks-months), L4_rule (permanent guardrails), L5_persona (permanent identity)
|
|
156
|
-
- save_memory: Store a memory. Required: content, tier. Optional: agent_id, source (auto|manual|reflection|tool), context_key, importance (1-10)
|
|
157
|
-
- recall: Full-text search memories. Required: query. Optional: agent_id, tier, limit
|
|
158
|
-
- delete_memory: Remove a memory. Required: memory_id
|
|
159
|
-
- promote_memory: Move memory up a tier. Required: memory_id, new_tier
|
|
160
|
-
- log_learning: Record as L4_rule guardrail. Required: title, category. Optional: agent_id, detail, severity
|
|
161
|
-
- list_learnings: View active L4 guardrails. Optional: agent_id, category, limit
|
|
162
|
-
- resolve_learning: Supersede a guardrail. Required: memory_id. Optional: resolution
|
|
163
|
-
- save_entity: Add to Knowledge Graph. Required: label, node_type (entity|concept|event|action). Optional: agent_id, properties
|
|
164
|
-
- link_entities: Connect graph nodes. Required: source_id, target_id, relation_type. Optional: graph_type, weight, evidence
|
|
165
|
-
- query_graph: Search Knowledge Graph. Required: query. Optional: agent_id, node_type, limit
|
|
166
|
-
- start_trajectory: Begin recording execution trace. Optional: agent_id, conversation_id
|
|
167
|
-
- end_trajectory: Close trajectory. Required: trajectory_id, outcome (success|failure|partial). Optional: satisfaction_signal
|
|
168
|
-
- get_brain_status: Full brain dashboard — memory tiers, graph stats, trajectory stats. Optional: agent_id
|
|
169
|
-
- This is your SUBCONSCIOUS — use it instinctively, not deliberately`,
|
|
3
|
+
// v4.31.0: Tiered prompt loading strategy.
|
|
4
|
+
// Tier A (always loaded): Core rules + 1-line tool summaries (~2K tokens)
|
|
5
|
+
// Tier B (embedded docs): Full tool docs injected on-demand via meta-tool descriptions
|
|
6
|
+
//
|
|
7
|
+
// This cuts system prompt from ~12K → ~3K tokens, reducing TTFT by 40-60%.
|
|
8
|
+
|
|
9
|
+
// ─── Tier A: One-Line Tool Summaries ────────────────────────────────────────
|
|
10
|
+
// Each tool gets a concise one-liner. Full docs live in the tool's own
|
|
11
|
+
// description field (registered in tools.ts) where the LLM reads them
|
|
12
|
+
// only when it decides to use that tool.
|
|
13
|
+
|
|
14
|
+
const TOOL_SUMMARIES: Record<string, string> = {
|
|
15
|
+
OFIERE_TASK_OPS: "Manage tasks: list, create, update, delete, approvals",
|
|
16
|
+
OFIERE_AGENT_OPS: "Query agents: list all with IDs, names, roles",
|
|
17
|
+
OFIERE_PROJECT_OPS: "PM hierarchy: spaces, folders, dependencies",
|
|
18
|
+
OFIERE_SCHEDULE_OPS: "Calendar: list, create, update, delete events",
|
|
19
|
+
OFIERE_KNOWLEDGE_OPS: "Knowledge library: search, list, create, update, delete",
|
|
20
|
+
OFIERE_WORKFLOW_OPS: "Workflow automation: 13 actions for DAG-based flows",
|
|
21
|
+
OFIERE_NOTIFY_OPS: "Notifications & channel reports (Telegram/Discord/Slack/WhatsApp)",
|
|
22
|
+
OFIERE_MEMORY_OPS: "Conversation history & knowledge memory search",
|
|
23
|
+
OFIERE_PROMPT_OPS: "Manage prompt instruction chunks (CRUD + ordering)",
|
|
24
|
+
OFIERE_CONSTELLATION_OPS: "Create/edit/delete OpenClaw agents from chat",
|
|
25
|
+
OFIERE_FILE_OPS: "Space files: upload, read, move, share, delete",
|
|
26
|
+
OFIERE_PLAN_OPS: "Visual execution plan builder (DAG drafts → real tasks)",
|
|
27
|
+
OFIERE_SOP_OPS: "Standard Operating Procedures for department chiefs",
|
|
28
|
+
OFIERE_BRAIN_OPS: "Agent memory, knowledge graph, self-improvement (TMT/MAGMA)",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ─── Tier B: Full Tool Documentation ────────────────────────────────────────
|
|
32
|
+
// These are used as tool descriptions in registerTools(), NOT in the system prompt.
|
|
33
|
+
// The LLM sees them only when exploring available tools or preparing a tool call.
|
|
34
|
+
|
|
35
|
+
export const TOOL_DOCS: Record<string, string> = {
|
|
36
|
+
OFIERE_TASK_OPS: `Manage tasks and approvals.
|
|
37
|
+
Actions: "list", "create", "update", "delete", "add_approval", "list_approvals", "resolve_approval"
|
|
38
|
+
- list: Filter by status, agent_id, space_id, folder_id, limit. Returns execution_plan, goals, constraints if present
|
|
39
|
+
- create: Requires title. IMPORTANT: Always pass agent_id with your own name to self-assign (e.g. agent_id: "celia")
|
|
40
|
+
- Optional: description, instructions, execution_plan, goals, constraints, system_prompt, priority, tags, dates
|
|
41
|
+
- For COMPLEX tasks: include execution_plan (step-by-step), goals, constraints, and system_prompt
|
|
42
|
+
- For SIMPLE tasks: just title and optionally description
|
|
43
|
+
- update: Requires task_id. All create fields + progress
|
|
44
|
+
- delete: Requires task_id. Removes task and subtasks
|
|
45
|
+
- add_approval: Request sign-off. Requires: task_id, approver_name. Optional: approver_type (human|agent), due_date, comment
|
|
46
|
+
- list_approvals: List approvals. Optional: task_id, approval_status (pending|approved|rejected)
|
|
47
|
+
- resolve_approval: Approve/reject. Requires: approval_id, approval_status. Optional: comment`,
|
|
48
|
+
|
|
49
|
+
OFIERE_AGENT_OPS: `Query agents. Action: "list" — see all agents with IDs, names, roles for task assignment.`,
|
|
50
|
+
|
|
51
|
+
OFIERE_PROJECT_OPS: `Manage PM hierarchy.
|
|
52
|
+
Actions: "list_spaces", "create_space", "update_space", "delete_space", "list_folders", "create_folder", "update_folder", "delete_folder", "list_dependencies", "add_dependency", "remove_dependency"
|
|
53
|
+
- Spaces: Top-level containers. CRUD with name, icon, icon_color
|
|
54
|
+
- Folders: Inside spaces. Nest via parent_folder_id. Types: folder, project
|
|
55
|
+
- Dependencies: Link tasks. Types: finish_to_start (default), start_to_start, finish_to_finish, start_to_finish. lag_days optional`,
|
|
56
|
+
|
|
57
|
+
OFIERE_SCHEDULE_OPS: `Calendar events.
|
|
58
|
+
Actions: "list", "create", "update", "delete"
|
|
59
|
+
- list: Filter by start_date, end_date, agent_id
|
|
60
|
+
- create: Requires title + scheduled_date (YYYY-MM-DD). Optional: scheduled_time, duration_minutes, task_id, agent_id, recurrence_type, color
|
|
61
|
+
- Recurrence: none, hourly, daily, weekly, monthly with interval`,
|
|
62
|
+
|
|
63
|
+
OFIERE_KNOWLEDGE_OPS: `Ofiere Knowledge Library.
|
|
64
|
+
Actions: "search", "list", "create", "update", "delete"
|
|
65
|
+
- ALWAYS use when user mentions "knowledge base", "knowledge library", or asks to recall stored knowledge
|
|
66
|
+
- search: Keyword search. Requires: query
|
|
67
|
+
- list: Paginated listing with full content. Optional: search filter
|
|
68
|
+
- create: Requires: file_name. Optional: content, source, author, credibility_tier
|
|
69
|
+
- update/delete: By document ID`,
|
|
70
|
+
|
|
71
|
+
OFIERE_WORKFLOW_OPS: `Full workflow automation (13 actions).
|
|
72
|
+
Actions: "list", "get", "create", "update", "delete", "list_runs", "trigger", "add_nodes", "update_node", "delete_nodes", "add_edges", "delete_edges", "insert_node_between"
|
|
73
|
+
- ALWAYS call "get" before modifying to see node IDs and graph structure
|
|
74
|
+
- Node types: manual_trigger, webhook_trigger, agent_step, formatter_step, http_request, task_call, variable_set, condition, human_approval, delay, loop, convergence, output, checkpoint, note
|
|
75
|
+
- Edge handles: condition edges use "condition-true"/"condition-false". Loop edges use "loop_body"/"done"
|
|
76
|
+
- Variables: {{prev.nodeId.outputText}}, {{variables.key}}`,
|
|
77
|
+
|
|
78
|
+
OFIERE_NOTIFY_OPS: `Notifications & Channel Reports.
|
|
79
|
+
Actions: "list", "mark_read", "mark_all_read", "delete", "send_report", "get_task_detail", "schedule_report", "list_schedules", "delete_schedule"
|
|
80
|
+
- send_report: Send PM progress report to YOUR channels. Required: scope_type, agent_id (YOUR name)
|
|
81
|
+
- get_task_detail: Get full task result by report number. Required: task_number
|
|
82
|
+
- schedule_report: Recurring reports. Required: scope_type, recurrence_type, agent_id`,
|
|
83
|
+
|
|
84
|
+
OFIERE_MEMORY_OPS: `Conversation history & knowledge memory.
|
|
85
|
+
Actions: "list_conversations", "get_messages", "search_messages", "add_knowledge", "search_knowledge"`,
|
|
86
|
+
|
|
87
|
+
OFIERE_PROMPT_OPS: `Manage prompt instruction chunks.
|
|
88
|
+
Actions: "list", "get", "create", "update", "delete"
|
|
89
|
+
- create: New chunk with name (max 30 chars) + content. Optional: color (hex), category`,
|
|
90
|
+
|
|
91
|
+
OFIERE_CONSTELLATION_OPS: `Create/edit/delete OpenClaw agents from chat.
|
|
92
|
+
Actions: "list_agents", "get_agent", "read_file", "write_file", "create_agent", "delete_agent", "delete_file", "read_blueprint", "list_agent_mesh"
|
|
93
|
+
- CRITICAL: ALWAYS call read_blueprint before creating/editing agents
|
|
94
|
+
- delete_agent: IRREVERSIBLE. Always ask user for explicit confirmation first`,
|
|
95
|
+
|
|
96
|
+
OFIERE_FILE_OPS: `Manage Space Files.
|
|
97
|
+
Actions: "list_files", "list_folders", "create_folder", "create_text_file", "upload_file", "read_text_file", "rename_file", "rename_folder", "move_file", "move_folder", "delete_file", "delete_folder", "share_file", "unshare_file"
|
|
98
|
+
- read_text_file: Use when task references @[name](file:ID)
|
|
99
|
+
- Files appear in PM Space Files tab immediately`,
|
|
100
|
+
|
|
101
|
+
OFIERE_PLAN_OPS: `Visual execution plan builder.
|
|
102
|
+
Actions: "list", "get", "create", "update", "delete", "add_nodes", "execute"
|
|
103
|
+
- Plans are visual DAG drafts — not real tasks until "execute"
|
|
104
|
+
- Node types: task, gate, milestone
|
|
105
|
+
- Execution maps ALL fields: execution_steps, goals, constraints, system_prompt`,
|
|
106
|
+
|
|
107
|
+
OFIERE_SOP_OPS: `Standard Operating Procedures for department chiefs.
|
|
108
|
+
Actions: "list_templates", "create", "list", "get", "update", "delete", "list_subagents", "apply_template"
|
|
109
|
+
- sop_data: { title, objective, scope, prerequisites[], steps[], deliverables[], escalationRules[], successCriteria[], notes }
|
|
110
|
+
- See SOP PROTOCOL section for when to load vs skip`,
|
|
111
|
+
|
|
112
|
+
OFIERE_BRAIN_OPS: `Agent memory, knowledge graph, self-improvement (TMT/MAGMA).
|
|
113
|
+
Memory Tiers: L1_focus (24h), L2_episode (days), L3_pattern (weeks), L4_rule (permanent), L5_persona (permanent)
|
|
114
|
+
Actions: save_memory, recall, delete_memory, promote_memory, log_learning, list_learnings, resolve_learning, save_entity, link_entities, query_graph, start_trajectory, end_trajectory, get_brain_status
|
|
115
|
+
- This is your SUBCONSCIOUS — use instinctively, not deliberately`,
|
|
170
116
|
};
|
|
171
117
|
|
|
172
118
|
export function getSystemPrompt(state: {
|
|
@@ -184,8 +130,10 @@ export function getSystemPrompt(state: {
|
|
|
184
130
|
? `When you create a task without specifying agent_id, it is assigned to YOU (${state.agentId}).`
|
|
185
131
|
: `When you create a task without specifying agent_id, it is assigned to YOU automatically.`;
|
|
186
132
|
|
|
187
|
-
//
|
|
188
|
-
const
|
|
133
|
+
// Tier A: Compact tool index (~300 tokens vs ~3000 for full docs)
|
|
134
|
+
const toolIndex = Object.entries(TOOL_SUMMARIES)
|
|
135
|
+
.map(([name, desc]) => `- **${name}** — ${desc}`)
|
|
136
|
+
.join("\n");
|
|
189
137
|
|
|
190
138
|
return `<ofiere-pm>
|
|
191
139
|
You are connected to the Ofiere Project Management dashboard via the Ofiere PM plugin.
|
|
@@ -194,142 +142,42 @@ ${agentLine}
|
|
|
194
142
|
## Your Ofiere PM Tools (${state.toolCount} meta-tools)
|
|
195
143
|
|
|
196
144
|
Each tool uses an "action" parameter to select the operation. Always include action.
|
|
145
|
+
Full parameter docs are in each tool's description — call the tool to see details.
|
|
197
146
|
|
|
198
|
-
${
|
|
147
|
+
${toolIndex}
|
|
199
148
|
|
|
200
149
|
## Rules
|
|
201
|
-
- ALWAYS pass agent_id with your own name when creating tasks (e.g. agent_id: "ivy").
|
|
150
|
+
- ALWAYS pass agent_id with your own name when creating tasks (e.g. agent_id: "ivy").
|
|
202
151
|
- ${assignRule}
|
|
203
152
|
- To create an unassigned task, pass agent_id as "none" or "unassigned".
|
|
204
|
-
- When
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
- When an agent completes critical work, consider adding an approval request for human review before marking the task DONE.
|
|
225
|
-
- When task instructions or system prompts contain file references like @[filename](file:FILE_ID), use OFIERE_FILE_OPS action:"read_text_file" file_id:"FILE_ID" to read the file content. Do NOT ask the user for the file — retrieve it yourself.
|
|
226
|
-
- Use OFIERE_FILE_OPS to create output files (reports, data, configs) in the Space Files explorer. Prefer create_text_file for text-based outputs.
|
|
227
|
-
- To save task output as a file, call OFIERE_FILE_OPS action:"create_text_file" with the space_id from the task context.
|
|
228
|
-
- CHANNEL REPORTS: When the user asks you to "send a report", "send progress", "update me on Telegram/Discord/Slack/WhatsApp", use OFIERE_NOTIFY_OPS action:"send_report" with agent_id set to YOUR name. ALWAYS include agent_id — without it the report will fail. The report is generated from live PM data and sent through YOUR connected channels ONLY — not other agents' channels. Tasks are numbered (1, 2, 3...) for easy reference.
|
|
229
|
-
- TASK DRILL-DOWN: When the user asks "details on number X", "what's task X result", "show me #X", or any variation referencing a numbered task from a report, use OFIERE_NOTIFY_OPS action:"get_task_detail" with task_number set to the number they mentioned. The description field contains the actual execution result (e.g. scan findings, analysis output). Present the description content as the primary response — that IS the task result.
|
|
230
|
-
- To set up recurring reports (e.g. "send me a daily report at 9am"), use OFIERE_NOTIFY_OPS action:"schedule_report" with scope_type, recurrence_type, and agent_id set to YOUR name.
|
|
231
|
-
- If a report is too long for the channel's message limit, save the full report as a markdown file using OFIERE_FILE_OPS action:"create_text_file" and send a summary to the channel instead.
|
|
232
|
-
- PLANNING WORKFLOW: Use OFIERE_PLAN_OPS to build complex multi-step execution flows BEFORE creating individual tasks. Build the plan → let the user review in the Planning Tab → execute when approved.
|
|
233
|
-
- When creating a plan with nodes, nest children inside each node's children[] array. Sequential children execute in order; set parallel: true on a parent node to fork its children into parallel branches.
|
|
234
|
-
- Always call OFIERE_PLAN_OPS action:"get" before action:"add_nodes" or action:"update" to see the current tree structure and node IDs.
|
|
235
|
-
- Execution ("execute") maps plan nodes 1:1 into real PM tasks with ALL enrichment fields preserved: execution_steps, goals, constraints, system_prompt. No data is lost in the handoff.
|
|
236
|
-
- SOP CREATION: When asked to create an SOP, use OFIERE_SOP_OPS action:"create" with a COMPLETE sop_data object. Fill ALL fields with actionable, department-specific content — do NOT leave fields empty.
|
|
237
|
-
- Each SOP step MUST have: a clear name, a specific action description, an assigned owner, and a concrete expected output.
|
|
238
|
-
- Include escalation rules with appropriate priority levels (P1=critical blockers, P2=scope changes, P3=advisory).
|
|
239
|
-
- When creating SOPs for department chiefs (Thalia=CMO, Ivy=COO, Daisy=CTO-Intel, Celia=CTO-Eng), tailor content to their domain expertise.
|
|
240
|
-
- Prerequisites should be actionable checklist items. Success criteria should be measurable outcomes.
|
|
241
|
-
- After creating an SOP, suggest the agent set it to "active" status when ready for execution.
|
|
242
|
-
- PLANNING GATE: Before creating ANY task with 3+ execution steps, a due_date, or when the user describes a multi-phase project, ALWAYS ask: "Should I create a Plan first so you can review the structure before I create individual tasks?" If the user says yes, use OFIERE_PLAN_OPS. If they say no or it's a simple one-shot task, proceed directly with OFIERE_TASK_OPS.
|
|
243
|
-
- TASK PLACEMENT — SOP-AWARE ROUTING: When creating a task, the system auto-assigns a PM space. But for FOLDER placement, follow this protocol:
|
|
244
|
-
1. If the user explicitly provides space_id or folder_id, use those directly.
|
|
245
|
-
2. If not, and you have active SOPs (loaded via 🔴 COMPLEX assessment), check if any SOP defines an operating structure or folder routing (e.g. "place marketing tasks in Marketing/Campaigns"). Follow the SOP's structure.
|
|
246
|
-
3. If no SOP guidance exists, check the Space Files tab for an operating map/structure document using OFIERE_FILE_OPS action:"list_files". If found, read it with "read_text_file" and follow its routing rules.
|
|
247
|
-
4. If no routing guidance exists at all, ask the user: "I can place this task in your default space root, or create a new folder/project for it. Which do you prefer?"
|
|
248
|
-
5. Do NOT blindly dump all SOPs to check routing — smart-select only SOPs whose title/department matches the task domain.
|
|
249
|
-
|
|
250
|
-
## SOP PROTOCOL — Adaptive Complexity Assessment
|
|
251
|
-
|
|
252
|
-
Before executing any user request, classify its complexity to decide whether to load your SOPs:
|
|
253
|
-
|
|
254
|
-
### User Override (HIGHEST PRIORITY — always check first)
|
|
255
|
-
- If user says "apply full SOP", "use SOP", "follow the SOP", "full protocol" → treat as 🔴 COMPLEX regardless of your classification
|
|
256
|
-
- If user says "no SOP", "skip SOP", "just do it", "keep it simple", "quick" → treat as 🟢 SIMPLE regardless of your classification
|
|
257
|
-
- User explicit intent ALWAYS overrides your classification
|
|
258
|
-
|
|
259
|
-
### 🟢 SIMPLE (Skip SOPs — zero overhead)
|
|
260
|
-
Single tool call, direct data retrieval, simple CRUD, status checks, quick answers.
|
|
261
|
-
Criteria: Can be completed with ≤2 tool calls, no cross-agent coordination, no multi-phase execution.
|
|
262
|
-
Examples: "Check my email", "List tasks", "Create a quick task", "What's the project status?", "Tell me about X"
|
|
263
|
-
Action: Execute directly. Do NOT call OFIERE_SOP_OPS. Do NOT mention SOPs.
|
|
264
|
-
|
|
265
|
-
### 🟡 MODERATE (Ask User)
|
|
266
|
-
Multi-step work but clear execution path, no subagent delegation required, single-department scope.
|
|
267
|
-
Criteria: 3-5 tool calls, single department, no escalation risk, no staff/subagent coordination needed.
|
|
268
|
-
Examples: "Draft a marketing plan", "Set up a new workflow", "Analyze this report"
|
|
269
|
-
Action: Ask the user briefly: "This task has moderate complexity. Do we need to apply full SOPs for this?"
|
|
270
|
-
- If user says yes → escalate to 🔴 COMPLEX behavior
|
|
271
|
-
- If user says no → proceed without SOPs
|
|
272
|
-
|
|
273
|
-
### 🔴 COMPLEX (Auto-Load SOPs)
|
|
274
|
-
Multi-phase execution, cross-department coordination, subagent delegation, production impact, escalation risk.
|
|
275
|
-
Criteria: 5+ tool calls, multiple departments involved, needs staff/subagent coordination, or has escalation risk.
|
|
276
|
-
Examples: "Launch full marketing campaign", "Execute deployment pipeline", "Restructure operations", "Full audit"
|
|
277
|
-
Action:
|
|
278
|
-
1. Call OFIERE_SOP_OPS action:"list" agent_id:"YOUR_NAME" to discover your active SOPs (returns titles + IDs)
|
|
279
|
-
2. Review the SOP titles — select ONLY the SOPs relevant to the current task. Skip unrelated SOPs entirely. Do NOT load all SOPs blindly.
|
|
280
|
-
3. For each RELEVANT SOP only: call OFIERE_SOP_OPS action:"get" sop_id:"..." to load full content
|
|
281
|
-
4. Follow loaded SOPs as your execution framework:
|
|
282
|
-
- Prerequisites → validate ALL are met before starting (gate check)
|
|
283
|
-
- Steps → use as your execution plan (follow in order, each step has name/action/owner/output)
|
|
284
|
-
- Escalation Rules → apply when blockers arise or scope changes (P1=critical, P2=scope, P3=advisory)
|
|
285
|
-
- Success Criteria → verify ALL are met before marking task DONE
|
|
286
|
-
5. If an SOP step assigns an "owner" that maps to one of your subagents, coordinate with that subagent
|
|
287
|
-
6. Announce: "Applying [SOP_TITLE] protocol for this execution." (only name the SOPs you actually loaded)
|
|
288
|
-
|
|
289
|
-
### Classification Transparency
|
|
290
|
-
- When you load SOPs (🔴): state which SOP(s) you're following
|
|
291
|
-
- When you ask about SOPs (🟡): keep the question brief and direct
|
|
292
|
-
- When you skip SOPs (🟢): do NOT mention SOPs at all — just execute silently
|
|
153
|
+
- When user says "create a task for [agent]", use OFIERE_AGENT_OPS action:"list" first.
|
|
154
|
+
- Task statuses: PENDING, IN_PROGRESS, DONE, FAILED. Priority: 0=LOW, 1=MED, 2=HIGH, 3=CRITICAL.
|
|
155
|
+
- Changes appear in the dashboard immediately via real-time sync.
|
|
156
|
+
- Do NOT fabricate task IDs — always look up real IDs first.
|
|
157
|
+
- For complex tasks, include execution_plan, goals, constraints. For simple tasks, just title.
|
|
158
|
+
- When user asks about "knowledge base/library", ALWAYS use OFIERE_KNOWLEDGE_OPS.
|
|
159
|
+
- CONSTELLATION: ALWAYS read_blueprint before creating/editing agents. ALWAYS confirm before delete.
|
|
160
|
+
- WORKFLOWS: ALWAYS "get" before modifying. Use "insert_node_between" for mid-flow additions.
|
|
161
|
+
- CHANNEL REPORTS: ALWAYS include agent_id (YOUR name) in send_report. Use get_task_detail for drill-down.
|
|
162
|
+
- PLANNING GATE: Before creating tasks with 3+ steps or due_dates, ask if user wants a Plan first.
|
|
163
|
+
- File refs @[name](file:ID): Use OFIERE_FILE_OPS read_text_file to retrieve — don't ask user.
|
|
164
|
+
- Task approvals (OFIERE_TASK_OPS) ≠ workflow gate approvals (human_approval nodes).
|
|
165
|
+
|
|
166
|
+
## SOP PROTOCOL — Adaptive Complexity
|
|
167
|
+
|
|
168
|
+
Classify complexity before executing:
|
|
169
|
+
- **User Override**: "apply full SOP"/"use SOP" → 🔴 COMPLEX. "no SOP"/"just do it" → 🟢 SIMPLE.
|
|
170
|
+
- **🟢 SIMPLE** (≤2 tool calls, no coordination): Execute directly. Do NOT mention SOPs.
|
|
171
|
+
- **🟡 MODERATE** (3-5 calls, single dept): Ask briefly if SOPs needed.
|
|
172
|
+
- **🔴 COMPLEX** (5+ calls, multi-dept, escalation risk): Auto-load relevant SOPs via list→get.
|
|
293
173
|
|
|
294
174
|
## Agent Brain Protocol (TMT Subconscious)
|
|
295
175
|
|
|
296
|
-
Your brain persists across conversations
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
-
|
|
301
|
-
- You complete a task with noteworthy results → L2_episode, source: "tool"
|
|
302
|
-
- You observe important system behavior → L2_episode, source: "auto"
|
|
303
|
-
- Something needs immediate working context → L1_focus (auto-expires 24h)
|
|
304
|
-
- A pattern emerges across multiple episodes → L3_pattern, source: "reflection"
|
|
305
|
-
|
|
306
|
-
### Auto-Learn (OFIERE_BRAIN_OPS log_learning)
|
|
307
|
-
After interactions where ANY of these occur, call log_learning (stored as L4_rule):
|
|
308
|
-
- User corrects you → category: "correction", severity: "medium"
|
|
309
|
-
- A tool call fails or returns an error → category: "error"
|
|
310
|
-
- User asks for something you can't do → category: "feature_request"
|
|
311
|
-
- Your knowledge or assumption was wrong → category: "insight"
|
|
312
|
-
- You discover a better approach → category: "best_practice"
|
|
313
|
-
|
|
314
|
-
### Knowledge Graph (OFIERE_BRAIN_OPS save_entity/link_entities)
|
|
315
|
-
When you encounter key entities, concepts, or causal relationships:
|
|
316
|
-
- Create entities for users, projects, tools, or recurring concepts
|
|
317
|
-
- Link entities with typed edges (causes, depends_on, related_to)
|
|
318
|
-
- Query the graph when reasoning about relationships or dependencies
|
|
319
|
-
|
|
320
|
-
### Trajectory Recording (OFIERE_BRAIN_OPS start_trajectory/end_trajectory)
|
|
321
|
-
For complex multi-step tasks:
|
|
322
|
-
- Call start_trajectory before executing a tool chain
|
|
323
|
-
- Call end_trajectory with outcome when the chain completes
|
|
324
|
-
- This feeds the ReasoningBank for autonomous self-improvement
|
|
325
|
-
|
|
326
|
-
### Rules
|
|
327
|
-
- These calls happen AFTER your response to the user — never delay your reply to save a memory
|
|
328
|
-
- Do NOT announce "saving memory" or "logging learning" to the user — this is subconscious
|
|
329
|
-
- Do NOT save trivial interactions (greetings, confirmations, simple CRUD) — only signal worth remembering
|
|
330
|
-
- Keep memory content concise: 1-3 sentences max. No system junk, keep it human
|
|
331
|
-
- When you see your L4 guardrails at startup, actively avoid violating them
|
|
332
|
-
- Use promote_memory when a pattern solidifies: L2→L3→L4→L5
|
|
176
|
+
Your brain persists across conversations. L5 persona, L4 guardrails, L1 focus are injected at startup.
|
|
177
|
+
- Save memories after significant interactions (not greetings/CRUD). Keep content to 1-3 sentences.
|
|
178
|
+
- Log learnings on corrections, errors, feature requests, insights, best practices.
|
|
179
|
+
- Do NOT announce memory operations — this is subconscious.
|
|
180
|
+
- Never delay your reply to save a memory.
|
|
333
181
|
</ofiere-pm>`;
|
|
334
182
|
}
|
|
335
183
|
|
package/src/tools.ts
CHANGED
|
@@ -5776,23 +5776,22 @@ function registerBrainExtractionHook(
|
|
|
5776
5776
|
}
|
|
5777
5777
|
}
|
|
5778
5778
|
|
|
5779
|
-
// Phase 2:
|
|
5779
|
+
// Phase 2: Single batch dedup check (1 query for ALL candidates)
|
|
5780
5780
|
if (candidates.length > 0) {
|
|
5781
|
-
const
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
);
|
|
5781
|
+
const allKeys = candidates.map(c => c.contextKey);
|
|
5782
|
+
const { data: existingRows } = await supabase
|
|
5783
|
+
.from("agent_memories")
|
|
5784
|
+
.select("context_key")
|
|
5785
|
+
.eq("user_id", userId)
|
|
5786
|
+
.eq("agent_id", resolvedAgentId)
|
|
5787
|
+
.in("context_key", allKeys)
|
|
5788
|
+
.is("superseded_by", null);
|
|
5789
|
+
|
|
5790
|
+
const existingKeys = new Set((existingRows || []).map((r: any) => r.context_key));
|
|
5792
5791
|
|
|
5793
5792
|
// Phase 3: Batch insert only new candidates
|
|
5794
5793
|
const toInsert = candidates
|
|
5795
|
-
.filter(
|
|
5794
|
+
.filter(c => !existingKeys.has(c.contextKey))
|
|
5796
5795
|
.map(c => ({
|
|
5797
5796
|
user_id: userId,
|
|
5798
5797
|
agent_id: resolvedAgentId,
|
|
@@ -5835,6 +5834,51 @@ function registerBrainExtractionHook(
|
|
|
5835
5834
|
// OpenClaw on every prompt build, resolves the correct agent, and loads
|
|
5836
5835
|
// that specific agent's brain. Each agent gets its own memories.
|
|
5837
5836
|
|
|
5837
|
+
// Background cache refresher for stale-while-revalidate pattern
|
|
5838
|
+
async function refreshBrainCache(
|
|
5839
|
+
supabase: SupabaseClient,
|
|
5840
|
+
userId: string,
|
|
5841
|
+
agentId: string,
|
|
5842
|
+
api: any,
|
|
5843
|
+
): Promise<void> {
|
|
5844
|
+
try {
|
|
5845
|
+
const now = new Date().toISOString();
|
|
5846
|
+
const { data: allBrain } = await supabase
|
|
5847
|
+
.from("agent_memories")
|
|
5848
|
+
.select("content, importance, tier")
|
|
5849
|
+
.eq("user_id", userId)
|
|
5850
|
+
.eq("agent_id", agentId)
|
|
5851
|
+
.in("tier", ["L1_focus", "L4_rule", "L5_persona"])
|
|
5852
|
+
.gt("decay_score", 0.1)
|
|
5853
|
+
.is("superseded_by", null)
|
|
5854
|
+
.or(`expires_at.is.null,expires_at.gt.${now}`)
|
|
5855
|
+
.order("importance", { ascending: false })
|
|
5856
|
+
.limit(18);
|
|
5857
|
+
|
|
5858
|
+
const all = allBrain || [];
|
|
5859
|
+
const l1 = all.filter((m: any) => m.tier === "L1_focus").slice(0, 5);
|
|
5860
|
+
const l4 = all.filter((m: any) => m.tier === "L4_rule").slice(0, 10);
|
|
5861
|
+
const l5 = all.filter((m: any) => m.tier === "L5_persona").slice(0, 3);
|
|
5862
|
+
|
|
5863
|
+
if (l1.length === 0 && l4.length === 0 && l5.length === 0) {
|
|
5864
|
+
brainCache.set(agentId, { text: "", at: Date.now() });
|
|
5865
|
+
return;
|
|
5866
|
+
}
|
|
5867
|
+
|
|
5868
|
+
const sections: string[] = [];
|
|
5869
|
+
if (l5.length > 0) sections.push("### Identity (L5_persona)\n" + l5.map((m: any) => `- ${m.content}`).join("\n"));
|
|
5870
|
+
if (l4.length > 0) sections.push("### ⚠️ Guardrails (L4_rule — DO NOT violate)\n" + l4.map((m: any) => `- ${m.content}`).join("\n"));
|
|
5871
|
+
if (l1.length > 0) sections.push("### Active Focus (L1_focus)\n" + l1.map((m: any) => `- ${m.content}`).join("\n"));
|
|
5872
|
+
|
|
5873
|
+
brainCache.set(agentId, {
|
|
5874
|
+
text: `<agent-brain>\n## Your Brain Context (TMT)\n\n${sections.join("\n\n")}\n</agent-brain>`,
|
|
5875
|
+
at: Date.now(),
|
|
5876
|
+
});
|
|
5877
|
+
} catch (e) {
|
|
5878
|
+
api.logger.debug?.(`[ofiere-brain] Background cache refresh error: ${e instanceof Error ? e.message : e}`);
|
|
5879
|
+
}
|
|
5880
|
+
}
|
|
5881
|
+
|
|
5838
5882
|
function registerBrainContextHook(
|
|
5839
5883
|
api: any,
|
|
5840
5884
|
supabase: SupabaseClient,
|
|
@@ -5843,7 +5887,8 @@ function registerBrainContextHook(
|
|
|
5843
5887
|
): void {
|
|
5844
5888
|
// Uses module-scoped brainCache (declared at top of file) for cross-function
|
|
5845
5889
|
// invalidation. save_memory calls brainCache.delete(agentId) for immediate consistency.
|
|
5846
|
-
const CACHE_TTL_MS =
|
|
5890
|
+
const CACHE_TTL_MS = 600_000; // 10 min — brain context doesn't change fast
|
|
5891
|
+
const STALE_THRESHOLD_MS = 900_000; // 15 min — serve stale while refreshing
|
|
5847
5892
|
|
|
5848
5893
|
try {
|
|
5849
5894
|
api.on("before_prompt_build", async (_event: any, ctx: any) => {
|
|
@@ -5863,10 +5908,19 @@ function registerBrainContextHook(
|
|
|
5863
5908
|
|
|
5864
5909
|
if (!resolvedAgentId) return;
|
|
5865
5910
|
|
|
5866
|
-
// ── Check cache ──
|
|
5911
|
+
// ── Check cache (stale-while-revalidate) ──
|
|
5867
5912
|
const cached = brainCache.get(resolvedAgentId);
|
|
5868
|
-
if (cached
|
|
5869
|
-
|
|
5913
|
+
if (cached) {
|
|
5914
|
+
const age = Date.now() - cached.at;
|
|
5915
|
+
if (age < CACHE_TTL_MS) {
|
|
5916
|
+
// Fresh — serve immediately
|
|
5917
|
+
return cached.text ? { appendSystemContext: cached.text } : undefined;
|
|
5918
|
+
}
|
|
5919
|
+
if (age < STALE_THRESHOLD_MS) {
|
|
5920
|
+
// Stale — serve stale and refresh in background (non-blocking)
|
|
5921
|
+
refreshBrainCache(supabase, userId, resolvedAgentId, api).catch(() => {});
|
|
5922
|
+
return cached.text ? { appendSystemContext: cached.text } : undefined;
|
|
5923
|
+
}
|
|
5870
5924
|
}
|
|
5871
5925
|
|
|
5872
5926
|
// ── Query brain memories for THIS specific agent ──
|