kairos-chain 2.3.1 → 2.4.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: 9e8935769926dfd8587c4c2c7fbb2e21cbc5b68b354b6837adba6dd58860e3eb
4
- data.tar.gz: 16ebe9f8141a3be43e9c33b7566f74ef4962f18a30c441967642bae4f2e09150
3
+ metadata.gz: 52819cfdb42eed0ec8b3c0789cd19b44458dfb5446f24beb25d2ef21df7d6d75
4
+ data.tar.gz: 0bdfc0afa6c20c8a6b93fd348e0fbe99ccdfe81a950c158127ef526d28287c7a
5
5
  SHA512:
6
- metadata.gz: 447c01e56eab57ac93784805cb05b9d9c3e81ce10277a8936efb2ad2a932eafa8d01b64c3084e4c03747ee6aa4075bed6615c4b137207e764dd4d55d6763c058
7
- data.tar.gz: a3b16ccd244acdff5abe65ebd2bb265f01209fe0c6cc71eeeaaede80e0d34da5e7c417eacca442f97cd2f172530bf8e070388db0e2011ad137e1f609dad3e9d0
6
+ metadata.gz: 5144b19067b3a7361581312ccb2d99c0b137c8b6d2291c40b762149232f3bf42fa8ae365c28ba3580b36acda43d9e914d7e0de14c1ca5c4231213c49d565a314
7
+ data.tar.gz: 81d99fb9024bf56b4c3080a6c61def85d98ccb91169d14071a23aeee02cc080701077098be547a6aede583f554f4ccd3a6050b11d2927a32543cc5a14d0e8381
data/CHANGELOG.md CHANGED
@@ -4,6 +4,29 @@ All notable changes to the `kairos-chain` gem will be documented in this file.
4
4
 
5
5
  This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [2.4.0] - 2026-03-03
8
+
9
+ ### Added
10
+
11
+ - **Dynamic Persona Suggestion** (`skills_promote` command: `"suggest"`): New 2-step workflow where the LLM analyzes source content and suggests optimal personas (type and count) before running Persona Assembly. Generates a structured suggestion template with content preview, available personas, and YAML response format.
12
+
13
+ - **Custom Persona Support**: Both `skills_promote` and `skills_audit` now accept arbitrary custom persona names in the `personas` parameter. The LLM infers roles from persona names and context when no pre-defined definition exists.
14
+
15
+ - **Improved Unknown Persona Handling**:
16
+ - `skills_promote`: Unknown personas now show "(custom persona — no pre-defined definition. Infer role from name and evaluate accordingly.)" instead of "(definition not found)"
17
+ - `skills_audit`: Unknown personas get a rich template with humanized name, inferred focus, and key insight fields
18
+
19
+ ---
20
+
21
+ ## [2.3.1] - 2026-03-03
22
+
23
+ ### Fixed
24
+
25
+ - **Tutorial mode activation**: Mark `kairos_tutorial.md` as ACTIVE when tutorial mode is set
26
+ - **SystemUpgrade**: Add missing `require 'fileutils'` and resolve gem-internal template paths
27
+
28
+ ---
29
+
7
30
  ## [2.3.0] - 2026-03-03
8
31
 
9
32
  ### Added
