kairos-chain 3.6.1 → 3.6.2
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/kairos_mcp/version.rb +1 -1
- data/templates/skillsets/agent/config/agent.yml +6 -0
- data/templates/skillsets/agent/test/test_agent_capability_discovery.rb +307 -0
- data/templates/skillsets/agent/tools/agent_step.rb +47 -6
- data/templates/skillsets/document_authoring/knowledge/agent_capability_document_authoring/agent_capability_document_authoring.md +57 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70e5ff9eff0a25ceba4e38cf6bdb7f0c7fb45bd1f11b9345148625fe86b48be2
|
|
4
|
+
data.tar.gz: 7de3d8c8b819cc86ab3847a60250ecc98fe1bf66077a10a9f43521910f51480b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d8385510f0309d0705ac2a311da86f05c62332b77cf0f4cc7a0de7d271863f73e9137320d5d7470d5552c0b3da441500c178b7f3d5d8abd6e0b253ce7d562ed
|
|
7
|
+
data.tar.gz: f298792554a96d5da897523d9b6342d3fef2bc06e4d9a86d54a829c611fe5885fe6896168f7fc1853e3565bc2f4e71ed86d3740b39b898aaa4b0afc3c5337f4b
|
data/lib/kairos_mcp/version.rb
CHANGED
|
@@ -39,5 +39,11 @@ tool_blacklist:
|
|
|
39
39
|
- "mcp_connect"
|
|
40
40
|
- "mcp_disconnect"
|
|
41
41
|
|
|
42
|
+
# Additional tools available during ORIENT phase (opt-in from SkillSets).
|
|
43
|
+
# Adding tools here increases the set the LLM can call during ORIENT;
|
|
44
|
+
# the per-phase budget (max_tool_calls) is unchanged.
|
|
45
|
+
orient_tools_extra: []
|
|
46
|
+
# - document_status # uncomment to enable draft checking during ORIENT
|
|
47
|
+
|
|
42
48
|
# Audit
|
|
43
49
|
audit_level: summary
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Test suite for Agent Capability Discovery (orient_tools, build_tool_catalog)
|
|
5
|
+
# Usage: ruby test_agent_capability_discovery.rb
|
|
6
|
+
|
|
7
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __dir__)
|
|
8
|
+
$LOAD_PATH.unshift File.expand_path('../../../../lib', __dir__)
|
|
9
|
+
|
|
10
|
+
require 'json'
|
|
11
|
+
require 'yaml'
|
|
12
|
+
require 'fileutils'
|
|
13
|
+
require 'tmpdir'
|
|
14
|
+
require 'kairos_mcp/invocation_context'
|
|
15
|
+
require 'kairos_mcp/tools/base_tool'
|
|
16
|
+
require 'kairos_mcp/tool_registry'
|
|
17
|
+
require_relative '../lib/agent'
|
|
18
|
+
require_relative '../tools/agent_start'
|
|
19
|
+
require_relative '../tools/agent_step'
|
|
20
|
+
|
|
21
|
+
$pass = 0
|
|
22
|
+
$fail = 0
|
|
23
|
+
|
|
24
|
+
def assert(description, &block)
|
|
25
|
+
result = block.call
|
|
26
|
+
if result
|
|
27
|
+
$pass += 1
|
|
28
|
+
puts " PASS: #{description}"
|
|
29
|
+
else
|
|
30
|
+
$fail += 1
|
|
31
|
+
puts " FAIL: #{description}"
|
|
32
|
+
end
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
$fail += 1
|
|
35
|
+
puts " FAIL: #{description} (#{e.class}: #{e.message})"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def section(title)
|
|
39
|
+
puts "\n#{'=' * 60}"
|
|
40
|
+
puts "TEST: #{title}"
|
|
41
|
+
puts '=' * 60
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
TMPDIR = Dir.mktmpdir('agent_cap_test')
|
|
45
|
+
|
|
46
|
+
# Stubs
|
|
47
|
+
module Autonomos
|
|
48
|
+
def self.storage_path(subpath)
|
|
49
|
+
path = File.join(TMPDIR, subpath)
|
|
50
|
+
FileUtils.mkdir_p(path)
|
|
51
|
+
path
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
module Mandate
|
|
55
|
+
def self.create(**kwargs); { mandate_id: 'test_mandate' }; end
|
|
56
|
+
def self.load(id); { mandate_id: id, max_cycles: 3, risk_budget: 'low', recent_gap_descriptions: [] }; end
|
|
57
|
+
def self.save(id, data); end
|
|
58
|
+
def self.update_status(id, status); end
|
|
59
|
+
def self.record_cycle(id, **kwargs); end
|
|
60
|
+
def self.risk_exceeds_budget?(proposal, budget); false; end
|
|
61
|
+
def self.loop_detected?(proposal, gaps); false; end
|
|
62
|
+
def self.check_termination(mandate); nil; end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
module Ooda
|
|
66
|
+
def observe(goal_name); { 'status' => 'observed' }; end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
module Autoexec
|
|
71
|
+
def self.config; {}; end
|
|
72
|
+
class TaskDsl
|
|
73
|
+
def self.from_json(json_string)
|
|
74
|
+
data = JSON.parse(json_string, symbolize_names: true)
|
|
75
|
+
data
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
Session = KairosMcp::SkillSets::Agent::Session
|
|
81
|
+
|
|
82
|
+
# =========================================================================
|
|
83
|
+
# Build test infrastructure
|
|
84
|
+
# =========================================================================
|
|
85
|
+
|
|
86
|
+
# Mock registry with some tools
|
|
87
|
+
class CapTestRegistry
|
|
88
|
+
def initialize(tools = [])
|
|
89
|
+
@tools = tools
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def list_tools
|
|
93
|
+
@tools
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def call_tool(name, arguments, invocation_context: nil)
|
|
97
|
+
[{ text: '{}' }]
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Create an AgentStep instance with custom registry
|
|
102
|
+
def build_agent_step(registry: nil, safety: nil)
|
|
103
|
+
step = KairosMcp::SkillSets::Agent::Tools::AgentStep.new(safety, registry: registry)
|
|
104
|
+
step
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Create a session with custom config
|
|
108
|
+
def build_session(config_overrides = {})
|
|
109
|
+
config = {
|
|
110
|
+
'phases' => {},
|
|
111
|
+
'tool_blacklist' => %w[agent_* autonomos_*]
|
|
112
|
+
}.merge(config_overrides)
|
|
113
|
+
|
|
114
|
+
ctx = KairosMcp::InvocationContext.new(
|
|
115
|
+
blacklist: config['tool_blacklist'],
|
|
116
|
+
mandate_id: 'test_mandate'
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
Session.new(
|
|
120
|
+
session_id: "test_#{rand(10000)}",
|
|
121
|
+
mandate_id: 'test_mandate',
|
|
122
|
+
goal_name: 'test_goal',
|
|
123
|
+
invocation_context: ctx,
|
|
124
|
+
config: config
|
|
125
|
+
)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# =========================================================================
|
|
129
|
+
# 1. orient_tools
|
|
130
|
+
# =========================================================================
|
|
131
|
+
|
|
132
|
+
section "orient_tools"
|
|
133
|
+
|
|
134
|
+
assert("T1: returns base tools when no orient_tools_extra") do
|
|
135
|
+
step = build_agent_step
|
|
136
|
+
session = build_session
|
|
137
|
+
tools = step.send(:orient_tools, session)
|
|
138
|
+
tools.include?('knowledge_list') &&
|
|
139
|
+
tools.include?('resource_read') &&
|
|
140
|
+
tools.size == KairosMcp::SkillSets::Agent::Tools::AgentStep::BASE_ORIENT_TOOLS.size
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
assert("T2: merges orient_tools_extra from config") do
|
|
144
|
+
step = build_agent_step
|
|
145
|
+
session = build_session('orient_tools_extra' => ['document_status', 'custom_tool'])
|
|
146
|
+
tools = step.send(:orient_tools, session)
|
|
147
|
+
tools.include?('document_status') &&
|
|
148
|
+
tools.include?('custom_tool') &&
|
|
149
|
+
tools.include?('knowledge_list')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
assert("T3: deduplicates entries") do
|
|
153
|
+
step = build_agent_step
|
|
154
|
+
session = build_session('orient_tools_extra' => ['knowledge_list', 'resource_read'])
|
|
155
|
+
tools = step.send(:orient_tools, session)
|
|
156
|
+
tools.count('knowledge_list') == 1
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
assert("handles nil session gracefully") do
|
|
160
|
+
step = build_agent_step
|
|
161
|
+
tools = step.send(:orient_tools, nil)
|
|
162
|
+
tools == KairosMcp::SkillSets::Agent::Tools::AgentStep::BASE_ORIENT_TOOLS
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# =========================================================================
|
|
166
|
+
# 2. build_tool_catalog
|
|
167
|
+
# =========================================================================
|
|
168
|
+
|
|
169
|
+
section "build_tool_catalog"
|
|
170
|
+
|
|
171
|
+
SAMPLE_TOOLS = [
|
|
172
|
+
{ name: 'write_section', description: 'Write a document section',
|
|
173
|
+
inputSchema: { type: 'object', properties: {}, required: %w[section_name instructions output_file] } },
|
|
174
|
+
{ name: 'document_status', description: 'Show draft file inventory',
|
|
175
|
+
inputSchema: { type: 'object', properties: {}, required: %w[output_dir] } },
|
|
176
|
+
{ name: 'knowledge_get', description: 'Get L1 knowledge',
|
|
177
|
+
inputSchema: { type: 'object', properties: {}, required: %w[name] } },
|
|
178
|
+
{ name: 'agent_start', description: 'Start agent session',
|
|
179
|
+
inputSchema: { type: 'object', properties: {}, required: %w[goal_name] } },
|
|
180
|
+
{ name: 'autonomos_loop', description: 'Run autonomos loop',
|
|
181
|
+
inputSchema: { type: 'object', properties: {} } }
|
|
182
|
+
].freeze
|
|
183
|
+
|
|
184
|
+
assert("T4: excludes blacklisted tools") do
|
|
185
|
+
registry = CapTestRegistry.new(SAMPLE_TOOLS)
|
|
186
|
+
step = build_agent_step(registry: registry)
|
|
187
|
+
session = build_session
|
|
188
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
189
|
+
!catalog.include?('agent_start') && !catalog.include?('autonomos_loop')
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
assert("T5: includes non-blacklisted tools with descriptions and required params") do
|
|
193
|
+
registry = CapTestRegistry.new(SAMPLE_TOOLS)
|
|
194
|
+
step = build_agent_step(registry: registry)
|
|
195
|
+
session = build_session
|
|
196
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
197
|
+
catalog.include?('write_section') &&
|
|
198
|
+
catalog.include?('section_name, instructions, output_file') &&
|
|
199
|
+
catalog.include?('document_status') &&
|
|
200
|
+
catalog.include?('knowledge_get')
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
assert("T6: returns fallback when no registry") do
|
|
204
|
+
step = build_agent_step(registry: nil)
|
|
205
|
+
session = build_session
|
|
206
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
207
|
+
catalog.include?('no registry')
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
assert("T7: exact blacklist match works") do
|
|
211
|
+
tools = [{ name: 'skills_evolve', description: 'Evolve skills', inputSchema: {} }]
|
|
212
|
+
registry = CapTestRegistry.new(tools)
|
|
213
|
+
step = build_agent_step(registry: registry)
|
|
214
|
+
session = build_session('tool_blacklist' => %w[skills_evolve])
|
|
215
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
216
|
+
!catalog.include?('skills_evolve')
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
assert("T8: wildcard blacklist via fnmatch works") do
|
|
220
|
+
tools = [
|
|
221
|
+
{ name: 'chain_migrate_execute', description: 'Migrate', inputSchema: {} },
|
|
222
|
+
{ name: 'chain_history', description: 'History', inputSchema: {} }
|
|
223
|
+
]
|
|
224
|
+
registry = CapTestRegistry.new(tools)
|
|
225
|
+
step = build_agent_step(registry: registry)
|
|
226
|
+
session = build_session('tool_blacklist' => %w[chain_migrate_*])
|
|
227
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
228
|
+
!catalog.include?('chain_migrate_execute') && catalog.include?('chain_history')
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
assert("handles namespaced tool names (basename blacklist)") do
|
|
232
|
+
tools = [{ name: 'peer1/agent_start', description: 'Remote agent start', inputSchema: {} }]
|
|
233
|
+
registry = CapTestRegistry.new(tools)
|
|
234
|
+
step = build_agent_step(registry: registry)
|
|
235
|
+
session = build_session # blacklist includes agent_*
|
|
236
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
237
|
+
# InvocationContext.allowed? checks basename — should be filtered
|
|
238
|
+
!catalog.include?('peer1/agent_start')
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# =========================================================================
|
|
242
|
+
# 3. extract_required_params
|
|
243
|
+
# =========================================================================
|
|
244
|
+
|
|
245
|
+
section "extract_required_params"
|
|
246
|
+
|
|
247
|
+
assert("T11: handles symbol keys") do
|
|
248
|
+
step = build_agent_step
|
|
249
|
+
params = step.send(:extract_required_params, { required: %w[name version] })
|
|
250
|
+
params == %w[name version]
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
assert("T11b: handles string keys") do
|
|
254
|
+
step = build_agent_step
|
|
255
|
+
params = step.send(:extract_required_params, { 'required' => %w[output_dir] })
|
|
256
|
+
params == %w[output_dir]
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
assert("handles nil schema") do
|
|
260
|
+
step = build_agent_step
|
|
261
|
+
params = step.send(:extract_required_params, nil)
|
|
262
|
+
params == []
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
assert("handles schema without required") do
|
|
266
|
+
step = build_agent_step
|
|
267
|
+
params = step.send(:extract_required_params, { type: 'object', properties: {} })
|
|
268
|
+
params == []
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# =========================================================================
|
|
272
|
+
# 4. build_decide_prompt integration
|
|
273
|
+
# =========================================================================
|
|
274
|
+
|
|
275
|
+
section "build_decide_prompt integration"
|
|
276
|
+
|
|
277
|
+
assert("T9: build_decide_prompt includes Available Tools section") do
|
|
278
|
+
registry = CapTestRegistry.new(SAMPLE_TOOLS)
|
|
279
|
+
step = build_agent_step(registry: registry)
|
|
280
|
+
session = build_session
|
|
281
|
+
orient_result = { 'content' => 'The goal requires writing a grant application.' }
|
|
282
|
+
prompt = step.send(:build_decide_prompt, session, orient_result)
|
|
283
|
+
prompt.include?('## Available Tools') &&
|
|
284
|
+
prompt.include?('write_section') &&
|
|
285
|
+
prompt.include?('Use ONLY tools listed above')
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
assert("T10: run_decide_with_feedback messages include catalog") do
|
|
289
|
+
# We can't easily run the full method (needs LLM), but we can verify
|
|
290
|
+
# the method exists and check the code path
|
|
291
|
+
step = build_agent_step(registry: CapTestRegistry.new(SAMPLE_TOOLS))
|
|
292
|
+
session = build_session
|
|
293
|
+
catalog = step.send(:build_tool_catalog, session)
|
|
294
|
+
catalog.include?('write_section') && catalog.include?('document_status')
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# =========================================================================
|
|
298
|
+
# Cleanup
|
|
299
|
+
# =========================================================================
|
|
300
|
+
|
|
301
|
+
FileUtils.rm_rf(TMPDIR)
|
|
302
|
+
|
|
303
|
+
puts "\n#{'=' * 60}"
|
|
304
|
+
puts "RESULTS: #{$pass} passed, #{$fail} failed (#{$pass + $fail} total)"
|
|
305
|
+
puts '=' * 60
|
|
306
|
+
|
|
307
|
+
exit($fail > 0 ? 1 : 0)
|
|
@@ -8,9 +8,9 @@ module KairosMcp
|
|
|
8
8
|
module Agent
|
|
9
9
|
module Tools
|
|
10
10
|
class AgentStep < KairosMcp::Tools::BaseTool
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
BASE_ORIENT_TOOLS = %w[knowledge_list knowledge_get chain_history
|
|
12
|
+
skills_list resource_list resource_read context_save
|
|
13
|
+
mcp_list_remote].freeze
|
|
14
14
|
|
|
15
15
|
def name
|
|
16
16
|
'agent_step'
|
|
@@ -150,7 +150,7 @@ module KairosMcp
|
|
|
150
150
|
orient_prompt = build_orient_prompt(session, observation_text)
|
|
151
151
|
messages = [{ 'role' => 'user', 'content' => orient_prompt }]
|
|
152
152
|
|
|
153
|
-
orient_result = loop_inst.run_phase('orient', orient_system_prompt, messages,
|
|
153
|
+
orient_result = loop_inst.run_phase('orient', orient_system_prompt, messages, orient_tools(session))
|
|
154
154
|
return error_with_state(session, 'observed', orient_result) if orient_result['error']
|
|
155
155
|
|
|
156
156
|
# DECIDE (single-stage; see design v0.4 sec 3.3 for future extension)
|
|
@@ -329,11 +329,16 @@ module KairosMcp
|
|
|
329
329
|
prior_decision = session.load_decision
|
|
330
330
|
prior_json = prior_decision ? JSON.generate(prior_decision) : '(none)'
|
|
331
331
|
|
|
332
|
+
# Include tool catalog so revise path has same tool awareness as initial DECIDE
|
|
333
|
+
catalog = build_tool_catalog(session)
|
|
334
|
+
|
|
332
335
|
messages = [
|
|
333
336
|
{ 'role' => 'user', 'content' =>
|
|
337
|
+
"## Available Tools\n#{catalog}\n\n" \
|
|
334
338
|
"Previous plan:\n#{prior_json}\n\n" \
|
|
335
339
|
"This plan was rejected. Feedback: #{feedback}\n\n" \
|
|
336
|
-
"Please revise the plan and output a new decision_payload as JSON."
|
|
340
|
+
"Please revise the plan and output a new decision_payload as JSON. " \
|
|
341
|
+
"Use ONLY tools listed above." }
|
|
337
342
|
]
|
|
338
343
|
decide_result = loop_inst.run_decide(decide_system_prompt, messages)
|
|
339
344
|
return error_with_state(session, 'proposed', decide_result) if decide_result['error']
|
|
@@ -442,8 +447,12 @@ module KairosMcp
|
|
|
442
447
|
|
|
443
448
|
def build_decide_prompt(session, orient_result)
|
|
444
449
|
analysis = orient_result['content'] || orient_result.to_json
|
|
450
|
+
catalog = build_tool_catalog(session)
|
|
451
|
+
|
|
445
452
|
"Based on this analysis:\n#{analysis}\n\n" \
|
|
446
|
-
"
|
|
453
|
+
"## Available Tools\n#{catalog}\n\n" \
|
|
454
|
+
"Create a task execution plan as JSON (decision_payload format). " \
|
|
455
|
+
"Use ONLY tools listed above."
|
|
447
456
|
end
|
|
448
457
|
|
|
449
458
|
def build_reflect_prompt(session, act_result)
|
|
@@ -452,6 +461,38 @@ module KairosMcp
|
|
|
452
461
|
"Evaluate: what was achieved, what remains, confidence level (0.0-1.0)."
|
|
453
462
|
end
|
|
454
463
|
|
|
464
|
+
# ---- Capability Discovery ----
|
|
465
|
+
|
|
466
|
+
# Config-driven ORIENT tools: base + optional extras from agent.yml
|
|
467
|
+
def orient_tools(session)
|
|
468
|
+
extra = session&.config&.dig('orient_tools_extra') || []
|
|
469
|
+
(BASE_ORIENT_TOOLS + extra).uniq
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
# Build a filtered tool catalog for DECIDE prompt.
|
|
473
|
+
# Uses session's InvocationContext.allowed? for blacklist/whitelist
|
|
474
|
+
# consistency with the ACT phase execution policy.
|
|
475
|
+
def build_tool_catalog(session)
|
|
476
|
+
return "(no registry available)" unless @registry
|
|
477
|
+
|
|
478
|
+
ctx = session&.invocation_context
|
|
479
|
+
tools = @registry.list_tools
|
|
480
|
+
tools = tools.reject { |t| ctx && !ctx.allowed?(t[:name]) } if ctx
|
|
481
|
+
|
|
482
|
+
tools.map { |t|
|
|
483
|
+
required = extract_required_params(t[:inputSchema])
|
|
484
|
+
params_str = required.empty? ? '' : " (params: #{required.join(', ')})"
|
|
485
|
+
"- **#{t[:name]}**#{params_str}: #{t[:description]}"
|
|
486
|
+
}.join("\n")
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Extract required parameter names from an inputSchema hash.
|
|
490
|
+
def extract_required_params(schema)
|
|
491
|
+
return [] unless schema.is_a?(Hash)
|
|
492
|
+
required = schema[:required] || schema['required'] || []
|
|
493
|
+
required.map(&:to_s)
|
|
494
|
+
end
|
|
495
|
+
|
|
455
496
|
# ---- Helpers ----
|
|
456
497
|
|
|
457
498
|
def load_last_decision(session)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [agent-capability, document-authoring]
|
|
3
|
+
version: "1.0"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Capability: Document Authoring
|
|
7
|
+
|
|
8
|
+
## When to use
|
|
9
|
+
|
|
10
|
+
The user asks to write, draft, or create structured documents such as:
|
|
11
|
+
- Grant applications (e.g., UZH fellowship, SNF, ERC)
|
|
12
|
+
- Research papers or manuscripts
|
|
13
|
+
- Technical reports
|
|
14
|
+
- Project proposals
|
|
15
|
+
|
|
16
|
+
Keywords: write, draft, create, application, grant, paper, report, proposal, document
|
|
17
|
+
|
|
18
|
+
## Tools
|
|
19
|
+
|
|
20
|
+
- `write_section`: Write a document section using LLM with L1/L2 context injection
|
|
21
|
+
- `document_status`: Check existing draft files and word counts
|
|
22
|
+
|
|
23
|
+
## Typical task pattern
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"task_id": "write_grant_draft",
|
|
28
|
+
"meta": { "description": "Write grant application sections", "risk_default": "low" },
|
|
29
|
+
"steps": [
|
|
30
|
+
{
|
|
31
|
+
"step_id": "write_abstract",
|
|
32
|
+
"action": "Write project abstract",
|
|
33
|
+
"tool_name": "write_section",
|
|
34
|
+
"tool_arguments": {
|
|
35
|
+
"section_name": "abstract",
|
|
36
|
+
"instructions": "Write a concise project abstract covering motivation, approach, and expected impact",
|
|
37
|
+
"context_sources": ["knowledge://project_description"],
|
|
38
|
+
"output_file": "grant_draft/01_abstract.md",
|
|
39
|
+
"max_words": 250
|
|
40
|
+
},
|
|
41
|
+
"risk": "low", "depends_on": []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"step_id": "check_status",
|
|
45
|
+
"action": "Verify all sections written",
|
|
46
|
+
"tool_name": "document_status",
|
|
47
|
+
"tool_arguments": { "output_dir": "grant_draft/" },
|
|
48
|
+
"risk": "low", "depends_on": ["write_abstract"]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Context sources
|
|
55
|
+
|
|
56
|
+
Use `knowledge://` URIs for project-level context and `context://` URIs for
|
|
57
|
+
session-specific context (e.g., previous grant feedback).
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kairos-chain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.6.
|
|
4
|
+
version: 3.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Masaomi Hatakeyama
|
|
@@ -213,6 +213,7 @@ files:
|
|
|
213
213
|
- templates/skillsets/agent/lib/agent/message_format.rb
|
|
214
214
|
- templates/skillsets/agent/lib/agent/session.rb
|
|
215
215
|
- templates/skillsets/agent/skillset.json
|
|
216
|
+
- templates/skillsets/agent/test/test_agent_capability_discovery.rb
|
|
216
217
|
- templates/skillsets/agent/test/test_agent_m1.rb
|
|
217
218
|
- templates/skillsets/agent/test/test_agent_m2.rb
|
|
218
219
|
- templates/skillsets/agent/test/test_agent_m3.rb
|
|
@@ -245,6 +246,7 @@ files:
|
|
|
245
246
|
- templates/skillsets/autonomos/tools/autonomos_reflect.rb
|
|
246
247
|
- templates/skillsets/autonomos/tools/autonomos_status.rb
|
|
247
248
|
- templates/skillsets/document_authoring/config/document_authoring.yml
|
|
249
|
+
- templates/skillsets/document_authoring/knowledge/agent_capability_document_authoring/agent_capability_document_authoring.md
|
|
248
250
|
- templates/skillsets/document_authoring/knowledge/document_authoring_guide/document_authoring_guide.md
|
|
249
251
|
- templates/skillsets/document_authoring/lib/document_authoring.rb
|
|
250
252
|
- templates/skillsets/document_authoring/lib/document_authoring/context_assembler.rb
|