insika 0.3.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +180 -0
- data/README.md +45 -10
- data/bin/insika +684 -0
- data/bin/insika-router +87 -0
- data/docs/AGENTS.md +94 -403
- data/docs/API.md +5 -5
- data/docs/ARCHITECTURE.md +3 -2
- data/docs/ARTIFACTS.md +95 -0
- data/docs/BENCHMARK.md +2 -2
- data/docs/CHANNELS.md +14 -14
- data/docs/CONTEXT.md +9 -7
- data/docs/DEMO.md +80 -0
- data/docs/DEPLOY.md +71 -3
- data/docs/EMBEDDING.md +1 -1
- data/docs/EVALS.md +128 -3
- data/docs/FACTS.md +3 -3
- data/docs/HARVEST.md +5 -6
- data/docs/KNOWLEDGE.md +290 -0
- data/docs/LOADTEST.md +2 -2
- data/docs/MEDIA.md +128 -0
- data/docs/OBSERVABILITY.md +15 -10
- data/docs/OUTCOMES.md +137 -0
- data/docs/PLUGINS.md +51 -6
- data/docs/POLICY.md +216 -0
- data/docs/REFINEMENT.md +14 -9
- data/docs/RELEASING.md +4 -4
- data/docs/ROUTER.md +213 -0
- data/docs/RUNNING-LOCAL.md +3 -3
- data/docs/SCHEDULING.md +121 -0
- data/docs/SECURITY.md +22 -6
- data/docs/SKILLS.md +11 -2
- data/docs/SOAK.md +2 -2
- data/docs/TEMPLATES.md +134 -0
- data/docs/TOOLS.md +152 -27
- data/docs/WHY.md +1 -1
- data/docs/WORKFLOWS.md +2 -2
- data/docs/_includes/head_custom.html +5 -0
- data/docs/_includes/title.html +13 -0
- data/docs/_sass/color_schemes/insika.scss +32 -0
- data/docs/_sass/custom/custom.scss +199 -0
- data/docs/_sass/custom/setup.scss +26 -0
- data/docs/assets/img/favicon.svg +7 -0
- data/docs/assets/img/insika-mark.svg +7 -0
- data/docs/core-concepts.md +21 -0
- data/docs/domain.md +4 -4
- data/docs/improve.md +20 -0
- data/docs/index.md +8 -5
- data/docs/integrate.md +20 -0
- data/docs/operate.md +13 -6
- data/docs/prompts/ADD-TOOL.md +118 -0
- data/docs/prompts/DIAGNOSE-TURN.md +65 -0
- data/docs/prompts/GO-LIVE.md +138 -0
- data/docs/prompts/RUN-EXAMPLES.md +70 -0
- data/docs/reference.md +19 -0
- data/docs/ship.md +10 -2
- data/docs/start-here.md +18 -0
- data/lib/insika/agent_profile.rb +73 -16
- data/lib/insika/artifact_signing.rb +82 -0
- data/lib/insika/artifact_store.rb +160 -0
- data/lib/insika/channel_delivery.rb +1 -1
- data/lib/insika/chat_builder.rb +22 -2
- data/lib/insika/commands/agent_payload.rb +2 -2
- data/lib/insika/commands/backfill_knowledge.rb +145 -0
- data/lib/insika/commands/delete_artifact.rb +35 -0
- data/lib/insika/commands/delete_concept.rb +34 -0
- data/lib/insika/commands/delete_mcp.rb +6 -2
- data/lib/insika/commands/delete_tenant_data.rb +15 -3
- data/lib/insika/commands/gate_refinement.rb +1 -1
- data/lib/insika/commands/refresh_mcp_tools.rb +47 -0
- data/lib/insika/commands/restore_concept.rb +34 -0
- data/lib/insika/commands/seed_demo_data.rb +31 -0
- data/lib/insika/commands/upsert_mcp.rb +6 -3
- data/lib/insika/commands/write_concept.rb +57 -0
- data/lib/insika/context/priority.rb +2 -0
- data/lib/insika/context/providers/knowledge.rb +108 -0
- data/lib/insika/context/providers/prompt.rb +30 -24
- data/lib/insika/cron.rb +189 -0
- data/lib/insika/demo/agent_attrs.rb +43 -0
- data/lib/insika/demo/golden_cases.rb +81 -0
- data/lib/insika/demo/seeder.rb +336 -0
- data/lib/insika/doctor.rb +176 -8
- data/lib/insika/dsl/definition.rb +3 -2
- data/lib/insika/dsl/runtime.rb +60 -79
- data/lib/insika/dsl/server_boot.rb +23 -1
- data/lib/insika/dsl/system.rb +10 -2
- data/lib/insika/dsl.rb +103 -2
- data/lib/insika/env_schema.rb +16 -1
- data/lib/insika/evals/golden.rb +41 -4
- data/lib/insika/evals/judge.rb +47 -2
- data/lib/insika/evals/pairwise.rb +11 -0
- data/lib/insika/evals/persona.rb +98 -0
- data/lib/insika/evals/runner.rb +9 -0
- data/lib/insika/evals/simulator.rb +225 -0
- data/lib/insika/evals/transport.rb +83 -1
- data/lib/insika/event_stream.rb +10 -0
- data/lib/insika/executor.rb +231 -55
- data/lib/insika/followup_policy.rb +2 -25
- data/lib/insika/golden_store.rb +16 -1
- data/lib/insika/grounding/matcher.rb +1 -1
- data/lib/insika/knowledge.rb +680 -0
- data/lib/insika/knowledge_store.rb +140 -0
- data/lib/insika/mcp_client.rb +94 -0
- data/lib/insika/mcp_json.rb +74 -0
- data/lib/insika/mcp_live_tool.rb +43 -0
- data/lib/insika/mcp_store.rb +98 -26
- data/lib/insika/mcp_tool_ingestor.rb +30 -8
- data/lib/insika/mcp_tool_registry.rb +100 -0
- data/lib/insika/media.rb +115 -31
- data/lib/insika/message_origin.rb +1 -1
- data/lib/insika/middleware.rb +9 -0
- data/lib/insika/onboarding.rb +17 -1
- data/lib/insika/outcome_store.rb +1 -1
- data/lib/insika/overlay_tool_registry.rb +37 -17
- data/lib/insika/packaging.rb +2 -2
- data/lib/insika/profile_source.rb +8 -1
- data/lib/insika/prompt_catalog.rb +10 -0
- data/lib/insika/retention.rb +36 -1
- data/lib/insika/router/app.rb +157 -0
- data/lib/insika/router/backend_pool.rb +98 -0
- data/lib/insika/router/hash_ring.rb +55 -0
- data/lib/insika/router/proxy_body.rb +34 -0
- data/lib/insika/router/session_key.rb +54 -0
- data/lib/insika/router.rb +18 -0
- data/lib/insika/schedule.rb +177 -0
- data/lib/insika/schedule_engine.rb +314 -0
- data/lib/insika/schedule_store.rb +208 -0
- data/lib/insika/server/app.rb +105 -15
- data/lib/insika/server/rack_app.rb +5 -1
- data/lib/insika/server/responses.rb +1 -1
- data/lib/insika/skill_catalog.rb +12 -0
- data/lib/insika/steer_injector.rb +21 -10
- data/lib/insika/studio/app.rb +567 -45
- data/lib/insika/studio/assets/dist/application.css +1 -1
- data/lib/insika/studio/assets/dist/application.js +21 -21
- data/lib/insika/studio/forms.rb +46 -5
- data/lib/insika/studio/nav_icons.rb +14 -1
- data/lib/insika/studio/views/_agent_tab_cache.erb +25 -0
- data/lib/insika/studio/views/_agent_tab_config.erb +514 -0
- data/lib/insika/studio/views/_agent_tab_history.erb +24 -0
- data/lib/insika/studio/views/_agent_tab_loops.erb +54 -0
- data/lib/insika/studio/views/_agent_tab_memory.erb +51 -0
- data/lib/insika/studio/views/_agent_tab_outcomes.erb +31 -0
- data/lib/insika/studio/views/_agent_tab_prompts.erb +108 -0
- data/lib/insika/studio/views/_agent_tab_skills.erb +38 -0
- data/lib/insika/studio/views/_agents_master.erb +44 -0
- data/lib/insika/studio/views/_message.erb +49 -32
- data/lib/insika/studio/views/agent_detail.erb +61 -820
- data/lib/insika/studio/views/agents.erb +70 -57
- data/lib/insika/studio/views/artifact.erb +23 -0
- data/lib/insika/studio/views/artifacts.erb +59 -0
- data/lib/insika/studio/views/evals.erb +2 -2
- data/lib/insika/studio/views/facts.erb +1 -1
- data/lib/insika/studio/views/funnel.erb +1 -1
- data/lib/insika/studio/views/home.erb +106 -67
- data/lib/insika/studio/views/knowledge.erb +123 -0
- data/lib/insika/studio/views/layout.erb +14 -11
- data/lib/insika/studio/views/mcp.erb +174 -80
- data/lib/insika/studio/views/session.erb +231 -177
- data/lib/insika/studio/views/settings.erb +39 -1
- data/lib/insika/studio/views/skills.erb +1 -1
- data/lib/insika/studio/views/tools.erb +24 -9
- data/lib/insika/templates/browser-agent/README.md +36 -0
- data/lib/insika/templates/browser-agent/agent.rb +49 -0
- data/lib/insika/templates/daily-digest/README.md +38 -0
- data/lib/insika/templates/daily-digest/agent.rb +77 -0
- data/lib/insika/templates/repo-explorer/README.md +36 -0
- data/lib/insika/templates/repo-explorer/agent.rb +45 -0
- data/lib/insika/templates/research-analyst/README.md +26 -0
- data/lib/insika/templates/research-analyst/agent.rb +58 -0
- data/lib/insika/templates/review-panel/README.md +20 -0
- data/lib/insika/templates/review-panel/agent.rb +50 -0
- data/lib/insika/templates/travel-planner/README.md +35 -0
- data/lib/insika/templates/travel-planner/agent.rb +87 -0
- data/lib/insika/templates.rb +112 -0
- data/lib/insika/tick.rb +24 -12
- data/lib/insika/timezone.rb +45 -0
- data/lib/insika/tools/generate_image.rb +52 -7
- data/lib/insika/tools/load_knowledge.rb +74 -0
- data/lib/insika/tools/run_persona_eval.rb +328 -0
- data/lib/insika/tools/save_artifact.rb +95 -0
- data/lib/insika/turn_output.rb +1 -1
- data/lib/insika/turn_state.rb +15 -4
- data/lib/insika/version.rb +1 -1
- data/lib/insika/wiring/graph.rb +184 -12
- data/lib/insika/wiring/graph_chat.rb +102 -0
- data/lib/insika.rb +57 -0
- metadata +105 -5
- data/docs/build.md +0 -14
- data/docs/understand.md +0 -10
data/lib/insika/studio/forms.rb
CHANGED
|
@@ -30,6 +30,21 @@ module Studio
|
|
|
30
30
|
limits[field.to_sym] = v
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
|
+
# Burst policy (QueuePolicy). Opt-in keys, same convention as the edge
|
|
34
|
+
# overrides above: blank DELETES (inherit platform / DEFAULTS — followup,
|
|
35
|
+
# steer_max 5); an explicit value pins it for this agent. steer_max 0 is
|
|
36
|
+
# a legitimate "never steer" and is stored, not deleted.
|
|
37
|
+
if (qm = presence(r.params["queue_mode"]))
|
|
38
|
+
unless Insika::QueuePolicy::MODES.map(&:to_s).include?(qm)
|
|
39
|
+
raise Insika::ValidationError, "queue_mode must be one of: #{Insika::QueuePolicy::MODES.join(', ')}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
limits[:queue_mode] = qm
|
|
43
|
+
else
|
|
44
|
+
limits.delete(:queue_mode)
|
|
45
|
+
end
|
|
46
|
+
smm = edge_int(r.params["steer_max_messages"], "steer_max_messages")
|
|
47
|
+
smm.nil? ? limits.delete(:steer_max_messages) : limits[:steer_max_messages] = smm
|
|
33
48
|
{
|
|
34
49
|
id: @agent.id,
|
|
35
50
|
model: presence(r.params["model"]),
|
|
@@ -44,6 +59,7 @@ module Studio
|
|
|
44
59
|
grounding: grounding_patch(r),
|
|
45
60
|
funnel: funnel_patch(r),
|
|
46
61
|
followup: followup_patch(r),
|
|
62
|
+
schedules: schedules_patch(r),
|
|
47
63
|
distill: distill_patch(r),
|
|
48
64
|
harvest: harvest_patch(r),
|
|
49
65
|
refinement: refinement_patch(r),
|
|
@@ -51,6 +67,7 @@ module Studio
|
|
|
51
67
|
reliability: reliability_patch(r),
|
|
52
68
|
routes: json_patch(r, "routes"),
|
|
53
69
|
outputs: json_patch(r, "outputs"),
|
|
70
|
+
stt_prompt: presence(r.params["stt_prompt"]),
|
|
54
71
|
metadata: json_patch(r, "metadata") || {},
|
|
55
72
|
alerts: alerts_patch(r),
|
|
56
73
|
edge_stream: edge_stream_patch(r),
|
|
@@ -124,6 +141,20 @@ module Studio
|
|
|
124
141
|
{ "arm" => arm, "policy" => policy }
|
|
125
142
|
end
|
|
126
143
|
|
|
144
|
+
# recurring schedules — a JSON array of declarations
|
|
145
|
+
# (name / trigger / tz / message / session mode / overrides / enabled).
|
|
146
|
+
# Same honest shape as routes/metadata: the list is unbounded, and a
|
|
147
|
+
# JSON textarea is the CSP-safe editor. Blank = no schedules (parity).
|
|
148
|
+
def schedules_patch(r)
|
|
149
|
+
parsed = json_block(r.params["schedules"], "schedules")
|
|
150
|
+
return nil if parsed.nil?
|
|
151
|
+
|
|
152
|
+
parsed = parsed.is_a?(Hash) ? [parsed] : parsed
|
|
153
|
+
raise Insika::ValidationError, "schedules must be an array of declarations" unless parsed.is_a?(Array)
|
|
154
|
+
|
|
155
|
+
parsed
|
|
156
|
+
end
|
|
157
|
+
|
|
127
158
|
# distillation — enabled checkbox + the forge's knobs. Blank
|
|
128
159
|
# prompt/model drop the keys (the engine defaults take over).
|
|
129
160
|
def distill_patch(r)
|
|
@@ -559,19 +590,24 @@ module Studio
|
|
|
559
590
|
}
|
|
560
591
|
end
|
|
561
592
|
|
|
562
|
-
# MCP instance from the form
|
|
563
|
-
#
|
|
564
|
-
#
|
|
565
|
-
#
|
|
593
|
+
# MCP instance from the form (transport-aware, but the
|
|
594
|
+
# form always submits every field regardless of which the JS shows;
|
|
595
|
+
# McpStore stores them all either way). `env`/`headers` come as
|
|
596
|
+
# "KEY=value" lines, `args` as one argv token per line (CSP forbids
|
|
597
|
+
# inline JS for add/remove line; a textarea is the simple, honest path).
|
|
598
|
+
# Masked credential values come back as a sentinel — keeping them
|
|
599
|
+
# preserves the secret; changing replaces; deleting the line clears it.
|
|
566
600
|
def mcp_patch(r)
|
|
567
601
|
{
|
|
568
602
|
name: presence(r.params["name"]),
|
|
569
603
|
transport: presence(r.params["transport"]) || "stdio",
|
|
570
604
|
command: r.params["command"].to_s,
|
|
605
|
+
args: split_lines(r.params["args"]),
|
|
571
606
|
url: r.params["url"].to_s,
|
|
572
607
|
description: r.params["description"].to_s,
|
|
573
608
|
enabled: r.params["enabled"] == "1",
|
|
574
|
-
env: parse_kv_lines(r.params["env"])
|
|
609
|
+
env: parse_kv_lines(r.params["env"]),
|
|
610
|
+
headers: parse_kv_lines(r.params["headers"])
|
|
575
611
|
}
|
|
576
612
|
end
|
|
577
613
|
|
|
@@ -588,5 +624,10 @@ module Studio
|
|
|
588
624
|
[k, v.to_s.strip]
|
|
589
625
|
end.to_h
|
|
590
626
|
end
|
|
627
|
+
|
|
628
|
+
# One argv token per line (stdio's `args`). Ignores blank lines/comments.
|
|
629
|
+
def split_lines(text)
|
|
630
|
+
text.to_s.each_line.map(&:strip).reject { |l| l.empty? || l.start_with?("#") }
|
|
631
|
+
end
|
|
591
632
|
end
|
|
592
633
|
end
|
|
@@ -25,12 +25,25 @@ module Studio
|
|
|
25
25
|
funnel: '<path d="M3 5h18l-8 9v6l-2 1v-7z"/>',
|
|
26
26
|
followups: '<path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/>',
|
|
27
27
|
facts: '<path d="M7 3h11a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H7z"/><path d="M7 3v18"/><path d="M11 8h5"/><path d="M11 12h5"/><path d="M11 16h3"/>',
|
|
28
|
-
harvest: '<path d="M4 20V10"/><path d="M20 20V4"/><path d="M4 10h4v10"/><path d="M20 4h-4v16"/><path d="M4 20h16"/><path d="m8 8 4-4 4 4"/>'
|
|
28
|
+
harvest: '<path d="M4 20V10"/><path d="M20 20V4"/><path d="M4 10h4v10"/><path d="M20 4h-4v16"/><path d="M4 20h16"/><path d="m8 8 4-4 4 4"/>',
|
|
29
|
+
knowledge: '<path d="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7V17h8v-2.3A7 7 0 0 0 12 2z"/>',
|
|
30
|
+
artifacts: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="m9.5 13 2 2 3.5-3.5"/><path d="M12 15v-4"/>'
|
|
29
31
|
}.freeze
|
|
30
32
|
|
|
31
33
|
def nav_icon(key)
|
|
32
34
|
%(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" ) +
|
|
33
35
|
%(stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">#{NAV_ICONS[key]}</svg>)
|
|
34
36
|
end
|
|
37
|
+
|
|
38
|
+
# Transcript event-chip icons: a tool call, a result, a
|
|
39
|
+
# skill, an artifact, a guardrail — each reuses a nav icon (same inline-SVG
|
|
40
|
+
# grammar, CSP-safe). Sized by the chip CSS, colored per kind.
|
|
41
|
+
CHIP_ICONS = { call: :tools, result: :approvals, skill: :skills,
|
|
42
|
+
artifact: :artifacts, guardrail: :system }.freeze
|
|
43
|
+
|
|
44
|
+
def chip_icon(kind)
|
|
45
|
+
key = CHIP_ICONS[kind]
|
|
46
|
+
key ? %(<span class="chip-ic">#{nav_icon(key)}</span>) : ""
|
|
47
|
+
end
|
|
35
48
|
end
|
|
36
49
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!-- ── Cache ─────────────────────────────────────────────────── -->
|
|
2
|
+
<section class="section" id="cache" data-tabs-target="panel">
|
|
3
|
+
<div class="section-head">
|
|
4
|
+
<h2>Cache</h2>
|
|
5
|
+
<p class="muted">prefix cache-hit per turn (provider-reported) — the invalidation reason names the first block whose bytes changed vs the previous turn.</p>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="card">
|
|
8
|
+
<% if @cache_series.empty? %>
|
|
9
|
+
<p class="muted">No turns recorded.</p>
|
|
10
|
+
<% else %>
|
|
11
|
+
<ul class="kv">
|
|
12
|
+
<% @cache_series.last(20).reverse.each do |c| %>
|
|
13
|
+
<li>
|
|
14
|
+
<span class="k mono"><%= c["at"] %></span>
|
|
15
|
+
<span class="v">
|
|
16
|
+
<%== c["hit_pct"].nil? ? "—" : "#{c['hit_pct']}% cached" %>
|
|
17
|
+
· <%= c["cached_tokens"] %>/<%= c["prompt_tokens"] %> tokens
|
|
18
|
+
<% if c["invalidation_reason"] %><span class="lat">broke: <%= c["invalidation_reason"] %></span><% end %>
|
|
19
|
+
</span>
|
|
20
|
+
</li>
|
|
21
|
+
<% end %>
|
|
22
|
+
</ul>
|
|
23
|
+
<% end %>
|
|
24
|
+
</div>
|
|
25
|
+
</section>
|