Skip to content

Commit 04d531e

Browse files
authored
Merge pull request #370 from Kiln-AI/main
Update docs for v0.17 release
2 parents 9f0278e + f435571 commit 04d531e

File tree

108 files changed

+4589
-1645
lines changed

Some content is hidden

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

108 files changed

+4589
-1645
lines changed

.cursorrules

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
2) assume an appriopirate test file already exists, find it, and suggest tests get appended to that file. If no such file exists, ask me before assuming a new test file is the correct route.
88
3) Test brevity is important. Use approaches for re-use and brevity including using fixtures for repeated code, and using pytest parameterize for similar tests
99
4) After writing a new test, run it and ensure it works. Fix any issues you find.
10-
11-
10+
- To run web tests `cd app/web_ui` then `npm run test_run`
11+
- Don't include comments in code explaining changes, explain changes in chat instead.
12+
- If a python API's interface changes (or a new one is added), generate new bindings by running `cd app/web_ui/src/lib/ && ./generate.sh`

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
],
1616
"python.testing.unittestEnabled": false,
1717
"python.testing.pytestEnabled": true,
18+
"python.analysis.typeCheckingMode": "basic",
19+
"python.analysis.autoImportCompletions": true,
20+
"python.analysis.extraPaths": ["./"],
21+
"python.analysis.ignore": ["**/test_*.py"],
1822
"files.exclude": {
1923
"**/__pycache__": true,
2024
"**/.pytest_cache": true,

AGENTS.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## .cursorrules
2+
3+
Read .cursorrules before starting.
4+
5+
## Python testing, formatting and linting
6+
7+
If you've edited any python code, the following commands should run and not produce error codes. Fix any issues and re-run.
8+
9+
```
10+
# Formatting 1:
11+
uvx ruff check --select I
12+
# Formatting 2:
13+
uvx ruff format --check .
14+
# type checking: warnings in output are acceptable, but error codes are not
15+
uv run pyright .
16+
# tests:
17+
uv run python3 -m pytest --benchmark-quiet -q .
18+
```
19+
20+
## Web app testing, formatting and linting
21+
22+
If you change any web app code, the following commands should run and not produce error codes. Fix any issues and re-run.
23+
24+
```
25+
# All commands below should be run from app/web_ui directory
26+
cd app/web_ui
27+
npm run format_check
28+
npm run lint
29+
npm run check
30+
npm run test_run
31+
npm run build > /dev/null
32+
```

CONTRIBUTING.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Running the web-UI and Python servers separately is useful for development, as b
2626

2727
To run the API server, Studio server, and Studio Web UI with auto-reload for development:
2828

29-
1. In your first terminal:
29+
1. In your first terminal, navigate to the base Kiln directory:
3030

3131
```bash
3232
uv run python -m app.desktop.dev_server
@@ -54,7 +54,7 @@ Please ensure any new code has test coverage, and that all code is formatted and
5454
To confirm everything works locally, run:
5555

5656
```bash
57-
./checks.sh
57+
uv run ./checks.sh
5858
```
5959

6060
## Optional Setup
@@ -71,7 +71,6 @@ We suggest the following extensions for VSCode/Cursor. With them, you'll get com
7171
- Svelte for VS Code
7272
- Vitest
7373
- ESLint
74-
- Cursor Pyright
7574

7675
### llms.txt
7776

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
| CI | [![Build and Test](https://github.com/Kiln-AI/kiln/actions/workflows/build_and_test.yml/badge.svg)](https://github.com/Kiln-AI/kiln/actions/workflows/build_and_test.yml) [![Format and Lint](https://github.com/Kiln-AI/kiln/actions/workflows/format_and_lint.yml/badge.svg)](https://github.com/Kiln-AI/kiln/actions/workflows/format_and_lint.yml) [![Desktop Apps Build](https://github.com/Kiln-AI/kiln/actions/workflows/build_desktop.yml/badge.svg)](https://github.com/Kiln-AI/kiln/actions/workflows/build_desktop.yml) [![Web UI Build](https://github.com/Kiln-AI/kiln/actions/workflows/web_format_lint_build.yml/badge.svg)](https://github.com/Kiln-AI/kiln/actions/workflows/web_format_lint_build.yml) [![Test Count Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/scosman/57742c1b1b60d597a6aba5d5148d728e/raw/test_count_kiln.json)](https://github.com/Kiln-AI/kiln/actions/workflows/test_count.yml) [![Test Coverage Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/scosman/57742c1b1b60d597a6aba5d5148d728e/raw/library_coverage_kiln.json)](https://github.com/Kiln-AI/kiln/actions/workflows/test_count.yml) [![Docs](https://github.com/Kiln-AI/Kiln/actions/workflows/build_docs.yml/badge.svg)](https://github.com/Kiln-AI/Kiln/actions/workflows/build_docs.yml) |
2323
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/kiln-ai.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/kiln-ai/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/kiln-ai.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/kiln-ai/) |
2424
| Meta | [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![types - Pyright](https://img.shields.io/badge/types-pyright-blue.svg)](https://github.com/microsoft/pyright) [![Docs](https://img.shields.io/badge/docs-pdoc-blue)](https://kiln-ai.github.io/Kiln/kiln_core_docs/index.html) |
25-
| Apps | [![MacOS](https://img.shields.io/badge/MacOS-black?logo=apple)](https://github.com/Kiln-AI/Kiln/releases/latest) [![Windows](https://img.shields.io/badge/Windows-0067b8.svg?logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyBmaWxsPSIjZmZmIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2Ljc0MiAxNi43NDJ2MTQuMjUzaDE0LjI1M3YtMTQuMjUzek0xLjAwNCAxNi43NDJ2MTQuMjUzaDE0LjI1NnYtMTQuMjUzek0xNi43NDIgMS4wMDR2MTQuMjU2aDE0LjI1M3YtMTQuMjU2ek0xLjAwNCAxLjAwNHYxNC4yNTZoMTQuMjU2di0xNC4yNTZ6Ij48L3BhdGg+Cjwvc3ZnPg==)](https://github.com/Kiln-AI/Kiln/releases/latest) [![Linux](https://img.shields.io/badge/Linux-444444?logo=linux&logoColor=ffffff)](https://github.com/Kiln-AI/Kiln/releases/latest) ![Github Downsloads](https://img.shields.io/github/downloads/kiln-ai/kiln/total) |
26-
| Connect | [![Discord](https://img.shields.io/badge/Discord-Kiln_AI-blue?logo=Discord&logoColor=white)](https://discord.gg/Q5QwFeGTDh) [![Newsletter](https://img.shields.io/badge/Newsletter-kilnai-blue?logo=Substack&logoColor=white)](https://kilnai.substack.com) |
25+
| Apps | [![MacOS](https://img.shields.io/badge/MacOS-black?logo=apple)](https://getkiln.ai/download) [![Windows](https://img.shields.io/badge/Windows-0067b8.svg?logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyBmaWxsPSIjZmZmIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2Ljc0MiAxNi43NDJ2MTQuMjUzaDE0LjI1M3YtMTQuMjUzek0xLjAwNCAxNi43NDJ2MTQuMjUzaDE0LjI1NnYtMTQuMjUzek0xNi43NDIgMS4wMDR2MTQuMjU2aDE0LjI1M3YtMTQuMjU2ek0xLjAwNCAxLjAwNHYxNC4yNTZoMTQuMjU2di0xNC4yNTZ6Ij48L3BhdGg+Cjwvc3ZnPg==)](https://getkiln.ai/download) [![Linux](https://img.shields.io/badge/Linux-444444?logo=linux&logoColor=ffffff)](https://getkiln.ai/download) ![Github Downsloads](https://img.shields.io/github/downloads/kiln-ai/kiln/total) |
26+
| Connect | [![Discord](https://img.shields.io/badge/Discord-Kiln_AI-blue?logo=Discord&logoColor=white)](https://getkiln.ai/discord) [![Newsletter](https://img.shields.io/badge/Newsletter-subscribe-blue?logo=mailboxdotorg&logoColor=white)](https://getkiln.ai/blog) |
2727

28-
[<img width="220" alt="Download button" src="https://github.com/user-attachments/assets/a5d51b8b-b30a-4a16-a902-ab6ef1d58dc0">](https://github.com/Kiln-AI/Kiln/releases/latest) [<img width="220" alt="Quick start button" src="https://github.com/user-attachments/assets/aff1b35f-72c0-4286-9b28-40a415558359">](https://docs.getkiln.ai/getting-started/quickstart)
28+
[<img width="220" alt="Download button" src="https://github.com/user-attachments/assets/a5d51b8b-b30a-4a16-a902-ab6ef1d58dc0">](https://getkiln.ai/download) [<img width="220" alt="Quick start button" src="https://github.com/user-attachments/assets/aff1b35f-72c0-4286-9b28-40a415558359">](https://docs.getkiln.ai/getting-started/quickstart)
2929

3030
## Key Features
3131

@@ -46,7 +46,7 @@
4646

4747
The Kiln desktop app is completely free. Available on MacOS, Windows and Linux.
4848

49-
[<img width="220" alt="Download button" src="https://github.com/user-attachments/assets/a5d51b8b-b30a-4a16-a902-ab6ef1d58dc0">](https://github.com/Kiln-AI/Kiln/releases/latest)
49+
[<img width="220" alt="Download button" src="https://github.com/user-attachments/assets/a5d51b8b-b30a-4a16-a902-ab6ef1d58dc0">](https://getkiln.ai/download)
5050

5151
## Demo
5252

app/desktop/WinInnoSetup.iss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#define MyAppPath "build\dist\Kiln"
55
#define MyAppName "Kiln"
6-
#define MyAppVersion "0.16.0"
6+
#define MyAppVersion "0.17.0"
77
#define MyAppPublisher "Chesterfield Laboratories Inc"
88
#define MyAppURL "https://getkiln.ai"
99
#define MyAppExeName "Kiln.exe"

app/desktop/desktop_server.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import asyncio
12
import contextlib
3+
import os
24
import threading
35
import time
46
from contextlib import asynccontextmanager
@@ -7,6 +9,7 @@
79
import kiln_server.server as kiln_server
810
import uvicorn
911
from fastapi import FastAPI
12+
from kiln_ai.utils.logging import setup_litellm_logging
1013

1114
from app.desktop.log_config import log_config
1215
from app.desktop.studio_server.data_gen_api import connect_data_gen_api
@@ -21,6 +24,12 @@
2124

2225
@asynccontextmanager
2326
async def lifespan(app: FastAPI):
27+
# debug event loop, warning on hangs
28+
should_debug = os.environ.get("DEBUG_EVENT_LOOP", "false") == "true"
29+
if should_debug:
30+
loop = asyncio.get_event_loop()
31+
loop.set_debug(True)
32+
2433
# Set datamodel strict mode on startup
2534
original_strict_mode = datamodel_strict_mode.strict_mode()
2635
datamodel_strict_mode.set_strict_mode(True)
@@ -30,6 +39,8 @@ async def lifespan(app: FastAPI):
3039

3140

3241
def make_app():
42+
setup_litellm_logging()
43+
3344
app = kiln_server.make_app(lifespan=lifespan)
3445
connect_provider_api(app)
3546
connect_prompt_api(app)

app/desktop/dev_server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
# Run a desktop server for development:
22
# - Auto-reload is enabled
33
# - Extra logging (level+colors) is enabled
4+
import os
5+
46
import uvicorn
57

68
from app.desktop.desktop_server import make_app
79

810
# top level app object, as that's needed by auto-reload
911
dev_app = make_app()
1012

13+
os.environ["DEBUG_EVENT_LOOP"] = "true"
14+
15+
1116
if __name__ == "__main__":
1217
uvicorn.run(
1318
"app.desktop.dev_server:dev_app",

app/desktop/log_config.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from enum import Enum
33
from typing import List
44

5-
from kiln_ai.utils.config import Config
5+
from kiln_ai.utils.logging import get_default_formatter, get_log_file_path
66

77

88
class LogDestination(Enum):
@@ -15,20 +15,6 @@ def get_log_level() -> str:
1515
return os.getenv("KILN_LOG_LEVEL", "WARNING")
1616

1717

18-
def get_log_file_path() -> str:
19-
"""Get the path to the log file, using environment override if specified.
20-
21-
Returns:
22-
str: The path to the log file
23-
"""
24-
log_path_default = os.path.join(Config.settings_dir(), "logs", "kiln_desktop.log")
25-
log_path = os.getenv("KILN_LOG_FILE", log_path_default)
26-
27-
# Ensure the log directory exists
28-
os.makedirs(os.path.dirname(log_path), exist_ok=True)
29-
return log_path
30-
31-
3218
def get_max_file_bytes() -> int:
3319
"""
3420
The maximum number of bytes to write to the log file.
@@ -47,10 +33,6 @@ def get_max_backup_count() -> int:
4733
return int(os.getenv("KILN_LOG_BACKUP_COUNT", default_backup_count))
4834

4935

50-
def get_default_formatter() -> str:
51-
return "%(asctime)s.%(msecs)03d - %(levelname)s - %(name)s - %(message)s"
52-
53-
5436
def get_handlers() -> List[str]:
5537
destination = os.getenv("KILN_LOG_DESTINATION", "all")
5638
handlers = {
@@ -86,7 +68,7 @@ def log_config():
8668
"class": "logging.handlers.RotatingFileHandler",
8769
"level": get_log_level(),
8870
"formatter": "logformatter",
89-
"filename": get_log_file_path(),
71+
"filename": get_log_file_path("kiln_desktop.log"),
9072
"mode": "a",
9173
"maxBytes": get_max_file_bytes(),
9274
"backupCount": get_max_backup_count(),

app/desktop/studio_server/data_gen_api.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
DataGenSampleTaskInput,
88
wrap_task_with_guidance,
99
)
10+
from kiln_ai.adapters.ml_model_list import (
11+
default_structured_output_mode_for_model_provider,
12+
)
1013
from kiln_ai.adapters.model_adapters.base_adapter import AdapterConfig
1114
from kiln_ai.datamodel import DataSource, DataSourceType, PromptId, TaskRun
15+
from kiln_ai.datamodel.prompt_id import PromptGenerators
16+
from kiln_ai.datamodel.task import RunConfigProperties
1217
from kiln_server.run_api import model_provider_from_string
1318
from kiln_server.task_api import task_from_id
1419
from pydantic import BaseModel, ConfigDict, Field
@@ -92,8 +97,15 @@ async def generate_categories(
9297

9398
adapter = adapter_for_task(
9499
categories_task,
95-
model_name=input.model_name,
96-
provider=model_provider_from_string(input.provider),
100+
run_config_properties=RunConfigProperties(
101+
model_name=input.model_name,
102+
model_provider_name=model_provider_from_string(input.provider),
103+
prompt_id=PromptGenerators.SIMPLE,
104+
# We don't expose setting this manually in the UI, so pull a recommended mode from ml_model_list
105+
structured_output_mode=default_structured_output_mode_for_model_provider(
106+
input.model_name, model_provider_from_string(input.provider)
107+
),
108+
),
97109
)
98110

99111
categories_run = await adapter.invoke(task_input.model_dump())
@@ -115,8 +127,15 @@ async def generate_samples(
115127

116128
adapter = adapter_for_task(
117129
sample_task,
118-
model_name=input.model_name,
119-
provider=model_provider_from_string(input.provider),
130+
run_config_properties=RunConfigProperties(
131+
model_name=input.model_name,
132+
model_provider_name=model_provider_from_string(input.provider),
133+
prompt_id=PromptGenerators.SIMPLE,
134+
# We don't expose setting this manually in the UI, so pull a recommended mode from ml_model_list
135+
structured_output_mode=default_structured_output_mode_for_model_provider(
136+
input.model_name, model_provider_from_string(input.provider)
137+
),
138+
),
120139
)
121140

122141
samples_run = await adapter.invoke(task_input.model_dump())
@@ -139,9 +158,16 @@ async def save_sample(
139158

140159
adapter = adapter_for_task(
141160
task,
142-
model_name=sample.output_model_name,
143-
provider=model_provider_from_string(sample.output_provider),
144-
prompt_id=sample.prompt_method,
161+
run_config_properties=RunConfigProperties(
162+
model_name=sample.output_model_name,
163+
model_provider_name=model_provider_from_string(sample.output_provider),
164+
prompt_id=sample.prompt_method,
165+
# We don't expose setting this manually in the UI, so pull a recommended mode from ml_model_list
166+
structured_output_mode=default_structured_output_mode_for_model_provider(
167+
sample.output_model_name,
168+
model_provider_from_string(sample.output_provider),
169+
),
170+
),
145171
)
146172

147173
properties: dict[str, str | int | float] = {

0 commit comments

Comments
 (0)