@@ -261,6 +284,9 @@ This project follows [Semantic Versioning](https://semver.org/).
261
284
  - Skill promotion with Persona Assembly
262
285
  - Tool guide and metadata system
263
286
 
287
+ [2.4.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.3.1...v2.4.0
288
+ [2.3.1]: https://github.com/masaomi/KairosChain_2026/compare/v2.3.0...v2.3.1
289
+ [2.3.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.2.0...v2.3.0
264
290
  [2.2.0]: https://github.com/masaomi/KairosChain_2026/compare/v2.1.0...v2.2.0
265
291
  [2.0.5]: https://github.com/masaomi/KairosChain_2026/compare/v2.0.4...v2.0.5
266
292
  [2.0.4]: https://github.com/masaomi/KairosChain_2026/compare/v2.0.3...v2.0.4
@@ -131,7 +131,8 @@ module KairosMcp
131
131
  builtin = PROTECTED_FILES.include?(basename)
132
132
  active = (mode == current_mode) ||
133
133
  (current_mode == 'developer' && basename == 'kairos.md') ||
134
- (current_mode == 'user' && basename == 'kairos_quickguide.md')
134
+ (current_mode == 'user' && basename == 'kairos_quickguide.md') ||
135
+ (current_mode == 'tutorial' && basename == 'kairos_tutorial.md')
135
136
  { file: basename, mode: mode, size: File.size(f), builtin: builtin, active: active }
136
137
  end
137
138
 
@@ -114,7 +114,7 @@ module KairosMcp
114
114
  personas: {
115
115
  type: 'array',
116
116
  items: { type: 'string' },
117
- description: 'Personas for assembly (default: ["archivist", "guardian", "promoter"])'
117
+ description: 'Personas for assembly (default: ["archivist", "guardian", "promoter"]). Pre-defined: archivist, guardian, promoter. Custom persona names are also accepted — the LLM will infer the role from the name and context.'
118
118
  },
119
119
  facilitator: {
120
120
  type: 'string',
@@ -882,11 +882,15 @@ module KairosMcp
882
882
  - **Candidates**: [Specific items ready for promotion]
883
883
  TEMPLATE
884
884
  else
885
+ # Custom persona: generate a descriptive template inferring role from name
886
+ humanized = persona.to_s.split(/[_\-]/).map(&:capitalize).join(' ')
885
887
  <<~TEMPLATE
886
-
887
- #### #{persona}
888
+
889
+ #### #{persona} (#{humanized} — Custom Persona)
890
+ - **Inferred focus**: Based on the name "#{persona}", evaluate from this perspective
888
891
  - **Position**: [SUPPORT / OPPOSE / NEUTRAL]
889
- - **Assessment**: [Evaluation]
892
+ - **Assessment**: [Evaluation from the #{humanized} perspective]
893
+ - **Key insight**: [What unique perspective does this role bring?]
890
894
  TEMPLATE
891
895
  end
892
896
  end
@@ -54,6 +54,10 @@ module KairosMcp
54
54
  {
55
55
  title: 'Check promotion requirements',
56
56
  code: 'skills_promote(command: "status", from_layer: "L1", to_layer: "L0")'
57
+ },
58
+ {
59
+ title: 'Suggest optimal personas for content',
60
+ code: 'skills_promote(command: "suggest", source_name: "my_context", from_layer: "L2", to_layer: "L1", session_id: "session_123")'
57
61
  }
58
62
  ]
59
63
  end
@@ -68,8 +72,8 @@ module KairosMcp
68
72
  properties: {
69
73
  command: {
70
74
  type: 'string',
71
- description: 'Command: "analyze" (with assembly), "promote" (direct promotion), or "status" (check promotion requirements)',
72
- enum: %w[analyze promote status]
75
+ description: 'Command: "analyze" (with assembly), "promote" (direct promotion), "status" (check requirements), or "suggest" (LLM suggests optimal personas for content)',
76
+ enum: %w[analyze promote status suggest]
73
77
  },
74
78
  source_name: {
75
79
  type: 'string',
@@ -100,7 +104,7 @@ module KairosMcp
100
104
  personas: {
101
105
  type: 'array',
102
106
  items: { type: 'string' },
103
- description: 'Personas to use for assembly (default: ["kairos"]). Available: kairos, conservative, radical, pragmatic, optimistic, skeptic'
107
+ description: 'Personas to use for assembly (default: ["kairos"]). Pre-defined: kairos, conservative, radical, pragmatic, optimistic, skeptic. Custom persona names are also accepted — the LLM will infer the role from the name and context. Use command: "suggest" to get context-aware recommendations.'
104
108
  },
105
109
  assembly_mode: {
106
110
  type: 'string',
@@ -134,6 +138,8 @@ module KairosMcp
134
138
  handle_promote(arguments)
135
139
  when 'status'
136
140
  handle_status(arguments)
141
+ when 'suggest'
142
+ handle_suggest(arguments)
137
143
  else
138
144
  text_content("Unknown command: #{command}")
139
145
  end
@@ -225,6 +231,85 @@ module KairosMcp
225
231
  text_content(output)
226
232
  end
227
233
 
234
+ # Suggest optimal personas based on source content analysis
235
+ def handle_suggest(args)
236
+ validation = validate_promotion_args(args)
237
+ return text_content("Error: #{validation[:error]}") unless validation[:valid]
238
+
239
+ source_content = fetch_source_content(args)
240
+ return text_content("Error: #{source_content[:error]}") if source_content[:error]
241
+
242
+ persona_definitions = load_persona_definitions
243
+ definitions_text = persona_definitions[:definitions] || default_persona_definitions
244
+
245
+ content_preview = source_content[:content].lines.first(30).join
246
+ content_preview += "\n...(truncated)" if source_content[:content].lines.size > 30
247
+
248
+ output = <<~MD
249
+ ## Persona Suggestion Request
250
+
251
+ ### Promotion Context
252
+
253
+ | Field | Value |
254
+ |-------|-------|
255
+ | **Source** | #{args['source_name']} (#{args['from_layer']}) |
256
+ | **Target** | #{args['target_name'] || args['source_name']} (#{args['to_layer']}) |
257
+
258
+ ### Source Content Preview
259
+
260
+ ```
261
+ #{content_preview}
262
+ ```
263
+
264
+ ### Available Pre-defined Personas
265
+
266
+ #{definitions_text}
267
+
268
+ ---
269
+
270
+ ### Instructions
271
+
272
+ Based on the source content above, please suggest the optimal persona combination for evaluating this promotion. Consider:
273
+
274
+ 1. **Content domain**: What expertise areas does this content touch? (e.g., genomics, security, philosophy, infrastructure)
275
+ 2. **Risk level**: How significant is this promotion? (L2→L1 is lower risk than L1→L0)
276
+ 3. **Persona selection**: Choose from pre-defined personas above, or propose new custom personas with clear role descriptions
277
+ 4. **Persona count**: Suggest 2-5 personas depending on complexity
278
+
279
+ ### Response Format
280
+
281
+ Please respond with:
282
+
283
+ ```yaml
284
+ suggested_personas:
285
+ - name: "persona_name"
286
+ reason: "Why this persona is relevant"
287
+ - name: "another_persona"
288
+ reason: "Why this persona is relevant"
289
+ recommended_mode: "oneshot" # or "discussion" for complex/high-risk promotions
290
+ rationale: "Brief explanation of why this combination is optimal"
291
+ ```
292
+
293
+ ### Next Step
294
+
295
+ After reviewing the suggestion, run:
296
+
297
+ ```
298
+ skills_promote(
299
+ command: "analyze",
300
+ source_name: "#{args['source_name']}",
301
+ from_layer: "#{args['from_layer']}",
302
+ to_layer: "#{args['to_layer']}",
303
+ #{args['session_id'] ? "session_id: \"#{args['session_id']}\"," : ''}
304
+ personas: ["suggested_persona_1", "suggested_persona_2", ...],
305
+ assembly_mode: "suggested_mode"
306
+ )
307
+ ```
308
+ MD
309
+
310
+ text_content(output)
311
+ end
312
+
228
313
  def validate_promotion_args(args)
229
314
  source_name = args['source_name']
230
315
  from_layer = args['from_layer']
@@ -466,7 +551,7 @@ module KairosMcp
466
551
  if match
467
552
  "**#{persona}**:\n#{match[1].strip.lines.first(5).join}"
468
553
  else
469
- "**#{persona}**: (definition not found)"
554
+ "**#{persona}**: (custom persona — no pre-defined definition. Infer role from name and evaluate accordingly.)"
470
555
  end
471
556
  end
472
557
 
@@ -1,4 +1,4 @@
1
1
  module KairosMcp
2
- VERSION = "2.3.1"
2
+ VERSION = "2.4.0"
3
3
  CHANGELOG_URL = "https://github.com/masaomi/KairosChain_2026/blob/main/CHANGELOG.md"
4
4
  end
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: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masa Hatakeyama
@@ -269,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
269
  - !ruby/object:Gem::Version
270
270
  version: '0'
271
271
  requirements: []
272
- rubygems_version: 3.5.22
272
+ rubygems_version: 3.3.26
273
273
  signing_key:
274
274
  specification_version: 4
275
275
  summary: KairosChain - Memory-driven agent framework with blockchain auditability