Skip to content

Commit d38850d

Browse files
committed
I turned myself into a pickle! Boom! Big reveal! I'm a pickle
0 parents  commit d38850d

File tree

2,359 files changed

+4214549
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,359 files changed

+4214549
-0
lines changed

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.bloop
2+
.bsp
3+
.metals
4+
project/target
5+
project/project
6+
.vscode
7+
target
8+
*.log
9+
graal_dumps
10+
.idea
11+
metals.sbt
12+
jmh-result.json
13+
*.jfr
14+
*.gpg
15+
.claude

.scalafmt.conf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
version = "3.8.3"
2+
runner.dialect = scala3
3+
rewrite.rules = [SortModifiers, Imports]
4+
rewrite.imports.expand = true
5+
rewrite.imports.sort = scalastyle
6+
rewrite.scala3.convertToNewSyntax = true
7+
rewrite.scala3.removeOptionalBraces = true
8+
rewrite.scala3.insertEndMarkerMinLines = 4
9+
rewriteTokens = {
10+
"⇒": "=>"
11+
"→": "->"
12+
"←": "<-"
13+
}
14+
align.preset = more
15+
maxColumn = 140
16+
indent.main = 4
17+
indent.callSite = 4
18+
newlines.source = keep
19+
fileOverride {
20+
"glob:**/kyo-scheduler*/**" {
21+
runner.dialect = scala212source3
22+
}
23+
"glob:**/kyo-stats-registry/**" {
24+
runner.dialect = scala212source3
25+
}
26+
"glob:**/kyo-stats-otel/**" {
27+
runner.dialect = scala212source3
28+
}
29+
"glob:**/scala-3/**" {
30+
runner.dialect = scala3
31+
}
32+
}

