agentf 0.3.0 → 0.4.1
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 +4 -4
- data/lib/agentf/agent_roles.rb +29 -0
- data/lib/agentf/agents/architect.rb +16 -0
- data/lib/agentf/agents/base.rb +12 -0
- data/lib/agentf/agents/debugger.rb +16 -0
- data/lib/agentf/agents/designer.rb +16 -0
- data/lib/agentf/agents/documenter.rb +16 -0
- data/lib/agentf/agents/explorer.rb +16 -0
- data/lib/agentf/agents/reviewer.rb +16 -0
- data/lib/agentf/agents/security.rb +16 -0
- data/lib/agentf/agents/specialist.rb +16 -0
- data/lib/agentf/agents/tester.rb +16 -0
- data/lib/agentf/cli/memory.rb +164 -3
- data/lib/agentf/cli/router.rb +1 -1
- data/lib/agentf/cli/update.rb +2 -2
- data/lib/agentf/commands/memory_reviewer.rb +18 -1
- data/lib/agentf/commands/metrics.rb +5 -6
- data/lib/agentf/installer.rb +73 -45
- data/lib/agentf/mcp/server.rb +79 -37
- data/lib/agentf/mcp/stub.rb +81 -0
- data/lib/agentf/memory.rb +535 -20
- data/lib/agentf/packs.rb +15 -15
- data/lib/agentf/service/providers.rb +42 -42
- data/lib/agentf/version.rb +1 -1
- data/lib/agentf/workflow_engine.rb +23 -23
- data/lib/agentf.rb +1 -0
- metadata +10 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 289cd869806a950c6bb25a92b56cc05d5f90481f3bbe61af65d97af23768d321
|
|
4
|
+
data.tar.gz: 8f16969b26684677f01d01821c541d14a338b924a310ad9cdd83435e7b7896b3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 230df28afb68ed450b76c16185dc14227342cfc3048ed5ab25183a99aebb57c79833180d6185c3d35d33e89dac9d9a514b8ee6ebbeef8ecf64d3822f34db0b0f
|
|
7
|
+
data.tar.gz: 9347250f29a7402d17ed0784c16387e268461785c02aa1d3f94024bdab6a89f2022a065169b1055f6b168d4a0472a193000e88f5c428ea8ce4757ed2843ff066
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Agentf
|
|
4
|
+
module AgentRoles
|
|
5
|
+
ORCHESTRATOR = "ORCHESTRATOR"
|
|
6
|
+
PLANNER = "PLANNER"
|
|
7
|
+
ENGINEER = "ENGINEER"
|
|
8
|
+
REVIEWER = "REVIEWER"
|
|
9
|
+
KNOWLEDGE_MANAGER = "KNOWLEDGE_MANAGER"
|
|
10
|
+
RESEARCHER = "RESEARCHER"
|
|
11
|
+
QA_TESTER = "QA_TESTER"
|
|
12
|
+
INCIDENT_RESPONDER = "INCIDENT_RESPONDER"
|
|
13
|
+
UI_ENGINEER = "UI_ENGINEER"
|
|
14
|
+
SECURITY_REVIEWER = "SECURITY_REVIEWER"
|
|
15
|
+
|
|
16
|
+
ALL = [
|
|
17
|
+
ORCHESTRATOR,
|
|
18
|
+
PLANNER,
|
|
19
|
+
ENGINEER,
|
|
20
|
+
REVIEWER,
|
|
21
|
+
KNOWLEDGE_MANAGER,
|
|
22
|
+
RESEARCHER,
|
|
23
|
+
QA_TESTER,
|
|
24
|
+
INCIDENT_RESPONDER,
|
|
25
|
+
UI_ENGINEER,
|
|
26
|
+
SECURITY_REVIEWER
|
|
27
|
+
].freeze
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -22,6 +22,22 @@ module Agentf
|
|
|
22
22
|
COMMANDS
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.typed_name
|
|
26
|
+
Agentf::AgentRoles::PLANNER
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.when_to_use
|
|
30
|
+
"Use for planning, decomposition, and constraints mapping before implementation."
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.deliverables
|
|
34
|
+
["Execution plan", "Decomposed subtasks", "Risk and pitfall notes"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.working_style
|
|
38
|
+
"Strategic and constraint-aware with explicit decomposition."
|
|
39
|
+
end
|
|
40
|
+
|
|
25
41
|
def self.memory_concepts
|
|
26
42
|
MEMORY_CONCEPTS
|
|
27
43
|
end
|
data/lib/agentf/agents/base.rb
CHANGED
|
@@ -14,6 +14,18 @@ module Agentf
|
|
|
14
14
|
"Agent for #{typed_name.downcase}"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def self.when_to_use
|
|
18
|
+
"Use when the workflow needs #{typed_name.downcase.tr('_', ' ')} expertise."
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.deliverables
|
|
22
|
+
[]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.working_style
|
|
26
|
+
"Structured, evidence-based, and outcome-oriented."
|
|
27
|
+
end
|
|
28
|
+
|
|
17
29
|
def self.commands
|
|
18
30
|
[]
|
|
19
31
|
end
|
|
@@ -23,6 +23,22 @@ module Agentf
|
|
|
23
23
|
COMMANDS
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.typed_name
|
|
27
|
+
Agentf::AgentRoles::INCIDENT_RESPONDER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.when_to_use
|
|
31
|
+
"Use for incident triage, root-cause analysis, and remediation paths."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.deliverables
|
|
35
|
+
["Root-cause analysis", "Fix guidance", "Incident lesson record"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.working_style
|
|
39
|
+
"Diagnostic, hypothesis-driven, and remediation-focused."
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
def self.memory_concepts
|
|
27
43
|
MEMORY_CONCEPTS
|
|
28
44
|
end
|
|
@@ -23,6 +23,22 @@ module Agentf
|
|
|
23
23
|
COMMANDS
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.typed_name
|
|
27
|
+
Agentf::AgentRoles::UI_ENGINEER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.when_to_use
|
|
31
|
+
"Use for transforming design specs into framework-ready UI components."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.deliverables
|
|
35
|
+
["Component implementation", "Generated UI code", "Design-system alignment"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.working_style
|
|
39
|
+
"Specification-driven with implementation-grade UI output."
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
def self.memory_concepts
|
|
27
43
|
MEMORY_CONCEPTS
|
|
28
44
|
end
|
|
@@ -22,6 +22,22 @@ module Agentf
|
|
|
22
22
|
COMMANDS
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.typed_name
|
|
26
|
+
Agentf::AgentRoles::KNOWLEDGE_MANAGER
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.when_to_use
|
|
30
|
+
"Use for memory synthesis, knowledge rollups, and delivery-ready summaries."
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.deliverables
|
|
34
|
+
["Success summary", "Pitfall summary", "Knowledge digest"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.working_style
|
|
38
|
+
"Concise synthesis with attention to sensitive data boundaries."
|
|
39
|
+
end
|
|
40
|
+
|
|
25
41
|
def self.memory_concepts
|
|
26
42
|
MEMORY_CONCEPTS
|
|
27
43
|
end
|
|
@@ -23,6 +23,22 @@ module Agentf
|
|
|
23
23
|
COMMANDS
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.typed_name
|
|
27
|
+
Agentf::AgentRoles::RESEARCHER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.when_to_use
|
|
31
|
+
"Use for codebase discovery, evidence gathering, and dependency tracing."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.deliverables
|
|
35
|
+
["Relevant file list", "Search evidence", "Context breadcrumbs"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.working_style
|
|
39
|
+
"Fast exploration with concrete references and traceable findings."
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
def self.memory_concepts
|
|
27
43
|
MEMORY_CONCEPTS
|
|
28
44
|
end
|
|
@@ -22,6 +22,22 @@ module Agentf
|
|
|
22
22
|
COMMANDS
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.typed_name
|
|
26
|
+
Agentf::AgentRoles::REVIEWER
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.when_to_use
|
|
30
|
+
"Use for approval decisions, regression checks, and evidence-backed review."
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.deliverables
|
|
34
|
+
["Approval decision", "Issue list", "Pitfall-aligned feedback"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.working_style
|
|
38
|
+
"Evidence-first with explicit approval criteria."
|
|
39
|
+
end
|
|
40
|
+
|
|
25
41
|
def self.memory_concepts
|
|
26
42
|
MEMORY_CONCEPTS
|
|
27
43
|
end
|
|
@@ -23,6 +23,22 @@ module Agentf
|
|
|
23
23
|
COMMANDS
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.typed_name
|
|
27
|
+
Agentf::AgentRoles::SECURITY_REVIEWER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.when_to_use
|
|
31
|
+
"Use for security gating, prompt-injection checks, and secret leak detection."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.deliverables
|
|
35
|
+
["Security findings", "Best-practice checklist", "Pass/warn outcome"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.working_style
|
|
39
|
+
"Risk-focused with redaction-safe reporting."
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
def self.memory_concepts
|
|
27
43
|
MEMORY_CONCEPTS
|
|
28
44
|
end
|
|
@@ -22,6 +22,22 @@ module Agentf
|
|
|
22
22
|
COMMANDS
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.typed_name
|
|
26
|
+
Agentf::AgentRoles::ENGINEER
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.when_to_use
|
|
30
|
+
"Use for implementation, code edits, and deterministic execution outcomes."
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.deliverables
|
|
34
|
+
["Implemented code", "Execution status", "Success or pitfall memory"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.working_style
|
|
38
|
+
"Execution-focused, deterministic, and evidence-driven."
|
|
39
|
+
end
|
|
40
|
+
|
|
25
41
|
def self.memory_concepts
|
|
26
42
|
MEMORY_CONCEPTS
|
|
27
43
|
end
|
data/lib/agentf/agents/tester.rb
CHANGED
|
@@ -23,6 +23,22 @@ module Agentf
|
|
|
23
23
|
COMMANDS
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.typed_name
|
|
27
|
+
Agentf::AgentRoles::QA_TESTER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.when_to_use
|
|
31
|
+
"Use for test generation, red/green validation, and execution verification."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.deliverables
|
|
35
|
+
["Generated test artifacts", "Pass/fail evidence", "TDD phase signals"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.working_style
|
|
39
|
+
"Quality-gate oriented with explicit pass/fail reporting."
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
def self.memory_concepts
|
|
27
43
|
MEMORY_CONCEPTS
|
|
28
44
|
end
|
data/lib/agentf/cli/memory.rb
CHANGED
|
@@ -54,6 +54,12 @@ module Agentf
|
|
|
54
54
|
list_tags
|
|
55
55
|
when "search"
|
|
56
56
|
search_memories(args)
|
|
57
|
+
when "delete"
|
|
58
|
+
delete_memories(args)
|
|
59
|
+
when "neighbors"
|
|
60
|
+
neighbors(args)
|
|
61
|
+
when "subgraph"
|
|
62
|
+
subgraph(args)
|
|
57
63
|
when "summary", "stats"
|
|
58
64
|
show_summary
|
|
59
65
|
when "by-tag"
|
|
@@ -195,7 +201,7 @@ module Agentf
|
|
|
195
201
|
|
|
196
202
|
tags = parse_list_option(args, "--tags=")
|
|
197
203
|
context = parse_single_option(args, "--context=").to_s
|
|
198
|
-
agent = parse_single_option(args, "--agent=") ||
|
|
204
|
+
agent = parse_single_option(args, "--agent=") || Agentf::AgentRoles::ENGINEER
|
|
199
205
|
code_snippet = parse_single_option(args, "--code=").to_s
|
|
200
206
|
|
|
201
207
|
intent_id = @memory.store_episode(
|
|
@@ -297,6 +303,93 @@ module Agentf
|
|
|
297
303
|
output(result)
|
|
298
304
|
end
|
|
299
305
|
|
|
306
|
+
def neighbors(args)
|
|
307
|
+
node_id = args.shift.to_s
|
|
308
|
+
if node_id.empty?
|
|
309
|
+
$stderr.puts "Error: neighbors requires a node id"
|
|
310
|
+
exit 1
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
relation = parse_single_option(args, "--relation=")
|
|
314
|
+
depth = parse_integer_option(args, "--depth=", default: 1)
|
|
315
|
+
limit = extract_limit(args)
|
|
316
|
+
result = @reviewer.neighbors(node_id, relation: relation, depth: depth, limit: limit)
|
|
317
|
+
output_graph(result)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def delete_memories(args)
|
|
321
|
+
mode = args.shift.to_s
|
|
322
|
+
case mode
|
|
323
|
+
when "id"
|
|
324
|
+
delete_by_id(args)
|
|
325
|
+
when "last"
|
|
326
|
+
delete_last(args)
|
|
327
|
+
when "all"
|
|
328
|
+
delete_all(args)
|
|
329
|
+
else
|
|
330
|
+
$stderr.puts "Error: delete requires one of: id|last|all"
|
|
331
|
+
exit 1
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def delete_by_id(args)
|
|
336
|
+
id = args.shift.to_s
|
|
337
|
+
if id.empty?
|
|
338
|
+
$stderr.puts "Error: delete id requires a memory id"
|
|
339
|
+
exit 1
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
scope = parse_scope_option(args)
|
|
343
|
+
dry_run = parse_boolean_flag(args, "--dry-run")
|
|
344
|
+
result = @memory.delete_memory_by_id(id: id, scope: scope, dry_run: dry_run)
|
|
345
|
+
output_delete(result)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def delete_last(args)
|
|
349
|
+
limit = extract_limit(args)
|
|
350
|
+
if limit <= 0
|
|
351
|
+
$stderr.puts "Error: delete last requires -n with value > 0"
|
|
352
|
+
exit 1
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
scope = parse_scope_option(args)
|
|
356
|
+
type = parse_single_option(args, "--type=")
|
|
357
|
+
agent = parse_single_option(args, "--agent=")
|
|
358
|
+
dry_run = parse_boolean_flag(args, "--dry-run")
|
|
359
|
+
result = @memory.delete_recent(limit: limit, scope: scope, type: type, agent: agent, dry_run: dry_run)
|
|
360
|
+
output_delete(result)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def delete_all(args)
|
|
364
|
+
scope = parse_scope_option(args)
|
|
365
|
+
type = parse_single_option(args, "--type=")
|
|
366
|
+
agent = parse_single_option(args, "--agent=")
|
|
367
|
+
dry_run = parse_boolean_flag(args, "--dry-run")
|
|
368
|
+
confirmed = parse_boolean_flag(args, "--yes")
|
|
369
|
+
|
|
370
|
+
if !dry_run && !confirmed
|
|
371
|
+
$stderr.puts "Error: delete all requires --yes (or use --dry-run)"
|
|
372
|
+
exit 1
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
result = @memory.delete_all(scope: scope, type: type, agent: agent, dry_run: dry_run)
|
|
376
|
+
output_delete(result)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def subgraph(args)
|
|
380
|
+
seeds = args.shift.to_s.split(",").map(&:strip).reject(&:empty?)
|
|
381
|
+
if seeds.empty?
|
|
382
|
+
$stderr.puts "Error: subgraph requires comma-separated seed ids"
|
|
383
|
+
exit 1
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
relation_filters = parse_list_option(args, "--relation=")
|
|
387
|
+
depth = parse_integer_option(args, "--depth=", default: 2)
|
|
388
|
+
limit = extract_limit(args, default: 200)
|
|
389
|
+
result = @reviewer.subgraph(seed_ids: seeds, relation_filters: relation_filters, depth: depth, limit: limit)
|
|
390
|
+
output_graph(result)
|
|
391
|
+
end
|
|
392
|
+
|
|
300
393
|
def merge_memory_results(*results, limit:)
|
|
301
394
|
entries = results.flat_map { |result| result["memories"] || [] }
|
|
302
395
|
sorted = entries.sort_by { |entry| -(entry["created_at_unix"] || 0) }
|
|
@@ -331,6 +424,65 @@ module Agentf
|
|
|
331
424
|
end
|
|
332
425
|
end
|
|
333
426
|
|
|
427
|
+
def output_delete(result)
|
|
428
|
+
if result["error"]
|
|
429
|
+
if @json_output
|
|
430
|
+
puts JSON.generate({ "error" => result["error"] })
|
|
431
|
+
else
|
|
432
|
+
$stderr.puts "Error: #{result['error']}"
|
|
433
|
+
end
|
|
434
|
+
exit 1
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
if @json_output
|
|
438
|
+
puts JSON.generate(result)
|
|
439
|
+
return
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
action = result["dry_run"] ? "Planned" : "Deleted"
|
|
443
|
+
puts "#{action} #{result['deleted_count']} keys (candidates: #{result['candidate_count']})"
|
|
444
|
+
puts "Mode: #{result['mode']} | Scope: #{result['scope']}"
|
|
445
|
+
filters = result["filters"] || {}
|
|
446
|
+
puts "Filters: type=#{filters['type'] || 'any'}, agent=#{filters['agent'] || 'any'}"
|
|
447
|
+
ids = Array(result["deleted_ids"])
|
|
448
|
+
puts "Memory ids: #{ids.join(', ')}" unless ids.empty?
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def parse_scope_option(args)
|
|
452
|
+
scope = parse_single_option(args, "--scope=") || "project"
|
|
453
|
+
unless %w[project all].include?(scope)
|
|
454
|
+
$stderr.puts "Error: --scope must be project or all"
|
|
455
|
+
exit 1
|
|
456
|
+
end
|
|
457
|
+
scope
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def parse_boolean_flag(args, flag)
|
|
461
|
+
!args.delete(flag).nil?
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def output_graph(result)
|
|
465
|
+
if result["error"]
|
|
466
|
+
if @json_output
|
|
467
|
+
puts JSON.generate({ "error" => result["error"] })
|
|
468
|
+
else
|
|
469
|
+
$stderr.puts "Error: #{result['error']}"
|
|
470
|
+
end
|
|
471
|
+
exit 1
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
if @json_output
|
|
475
|
+
puts JSON.generate(result)
|
|
476
|
+
return
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
puts "Graph result: #{result['count']} edges"
|
|
480
|
+
puts "Nodes: #{Array(result['nodes']).length}"
|
|
481
|
+
Array(result["edges"]).each do |edge|
|
|
482
|
+
puts " - #{edge['source_id']} --#{edge['relation']}--> #{edge['target_id']}"
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
334
486
|
def format_memory(mem)
|
|
335
487
|
<<~OUTPUT
|
|
336
488
|
[#{mem["type"]&.upcase}] #{mem["title"]}
|
|
@@ -366,6 +518,11 @@ module Agentf
|
|
|
366
518
|
add-pitfall Store pitfall memory
|
|
367
519
|
tags List all unique tags
|
|
368
520
|
search <query> Search memories by keyword
|
|
521
|
+
delete id <memory_id> Delete one memory and related edges
|
|
522
|
+
delete last -n <count> Delete most recent memories
|
|
523
|
+
delete all Delete memories and graph/task keys
|
|
524
|
+
neighbors <id> Traverse graph edges from a memory id
|
|
525
|
+
subgraph <ids> Build graph from comma-separated seed ids
|
|
369
526
|
summary, stats Show summary statistics
|
|
370
527
|
by-tag <tag> Get memories with specific tag
|
|
371
528
|
by-agent <agent> Get memories from specific agent
|
|
@@ -381,9 +538,13 @@ module Agentf
|
|
|
381
538
|
agentf memory intents business -n 5
|
|
382
539
|
agentf memory add-business-intent "Reliability" "Prioritize uptime" --tags=ops,platform --constraints="No downtime;No vendor lock-in"
|
|
383
540
|
agentf memory add-feature-intent "Agent handoff" "Improve orchestrator continuity" --acceptance="Keeps context;Preserves task state"
|
|
384
|
-
agentf memory add-lesson "Refactor strategy" "Extracted adapter seam" --agent=
|
|
385
|
-
agentf memory add-success "Provider install works" "Installed copilot + opencode manifests" --agent=
|
|
541
|
+
agentf memory add-lesson "Refactor strategy" "Extracted adapter seam" --agent=PLANNER --tags=architecture
|
|
542
|
+
agentf memory add-success "Provider install works" "Installed copilot + opencode manifests" --agent=ENGINEER
|
|
386
543
|
agentf memory search "react"
|
|
544
|
+
agentf memory delete id episode_abcd
|
|
545
|
+
agentf memory delete last -n 10 --scope=project
|
|
546
|
+
agentf memory delete all --scope=all --yes
|
|
547
|
+
agentf memory neighbors episode_abcd --depth=2
|
|
387
548
|
agentf memory by-tag "performance"
|
|
388
549
|
agentf memory summary
|
|
389
550
|
HELP
|
data/lib/agentf/cli/router.rb
CHANGED
|
@@ -90,7 +90,7 @@ module Agentf
|
|
|
90
90
|
|
|
91
91
|
Examples:
|
|
92
92
|
agentf memory recent -n 5
|
|
93
|
-
agentf memory add-lesson "Title" "Description" --agent=
|
|
93
|
+
agentf memory add-lesson "Title" "Description" --agent=PLANNER
|
|
94
94
|
agentf code glob "lib/**/*.rb"
|
|
95
95
|
agentf code grep "def execute" --file-pattern=*.rb
|
|
96
96
|
agentf install --provider opencode,copilot --scope local
|
data/lib/agentf/cli/update.rb
CHANGED
|
@@ -138,11 +138,11 @@ module Agentf
|
|
|
138
138
|
|
|
139
139
|
old_files = [
|
|
140
140
|
File.join(opencode_dir, "tools", "agentf-tools.ts"),
|
|
141
|
-
File.join(opencode_dir, "agents", "
|
|
141
|
+
File.join(opencode_dir, "agents", "ORCHESTRATOR.md"),
|
|
142
142
|
File.join(opencode_dir, "memory", "REDIS_SCHEMA.md")
|
|
143
143
|
]
|
|
144
144
|
|
|
145
|
-
old_agent_names = %w[
|
|
145
|
+
old_agent_names = %w[RESEARCHER PLANNER UI_ENGINEER INCIDENT_RESPONDER REVIEWER QA_TESTER KNOWLEDGE_MANAGER SECURITY_REVIEWER ENGINEER]
|
|
146
146
|
old_files.concat(old_agent_names.map { |name| File.join(opencode_dir, "agents", "#{name}.md") })
|
|
147
147
|
|
|
148
148
|
old_command_names = %w[explorer tester metrics security_scanner memory_reviewer designer debugger architecture]
|
|
@@ -23,7 +23,9 @@ module Agentf
|
|
|
23
23
|
{ "name" => "get_by_type", "type" => "function" },
|
|
24
24
|
{ "name" => "get_by_agent", "type" => "function" },
|
|
25
25
|
{ "name" => "search", "type" => "function" },
|
|
26
|
-
{ "name" => "get_summary", "type" => "function" }
|
|
26
|
+
{ "name" => "get_summary", "type" => "function" },
|
|
27
|
+
{ "name" => "neighbors", "type" => "function" },
|
|
28
|
+
{ "name" => "subgraph", "type" => "function" }
|
|
27
29
|
]
|
|
28
30
|
}
|
|
29
31
|
end
|
|
@@ -150,6 +152,18 @@ module Agentf
|
|
|
150
152
|
{ "error" => e.message }
|
|
151
153
|
end
|
|
152
154
|
|
|
155
|
+
def neighbors(node_id, relation: nil, depth: 1, limit: 50)
|
|
156
|
+
@memory.neighbors(node_id: node_id, relation: relation, depth: depth, limit: limit)
|
|
157
|
+
rescue => e
|
|
158
|
+
{ "error" => e.message }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def subgraph(seed_ids:, depth: 2, relation_filters: nil, limit: 200)
|
|
162
|
+
@memory.subgraph(seed_ids: seed_ids, depth: depth, relation_filters: relation_filters, limit: limit)
|
|
163
|
+
rescue => e
|
|
164
|
+
{ "error" => e.message }
|
|
165
|
+
end
|
|
166
|
+
|
|
153
167
|
private
|
|
154
168
|
|
|
155
169
|
def format_memories(memories)
|
|
@@ -169,6 +183,9 @@ module Agentf
|
|
|
169
183
|
"code_snippet" => m["code_snippet"],
|
|
170
184
|
"tags" => m["tags"],
|
|
171
185
|
"agent" => m["agent"],
|
|
186
|
+
"metadata" => m["metadata"],
|
|
187
|
+
"entity_ids" => m["entity_ids"],
|
|
188
|
+
"relationships" => m["relationships"],
|
|
172
189
|
"created_at" => format_time(m["created_at"]),
|
|
173
190
|
"created_at_unix" => m["created_at"]
|
|
174
191
|
}
|
|
@@ -35,7 +35,7 @@ module Agentf
|
|
|
35
35
|
description: metric_description(metrics),
|
|
36
36
|
context: metric_context(metrics),
|
|
37
37
|
tags: metric_tags(metrics),
|
|
38
|
-
agent:
|
|
38
|
+
agent: Agentf::AgentRoles::ORCHESTRATOR,
|
|
39
39
|
code_snippet: ""
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -128,12 +128,12 @@ module Agentf
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
def reviewer_approved?(results)
|
|
131
|
-
review = results.find { |entry| entry["agent"] ==
|
|
131
|
+
review = results.find { |entry| entry["agent"] == Agentf::AgentRoles::REVIEWER }
|
|
132
132
|
review&.dig("result", "approved") == true
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def security_issue_count(results)
|
|
136
|
-
security_result = results.find { |entry| entry["agent"] ==
|
|
136
|
+
security_result = results.find { |entry| entry["agent"] == Agentf::AgentRoles::SECURITY_REVIEWER }
|
|
137
137
|
issues = security_result&.dig("result", "issues")
|
|
138
138
|
Array(issues).length
|
|
139
139
|
end
|
|
@@ -190,12 +190,11 @@ module Agentf
|
|
|
190
190
|
|
|
191
191
|
memories
|
|
192
192
|
.select { |m| Array(m["tags"]).include?(WORKFLOW_METRICS_TAG) }
|
|
193
|
-
.
|
|
193
|
+
.map do |m|
|
|
194
194
|
context = parse_context_json(m["context"])
|
|
195
|
-
next if context.nil?
|
|
196
|
-
|
|
197
195
|
context
|
|
198
196
|
end
|
|
197
|
+
.compact
|
|
199
198
|
end
|
|
200
199
|
|
|
201
200
|
def parse_context_json(value)
|