Class: Insika::DSL::Builder
- Inherits:
-
Object
- Object
- Insika::DSL::Builder
- Defined in:
- lib/insika/dsl.rb
Overview
Collects the declarations and emits a Insika::Pack. Declarations map 1:1 to the pack manifest (AgentProfile.build attrs) + the pack's files/skills/tools — so what you write is exactly the data the engine stores.
Instance Method Summary collapse
-
#alerts(hash) ⇒ Object
breaker_open / delivery_failed events to the webhook as JSON.
- #api_base(value) ⇒ Object
-
#api_key(value) ⇒ Object
--- runtime (LLM provider) config — NOT part of the pack ------------ Configures RubyLLM at chat/serve time.
-
#briefing_fields(*names) ⇒ Object
The per-session working-state schema this agent keeps and asks for a flat list of field names.
-
#budget(hash) ⇒ Object
Spend caps per calendar window (WS2): daily/monthly token budgets for this agent, per (tenant, agent) when multi-tenant.
- #build(&block) ⇒ Object
-
#data_tool(defn) ⇒ Object
A DATA-DEFINED (declarative HTTP) tool — pure config-over-code.
-
#declares(*names) ⇒ Object
Facts about THIS deployment that are not tools, so an eval case can declare what it needs and be skipped where it is absent instead of failing for the wrong reason.
- #deny_tools(*names) ⇒ Object
-
#distill(hash) ⇒ Object
The session-distillation declaration: what counts as a fact for THIS store, distilled from finished customer conversations.
-
#edge_stream(hash) ⇒ Object
Which internal channels may cross to the CUSTOMER.
-
#followup(hash) ⇒ Object
The follow-up declaration: the agent may book a follow-up with a customer at a future time (
scheduletool); the engine fires the synthetic turn and enforces the policy (quiet hours, max frequency, cancellation keywords, silence detection) at fire time. -
#funnel(hash) ⇒ Object
The outcome funnel declaration: the store's stage vocabulary as pack data — the engine folds WS7 outcome kinds into the DECLARED stages, and never hard-codes one itself.
-
#grounding(hash = {}) ⇒ Object
Evidence-grounding policy: the pack declares how the engine polices product claims against the evidence ledger.
-
#guardrails(hash) ⇒ Object
Content-safety guardrails — opt-in and configurable per agent.
-
#harvest(hash) ⇒ Object
The gated-harvest declaration: the engine may read this agent's finished traffic and propose SKILLS for the store's playbook — through the negative list, the grounding filter and the double gate, never applied automatically.
-
#initialize(id) ⇒ Builder
constructor
A new instance of Builder.
- #instructions(text) ⇒ Object (also: #prompt)
-
#knowledge(hash) ⇒ Object
The post-turn knowledge declaration: after a turn completes, the engine may extract durable CONCEPTS (facts, procedures, policies, objections) from it and persist them for later turns to retrieve.
-
#limit(key, value) ⇒ Object
Per-agent limits (timeouts/budgets).
- #limits(hash) ⇒ Object
- #max_tokens(value) ⇒ Object
-
#mcp(name, transport: nil, command: nil, args: nil, url: nil, headers: nil, env: nil, description: nil, enabled: true) ⇒ Object
--- mcp --------------------------------------------------------------- Declares an MCP server instance — see Insika::DSL::SystemBuilder#mcp for the transport/lifecycle doc; identical shape here for a standalone
Insika.agent { … }script, or one member agent of a system, that wants one. -
#memory(on = true) ⇒ Object
--- knobs -----------------------------------------------------------.
- #metadata(hash) ⇒ Object
-
#model(name) ⇒ Object
--- identity & model ------------------------------------------------.
-
#outputs(hash) ⇒ Object
Generated-media output policy (WS9, saída): the media kinds this agent MAY generate as turn outputs, with per-kind config.
-
#param(key, value) ⇒ Object
LLM generation params.
- #params(hash) ⇒ Object
- #policies(*names) ⇒ Object
-
#prompt_file(name, content) ⇒ Object
An extra prompt FILE (identity fragment).
-
#provider(name) ⇒ Object
Provider for both the profile AND the RubyLLM configuration at run time.
-
#refine(hash) ⇒ Object
Refinement — how the agent's own instruction files may be improved from real traffic.
-
#reliability(hash) ⇒ Object
Provider-interaction reliability, as DATA (WS3): retries + exponential backoff on transient failures, a fallback model chain (mid-turn rotation), and a circuit breaker per (tenant, provider/model) that fail-fasts once the window trips.
-
#routes(hash) ⇒ Object
Intent routing (WS4): classify each turn's message into one route with a cheap model BEFORE the ask.
-
#schedule(name, every: nil, cron: nil, tz: nil, message: nil, session_mode: nil, session_id: nil, overrides: nil, enabled: nil) ⇒ Object
A recurring schedule: one declaration per call, named — a turn the ENGINE fires on its own tick, nobody has to remember.
-
#skill(name, content = nil, description: nil, instructions: nil) ⇒ Object
--- skills ---------------------------------------------------------- skill "escalate", "
" — or — skill "escalate", description: "…", instructions: "…" The name is auto-added to the agent's skill allowlist. -
#skills_eager(*names) ⇒ Object
skills_eager — turns progressive disclosure off for THIS agent, wholly or in part.
-
#stt_prompt(text) ⇒ Object
STT vocabulary hint (WS9): domain words (product names, brand terms) the transcriber should expect on THIS agent's voice notes — passed straight through to the Whisper-family provider's
prompt:. -
#stuck_signal(on = true) ⇒ Object
The agent may signal it cannot proceed (WS5): when on, the model can call
signal_stuck, which ends the turn withoutcome: :stuck+ a final message + a:turn_stuckevent. -
#subagents(*ids) ⇒ Object
--- delegation ------------------------------------------------------ subagents "security", "performance" → the child agents this one MAY spawn.
- #temperature(value) ⇒ Object
-
#to_pack ⇒ Object
The generated portable artifact — the heart of "generates the data".
-
#tool_output_compression(on = true) ⇒ Object
Mechanical tool-result dedupe in the replayed history (no-LLM compaction, apt for bloated transcripts).
-
#tool_persistence(on = true) ⇒ Object
The engine's "Tool discipline" block in the system prompt (retry a weak/empty tool result with a different approach before giving up).
-
#tools(*names) ⇒ Object
--- tools ----------------------------------------------------------- tools "a", "b" → allowlist [names].
Constructor Details
#initialize(id) ⇒ Builder
Returns a new instance of Builder.
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/insika/dsl.rb', line 140 def initialize(id) @id = id.to_s @config = {} @files = {} @skills = {} @tools = [] # Auto-enable the allowlist policies: harmless when the allowlist is nil=all, # correct once you restrict tools/skills. Visible in #to_pack — no hidden magic. @config[:policies] = %i[tool_allowlist skill_allowlist] @runtime = {} # non-pack knobs (llm provider/key/base) consumed by the runtime @mcp_instances = [] end |
Instance Method Details
#alerts(hash) ⇒ Object
breaker_open / delivery_failed events to the webhook as JSON.
365 |
# File 'lib/insika/dsl.rb', line 365 def alerts(hash) = (@config[:alerts] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#api_base(value) ⇒ Object
475 |
# File 'lib/insika/dsl.rb', line 475 def api_base(value) = @runtime[:api_base] = value.to_s |
#api_key(value) ⇒ Object
--- runtime (LLM provider) config — NOT part of the pack ------------ Configures RubyLLM at chat/serve time. Defaults: provider = the agent's provider; key = ENV.
474 |
# File 'lib/insika/dsl.rb', line 474 def api_key(value) = @runtime[:api_key] = value.to_s |
#briefing_fields(*names) ⇒ Object
The per-session working-state schema this agent keeps and asks for a flat list of field names. [] = off (no provider output, no update_briefing/set_next_step tools). briefing_fields "size", "budget", "delivery_day"
390 391 392 |
# File 'lib/insika/dsl.rb', line 390 def briefing_fields(*names) @config[:briefing_fields] = names.flatten.map(&:to_s) end |
#budget(hash) ⇒ Object
Spend caps per calendar window (WS2): daily/monthly token budgets for
this agent, per (tenant, agent) when multi-tenant. HARD is the default:
absent soft: (or soft: false) turns the cap into a hard wall (the
turn fails with budget_exceeded + retry_after); soft: true warns once
per window and keeps running.
budget daily: 100_000, monthly: 2_000_000, soft: false
275 |
# File 'lib/insika/dsl.rb', line 275 def budget(hash) = (@config[:budget] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#build(&block) ⇒ Object
153 154 155 156 |
# File 'lib/insika/dsl.rb', line 153 def build(&block) instance_eval(&block) if block Definition.new(pack: to_pack, runtime: @runtime, mcp_instances: @mcp_instances) end |
#data_tool(defn) ⇒ Object
A DATA-DEFINED (declarative HTTP) tool — pure config-over-code. defn is a
ToolDefinition hash (name/description/parameters/binding…). Its name is
auto-added to the allowlist so the agent can call its own tool.
188 189 190 191 192 193 194 |
# File 'lib/insika/dsl.rb', line 188 def data_tool(defn) h = defn.transform_keys(&:to_s) @tools << h name = h["name"].to_s (@config[:tools_allow] ||= []) << name unless name.empty? || Array(@config[:tools_allow]).include?(name) h end |
#declares(*names) ⇒ Object
Facts about THIS deployment that are not tools, so an eval case can declare what it needs and be skipped where it is absent instead of failing for the wrong reason. declares "promotions", "human_handoff"
446 447 448 |
# File 'lib/insika/dsl.rb', line 446 def declares(*names) (@config[:capabilities_declared] ||= []).concat(names.flatten.map(&:to_s)) end |
#deny_tools(*names) ⇒ Object
181 182 183 |
# File 'lib/insika/dsl.rb', line 181 def deny_tools(*names) @config[:tools_deny] = names.flatten.map(&:to_s) end |
#distill(hash) ⇒ Object
The session-distillation declaration: what counts as a fact
for THIS store, distilled from finished customer conversations. Pack
data — merges, so repeated calls accumulate (like budget). prompt and
model are pack-authored keys the DSL passes through.
distill enabled: true, idle_hours: 6, max_proposals: 10
304 |
# File 'lib/insika/dsl.rb', line 304 def distill(hash) = (@config[:distill] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#edge_stream(hash) ⇒ Object
Which internal channels may cross to the CUSTOMER. Both off by default: the
answer is the answer, and the provider's reasoning (thinking) or the model
narrating its tool loop (intermediate) is for the Studio and the trace.
Each opted-in channel gets its OWN frame type at /v1/responses — never the
answer's — so a consumer that only reads the answer is unaffected either way.
edge_stream thinking: true, intermediate: false
456 |
# File 'lib/insika/dsl.rb', line 456 def edge_stream(hash) = (@config[:edge_stream] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#followup(hash) ⇒ Object
The follow-up declaration: the agent may book a follow-up
with a customer at a future time (schedule tool); the engine fires the
synthetic turn and enforces the policy (quiet hours, max frequency,
cancellation keywords, silence detection) at fire time. Pack data —
merges, so repeated calls accumulate (like budget).
followup arm: "schedule",
policy: { quiet_hours: { timezone: "America/Sao_Paulo",
start: "21:30", end: "09:00" },
max_frequency: "2/24h",
cancel_keywords: ["não quero mais contato"],
silence_after_sends: 3 }
297 |
# File 'lib/insika/dsl.rb', line 297 def followup(hash) = (@config[:followup] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#funnel(hash) ⇒ Object
The outcome funnel declaration: the store's stage vocabulary as pack data — the engine folds WS7 outcome kinds into the DECLARED stages, and never hard-codes one itself. Merges, so repeated calls accumulate (like budget). funnel stages: %w[greeted qualified cart paid], advance_on: { "pix_paid" => "paid", "abandoned_cart" => "cart" }, primary: "paid", attribution_window: "72h"
284 |
# File 'lib/insika/dsl.rb', line 284 def funnel(hash) = (@config[:funnel] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#grounding(hash = {}) ⇒ Object
Evidence-grounding policy: the pack declares how the engine
polices product claims against the evidence ledger. Same
config-over-code shape as guardrails; absent = off (parity).
grounding mode: :flag, matcher: { sku: '\b[A-Z]2,4\d4,8\b' }
432 |
# File 'lib/insika/dsl.rb', line 432 def grounding(hash = {}) = (@config[:grounding] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#guardrails(hash) ⇒ Object
Content-safety guardrails — opt-in and configurable per agent. Pure config-over-code: the hash is stored on the profile and consumed by Safety::Config.from_profile. Merges, so repeated calls accumulate. guardrails input: true, output: true, strictness: "medium", moderator: "deepseek/deepseek-v4-flash", responses: { "injection" => "I can't help with that." }
426 |
# File 'lib/insika/dsl.rb', line 426 def guardrails(hash) = (@config[:guardrails] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#harvest(hash) ⇒ Object
The gated-harvest declaration: the engine may read this
agent's finished traffic and propose SKILLS for the store's playbook —
through the negative list, the grounding filter and the double gate,
never applied automatically. Pack data — merges, so repeated calls
accumulate (like budget). prompt/model are pack-authored keys the
DSL passes through.
harvest enabled: true,
negative_list: [ { rule: "no-competitor-prices", pattern: "concorrente" } ],
miner: { model: "deepseek-v4-flash", window: { last_sessions: 200 } }
315 |
# File 'lib/insika/dsl.rb', line 315 def harvest(hash) = (@config[:harvest] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#instructions(text) ⇒ Object Also known as: prompt
167 |
# File 'lib/insika/dsl.rb', line 167 def instructions(text) = @config[:base_prompt] = text.to_s |
#knowledge(hash) ⇒ Object
The post-turn knowledge declaration: after a turn completes, the
engine may extract durable CONCEPTS (facts, procedures, policies,
objections) from it and persist them for later turns to retrieve.
Pack data — merges, so repeated calls accumulate (like budget).
prompt/model are pack-authored keys the DSL passes through.
knowledge extract: true, retrieve: true, types: %w[fact policy]
323 |
# File 'lib/insika/dsl.rb', line 323 def knowledge(hash) = (@config[:knowledge] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#limit(key, value) ⇒ Object
Per-agent limits (timeouts/budgets). limit :turn_timeout, 120 or limits(...).
465 |
# File 'lib/insika/dsl.rb', line 465 def limit(key, value) = (@config[:limits] ||= {})[key.to_sym] = value |
#limits(hash) ⇒ Object
466 |
# File 'lib/insika/dsl.rb', line 466 def limits(hash) = (@config[:limits] ||= {}).merge!(hash.transform_keys(&:to_sym)) |
#max_tokens(value) ⇒ Object
462 |
# File 'lib/insika/dsl.rb', line 462 def max_tokens(value) = param(:max_tokens, value) |
#mcp(name, transport: nil, command: nil, args: nil, url: nil, headers: nil, env: nil, description: nil, enabled: true) ⇒ Object
--- mcp ---------------------------------------------------------------
Declares an MCP server instance — see
Insika::DSL::SystemBuilder#mcp for the transport/lifecycle doc; identical
shape here for a standalone Insika.agent { … } script, or one member
agent of a system, that wants one.
Auto-adds "mcp:tools_allow_groups — without
it, a pack with no data_tool gets PackImporter's tools_allow: []
(isolation default) and no tools_allow_groups at all, so
Policy::ToolAllowlist#allowed_names resolves an EMPTY allowlist and the
agent could never call the MCP tool it just declared (found writing the
MCP templates — no existing spec exercised this path end to
end). Same "auto-added to the allowlist" contract data_tool already
gives its own tool name; deny_tools has no group-string equivalent
yet, so a whole MCP group cannot be denied by name today.
253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/insika/dsl.rb', line 253 def mcp(name, transport: nil, command: nil, args: nil, url: nil, headers: nil, env: nil, description: nil, enabled: true) n = name.to_s raise ArgumentError, "duplicate mcp instance in agent: #{n}" if @mcp_instances.any? { |m| m[:name] == n } @mcp_instances << { name: n, transport: transport&.to_s, command: command, args: args, url: url, headers: headers, env: env, description: description, enabled: enabled } group = "mcp:#{n}" (@config[:tools_allow_groups] ||= []) << group unless Array(@config[:tools_allow_groups]).include?(group) n end |
#memory(on = true) ⇒ Object
--- knobs -----------------------------------------------------------
267 |
# File 'lib/insika/dsl.rb', line 267 def memory(on = true) = @config[:memory] = on |
#metadata(hash) ⇒ Object
469 |
# File 'lib/insika/dsl.rb', line 469 def (hash) = (@config[:metadata] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#model(name) ⇒ Object
--- identity & model ------------------------------------------------
159 |
# File 'lib/insika/dsl.rb', line 159 def model(name) = @config[:model] = name.to_s |
#outputs(hash) ⇒ Object
Generated-media output policy (WS9, saída): the media kinds this agent MAY generate as turn outputs, with per-kind config. The other half of the gate is the CHANNEL's: the request must declare the matching capability for the tools to exist at all. outputs image: { model: "gpt-image-1", size: "1024x1024" }, tts: { model: "tts-1", voice: "alloy" }
400 |
# File 'lib/insika/dsl.rb', line 400 def outputs(hash) = (@config[:outputs] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#param(key, value) ⇒ Object
LLM generation params. param:temperature, 0.2 or params(...).
459 |
# File 'lib/insika/dsl.rb', line 459 def param(key, value) = (@config[:params] ||= {})[key.to_sym] = value |
#params(hash) ⇒ Object
460 |
# File 'lib/insika/dsl.rb', line 460 def params(hash) = (@config[:params] ||= {}).merge!(hash.transform_keys(&:to_sym)) |
#policies(*names) ⇒ Object
468 |
# File 'lib/insika/dsl.rb', line 468 def policies(*names) = @config[:policies] = names.flatten.map(&:to_sym) |
#prompt_file(name, content) ⇒ Object
An extra prompt FILE (identity fragment). Name = the file name (e.g. "SOUL.md").
171 172 173 |
# File 'lib/insika/dsl.rb', line 171 def prompt_file(name, content) @files[name.to_s] = content.to_s end |
#provider(name) ⇒ Object
Provider for both the profile AND the RubyLLM configuration at run time.
162 163 164 165 |
# File 'lib/insika/dsl.rb', line 162 def provider(name) @config[:provider] = name.to_s @runtime[:provider] ||= name.to_s end |
#refine(hash) ⇒ Object
Refinement — how the agent's own instruction files may be
improved from real traffic. Same config-over-code shape as guardrails;
omitting it entirely leaves the agent report-only (writes nothing).
refine mode: "propose", window: { last_sessions: 200 }, files: %w,
proposers: ["deepseek/deepseek-v4-flash", "gpt-5-mini"],
budget: { tokens: 200_000 }
440 |
# File 'lib/insika/dsl.rb', line 440 def refine(hash) = (@config[:refinement] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#reliability(hash) ⇒ Object
Provider-interaction reliability, as DATA (WS3): retries + exponential
backoff on transient failures, a fallback model chain (mid-turn
rotation), and a circuit breaker per (tenant, provider/model) that
fail-fasts once the window trips. fallback/circuit_breaker entries
are "provider/model" refs or plain model ids.
reliability retries: 3, backoff: "exponential",
fallback: ["gpt-4o-mini"], circuit_breaker: { after: 10, within: 60, cooldown: 300 }
359 360 361 |
# File 'lib/insika/dsl.rb', line 359 def reliability(hash) (@config[:reliability] ||= {}).merge!(hash.transform_keys(&:to_s)) end |
#routes(hash) ⇒ Object
Intent routing (WS4): classify each turn's message into one route with a cheap model BEFORE the ask. A Hash: route name -> description (or a Hash with description/delegate/stuck/message), plus the reserved keys "default" (the deterministic fallback) and "model"/"provider" (the cheap classifier). The classifier prompt is generated — data only. routes "shopping" => "the customer wants to browse products", "order" => { "description" => "asks about an existing order", "delegate" => "order-agent" }, "human" => { "description" => "the customer asks for a person", "stuck" => true }, "default" => "shopping", "model" => "deepseek-v4-flash"
378 |
# File 'lib/insika/dsl.rb', line 378 def routes(hash) = (@config[:routes] ||= {}).merge!(hash.transform_keys(&:to_s)) |
#schedule(name, every: nil, cron: nil, tz: nil, message: nil, session_mode: nil, session_id: nil, overrides: nil, enabled: nil) ⇒ Object
A recurring schedule: one declaration per call,
named — a turn the ENGINE fires on its own tick, nobody has to
remember. cron (5 fields) or every (plain interval), a tz for
cron materialization, the synthetic inbound message that kicks each
run, a session mode (new = a fresh session per run — the report
case; fixed = one standing session), per-run overrides
(turn_timeout / max_tool_calls / model) and enabled.
schedule "daily_report", cron: "0 22 * * *", tz: "America/Sao_Paulo",
message: "Run the daily report now.",
overrides: { turn_timeout: 900, max_tool_calls: 200 }
Distinct by shape from the schedule_followup TOOL (a one-shot,
customer-facing, consent-gated contact); see docs/SCHEDULING.md.
337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/insika/dsl.rb', line 337 def schedule(name, every: nil, cron: nil, tz: nil, message: nil, session_mode: nil, session_id: nil, overrides: nil, enabled: nil) id = name.to_s.downcase # the engine canonicalizes ids to lowercase if Array(@config[:schedules]).any? { |s| s["id"] == id } raise ArgumentError, "duplicate schedule in agent: #{id}" end entry = { "id" => id, "every" => every, "cron" => cron, "tz" => tz, "message" => , "session_mode" => session_mode, "session_id" => session_id, "overrides" => overrides, "enabled" => enabled }.compact @config[:schedules] = Array(@config[:schedules]) + [entry] id end |
#skill(name, content = nil, description: nil, instructions: nil) ⇒ Object
--- skills ----------------------------------------------------------
skill "escalate", "
200 201 202 203 204 205 |
# File 'lib/insika/dsl.rb', line 200 def skill(name, content = nil, description: nil, instructions: nil) n = name.to_s @skills[n] = normalize_skill(n, content, description, instructions) (@config[:skills] ||= []) << n unless @config.fetch(:skills, []).include?(n) n end |
#skills_eager(*names) ⇒ Object
skills_eager — turns progressive disclosure off for THIS agent, wholly or in
part. The body of an eager skill is in the prompt on every turn, so its
activation is not a decision and cannot be missed; it is paid for on every
turn, so measure the bodies against context_budget first (a stable position
makes them a cacheable prefix).
skills_eager # every allowed skill
skills_eager "formato", "markers" # exactly these
skills_eager false # none (the default)
A LIST and not a per-skill flag because skills are shared: escalation-to-human
sits in several allowlists, and one flag on the skill would force one decision
onto every agent holding it.
220 221 222 223 224 225 226 227 |
# File 'lib/insika/dsl.rb', line 220 def skills_eager(*names) flat = names.flatten @config[:skills_eager] = if flat.empty? then true elsif flat == [true] || flat == [false] then flat.first else flat.map(&:to_s) end end |
#stt_prompt(text) ⇒ Object
STT vocabulary hint (WS9): domain words (product names, brand terms)
the transcriber should expect on THIS agent's voice notes — passed
straight through to the Whisper-family provider's prompt:. Falls
back to INSIKA_STT_PROMPT (deployment default) when unset.
stt_prompt "Ocean Drop, tênis, boné trucker, chinelo"
407 |
# File 'lib/insika/dsl.rb', line 407 def stt_prompt(text) = @config[:stt_prompt] = text.to_s |
#stuck_signal(on = true) ⇒ Object
The agent may signal it cannot proceed (WS5): when on, the model
can call signal_stuck, which ends the turn with outcome: :stuck + a final
message + a :turn_stuck event. What "stuck" means is the consumer's call.
stuck_signal true
384 |
# File 'lib/insika/dsl.rb', line 384 def stuck_signal(on = true) = @config[:stuck_signal] = on |
#subagents(*ids) ⇒ Object
--- delegation ------------------------------------------------------
subagents "security", "performance" → the child agents this one MAY
spawn. CAPACITY field: opt-in, never inherited, and the ids
must be agents of the same system (Insika.system { … }) or already in
the store. Present ⇒ the engine wires spawn_subagent/spawn_subagents.
234 235 236 |
# File 'lib/insika/dsl.rb', line 234 def subagents(*ids) @config[:subagents] = ids.flatten.map(&:to_s) end |
#temperature(value) ⇒ Object
461 |
# File 'lib/insika/dsl.rb', line 461 def temperature(value) = param(:temperature, value) |
#to_pack ⇒ Object
The generated portable artifact — the heart of "generates the data".
478 479 480 481 482 483 |
# File 'lib/insika/dsl.rb', line 478 def to_pack Insika::Pack.from_h( config: @config.merge(id: @id), files: @files, skills: @skills, tools: @tools ) end |
#tool_output_compression(on = true) ⇒ Object
Mechanical tool-result dedupe in the replayed history (no-LLM compaction, apt for bloated transcripts). CHANGES WHAT THE MODEL SEES: repeated identical tool results collapse to a back-reference.
418 |
# File 'lib/insika/dsl.rb', line 418 def tool_output_compression(on = true) = @config[:tool_output_compression] = on |
#tool_persistence(on = true) ⇒ Object
The engine's "Tool discipline" block in the system prompt (retry a weak/empty tool result with a different approach before giving up). ON by default — this setter exists to turn it OFF:
tool_persistence false
413 |
# File 'lib/insika/dsl.rb', line 413 def tool_persistence(on = true) = @config[:tool_persistence] = on |
#tools(*names) ⇒ Object
--- tools ----------------------------------------------------------- tools "a", "b" → allowlist [names]. Not called → nil = all (parity).
177 178 179 |
# File 'lib/insika/dsl.rb', line 177 def tools(*names) @config[:tools_allow] = names.flatten.map(&:to_s) end |