agentf 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6072a9a176fba8e2376b10cc125d78d450057c90c4aa5d95158797429504d1f5
4
- data.tar.gz: f66dc58d0030e1ba289d3f7046811190b9ae818aca61021729c9da12d19e710c
3
+ metadata.gz: ace5a58ed6bfb8389d1e7a68349d7cc9f8d80b4093131a8cf2013388b001a08d
4
+ data.tar.gz: ba9a86b1c4b9e7e7edf62bed089d5cb3a1dddb9c5b4282c16e9be27438fec088
5
5
  SHA512:
6
- metadata.gz: '0397d2603cc060239303773b370f14cc9585b94b4ba5109207ac7f705b18aec244f83443478c15c1ed40be4650c20f9f13d669f224dfc916374e924da4ab6cb1'
7
- data.tar.gz: a8f7562d3bc1f8bd43897b4692c18a4096509d2c4ce413eaa1c992c61c2a7fada7c0c52228c543d62387c9a56c37672819f1becfd39240bc83066491947678f8
6
+ metadata.gz: 35767581d0b7561c1800464909dbf00524724527148b20f4f1ab911d846301d1a60333e8703d7b3db04e7d3d34e1a977d522fef236f8899692ae8a8c2bac65ad
7
+ data.tar.gz: 8d61e62517723d4bc4d39905dfb87b792d27ba1bfbe2b1eb6c445409b138091d072413ad21bffbe2cd584887d9a75f798df64f79601594ccb1029e9db54439f1
@@ -9,7 +9,7 @@ module Agentf
9
9
  DESCRIPTION = "Strategy, task decomposition, and memory retrieval."
10
10
  COMMANDS = %w[glob read_file memory].freeze
11
11
  MEMORY_CONCEPTS = {
12
- "reads" => ["get_recent_memories", "get_pitfalls"],
12
+ "reads" => ["get_recent_memories", "get_episodes"],
13
13
  "writes" => [],
14
14
  "policy" => "Retrieve relevant memories before planning; do not duplicate runtime memory into static markdown."
15
15
  }.freeze
@@ -44,7 +44,7 @@ module Agentf
44
44
 
45
45
  def self.policy_boundaries
