Module: Insika::Knowledge::Concept

Defined in:
lib/insika/knowledge.rb

Overview

The concept format: markdown with a YAML frontmatter block, parsed and rendered with the SAME split SkillCatalog#parse_content uses, so the Studio's existing markdown editor already curates it.

Constant Summary collapse

NAME_RE =
/\A[a-z0-9]+(-[a-z0-9]+)*\z/

Class Method Summary collapse

Class Method Details

[[name]] references inside a concept's body — the whole "graph" layers 1+2 support: plain text, resolved lazily by name, never a stored structure of its own. Shared by retrieval's one-hop expansion and the GraphML export, so the two readings of "a link" never drift.



220
221
222
# File 'lib/insika/knowledge.rb', line 220

def links(body)
  body.to_s.scan(/\[\[([^\]]+)\]\]/).flatten.map(&:strip).reject(&:empty?).uniq
end

.parse(raw) ⇒ Object

-> { name:, description:, type:, body:, provenance:, confidence:, sources:, occurrences:, created_at:, updated_at: } | nil



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/insika/knowledge.rb', line 185

def parse(raw)
  match = raw.to_s.match(/\A---\s*\n(.*?)\n---\s*\n(.*)\z/m)
  return nil unless match

  meta = Insika::Frontmatter.parse(match[1])
  name = Coercion.presence(meta["name"])
  return nil unless name

  {
    name: name.to_s, description: meta["description"].to_s, type: meta["type"].to_s,
    provenance: meta["provenance"].to_s, confidence: meta["confidence"].to_f,
    sources: Array(meta["sources"]).map(&:to_s), occurrences: meta["occurrences"].to_i,
    created_at: meta["created_at"].to_s, updated_at: meta["updated_at"].to_s,
    body: match[2].strip
  }
end

.render(name:, description:, type:, body:, provenance:, confidence:, sources:, occurrences:, created_at:, updated_at:) ⇒ Object

Renders the complete concept markdown. Every field but body is engine-stamped (never the model's own words) — see Extractor.



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/insika/knowledge.rb', line 204

def render(name:, description:, type:, body:, provenance:, confidence:, sources:, occurrences:,
           created_at:, updated_at:)
  frontmatter = {
    "name" => name, "description" => description, "type" => type,
    "provenance" => provenance, "confidence" => confidence.round(2),
    "sources" => Array(sources), "occurrences" => occurrences,
    "created_at" => created_at, "updated_at" => updated_at
  }
  yaml = frontmatter.map { |k, v| "#{k}: #{v.to_json}" }.join("\n")
  "---\n#{yaml}\n---\n\n#{body}\n"
end