CLAUDE.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
kyo-ai is a Scala 3 library that extends the Kyo effect system with AI/LLM capabilities. The project provides composable, type-safe abstractions for interacting with large language models through a distinctive architecture that treats AI interactions as first-class effects.
8+
9+
## Build System
10+
11+
This is an SBT-based Scala project (Scala 3.7.0, SBT 1.10.1) configured as a cross-platform build with JVM support.
12+
13+
### Common Commands
14+
15+
- **Compile**: `sbt compile`
16+
- **Run tests**: `sbt test`
17+
- **Run specific test**: `sbt "testOnly *AITest"` or `sbt "testOnly *TestClassName"`
18+
- **Format code**: `sbt scalafmt` (or `sbt scalafmtAll`)
19+
- **Format check**: `sbt scalafmtCheck`
20+
- **Run build**: `sbt clean compile test`
21+
22+
### Module Structure
23+
24+
The project is organized into these SBT modules:
25+
- `kyo-ai`: Core AI module with LLM effects, agents, tools, prompts, and thoughts
26+
- `kyo-ai-mcp`: Model Context Protocol integration (currently commented out)
27+
- `kyo-ai-copilot`: Copilot-related functionality
28+
- `kyo-ai-tlstm`: LSTM-based AI components
29+
- `kyo-neotypes`: Neo4j graph database integration
30+
- `kyo-container`: Container management for tests
31+
- `kyo-tastyquery`: TASTy query support for compile-time reflection
32+
33+
The default SBT project is set based on the `platform` system property (defaults to JVM).
34+
35+
## Core Architecture
36+
37+
The library follows a distinctive effect-driven design where AI capabilities are effects that compose with other Kyo effects.
38+
39+
### AI Effect (`kyo.AI`)
40+
41+
The `AI` effect is an opaque type combining `Var[Context] & Async`, meaning:
42+
- It automatically tracks and manages conversation context through the computation
43+
- Context updates persist across operations within the same AI computation
44+
- The AI instance IS the computation itself, not a service handle
45+
46+
**Key insight**: Since AI extends `Var[Context]`, the conversation history is managed as mutable state that flows through the effect composition.
47+
48+
Entry points:
49+
- `AI.run(computation)`: Run with empty context
50+
- `AI.run(config)(computation)`: Run with specific configuration
51+
- `AI.gen[A]`: Generate typed response (core generation method)
52+
- `AI.forget(computation)`: Run computation but discard context changes (transaction-like)
53+
- `AI.fresh(computation)`: Run with new empty context
54+
55+
### Agents (`kyo.Agent`)
56+
57+
Agents are stateful, actor-based LLM entities: `opaque type Agent[+Error, In, Out] = Actor[Error, Message[In, Out], Any]`
58+
59+
Agents combine:
60+
- Actor concurrency model for message processing
61+
- Persistent conversation state
62+
- Lifecycle management (created, running, stopped)
63+
64+
Create agents with:
65+
- `Agent.run[In, Out](prompt, tools, thoughts)(messageHandler)`: High-level API
66+
- `Agent.runBehavior(behavior)`: Low-level API with custom actor behavior
67+
68+
### Tools (`kyo.Tool`)
69+
70+
Tools are type-safe functions that LLMs can invoke. The system automatically:
71+
- Derives JSON schemas from Scala types (using ZIO Schema)
72+
- Registers tools when enabled
73+
- Parses and dispatches tool calls
74+
- Serializes results
75+
76+
Each tool can have an integrated `Prompt` that provides specialized instructions for using that tool. Tool prompts are automatically included in the context when tools are enabled.
77+
78+
Create tools: `Tool.init[In][Out, S](name, description, prompt)(implementation)`
79+
80+
### Prompts (`kyo.Prompt`)
81+
82+
Prompts use a dual-component structure to address instruction forgetting:
83+
- **Primary instructions**: Placed at the start of context (detailed guidance)
84+
- **Reminders**: "Float" at the end of context (concise summaries of critical instructions)
85+
86+
This design ensures models maintain instruction adherence in long conversations since reminders always appear immediately before generation.
87+
88+
Create prompts: `Prompt.init[S](primaryInstructions, reminders)`
89+
90+
The `p` string interpolator normalizes whitespace for multi-line prompts.
91+
92+
### Thoughts (`kyo.Thought`)
93+
94+
Structured thinking framework that embeds explicit reasoning into generation by extending the output JSON schema:
95+
- `Opening` thoughts: Execute before main generation
96+
- `Closing` thoughts: Execute after main generation
97+
98+
Each thought can have a processing function that executes after generation, enabling verification, metrics, or dependent generations.
99+
100+
Create thoughts:
101+
- `Thought.opening[A](processingFunction)`
102+
- `Thought.closing[A](processingFunction)`
103+
104+
### JSON Handling (`kyo.ai.json.Json`)
105+
106+
Type-safe JSON encoding/decoding using ZIO Schema:
107+
- `Json[T]` trait provides schema, encode, decode
108+
- Automatic schema derivation via `JsonDerive`
109+
- Integration with ZIO JSON codecs
110+
111+
The `@doc` annotation adds documentation to JSON schemas sent to LLMs.
112+
113+
### Context Management (`kyo.ai.Context`)
114+
115+
Context tracks conversation history with messages:
116+
- `SystemMessage`: Instructions/role definition
117+
- `UserMessage`: User inputs (can include images)
118+
- `AssistantMessage`: Model responses
119+
- `ToolMessage`: Tool call results
120+
121+
Context operations:
122+
- `context.systemMessage(content)`
123+
- `context.userMessage(content, maybeImage)`
124+
- `context.assistantMessage(content)`
125+
- `context.merge(otherContext)`: Merges two contexts
126+
127+
### Configuration (`kyo.ai.Config`)
128+
129+
Configuration specifies LLM provider and parameters:
130+
- Provider-specific configs: `Config.OpenAI.*`, `Config.Anthropic.*`
131+
- Common parameters: temperature, maxTokens, topP, seed
132+
- Configuration scoping: `AI.withConfig(config)(computation)`
133+
134+
## Effect Composition
135+
136+
The AI effects compose with Kyo's effect system:
137+
- `AI & S`: Computation requiring AI and other effects S
138+
- Effects are handled via `.handle()` or specific runners
139+
- `Isolate[S, Sync, Any]` constraint ensures safe effect isolation
140+
141+
## Testing
142+
143+
Tests use ScalaTest with the custom `Test` base class (extends AsyncFlatSpec).
144+
Test files: `kyo-ai/shared/src/test/scala/kyo/*Test.scala`
145+
146+
Common test pattern:
147+
```scala
148+
"test description" in run {
149+
AI.run(testConfig) {
150+
for
151+
result <- AI.gen[ExpectedType](input)
152+
yield assert(result.field == expectedValue)
153+
}
154+
}
155+
```
156+
157+
### Test Debugging Protocol
158+
159+
When debugging test failures, follow this systematic approach:
160+
161+
1. **Plan with TodoWrite**: Create a task list with one item per failing test suite
162+
2. **Run tests**: Execute the test suite to identify all failures with `sbt "project <module>" test`
163+
3. **Analyze each failure**:
164+
- Read the failing test code to understand expectations
165+
- Read the implementation being tested
166+
- Determine if it's a **code bug** or **test bug**
167+
4. **Fix systematically**:
168+
- **Code bugs**: Fix the implementation to meet test expectations
169+
- **Test bugs**: Fix incorrect test expectations or invalid test data
170+
- **Never reduce test coverage** - maintain or improve coverage
171+
5. **Verify incrementally**: Run `sbt "project <module>" "testOnly *TestName"` after each fix
172+
6. **Final verification**: Run complete test suite to ensure no regressions
173+
7. **Update TodoWrite**: Mark each task completed as you finish
174+
175+
**Common Issues in kyo-ai-ren:**
176+
- Grid operations: Distinguish between object IDs from `grid.analysis` vs direct grid cell values
177+
- Grid validation: Colors must be 0-9
178+
- Commented code: Check for commented-out validations or logic that should be active
179+
- Test data: Ensure test inputs use valid object IDs and color values
180+
181+
**Use `/debug-tests` slash command** to invoke this protocol automatically.
182+
183+
## Code Style
184+
185+
- Scala 3 syntax with `scala3` dialect
186+
- 140 character line limit
187+
- 4-space indentation
188+
- End markers for blocks with 4+ lines
189+
- Sorted imports with scalastyle ordering
190+
- Format enforced via scalafmt on compile
191+
192+
## Dependencies
193+
194+
Core dependencies:
195+
- Kyo framework (version 1.0-RC1+22-038de0d8-SNAPSHOT)
196+
- ZIO Schema for JSON schema derivation
197+
- STTP for HTTP client
198+
- Playwright for browser automation
199+
200+
## Important Notes
201+
202+
- The repository uses forking in tests (`fork := true`) with JVM option `--add-opens=java.base/java.lang=ALL-UNNAMED`
203+
- The AI computation model is stateful - context changes persist through the computation chain
204+
- Use `AI.forget` when you need to make exploratory LLM calls without affecting the main conversation
205+
- Tools and Prompts are enabled for computations via `.enable(v)` or `Tool.enable(tools*)(v)`

0 commit comments

Comments
 (0)