# Kitaru Reference
This site is the auto-generated reference for Kitaru's public **Python SDK** and
**command-line interface**. It is generated directly from the Kitaru source on
every release.
Looking for guides, concepts, and tutorials? Those live in the main
[Kitaru documentation](https://docs.zenml.io/kitaru).
# kitaru doctor
## Usage [#usage]
```bash
kitaru doctor [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# CLI Reference
Reference pages for every `kitaru` command, generated from the CLI's own schema output.
## Global options [#global-options]
Every command accepts these options in addition to its own.
| Name | Type | Required | Description |
| ------------------------ | ------------------------- | -------- | --------------------------- |
| `--output/-o` | `auto\|text\|json\|jsonl` | No | Serialization mode. |
| `--machine/--no-machine` | `boolean` | No | Terminal rendering mode. |
| `--server` | `URL` | No | Server URL override. |
| `--non-interactive` | `boolean` | No | Disable interaction. |
| `--no-browser` | `boolean` | No | Disable browser launch. |
| `--request-timeout` | `positive float` | No | HTTP timeout. |
| `--debug` | `boolean` | No | Redacted debug diagnostics. |
| `--traceback` | `boolean` | No | Redacted traceback. |
The `--output` type above is the union across all commands; each command page lists the modes that command supports.
## Commands [#commands]
| Command | Description |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`agent`](/cli/agent/) | Register and inspect agents. |
| [`analyzer`](/cli/analyzer/) | Register and inspect analyzers. |
| [`annotation`](/cli/annotation/) | Create and manage session annotations. |
| [`cohort`](/cli/cohort/) | Manage cohort namespaces and immutable membership versions. |
| [`config`](/cli/config/) | Manage allowlisted CLI preferences. |
| [`connection`](/cli/connection/) | Create and manage provider connections. |
| [`doctor`](/cli/doctor/) | Run independent local, server, authentication, and tooling checks. |
| [`evaluation`](/cli/evaluation/) | Inspect stored evaluations. |
| [`evaluator`](/cli/evaluator/) | Develop, register, and inspect evaluators. |
| [`experiment`](/cli/experiment/) | Configure experiments and manage asynchronous runs. |
| [`import`](/cli/import/) | Inspect imports and rerun analyzers over them. |
| [`importer`](/cli/importer/) | Develop, register, and inspect importers. |
| [`info`](/cli/info/) | Show local runtime details and resolved server information. |
| [`insight`](/cli/insight/) | Create and inspect agent insights. |
| [`investigation`](/cli/investigation/) | Create investigations and review their linked sessions. |
| [`job`](/cli/job/) | Inspect, watch, and cancel jobs. |
| [`local`](/cli/local/) | Inspect the CLI-owned local Kitaru deployment. |
| [`login`](/cli/login/) | Authenticate with managed cloud (14-day trial, no credit card required) or a Kitaru server. |
| [`logout`](/cli/logout/) | Disconnect from a server and stop an owned local deployment. |
| [`replay`](/cli/replay/) | Create and inspect standalone replays. |
| [`schema`](/cli/schema/) | Describe the CLI command tree from offline registration metadata. |
| [`session`](/cli/session/) | Import and inspect sessions and their nodes. |
| [`setup`](/cli/setup/) | Install the agent skills and register the MCP server with every detected coding agent. Re-run after installing a new one. The global --server picks the server the MCP server targets. |
| [`status`](/cli/status/) | Show connection, authentication, compatibility, and live-worker status. |
| [`version`](/cli/version/) | Show the installed Kitaru version. |
| [`worker`](/cli/worker/) | Run and inspect generic local workers. |
# kitaru info
## Usage [#usage]
```bash
kitaru info [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru login
## Usage [#usage]
```bash
kitaru login [SERVER] [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----- | -------- | ------------------------------------------------------------ |
| `SERVER` | `URL` | No | Managed or self-hosted instance URL; omit for managed cloud. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------ | --------- | -------- | ----------------------------------------------------- |
| `--local` | `boolean` | No | Provision and use a local Docker deployment. |
| `--port` | `integer` | No | Host port for --local; overrides KITARU\_LOCAL\_PORT. |
| `--upgrade` | `boolean` | No | Upgrade the CLI-owned local deployment. |
| `--username` | `string` | No | Local account name. |
| `--password-stdin` | `boolean` | No | Read password from stdin. |
| `--api-key-stdin` | `boolean` | No | Read API key from stdin. |
| `--refresh` | `boolean` | No | Skip stored credentials and force a new device login. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru logout
## Usage [#usage]
```bash
kitaru logout [SERVER] [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----- | -------- | ----------------------- |
| `SERVER` | `URL` | No | Server to log out from. |
## Options [#options]
| Name | Type | Required | Description |
| -------------- | --------- | -------- | ----------------------------------------------- |
| `--all` | `boolean` | No | Remove every stored credential. |
| `--volumes/-v` | `boolean` | No | Delete data for the CLI-owned local deployment. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru schema
## Usage [#usage]
```bash
kitaru schema [COMMAND...] [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ---------- | -------- | ---------------------- |
| `COMMAND` | `string[]` | No | Command or group path. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru setup
## Usage [#usage]
```bash
kitaru setup [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ------------- | --------- | -------- | ------------------------------------------------------------------- |
| `--mode` | `string` | No | MCP capability mode: read-only, standard (default), or destructive. |
| `--no-skills` | `boolean` | No | Skip installing the skills. |
| `--no-mcp` | `boolean` | No | Skip registering the MCP server. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru status
## Usage [#usage]
```bash
kitaru status [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru version
## Usage [#usage]
```bash
kitaru version [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent delete
## Usage [#usage]
```bash
kitaru agent delete AGENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------- | ----------- | -------- | ------------------- |
| `AGENT` | `reference` | Yes | Agent UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent get
## Usage [#usage]
```bash
kitaru agent get AGENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------- | ----------- | -------- | ------------------- |
| `AGENT` | `reference` | Yes | Agent UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent
## Usage [#usage]
```bash
kitaru agent COMMAND
```
## Commands [#commands]
| Command | Description |
| ---------------------------------- | -------------------------------------------------- |
| [`delete`](/cli/agent/delete/) | Soft delete an agent. |
| [`get`](/cli/agent/get/) | Get an agent by exact UUID or case-sensitive name. |
| [`list`](/cli/agent/list/) | List agents. |
| [`register`](/cli/agent/register/) | Create an agent and its first mutable version. |
| [`version`](/cli/agent/version/) | Subcommands of `kitaru agent version`. |
# kitaru agent list
## Usage [#usage]
```bash
kitaru agent list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent register
## Usage [#usage]
```bash
kitaru agent register NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | --------------- |
| `NAME` | `string` | Yes | New agent name. |
## Options [#options]
| Name | Type | Required | Description |
| ----------------------- | ------------------ | -------- | --------------------------------- |
| `--description` | `string` | No | Parent description. |
| `--version-description` | `string` | No | Version description. |
| `--spec` | `path` | No | YAML or JSON spec document. |
| `--command` | `string` | No | Shell command stored as supplied. |
| `--display-version` | `string` | No | Human-readable version. |
| `--working-dir` | `path` | No | Worker process directory. |
| `--env` | `KEY=VALUE[]` | No | Non-secret process environment. |
| `--secret-id` | `UUID[]` | No | Server secret IDs. |
| `--timeout-seconds` | `positive integer` | No | Process timeout. |
| `--tool` | `string[]` | No | Declared tools. |
| `--mcp-server` | `string[]` | No | Declared MCP servers. |
| `--skill` | `string[]` | No | Declared skills. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer get
## Usage [#usage]
```bash
kitaru analyzer get ANALYZER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `ANALYZER` | `reference` | Yes | Analyzer UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer
## Usage [#usage]
```bash
kitaru analyzer COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------------- | ----------------------------------------------------- |
| [`get`](/cli/analyzer/get/) | Get an analyzer by exact UUID or case-sensitive name. |
| [`list`](/cli/analyzer/list/) | List analyzers. |
| [`register`](/cli/analyzer/register/) | Create an analyzer and its first version. |
| [`version`](/cli/analyzer/version/) | Subcommands of `kitaru analyzer version`. |
# kitaru analyzer list
## Usage [#usage]
```bash
kitaru analyzer list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer register
## Usage [#usage]
```bash
kitaru analyzer register NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | ------------------ |
| `NAME` | `string` | Yes | New analyzer name. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | ------------- | -------- | -------------------------------------------------- |
| `--description` | `string` | No | Parent description. |
| `--metadata` | `JSON object` | No | Parent metadata. |
| `--provider` | `string` | No | Source provider. |
| `--connection-schema` | `path` | No | JSON Schema file describing the connection values. |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru annotation create
## Usage [#usage]
```bash
kitaru annotation create [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ------------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--session` | `UUID` | No | Session ID for a manual annotation. |
| `--investigation-session` | `UUID` | No | Investigation-session ID for an answer. |
| `--question-key` | `string` | No | Key of the question being answered. |
| `--selector` | `JSON object` | No | Optional node, JSON Pointer, or span selector. |
| `--value` | `JSON value` | Yes | Annotation value. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru annotation delete
## Usage [#usage]
```bash
kitaru annotation delete ANNOTATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ------ | -------- | -------------- |
| `ANNOTATION` | `UUID` | Yes | Annotation ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru annotation get
## Usage [#usage]
```bash
kitaru annotation get ANNOTATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ------ | -------- | -------------- |
| `ANNOTATION` | `UUID` | Yes | Annotation ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru annotation
## Usage [#usage]
```bash
kitaru annotation COMMAND
```
## Commands [#commands]
| Command | Description |
| ----------------------------------- | --------------------------------------------------------------- |
| [`create`](/cli/annotation/create/) | Create a manual annotation or answer an investigation question. |
| [`delete`](/cli/annotation/delete/) | Delete an annotation. |
| [`get`](/cli/annotation/get/) | Get an annotation by exact UUID. |
| [`list`](/cli/annotation/list/) | List annotations. |
| [`update`](/cli/annotation/update/) | Replace an annotation's JSON value. |
# kitaru annotation list
## Usage [#usage]
```bash
kitaru annotation list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru annotation update
## Usage [#usage]
```bash
kitaru annotation update ANNOTATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ------ | -------- | -------------- |
| `ANNOTATION` | `UUID` | Yes | Annotation ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | ------------ | -------- | ------------------ |
| `--value` | `JSON value` | Yes | Replacement value. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort create
## Usage [#usage]
```bash
kitaru cohort create NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | ---------------- |
| `NAME` | `string` | Yes | New cohort name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--agent` | `reference` | Yes | Exact agent UUID or case-sensitive name. |
| `--description` | `string` | No | Cohort description. |
| `--metadata` | `JSON object` | No | Cohort metadata. |
| `--session` | `UUID[]` | No | Explicit session IDs. |
| `--sessions-file` | `path` | No | UTF-8 file with one session UUID per nonblank line. |
| `--tag` | `text` | No | Sessions with this tag. |
| `--cohort` | `reference` | No | Sessions in this cohort version. |
| `--filter` | `JSON filter` | No | Session filter expression. |
| `--all` | `boolean` | No | All sessions. |
| `--display-version` | `string` | No | Display version for the membership snapshot. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort delete
## Usage [#usage]
```bash
kitaru cohort delete COHORT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----------- | -------- | -------------------- |
| `COHORT` | `reference` | Yes | Cohort UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------- |
| `--force` | `boolean` | No | Confirm cascading remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort get
## Usage [#usage]
```bash
kitaru cohort get COHORT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----------- | -------- | -------------------- |
| `COHORT` | `reference` | Yes | Cohort UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort
## Usage [#usage]
```bash
kitaru cohort COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------- | ---------------------------------------------------------- |
| [`create`](/cli/cohort/create/) | Create a cohort and optionally snapshot selected sessions. |
| [`delete`](/cli/cohort/delete/) | Delete a cohort and all of its versions. |
| [`get`](/cli/cohort/get/) | Get a cohort by exact UUID or case-sensitive name. |
| [`list`](/cli/cohort/list/) | List cohorts. |
| [`update`](/cli/cohort/update/) | Update selected fields on an exact cohort. |
| [`version`](/cli/cohort/version/) | Subcommands of `kitaru cohort version`. |
# kitaru cohort list
## Usage [#usage]
```bash
kitaru cohort list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort update
## Usage [#usage]
```bash
kitaru cohort update COHORT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----------- | -------- | -------------------- |
| `COHORT` | `reference` | Yes | Cohort UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | ------------- | -------- | ------------------------------------ |
| `--name` | `string` | No | New cohort name. |
| `--description` | `string` | No | New description. |
| `--clear-description` | `boolean` | No | Clear the description. |
| `--metadata` | `JSON object` | No | Replacement metadata; \{} clears it. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru config get
## Usage [#usage]
```bash
kitaru config get KEY [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | -------- | -------- | --------------------------- |
| `KEY` | `string` | Yes | Allowlisted preference key. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru config
## Usage [#usage]
```bash
kitaru config COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------- | ------------------------------------------------------------------- |
| [`get`](/cli/config/get/) | Get one allowlisted CLI preference. |
| [`list`](/cli/config/list/) | List allowlisted CLI preferences with effective values and sources. |
| [`path`](/cli/config/path/) | Show the global CLI config path without reading its contents. |
| [`set`](/cli/config/set/) | Set one allowlisted CLI preference. |
# kitaru config list
## Usage [#usage]
```bash
kitaru config list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru config path
## Usage [#usage]
```bash
kitaru config path [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru config set
## Usage [#usage]
```bash
kitaru config set KEY VALUE [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------- | --------- | -------- | --------------------------- |
| `KEY` | `string` | Yes | Allowlisted preference key. |
| `VALUE` | `boolean` | Yes | Boolean preference value. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluation get
## Usage [#usage]
```bash
kitaru evaluation get EVALUATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ------ | -------- | -------------- |
| `EVALUATION` | `UUID` | Yes | Evaluation ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluation
## Usage [#usage]
```bash
kitaru evaluation COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------- | -------------------------------------- |
| [`get`](/cli/evaluation/get/) | Get a stored evaluation by exact UUID. |
| [`list`](/cli/evaluation/list/) | List stored evaluations. |
# kitaru evaluation list
## Usage [#usage]
```bash
kitaru evaluation list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator get
## Usage [#usage]
```bash
kitaru evaluator get EVALUATOR [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----------- | ----------- | -------- | ----------------------- |
| `EVALUATOR` | `reference` | Yes | Evaluator UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator
## Usage [#usage]
```bash
kitaru evaluator COMMAND
```
## Commands [#commands]
| Command | Description |
| -------------------------------------- | ------------------------------------------------------------------------ |
| [`get`](/cli/evaluator/get/) | Get an evaluator by exact UUID or case-sensitive name. |
| [`list`](/cli/evaluator/list/) | List evaluators. |
| [`register`](/cli/evaluator/register/) | Create an evaluator and its first version. |
| [`scaffold`](/cli/evaluator/scaffold/) | Create a minimal evaluator script. |
| [`test`](/cli/evaluator/test/) | Load an evaluator and validate its signature in a bounded child process. |
| [`version`](/cli/evaluator/version/) | Subcommands of `kitaru evaluator version`. |
# kitaru evaluator list
## Usage [#usage]
```bash
kitaru evaluator list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator register
## Usage [#usage]
```bash
kitaru evaluator register NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | ------------------- |
| `NAME` | `string` | Yes | New evaluator name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ------------------------------------- |
| `--description` | `string` | No | Parent description. |
| `--metadata` | `JSON object` | No | Parent metadata. |
| `--agent-id` | `UUID` | No | Scoping agent. |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator scaffold
## Usage [#usage]
```bash
kitaru evaluator scaffold NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | -------------- |
| `NAME` | `string` | Yes | Scaffold name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | -------------------------- |
| `--path` | `path` | No | Exact target .py file. |
| `--force` | `boolean` | No | Overwrite the target file. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator test
## Usage [#usage]
```bash
kitaru evaluator test PATH [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | ------ | -------- | ----------------- |
| `PATH` | `path` | Yes | Evaluator script. |
## Options [#options]
| Name | Type | Required | Description |
| -------------- | ---------------- | -------- | -------------------- |
| `--entrypoint` | `attribute` | Yes | Evaluator attribute. |
| `--timeout` | `positive float` | No | Child timeout. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection create
## Usage [#usage]
```bash
kitaru connection create NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | -------------------- |
| `NAME` | `string` | Yes | New connection name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--importer` | `reference` | No | Importer whose connection schema drives the prompts. |
| `--analyzer` | `reference` | No | Analyzer whose connection schema drives the prompts. |
| `--provider` | `string` | No | Provider addressed directly. |
| `--set` | `KEY=VALUE[]` | No | Non-secret environment value. |
| `--set-secret` | `KEY=VALUE[]` | No | Sensitive environment value. |
| `--default` | `boolean` | No | Make this the provider's default connection. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection delete
## Usage [#usage]
```bash
kitaru connection delete CONNECTION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `CONNECTION` | `reference` | Yes | Connection UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection get
## Usage [#usage]
```bash
kitaru connection get CONNECTION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `CONNECTION` | `reference` | Yes | Connection UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection
## Usage [#usage]
```bash
kitaru connection COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------------------- | --------------------------------------------------------------- |
| [`create`](/cli/connection/create/) | Create a connection from a plugin schema or from direct values. |
| [`delete`](/cli/connection/delete/) | Delete a connection and the secret holding its values. |
| [`get`](/cli/connection/get/) | Get a connection by exact UUID or case-sensitive name. |
| [`list`](/cli/connection/list/) | List connections. |
| [`set-default`](/cli/connection/set-default/) | Make a connection the default for its provider. |
| [`update`](/cli/connection/update/) | Update values on an exact connection. |
# kitaru connection list
## Usage [#usage]
```bash
kitaru connection list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection set-default
## Usage [#usage]
```bash
kitaru connection set-default CONNECTION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `CONNECTION` | `reference` | Yes | Connection UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru connection update
## Usage [#usage]
```bash
kitaru connection update CONNECTION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `CONNECTION` | `reference` | Yes | Connection UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------------ | ------------- | -------- | --------------------------------------------------------------- |
| `--set` | `KEY=VALUE[]` | No | Non-secret environment value. Keeps the other stored values. |
| `--set-secret` | `KEY=VALUE[]` | No | Sensitive environment value. Replaces all stored secret values. |
| `--default/--no-default` | `boolean` | No | Set or clear the provider's default connection. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment create
## Usage [#usage]
```bash
kitaru experiment create NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | -------------------- |
| `NAME` | `string` | Yes | New experiment name. |
## Options [#options]
| Name | Type | Required | Description |
| -------------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--agent` | `reference` | Yes | Exact agent UUID or case-sensitive name. |
| `--description` | `string` | No | Experiment description. |
| `--override` | `JSON object` | No | Replay override applied to every run. |
| `--tool-policy` | `JSON object` | No | Tool policy applied to every run; omitted uses the server default. |
| `--evaluator` | `reference[]` | Yes | Exact EVALUATOR\@VERSION references. |
| `--evaluator-params` | `EVALUATOR@VERSION=JSON_OBJECT[]` | No | Parameters for a selected evaluator token. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment delete
## Usage [#usage]
```bash
kitaru experiment delete EXPERIMENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `EXPERIMENT` | `reference` | Yes | Experiment UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment get
## Usage [#usage]
```bash
kitaru experiment get EXPERIMENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `EXPERIMENT` | `reference` | Yes | Experiment UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment
## Usage [#usage]
```bash
kitaru experiment COMMAND
```
## Commands [#commands]
| Command | Description |
| ----------------------------------- | ----------------------------------------------------------- |
| [`create`](/cli/experiment/create/) | Create an experiment with exact evaluator versions. |
| [`delete`](/cli/experiment/delete/) | Delete an experiment and preserve server conflict behavior. |
| [`get`](/cli/experiment/get/) | Get an experiment by exact UUID or case-sensitive name. |
| [`list`](/cli/experiment/list/) | List experiments. |
| [`run`](/cli/experiment/run/) | Subcommands of `kitaru experiment run`. |
| [`update`](/cli/experiment/update/) | Update selected fields on an exact experiment. |
# kitaru experiment list
## Usage [#usage]
```bash
kitaru experiment list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment update
## Usage [#usage]
```bash
kitaru experiment update EXPERIMENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `EXPERIMENT` | `reference` | Yes | Experiment UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | --------------------------------- | -------- | ----------------------------------------------------- |
| `--name` | `string` | No | New experiment name. |
| `--description` | `string` | No | New description. |
| `--clear-description` | `boolean` | No | Clear the description. |
| `--override` | `JSON object` | No | Replacement replay override. |
| `--clear-override` | `boolean` | No | Clear the replay override. |
| `--tool-policy` | `JSON object` | No | Replacement tool policy; cannot be cleared. |
| `--evaluator` | `reference[]` | No | Exact evaluator versions replacing the complete list. |
| `--evaluator-params` | `EVALUATOR@VERSION=JSON_OBJECT[]` | No | Parameters for a selected evaluator token. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru import analyze
## Usage [#usage]
```bash
kitaru import analyze IMPORT_ID [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----------- | ------ | -------- | ----------- |
| `IMPORT_ID` | `UUID` | Yes | Import ID. |
## Options [#options]
| Name | Type | Required | Description |
| ----------------------- | -------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--analyzer` | `ANALYZER@VERSION[]` | Yes | Exact analyzer version run once over the import's sessions. |
| `--analyzer-params` | `ANALYZER@VERSION=JSON_OBJECT[]` | No | Parameters for a selected analyzer token. |
| `--analyzer-connection` | `ANALYZER@VERSION=CONNECTION[]` | No | Connection for a selected analyzer token. |
| `--wait` | `boolean` | No | Wait for remote work settlement. |
| `--interval` | `positive float` | No | Polling interval; requires --wait. |
| `--timeout` | `positive float` | No | Local wait timeout; requires --wait. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru import get
## Usage [#usage]
```bash
kitaru import get IMPORT_ID [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----------- | ------ | -------- | ----------- |
| `IMPORT_ID` | `UUID` | Yes | Import ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru import
## Usage [#usage]
```bash
kitaru import COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------- | ----------------------------------------------------------------- |
| [`analyze`](/cli/import/analyze/) | Run analyzers over the sessions of an existing import as one job. |
| [`get`](/cli/import/get/) | Get one import by exact UUID. |
| [`list`](/cli/import/list/) | List imports. |
# kitaru import list
## Usage [#usage]
```bash
kitaru import list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer get
## Usage [#usage]
```bash
kitaru importer get IMPORTER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `IMPORTER` | `reference` | Yes | Importer UUID or name. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer
## Usage [#usage]
```bash
kitaru importer COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------------- | ------------------------------------------------------------------------- |
| [`get`](/cli/importer/get/) | Get an importer by exact UUID or case-sensitive name. |
| [`list`](/cli/importer/list/) | List importers. |
| [`register`](/cli/importer/register/) | Create an importer and its first version. |
| [`scaffold`](/cli/importer/scaffold/) | Create a minimal importer Parser script. |
| [`test`](/cli/importer/test/) | Load and optionally invoke an importer Parser in a bounded child process. |
| [`version`](/cli/importer/version/) | Subcommands of `kitaru importer version`. |
# kitaru importer list
## Usage [#usage]
```bash
kitaru importer list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer register
## Usage [#usage]
```bash
kitaru importer register NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | ------------------ |
| `NAME` | `string` | Yes | New importer name. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | ------------- | -------- | -------------------------------------------------- |
| `--description` | `string` | No | Parent description. |
| `--metadata` | `JSON object` | No | Parent metadata. |
| `--provider` | `string` | No | Source provider. |
| `--connection-schema` | `path` | No | JSON Schema file describing the connection values. |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer scaffold
## Usage [#usage]
```bash
kitaru importer scaffold NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | -------------- |
| `NAME` | `string` | Yes | Scaffold name. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | -------------------------- |
| `--path` | `path` | No | Exact target .py file. |
| `--force` | `boolean` | No | Overwrite the target file. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer test
## Usage [#usage]
```bash
kitaru importer test PATH [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | ------ | -------- | ---------------- |
| `PATH` | `path` | Yes | Importer script. |
## Options [#options]
| Name | Type | Required | Description |
| -------------- | ---------------- | -------- | ------------------ |
| `--entrypoint` | `attribute` | Yes | Parser attribute. |
| `--payload` | `path` | No | Payload to parse. |
| `--params` | `JSON object` | No | Parser parameters. |
| `--timeout` | `positive float` | No | Child timeout. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru insight create
## Usage [#usage]
```bash
kitaru insight create [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--agent` | `reference` | Yes | Agent UUID or case-sensitive name. |
| `--insight` | `JSON[]` | Yes | Insight JSON object; repeat for each created insight. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru insight delete
## Usage [#usage]
```bash
kitaru insight delete INSIGHT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ------ | -------- | ----------- |
| `INSIGHT` | `UUID` | Yes | Insight ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru insight get
## Usage [#usage]
```bash
kitaru insight get INSIGHT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ------ | -------- | ----------- |
| `INSIGHT` | `UUID` | Yes | Insight ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru insight
## Usage [#usage]
```bash
kitaru insight COMMAND
```
## Commands [#commands]
| Command | Description |
| -------------------------------- | ----------------------------------------- |
| [`create`](/cli/insight/create/) | Create a batch of insights for one agent. |
| [`delete`](/cli/insight/delete/) | Delete an insight. |
| [`get`](/cli/insight/get/) | Get an insight by exact UUID. |
| [`list`](/cli/insight/list/) | List insights. |
| [`update`](/cli/insight/update/) | Update selected insight fields. |
# kitaru insight list
## Usage [#usage]
```bash
kitaru insight list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | --------------------------- | -------- | ------------------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
| `--agent` | `reference` | No | Only insights for this exact agent UUID or name. |
| `--name` | `string` | No | Only insights with this exact name. |
| `--type` | `text\|categorical\|binned` | No | Only insights with this data type. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru insight update
## Usage [#usage]
```bash
kitaru insight update INSIGHT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ------ | -------- | ----------- |
| `INSIGHT` | `UUID` | Yes | Insight ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | --------- | -------- | ---------------------- |
| `--title` | `string` | No | New title. |
| `--description` | `string` | No | New description. |
| `--clear-description` | `boolean` | No | Clear the description. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation create
## Usage [#usage]
```bash
kitaru investigation create NAME [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | -------- | -------- | ----------------------- |
| `NAME` | `string` | Yes | New investigation name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------------------- | -------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--agent` | `reference` | Yes | Agent UUID or case-sensitive name. |
| `--description` | `string` | No | Curator rationale. |
| `--session` | `UUID[]` | No | Ordered session UUID; repeat for each linked session. |
| `--session-question` | `SESSION:KEY=QUESTION[]` | No | Keyed question for a session selected with --session. |
| `--session-highlights` | `SESSION:KEY=JSON_ARRAY[]` | No | Curated highlights for a question added with --session-question. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation delete
## Usage [#usage]
```bash
kitaru investigation delete INVESTIGATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ------ | -------- | ----------------- |
| `INVESTIGATION` | `UUID` | Yes | Investigation ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ---------------------------------- |
| `--force` | `boolean` | No | Confirm cascading remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation get
## Usage [#usage]
```bash
kitaru investigation get INVESTIGATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ------ | -------- | ----------------- |
| `INVESTIGATION` | `UUID` | Yes | Investigation ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation
## Usage [#usage]
```bash
kitaru investigation COMMAND
```
## Commands [#commands]
| Command | Description |
| ---------------------------------------- | -------------------------------------------------------------- |
| [`create`](/cli/investigation/create/) | Create an investigation with linked sessions. |
| [`delete`](/cli/investigation/delete/) | Delete an investigation, its linked sessions, and its answers. |
| [`get`](/cli/investigation/get/) | Get an investigation by exact UUID. |
| [`list`](/cli/investigation/list/) | List investigations. |
| [`session`](/cli/investigation/session/) | Subcommands of `kitaru investigation session`. |
| [`update`](/cli/investigation/update/) | Update selected investigation fields. |
# kitaru investigation list
## Usage [#usage]
```bash
kitaru investigation list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation update
## Usage [#usage]
```bash
kitaru investigation update INVESTIGATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ------ | -------- | ----------------- |
| `INVESTIGATION` | `UUID` | Yes | Investigation ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------------------- | ------------------------ | -------- | ---------------------------- |
| `--name` | `string` | No | New name. |
| `--description` | `string` | No | New curator rationale. |
| `--clear-description` | `boolean` | No | Clear the curator rationale. |
| `--status` | `in_progress\|completed` | No | New investigation status. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru job cancel
## Usage [#usage]
```bash
kitaru job cancel JOB [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ----------- |
| `JOB` | `UUID` | Yes | Job ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru job get
## Usage [#usage]
```bash
kitaru job get JOB [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ----------- |
| `JOB` | `UUID` | Yes | Job ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ---------------------- |
| `--tasks` | `boolean` | No | Include all job tasks. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru job
## Usage [#usage]
```bash
kitaru job COMMAND
```
## Commands [#commands]
| Command | Description |
| ---------------------------- | ------------------------------------------------------------------------- |
| [`cancel`](/cli/job/cancel/) | Request job cancellation once without waiting for settlement. |
| [`get`](/cli/job/get/) | Get a job and optionally include a complete task snapshot. |
| [`watch`](/cli/job/watch/) | Poll a job until it completes, fails, or is canceled without changing it. |
# kitaru job watch
## Usage [#usage]
```bash
kitaru job watch JOB [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ----------- |
| `JOB` | `UUID` | Yes | Job ID. |
## Options [#options]
| Name | Type | Required | Description |
| ------------ | ---------------- | -------- | ------------------- |
| `--interval` | `positive float` | No | Polling interval. |
| `--timeout` | `positive float` | No | Local wait timeout. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru local
## Usage [#usage]
```bash
kitaru local COMMAND
```
## Commands [#commands]
| Command | Description |
| -------------------------- | ---------------------------------------------- |
| [`logs`](/cli/local/logs/) | Read logs from the CLI-owned local deployment. |
# kitaru local logs
## Usage [#usage]
```bash
kitaru local logs [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Options [#options]
| Name | Type | Required | Description |
| ----------- | ------------ | -------- | ------------------------------------ |
| `--service` | `server\|db` | No | Limit output to one Compose service. |
| `--tail` | `integer` | No | Number of recent lines. |
| `--follow` | `boolean` | No | Follow new log lines. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru replay create
## Usage [#usage]
```bash
kitaru replay create BASELINE [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ------ | -------- | -------------------- |
| `BASELINE` | `UUID` | Yes | Baseline session ID. |
## Options [#options]
| Name | Type | Required | Description |
| ---------------------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--evaluator` | `EVALUATOR@VERSION[]` | Yes | Exact evaluator version; repeat for additional evaluators. |
| `--evaluator-params` | `EVALUATOR@VERSION=JSON_OBJECT[]` | No | Parameters for a selected evaluator token. |
| `--agent` | `AGENT@VERSION` | No | Exact agent version; omit to use the baseline's recorded version. |
| `--override` | `JSON object` | No | Replay model, prompt, or model-parameter override. |
| `--tool-policy` | `JSON object` | No | Tool policy; omitting it uses the server default and may execute live tools. |
| `--baseline-evaluation-mode` | `none\|if_missing\|force` | No | How to score the baseline session. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru replay get
## Usage [#usage]
```bash
kitaru replay get REPLAY [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ------ | -------- | ----------- |
| `REPLAY` | `UUID` | Yes | Replay ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru replay
## Usage [#usage]
```bash
kitaru replay COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------- | ------------------------------------------------------------ |
| [`create`](/cli/replay/create/) | Create one standalone replay from an exact baseline session. |
| [`get`](/cli/replay/get/) | Get one replay by exact UUID. |
| [`list`](/cli/replay/list/) | List standalone and experiment-created replays. |
# kitaru replay list
## Usage [#usage]
```bash
kitaru replay list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru session evaluate
## Usage [#usage]
```bash
kitaru session evaluate [SESSION...] [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | -------- | -------- | --------------------- |
| `SESSION` | `UUID[]` | No | Explicit session IDs. |
## Options [#options]
| Name | Type | Required | Description |
| -------------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--sessions-file` | `path` | No | UTF-8 file with one session UUID per nonblank line. |
| `--tag` | `text` | No | Evaluate sessions with this tag. |
| `--agent` | `reference` | No | Evaluate an agent's sessions. |
| `--cohort` | `reference` | No | Evaluate sessions in this cohort version. |
| `--filter` | `JSON filter` | No | Evaluate matching sessions. |
| `--all` | `boolean` | No | Evaluate all sessions. |
| `--evaluator` | `reference[]` | Yes | Exact EVALUATOR\@VERSION references. |
| `--evaluator-params` | `EVALUATOR@VERSION=JSON_OBJECT[]` | No | Parameters for a selected evaluator token. |
| `--wait` | `boolean` | No | Wait for remote work settlement. |
| `--interval` | `positive float` | No | Polling interval; requires --wait. |
| `--timeout` | `positive float` | No | Local wait timeout; requires --wait. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru session get
## Usage [#usage]
```bash
kitaru session get SESSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ------ | -------- | ----------- |
| `SESSION` | `UUID` | Yes | Session ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru session import
## Usage [#usage]
```bash
kitaru session import [FILE] [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------ | ------ | -------- | ------------------------------------------- |
| `FILE` | `path` | No | Local payload file. Omit for an API import. |
## Options [#options]
| Name | Type | Required | Description |
| ----------------------- | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| `--importer` | `reference` | Yes | Exact IMPORTER\@VERSION reference. |
| `--agent` | `reference` | Yes | Exact AGENT\@VERSION reference. |
| `--params` | `JSON object` | No | Importer parameters. |
| `--join-on` | `JSON Pointer` | No | Group source traces by the value at this RFC 6901 JSON Pointer. |
| `--since` | `timestamp or duration` | No | For an API import, fetch traces at or after this ISO 8601 timestamp or relative duration such as 7d, 12h, or 30m. |
| `--until` | `timestamp or duration` | No | For an API import, fetch traces before this ISO 8601 timestamp or relative duration such as 7d, 12h, or 30m. |
| `--trace-id` | `text[]` | No | For an API import, fetch exactly these provider trace ids. |
| `--query` | `JSON object` | No | Additional importer-defined API selection fields, merged with --since, --until, and --trace-id. |
| `--connection` | `reference` | No | For an API import, the connection UUID or name supplying provider credentials. |
| `--tag` | `text[]` | No | Tag every session created by this import; requires --wait. |
| `--evaluator` | `EVALUATOR@VERSION[]` | No | Exact evaluator version scored against every imported session. |
| `--evaluator-params` | `EVALUATOR@VERSION=JSON_OBJECT[]` | No | Parameters for a selected evaluator token. |
| `--analyzer` | `ANALYZER@VERSION[]` | No | Exact analyzer version run once over every imported session. |
| `--analyzer-params` | `ANALYZER@VERSION=JSON_OBJECT[]` | No | Parameters for a selected analyzer token. |
| `--analyzer-connection` | `ANALYZER@VERSION=CONNECTION[]` | No | Connection for a selected analyzer token. |
| `--media-type` | `string` | No | Payload media type. |
| `--max-sessions` | `integer` | No | Stop the import after creating this many sessions. |
| `--wait` | `boolean` | No | Wait for remote work settlement. |
| `--interval` | `positive float` | No | Polling interval; requires --wait. |
| `--timeout` | `positive float` | No | Local wait timeout; requires --wait. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru session
## Usage [#usage]
```bash
kitaru session COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------------ | ------------------------------------------------------------------------------ |
| [`evaluate`](/cli/session/evaluate/) | Evaluate sessions selected by ID, tag, or all sessions. |
| [`get`](/cli/session/get/) | Get a session by exact UUID. |
| [`import`](/cli/session/import/) | Upload a local payload or fetch from a provider API, and create an import job. |
| [`list`](/cli/session/list/) | List sessions. |
| [`nodes`](/cli/session/nodes/) | List a session's nodes in index order. |
# kitaru session list
## Usage [#usage]
```bash
kitaru session list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| -------------------- | -------------------------------- | -------- | ---------------------------------------------------------- |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
| `--status` | `in_progress\|completed\|failed` | No | Only sessions with this status. |
| `--agent` | `reference` | No | Only sessions for this exact agent UUID or name. |
| `--origin` | `imported\|recorded\|replay` | No | Only sessions with this origin. |
| `--imported-from` | `string` | No | Only sessions imported from this exact source system. |
| `--tag` | `text` | No | Only sessions with this tag. |
| `--cohort` | `reference` | No | Only sessions in this cohort version. |
| `--started-after` | `timestamp` | No | Only sessions started at or after this ISO 8601 timestamp. |
| `--started-before` | `timestamp` | No | Only sessions started before this ISO 8601 timestamp. |
| `--include-payloads` | `boolean` | No | Include session inputs and outputs. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru session nodes
## Usage [#usage]
```bash
kitaru session nodes SESSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ------ | -------- | ----------- |
| `SESSION` | `UUID` | Yes | Session ID. |
## Options [#options]
| Name | Type | Required | Description |
| -------------------- | --------- | -------- | --------------------------------------------- |
| `--size` | `integer` | No | Items per page. |
| `--cursor` | `string` | No | Page cursor. |
| `--filter` | `JSON` | No | Filter expression as a JSON object. |
| `--include-payloads` | `boolean` | No | Include node inputs, outputs, and attributes. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru worker get
## Usage [#usage]
```bash
kitaru worker get WORKER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ------ | -------- | ----------- |
| `WORKER` | `UUID` | Yes | Worker ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru worker
## Usage [#usage]
```bash
kitaru worker COMMAND
```
## Commands [#commands]
| Command | Description |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| [`get`](/cli/worker/get/) | Get a worker by exact UUID. |
| [`list`](/cli/worker/list/) | List live workers, or every server record with --include-stale. |
| [`start`](/cli/worker/start/) | Run a generic local worker in the foreground without durable provider binding. The first SIGINT or SIGTERM requests a safe drain of held tasks. |
# kitaru worker list
## Usage [#usage]
```bash
kitaru worker list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ----------------- | ----------------- | -------- | ----------------------------------------- |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
| `--include-stale` | `boolean` | No | Include workers past the liveness window. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru worker start
## Usage [#usage]
```bash
kitaru worker start [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Options [#options]
| Name | Type | Required | Description |
| ---------------------- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------- |
| `--name` | `string` | No | Ephemeral worker name. |
| `--claim` | `agent\|evaluator\|importer\|agent=UUID[]` | No | Claim the worker serves: agent, evaluator, importer, or agent=AGENT\_VERSION\_ID. Repeat for multiple claims. |
| `--selector` | `KEY=[VALUE[,VALUE]][]\|JSON[]` | No | Task label selectors, combined by conjunction. |
| `--job-id` | `UUID` | No | Restrict claims to one job. |
| `--concurrency` | `positive integer` | No | Maximum held tasks. |
| `--claim-batch-size` | `positive integer` | No | Maximum tasks per claim. |
| `--poll-interval` | `positive float` | No | Idle polling interval. |
| `--heartbeat-interval` | `positive float` | No | Heartbeat interval. |
| `--timeout` | `positive float` | No | Worker lifetime in seconds. |
| `--drain-timeout` | `positive float` | No | Seconds to wait for held tasks before canceling them. |
| `--blob-cache-root` | `path` | No | Blob cache directory. |
| `--payload-cache-root` | `path` | No | Payload cache directory. |
| `--metadata` | `KEY=VALUE[]` | No | Worker registration metadata. |
| `--log-level` | `string` | No | Log level for worker runtime logs: debug, info, warning, or error. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru
Kitaru.
# kitaru agent version get
## Usage [#usage]
```bash
kitaru agent version get AGENT@VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ----------- | -------- | ------------------------ |
| `AGENT@VERSION` | `reference` | Yes | Exact version reference. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent version
## Usage [#usage]
```bash
kitaru agent version COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------------------ | -------------------------------------------------------- |
| [`get`](/cli/agent/version/get/) | Get an agent version by exact PARENT\@VERSION reference. |
| [`list`](/cli/agent/version/list/) | List versions of an exact agent. |
| [`register`](/cli/agent/version/register/) | Create the next mutable version of an existing agent. |
# kitaru agent version list
## Usage [#usage]
```bash
kitaru agent version list AGENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------- | ----------- | -------- | ------------------- |
| `AGENT` | `reference` | Yes | Agent UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru agent version register
## Usage [#usage]
```bash
kitaru agent version register AGENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------- | ----------- | -------- | ------------------- |
| `AGENT` | `reference` | Yes | Agent UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `--description` | `string` | No | Version description. |
| `--spec` | `path` | No | YAML or JSON spec document. |
| `--command` | `string` | No | Shell command stored as supplied. |
| `--display-version` | `string` | No | Human-readable version. |
| `--working-dir` | `path` | No | Worker process directory. |
| `--env` | `KEY=VALUE[]` | No | Non-secret process environment. |
| `--secret-id` | `UUID[]` | No | Server secret IDs. |
| `--timeout-seconds` | `positive integer` | No | Process timeout. |
| `--tool` | `string[]` | No | Declared tools. |
| `--mcp-server` | `string[]` | No | Declared MCP servers. |
| `--skill` | `string[]` | No | Declared skills. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer version get
## Usage [#usage]
```bash
kitaru analyzer version get ANALYZER@VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------------ | ----------- | -------- | ------------------------ |
| `ANALYZER@VERSION` | `reference` | Yes | Exact version reference. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer version
## Usage [#usage]
```bash
kitaru analyzer version COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------------------- | ----------------------------------------------------------- |
| [`get`](/cli/analyzer/version/get/) | Get an analyzer version by exact PARENT\@VERSION reference. |
| [`list`](/cli/analyzer/version/list/) | List versions of an exact analyzer. |
| [`register`](/cli/analyzer/version/register/) | Create the next version of an existing analyzer. |
# kitaru analyzer version list
## Usage [#usage]
```bash
kitaru analyzer version list ANALYZER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `ANALYZER` | `reference` | Yes | Analyzer UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru analyzer version register
## Usage [#usage]
```bash
kitaru analyzer version register ANALYZER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `ANALYZER` | `reference` | Yes | Analyzer UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort version create
## Usage [#usage]
```bash
kitaru cohort version create COHORT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----------- | -------- | -------------------- |
| `COHORT` | `reference` | Yes | Cohort UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--add-session` | `UUID[]` | No | Ordered session IDs to add. |
| `--remove-session` | `UUID[]` | No | Ordered session IDs to remove. |
| `--baseline` | `UUID` | No | Exact cohort version the membership delta applies to. |
| `--display-version` | `string` | No | Human-readable version. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort version delete
## Usage [#usage]
```bash
kitaru cohort version delete VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ---------------------- | -------- | ----------------------------------------------------- |
| `VERSION` | `UUID\|COHORT@VERSION` | Yes | Cohort-version UUID or exact server-assigned version. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort version get
## Usage [#usage]
```bash
kitaru cohort version get VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ---------------------- | -------- | ----------------------------------------------------- |
| `VERSION` | `UUID\|COHORT@VERSION` | Yes | Cohort-version UUID or exact server-assigned version. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort version
## Usage [#usage]
```bash
kitaru cohort version COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------------- | --------------------------------------------------------------- |
| [`create`](/cli/cohort/version/create/) | Create the next immutable version from a membership delta. |
| [`delete`](/cli/cohort/version/delete/) | Delete one immutable cohort version without reusing its number. |
| [`get`](/cli/cohort/version/get/) | Get a version by UUID or exact COHORT\@VERSION reference. |
| [`list`](/cli/cohort/version/list/) | List immutable versions of an exact cohort. |
| [`update`](/cli/cohort/version/update/) | Update a cohort version's display version. |
# kitaru cohort version list
## Usage [#usage]
```bash
kitaru cohort version list COHORT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| -------- | ----------- | -------- | -------------------- |
| `COHORT` | `reference` | Yes | Cohort UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru cohort version update
## Usage [#usage]
```bash
kitaru cohort version update VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------- | ---------------------- | -------- | ----------------------------------------------------- |
| `VERSION` | `UUID\|COHORT@VERSION` | Yes | Cohort-version UUID or exact server-assigned version. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------------- | --------- | -------- | --------------------------------- |
| `--display-version` | `string` | No | New human-readable version. |
| `--clear-display-version` | `boolean` | No | Clear the human-readable version. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator version get
## Usage [#usage]
```bash
kitaru evaluator version get EVALUATOR@VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------------- | ----------- | -------- | ------------------------ |
| `EVALUATOR@VERSION` | `reference` | Yes | Exact version reference. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator version
## Usage [#usage]
```bash
kitaru evaluator version COMMAND
```
## Commands [#commands]
| Command | Description |
| ---------------------------------------------- | ------------------------------------------------------------ |
| [`get`](/cli/evaluator/version/get/) | Get an evaluator version by exact PARENT\@VERSION reference. |
| [`list`](/cli/evaluator/version/list/) | List versions of an exact evaluator. |
| [`register`](/cli/evaluator/version/register/) | Create the next version of an existing evaluator. |
# kitaru evaluator version list
## Usage [#usage]
```bash
kitaru evaluator version list EVALUATOR [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----------- | ----------- | -------- | ----------------------- |
| `EVALUATOR` | `reference` | Yes | Evaluator UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru evaluator version register
## Usage [#usage]
```bash
kitaru evaluator version register EVALUATOR [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----------- | ----------- | -------- | ----------------------- |
| `EVALUATOR` | `reference` | Yes | Evaluator UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run cancel
## Usage [#usage]
```bash
kitaru experiment run cancel RUN [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ------------------ |
| `RUN` | `UUID` | Yes | Experiment-run ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run delete
## Usage [#usage]
```bash
kitaru experiment run delete RUN [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ------------------ |
| `RUN` | `UUID` | Yes | Experiment-run ID. |
## Options [#options]
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------------ |
| `--force` | `boolean` | No | Confirm remote deletion. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run get
## Usage [#usage]
```bash
kitaru experiment run get RUN [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ------------------ |
| `RUN` | `UUID` | Yes | Experiment-run ID. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run
## Usage [#usage]
```bash
kitaru experiment run COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------------- | ------------------------------------------------------------------------- |
| [`cancel`](/cli/experiment/run/cancel/) | Request run cancellation once without waiting for settlement. |
| [`delete`](/cli/experiment/run/delete/) | Delete a run and immediately delete all of its replay jobs and tasks. |
| [`get`](/cli/experiment/run/get/) | Get an experiment run and its aggregate progress by exact UUID. |
| [`jobs`](/cli/experiment/run/jobs/) | List one page of replay jobs backing an experiment run. |
| [`list`](/cli/experiment/run/list/) | List experiment runs without deriving state from their jobs. |
| [`start`](/cli/experiment/run/start/) | Start an experiment run and optionally wait for terminal settlement. |
| [`watch`](/cli/experiment/run/watch/) | Poll a run until it completes, fails, or is canceled without changing it. |
# kitaru experiment run jobs
## Usage [#usage]
```bash
kitaru experiment run jobs RUN [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ------------------ |
| `RUN` | `UUID` | Yes | Experiment-run ID. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run list
## Usage [#usage]
```bash
kitaru experiment run list [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
| `--filter` | `JSON` | No | Advanced JSON filter expression. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run start
## Usage [#usage]
```bash
kitaru experiment run start EXPERIMENT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------ | ----------- | -------- | ------------------------ |
| `EXPERIMENT` | `reference` | Yes | Experiment UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------------------------- | ------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--cohort-version` | `UUID` | Yes | Exact cohort-version ID. |
| `--agent` | `AGENT@VERSION` | Yes | Exact agent version reference. |
| `--baseline-evaluation-mode` | `none\|if_missing\|force` | No | How to score each baseline session. |
| `--wait` | `boolean` | No | Wait for remote work settlement. |
| `--interval` | `positive float` | No | Polling interval; requires --wait. |
| `--timeout` | `positive float` | No | Local wait timeout; requires --wait. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru experiment run watch
## Usage [#usage]
```bash
kitaru experiment run watch RUN [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`, `jsonl`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ----- | ------ | -------- | ------------------ |
| `RUN` | `UUID` | Yes | Experiment-run ID. |
## Options [#options]
| Name | Type | Required | Description |
| ------------ | ---------------- | -------- | --------------------- |
| `--interval` | `positive float` | No | Run polling interval. |
| `--timeout` | `positive float` | No | Local wait timeout. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer version get
## Usage [#usage]
```bash
kitaru importer version get IMPORTER@VERSION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ------------------ | ----------- | -------- | ------------------------ |
| `IMPORTER@VERSION` | `reference` | Yes | Exact version reference. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer version
## Usage [#usage]
```bash
kitaru importer version COMMAND
```
## Commands [#commands]
| Command | Description |
| --------------------------------------------- | ----------------------------------------------------------- |
| [`get`](/cli/importer/version/get/) | Get an importer version by exact PARENT\@VERSION reference. |
| [`list`](/cli/importer/version/list/) | List versions of an exact importer. |
| [`register`](/cli/importer/version/register/) | Create the next version of an existing importer. |
# kitaru importer version list
## Usage [#usage]
```bash
kitaru importer version list IMPORTER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `IMPORTER` | `reference` | Yes | Importer UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | ----------------- | -------- | ------------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
| `--sort` | `field:direction` | No | Sort by created:asc or created:desc. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru importer version register
## Usage [#usage]
```bash
kitaru importer version register IMPORTER [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| ---------- | ----------- | -------- | ---------------------- |
| `IMPORTER` | `reference` | Yes | Importer UUID or name. |
## Options [#options]
| Name | Type | Required | Description |
| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `--script` | `path` | No | Python script to upload. |
| `--package` | `requirement` | No | Pinned package requirement. |
| `--entrypoint` | `string` | Yes | Script attribute or module reference. |
| `--display-version` | `string` | No | Human-readable version. |
| `--idempotency-key` | `string` | No | Retrying this exact invocation with the same key returns the original result instead of acting twice. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation session
## Usage [#usage]
```bash
kitaru investigation session COMMAND
```
## Commands [#commands]
| Command | Description |
| ------------------------------------------------ | --------------------------------------------------------------- |
| [`list`](/cli/investigation/session/list/) | List sessions linked to an investigation in presentation order. |
| [`verdict`](/cli/investigation/session/verdict/) | Set an investigation session verdict. |
# kitaru investigation session list
## Usage [#usage]
```bash
kitaru investigation session list INVESTIGATION [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ------ | -------- | ----------------- |
| `INVESTIGATION` | `UUID` | Yes | Investigation ID. |
## Options [#options]
| Name | Type | Required | Description |
| ---------- | --------- | -------- | ------------------------------ |
| `--size` | `integer` | No | Items per page (1-1000). |
| `--cursor` | `string` | No | Cursor from the previous page. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# kitaru investigation session verdict
## Usage [#usage]
```bash
kitaru investigation session verdict INVESTIGATION SESSION VERDICT [OPTIONS]
```
Supported `--output` modes: `auto`, `text`, `json`.
## Arguments [#arguments]
| Name | Type | Required | Description |
| --------------- | ------------------------------------ | -------- | --------------------------------------- |
| `INVESTIGATION` | `UUID` | Yes | Investigation ID. |
| `SESSION` | `UUID` | Yes | Session ID linked to the investigation. |
| `VERDICT` | `acceptable\|problematic\|uncertain` | Yes | Verdict for the investigation session. |
Every command also accepts the [global options](/cli/) listed on the CLI overview page.
# api_models
API wire contract models.
# task
Agent-facing accessors for code running inside a task process.
Get the id of the running task.
```python
def get_task_id() -> str | None:
"""Get the id of the running task.
Returns:
Task id, None outside task mode.
"""
return os.environ.get("KITARU_TASK_ID")
```
Task id, None outside task mode.
Get the inputs of the running agent task.
Reads KITARU\_TASK\_INPUTS when set. Otherwise fetches the task spec with a
single synchronous request, since this accessor must stay callable from
inside a running event loop.
```python
def get_task_inputs() -> Any:
"""Get the inputs of the running agent task.
Reads KITARU_TASK_INPUTS when set. Otherwise fetches the task spec with a
single synchronous request, since this accessor must stay callable from
inside a running event loop.
Raises:
RuntimeError: KITARU_API_URL is not set and the spec fetch fallback
is needed, or the task is not an agent task.
Returns:
Task inputs, None outside task mode.
"""
task_id = os.environ.get("KITARU_TASK_ID")
if task_id is None:
return None
inputs_env = os.environ.get("KITARU_TASK_INPUTS")
if inputs_env is not None:
return json.loads(inputs_env)
base_url = get_required_env("KITARU_API_URL")
headers = {}
token = os.environ.get("KITARU_API_TOKEN")
if token:
headers["Authorization"] = f"Bearer {token}"
response = httpx.get(f"{base_url}/api/v1/tasks/{task_id}/spec", headers=headers)
response.raise_for_status()
spec = TaskSpecResponse.model_validate(response.json())
if not isinstance(spec.details, AgentTaskDetails):
raise RuntimeError(f"Task {task_id} is not an agent task")
return spec.details.inputs
```
Task inputs, None outside task mode.
# APIError
API error.
## Attributes [#attributes]
## Functions [#functions]
Initialize the error.
```python
def __init__(self, status_code: int, detail: str) -> None:
"""Initialize the error.
Args:
status_code: HTTP status code.
detail: Error detail.
"""
super().__init__(f"{status_code}: {detail}")
self.status_code = status_code
self.detail = detail
```
HTTP status code.
Error detail.
# ApiToken
Cached bearer token.
## Attributes [#attributes]
Report whether the token is expired or about to be.
## Functions [#functions]
Build a cached token from a login response.
```python
@classmethod
def from_response(cls, response: TokenResponse) -> Self:
"""Build a cached token from a login response.
Args:
response: Token response returned by the server.
Returns:
Token with its absolute expiry and leeway resolved.
"""
return cls.issued(response.access_token, response.expires_in)
```
Token response returned by the server.
Token with its absolute expiry and leeway resolved.
Build a cached token from a bearer token and its lifetime.
```python
@classmethod
def issued(cls, access_token: str, expires_in: int) -> Self:
"""Build a cached token from a bearer token and its lifetime.
Args:
access_token: Bearer token.
expires_in: Token lifetime in seconds.
Returns:
Token with its absolute expiry and leeway resolved.
"""
return cls(
access_token=access_token,
expires_at=datetime.now(UTC) + timedelta(seconds=expires_in),
leeway_seconds=_leeway_seconds(expires_in),
)
```
Bearer token.
Token lifetime in seconds.
Token with its absolute expiry and leeway resolved.
# ApiType
API type.
## Attributes [#attributes]
# AuthenticationError
Authentication error.
# AuthorizationError
Authorization error.
# ClientConfig
Client configuration.
## Attributes [#attributes]
# ControlPlaneLoginError
Raised when a control plane login cannot be started.
# ControlPlaneSession
Control plane tokens for one control plane, refreshed as they expire.
## Functions [#functions]
Initialize the session.
```python
def __init__(
self,
api_url: str,
store: CredentialStore,
timeout: float = 30.0,
retries: int = 3,
pool_size: int = 20,
) -> None:
"""Initialize the session.
Args:
api_url: Control plane API base URL.
store: Credential store holding the token and the API key that
renews it.
timeout: Request timeout in seconds.
retries: Retry count for failed requests.
pool_size: Connection pool size.
"""
self._url = normalize_server_url(api_url)
self._store = store
self._http = build_async_client(
self._url,
{"Accept": "application/json"},
timeout=timeout,
retries=retries,
pool_size=pool_size,
)
```
Control plane API base URL.
Credential store holding the token and the API key that
renews it.
Request timeout in seconds.
Retry count for failed requests.
Connection pool size.
Return a usable control plane token, renewing an expiring one first.
```python
async def get_token(self) -> str | None:
"""Return a usable control plane token, renewing an expiring one first.
Returns:
Bearer token, or None when nothing stored can produce one.
"""
token = self._store.get_token(self._url)
if token is not None:
return token.access_token
credentials = self._store.get_control_plane(self._url)
if credentials is None or credentials.api_key is None:
return None
return (await self.login_with_api_key(credentials.api_key)).access_token
```
Bearer token, or None when nothing stored can produce one.
Exchange a control plane API key for a control plane token.
```python
async def login_with_api_key(self, api_key: str) -> ApiToken:
"""Exchange a control plane API key for a control plane token.
Args:
api_key: Control plane API key.
Raises:
APIError: The request failed, including 401 for an invalid key.
Returns:
Token issued by the control plane.
"""
response = await self._post(
LOGIN_PATH,
data={"grant_type": API_KEY_GRANT_TYPE, "password": api_key},
headers={"Authorization": f"Bearer {api_key}"},
)
credentials = self._store.get_control_plane(self._url)
# Stored only once the control plane has accepted it, so a rejected key
# never displaces a working one.
if credentials is None or credentials.api_key != api_key:
self._store.set_api_key(self._url, api_key, type=ApiType.CONTROL_PLANE)
return self._store_token(response)
```
Token issued by the control plane.
Authorize this machine and return its cached control plane token.
```python
async def device_login(
self,
open_browser: bool = True,
prompt: Callable[[ControlPlaneDeviceAuthorization], None] | None = None,
workspace_id: str | None = None,
) -> ApiToken:
"""Authorize this machine and return its cached control plane token."""
result = await self.device_login_with_metadata(
open_browser=open_browser,
prompt=prompt,
workspace_id=workspace_id,
)
return ApiToken.issued(result.access_token, result.expires_in)
```
Authorize this machine against the control plane.
The call blocks until a signed-in account completes authorization in a
browser, or until the authorization expires.
```python
async def device_login_with_metadata(
self,
open_browser: bool = True,
prompt: Callable[[ControlPlaneDeviceAuthorization], None] | None = None,
workspace_id: str | None = None,
) -> ControlPlaneToken:
"""Authorize this machine against the control plane.
The call blocks until a signed-in account completes authorization in a
browser, or until the authorization expires.
Args:
open_browser: Whether to open the verification page.
prompt: Called with the authorization so the caller can show the
verification URL. Defaults to logging it.
workspace_id: Workspace ID preselected on the verification page.
Raises:
DeviceLoginError: The authorization expired or was refused.
Returns:
Control plane token and workspace selection issued for the device.
"""
client_id = get_client_id()
device = describe_this_device()
response = await self._post(
DEVICE_AUTHORIZATION_PATH,
data={"client_id": str(client_id)},
headers={"User-Agent": f"Host/{device.hostname} OS/{device.os}"},
)
authorization = ControlPlaneDeviceAuthorization.model_validate(response.json())
uri = authorization.verification_uri_complete or authorization.verification_uri
verification_uri = self._url + uri if uri.startswith("/") else uri
parsed = urlparse(verification_uri)
query_params = dict(parse_qsl(parsed.query))
query_params["product"] = PRODUCT
if workspace_id is not None:
query_params["workspace"] = workspace_id
verification_uri = urlunparse(parsed._replace(query=urlencode(query_params)))
# Written back so the prompt shows the same URL the browser opens.
authorization.verification_uri_complete = verification_uri
if prompt is not None:
prompt(authorization)
else:
logger.info(
"Open %s to continue.",
verification_uri,
)
if open_browser:
webbrowser.open(verification_uri)
async def exchange() -> httpx.Response:
return await self._post(
LOGIN_PATH,
data={
"grant_type": DEVICE_CODE_GRANT_TYPE,
"client_id": str(client_id),
"device_code": authorization.device_code,
},
)
confirmed = await poll_for_token(
exchange, authorization.expires_in, authorization.interval
)
issued = ControlPlaneToken.model_validate(confirmed.json())
self._store_issued_token(issued)
return issued
```
Whether to open the verification page.
Called with the authorization so the caller can show the
verification URL. Defaults to logging it.
Workspace ID preselected on the verification page.
Control plane token and workspace selection issued for the device.
Get the managed workspace selected during device authorization.
```python
async def get_workspace(
self, workspace_id: uuid.UUID, access_token: str
) -> ControlPlaneWorkspace:
"""Get the managed workspace selected during device authorization.
Args:
workspace_id: Selected workspace ID.
access_token: Control plane bearer token.
Returns:
Managed workspace connection details.
"""
response = await self._http.get(
WORKSPACE_PATH.format(workspace_id=workspace_id),
headers={"Authorization": f"Bearer {access_token}"},
)
raise_for_response(response)
return ControlPlaneWorkspace.model_validate(response.json())
```
Selected workspace ID.
Control plane bearer token.
Managed workspace connection details.
Close the underlying HTTP client.
```python
async def close(self) -> None:
"""Close the underlying HTTP client."""
await self._http.aclose()
```
# CredentialStore
Server credentials persisted as JSON in the user's config directory.
## Attributes [#attributes]
Return the location of the credentials file.
## Functions [#functions]
Initialize the store and load any credentials already on disk.
```python
def __init__(self, path: Path | None = None, persist: bool | None = None) -> None:
"""Initialize the store and load any credentials already on disk.
Args:
path: Location of the credentials file.
persist: Whether to read and write the file. Defaults to reading
``KITARU_DISABLE_CREDENTIALS_CACHE``.
"""
self._path = path or get_config_directory() / CREDENTIALS_FILE_NAME
if persist is None:
persist = os.environ.get(ENV_DISABLE_CREDENTIALS_CACHE, "").lower() not in (
"1",
"true",
"yes",
)
self._persist = persist
self._credentials: dict[str, ServerCredentials] = {}
self._loaded_at: float | None = None
self._load()
```
Location of the credentials file.
Whether to read and write the file. Defaults to reading
`KITARU_DISABLE_CREDENTIALS_CACHE`.
Return the credentials stored for a server.
```python
def get(self, url: str) -> ServerCredentials | None:
"""Return the credentials stored for a server.
Args:
url: Server base URL.
Returns:
Stored credentials, or None when the server is unknown.
"""
self._reload_if_stale()
return self._credentials.get(normalize_server_url(url))
```
Stored credentials, or None when the server is unknown.
Return the credentials of every known server.
```python
def list(self) -> list[ServerCredentials]:
"""Return the credentials of every known server.
Returns:
Stored credentials, ordered by server URL.
"""
self._reload_if_stale()
return [self._credentials[key] for key in sorted(self._credentials)]
```
Stored credentials, ordered by server URL.
Return the cached token of a server.
```python
def get_token(self, url: str, allow_expired: bool = False) -> ApiToken | None:
"""Return the cached token of a server.
Args:
url: Server base URL.
allow_expired: Whether to return a token inside its leeway window.
Returns:
Cached token, or None when there is none to return.
"""
credentials = self.get(url)
if credentials is None or credentials.api_token is None:
return None
if credentials.api_token.expired and not allow_expired:
return None
return credentials.api_token
```
Server base URL.
Whether to return a token inside its leeway window.
Cached token, or None when there is none to return.
Cache a token for a server.
The control plane is recorded with the token it issued rather than on
its own, because an entry that holds neither a token nor a credential
is dropped when the store is written.
```python
def set_token(
self,
url: str,
token: ApiToken,
type: ApiType | None = None,
control_plane_api_url: str | None = None,
) -> None:
"""Cache a token for a server.
The control plane is recorded with the token it issued rather than on
its own, because an entry that holds neither a token nor a credential
is dropped when the store is written.
Args:
url: Server base URL.
token: Token to cache.
type: API type, left as stored when omitted.
control_plane_api_url: Control plane that issued the credential
behind this token, left as stored when omitted.
"""
values: dict[str, object] = {"api_token": token}
if type is not None:
values["type"] = type
if control_plane_api_url is not None:
values["control_plane_api_url"] = normalize_server_url(
control_plane_api_url
)
self._mutate(url, values)
```
Server base URL.
Token to cache.
API type, left as stored when omitted.
Control plane that issued the credential
behind this token, left as stored when omitted.
Store an API key for a server and drop the token it replaces.
```python
def set_api_key(
self,
url: str,
api_key: str,
type: ApiType = ApiType.SERVER,
) -> None:
"""Store an API key for a server and drop the token it replaces.
Args:
url: Server base URL.
api_key: API key to store.
type: API type.
"""
self._mutate(url, {"api_key": api_key, "type": type, "api_token": None})
```
Server base URL.
API key to store.
API type.
Store a device authorization for a server.
```python
def set_device(self, url: str, device_id: uuid.UUID, device_code: str) -> None:
"""Store a device authorization for a server.
Args:
url: Server base URL.
device_id: Id of the authorized device.
device_code: Device code the client polls with.
"""
self._mutate(url, {"device_id": device_id, "device_code": device_code})
```
Server base URL.
Id of the authorized device.
Device code the client polls with.
Return the credentials stored for a control plane.
```python
def get_control_plane(self, control_plane_api_url: str) -> ServerCredentials | None:
"""Return the credentials stored for a control plane.
Args:
control_plane_api_url: Control plane API base URL.
Returns:
Stored credentials, or None when the entry is missing or is not a
control plane entry.
"""
credentials = self.get(control_plane_api_url)
if credentials is None or credentials.type is not ApiType.CONTROL_PLANE:
return None
return credentials
```
Control plane API base URL.
Stored credentials, or None when the entry is missing or is not a
Drop the cached token of a server, keeping the way to get a new one.
```python
def clear_token(self, url: str) -> None:
"""Drop the cached token of a server, keeping the way to get a new one.
Args:
url: Server base URL.
"""
if self.get(url) is None:
return
self._mutate(url, {"api_token": None})
```
Drop every credential stored for a server.
```python
def clear(self, url: str) -> None:
"""Drop every credential stored for a server.
Args:
url: Server base URL.
"""
self._reload_if_stale()
if self._credentials.pop(normalize_server_url(url), None) is not None:
self._save()
```
Drop every stored credential and remove the credentials file.
```python
def clear_all(self) -> None:
"""Drop every stored credential and remove the credentials file."""
self._credentials = {}
if not self._persist:
return
self._path.unlink(missing_ok=True)
self._loaded_at = None
```
# CredentialStoreTokenSource
Token source backed by the credentials stored for one server.
## Functions [#functions]
Initialize the source.
```python
def __init__(
self,
base_url: str,
store: CredentialStore,
exchange: TokenExchange,
) -> None:
"""Initialize the source.
Args:
base_url: Server base URL credentials are stored under.
store: Credential store holding the token and the way to renew it.
exchange: Login endpoint calls used to renew the token.
"""
self._url = normalize_server_url(base_url)
self._store = store
self._exchange = exchange
self._control_plane: ControlPlaneSession | None = None
```
Server base URL credentials are stored under.
Credential store holding the token and the way to renew it.
Login endpoint calls used to renew the token.
Return the stored bearer token.
```python
def get_cached_token(self) -> str | None:
"""Return the stored bearer token.
Returns:
Bearer token, or None when nothing usable is stored.
"""
credentials = self._store.get(self._url)
if credentials is not None and credentials.server_api_key is not None:
# A server API key is used directly as a bearer credential and we
# don't need to exchange it for a server token.
return credentials.server_api_key
token = self._store.get_token(self._url)
if token is not None:
return token.access_token
return None
```
Bearer token, or None when nothing usable is stored.
Fetch a fresh bearer token and write it back to the store.
```python
async def fetch_token(self) -> str | None:
"""Fetch a fresh bearer token and write it back to the store.
Returns:
Bearer token, or None when nothing stored can produce one.
"""
credentials = self._store.get(self._url)
if credentials is None:
return None
token = await self._fetch(credentials)
if token is None:
return None
self._store.set_token(self._url, token)
return token.access_token
```
Bearer token, or None when nothing stored can produce one.
Close the control plane session the source opened.
```python
async def close(self) -> None:
"""Close the control plane session the source opened."""
if self._control_plane is not None:
await self._control_plane.close()
self._control_plane = None
```
# DeviceLoginError
Raised when a device authorization cannot be completed.
# KitaruAPIClient
Kitaru API client.
## Attributes [#attributes]
Return the server base URL this client resolved.
## Functions [#functions]
Initialize the client.
```python
def __init__(
self,
base_url: str | None = None,
api_key: str | None = None,
credential_store: CredentialStore | None = None,
timeout: float = 30.0,
retries: int = 3,
pool_size: int = 20,
analytics_source: AnalyticsSource = AnalyticsSource.PYTHON,
) -> None:
"""Initialize the client.
Args:
base_url: Server base URL, read from KITARU_API_URL and then the
stored server URL when omitted.
api_key: API key authenticating this client. A server key is sent
as a bearer token, a control plane key is exchanged for a
session token held in memory. Read from KITARU_API_TOKEN and
then KITARU_API_KEY when omitted.
credential_store: Store holding the credentials this client
authenticates with, renewing its token as it expires. Defaults
to the on-disk store when no API key is given.
timeout: Request timeout in seconds.
retries: Retry count for failed requests.
pool_size: Connection pool size.
analytics_source: Client sending the requests.
Raises:
RuntimeError: No server URL is configured.
ValueError: Both an API key and a credential store were supplied.
"""
if api_key is not None and credential_store is not None:
raise ValueError("api_key and credential_store are mutually exclusive")
if base_url is None:
base_url = os.environ.get("KITARU_API_URL") or get_server_url()
if not base_url:
raise RuntimeError("No server URL is configured")
self._base_url = base_url
self._owns_transport = True
self._owns_auth = True
self._request_headers: dict[str, str] = {}
identification = format_client_header(analytics_source)
client_identification = format_client_header(
analytics_source, get_analytics_id()
)
headers = {"User-Agent": identification, CLIENT_HEADER: client_identification}
if skill := os.environ.get("KITARU_ACTIVE_SKILL"):
headers[SKILL_HEADER] = skill
self._http = build_async_client(
base_url, headers, timeout=timeout, retries=retries, pool_size=pool_size
)
self._auth: TokenAuth | None = None
if api_key is None and credential_store is None:
if api_token := os.environ.get("KITARU_API_TOKEN"):
self._auth = StaticTokenAuth(api_token)
elif api_key := os.environ.get("KITARU_API_KEY"):
# Used later
pass
else:
# Nothing configured, fall back to the on-disk credential store.
credential_store = CredentialStore()
if api_key:
if api_key.startswith(CONTROL_PLANE_API_KEY_PREFIX):
# Control plane API keys are exchanged for a session token, so
# we need an in-memory credential store to hold it.
credential_store = CredentialStore(persist=False)
credential_store.set_api_key(base_url, api_key)
else:
self._auth = StaticTokenAuth(api_key)
self._bind_resources()
if credential_store is not None:
self._auth = RenewingTokenAuth(
CredentialStoreTokenSource(base_url, credential_store, self.auth)
)
```
Server base URL, read from KITARU\_API\_URL and then the
stored server URL when omitted.
API key authenticating this client. A server key is sent
as a bearer token, a control plane key is exchanged for a
session token held in memory. Read from KITARU\_API\_TOKEN and
then KITARU\_API\_KEY when omitted.
Store holding the credentials this client
authenticates with, renewing its token as it expires. Defaults
to the on-disk store when no API key is given.
Request timeout in seconds.
Retry count for failed requests.
Connection pool size.
Client sending the requests.
Return a view of this client authenticating with a fixed bearer token.
```python
def with_token(self, token: str) -> "KitaruAPIClient":
"""Return a view of this client authenticating with a fixed bearer token.
Args:
token: Bearer token attached to every request sent through the
view.
Returns:
Client view authenticating with the given token.
"""
return self.with_auth(StaticTokenAuth(token))
```
Bearer token attached to every request sent through the
view.
Client view authenticating with the given token.
Return a view of this client authenticating with the given auth flow.
The view shares this client's HTTP transport instead of opening a new
connection pool. Closing the view closes only its auth flow, and
closing this client also invalidates the view.
```python
def with_auth(self, auth: TokenAuth) -> "KitaruAPIClient":
"""Return a view of this client authenticating with the given auth flow.
The view shares this client's HTTP transport instead of opening a new
connection pool. Closing the view closes only its auth flow, and
closing this client also invalidates the view.
Args:
auth: Auth flow attached to every request sent through the view.
Returns:
Client view authenticating with the given auth flow.
"""
view = copy.copy(self)
view._auth = auth
view._owns_transport = False
view._owns_auth = True
view._bind_resources()
return view
```
Auth flow attached to every request sent through the view.
Client view authenticating with the given auth flow.
Return a view of this client with request options applied.
The view shares this client's HTTP transport and auth flow, and
closing it leaves both open.
```python
def with_options(
self, consistency: Literal["strong"] | None = None
) -> "KitaruAPIClient":
"""Return a view of this client with request options applied.
The view shares this client's HTTP transport and auth flow, and
closing it leaves both open.
Args:
consistency: ``strong`` sends ``Prefer: consistency=strong`` on
every request, so endpoints that serve reads from a replica
serve the view from the primary database.
Returns:
Client view with the options applied.
"""
view = copy.copy(self)
if consistency == "strong":
view._request_headers = {
**self._request_headers,
"Prefer": "consistency=strong",
}
view._owns_transport = False
view._owns_auth = False
view._bind_resources()
return view
```
`strong` sends `Prefer: consistency=strong` on
every request, so endpoints that serve reads from a replica
serve the view from the primary database.
Client view with the options applied.
Send a request and raise a typed error on failure.
```python
async def request(
self,
method: str,
path: str,
params: dict[str, Any] | None = None,
json: Any = None,
data: dict[str, str] | None = None,
files: dict[str, tuple[str | None, bytes, str]] | None = None,
content: bytes | AsyncIterable[bytes] | None = None,
headers: dict[str, str] | None = None,
idempotency_key: str | None = None,
authenticate: bool = True,
) -> httpx.Response:
"""Send a request and raise a typed error on failure.
Args:
method: HTTP method.
path: Request path relative to the base URL.
params: Query parameters.
json: JSON request body.
data: Form request body.
files: Multipart file fields, filename/content/content-type per
field.
content: Raw or streaming request body.
headers: Additional request headers.
idempotency_key: Idempotency key overriding the transport's
random default.
authenticate: Whether to send the request through this client's
auth flow. The login endpoints send their own credential.
Raises:
APIError: The response has an error status code.
InvalidServerResponseError: The response is not an API response.
Returns:
HTTP response.
"""
if params is not None:
# httpx renders None query values as empty strings, which the
# server rejects for typed filters.
params = {key: value for key, value in params.items() if value is not None}
if idempotency_key is not None:
headers = {**(headers or {}), IDEMPOTENCY_KEY_HEADER: idempotency_key}
if self._request_headers:
headers = {**self._request_headers, **(headers or {})}
response = await self._http.request(
method,
path,
params=params,
json=json,
data=data,
files=files,
content=content,
headers=headers,
auth=self._auth if authenticate else None,
)
raise_for_response(response)
# A UI catch-all or proxy answers an unknown path with an HTML page
# and a success status, usually on a client/server version mismatch.
if response.headers.get("Content-Type", "").startswith("text/html"):
raise InvalidServerResponseError(
f"The server answered {method} {path} with an HTML page "
"instead of an API response"
)
return response
```
HTTP method.
Request path relative to the base URL.
Query parameters.
JSON request body.
Form request body.
Multipart file fields, filename/content/content-type per
field.
Raw or streaming request body.
Additional request headers.
Idempotency key overriding the transport's
random default.
Whether to send the request through this client's
auth flow. The login endpoints send their own credential.
HTTP response.
Close the auth flow and HTTP transport this client owns.
```python
async def close(self) -> None:
"""Close the auth flow and HTTP transport this client owns."""
if self._auth is not None and self._owns_auth:
await self._auth.close()
if self._owns_transport:
await self._http.aclose()
```
# KitaruClient
Kitaru client.
## Attributes [#attributes]
API client with one method per endpoint.
## Functions [#functions]
Initialize the client.
```python
def __init__(self, api_client: KitaruAPIClient | None = None) -> None:
"""Initialize the client.
Args:
api_client: API client used to send requests.
"""
self._api_client = api_client or KitaruAPIClient()
```
API client used to send requests.
Close the underlying API client.
```python
async def close(self) -> None:
"""Close the underlying API client."""
await self._api_client.close()
```
Get an agent by id or name.
```python
async def get_agent(self, agent: uuid.UUID | str) -> AgentResponse:
"""Get an agent by id or name.
Args:
agent: Id or name of the agent.
Raises:
APIError: The request failed, including 404 for a missing agent.
Returns:
Stored agent.
"""
if isinstance(agent, uuid.UUID):
return await self._api_client.agents.get(agent)
return await self._get_by_name(
"agent", agent, AgentListParams, self._api_client.agents.list
)
```
Stored agent.
Iterate over all agents.
```python
def list_agents(self) -> AsyncIterator[AgentResponse]:
"""Iterate over all agents.
Returns:
Async iterator over every agent.
"""
return self._api_client.agents.iter()
```
Async iterator over every agent.
Get a session by id.
```python
async def get_session(self, session_id: uuid.UUID) -> SessionDetailResponse:
"""Get a session by id.
Args:
session_id: Id of the session.
Raises:
APIError: The request failed, including 404 for a missing session.
Returns:
Stored session.
"""
return await self._api_client.sessions.get(session_id)
```
Stored session.
Iterate over sessions, optionally scoped to one agent.
```python
async def list_sessions(
self, agent: uuid.UUID | str | None = None
) -> AsyncIterator[SessionResponse]:
"""Iterate over sessions, optionally scoped to one agent.
Args:
agent: Id or name of the agent to scope to.
Raises:
APIError: The request failed.
Returns:
Async iterator over every matching session.
"""
params = SessionListParams()
if agent is not None:
agent_id = (await self.get_agent(agent)).id
params = SessionListParams(
filter=FilterCondition(
field="agent_id", op=FilterOp.EQ, value=str(agent_id)
)
)
async for session in self._api_client.sessions.iter(params):
yield session
```
Id or name of the agent to scope to.
Async iterator over every matching session.
Iterate over the nodes of a session in index order.
```python
def list_session_nodes(
self, session_id: uuid.UUID
) -> AsyncIterator[SessionNodeResponse]:
"""Iterate over the nodes of a session in index order.
Args:
session_id: Id of the session.
Returns:
Async iterator over every node.
"""
return self._api_client.sessions.iter_nodes(session_id)
```
Async iterator over every node.
Replay a session and optionally wait for it to finish.
```python
async def replay(
self,
session_id: uuid.UUID,
evaluators: list[EvaluatorConfig],
agent_version_id: uuid.UUID | None = None,
override: ReplayOverride | None = None,
tool_policy: ToolPolicy | None = None,
baseline_evaluation_mode: BaselineEvaluationMode = (
BaselineEvaluationMode.IF_MISSING
),
wait: bool = True,
timeout: float | None = None,
) -> ReplayResponse:
"""Replay a session and optionally wait for it to finish.
Args:
session_id: Id of the session to replay.
evaluators: Evaluators run against the result session.
agent_version_id: Agent version to replay with, the session's
recorded version when unset.
override: Override to apply.
tool_policy: Tool policy to apply.
baseline_evaluation_mode: How to score the baseline session.
wait: Whether to wait for the replay to reach a terminal status.
timeout: Seconds to wait before giving up.
Raises:
APIError: The request failed, including 404 for a missing session
or agent version.
TimeoutError: The replay did not finish within the timeout.
Returns:
Replay, in a terminal status when waited for.
"""
request = ReplayCreateRequest(
baseline_session_id=session_id,
agent_version_id=agent_version_id,
override=override,
tool_policy=tool_policy,
evaluators=evaluators,
baseline_evaluation_mode=baseline_evaluation_mode,
)
replay = await self._api_client.replays.create(request)
if wait:
replay = await self.wait_for_replay(replay.id, timeout=timeout)
return replay
```
Id of the session to replay.
Evaluators run against the result session.
Agent version to replay with, the session's
recorded version when unset.
Override to apply.
Tool policy to apply.
How to score the baseline session.
Whether to wait for the replay to reach a terminal status.
Seconds to wait before giving up.
Replay, in a terminal status when waited for.
Get a replay by id.
```python
async def get_replay(self, replay_id: uuid.UUID) -> ReplayResponse:
"""Get a replay by id.
Args:
replay_id: Id of the replay.
Raises:
APIError: The request failed, including 404 for a missing replay.
Returns:
Stored replay.
"""
return await self._api_client.replays.get(replay_id)
```
Stored replay.
Wait for a replay to reach a terminal status.
```python
async def wait_for_replay(
self,
replay_id: uuid.UUID,
timeout: float | None = None,
poll_interval: float = 2.0,
) -> ReplayResponse:
"""Wait for a replay to reach a terminal status.
Args:
replay_id: Id of the replay.
timeout: Seconds to wait before giving up.
poll_interval: Seconds between status checks.
Raises:
APIError: The request failed.
TimeoutError: The replay did not finish within the timeout.
Returns:
Replay in a terminal status.
"""
return await self._wait_for_status(
lambda: self._api_client.replays.get(replay_id),
lambda replay: replay.status in TERMINAL_REPLAY_STATUSES,
timeout=timeout,
poll_interval=poll_interval,
)
```
Id of the replay.
Seconds to wait before giving up.
Seconds between status checks.
Replay in a terminal status.
Get an experiment by id or name.
```python
async def get_experiment(self, experiment: uuid.UUID | str) -> ExperimentResponse:
"""Get an experiment by id or name.
Args:
experiment: Id or name of the experiment.
Raises:
APIError: The request failed, including 404 for a missing
experiment.
Returns:
Stored experiment.
"""
if isinstance(experiment, uuid.UUID):
return await self._api_client.experiments.get(experiment)
return await self._get_by_name(
"experiment",
experiment,
ExperimentListParams,
self._api_client.experiments.list,
)
```
Id or name of the experiment.
Stored experiment.
Iterate over all experiments.
```python
def list_experiments(self) -> AsyncIterator[ExperimentResponse]:
"""Iterate over all experiments.
Returns:
Async iterator over every experiment.
"""
return self._api_client.experiments.iter()
```
Async iterator over every experiment.
Start an experiment run and optionally wait for it to finish.
```python
async def run_experiment(
self,
experiment: uuid.UUID | str,
cohort_version_id: uuid.UUID,
agent_version_id: uuid.UUID,
baseline_evaluation_mode: BaselineEvaluationMode = (
BaselineEvaluationMode.IF_MISSING
),
wait: bool = True,
timeout: float | None = None,
) -> ExperimentRunResponse:
"""Start an experiment run and optionally wait for it to finish.
Args:
experiment: Id or name of the experiment.
cohort_version_id: Cohort version whose sessions are replayed.
agent_version_id: Agent version to replay with.
baseline_evaluation_mode: How to score each baseline session.
wait: Whether to wait for the run to reach a terminal status.
timeout: Seconds to wait before giving up.
Raises:
APIError: The request failed, including 404 for a missing
experiment, cohort version, or agent version.
TimeoutError: The run did not finish within the timeout.
Returns:
Experiment run, in a terminal status when waited for.
"""
experiment_id = (await self.get_experiment(experiment)).id
request = ExperimentRunCreateRequest(
cohort_version_id=cohort_version_id,
agent_version_id=agent_version_id,
baseline_evaluation_mode=baseline_evaluation_mode,
)
run = await self._api_client.experiments.start_run(experiment_id, request)
if wait:
run = await self.wait_for_experiment_run(run.id, timeout=timeout)
return run
```
Id or name of the experiment.
Cohort version whose sessions are replayed.
Agent version to replay with.
How to score each baseline session.
Whether to wait for the run to reach a terminal status.
Seconds to wait before giving up.
Experiment run, in a terminal status when waited for.
Get an experiment run by id.
```python
async def get_experiment_run(self, run_id: uuid.UUID) -> ExperimentRunResponse:
"""Get an experiment run by id.
Args:
run_id: Id of the experiment run.
Raises:
APIError: The request failed, including 404 for a missing run.
Returns:
Stored experiment run.
"""
return await self._api_client.experiment_runs.get(run_id)
```
Id of the experiment run.
Stored experiment run.
Wait for an experiment run to reach a terminal status.
```python
async def wait_for_experiment_run(
self,
run_id: uuid.UUID,
timeout: float | None = None,
poll_interval: float = 2.0,
) -> ExperimentRunResponse:
"""Wait for an experiment run to reach a terminal status.
Args:
run_id: Id of the experiment run.
timeout: Seconds to wait before giving up.
poll_interval: Seconds between status checks.
Raises:
APIError: The request failed.
TimeoutError: The run did not finish within the timeout.
Returns:
Experiment run in a terminal status.
"""
return await self._wait_for_status(
lambda: self._api_client.experiment_runs.get(run_id),
lambda run: run.status in TERMINAL_EXPERIMENT_RUN_STATUSES,
timeout=timeout,
poll_interval=poll_interval,
)
```
Id of the experiment run.
Seconds to wait before giving up.
Seconds between status checks.
Experiment run in a terminal status.
# KitaruClientError
Kitaru client error.
# KitaruSyncClient
Synchronous Kitaru client.
## Attributes [#attributes]
API client with one method per endpoint.
## Functions [#functions]
Initialize the client.
```python
def __init__(self, api_client: KitaruAPIClient | None = None) -> None:
"""Initialize the client.
Args:
api_client: API client used to send requests.
"""
self._loop = asyncio.new_event_loop()
self._thread = threading.Thread(target=self._loop.run_forever, daemon=True)
self._thread.start()
self._client = KitaruClient(api_client=api_client)
```
API client used to send requests.
Close the underlying client and stop the event loop thread.
```python
def close(self) -> None:
"""Close the underlying client and stop the event loop thread."""
self._run(self._client.close())
self._loop.call_soon_threadsafe(self._loop.stop)
self._thread.join()
self._loop.close()
```
Get an agent by id or name.
```python
def get_agent(self, agent: uuid.UUID | str) -> AgentResponse:
"""Get an agent by id or name.
Args:
agent: Id or name of the agent.
Raises:
APIError: The request failed, including 404 for a missing agent.
Returns:
Stored agent.
"""
return self._run(self._client.get_agent(agent))
```
Stored agent.
Iterate over all agents.
```python
def list_agents(self) -> Iterator[AgentResponse]:
"""Iterate over all agents.
Returns:
Iterator over every agent.
"""
return self._iterate(self._client.list_agents())
```
Iterator over every agent.
Get a session by id.
```python
def get_session(self, session_id: uuid.UUID) -> SessionDetailResponse:
"""Get a session by id.
Args:
session_id: Id of the session.
Raises:
APIError: The request failed, including 404 for a missing session.
Returns:
Stored session.
"""
return self._run(self._client.get_session(session_id))
```
Stored session.
Iterate over sessions, optionally scoped to one agent.
```python
def list_sessions(
self, agent: uuid.UUID | str | None = None
) -> Iterator[SessionResponse]:
"""Iterate over sessions, optionally scoped to one agent.
Args:
agent: Id or name of the agent to scope to.
Raises:
APIError: The request failed.
Returns:
Iterator over every matching session.
"""
return self._iterate(self._client.list_sessions(agent))
```
Id or name of the agent to scope to.
Iterator over every matching session.
Iterate over the nodes of a session in index order.
```python
def list_session_nodes(
self, session_id: uuid.UUID
) -> Iterator[SessionNodeResponse]:
"""Iterate over the nodes of a session in index order.
Args:
session_id: Id of the session.
Returns:
Iterator over every node.
"""
return self._iterate(self._client.list_session_nodes(session_id))
```
Iterator over every node.
Replay a session and optionally wait for it to finish.
```python
def replay(
self,
session_id: uuid.UUID,
evaluators: list[EvaluatorConfig],
agent_version_id: uuid.UUID | None = None,
override: ReplayOverride | None = None,
tool_policy: ToolPolicy | None = None,
baseline_evaluation_mode: BaselineEvaluationMode = (
BaselineEvaluationMode.IF_MISSING
),
wait: bool = True,
timeout: float | None = None,
) -> ReplayResponse:
"""Replay a session and optionally wait for it to finish.
Args:
session_id: Id of the session to replay.
evaluators: Evaluators run against the result session.
agent_version_id: Agent version to replay with, the session's
recorded version when unset.
override: Override to apply.
tool_policy: Tool policy to apply.
baseline_evaluation_mode: How to score the baseline session.
wait: Whether to wait for the replay to reach a terminal status.
timeout: Seconds to wait before giving up.
Raises:
APIError: The request failed, including 404 for a missing session
or agent version.
TimeoutError: The replay did not finish within the timeout.
Returns:
Replay, in a terminal status when waited for.
"""
return self._run(
self._client.replay(
session_id,
evaluators,
agent_version_id=agent_version_id,
override=override,
tool_policy=tool_policy,
baseline_evaluation_mode=baseline_evaluation_mode,
wait=wait,
timeout=timeout,
)
)
```
Id of the session to replay.
Evaluators run against the result session.
Agent version to replay with, the session's
recorded version when unset.
Override to apply.
Tool policy to apply.
How to score the baseline session.
Whether to wait for the replay to reach a terminal status.
Seconds to wait before giving up.
Replay, in a terminal status when waited for.
Get a replay by id.
```python
def get_replay(self, replay_id: uuid.UUID) -> ReplayResponse:
"""Get a replay by id.
Args:
replay_id: Id of the replay.
Raises:
APIError: The request failed, including 404 for a missing replay.
Returns:
Stored replay.
"""
return self._run(self._client.get_replay(replay_id))
```
Stored replay.
Wait for a replay to reach a terminal status.
```python
def wait_for_replay(
self,
replay_id: uuid.UUID,
timeout: float | None = None,
poll_interval: float = 2.0,
) -> ReplayResponse:
"""Wait for a replay to reach a terminal status.
Args:
replay_id: Id of the replay.
timeout: Seconds to wait before giving up.
poll_interval: Seconds between status checks.
Raises:
APIError: The request failed.
TimeoutError: The replay did not finish within the timeout.
Returns:
Replay in a terminal status.
"""
return self._run(
self._client.wait_for_replay(
replay_id, timeout=timeout, poll_interval=poll_interval
)
)
```
Id of the replay.
Seconds to wait before giving up.
Seconds between status checks.
Replay in a terminal status.
Get an experiment by id or name.
```python
def get_experiment(self, experiment: uuid.UUID | str) -> ExperimentResponse:
"""Get an experiment by id or name.
Args:
experiment: Id or name of the experiment.
Raises:
APIError: The request failed, including 404 for a missing
experiment.
Returns:
Stored experiment.
"""
return self._run(self._client.get_experiment(experiment))
```
Id or name of the experiment.
Stored experiment.
Iterate over all experiments.
```python
def list_experiments(self) -> Iterator[ExperimentResponse]:
"""Iterate over all experiments.
Returns:
Iterator over every experiment.
"""
return self._iterate(self._client.list_experiments())
```
Iterator over every experiment.
Start an experiment run and optionally wait for it to finish.
```python
def run_experiment(
self,
experiment: uuid.UUID | str,
cohort_version_id: uuid.UUID,
agent_version_id: uuid.UUID,
baseline_evaluation_mode: BaselineEvaluationMode = (
BaselineEvaluationMode.IF_MISSING
),
wait: bool = True,
timeout: float | None = None,
) -> ExperimentRunResponse:
"""Start an experiment run and optionally wait for it to finish.
Args:
experiment: Id or name of the experiment.
cohort_version_id: Cohort version whose sessions are replayed.
agent_version_id: Agent version to replay with.
baseline_evaluation_mode: How to score each baseline session.
wait: Whether to wait for the run to reach a terminal status.
timeout: Seconds to wait before giving up.
Raises:
APIError: The request failed, including 404 for a missing
experiment, cohort version, or agent version.
TimeoutError: The run did not finish within the timeout.
Returns:
Experiment run, in a terminal status when waited for.
"""
return self._run(
self._client.run_experiment(
experiment,
cohort_version_id,
agent_version_id,
baseline_evaluation_mode=baseline_evaluation_mode,
wait=wait,
timeout=timeout,
)
)
```
Id or name of the experiment.
Cohort version whose sessions are replayed.
Agent version to replay with.
How to score each baseline session.
Whether to wait for the run to reach a terminal status.
Seconds to wait before giving up.
Experiment run, in a terminal status when waited for.
Get an experiment run by id.
```python
def get_experiment_run(self, run_id: uuid.UUID) -> ExperimentRunResponse:
"""Get an experiment run by id.
Args:
run_id: Id of the experiment run.
Raises:
APIError: The request failed, including 404 for a missing run.
Returns:
Stored experiment run.
"""
return self._run(self._client.get_experiment_run(run_id))
```
Id of the experiment run.
Stored experiment run.
Wait for an experiment run to reach a terminal status.
```python
def wait_for_experiment_run(
self,
run_id: uuid.UUID,
timeout: float | None = None,
poll_interval: float = 2.0,
) -> ExperimentRunResponse:
"""Wait for an experiment run to reach a terminal status.
Args:
run_id: Id of the experiment run.
timeout: Seconds to wait before giving up.
poll_interval: Seconds between status checks.
Raises:
APIError: The request failed.
TimeoutError: The run did not finish within the timeout.
Returns:
Experiment run in a terminal status.
"""
return self._run(
self._client.wait_for_experiment_run(
run_id, timeout=timeout, poll_interval=poll_interval
)
)
```
Id of the experiment run.
Seconds to wait before giving up.
Seconds between status checks.
Experiment run in a terminal status.
# NotFoundError
Not found error.
# RenewingTokenAuth
Bearer token auth flow renewing its token through a source on HTTP 401.
## Functions [#functions]
Initialize the auth flow.
```python
def __init__(self, source: TokenSource) -> None:
"""Initialize the auth flow.
Args:
source: Source producing and renewing the bearer token.
"""
self._source = source
self._lock = asyncio.Lock()
self._generation = 0
```
Source producing and renewing the bearer token.
Attach a bearer token and retry once with a renewed one on HTTP 401.
A request rejected with HTTP 401 is retried once with a renewed token,
unless another caller renewed it first, in which case the retry uses
theirs.
```python
async def async_auth_flow(
self, request: httpx.Request
) -> AsyncGenerator[httpx.Request, httpx.Response]:
"""Attach a bearer token and retry once with a renewed one on HTTP 401.
A request rejected with HTTP 401 is retried once with a renewed token,
unless another caller renewed it first, in which case the retry uses
theirs.
Args:
request: Outgoing HTTP request.
Yields:
The request with a bearer token attached, and once more after a
renewal following an HTTP 401 response.
"""
generation = self._generation
token = await self._get_token()
if token is not None:
request.headers["Authorization"] = f"Bearer {token}"
response = yield request
if response.status_code != httpx.codes.UNAUTHORIZED:
return
token = await self._renew(generation)
if token is None:
return
request.headers["Authorization"] = f"Bearer {token}"
yield request
```
Close the token source.
```python
async def close(self) -> None:
"""Close the token source."""
await self._source.close()
```
# ServerCredentials
Credentials stored for one server.
## Attributes [#attributes]
Return the stored API key when it is a control plane key.
Return the stored API key when it is a server key.
Report whether a new token can be obtained without a fresh login.
# ServerError
Server error.
# StaticTokenAuth
Fixed bearer token that never renews.
## Functions [#functions]
Initialize the auth flow.
```python
def __init__(self, token: str) -> None:
"""Initialize the auth flow.
Args:
token: Bearer token attached to every request.
"""
self._header = f"Bearer {token}"
```
Bearer token attached to every request.
Attach the fixed bearer token to the request.
```python
async def async_auth_flow(
self, request: httpx.Request
) -> AsyncGenerator[httpx.Request, httpx.Response]:
"""Attach the fixed bearer token to the request.
Args:
request: Outgoing HTTP request.
Yields:
The request with the bearer token attached.
"""
request.headers["Authorization"] = self._header
yield request
```
# TokenAuth
Bearer token auth flow.
## Functions [#functions]
Close any resources this auth flow opened.
```python
async def close(self) -> None:
"""Close any resources this auth flow opened."""
```
# TokenGrantError
Token grant error.
## Attributes [#attributes]
## Functions [#functions]
Initialize the error.
```python
def __init__(self, status_code: int, detail: str, error: str) -> None:
"""Initialize the error.
Args:
status_code: HTTP status code.
detail: Error detail.
error: OAuth 2.0 error code.
"""
super().__init__(status_code, detail)
self.error = error
```
HTTP status code.
Error detail.
OAuth 2.0 error code.
# TokenSource
Source of bearer tokens for a renewing auth flow.
## Functions [#functions]
Return the cached bearer token.
```python
def get_cached_token(self) -> str | None:
"""Return the cached bearer token.
Returns:
Bearer token, or None when nothing usable is cached.
"""
...
```
Bearer token, or None when nothing usable is cached.
Fetch a fresh bearer token.
```python
async def fetch_token(self) -> str | None:
"""Fetch a fresh bearer token.
Returns:
Bearer token, or None when the source cannot produce one.
"""
...
```
Bearer token, or None when the source cannot produce one.
Close any resources this source opened.
```python
async def close(self) -> None:
"""Close any resources this source opened."""
...
```
# ValidationError
Validation error.
# client
Public SDK surface.
Log in to a server that delegates identity to a control plane.
Without an API key, a stored control plane credential that still produces
an accepted token is reused. Otherwise the call blocks until a signed-in
account confirms the user code in a browser, or until the authorization
expires.
```python
async def control_plane_login(
api_client: KitaruAPIClient,
base_url: str,
store: CredentialStore,
api_key: str | None = None,
open_browser: bool = True,
prompt: Callable[[ControlPlaneDeviceAuthorization], None] | None = None,
refresh: bool = False,
) -> tuple[ApiToken, ControlPlaneLoginMethod]:
"""Log in to a server that delegates identity to a control plane.
Without an API key, a stored control plane credential that still produces
an accepted token is reused. Otherwise the call blocks until a signed-in
account confirms the user code in a browser, or until the authorization
expires.
Args:
api_client: API client pointed at the server.
base_url: Server base URL credentials are stored under.
store: Credential store the credentials are written to.
api_key: Control plane API key. Reuses a stored credential or runs
the device authorization flow when omitted.
open_browser: Whether to open the verification page.
prompt: Called with the authorization so the caller can show the user
code.
refresh: Whether to skip stored credentials and force a new device
authorization flow.
Raises:
ControlPlaneLoginError: The server does not delegate to a control
plane.
DeviceLoginError: The authorization expired or was refused.
Returns:
Session token issued by the server and the method that produced it.
"""
info = await api_client.info.get()
if not info.control_plane_api_url:
raise ControlPlaneLoginError(
f"Server {base_url} does not authenticate against a control plane"
)
control_plane_api_url = info.control_plane_api_url
session = ControlPlaneSession(control_plane_api_url, store)
try:
if api_key is not None:
credential = (await session.login_with_api_key(api_key)).access_token
token = await exchange_control_plane_credential(
api_client, base_url, store, control_plane_api_url, credential
)
return token, "api_key"
if not refresh:
# A stored credential the control plane or the server no longer
# accepts falls through to the device flow.
try:
credential = await session.get_token()
except AuthenticationError:
credential = None
if credential is not None:
try:
token = await exchange_control_plane_credential(
api_client, base_url, store, control_plane_api_url, credential
)
return token, "stored"
except AuthenticationError:
pass
credential = (
await session.device_login(
open_browser=open_browser,
prompt=prompt,
workspace_id=str(info.id) if info.id else None,
)
).access_token
token = await exchange_control_plane_credential(
api_client, base_url, store, control_plane_api_url, credential
)
return token, "device"
finally:
await session.close()
```
API client pointed at the server.
Server base URL credentials are stored under.
Credential store the credentials are written to.
Control plane API key. Reuses a stored credential or runs
the device authorization flow when omitted.
Whether to open the verification page.
Called with the authorization so the caller can show the user
code.
Whether to skip stored credentials and force a new device
authorization flow.
Session token issued by the server and the method that produced it.
Authorize this machine against a server and store the token it gets.
The call blocks until a signed-in account completes authorization in a
browser, or until the authorization expires.
```python
async def device_login(
api_client: KitaruAPIClient,
base_url: str,
store: CredentialStore,
open_browser: bool = True,
prompt: Callable[[DeviceAuthorizationResponse], None] | None = None,
) -> ApiToken:
"""Authorize this machine against a server and store the token it gets.
The call blocks until a signed-in account completes authorization in a
browser, or until the authorization expires.
Args:
api_client: API client pointed at the server.
base_url: Server base URL credentials are stored under.
store: Credential store the device authorization is written to.
open_browser: Whether to open the verification page.
prompt: Called with the authorization so the caller can show the
verification URL. Defaults to logging it.
Raises:
DeviceLoginError: The authorization expired or was refused.
Returns:
Token issued for the authorized device.
"""
fingerprint = describe_this_device()
authorization = await api_client.auth.device_authorization(
hostname=fingerprint.hostname,
os=fingerprint.os,
python_version=fingerprint.python_version,
client_version=fingerprint.client_version,
)
if prompt is not None:
prompt(authorization)
else:
logger.info(
"Open %s to continue.",
authorization.verification_uri_complete,
)
if open_browser:
webbrowser.open(authorization.verification_uri_complete)
response = await _poll_for_token(api_client, authorization)
token = ApiToken.from_response(response)
store.set_device(base_url, authorization.device_id, authorization.device_code)
store.set_token(base_url, token)
return token
```
API client pointed at the server.
Server base URL credentials are stored under.
Credential store the device authorization is written to.
Whether to open the verification page.
Called with the authorization so the caller can show the
verification URL. Defaults to logging it.
Token issued for the authorized device.
Return the stored server URL.
```python
def get_server_url() -> str | None:
"""Return the stored server URL.
Returns:
Server URL, or None when none is stored.
"""
return load_config().server_url
```
Server URL, or None when none is stored.
Read the configuration file, ignoring one that cannot be parsed.
```python
def load_config() -> ClientConfig:
"""Read the configuration file, ignoring one that cannot be parsed.
Returns:
Stored configuration, or an empty one when the file is missing or
malformed.
"""
path = get_config_path()
try:
raw = path.read_text(encoding="utf-8")
except OSError:
return ClientConfig()
try:
return ClientConfig.model_validate_json(raw)
except ValidationError:
logger.warning("Ignoring malformed configuration file %s.", path)
return ClientConfig()
```
Stored configuration, or an empty one when the file is missing or
Write the configuration file, replacing it in one step.
```python
def save_config(config: ClientConfig) -> None:
"""Write the configuration file, replacing it in one step.
Args:
config: Configuration to write.
"""
write_json_file(
get_config_path(),
config.model_dump(mode="json", exclude_none=True),
)
```
Store the server URL.
```python
def set_server_url(url: str | None) -> None:
"""Store the server URL.
Args:
url: Server base URL, None clears the stored URL.
"""
config = load_config()
config.server_url = normalize_server_url(url) if url else None
save_config(config)
```
Server base URL, None clears the stored URL.
# v1
Version 1 API models.
# AnalysisError
Raised when loading or invoking an analyzer plugin fails.
# InsightInput
Insight input.
## Attributes [#attributes]
# analyzer
Analyzer plugin contract and the analysis flow.
Invoke an analyzer and validate its results.
```python
async def call_analyzer(
name: str,
analyzer: Callable[..., AnalyzerReturn | Awaitable[AnalyzerReturn]],
session_ids: list[uuid.UUID],
params: dict[str, Any],
) -> list[InsightInput]:
"""Invoke an analyzer and validate its results.
Args:
name: Analyzer name, named in error messages.
analyzer: Analyzer callable, sync or returning an awaitable.
session_ids: Imported session IDs passed to the analyzer. Analyzers
fetch any session details they need through the API client.
params: Parameters passed to the analyzer.
Raises:
AnalysisError: The analyzer raised, returned a
non-InsightInput value, or returned duplicate result names.
Returns:
Insight inputs.
"""
try:
result = analyzer(session_ids, **params)
if inspect.isawaitable(result):
result = await result
except Exception as exc:
raise AnalysisError(f"Analyzer '{name}' raised an error: {exc}") from exc
results = result if isinstance(result, list) else [result]
if not all(isinstance(item, InsightInput) for item in results):
raise AnalysisError(f"Analyzer '{name}' returned a non-InsightInput value")
names = [item.name for item in results]
if len(set(names)) != len(names):
raise AnalysisError(f"Analyzer '{name}' returned duplicate result names")
return results
```
Analyzer name, named in error messages.
Analyzer callable, sync or returning an awaitable.
Imported session IDs passed to the analyzer. Analyzers
fetch any session details they need through the API client.
Parameters passed to the analyzer.
Insight inputs.
# EvaluationError
Raised when loading or invoking an evaluator plugin fails.
# EvaluationResult
Evaluation result.
## Attributes [#attributes]
Data type derived from which of score and value are set.
## Functions [#functions]
Route a single positional score or value by type.
```python
def __init__(self, value: float | bool | str | None = None, **data: Any) -> None:
"""Route a single positional score or value by type.
Args:
value: Positional score, bool or float routes to score and str
routes to value.
data: Remaining fields, passed as keywords.
"""
if isinstance(value, str):
data.setdefault("value", value)
elif value is not None:
data.setdefault("score", value)
super().__init__(**data)
```
Positional score, bool or float routes to score and str
routes to value.
Remaining fields, passed as keywords.
# SessionView
Session view.
## Attributes [#attributes]
# evaluator
Evaluator plugin contract and the evaluation flow.
Invoke an evaluator and validate its results.
```python
async def call_evaluator(
name: str,
evaluator: Callable[..., EvaluatorReturn | Awaitable[EvaluatorReturn]],
session: SessionView,
params: dict[str, Any],
) -> list[EvaluationResult]:
"""Invoke an evaluator and validate its results.
Args:
name: Evaluator name, named in error messages.
evaluator: Evaluator callable, sync or returning an awaitable.
session: Session view passed to the evaluator.
params: Parameters passed to the evaluator.
Raises:
EvaluationError: The evaluator raised, returned no results, returned
a non-EvaluationResult value, or returned duplicate result names.
Returns:
Evaluation results.
"""
try:
result = evaluator(session, **params)
if inspect.isawaitable(result):
result = await result
except Exception as exc:
raise EvaluationError(f"Evaluator '{name}' raised an error: {exc}") from exc
results = result if isinstance(result, list) else [result]
if not results:
raise EvaluationError(f"Evaluator '{name}' returned no results")
if not all(isinstance(item, EvaluationResult) for item in results):
raise EvaluationError(
f"Evaluator '{name}' returned a non-EvaluationResult value"
)
names = [item.name for item in results]
if len(set(names)) != len(names):
raise EvaluationError(f"Evaluator '{name}' returned duplicate result names")
return results
```
Evaluator name, named in error messages.
Evaluator callable, sync or returning an awaitable.
Session view passed to the evaluator.
Parameters passed to the evaluator.
Evaluation results.
# FetchingImporter
Importer object that also fetches payloads from a provider API.
## Functions [#functions]
Fetch payloads matching a query, sync or async.
```python
def fetch(self, query: dict[str, Any]) -> Iterator[bytes] | AsyncIterator[bytes]:
"""Fetch payloads matching a query, sync or async."""
...
```
# ImportFailure
Import failure.
## Attributes [#attributes]
# ImportStats
Import stats.
## Attributes [#attributes]
# ImportedNode
Provider data normalized for node ingestion.
## Attributes [#attributes]
# ImportedSession
Provider data normalized for session ingestion.
## Attributes [#attributes]
# Importer
Importer object.
## Functions [#functions]
Parse one payload into imported items, sync or async.
```python
def parse(
self, payload: bytes, params: dict[str, Any]
) -> Iterator[ImportedItem] | AsyncIterator[ImportedItem]:
"""Parse one payload into imported items, sync or async."""
...
```
# SessionImportError
Raised when a parser fails while starting or advancing.
# importer
Importer plugin contract and the import flow.
Advance a fetcher one payload at a time, wrapping any failure.
Wrapping only the fetcher call would protect nothing, since a generator
function runs no code until iterated. This wraps every step of the
iteration instead.
```python
async def call_fetcher(fetcher: Fetcher, query: dict[str, Any]) -> AsyncIterator[bytes]:
"""Advance a fetcher one payload at a time, wrapping any failure.
Wrapping only the fetcher call would protect nothing, since a generator
function runs no code until iterated. This wraps every step of the
iteration instead.
Args:
fetcher: Fetcher callable, sync or async.
query: Importer-defined selection of what to fetch.
Raises:
SessionImportError: The fetcher raised while starting or advancing,
or yielded an item that is not bytes.
Yields:
Fetched payloads.
"""
try:
result = fetcher(query)
iterator = result if isinstance(result, AsyncIterator) else iter(result)
except Exception as exc:
raise SessionImportError(
f"Fetcher raised an error: {type(exc).__name__}: {exc}"
) from exc
while True:
try:
payload = await _advance(iterator)
except StopAsyncIteration:
return
except Exception as exc:
raise SessionImportError(
f"Fetcher raised an error: {type(exc).__name__}: {exc}"
) from exc
if not isinstance(payload, bytes):
raise SessionImportError(
f"Fetcher yielded an item that is not bytes: {payload!r}"
)
yield payload
```
Fetcher callable, sync or async.
Importer-defined selection of what to fetch.
Advance a parser one item at a time, wrapping any failure.
Wrapping only the parser call would protect nothing, since a generator
function runs no code until iterated. This wraps every step of the
iteration instead.
```python
async def call_parser(
parser: Parser, payload: bytes, params: dict[str, Any]
) -> AsyncIterator[ImportedItem]:
"""Advance a parser one item at a time, wrapping any failure.
Wrapping only the parser call would protect nothing, since a generator
function runs no code until iterated. This wraps every step of the
iteration instead.
Args:
parser: Parser callable, sync or async.
payload: Raw payload bytes.
params: Parameters passed to the parser.
Raises:
SessionImportError: The parser raised while starting or advancing, or
yielded an item that is not an ImportedSession or ImportFailure.
Yields:
Imported items.
"""
try:
result = parser(payload, params)
iterator = result if isinstance(result, AsyncIterator) else iter(result)
except Exception as exc:
raise SessionImportError(
f"Parser raised an error: {type(exc).__name__}: {exc}"
) from exc
while True:
try:
item = await _advance(iterator)
except StopAsyncIteration:
return
except Exception as exc:
raise SessionImportError(
f"Parser raised an error: {type(exc).__name__}: {exc}"
) from exc
if not isinstance(item, ImportedSession | ImportFailure):
raise SessionImportError(
f"Parser yielded an item that is not an ImportedSession or "
f"ImportFailure: {item!r}"
)
yield item
```
Parser callable, sync or async.
Raw payload bytes.
Parameters passed to the parser.
Flatten an imported node tree into indexed ingest requests, depth-first.
```python
def flatten_nodes(nodes: list[ImportedNode]) -> list[SessionNodeCreateRequest]:
"""Flatten an imported node tree into indexed ingest requests, depth-first.
Args:
nodes: Top-level imported nodes.
Returns:
Flat session node create requests in depth-first order.
"""
explicit_indexes = [node.index is not None for node in nodes]
if any(explicit_indexes):
if not all(explicit_indexes) or any(node.children for node in nodes):
raise SessionImportError(
"Indexed imported nodes must all have indexes and cannot have children"
)
indexed_nodes = sorted(
nodes, key=lambda node: node.index if node.index is not None else -1
)
direct = [
_node_request(
node,
index=node.index,
parent_index=node.parent_index,
)
for node in indexed_nodes
if node.index is not None
]
return SessionNodeBatchRequest(nodes=direct).nodes
flattened: list[SessionNodeCreateRequest] = []
active: set[int] = set()
stack: list[tuple[ImportedNode, int | None, bool]] = [
(node, None, False) for node in reversed(nodes)
]
while stack:
node, parent_index, exiting = stack.pop()
if exiting:
active.remove(id(node))
continue
if id(node) in active:
raise SessionImportError("Imported node tree contains a cycle")
active.add(id(node))
index = len(flattened)
flattened.append(_node_request(node, index=index, parent_index=parent_index))
stack.append((node, parent_index, True))
stack.extend((child, index, False) for child in reversed(node.children))
return flattened
```
Top-level imported nodes.
Flat session node create requests in depth-first order.
Await every awaitable with at most concurrency in flight, in input order.
```python
async def gather_bounded(
awaitables: Iterable[Awaitable[T]], concurrency: int
) -> list[T]:
"""Await every awaitable with at most concurrency in flight, in input order.
Args:
awaitables: Awaitables to run.
concurrency: Maximum number in flight at once.
Returns:
Results in input order.
"""
semaphore = asyncio.Semaphore(concurrency)
async def _run(awaitable: Awaitable[T]) -> T:
async with semaphore:
return await awaitable
return list(await asyncio.gather(*(_run(item) for item in awaitables)))
```
Awaitables to run.
Maximum number in flight at once.
Results in input order.
Create a session for one parsed import item and ingest its nodes.
```python
async def ingest_session(
client: KitaruAPIClient,
parsed: ImportedSession,
agent_id: uuid.UUID | None,
provider: str | None,
origin: SessionOrigin = SessionOrigin.IMPORTED,
) -> SessionResponse | None:
"""Create a session for one parsed import item and ingest its nodes.
Args:
client: API client.
parsed: Imported session.
agent_id: Agent the session is created under, None resolves it from
the task.
provider: Source system named on the import.
origin: Session origin.
Raises:
APIError: Session creation or node ingestion failed.
SessionImportError: The imported node tree is invalid.
Returns:
Created session, None when a session with the external id already
exists.
"""
request = session_request(parsed, agent_id, provider, origin)
try:
session = await client.sessions.create(request)
except APIError as exc:
if exc.status_code == httpx.codes.CONFLICT:
return None
raise
nodes = flatten_nodes(parsed.nodes)
for start in range(0, len(nodes), NODE_BATCH_SIZE):
batch = nodes[start : start + NODE_BATCH_SIZE]
await client.sessions.ingest_nodes(
session.id, SessionNodeBatchRequest(nodes=batch)
)
return session
```
API client.
Imported session.
Agent the session is created under, None resolves it from
the task.
Source system named on the import.
Session origin.
Created session, None when a session with the external id already
Await a call, sleeping and retrying while it reports a rate limit.
```python
async def retry_rate_limited(
call: Callable[[], Awaitable[T]],
get_retry_after: Callable[[Exception], float | None],
max_retries: int = MAX_RATE_LIMIT_RETRIES,
) -> T:
"""Await a call, sleeping and retrying while it reports a rate limit.
Args:
call: Factory of the awaitable to run.
get_retry_after: Seconds to wait when the exception is a rate limit,
None when it is not.
max_retries: Retries before the rate limit error propagates.
Returns:
Result of the call.
"""
retries = 0
while True:
try:
return await call()
except Exception as exc:
retry_after = get_retry_after(exc)
if retry_after is None or retries >= max_retries:
raise
retries += 1
await asyncio.sleep(retry_after)
```
Factory of the awaitable to run.
Seconds to wait when the exception is a rate limit,
None when it is not.
Retries before the rate limit error propagates.
Result of the call.
Build a session create request for one parsed import item.
```python
def session_request(
parsed: ImportedSession,
agent_id: uuid.UUID | None,
provider: str | None,
origin: SessionOrigin = SessionOrigin.IMPORTED,
) -> SessionCreateRequest:
"""Build a session create request for one parsed import item.
Args:
parsed: Imported session.
agent_id: Agent the session is created under, None resolves it from
the task.
provider: Source system named on the import.
origin: Session origin.
Returns:
Session create request.
"""
return SessionCreateRequest(
agent_id=agent_id,
origin=origin,
status=parsed.status,
name=parsed.name,
input_text_selector=parsed.input_text_selector,
output_text_selector=parsed.output_text_selector,
inputs=parsed.inputs,
outputs=parsed.outputs,
error=parsed.error,
started_at=parsed.started_at,
ended_at=parsed.ended_at,
external_id=parsed.external_id,
metadata=parsed.metadata,
imported_from=provider,
framework=parsed.framework,
)
```
Imported session.
Agent the session is created under, None resolves it from
the task.
Source system named on the import.
Session origin.
Session create request.
# AgentVersionsResource
Agent version API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Get an agent version by id.
```python
async def get(self, agent_version_id: uuid.UUID) -> AgentVersionResponse:
"""Get an agent version by id.
Args:
agent_version_id: Id of the agent version.
Raises:
APIError: The request failed, including 404 for a missing agent
version.
Returns:
Stored agent version.
"""
response = await self._client.request(
"GET", f"/api/v1/agent-versions/{agent_version_id}"
)
return AgentVersionResponse.model_validate(response.json())
```
Stored agent version.
Update an agent version.
```python
async def update(
self, agent_version_id: uuid.UUID, request: AgentVersionUpdateRequest
) -> AgentVersionResponse:
"""Update an agent version.
Args:
agent_version_id: Id of the agent version.
request: Agent version update request, unset fields stay
unchanged.
Raises:
APIError: The request failed, including 404 for a missing agent
version.
Returns:
Updated agent version.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/agent-versions/{agent_version_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return AgentVersionResponse.model_validate(response.json())
```
Id of the agent version.
Agent version update request, unset fields stay
unchanged.
Updated agent version.
Delete an agent version.
```python
async def delete(self, agent_version_id: uuid.UUID) -> None:
"""Delete an agent version.
Args:
agent_version_id: Id of the agent version.
Raises:
APIError: The request failed, including 404 for a missing agent
version and 409 when an experiment run references it.
"""
await self._client.request(
"DELETE", f"/api/v1/agent-versions/{agent_version_id}"
)
```
# AgentsResource
Agent API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create an agent.
```python
async def create(
self, request: AgentCreateRequest, idempotency_key: str | None = None
) -> AgentResponse:
"""Create an agent.
Args:
request: Agent create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 409 for a duplicate name.
Returns:
Created agent.
"""
response = await self._client.request(
"POST",
"/api/v1/agents",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return AgentResponse.model_validate(response.json())
```
Agent create request.
Idempotency key overriding the transport's
random default.
Created agent.
Get an agent by id.
```python
async def get(self, agent_id: uuid.UUID) -> AgentResponse:
"""Get an agent by id.
Args:
agent_id: Id of the agent.
Raises:
APIError: The request failed, including 404 for a missing agent.
Returns:
Stored agent.
"""
response = await self._client.request("GET", f"/api/v1/agents/{agent_id}")
return AgentResponse.model_validate(response.json())
```
Stored agent.
List agents.
```python
async def list(
self,
params: AgentListParams | None = None,
) -> Page[AgentResponse]:
"""List agents.
Args:
params: Agent list params.
Raises:
APIError: The request failed.
Returns:
Page of agents.
"""
params = params or AgentListParams()
response = await self._client.request(
"GET",
"/api/v1/agents",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[AgentResponse].model_validate(response.json())
```
Page of agents.
Iterate over all agents.
```python
async def iter(
self,
params: AgentListParams | None = None,
) -> AsyncIterator[AgentResponse]:
"""Iterate over all agents.
Args:
params: Agent list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every agent.
"""
async for item in iterate_pages(params or AgentListParams(), self.list):
yield item
```
Async iterator over every agent.
Update an agent.
```python
async def update(
self, agent_id: uuid.UUID, request: AgentUpdateRequest
) -> AgentResponse:
"""Update an agent.
Args:
agent_id: Id of the agent.
request: Agent update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing agent.
Returns:
Updated agent.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/agents/{agent_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return AgentResponse.model_validate(response.json())
```
Id of the agent.
Agent update request, unset fields stay unchanged.
Updated agent.
Delete an agent, hiding the agent and retaining its subtree.
The agent's stored sessions, versions, cohorts, experiments, and
investigations are retained and stay readable through their own
resources. Creating new ones for the agent fails.
```python
async def delete(self, agent_id: uuid.UUID) -> None:
"""Delete an agent, hiding the agent and retaining its subtree.
The agent's stored sessions, versions, cohorts, experiments, and
investigations are retained and stay readable through their own
resources. Creating new ones for the agent fails.
Args:
agent_id: Id of the agent.
Raises:
APIError: The request failed, including 404 for a missing agent.
"""
await self._client.request("DELETE", f"/api/v1/agents/{agent_id}")
```
Create a new version of an agent.
```python
async def create_version(
self,
agent_id: uuid.UUID,
request: AgentVersionCreateRequest,
idempotency_key: str | None = None,
) -> AgentVersionResponse:
"""Create a new version of an agent.
Args:
agent_id: Id of the agent.
request: Agent version create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing agent.
Returns:
Created agent version.
"""
response = await self._client.request(
"POST",
f"/api/v1/agents/{agent_id}/versions",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return AgentVersionResponse.model_validate(response.json())
```
Id of the agent.
Agent version create request.
Idempotency key overriding the transport's
random default.
Created agent version.
List the versions of an agent.
```python
async def list_versions(
self, agent_id: uuid.UUID, params: AgentVersionListParams | None = None
) -> Page[AgentVersionResponse]:
"""List the versions of an agent.
Args:
agent_id: Id of the agent.
params: Agent version list params.
Raises:
APIError: The request failed.
Returns:
Page of agent versions.
"""
params = params or AgentVersionListParams()
response = await self._client.request(
"GET",
f"/api/v1/agents/{agent_id}/versions",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[AgentVersionResponse].model_validate(response.json())
```
Id of the agent.
Agent version list params.
Page of agent versions.
Iterate over every version of an agent.
```python
async def iter_versions(
self, agent_id: uuid.UUID, params: AgentVersionListParams | None = None
) -> AsyncIterator[AgentVersionResponse]:
"""Iterate over every version of an agent.
Args:
agent_id: Id of the agent.
params: Agent version list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every version of the agent.
"""
async for item in iterate_pages(
params or AgentVersionListParams(),
lambda page_params: self.list_versions(agent_id, page_params),
):
yield item
```
Id of the agent.
Agent version list params.
Async iterator over every version of the agent.
# AnalyzersResource
Analyzer API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create an analyzer.
```python
async def create(
self, request: AnalyzerCreateRequest, idempotency_key: str | None = None
) -> AnalyzerResponse:
"""Create an analyzer.
Args:
request: Analyzer create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 409 for a duplicate name.
Returns:
Created analyzer.
"""
response = await self._client.request(
"POST",
"/api/v1/analyzers",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return AnalyzerResponse.model_validate(response.json())
```
Analyzer create request.
Idempotency key overriding the transport's
random default.
Created analyzer.
Get an analyzer by id.
```python
async def get(self, analyzer_id: uuid.UUID) -> AnalyzerResponse:
"""Get an analyzer by id.
Args:
analyzer_id: Id of the analyzer.
Raises:
APIError: The request failed, including 404 for a missing
analyzer.
Returns:
Stored analyzer.
"""
response = await self._client.request("GET", f"/api/v1/analyzers/{analyzer_id}")
return AnalyzerResponse.model_validate(response.json())
```
Stored analyzer.
List analyzers.
```python
async def list(
self, params: AnalyzerListParams | None = None
) -> Page[AnalyzerResponse]:
"""List analyzers.
Args:
params: Analyzer list params.
Raises:
APIError: The request failed.
Returns:
Page of analyzers.
"""
params = params or AnalyzerListParams()
response = await self._client.request(
"GET",
"/api/v1/analyzers",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[AnalyzerResponse].model_validate(response.json())
```
Page of analyzers.
Iterate over all analyzers.
```python
async def iter(
self, params: AnalyzerListParams | None = None
) -> AsyncIterator[AnalyzerResponse]:
"""Iterate over all analyzers.
Args:
params: Analyzer list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every analyzer.
"""
async for item in iterate_pages(params or AnalyzerListParams(), self.list):
yield item
```
Async iterator over every analyzer.
Update an analyzer.
```python
async def update(
self, analyzer_id: uuid.UUID, request: AnalyzerUpdateRequest
) -> AnalyzerResponse:
"""Update an analyzer.
Args:
analyzer_id: Id of the analyzer.
request: Analyzer update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
analyzer.
Returns:
Updated analyzer.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/analyzers/{analyzer_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return AnalyzerResponse.model_validate(response.json())
```
Id of the analyzer.
Analyzer update request, unset fields stay unchanged.
Updated analyzer.
Delete an analyzer, cascading its versions.
```python
async def delete(self, analyzer_id: uuid.UUID) -> None:
"""Delete an analyzer, cascading its versions.
Args:
analyzer_id: Id of the analyzer.
Raises:
APIError: The request failed, including 404 for a missing
analyzer.
"""
await self._client.request("DELETE", f"/api/v1/analyzers/{analyzer_id}")
```
Create an analyzer version.
```python
async def create_version(
self,
analyzer_id: uuid.UUID,
request: AnalyzerVersionCreateRequest,
idempotency_key: str | None = None,
) -> AnalyzerVersionResponse:
"""Create an analyzer version.
Args:
analyzer_id: Id of the analyzer.
request: Analyzer version create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing
analyzer or blob.
Returns:
Created analyzer version.
"""
response = await self._client.request(
"POST",
f"/api/v1/analyzers/{analyzer_id}/versions",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return AnalyzerVersionResponse.model_validate(response.json())
```
Id of the analyzer.
Analyzer version create request.
Idempotency key overriding the transport's
random default.
Created analyzer version.
List an analyzer's versions.
```python
async def list_versions(
self, analyzer_id: uuid.UUID, params: ListParams | None = None
) -> Page[AnalyzerVersionResponse]:
"""List an analyzer's versions.
Args:
analyzer_id: Id of the analyzer.
params: List params.
Raises:
APIError: The request failed.
Returns:
Page of analyzer versions.
"""
params = params or ListParams()
response = await self._client.request(
"GET",
f"/api/v1/analyzers/{analyzer_id}/versions",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[AnalyzerVersionResponse].model_validate(response.json())
```
Id of the analyzer.
List params.
Page of analyzer versions.
Iterate over all of an analyzer's versions.
```python
async def iter_versions(
self, analyzer_id: uuid.UUID, params: ListParams | None = None
) -> AsyncIterator[AnalyzerVersionResponse]:
"""Iterate over all of an analyzer's versions.
Args:
analyzer_id: Id of the analyzer.
params: List params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every analyzer version.
"""
async for item in iterate_pages(
params or ListParams(),
lambda page_params: self.list_versions(analyzer_id, page_params),
):
yield item
```
Id of the analyzer.
List params.
Async iterator over every analyzer version.
Get an analyzer version by version number.
```python
async def get_version(
self, analyzer_id: uuid.UUID, version: int
) -> AnalyzerVersionResponse:
"""Get an analyzer version by version number.
Args:
analyzer_id: Id of the analyzer.
version: Version number.
Raises:
APIError: The request failed, including 404 for a missing
version.
Returns:
Stored analyzer version.
"""
response = await self._client.request(
"GET", f"/api/v1/analyzers/{analyzer_id}/versions/{version}"
)
return AnalyzerVersionResponse.model_validate(response.json())
```
Id of the analyzer.
Version number.
Stored analyzer version.
Update an analyzer version's display version.
```python
async def update_version(
self,
analyzer_id: uuid.UUID,
version: int,
request: AnalyzerVersionUpdateRequest,
) -> AnalyzerVersionResponse:
"""Update an analyzer version's display version.
Args:
analyzer_id: Id of the analyzer.
version: Version number.
request: Analyzer version update request, unset fields stay
unchanged.
Raises:
APIError: The request failed, including 404 for a missing
version.
Returns:
Updated analyzer version.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/analyzers/{analyzer_id}/versions/{version}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return AnalyzerVersionResponse.model_validate(response.json())
```
Id of the analyzer.
Version number.
Analyzer version update request, unset fields stay
unchanged.
Updated analyzer version.
# CohortVersionsResource
Cohort version API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Get a cohort version by id.
```python
async def get(self, cohort_version_id: uuid.UUID) -> CohortVersionResponse:
"""Get a cohort version by id.
Args:
cohort_version_id: Id of the cohort version.
Raises:
APIError: The request failed, including 404 for a missing cohort
version.
Returns:
Stored cohort version.
"""
response = await self._client.request(
"GET", f"/api/v1/cohort-versions/{cohort_version_id}"
)
return CohortVersionResponse.model_validate(response.json())
```
Id of the cohort version.
Stored cohort version.
Update a cohort version.
```python
async def update(
self, cohort_version_id: uuid.UUID, request: CohortVersionUpdateRequest
) -> CohortVersionResponse:
"""Update a cohort version.
Args:
cohort_version_id: Id of the cohort version.
request: Cohort version update request, unset fields stay
unchanged.
Raises:
APIError: The request failed, including 404 for a missing cohort
version.
Returns:
Updated cohort version.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/cohort-versions/{cohort_version_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return CohortVersionResponse.model_validate(response.json())
```
Id of the cohort version.
Cohort version update request, unset fields stay
unchanged.
Updated cohort version.
Delete a cohort version.
```python
async def delete(self, cohort_version_id: uuid.UUID) -> None:
"""Delete a cohort version.
Args:
cohort_version_id: Id of the cohort version.
Raises:
APIError: The request failed, including 404 for a missing cohort
version.
"""
await self._client.request(
"DELETE", f"/api/v1/cohort-versions/{cohort_version_id}"
)
```
Id of the cohort version.
# CohortsResource
Cohort API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create a cohort.
```python
async def create(
self, request: CohortCreateRequest, idempotency_key: str | None = None
) -> CohortResponse:
"""Create a cohort.
Args:
request: Cohort create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 when the agent does
not exist, 409 for a duplicate name, and 422 for an invalid
or mismatched member list.
Returns:
Created cohort.
"""
response = await self._client.request(
"POST",
"/api/v1/cohorts",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return CohortResponse.model_validate(response.json())
```
Cohort create request.
Idempotency key overriding the transport's
random default.
Created cohort.
Get a cohort by id.
```python
async def get(self, cohort_id: uuid.UUID) -> CohortResponse:
"""Get a cohort by id.
Args:
cohort_id: Id of the cohort.
Raises:
APIError: The request failed, including 404 for a missing
cohort.
Returns:
Stored cohort.
"""
response = await self._client.request("GET", f"/api/v1/cohorts/{cohort_id}")
return CohortResponse.model_validate(response.json())
```
Stored cohort.
List cohorts.
```python
async def list(
self,
params: CohortListParams | None = None,
) -> Page[CohortResponse]:
"""List cohorts.
Args:
params: Cohort list params.
Raises:
APIError: The request failed.
Returns:
Page of cohorts.
"""
params = params or CohortListParams()
response = await self._client.request(
"GET",
"/api/v1/cohorts",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[CohortResponse].model_validate(response.json())
```
Page of cohorts.
Iterate over all cohorts.
```python
async def iter(
self,
params: CohortListParams | None = None,
) -> AsyncIterator[CohortResponse]:
"""Iterate over all cohorts.
Args:
params: Cohort list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every cohort.
"""
async for item in iterate_pages(params or CohortListParams(), self.list):
yield item
```
Async iterator over every cohort.
Update a cohort's name and description.
```python
async def update(
self, cohort_id: uuid.UUID, request: CohortUpdateRequest
) -> CohortResponse:
"""Update a cohort's name and description.
Args:
cohort_id: Id of the cohort.
request: Cohort update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
cohort.
Returns:
Updated cohort.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/cohorts/{cohort_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return CohortResponse.model_validate(response.json())
```
Id of the cohort.
Cohort update request, unset fields stay unchanged.
Updated cohort.
Delete a cohort.
```python
async def delete(self, cohort_id: uuid.UUID) -> None:
"""Delete a cohort.
Args:
cohort_id: Id of the cohort.
Raises:
APIError: The request failed, including 404 for a missing
cohort and 409 when an experiment run references one of
its versions.
"""
await self._client.request("DELETE", f"/api/v1/cohorts/{cohort_id}")
```
Create a new version of a cohort.
```python
async def create_version(
self,
cohort_id: uuid.UUID,
request: CohortVersionCreateRequest,
idempotency_key: str | None = None,
) -> CohortVersionResponse:
"""Create a new version of a cohort.
Args:
cohort_id: Id of the cohort.
request: Cohort version create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing
cohort or baseline version and 422 for an invalid or
mismatched member list.
Returns:
Created cohort version.
"""
response = await self._client.request(
"POST",
f"/api/v1/cohorts/{cohort_id}/versions",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return CohortVersionResponse.model_validate(response.json())
```
Id of the cohort.
Cohort version create request.
Idempotency key overriding the transport's
random default.
Created cohort version.
List the versions of a cohort.
```python
async def list_versions(
self, cohort_id: uuid.UUID, params: CohortVersionListParams | None = None
) -> Page[CohortVersionResponse]:
"""List the versions of a cohort.
Args:
cohort_id: Id of the cohort.
params: Cohort version list params.
Raises:
APIError: The request failed.
Returns:
Page of cohort versions.
"""
params = params or CohortVersionListParams()
response = await self._client.request(
"GET",
f"/api/v1/cohorts/{cohort_id}/versions",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[CohortVersionResponse].model_validate(response.json())
```
Id of the cohort.
Cohort version list params.
Page of cohort versions.
Iterate over every version of a cohort.
```python
async def iter_versions(
self, cohort_id: uuid.UUID, params: CohortVersionListParams | None = None
) -> AsyncIterator[CohortVersionResponse]:
"""Iterate over every version of a cohort.
Args:
cohort_id: Id of the cohort.
params: Cohort version list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every version of the cohort.
"""
async for item in iterate_pages(
params or CohortVersionListParams(),
lambda page_params: self.list_versions(cohort_id, page_params),
):
yield item
```
Id of the cohort.
Cohort version list params.
Async iterator over every version of the cohort.
# EvaluationsResource
Evaluation API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Score every input session with every evaluator.
```python
async def create(
self, request: EvaluationBatchCreateRequest, idempotency_key: str | None = None
) -> JobResponse:
"""Score every input session with every evaluator.
Args:
request: Evaluation batch create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 422 when the pair count
exceeds the cap or an input session does not exist.
Returns:
Created job.
"""
response = await self._client.request(
"POST",
"/api/v1/evaluations",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return JobResponse.model_validate(response.json())
```
Evaluation batch create request.
Idempotency key overriding the transport's
random default.
Created job.
Get an evaluation by id.
```python
async def get(self, evaluation_id: uuid.UUID) -> EvaluationResponse:
"""Get an evaluation by id.
Args:
evaluation_id: Id of the evaluation.
Raises:
APIError: The request failed, including 404 for a missing
evaluation.
Returns:
Stored evaluation.
"""
response = await self._client.request(
"GET", f"/api/v1/evaluations/{evaluation_id}"
)
return EvaluationResponse.model_validate(response.json())
```
Stored evaluation.
List evaluations.
```python
async def list(
self,
params: EvaluationListParams | None = None,
) -> Page[EvaluationResponse]:
"""List evaluations.
Args:
params: Evaluation list params.
Raises:
APIError: The request failed.
Returns:
Page of evaluations.
"""
params = params or EvaluationListParams()
response = await self._client.request(
"GET",
"/api/v1/evaluations",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[EvaluationResponse].model_validate(response.json())
```
Page of evaluations.
Iterate over all evaluations.
```python
async def iter(
self,
params: EvaluationListParams | None = None,
) -> AsyncIterator[EvaluationResponse]:
"""Iterate over all evaluations.
Args:
params: Evaluation list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every evaluation.
"""
async for item in iterate_pages(params or EvaluationListParams(), self.list):
yield item
```
Async iterator over every evaluation.
# EvaluatorsResource
Evaluator API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create an evaluator.
```python
async def create(
self, request: EvaluatorCreateRequest, idempotency_key: str | None = None
) -> EvaluatorResponse:
"""Create an evaluator.
Args:
request: Evaluator create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 409 for a duplicate name.
Returns:
Created evaluator.
"""
response = await self._client.request(
"POST",
"/api/v1/evaluators",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return EvaluatorResponse.model_validate(response.json())
```
Evaluator create request.
Idempotency key overriding the transport's
random default.
Created evaluator.
Get an evaluator by id.
```python
async def get(self, evaluator_id: uuid.UUID) -> EvaluatorResponse:
"""Get an evaluator by id.
Args:
evaluator_id: Id of the evaluator.
Raises:
APIError: The request failed, including 404 for a missing
evaluator.
Returns:
Stored evaluator.
"""
response = await self._client.request(
"GET", f"/api/v1/evaluators/{evaluator_id}"
)
return EvaluatorResponse.model_validate(response.json())
```
Stored evaluator.
List evaluators.
```python
async def list(
self, params: EvaluatorListParams | None = None
) -> Page[EvaluatorResponse]:
"""List evaluators.
Args:
params: Evaluator list params.
Raises:
APIError: The request failed.
Returns:
Page of evaluators.
"""
params = params or EvaluatorListParams()
response = await self._client.request(
"GET",
"/api/v1/evaluators",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[EvaluatorResponse].model_validate(response.json())
```
Page of evaluators.
Iterate over all evaluators.
```python
async def iter(
self, params: EvaluatorListParams | None = None
) -> AsyncIterator[EvaluatorResponse]:
"""Iterate over all evaluators.
Args:
params: Evaluator list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every evaluator.
"""
async for item in iterate_pages(params or EvaluatorListParams(), self.list):
yield item
```
Async iterator over every evaluator.
Update an evaluator.
```python
async def update(
self, evaluator_id: uuid.UUID, request: EvaluatorUpdateRequest
) -> EvaluatorResponse:
"""Update an evaluator.
Args:
evaluator_id: Id of the evaluator.
request: Evaluator update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
evaluator.
Returns:
Updated evaluator.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/evaluators/{evaluator_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return EvaluatorResponse.model_validate(response.json())
```
Id of the evaluator.
Evaluator update request, unset fields stay unchanged.
Updated evaluator.
Delete an evaluator, cascading its versions.
```python
async def delete(self, evaluator_id: uuid.UUID) -> None:
"""Delete an evaluator, cascading its versions.
Args:
evaluator_id: Id of the evaluator.
Raises:
APIError: The request failed, including 404 for a missing
evaluator.
"""
await self._client.request("DELETE", f"/api/v1/evaluators/{evaluator_id}")
```
Create an evaluator version.
```python
async def create_version(
self,
evaluator_id: uuid.UUID,
request: EvaluatorVersionCreateRequest,
idempotency_key: str | None = None,
) -> EvaluatorVersionResponse:
"""Create an evaluator version.
Args:
evaluator_id: Id of the evaluator.
request: Evaluator version create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing
evaluator or blob.
Returns:
Created evaluator version.
"""
response = await self._client.request(
"POST",
f"/api/v1/evaluators/{evaluator_id}/versions",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return EvaluatorVersionResponse.model_validate(response.json())
```
Id of the evaluator.
Evaluator version create request.
Idempotency key overriding the transport's
random default.
Created evaluator version.
List an evaluator's versions.
```python
async def list_versions(
self, evaluator_id: uuid.UUID, params: ListParams | None = None
) -> Page[EvaluatorVersionResponse]:
"""List an evaluator's versions.
Args:
evaluator_id: Id of the evaluator.
params: List params.
Raises:
APIError: The request failed.
Returns:
Page of evaluator versions.
"""
params = params or ListParams()
response = await self._client.request(
"GET",
f"/api/v1/evaluators/{evaluator_id}/versions",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[EvaluatorVersionResponse].model_validate(response.json())
```
Id of the evaluator.
List params.
Page of evaluator versions.
Iterate over all of an evaluator's versions.
```python
async def iter_versions(
self, evaluator_id: uuid.UUID, params: ListParams | None = None
) -> AsyncIterator[EvaluatorVersionResponse]:
"""Iterate over all of an evaluator's versions.
Args:
evaluator_id: Id of the evaluator.
params: List params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every evaluator version.
"""
async for item in iterate_pages(
params or ListParams(),
lambda page_params: self.list_versions(evaluator_id, page_params),
):
yield item
```
Id of the evaluator.
List params.
Async iterator over every evaluator version.
Get an evaluator version by version number.
```python
async def get_version(
self, evaluator_id: uuid.UUID, version: int
) -> EvaluatorVersionResponse:
"""Get an evaluator version by version number.
Args:
evaluator_id: Id of the evaluator.
version: Version number.
Raises:
APIError: The request failed, including 404 for a missing
version.
Returns:
Stored evaluator version.
"""
response = await self._client.request(
"GET", f"/api/v1/evaluators/{evaluator_id}/versions/{version}"
)
return EvaluatorVersionResponse.model_validate(response.json())
```
Id of the evaluator.
Version number.
Stored evaluator version.
Update an evaluator version's display version.
```python
async def update_version(
self,
evaluator_id: uuid.UUID,
version: int,
request: EvaluatorVersionUpdateRequest,
) -> EvaluatorVersionResponse:
"""Update an evaluator version's display version.
Args:
evaluator_id: Id of the evaluator.
version: Version number.
request: Evaluator version update request, unset fields stay
unchanged.
Raises:
APIError: The request failed, including 404 for a missing
version.
Returns:
Updated evaluator version.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/evaluators/{evaluator_id}/versions/{version}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return EvaluatorVersionResponse.model_validate(response.json())
```
Id of the evaluator.
Version number.
Evaluator version update request, unset fields stay
unchanged.
Updated evaluator version.
# ExperimentRunsResource
Experiment run API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Get an experiment run by id.
```python
async def get(self, experiment_run_id: uuid.UUID) -> ExperimentRunResponse:
"""Get an experiment run by id.
Args:
experiment_run_id: Id of the run.
Raises:
APIError: The request failed, including 404 for a missing run.
Returns:
Stored experiment run.
"""
response = await self._client.request(
"GET", f"/api/v1/experiment-runs/{experiment_run_id}"
)
return ExperimentRunResponse.model_validate(response.json())
```
Stored experiment run.
List experiment runs.
```python
async def list(
self, params: ExperimentRunListParams | None = None
) -> Page[ExperimentRunResponse]:
"""List experiment runs.
Args:
params: Experiment run list params.
Raises:
APIError: The request failed.
Returns:
Page of experiment runs.
"""
params = params or ExperimentRunListParams()
response = await self._client.request(
"GET",
"/api/v1/experiment-runs",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[ExperimentRunResponse].model_validate(response.json())
```
Experiment run list params.
Page of experiment runs.
Iterate over all experiment runs.
```python
async def iter(
self, params: ExperimentRunListParams | None = None
) -> AsyncIterator[ExperimentRunResponse]:
"""Iterate over all experiment runs.
Args:
params: Experiment run list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every experiment run.
"""
async for item in iterate_pages(params or ExperimentRunListParams(), self.list):
yield item
```
Experiment run list params.
Async iterator over every experiment run.
Delete an experiment run and its jobs.
```python
async def delete(self, experiment_run_id: uuid.UUID) -> None:
"""Delete an experiment run and its jobs.
Args:
experiment_run_id: Id of the run.
Raises:
APIError: The request failed, including 404 for a missing run.
"""
await self._client.request(
"DELETE", f"/api/v1/experiment-runs/{experiment_run_id}"
)
```
List the jobs backing an experiment run's replays.
```python
async def list_jobs(
self,
experiment_run_id: uuid.UUID,
params: ExperimentRunJobsListParams | None = None,
) -> Page[JobResponse]:
"""List the jobs backing an experiment run's replays.
Args:
experiment_run_id: Id of the run.
params: Experiment run jobs list params.
Raises:
APIError: The request failed, including 404 for a missing run.
Returns:
Page of jobs.
"""
params = params or ExperimentRunJobsListParams()
response = await self._client.request(
"GET",
f"/api/v1/experiment-runs/{experiment_run_id}/jobs",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[JobResponse].model_validate(response.json())
```
Id of the run.
Experiment run jobs list params.
Page of jobs.
Iterate over all jobs backing an experiment run's replays.
```python
async def iter_jobs(
self,
experiment_run_id: uuid.UUID,
params: ExperimentRunJobsListParams | None = None,
) -> AsyncIterator[JobResponse]:
"""Iterate over all jobs backing an experiment run's replays.
Args:
experiment_run_id: Id of the run.
params: Experiment run jobs list params.
Raises:
APIError: The request failed, including 404 for a missing run.
Returns:
Async iterator over every job of the run.
"""
async for item in iterate_pages(
params or ExperimentRunJobsListParams(),
lambda page_params: self.list_jobs(experiment_run_id, page_params),
):
yield item
```
Id of the run.
Experiment run jobs list params.
Async iterator over every job of the run.
Request cancellation of a running experiment run.
```python
async def cancel(self, experiment_run_id: uuid.UUID) -> ExperimentRunResponse:
"""Request cancellation of a running experiment run.
Args:
experiment_run_id: Id of the run.
Raises:
APIError: The request failed, including 404 for a missing run
and 409 when the run is not running.
Returns:
Run carrying the cancel request.
"""
response = await self._client.request(
"POST", f"/api/v1/experiment-runs/{experiment_run_id}/cancel"
)
return ExperimentRunResponse.model_validate(response.json())
```
Run carrying the cancel request.
# ExperimentsResource
Experiment API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create an experiment.
```python
async def create(
self, request: ExperimentCreateRequest, idempotency_key: str | None = None
) -> ExperimentResponse:
"""Create an experiment.
Args:
request: Experiment create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 when the agent does
not exist or an evaluator name or version is unknown, and
409 for a duplicate name.
Returns:
Created experiment.
"""
response = await self._client.request(
"POST",
"/api/v1/experiments",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return ExperimentResponse.model_validate(response.json())
```
Experiment create request.
Idempotency key overriding the transport's
random default.
Created experiment.
Get an experiment by id.
```python
async def get(self, experiment_id: uuid.UUID) -> ExperimentResponse:
"""Get an experiment by id.
Args:
experiment_id: Id of the experiment.
Raises:
APIError: The request failed, including 404 for a missing
experiment.
Returns:
Stored experiment.
"""
response = await self._client.request(
"GET", f"/api/v1/experiments/{experiment_id}"
)
return ExperimentResponse.model_validate(response.json())
```
Stored experiment.
List experiments.
```python
async def list(
self, params: ExperimentListParams | None = None
) -> Page[ExperimentResponse]:
"""List experiments.
Args:
params: Experiment list params.
Raises:
APIError: The request failed.
Returns:
Page of experiments.
"""
params = params or ExperimentListParams()
response = await self._client.request(
"GET",
"/api/v1/experiments",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[ExperimentResponse].model_validate(response.json())
```
Page of experiments.
Iterate over all experiments.
```python
async def iter(
self, params: ExperimentListParams | None = None
) -> AsyncIterator[ExperimentResponse]:
"""Iterate over all experiments.
Args:
params: Experiment list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every experiment.
"""
async for item in iterate_pages(params or ExperimentListParams(), self.list):
yield item
```
Async iterator over every experiment.
Update an experiment.
```python
async def update(
self, experiment_id: uuid.UUID, request: ExperimentUpdateRequest
) -> ExperimentResponse:
"""Update an experiment.
Args:
experiment_id: Id of the experiment.
request: Experiment update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
experiment or an unknown evaluator name or version.
Returns:
Updated experiment.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/experiments/{experiment_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return ExperimentResponse.model_validate(response.json())
```
Id of the experiment.
Experiment update request, unset fields stay unchanged.
Updated experiment.
Delete an experiment.
```python
async def delete(self, experiment_id: uuid.UUID) -> None:
"""Delete an experiment.
Args:
experiment_id: Id of the experiment.
Raises:
APIError: The request failed, including 404 for a missing
experiment.
"""
await self._client.request("DELETE", f"/api/v1/experiments/{experiment_id}")
```
Start an experiment run, fanning out one replay per cohort version session.
```python
async def start_run(
self,
experiment_id: uuid.UUID,
request: ExperimentRunCreateRequest,
idempotency_key: str | None = None,
) -> ExperimentRunResponse:
"""Start an experiment run, fanning out one replay per cohort version session.
Args:
experiment_id: Id of the experiment.
request: Experiment run create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing
experiment, cohort version, or agent version, and 422 for an
empty or mismatched cohort version, a mismatched agent
version, or a missing agent version resolution.
Returns:
Created run.
"""
response = await self._client.request(
"POST",
f"/api/v1/experiments/{experiment_id}/runs",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return ExperimentRunResponse.model_validate(response.json())
```
Id of the experiment.
Experiment run create request.
Idempotency key overriding the transport's
random default.
Created run.
# InsightsResource
Insight API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create a batch of insights for one agent in one shot.
```python
async def create(
self,
agent_id: uuid.UUID,
insights: list[InsightInput],
idempotency_key: str | None = None,
) -> list[InsightResponse]:
"""Create a batch of insights for one agent in one shot.
Args:
agent_id: Agent the insights belong to.
insights: Insights to create, in input order.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 when the agent does
not exist.
Returns:
Created insights in input order.
"""
request = InsightBatchCreateRequest(agent_id=agent_id, insights=insights)
response = await self._client.request(
"POST",
"/api/v1/insights",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return [InsightResponse.model_validate(item) for item in response.json()]
```
Agent the insights belong to.
Insights to create, in input order.
Idempotency key overriding the transport's
random default.
Created insights in input order.
Get an insight by id.
```python
async def get(self, insight_id: uuid.UUID) -> InsightResponse:
"""Get an insight by id.
Args:
insight_id: Id of the insight.
Raises:
APIError: The request failed, including 404 for a missing
insight.
Returns:
Stored insight.
"""
response = await self._client.request("GET", f"/api/v1/insights/{insight_id}")
return InsightResponse.model_validate(response.json())
```
Stored insight.
List insights.
```python
async def list(
self,
params: InsightListParams | None = None,
) -> Page[InsightResponse]:
"""List insights.
Args:
params: Insight list params.
Raises:
APIError: The request failed.
Returns:
Page of insights.
"""
params = params or InsightListParams()
response = await self._client.request(
"GET",
"/api/v1/insights",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[InsightResponse].model_validate(response.json())
```
Page of insights.
Iterate over all insights.
```python
async def iter(
self,
params: InsightListParams | None = None,
) -> AsyncIterator[InsightResponse]:
"""Iterate over all insights.
Args:
params: Insight list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every insight.
"""
async for item in iterate_pages(params or InsightListParams(), self.list):
yield item
```
Async iterator over every insight.
Update an insight's title and description.
```python
async def update(
self, insight_id: uuid.UUID, request: InsightUpdateRequest
) -> InsightResponse:
"""Update an insight's title and description.
Args:
insight_id: Id of the insight.
request: Insight update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
insight.
Returns:
Updated insight.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/insights/{insight_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return InsightResponse.model_validate(response.json())
```
Id of the insight.
Insight update request, unset fields stay unchanged.
Updated insight.
Delete an insight.
```python
async def delete(self, insight_id: uuid.UUID) -> None:
"""Delete an insight.
Args:
insight_id: Id of the insight.
Raises:
APIError: The request failed, including 404 for a missing
insight.
"""
await self._client.request("DELETE", f"/api/v1/insights/{insight_id}")
```
# InvestigationsResource
Investigation API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create an investigation with its sessions in one shot.
```python
async def create(
self,
request: InvestigationCreateRequest,
idempotency_key: str | None = None,
) -> InvestigationResponse:
"""Create an investigation with its sessions in one shot.
Args:
request: Investigation create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 when the agent or a
session does not exist.
Returns:
Created investigation.
"""
response = await self._client.request(
"POST",
"/api/v1/investigations",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return InvestigationResponse.model_validate(response.json())
```
Investigation create request.
Idempotency key overriding the transport's
random default.
Created investigation.
Get an investigation by id.
```python
async def get(self, investigation_id: uuid.UUID) -> InvestigationResponse:
"""Get an investigation by id.
Args:
investigation_id: Id of the investigation.
Raises:
APIError: The request failed, including 404 for a missing
investigation.
Returns:
Stored investigation.
"""
response = await self._client.request(
"GET", f"/api/v1/investigations/{investigation_id}"
)
return InvestigationResponse.model_validate(response.json())
```
Stored investigation.
List investigations.
```python
async def list(
self,
params: InvestigationListParams | None = None,
) -> Page[InvestigationResponse]:
"""List investigations.
Args:
params: Investigation list params.
Raises:
APIError: The request failed.
Returns:
Page of investigations.
"""
params = params or InvestigationListParams()
response = await self._client.request(
"GET",
"/api/v1/investigations",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[InvestigationResponse].model_validate(response.json())
```
Investigation list params.
Page of investigations.
Iterate over all investigations.
```python
async def iter(
self,
params: InvestigationListParams | None = None,
) -> AsyncIterator[InvestigationResponse]:
"""Iterate over all investigations.
Args:
params: Investigation list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every investigation.
"""
async for item in iterate_pages(params or InvestigationListParams(), self.list):
yield item
```
Investigation list params.
Async iterator over every investigation.
Update an investigation's name, description, and status.
```python
async def update(
self, investigation_id: uuid.UUID, request: InvestigationUpdateRequest
) -> InvestigationResponse:
"""Update an investigation's name, description, and status.
Args:
investigation_id: Id of the investigation.
request: Investigation update request, unset fields stay
unchanged.
Raises:
APIError: The request failed, including 404 for a missing
investigation.
Returns:
Updated investigation.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/investigations/{investigation_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return InvestigationResponse.model_validate(response.json())
```
Id of the investigation.
Investigation update request, unset fields stay
unchanged.
Updated investigation.
Delete an investigation, cascading its sessions and answers.
```python
async def delete(self, investigation_id: uuid.UUID) -> None:
"""Delete an investigation, cascading its sessions and answers.
Args:
investigation_id: Id of the investigation.
Raises:
APIError: The request failed, including 404 for a missing
investigation.
"""
await self._client.request(
"DELETE", f"/api/v1/investigations/{investigation_id}"
)
```
List the sessions of an investigation, ordered by position.
```python
async def list_sessions(
self,
investigation_id: uuid.UUID,
params: InvestigationSessionsListParams | None = None,
) -> Page[InvestigationSessionResponse]:
"""List the sessions of an investigation, ordered by position.
Args:
investigation_id: Id of the investigation.
params: Investigation sessions list params.
Raises:
APIError: The request failed, including 404 for a missing
investigation.
Returns:
Page of investigation sessions, ordered by position.
"""
params = params or InvestigationSessionsListParams()
response = await self._client.request(
"GET",
f"/api/v1/investigations/{investigation_id}/sessions",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[InvestigationSessionResponse].model_validate(response.json())
```
Id of the investigation.
Investigation sessions list params.
Page of investigation sessions, ordered by position.
Iterate over all sessions of an investigation, ordered by position.
```python
async def iter_sessions(
self,
investigation_id: uuid.UUID,
params: InvestigationSessionsListParams | None = None,
) -> AsyncIterator[InvestigationSessionResponse]:
"""Iterate over all sessions of an investigation, ordered by position.
Args:
investigation_id: Id of the investigation.
params: Investigation sessions list params.
Raises:
APIError: The request failed, including 404 for a missing
investigation.
Returns:
Async iterator over every session of the investigation, ordered
by position.
"""
async for item in iterate_pages(
params or InvestigationSessionsListParams(),
lambda page_params: self.list_sessions(investigation_id, page_params),
):
yield item
```
Id of the investigation.
Investigation sessions list params.
Async iterator over every session of the investigation, ordered
Set or clear an investigation session's verdict.
```python
async def update_session(
self,
investigation_id: uuid.UUID,
session_id: uuid.UUID,
request: InvestigationSessionUpdateRequest,
) -> InvestigationSessionResponse:
"""Set or clear an investigation session's verdict.
Args:
investigation_id: Id of the investigation.
session_id: Id of the session.
request: Investigation session update request.
Raises:
APIError: The request failed, including 404 for a missing
investigation session.
Returns:
Updated investigation session.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/investigations/{investigation_id}/sessions/{session_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return InvestigationSessionResponse.model_validate(response.json())
```
Id of the investigation.
Id of the session.
Investigation session update request.
Updated investigation session.
# JobsResource
Job API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Get a job by id.
```python
async def get(self, job_id: uuid.UUID) -> JobResponse:
"""Get a job by id.
Args:
job_id: Id of the job.
Raises:
APIError: The request failed, including 404 for a missing job.
Returns:
Stored job.
"""
response = await self._client.request("GET", f"/api/v1/jobs/{job_id}")
return JobResponse.model_validate(response.json())
```
Stored job.
List jobs.
```python
async def list(self, params: JobListParams | None = None) -> Page[JobResponse]:
"""List jobs.
Args:
params: Job list params.
Raises:
APIError: The request failed.
Returns:
Page of jobs.
"""
params = params or JobListParams()
response = await self._client.request(
"GET",
"/api/v1/jobs",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[JobResponse].model_validate(response.json())
```
Page of jobs.
Iterate over all jobs.
```python
async def iter(
self, params: JobListParams | None = None
) -> AsyncIterator[JobResponse]:
"""Iterate over all jobs.
Args:
params: Job list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every job.
"""
async for item in iterate_pages(params or JobListParams(), self.list):
yield item
```
Async iterator over every job.
List the tasks of a job.
```python
async def list_tasks(
self, job_id: uuid.UUID, params: JobTasksListParams | None = None
) -> Page[TaskResponse]:
"""List the tasks of a job.
Args:
job_id: Id of the job.
params: Job tasks list params.
Raises:
APIError: The request failed, including 404 for a missing job.
Returns:
Page of tasks.
"""
params = params or JobTasksListParams()
response = await self._client.request(
"GET",
f"/api/v1/jobs/{job_id}/tasks",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[TaskResponse].model_validate(response.json())
```
Id of the job.
Job tasks list params.
Page of tasks.
Iterate over all tasks of a job.
```python
async def iter_tasks(
self, job_id: uuid.UUID, params: JobTasksListParams | None = None
) -> AsyncIterator[TaskResponse]:
"""Iterate over all tasks of a job.
Args:
job_id: Id of the job.
params: Job tasks list params.
Raises:
APIError: The request failed, including 404 for a missing job.
Returns:
Async iterator over every task of the job.
"""
async for item in iterate_pages(
params or JobTasksListParams(),
lambda page_params: self.list_tasks(job_id, page_params),
):
yield item
```
Id of the job.
Job tasks list params.
Async iterator over every task of the job.
Request cancellation of a job.
```python
async def cancel(self, job_id: uuid.UUID) -> JobResponse:
"""Request cancellation of a job.
Args:
job_id: Id of the job.
Raises:
APIError: The request failed, including 409 for a settled job.
Returns:
Job carrying the cancel request.
"""
response = await self._client.request("POST", f"/api/v1/jobs/{job_id}/cancel")
return JobResponse.model_validate(response.json())
```
Job carrying the cancel request.
Delete a settled job, cascading its tasks.
```python
async def delete(self, job_id: uuid.UUID) -> None:
"""Delete a settled job, cascading its tasks.
Args:
job_id: Id of the job.
Raises:
APIError: The request failed, including 404 for a missing job
and 409 for a job that has not settled.
"""
await self._client.request("DELETE", f"/api/v1/jobs/{job_id}")
```
# ReplaysResource
Replay API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create a standalone replay of a recorded or imported session.
```python
async def create(
self, request: ReplayCreateRequest, idempotency_key: str | None = None
) -> ReplayResponse:
"""Create a standalone replay of a recorded or imported session.
Args:
request: Replay create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 404 for a missing
baseline session, agent version, or evaluator, and 422 for
a missing agent version resolution or an invalid tool
policy.
Returns:
Created replay.
"""
response = await self._client.request(
"POST",
"/api/v1/replays",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return ReplayResponse.model_validate(response.json())
```
Replay create request.
Idempotency key overriding the transport's
random default.
Created replay.
Get a replay by id.
```python
async def get(self, replay_id: uuid.UUID) -> ReplayResponse:
"""Get a replay by id.
Args:
replay_id: Id of the replay.
Raises:
APIError: The request failed, including 404 for a missing
replay.
Returns:
Stored replay.
"""
response = await self._client.request("GET", f"/api/v1/replays/{replay_id}")
return ReplayResponse.model_validate(response.json())
```
Stored replay.
List replays.
```python
async def list(
self, params: ReplayListParams | None = None
) -> Page[ReplayResponse]:
"""List replays.
Args:
params: Replay list params.
Raises:
APIError: The request failed.
Returns:
Page of replays.
"""
params = params or ReplayListParams()
response = await self._client.request(
"GET",
"/api/v1/replays",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[ReplayResponse].model_validate(response.json())
```
Page of replays.
Iterate over all replays.
```python
async def iter(
self, params: ReplayListParams | None = None
) -> AsyncIterator[ReplayResponse]:
"""Iterate over all replays.
Args:
params: Replay list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every replay.
"""
async for item in iterate_pages(params or ReplayListParams(), self.list):
yield item
```
Async iterator over every replay.
Delete a replay.
```python
async def delete(self, replay_id: uuid.UUID) -> None:
"""Delete a replay.
Args:
replay_id: Id of the replay.
Raises:
APIError: The request failed, including 404 for a missing replay
and 409 when the replay belongs to an experiment run.
"""
await self._client.request("DELETE", f"/api/v1/replays/{replay_id}")
```
Search recorded tool-call history for a cached result.
```python
async def tool_lookup(
self, replay_id: uuid.UUID, request: ToolLookupRequest
) -> ToolLookupResponse:
"""Search recorded tool-call history for a cached result.
Args:
replay_id: Id of the replay.
request: Tool lookup request.
Raises:
APIError: The request failed, including 404 for a missing
replay and 422 for a tool not configured for history or an
occurrence given for a non-baseline history scope.
Returns:
Matching recorded tool call, unset on a miss.
"""
response = await self._client.request(
"POST",
f"/api/v1/replays/{replay_id}/tool-lookup",
json=request.model_dump(mode="json", exclude_unset=True),
)
return ToolLookupResponse.model_validate(response.json())
```
Id of the replay.
Tool lookup request.
Matching recorded tool call, unset on a miss.
# SessionsResource
Session API methods.
## Functions [#functions]
Initialize the resource.
```python
def __init__(self, client: "KitaruAPIClient") -> None:
"""Initialize the resource.
Args:
client: API client used to send requests.
"""
self._client = client
```
API client used to send requests.
Create a session.
```python
async def create(
self, request: SessionCreateRequest, idempotency_key: str | None = None
) -> SessionResponse:
"""Create a session.
Args:
request: Session create request.
idempotency_key: Idempotency key overriding the transport's
random default.
Raises:
APIError: The request failed, including 409 for a duplicate
imported_from and external id pair.
Returns:
Created session.
"""
response = await self._client.request(
"POST",
"/api/v1/sessions",
json=request.model_dump(mode="json", exclude_unset=True),
idempotency_key=idempotency_key,
)
return SessionResponse.model_validate(response.json())
```
Session create request.
Idempotency key overriding the transport's
random default.
Created session.
Get a session by id.
```python
async def get(self, session_id: uuid.UUID) -> SessionDetailResponse:
"""Get a session by id.
Args:
session_id: Id of the session.
Raises:
APIError: The request failed, including 404 for a missing
session.
Returns:
Stored session.
"""
response = await self._client.request("GET", f"/api/v1/sessions/{session_id}")
return SessionDetailResponse.model_validate(response.json())
```
Stored session.
Get a session together with every one of its nodes.
The node list is not paginated, so one call carries a whole session.
```python
async def get_with_nodes(self, session_id: uuid.UUID) -> SessionWithNodesResponse:
"""Get a session together with every one of its nodes.
The node list is not paginated, so one call carries a whole session.
Args:
session_id: Id of the session.
Raises:
APIError: The request failed, including 404 for a missing
session.
Returns:
Session with every node, ordered by index.
"""
response = await self._client.request(
"GET", f"/api/v1/sessions/{session_id}/full"
)
return SessionWithNodesResponse.model_validate(response.json())
```
Session with every node, ordered by index.
Ingest a batch of session nodes.
An index already stored is replaced whole.
```python
async def ingest_nodes(
self, session_id: uuid.UUID, batch: SessionNodeBatchRequest
) -> list[SessionNodeResponse]:
"""Ingest a batch of session nodes.
An index already stored is replaced whole.
Args:
session_id: Id of the session to ingest into.
batch: Session node batch request.
Raises:
APIError: The request failed, including 409 when the session
does not currently accept node ingestion.
Returns:
Stored nodes in batch order.
"""
response = await self._client.request(
"POST",
f"/api/v1/sessions/{session_id}/nodes",
json=batch.model_dump(mode="json", exclude_unset=True),
)
return [SessionNodeResponse.model_validate(item) for item in response.json()]
```
Id of the session to ingest into.
Session node batch request.
Stored nodes in batch order.
Create manual evaluations on a session.
```python
async def create_evaluations(
self, session_id: uuid.UUID, request: SessionEvaluationsRequest
) -> list[EvaluationResponse]:
"""Create manual evaluations on a session.
Args:
session_id: Id of the session to create evaluations on.
request: Session evaluations request.
Raises:
APIError: The request failed, including 404 for a missing
session, 409 when an evaluation name already exists for the
session, and 422 when the request names the same evaluation
twice.
Returns:
Stored evaluations in request order.
"""
response = await self._client.request(
"POST",
f"/api/v1/sessions/{session_id}/evaluations",
json=request.model_dump(mode="json", exclude_unset=True),
)
return [EvaluationResponse.model_validate(item) for item in response.json()]
```
Id of the session to create evaluations on.
Session evaluations request.
Stored evaluations in request order.
List sessions.
```python
async def list(
self,
params: SessionListParams | None = None,
) -> Page[SessionResponse] | Page[SessionDetailResponse]:
"""List sessions.
Args:
params: Session list params.
Raises:
APIError: The request failed.
Returns:
Page of sessions, with payloads when include_payloads is set.
"""
params = params or SessionListParams()
response = await self._client.request(
"GET",
"/api/v1/sessions",
params=params.model_dump(mode="json", exclude_unset=True),
)
if params.include_payloads:
return Page[SessionDetailResponse].model_validate(response.json())
return Page[SessionResponse].model_validate(response.json())
```
Page of sessions, with payloads when include\_payloads is set.
Iterate over all sessions.
```python
async def iter(
self,
params: SessionListParams | None = None,
) -> AsyncIterator[SessionResponse]:
"""Iterate over all sessions.
Args:
params: Session list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every session.
"""
async for item in iterate_pages(params or SessionListParams(), self.list):
yield item
```
Async iterator over every session.
Update a session.
```python
async def update(
self, session_id: uuid.UUID, request: SessionUpdateRequest
) -> SessionResponse:
"""Update a session.
Args:
session_id: Id of the session.
request: Session update request, unset fields stay unchanged.
Raises:
APIError: The request failed, including 404 for a missing
session and 409 for an illegal status transition.
Returns:
Updated session.
"""
response = await self._client.request(
"PATCH",
f"/api/v1/sessions/{session_id}",
json=request.model_dump(mode="json", exclude_unset=True),
)
return SessionResponse.model_validate(response.json())
```
Id of the session.
Session update request, unset fields stay unchanged.
Updated session.
Delete a session.
```python
async def delete(self, session_id: uuid.UUID) -> None:
"""Delete a session.
Args:
session_id: Id of the session.
Raises:
APIError: The request failed, including 404 for a missing
session and 409 when the session is referenced by a
cohort version, investigation, or replay.
"""
await self._client.request("DELETE", f"/api/v1/sessions/{session_id}")
```
List the nodes of a session, ordered by index ascending.
```python
async def list_nodes(
self,
session_id: uuid.UUID,
params: SessionNodeListParams | None = None,
) -> Page[SessionNodeResponse]:
"""List the nodes of a session, ordered by index ascending.
Args:
session_id: Id of the session.
params: Session node list params.
Raises:
APIError: The request failed.
Returns:
Page of session nodes, ordered by index.
"""
params = params or SessionNodeListParams()
response = await self._client.request(
"GET",
f"/api/v1/sessions/{session_id}/nodes",
params=params.model_dump(mode="json", exclude_unset=True),
)
return Page[SessionNodeResponse].model_validate(response.json())
```
Id of the session.
Session node list params.
Page of session nodes, ordered by index.
Iterate over every node of a session, ordered by index ascending.
```python
async def iter_nodes(
self,
session_id: uuid.UUID,
params: SessionNodeListParams | None = None,
) -> AsyncIterator[SessionNodeResponse]:
"""Iterate over every node of a session, ordered by index ascending.
Args:
session_id: Id of the session.
params: Session node list params.
Raises:
APIError: The request failed.
Returns:
Async iterator over every node of the session.
"""
async for item in iterate_pages(
params or SessionNodeListParams(),
lambda page_params: self.list_nodes(session_id, page_params),
):
yield item
```
Id of the session.
Session node list params.
Async iterator over every node of the session.
# resources
Resource method groups.
Yield every item while following opaque page cursors.
```python
async def iterate_pages(
params: ParamsT,
load_page: Callable[[ParamsT], Awaitable[Page[ItemT]]],
) -> AsyncIterator[ItemT]:
"""Yield every item while following opaque page cursors."""
while True:
page = await load_page(params)
for item in page.items:
yield item
if page.next_cursor is None:
return
params = params.model_copy(update={"cursor": page.next_cursor})
```
# AgentCreateRequest
Agent create request.
## Attributes [#attributes]
# AgentListParams
Agent list params.
# AgentResponse
Agent response.
## Attributes [#attributes]
# AgentUpdateRequest
Agent update request.
## Attributes [#attributes]
# agent
Agent API models.
# AnnotationListParams
Annotation list params.
# AnnotationResponse
Annotation response.
## Attributes [#attributes]
# AnnotationSelector
Annotation selector.
## Attributes [#attributes]
# AnnotationSpan
Annotation span.
## Attributes [#attributes]
# AnnotationUpdateRequest
Annotation update request.
## Attributes [#attributes]
# InvestigationAnswerCreateRequest
Investigation answer create request.
## Attributes [#attributes]
# ManualAnnotationCreateRequest
Manual annotation create request.
## Attributes [#attributes]
# annotation
Annotation API models.
# AgentCapabilities
Agent capabilities.
## Attributes [#attributes]
# AgentVersionCreateRequest
Agent version create request.
## Attributes [#attributes]
# AgentVersionListParams
Agent version list params.
# AgentVersionResponse
Agent version response.
## Attributes [#attributes]
# AgentVersionUpdateRequest
Agent version update request.
## Attributes [#attributes]
# RunSpec
Run spec.
## Attributes [#attributes]
# RuntimeCapabilities
Runtime capabilities.
## Attributes [#attributes]
# agent_version
Agent version API models.
# AnalyzerCreateRequest
Analyzer create request.
## Attributes [#attributes]
# AnalyzerListParams
Analyzer list params.
# AnalyzerResponse
Analyzer response.
## Attributes [#attributes]
# AnalyzerUpdateRequest
Analyzer update request.
## Attributes [#attributes]
# AnalyzerVersionCreateRequest
Analyzer version create request.
## Attributes [#attributes]
# AnalyzerVersionResponse
Analyzer version response.
## Attributes [#attributes]
# AnalyzerVersionUpdateRequest
Analyzer version update request.
## Attributes [#attributes]
# analyzer
Analyzer API models.
# CohortCreateRequest
Cohort create request.
## Attributes [#attributes]
# CohortListParams
Cohort list params.
# CohortResponse
Cohort response.
## Attributes [#attributes]
# CohortUpdateRequest
Cohort update request.
## Attributes [#attributes]
# cohort
Cohort API models.
# CohortVersionCreateRequest
Cohort version create request.
## Attributes [#attributes]
# CohortVersionListParams
Cohort version list params.
# CohortVersionResponse
Cohort version response.
## Attributes [#attributes]
# CohortVersionUpdateRequest
Cohort version update request.
## Attributes [#attributes]
# cohort_version
Cohort version API models.
# EvaluationBatchCreateRequest
Evaluation batch create request.
## Attributes [#attributes]
# EvaluationDataType
Data type an evaluation result carries.
## Attributes [#attributes]
# EvaluationListParams
Evaluation list params.
# EvaluationResponse
Evaluation response.
## Attributes [#attributes]
# evaluation
Evaluation API models.
# EvaluatorCreateRequest
Evaluator create request.
## Attributes [#attributes]
# EvaluatorListParams
Evaluator list params.
# EvaluatorResponse
Evaluator response.
## Attributes [#attributes]
# EvaluatorUpdateRequest
Evaluator update request.
## Attributes [#attributes]
# EvaluatorVersionCreateRequest
Evaluator version create request.
## Attributes [#attributes]
# EvaluatorVersionResponse
Evaluator version response.
## Attributes [#attributes]
# EvaluatorVersionUpdateRequest
Evaluator version update request.
## Attributes [#attributes]
# evaluator
Evaluator API models.
# ExperimentCreateRequest
Experiment create request.
## Attributes [#attributes]
# ExperimentListParams
Experiment list params.
# ExperimentResponse
Experiment response.
## Attributes [#attributes]
# ExperimentUpdateRequest
Experiment update request.
## Attributes [#attributes]
# experiment
Experiment API models.
# ExperimentRunCreateRequest
Experiment run create request.
## Attributes [#attributes]
# ExperimentRunJobsListParams
Experiment run jobs list params.
# ExperimentRunListParams
Experiment run list params.
# ExperimentRunProgress
Experiment run progress.
## Attributes [#attributes]
# ExperimentRunResponse
Experiment run response.
## Attributes [#attributes]
# ExperimentRunStatus
Experiment run status.
## Attributes [#attributes]
# experiment_run
Experiment run API models.
# AndFilter
And filter.
## Attributes [#attributes]
# FilterCondition
Filter condition.
## Attributes [#attributes]
# FilterOp
Filter condition operator.
## Attributes [#attributes]
# FilterableListParams
List params with a filter expression.
## Attributes [#attributes]
# NotFilter
Not filter.
## Attributes [#attributes]
# OrFilter
Or filter.
## Attributes [#attributes]
# filter
Filter API models.
# ApiImportSource
API import source.
## Attributes [#attributes]
# BlobImportSource
Blob import source.
## Attributes [#attributes]
# ImportAnalyzeRequest
Import analyze request.
## Attributes [#attributes]
# ImportCreateRequest
Import create request.
## Attributes [#attributes]
## Functions [#functions]
Return the import source, mapping the deprecated blob id to it.
```python
def get_source(self) -> ImportSource:
"""Return the import source, mapping the deprecated blob id to it.
Returns:
Import source.
"""
if self.source is not None:
return self.source
blob_id = self.payload_blob_id
assert blob_id is not None
return BlobImportSource(blob_id=blob_id)
```
Import source.
# ImportListParams
Import list params.
# ImportQuery
Import query.
## Attributes [#attributes]
## Functions [#functions]
Return the time window, with until defaulting to now.
```python
def get_window(self) -> tuple[datetime, datetime]:
"""Return the time window, with until defaulting to now.
Returns:
Window bounds.
"""
assert self.since is not None
return self.since, self.until or datetime.now(UTC)
```
Window bounds.
# ImportResponse
Import response.
## Attributes [#attributes]
# imports
Import API models.
# Bin
Bin.
## Attributes [#attributes]
# BinnedInsightData
Binned insight data.
## Attributes [#attributes]
# CategoricalInsightData
Categorical insight data.
## Attributes [#attributes]
# CategoryValue
Category value.
## Attributes [#attributes]
# InsightBatchCreateRequest
Insight batch create request.
## Attributes [#attributes]
# InsightListParams
Insight list params.
# InsightResponse
Insight response.
## Attributes [#attributes]
# InsightUpdateRequest
Insight update request.
## Attributes [#attributes]
# TextInsightData
Text insight data.
## Attributes [#attributes]
# insight
Insight API models.
# InvestigationCreateRequest
Investigation create request.
## Attributes [#attributes]
# InvestigationListParams
Investigation list params.
# InvestigationResponse
Investigation response.
## Attributes [#attributes]
# InvestigationSessionHighlight
Investigation session highlight.
## Attributes [#attributes]
# InvestigationSessionInput
Investigation session input.
## Attributes [#attributes]
# InvestigationSessionQuestion
Investigation session question.
## Attributes [#attributes]
# InvestigationSessionResponse
Investigation session response.
## Attributes [#attributes]
# InvestigationSessionUpdateRequest
Investigation session update request.
## Attributes [#attributes]
# InvestigationSessionVerdict
Investigation session verdict.
## Attributes [#attributes]
# InvestigationSessionsListParams
Investigation sessions list params.
# InvestigationStatus
Investigation status.
## Attributes [#attributes]
# InvestigationUpdateRequest
Investigation update request.
## Attributes [#attributes]
# investigation
Investigation and investigation session API models.
# JobKind
Job kind.
## Attributes [#attributes]
# JobListParams
Job list params.
# JobResponse
Job response.
## Attributes [#attributes]
# JobStatus
Job status.
## Attributes [#attributes]
# JobTasksListParams
Job tasks list params.
# job
Job API models.
# BaselineEvaluationMode
Baseline evaluation mode.
## Attributes [#attributes]
# ReplayCreateRequest
Replay create request.
## Attributes [#attributes]
# ReplayListParams
Replay list params.
# ReplayResponse
Replay response.
## Attributes [#attributes]
# ReplayStatus
Replay status.
## Attributes [#attributes]
# ToolLookupMatch
Tool lookup match.
## Attributes [#attributes]
# ToolLookupRequest
Tool lookup request.
## Attributes [#attributes]
# ToolLookupResponse
Tool lookup response.
## Attributes [#attributes]
# replay
Replay API models.
# NodeStatus
Session node status.
## Attributes [#attributes]
# NodeType
Kind of work a session node records.
## Attributes [#attributes]
# SessionNodeBatchRequest
Session node batch request.
## Attributes [#attributes]
# SessionNodeCreateRequest
Session node create request.
## Attributes [#attributes]
# SessionNodeListParams
Session node list params.
## Attributes [#attributes]
# SessionNodeResponse
Session node response.
## Attributes [#attributes]
# SessionWithNodesResponse
Session with nodes response.
## Attributes [#attributes]
# session_node
Session node API models.
# SessionCreateRequest
Session create request.
## Attributes [#attributes]
# SessionDetailResponse
Session detail response.
## Attributes [#attributes]
# SessionEvaluationsRequest
Session evaluations request.
## Attributes [#attributes]
# SessionListParams
Session list params.
## Attributes [#attributes]
# SessionOrigin
How a session came to exist.
## Attributes [#attributes]
# SessionResponse
Session response.
## Attributes [#attributes]
# SessionStatus
Session status.
## Attributes [#attributes]
# SessionUpdateRequest
Session update request.
## Attributes [#attributes]
# TokenUsage
Token usage.
## Attributes [#attributes]
# session
Session API models.
# AnalyzerConfig
Analyzer config.
## Attributes [#attributes]
# EvaluatorConfig
Evaluator config.
## Attributes [#attributes]
# HistoryConfig
History tool config.
## Attributes [#attributes]
# HistoryScope
Scope a history tool config draws recorded calls from.
## Attributes [#attributes]
# LLMConfig
LLM tool config.
## Attributes [#attributes]
# PassthroughConfig
Passthrough tool config.
## Attributes [#attributes]
# ReplayOverride
Replay override.
## Attributes [#attributes]
# StaticCase
Static tool call case.
## Attributes [#attributes]
# StaticConfig
Static tool config.
## Attributes [#attributes]
# StaticMatchMode
How a static case matches a tool call.
## Attributes [#attributes]
# ToolPolicy
Tool policy.
## Attributes [#attributes]
# ToolPolicyOnMiss
Behavior when a replayed tool call has no match.
## Attributes [#attributes]
# replay_config
Replay configuration API models, shared by experiments, replays, and evaluations.
# CursorParams
Cursor params.
## Attributes [#attributes]
# ListParams
List params.
## Attributes [#attributes]
# Page
Pagination envelope.
## Attributes [#attributes]
# base
Shared DTO bases, pagination envelope, and error body.