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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Insika's colour scheme for Just the Docs.
|
|
2
|
+
//
|
|
3
|
+
// Selected by `color_scheme: insika` in _config.yml; the theme picks the file up
|
|
4
|
+
// by name and needs no other wiring. This file only maps the palette tokens from
|
|
5
|
+
// _sass/custom/setup.scss onto the theme's own `!default` variables — anything
|
|
6
|
+
// that is not a theme variable belongs in _sass/custom/custom.scss.
|
|
7
|
+
//
|
|
8
|
+
// The palette is warm stone with a terracotta accent: the name is Zulu for the
|
|
9
|
+
// pillar that carries a structure, and the docs should read like one — quiet
|
|
10
|
+
// neutrals, a single load-bearing colour. It is deliberately unlike the blue and
|
|
11
|
+
// purple that every other Ruby docs site defaults to.
|
|
12
|
+
|
|
13
|
+
$color-scheme: insika;
|
|
14
|
+
|
|
15
|
+
$body-background-color: $white;
|
|
16
|
+
$body-heading-color: $ink-900;
|
|
17
|
+
$body-text-color: $ink-700;
|
|
18
|
+
$link-color: $terracotta-100;
|
|
19
|
+
$nav-child-link-color: $ink-700;
|
|
20
|
+
$sidebar-color: $stone-050;
|
|
21
|
+
$border-color: $stone-200;
|
|
22
|
+
$base-button-color: $stone-100;
|
|
23
|
+
$btn-primary-color: $terracotta-100;
|
|
24
|
+
$code-background-color: $stone-100;
|
|
25
|
+
$feedback-color: darken($sidebar-color, 3%);
|
|
26
|
+
$table-background-color: $white;
|
|
27
|
+
$search-background-color: $white;
|
|
28
|
+
$search-result-preview-color: $ink-500;
|
|
29
|
+
|
|
30
|
+
// The theme ships accessible-pygments; github-light is the one that sits calmly
|
|
31
|
+
// on a warm background instead of fighting it.
|
|
32
|
+
@import "./vendor/accessible-pygments/github-light";
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// Insika's own styling on top of Just the Docs.
|
|
2
|
+
//
|
|
3
|
+
// Everything that is NOT one of the theme's `!default` variables lives here;
|
|
4
|
+
// the palette itself is in _sass/color_schemes/insika.scss. Kept deliberately
|
|
5
|
+
// small: the theme already handles layout, search and responsiveness, and every
|
|
6
|
+
// rule below exists because a specific page needed it.
|
|
7
|
+
//
|
|
8
|
+
// IMPORTANT: these pages are read in three places — this site, GitHub, and the
|
|
9
|
+
// raw-markdown API (`GET /docs/<name>.md`). Styling is therefore driven by
|
|
10
|
+
// kramdown attribute lists (`{: .card-grid }`) on ORDINARY markdown, never by
|
|
11
|
+
// raw HTML blocks: a list still reads as a list everywhere else.
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Typography
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
// The theme's 1.6 content line-height is tight for pages this long.
|
|
18
|
+
.main-content {
|
|
19
|
+
line-height: 1.65;
|
|
20
|
+
|
|
21
|
+
h1,
|
|
22
|
+
h2,
|
|
23
|
+
h3 {
|
|
24
|
+
letter-spacing: -0.01em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// A rule above every h2 turns a long page into visible sections. h2 is the
|
|
28
|
+
// level the search index already uses as a landmark, so it is the honest one
|
|
29
|
+
// to draw.
|
|
30
|
+
h2 {
|
|
31
|
+
padding-top: $sp-5;
|
|
32
|
+
margin-top: $sp-7;
|
|
33
|
+
border-top: $border $border-color;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
h2:first-of-type {
|
|
37
|
+
margin-top: $sp-4;
|
|
38
|
+
padding-top: 0;
|
|
39
|
+
border-top: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Inline code appears in nearly every sentence here (env vars, method names).
|
|
43
|
+
// A tinted chip separates it from prose without shouting.
|
|
44
|
+
p > code,
|
|
45
|
+
li > code,
|
|
46
|
+
td > code,
|
|
47
|
+
h2 > code,
|
|
48
|
+
h3 > code,
|
|
49
|
+
h4 > code {
|
|
50
|
+
padding: 0.12em 0.32em;
|
|
51
|
+
background-color: $stone-100;
|
|
52
|
+
border: $border $stone-200;
|
|
53
|
+
border-radius: 3px;
|
|
54
|
+
font-size: 0.85em;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
blockquote {
|
|
58
|
+
margin-left: 0;
|
|
59
|
+
padding: $sp-2 $sp-4;
|
|
60
|
+
border-left: 3px solid $terracotta-000;
|
|
61
|
+
background-color: $stone-050;
|
|
62
|
+
color: $ink-700;
|
|
63
|
+
|
|
64
|
+
> :first-child { margin-top: 0; }
|
|
65
|
+
> :last-child { margin-bottom: 0; }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Home hero
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
// `{: .hero-tagline }` on the one line under the h1.
|
|
74
|
+
.hero-tagline {
|
|
75
|
+
max-width: 34rem;
|
|
76
|
+
margin-bottom: $sp-6;
|
|
77
|
+
color: $ink-700;
|
|
78
|
+
font-size: $font-size-6;
|
|
79
|
+
font-weight: 300;
|
|
80
|
+
line-height: 1.45;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Card grid
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
// `{: .card-grid }` on a markdown list whose items read
|
|
88
|
+
// `**[Title](page.md)** — what the page answers.`
|
|
89
|
+
//
|
|
90
|
+
// The em dash is the split point: the bold link becomes the card title and the
|
|
91
|
+
// remainder becomes the card's body. No HTML in the markdown, so GitHub and the
|
|
92
|
+
// raw-markdown API still see a plain, readable list.
|
|
93
|
+
.main-content ul.card-grid {
|
|
94
|
+
display: grid;
|
|
95
|
+
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
|
|
96
|
+
gap: $sp-3;
|
|
97
|
+
margin: $sp-5 0;
|
|
98
|
+
padding: 0;
|
|
99
|
+
list-style: none;
|
|
100
|
+
|
|
101
|
+
> li {
|
|
102
|
+
margin: 0;
|
|
103
|
+
padding: $sp-4;
|
|
104
|
+
border: $border $border-color;
|
|
105
|
+
border-radius: 6px;
|
|
106
|
+
background-color: $body-background-color;
|
|
107
|
+
line-height: 1.5;
|
|
108
|
+
transition: border-color 150ms ease, background-color 150ms ease;
|
|
109
|
+
|
|
110
|
+
&::before { content: none; }
|
|
111
|
+
|
|
112
|
+
&:hover {
|
|
113
|
+
border-color: $terracotta-000;
|
|
114
|
+
background-color: $stone-050;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// The bold-wrapped link is the card's title.
|
|
118
|
+
> strong {
|
|
119
|
+
display: block;
|
|
120
|
+
margin-bottom: $sp-1;
|
|
121
|
+
font-size: $font-size-5;
|
|
122
|
+
font-weight: 600;
|
|
123
|
+
|
|
124
|
+
> a {
|
|
125
|
+
color: $body-heading-color;
|
|
126
|
+
text-decoration: none;
|
|
127
|
+
background-image: none;
|
|
128
|
+
|
|
129
|
+
&:hover { color: $terracotta-100; }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
color: $ink-500;
|
|
134
|
+
font-size: $font-size-4;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Navigation
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
|
|
142
|
+
.site-title {
|
|
143
|
+
font-weight: 600;
|
|
144
|
+
letter-spacing: -0.02em;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// The sidebar is six sections deep; a hairline between top-level entries makes
|
|
148
|
+
// the grouping legible at a glance instead of one 40-item column.
|
|
149
|
+
.site-nav > .nav-list > .nav-list-item + .nav-list-item {
|
|
150
|
+
border-top: $border $border-color;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.nav-list .nav-list-item .nav-list-link.active {
|
|
154
|
+
font-weight: 600;
|
|
155
|
+
box-shadow: inset 2px 0 0 $terracotta-100;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// Tables
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
// Reference tables here are wide (env var, default, meaning). Zebra striping
|
|
163
|
+
// and a tinted header make a 20-row table scannable.
|
|
164
|
+
.main-content table {
|
|
165
|
+
th {
|
|
166
|
+
background-color: $stone-100;
|
|
167
|
+
font-size: $font-size-3;
|
|
168
|
+
text-transform: uppercase;
|
|
169
|
+
letter-spacing: 0.04em;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
tbody tr:nth-child(even) {
|
|
173
|
+
background-color: $stone-050;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Site title
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
|
|
181
|
+
// _includes/title.html puts the pillar mark inline before the wordmark.
|
|
182
|
+
.site-title {
|
|
183
|
+
display: inline-flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
gap: $sp-2;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.site-title-mark {
|
|
189
|
+
display: inline-flex;
|
|
190
|
+
flex: 0 0 auto;
|
|
191
|
+
|
|
192
|
+
svg {
|
|
193
|
+
width: 1.05em;
|
|
194
|
+
height: 1.05em;
|
|
195
|
+
fill: $terracotta-100;
|
|
196
|
+
|
|
197
|
+
.shaft { fill: $terracotta-000; }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Insika's palette tokens.
|
|
2
|
+
//
|
|
3
|
+
// This file is the ONE place the raw colours are written. It lives in
|
|
4
|
+
// custom/setup rather than in the colour scheme because Just the Docs imports
|
|
5
|
+
// it before every scheme it compiles — including its own stock light and dark
|
|
6
|
+
// stylesheets, which also pull in _sass/custom/custom.scss and would otherwise
|
|
7
|
+
// fail on an undefined variable.
|
|
8
|
+
//
|
|
9
|
+
// _sass/color_schemes/insika.scss maps these onto the theme's own variables.
|
|
10
|
+
|
|
11
|
+
// Warm neutrals. The greys carry a little red so that text on the off-white
|
|
12
|
+
// sidebar does not read as blue-grey next to the terracotta accent.
|
|
13
|
+
$ink-900: #16191d !default; // headings
|
|
14
|
+
$ink-700: #3d4148 !default; // body copy
|
|
15
|
+
$ink-500: #6b6a68 !default; // muted
|
|
16
|
+
$stone-050: #faf8f5 !default; // sidebar
|
|
17
|
+
$stone-100: #f6f3ef !default; // code blocks, table stripes
|
|
18
|
+
$stone-200: #e8e2d9 !default; // borders
|
|
19
|
+
|
|
20
|
+
// The single accent. #a8431e clears 4.5:1 on both #fff and the sidebar, which
|
|
21
|
+
// the lighter, prettier terracottas do not — links are the one thing here that
|
|
22
|
+
// cannot trade contrast for warmth.
|
|
23
|
+
$terracotta-000: #c2542a !default;
|
|
24
|
+
$terracotta-100: #a8431e !default;
|
|
25
|
+
$terracotta-200: #8a3617 !default;
|
|
26
|
+
$terracotta-300: #6b2911 !default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-label="Insika">
|
|
2
|
+
<!-- A pillar seen head-on: capital, shaft, base. It doubles as the "I" of
|
|
3
|
+
Insika, which is why the shaft is centred and the slabs overhang. -->
|
|
4
|
+
<rect x="3" y="3" width="18" height="3.6" rx="1" fill="#a8431e"/>
|
|
5
|
+
<rect x="8.7" y="7.6" width="6.6" height="8.8" fill="#c2542a"/>
|
|
6
|
+
<rect x="3" y="17.4" width="18" height="3.6" rx="1" fill="#a8431e"/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-label="Insika">
|
|
2
|
+
<!-- A pillar seen head-on: capital, shaft, base. It doubles as the "I" of
|
|
3
|
+
Insika, which is why the shaft is centred and the slabs overhang. -->
|
|
4
|
+
<rect x="3" y="3" width="18" height="3.6" rx="1" fill="#a8431e"/>
|
|
5
|
+
<rect x="8.7" y="7.6" width="6.6" height="8.8" fill="#c2542a"/>
|
|
6
|
+
<rect x="3" y="17.4" width="18" height="3.6" rx="1" fill="#a8431e"/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Core concepts
|
|
3
|
+
nav_order: 3
|
|
4
|
+
has_children: true
|
|
5
|
+
permalink: /core-concepts/
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Core concepts
|
|
9
|
+
|
|
10
|
+
An agent is data: a profile, what it is allowed to do, its tools, its skills, and
|
|
11
|
+
what fills its prompt. These six pages are the vocabulary everything else on this
|
|
12
|
+
site assumes. Each one has a runnable counterpart under
|
|
13
|
+
[`examples/`](https://github.com/guizaols/insika/tree/main/examples/).
|
|
14
|
+
|
|
15
|
+
- **[Agents](AGENTS.md)** — the profile, the three ways to create one, and every key on it.
|
|
16
|
+
- **[Limits and policy](POLICY.md)** — the five layers that decide what an agent may do and what stops it.
|
|
17
|
+
- **[Tools](TOOLS.md)** — code tools, data-defined tools, MCP servers, and why a tool call goes missing.
|
|
18
|
+
- **[Skills](SKILLS.md)** — playbooks the agent loads only when the conversation calls for them.
|
|
19
|
+
- **[Context](CONTEXT.md)** — what fills a turn's prompt, the token budget, and cross-session memory.
|
|
20
|
+
- **[Workflows](WORKFLOWS.md)** — when the order of work belongs in Ruby instead of a prompt.
|
|
21
|
+
{: .card-grid }
|
data/docs/domain.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: The domain-free core
|
|
3
|
-
parent:
|
|
4
|
-
nav_order:
|
|
3
|
+
parent: Reference
|
|
4
|
+
nav_order: 1
|
|
5
5
|
permalink: /domain/
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# The domain-free core — what ships, what a deployment declares, and how to clear it
|
|
9
9
|
|
|
10
|
-
The engine is domain-free by construction
|
|
10
|
+
The engine is domain-free by construction: the gem carries no store
|
|
11
11
|
vocabulary, no persona, and no fixed conversation language. This page is the
|
|
12
12
|
removability map — for every artifact that could make a deployment look like
|
|
13
13
|
"the Brazilian store harness", here is what ships, what the doctor reports, and
|
|
@@ -90,7 +90,7 @@ metadata domain: "e-commerce-pt-BR"
|
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
- **Outcome funnel** — `funnel:` on the profile (see
|
|
93
|
-
[Outcomes](
|
|
93
|
+
[Outcomes](OUTCOMES.md#outcomes--business-results-over-real-traffic)).
|
|
94
94
|
Vocabulary note: in the gem and the doctor output it is an **outcome
|
|
95
95
|
funnel**, never "conversion" — the stage names are the deployment's, and a
|
|
96
96
|
bare install shows no funnel and no stage names at all.
|
data/docs/improve.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Improve
|
|
3
|
+
nav_order: 7
|
|
4
|
+
has_children: true
|
|
5
|
+
permalink: /improve/
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Improve
|
|
9
|
+
|
|
10
|
+
The loops that make an agent better than it was last month — measure it, read
|
|
11
|
+
its own traffic back, and turn finished conversations into something the next
|
|
12
|
+
conversation can use. Every one of them ends at a human approval.
|
|
13
|
+
|
|
14
|
+
- **[Evals](EVALS.md)** — the cases that grade an agent, and the gate that stops a regression.
|
|
15
|
+
- **[Refinement](REFINEMENT.md)** — production traffic read back as a ranked report of what broke.
|
|
16
|
+
- **[Outcomes and follow-ups](OUTCOMES.md)** — what the traffic was worth, and coming back on a promise.
|
|
17
|
+
- **[Knowledge](KNOWLEDGE.md)** — durable concepts extracted from finished conversations.
|
|
18
|
+
- **[Facts](FACTS.md)** — distilled customer memory, approved one fact at a time.
|
|
19
|
+
- **[Harvest](HARVEST.md)** — skills mined from real traffic, promoted only if two gates hold.
|
|
20
|
+
{: .card-grid }
|
data/docs/index.md
CHANGED
|
@@ -8,7 +8,7 @@ permalink: /
|
|
|
8
8
|
{: .fs-9 }
|
|
9
9
|
|
|
10
10
|
Your agent is the idea. Insika is what holds it up in production.
|
|
11
|
-
{: .
|
|
11
|
+
{: .hero-tagline }
|
|
12
12
|
|
|
13
13
|
[Build your first agent](RUNNING-LOCAL.md){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
|
14
14
|
[View on GitHub](https://github.com/guizaols/insika){: .btn .fs-5 .mb-4 .mb-md-0 }
|
|
@@ -60,9 +60,12 @@ secrets), `GET /docs` and `GET /docs/<name>.md`. Public and on by default when y
|
|
|
60
60
|
|
|
61
61
|
## Where to go next
|
|
62
62
|
|
|
63
|
-
- **[
|
|
64
|
-
- **[
|
|
65
|
-
- **[
|
|
66
|
-
- **[
|
|
63
|
+
- **[Start here](start-here.md)** — why a runtime, getting one running, and what a turn actually does.
|
|
64
|
+
- **[Core concepts](core-concepts.md)** — agents, limits, tools, skills, context, workflows.
|
|
65
|
+
- **[Integrate](integrate.md)** — the API, channels, media, embedding, plugins, templates.
|
|
66
|
+
- **[Ship it](ship.md)** — security, confined execution, deployment, scaling past one worker.
|
|
67
|
+
- **[Operate](operate.md)** — observability, schedules, artifacts, load and soak testing.
|
|
68
|
+
- **[Improve](improve.md)** — evals, refinement, outcomes, and the three learning loops.
|
|
69
|
+
{: .card-grid }
|
|
67
70
|
|
|
68
71
|
Pre-release: APIs may still change and nothing is tagged yet. Licensed MIT.
|
data/docs/integrate.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Integrate
|
|
3
|
+
nav_order: 4
|
|
4
|
+
has_children: true
|
|
5
|
+
permalink: /integrate/
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Integrate
|
|
9
|
+
|
|
10
|
+
How the agent connects to everything that is not the engine: the clients that
|
|
11
|
+
call it, the places people talk to it from, the app it may live inside, and the
|
|
12
|
+
code you write to extend it.
|
|
13
|
+
|
|
14
|
+
- **[The /v1 API](API.md)** — the frozen, OpenAI-Responses-compatible contract.
|
|
15
|
+
- **[Channels](CHANNELS.md)** — the web widget and the relay: how people actually reach the agent.
|
|
16
|
+
- **[Media](MEDIA.md)** — photos, voice notes and documents in; generated images out.
|
|
17
|
+
- **[Embedding](EMBEDDING.md)** — mounting the engine inside a Ruby app you already have.
|
|
18
|
+
- **[Plugins](PLUGINS.md)** — the two extension tiers, and how to pick between them.
|
|
19
|
+
- **[Templates](TEMPLATES.md)** — the example agents that ship in the gem, and the gallery that installs them.
|
|
20
|
+
{: .card-grid }
|
data/docs/operate.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Operate
|
|
3
|
-
nav_order:
|
|
2
|
+
title: Operate
|
|
3
|
+
nav_order: 6
|
|
4
4
|
has_children: true
|
|
5
5
|
permalink: /operate/
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Operate
|
|
8
|
+
# Operate
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
Running it once it is live: seeing what happened, firing turns nobody sent,
|
|
11
|
+
handing back a report, and knowing what the box will take before it takes it.
|
|
12
|
+
|
|
13
|
+
- **[Observability](OBSERVABILITY.md)** — the event stream, and turns as OpenTelemetry traces and metrics.
|
|
14
|
+
- **[Schedules](SCHEDULING.md)** — recurring turns the engine fires on its own tick.
|
|
15
|
+
- **[Artifacts](ARTIFACTS.md)** — a report the agent can hand you a URL to.
|
|
16
|
+
- **[Load test](LOADTEST.md)** — end-to-end load testing, and comparing topologies before you choose one.
|
|
17
|
+
- **[Soak](SOAK.md)** — the long run that finds what a short one cannot.
|
|
18
|
+
- **[Benchmark](BENCHMARK.md)** — the engine's measured overhead, reproducible without an API key.
|
|
19
|
+
{: .card-grid }
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Prompt — add a tool or skill
|
|
3
|
+
parent: Reference
|
|
4
|
+
nav_order: 3
|
|
5
|
+
permalink: /add-tool/
|
|
6
|
+
layout: default
|
|
7
|
+
render_with_liquid: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Add a tool, MCP server, or skill to my agent
|
|
11
|
+
|
|
12
|
+
> **You are a coding agent** (Claude Code, Codex, Cursor, …) reading this because a
|
|
13
|
+
> developer pasted a prompt pointing here. Treat this file as a **skill**: follow the
|
|
14
|
+
> steps in order and apply the RULES literally.
|
|
15
|
+
|
|
16
|
+
Your job: extend **one existing agent** with **one new capability** and prove it works
|
|
17
|
+
with one turn. Nothing more.
|
|
18
|
+
|
|
19
|
+
## Step 0 — Gather context (silently)
|
|
20
|
+
|
|
21
|
+
- **Which agent?** Find its `Insika.agent { … }` block (or its pack). If the developer
|
|
22
|
+
has no agent yet, stop and build the minimal first agent instead — this file assumes
|
|
23
|
+
one exists. Do not mix onboarding with capability.
|
|
24
|
+
- **A provider key in the environment**; ask if none is set.
|
|
25
|
+
- Read [`docs/TOOLS.md`](../TOOLS.md) (also served at `GET /docs/tools.md`) and, for
|
|
26
|
+
skills, [`docs/SKILLS.md`](../SKILLS.md) before writing anything.
|
|
27
|
+
|
|
28
|
+
## Step 1 — Pick the kind (RULES, not taste)
|
|
29
|
+
|
|
30
|
+
| The need | The kind | Where it lives |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Call an external HTTP API | **data tool** (`data_tool` in the DSL block) | a row in SQLite, editable at runtime |
|
|
33
|
+
| Logic must run in-process | **code tool** (a Ruby class `< RubyLLM::Tool`) | the deployment image |
|
|
34
|
+
| Adopt a whole external MCP server | **`mcp` instance** | durable config; its tools appear tagged `mcp:<name>` |
|
|
35
|
+
| Teach a procedure (no data fetching) | **skill** (`skill "name", description:, instructions:`) | loads on demand via `load_skill` |
|
|
36
|
+
|
|
37
|
+
Exactly one kind. A skill is not a tool; an MCP server is not five data tools.
|
|
38
|
+
|
|
39
|
+
## Step 2 — Build the smallest version
|
|
40
|
+
|
|
41
|
+
Data tool, via DSL (shape from
|
|
42
|
+
[`examples/data-tool/`](https://github.com/guizaols/insika/tree/main/examples/data-tool/)):
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
data_tool(
|
|
46
|
+
"name" => "convert_currency",
|
|
47
|
+
"description" => "Latest reference exchange rate between two currencies.",
|
|
48
|
+
"parameters" => {
|
|
49
|
+
"type" => "object",
|
|
50
|
+
"properties" => {
|
|
51
|
+
"from" => { "type" => "string", "description" => "source currency code" },
|
|
52
|
+
"to" => { "type" => "string", "description" => "target currency code" }
|
|
53
|
+
},
|
|
54
|
+
"required" => %w[from to]
|
|
55
|
+
},
|
|
56
|
+
"request" => { "method" => "GET",
|
|
57
|
+
"url" => "https://api.example.com/latest?from={{from}}&to={{to}}" },
|
|
58
|
+
"response" => { "extract" => "body_raw" }
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Skill, via DSL (from
|
|
63
|
+
[`examples/skills/`](https://github.com/guizaols/insika/tree/main/examples/skills/)):
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
skill "refunds",
|
|
67
|
+
description: "How to handle a refund request",
|
|
68
|
+
instructions: <<~MD
|
|
69
|
+
When a customer asks for a refund:
|
|
70
|
+
1. If you don't have the order number, ask for it first.
|
|
71
|
+
…
|
|
72
|
+
MD
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
RULES:
|
|
76
|
+
|
|
77
|
+
- `parameters` is JSON Schema (safe subset — no `oneOf`/`$ref`); it reaches the model
|
|
78
|
+
verbatim and arguments are checked against it at call time.
|
|
79
|
+
- Author the FINAL url: the HTTP client does not follow redirects, and the egress guard
|
|
80
|
+
cleared that host only.
|
|
81
|
+
- Do not add a second capability "while we're here".
|
|
82
|
+
|
|
83
|
+
## Step 3 — Make sure it enters the tool-loop
|
|
84
|
+
|
|
85
|
+
Registered is not enough — the agent's policy allowlist decides. The DSL auto-enables
|
|
86
|
+
the allowlist policy, and the three-state rule applies (`nil` = all, `[]` = none,
|
|
87
|
+
`[names]` = exactly those; deny wins):
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
tools %w[convert_currency] # or tools_allow: [...] on the pack
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
A code tool can never be shadowed by a data tool of the same name — pick another name
|
|
94
|
+
instead of fighting it.
|
|
95
|
+
|
|
96
|
+
## Step 4 — Prove it with ONE turn
|
|
97
|
+
|
|
98
|
+
Run one `reply()` whose message forces the call ("how many BRL is 1 USD right now?").
|
|
99
|
+
The reply must use what the tool returned — if the model answers from imagination, the
|
|
100
|
+
tool did not run: re-check Step 3 before touching the prompt.
|
|
101
|
+
|
|
102
|
+
## Step 5 — Self-check
|
|
103
|
+
|
|
104
|
+
- [ ] One agent, one new capability, one proving turn with real output.
|
|
105
|
+
- [ ] The tool/skill is named in the allowlist (or absence was a deliberate "all").
|
|
106
|
+
- [ ] No secret in any file — keys live in the environment.
|
|
107
|
+
- [ ] No new gem dependency was added without asking.
|
|
108
|
+
|
|
109
|
+
## Hard constraints
|
|
110
|
+
|
|
111
|
+
- **Secrets stay in the environment.** `{{secret.*}}` resolves ONLY on the manifest
|
|
112
|
+
write path (`POST /v1/tools/manifest`); written via DSL or Studio it fails
|
|
113
|
+
registration. Tools authored outside a manifest ship literal values (masked on read).
|
|
114
|
+
- **The egress guard refusing a URL is a feature**, not a bug to disable globally.
|
|
115
|
+
Report it; open an allowlist exception deliberately.
|
|
116
|
+
- **Config over code**: everything above is data the DSL generates (`to_pack`). If it
|
|
117
|
+
seems to require reaching past the DSL, the answer is a DSL method you have not used
|
|
118
|
+
yet — re-read the docs first.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Prompt — diagnose a failed turn
|
|
3
|
+
parent: Reference
|
|
4
|
+
nav_order: 4
|
|
5
|
+
permalink: /diagnose-turn/
|
|
6
|
+
layout: default
|
|
7
|
+
render_with_liquid: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Diagnose a turn that failed or misbehaved
|
|
11
|
+
|
|
12
|
+
> **You are a coding agent** (Claude Code, Codex, Cursor, …) reading this because a
|
|
13
|
+
> developer pasted a prompt pointing here — something like *"the agent didn't answer /
|
|
14
|
+
> answered wrong / errored"*. Treat this file as a **skill**: investigate BEFORE
|
|
15
|
+
> proposing fixes, and report findings in plain language with evidence.
|
|
16
|
+
|
|
17
|
+
The engine already recorded what happened: every turn emits structured events stamped
|
|
18
|
+
with `task_id`/`session_id`. Your job is to read the record, not to guess.
|
|
19
|
+
|
|
20
|
+
## Step 0 — Pin down the facts
|
|
21
|
+
|
|
22
|
+
Ask for (or find) the minimum: **agent id**, **session id** (or the customer's message
|
|
23
|
+
text), roughly **when**, and expected vs. actual. Reproduce once locally if cheap
|
|
24
|
+
(`reply()` or one `curl` against a dev instance) — never hammer production.
|
|
25
|
+
|
|
26
|
+
## Step 1 — Read the record, in this order
|
|
27
|
+
|
|
28
|
+
1. **`GET /v1/tasks/:id`** (or the Studio) — the terminal state:
|
|
29
|
+
`completed` / `failed` / `cancelled`, outcome, usage, timing. No task id? Find it
|
|
30
|
+
via **`GET /v1/events?session_id=…`**.
|
|
31
|
+
2. **That task's events**: `task_started` → `tool_call`/`tool_result`/`data_tool_call`
|
|
32
|
+
… → the terminal event. A failure's reason lives there.
|
|
33
|
+
3. **`GET /v1/sessions/:id`** — the transcript: what the model actually saw and said.
|
|
34
|
+
4. **`bin/insika doctor`** — configuration sanity; relay its findings verbatim.
|
|
35
|
+
|
|
36
|
+
## Step 2 — Map symptom to mechanism
|
|
37
|
+
|
|
38
|
+
| On the record | Usual suspect | Details |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| provider auth/model error | missing key or wrong model id | fails at the provider, not the engine |
|
|
41
|
+
| `provider_failure` then `provider_fallback` | reliability chain rotated mid-turn | [Agents](../AGENTS.md) § reliability |
|
|
42
|
+
| `breaker_open` + fail-fast turns | circuit open until cooldown | same |
|
|
43
|
+
| turn completed, customer got nothing | delivery is separate from the turn: check `channel_delivered` / `delivery_failed` | [Channels](../CHANNELS.md) |
|
|
44
|
+
| freshly created agent returns empty turns | persona overflows the default `context_budget` (8000) | [Context](../CONTEXT.md) |
|
|
45
|
+
| tool never called (or "missing") | not registered OR not allowed (`tools_allow`) | [Tools](../TOOLS.md) § troubleshooting |
|
|
46
|
+
| identical `tool_call` repeated, then abort | the `max_tool_repeat` loop guard | [Agents](../AGENTS.md) § limits |
|
|
47
|
+
| model gave up after one empty result | `tool_persistence` off (it is ON by default) | same |
|
|
48
|
+
| `turn_stuck` event | the agent declared it cannot proceed — escalation signal, not a bug | [Agents](../AGENTS.md) § stuck |
|
|
49
|
+
|
|
50
|
+
## Step 3 — Report, then fix ONE thing
|
|
51
|
+
|
|
52
|
+
- Plain-language summary: **what happened → evidence (event names + ids) → root cause
|
|
53
|
+
→ the fix you propose.**
|
|
54
|
+
- Apply the fix; re-run the Step 0 reproduction; show the new terminal event as proof.
|
|
55
|
+
- If the evidence does not fit any row above, say so and bring the raw events back —
|
|
56
|
+
do not force a diagnosis.
|
|
57
|
+
|
|
58
|
+
## Hard constraints
|
|
59
|
+
|
|
60
|
+
- **Never invent event data.** If you did not read it, you cannot claim it.
|
|
61
|
+
- **Do not change config just to silence the symptom** without explaining the
|
|
62
|
+
mechanism (raising `context_budget` because the prompt is big is a fix; deleting the
|
|
63
|
+
guardrail that fired is not).
|
|
64
|
+
- **Quote ids, counts and states first; message content only when needed** for the
|
|
65
|
+
developer to recognize the case.
|