46
46
  {
47
- "always" => ["Capture constraints before decomposition", "Use recent memories and pitfalls in planning"],
47
+ "always" => ["Capture constraints before decomposition", "Use recent memories and negative episodes in planning"],
48
48
  "ask_first" => ["Changing architectural style from project defaults"],
49
49
  "never" => ["Skip task decomposition for non-trivial workflows"],
50
50
  "required_inputs" => [],
@@ -57,7 +57,7 @@ module Agentf
57
57
 
58
58
  # Retrieve relevant memories before planning
59
59
  recent = memory.get_recent_memories(limit: 5)
60
- pitfalls = memory.get_pitfalls(limit: 3)
60
+ pitfalls = memory.get_episodes(limit: 3, outcome: "negative")
61
61
 
62
62
  context = {
63
63
  "task" => task,
@@ -32,8 +32,8 @@ module Agentf
32
32
 
33
33
  def self.memory_concepts
34
34
  {
35
- "reads" => ["RedisMemory#get_recent_memories", "RedisMemory#get_pitfalls"],
36
- "writes" => ["RedisMemory#store_lesson", "RedisMemory#store_success", "RedisMemory#store_pitfall"],
35
+ "reads" => ["RedisMemory#get_recent_memories", "RedisMemory#get_episodes"],
36
+ "writes" => ["RedisMemory#store_lesson", "RedisMemory#store_episode", "RedisMemory#store_playbook"],
37
37
  "policy" => "Memory is runtime state in Redis and should not be embedded as raw data in manifest markdown."
38
38
  }
39
39
  end
@@ -66,13 +66,12 @@ module Agentf
66
66
 
67
67
  analysis = @commands.parse_error(error)
68
68
 
69
- res = safe_memory_write(attempted: { action: "store_lesson", title: "Debugged: #{error[0..50]}...", tags: ["debugging", "error", "fix"], agent: name }) do
69
+ res = safe_memory_write(attempted: { action: "store_lesson", title: "Debugged: #{error[0..50]}...", agent: name }) do
70
70
  memory.store_episode(
71
71
  type: "lesson",
72
72
  title: "Debugged: #{error[0..50]}...",
73
73
  description: "Root cause: #{analysis.possible_causes.first}. Fix: #{analysis.suggested_fix}",
74
74
  context: context.to_s,
75
- tags: ["debugging", "error", "fix"],
76
75
  agent: name
77
76
  )
78
77
  end
@@ -11,7 +11,7 @@ module Agentf
11
11
  COMMANDS = %w[generate_component validate_design_system].freeze
12
12
  MEMORY_CONCEPTS = {
13
13
  "reads" => [],
14
- "writes" => ["store_success"],
14
+ "writes" => ["store_episode"],
15
15
  "policy" => "Capture successful design implementation patterns."
16
16
  }.freeze
17
17
 
@@ -64,13 +64,14 @@ module Agentf
64
64
 
65
65
  spec = @commands.generate_component("GeneratedComponent", design_spec)
66
66
 
67
- res = safe_memory_write(attempted: { action: "store_success", title: "Implemented design: #{design_spec}", tags: ["design", "ui", framework], agent: name }) do
68
- memory.store_success(
67
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Implemented design: #{design_spec}", outcome: "positive", agent: name }) do
68
+ memory.store_episode(
69
+ type: "episode",
69
70
  title: "Implemented design: #{design_spec}",
70
71
  description: "Created #{spec.name} in #{spec.framework}",
71
72
  context: "Framework: #{framework}",
72
- tags: ["design", "ui", framework],
73
- agent: name
73
+ agent: name,
74
+ outcome: "positive"
74
75
  )
75
76
  end
76
77
 
@@ -57,8 +57,8 @@ module Agentf
57
57
 
58
58
  memories = memory.get_recent_memories(limit: 20)
59
59
 
60
- successes = memories.select { |m| m["type"] == "success" }
61
- pitfalls = memories.select { |m| m["type"] == "pitfall" }
60
+ successes = memories.select { |m| m["type"] == "episode" && m["outcome"] == "positive" }
61
+ pitfalls = memories.select { |m| m["type"] == "episode" && m["outcome"] == "negative" }
62
62
 
63
63
  log "Found #{successes.size} successes"
64
64
  log "Found #{pitfalls.size} pitfalls"
@@ -63,12 +63,11 @@ module Agentf
63
63
 
64
64
  files = @commands.glob(query, file_types: nil)
65
65
 
66
- res = safe_memory_write(attempted: { action: "store_lesson", title: "Research finding: #{query}", tags: ["research", "exploration"], agent: name }) do
66
+ res = safe_memory_write(attempted: { action: "store_lesson", title: "Research finding: #{query}", agent: name }) do
67
67
  memory.store_lesson(
68
68
  title: "Research finding: #{query}",
69
69
  description: "Found #{files.size} relevant files during exploration",
70
70
  context: "Search pattern: #{file_pattern || 'all files'}",
71
- tags: ["research", "exploration"],
72
71
  agent: name
73
72
  )
74
73
  end
@@ -9,9 +9,9 @@ module Agentf
9
9
  DESCRIPTION = "Quality assurance and regression checking against memory."
10
10
  COMMANDS = %w[read_file memory].freeze
11
11
  MEMORY_CONCEPTS = {
12
- "reads" => ["get_pitfalls", "get_recent_memories"],
12
+ "reads" => ["get_episodes", "get_recent_memories"],
13
13
  "writes" => [],
14
- "policy" => "Validate outputs against known pitfalls before approval."
14
+ "policy" => "Validate outputs against known negative episodes before approval."
15
15
  }.freeze
16
16
 
17
17
  def self.description
@@ -56,14 +56,14 @@ module Agentf
56
56
  execute_with_contract(context: { "execution" => subtask_result }) do
57
57
  log "Reviewing subtask #{subtask_result['subtask_id']}"
58
58
 
59
- pitfalls = memory.get_pitfalls(limit: 5)
60
- memories = memory.get_recent_memories(limit: 5)
59
+ pitfalls = memory.get_episodes(limit: 5, outcome: "negative")
60
+ memories = memory.get_recent_memories(limit: 5)
61
61
 
62
62
  issues = []
63
63
 
64
- pitfalls.each do |pitfall|
65
- issues << "Warning: Known pitfall - #{pitfall['title']}" if pitfall["type"] == "pitfall"
66
- end
64
+ pitfalls.each do |pitfall|
65
+ issues << "Warning: Known negative episode - #{pitfall['title']}" if pitfall["type"] == "episode"
66
+ end
67
67
 
68
68
  approved = issues.empty?
69
69
 
@@ -11,7 +11,7 @@ module Agentf
11
11
  COMMANDS = %w[scan best_practices].freeze
12
12
  MEMORY_CONCEPTS = {
13
13
  "reads" => [],
14
- "writes" => ["store_success", "store_pitfall"],
14
+ "writes" => ["store_episode"],
15
15
  "policy" => "Record findings while redacting sensitive values."
16
16
  }.freeze
17
17
 
@@ -66,24 +66,26 @@ module Agentf
66
66
  summary = summarize_findings(findings)
67
67
 
68
68
  if findings["issues"].empty?
69
- res = safe_memory_write(attempted: { action: "store_success", title: "Security review passed", tags: ["security", "pass"], agent: name }) do
70
- memory.store_success(
69
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Security review passed", outcome: "positive", agent: name }) do
70
+ memory.store_episode(
71
+ type: "episode",
71
72
  title: "Security review passed",
72
73
  description: summary,
73
74
  context: task,
74
- tags: ["security", "pass"],
75
- agent: name
75
+ agent: name,
76
+ outcome: "positive"
76
77
  )
77
78
  end
78
79
  return findings.merge(res) if res.is_a?(Hash) && res["confirmation_required"]
79
80
  else
80
- res = safe_memory_write(attempted: { action: "store_pitfall", title: "Security findings detected", tags: ["security", "warning"], agent: name }) do
81
- memory.store_pitfall(
81
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Security findings detected", outcome: "negative", agent: name }) do
82
+ memory.store_episode(
83
+ type: "episode",
82
84
  title: "Security findings detected",
83
85
  description: summary,
84
86
  context: task,
85
- tags: ["security", "warning"],
86
- agent: name
87
+ agent: name,
88
+ outcome: "negative"
87
89
  )
88
90
  end
89
91
  return findings.merge(res) if res.is_a?(Hash) && res["confirmation_required"]
@@ -10,7 +10,7 @@ module Agentf
10
10
  COMMANDS = %w[read_file write_file run_command].freeze
11
11
  MEMORY_CONCEPTS = {
12
12
  "reads" => [],
13
- "writes" => ["store_success", "store_pitfall"],
13
+ "writes" => ["store_episode"],
14
14
  "policy" => "Persist execution outcomes as lessons for downstream agents."
15
15
  }.freeze
16
16
 
@@ -66,13 +66,14 @@ module Agentf
66
66
  success = normalized_subtask.fetch("success", true)
67
67
 
68
68
  if success
69
- res = safe_memory_write(attempted: { action: "store_success", title: "Completed: #{normalized_subtask['description']}", tags: ["implementation", normalized_subtask.fetch("language", "general")], agent: name }) do
70
- memory.store_success(
69
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Completed: #{normalized_subtask['description']}", outcome: "positive", agent: name }) do
70
+ memory.store_episode(
71
+ type: "episode",
71
72
  title: "Completed: #{normalized_subtask['description']}",
72
73
  description: "Successfully executed subtask #{normalized_subtask['id']}",
73
74
  context: "Working on #{normalized_subtask.fetch('task', 'unknown task')}",
74
- tags: ["implementation", normalized_subtask.fetch("language", "general")],
75
- agent: name
75
+ agent: name,
76
+ outcome: "positive"
76
77
  )
77
78
  end
78
79
 
@@ -81,13 +82,14 @@ module Agentf
81
82
  return { "subtask_id" => normalized_subtask["id"], "success" => success, "result" => "Code executed", "confirmation_required" => true, "confirmation_details" => res["confirmation_details"], "attempted" => res["attempted"] }
82
83
  end
83
84
  else
84
- res = safe_memory_write(attempted: { action: "store_pitfall", title: "Failed: #{normalized_subtask['description']}", tags: ["failure", "implementation"], agent: name }) do
85
- memory.store_pitfall(
85
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Failed: #{normalized_subtask['description']}", outcome: "negative", agent: name }) do
86
+ memory.store_episode(
87
+ type: "episode",
86
88
  title: "Failed: #{normalized_subtask['description']}",
87
89
  description: "Subtask #{normalized_subtask['id']} failed",
88
90
  context: "Working on #{normalized_subtask.fetch('task', 'unknown task')}",
89
- tags: ["failure", "implementation"],
90
- agent: name
91
+ agent: name,
92
+ outcome: "negative"
91
93
  )
92
94
  end
93
95
 
@@ -11,7 +11,7 @@ module Agentf
11
11
  COMMANDS = %w[detect_framework generate_unit_tests run_tests].freeze
12
12
  MEMORY_CONCEPTS = {
13
13
  "reads" => [],
14
- "writes" => ["store_success"],
14
+ "writes" => ["store_episode"],
15
15
  "policy" => "Persist test generation outcomes for future reuse."
16
16
  }.freeze
17
17
 
@@ -63,13 +63,14 @@ module Agentf
63
63
 
64
64
  template = @commands.generate_unit_tests(code_file)
65
65
 
66
- res = safe_memory_write(attempted: { action: "store_success", title: "Generated #{test_type} tests for #{code_file}", tags: ["testing", test_type, code_file.split(".").last], agent: name }) do
67
- memory.store_success(
66
+ res = safe_memory_write(attempted: { action: "store_episode", title: "Generated #{test_type} tests for #{code_file}", outcome: "positive", agent: name }) do
67
+ memory.store_episode(
68
+ type: "episode",
68
69
  title: "Generated #{test_type} tests for #{code_file}",
69
70
  description: "Created #{template.test_file} with #{test_type} tests",
70
71
  context: "Test framework: #{template.framework}",
71
- tags: ["testing", test_type, code_file.split(".").last],
72
- agent: name
72
+ agent: name,
73
+ outcome: "positive"
73
74
  )
74
75
  end
75
76
 
@@ -113,7 +113,7 @@ module Agentf
113
113
 
114
114
  Examples:
115
115
  agentf eval list
116
- agentf eval run engineer_store_success
116
+ agentf eval run engineer_episode_positive
117
117
  agentf eval report
118
118
  agentf eval run all --json
119
119
  HELP
@@ -13,7 +13,7 @@ module Agentf
13
13
  class Memory
14
14
  include ArgParser
15
15
 
16
- VALID_EPISODE_TYPES = %w[pitfall lesson success business_intent feature_intent].freeze
16
+ VALID_EPISODE_TYPES = %w[episode lesson playbook business_intent feature_intent incident].freeze
17
17
 
18
18
  def initialize(reviewer: nil, memory: nil)
19
19
  @reviewer = reviewer || Commands::MemoryReviewer.new
@@ -28,12 +28,10 @@ module Agentf
28
28
  case command
29
29
  when "recent", "list"
30
30
  list_memories(args)
31
- when "pitfalls"
32
- list_pitfalls(args)
31
+ when "episodes"
32
+ list_episodes(args)
33
33
  when "lessons"
34
34
  list_lessons(args)
35
- when "successes"
36
- list_successes(args)
37
35
  when "intents"
38
36
  list_intents(args)
39
37
  when "business-intents"
@@ -44,14 +42,10 @@ module Agentf
44
42
  add_business_intent(args)
45
43
  when "add-feature-intent"
46
44
  add_feature_intent(args)
45
+ when "add-playbook"
46
+ add_playbook(args)
47
47
  when "add-lesson"
48
48
  add_episode("lesson", args)
49
- when "add-success"
50
- add_episode("success", args)
51
- when "add-pitfall"
52
- add_episode("pitfall", args)
53
- when "tags"
54
- list_tags
55
49
  when "search"
56
50
  search_memories(args)
57
51
  when "delete"
@@ -62,8 +56,6 @@ module Agentf
62
56
  subgraph(args)
63
57
  when "summary", "stats"
64
58
  show_summary
65
- when "by-tag"
66
- by_tag(args)
67
59
  when "by-agent"
68
60
  by_agent(args)
69
61
  when "by-type"
@@ -86,9 +78,10 @@ module Agentf
86
78
  output(result)
87
79
  end
88
80
 
89
- def list_pitfalls(args)
81
+ def list_episodes(args)
90
82
  limit = extract_limit(args)
91
- result = @reviewer.get_pitfalls(limit: limit)
83
+ outcome = parse_single_option(args, "--outcome=")
84
+ result = @reviewer.get_episodes(limit: limit, outcome: outcome)
92
85
  output(result)
93
86
  end
94
87
 
@@ -98,12 +91,6 @@ module Agentf
98
91
  output(result)
99
92
  end
100
93
 
101
- def list_successes(args)
102
- limit = extract_limit(args)
103
- result = @reviewer.get_successes(limit: limit)
104
- output(result)
105
- end
106
-
107
94
  def list_intents(args)
108
95
  limit = extract_limit(args)
109
96
  kind = args.shift
@@ -141,16 +128,14 @@ module Agentf
141
128
  exit 1
142
129
  end
143
130
 
144
- tags = parse_list_option(args, "--tags=")
145
131
  constraints = parse_list_option(args, "--constraints=")
146
132
  priority = parse_integer_option(args, "--priority=", default: 1)
147
133
 
148
134
  id = nil
149
- res = safe_cli_memory_write(@memory, attempted: { command: "add-business-intent", args: { title: title, description: description, tags: tags, constraints: constraints, priority: priority } }) do
135
+ res = safe_cli_memory_write(@memory, attempted: { command: "add-business-intent", args: { title: title, description: description, constraints: constraints, priority: priority } }) do
150
136
  id = @memory.store_business_intent(
151
137
  title: title,
152
138
  description: description,
153
- tags: tags,
154
139
  constraints: constraints,
155
140
  priority: priority
156
141
  )
@@ -181,17 +166,15 @@ module Agentf
181
166
  exit 1
182
167
  end
183
168
 
184
- tags = parse_list_option(args, "--tags=")
185
169
  acceptance_criteria = parse_list_option(args, "--acceptance=")
186
170
  non_goals = parse_list_option(args, "--non-goals=")
187
171
  related_task_id = parse_single_option(args, "--task=")
188
172
 
189
173
  id = nil
190
- res = safe_cli_memory_write(@memory, attempted: { command: "add-feature-intent", args: { title: title, description: description, tags: tags, acceptance: acceptance_criteria, non_goals: non_goals, related_task_id: related_task_id } }) do
174
+ res = safe_cli_memory_write(@memory, attempted: { command: "add-feature-intent", args: { title: title, description: description, acceptance: acceptance_criteria, non_goals: non_goals, related_task_id: related_task_id } }) do
191
175
  id = @memory.store_feature_intent(
192
176
  title: title,
193
177
  description: description,
194
- tags: tags,
195
178
  acceptance_criteria: acceptance_criteria,
196
179
  non_goals: non_goals,
197
180
  related_task_id: related_task_id
@@ -214,6 +197,46 @@ module Agentf
214
197
  end
215
198
  end
216
199
 
200
+ def add_playbook(args)
201
+ title = args.shift
202
+ description = args.shift
203
+
204
+ if title.to_s.empty? || description.to_s.empty?
205
+ $stderr.puts "Error: add-playbook requires <title> <description>"
206
+ exit 1
207
+ end
208
+
209
+ steps = parse_list_option(args, "--steps=")
210
+ feature_area = parse_single_option(args, "--feature-area=")
211
+ agent = parse_single_option(args, "--agent=") || Agentf::AgentRoles::PLANNER
212
+
213
+ id = nil
214
+ res = safe_cli_memory_write(@memory, attempted: { command: "add-playbook", args: { title: title, description: description, steps: steps, feature_area: feature_area, agent: agent } }) do
215
+ id = @memory.store_playbook(
216
+ title: title,
217
+ description: description,
218
+ steps: steps,
219
+ feature_area: feature_area,
220
+ agent: agent
221
+ )
222
+ end
223
+
224
+ if res.is_a?(Hash) && res["confirmation_required"]
225
+ if @json_output
226
+ puts JSON.generate(res)
227
+ else
228
+ $stderr.puts "Confirmation required to store playbook: #{res['confirmation_details'].inspect}"
229
+ end
230
+ return
231
+ end
232
+
233
+ if @json_output
234
+ puts JSON.generate({ "id" => id, "type" => "playbook", "status" => "stored" })
235
+ else
236
+ puts "Stored playbook: #{id}"
237
+ end
238
+ end
239
+
217
240
  def add_episode(type, args)
218
241
  title = args.shift
219
242
  description = args.shift
@@ -223,21 +246,21 @@ module Agentf
223
246
  exit 1
224
247
  end
225
248
 
226
- tags = parse_list_option(args, "--tags=")
227
249
  context = parse_single_option(args, "--context=").to_s
228
250
  agent = parse_single_option(args, "--agent=") || Agentf::AgentRoles::ENGINEER
229
251
  code_snippet = parse_single_option(args, "--code=").to_s
252
+ outcome = parse_single_option(args, "--outcome=")
230
253
 
231
254
  id = nil
232
- res = safe_cli_memory_write(@memory, attempted: { command: "add-#{type}", args: { title: title, description: description, tags: tags, context: context, agent: agent, code: code_snippet } }) do
255
+ res = safe_cli_memory_write(@memory, attempted: { command: "add-#{type}", args: { title: title, description: description, context: context, agent: agent, code: code_snippet, outcome: outcome } }) do
233
256
  id = @memory.store_episode(
234
257
  type: type,
235
258
  title: title,
236
259
  description: description,
237
260
  context: context,
238
- tags: tags,
239
261
  agent: agent,
240
- code_snippet: code_snippet
262
+ code_snippet: code_snippet,
263
+ outcome: outcome
241
264
  )
242
265
  end
243
266
 
@@ -273,21 +296,6 @@ module Agentf
273
296
  end
274
297
  end
275
298
 
276
- def list_tags
277
- result = @reviewer.get_all_tags
278
- if @json_output
279
- puts JSON.generate(result)
280
- return
281
- end
282
-
283
- if result["tags"].empty?
284
- puts "No tags found."
285
- else
286
- puts "Tags (#{result["count"]}):"
287
- result["tags"].each { |tag| puts " - #{tag}" }
288
- end
289
- end
290
-
291
299
  def search_memories(args)
292
300
  # Extract limit BEFORE joining remaining args as query (fixes finding #7)
293
301
  limit = extract_limit(args)
@@ -318,19 +326,12 @@ module Agentf
318
326
  puts ""
319
327
  puts "By agent:"
320
328
  result["by_agent"].each { |agent, count| puts " #{agent}: #{count}" }
321
- puts ""
322
- puts "Unique tags: #{result["unique_tags"]}"
323
- end
324
329
 
325
- def by_tag(args)
326
- tag = args.shift
327
- if tag.nil? || tag.empty?
328
- $stderr.puts "Error: by-tag requires a tag name"
329
- exit 1
330
+ if result["by_outcome"].is_a?(Hash)
331
+ puts ""
332
+ puts "By outcome:"
333
+ result["by_outcome"].each { |outcome, count| puts " #{outcome}: #{count}" }
330
334
  end
331
- limit = extract_limit(args)
332
- result = @reviewer.get_by_tag(tag, limit: limit)
333
- output(result)
334
335
  end
335
336
 
336
337
  def by_agent(args)
@@ -540,8 +541,8 @@ module Agentf
540
541
  [#{mem["type"]&.upcase}] #{mem["title"]}
541
542
  #{mem["created_at"]} by #{mem["agent"]}
542
543
  #{mem["description"]}
544
+ #{"Outcome: #{mem['outcome']}" unless mem["outcome"].to_s.empty?}
543
545
  #{format_code(mem["code_snippet"]) unless mem["code_snippet"].to_s.empty?}
544
- Tags: #{mem["tags"]&.join(", ") || "none"}
545
546
  OUTPUT
546
547
  end
547
548
 
@@ -557,26 +558,22 @@ module Agentf
557
558
 
558
559
  Commands:
559
560
  recent, list List recent memories (default: 10)
560
- pitfalls List pitfalls (things that went wrong)
561
+ episodes List episode memories
561
562
  lessons List lessons learned
562
- successes List successes
563
563
  intents [kind] List intents (kind: business|feature)
564
564
  business-intents List business intents
565
565
  feature-intents List feature intents
566
566
  add-business-intent Store business intent
567
567
  add-feature-intent Store feature intent
568
+ add-playbook Store playbook memory
568
569
  add-lesson Store lesson memory
569
- add-success Store success memory
570
- add-pitfall Store pitfall memory
571
- tags List all unique tags
572
- search <query> Search memories by keyword
570
+ search <query> Search memories semantically
573
571
  delete id <memory_id> Delete one memory and related edges
574
572
  delete last -n <count> Delete most recent memories
575
573
  delete all Delete memories and graph/task keys
576
574
  neighbors <id> Traverse graph edges from a memory id
577
575
  subgraph <ids> Build graph from comma-separated seed ids
578
576
  summary, stats Show summary statistics
579
- by-tag <tag> Get memories with specific tag
580
577
  by-agent <agent> Get memories from specific agent
581
578
  by-type <type> Get memories by type (#{VALID_EPISODE_TYPES.join("|")})
582
579
 
@@ -586,18 +583,17 @@ module Agentf
586
583
 
587
584
  Examples:
588
585
  agentf memory recent -n 5
589
- agentf memory pitfalls
586
+ agentf memory episodes --outcome=negative
590
587
  agentf memory intents business -n 5
591
- agentf memory add-business-intent "Reliability" "Prioritize uptime" --tags=ops,platform --constraints="No downtime;No vendor lock-in"
588
+ agentf memory add-business-intent "Reliability" "Prioritize uptime" --constraints="No downtime;No vendor lock-in"
592
589
  agentf memory add-feature-intent "Agent handoff" "Improve orchestrator continuity" --acceptance="Keeps context;Preserves task state"
593
- agentf memory add-lesson "Refactor strategy" "Extracted adapter seam" --agent=PLANNER --tags=architecture
594
- agentf memory add-success "Provider install works" "Installed copilot + opencode manifests" --agent=ENGINEER
590
+ agentf memory add-playbook "Release rollout" "Safe deploy sequence" --steps="deploy canary;monitor;promote"
591
+ agentf memory add-lesson "Refactor strategy" "Extracted adapter seam" --agent=PLANNER
595
592
  agentf memory search "react"
596
593
  agentf memory delete id episode_abcd
597
594
  agentf memory delete last -n 10 --scope=project
598
595
  agentf memory delete all --scope=all --yes
599
596
  agentf memory neighbors episode_abcd --depth=2
600
- agentf memory by-tag "performance"
601
597
  agentf memory summary
602
598
  HELP
603
599
  end
@@ -75,7 +75,7 @@ module Agentf
75
75
  Usage: agentf <command> [subcommand] [options]
76
76
 
77
77
  Commands:
78
- memory Manage agent memory (lessons, pitfalls, successes, intents)
78
+ memory Manage agent memory (episodes, lessons, playbooks, intents)
79
79
  code Explore codebase (glob, grep, tree, related files)
80
80
  metrics Show workflow success and provider parity metrics
81
81
  architecture Analyze architecture layers and violations