# 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) ```
Control plane API key.
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)) ```
Server base 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}) ```
Server base URL.
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() ```
Server base URL.
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 ) ```
Id or name of the agent.
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) ```
Id of the session.
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) ```
Id of the session.
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) ```
Id of the replay.
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)) ```
Id or name of the 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)) ```
Id of the session.
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)) ```
Id of the session.
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)) ```
Id of the replay.
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 ```
Outgoing HTTP 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 ```
Outgoing HTTP 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), ) ```
Configuration to write.
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()) ```
Id of the agent version.
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}" ) ```
Id of the agent version.
# 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()) ```
Id of the agent.
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()) ```
Agent list params.
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 ```
Agent list params.
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}") ```
Id of the agent.
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()) ```
Id of the analyzer.
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()) ```
Analyzer list params.
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 ```
Analyzer list params.
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}") ```
Id of the analyzer.
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()) ```
Id of the cohort.
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()) ```
Cohort list params.
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 ```
Cohort list params.
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}") ```
Id of the cohort.
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()) ```
Id of the evaluation.
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()) ```
Evaluation list params.
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 ```
Evaluation list params.
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()) ```
Id of the evaluator.
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()) ```
Evaluator list params.
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 ```
Evaluator list params.
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}") ```
Id of the evaluator.
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()) ```
Id of the run.
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}" ) ```
Id of the run.
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()) ```
Id of the run.
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()) ```
Id of the experiment.
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()) ```
Experiment list params.
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 ```
Experiment list params.
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}") ```
Id of the experiment.
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()) ```
Id of the insight.
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()) ```
Insight list params.
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 ```
Insight list params.
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}") ```
Id of the insight.
# 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()) ```
Id of the investigation.
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}" ) ```
Id of the investigation.
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()) ```
Id of the job.
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()) ```
Job list params.
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 ```
Job list params.
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()) ```
Id of the job.
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}") ```
Id of the job.
# 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()) ```
Id of the replay.
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()) ```
Replay list params.
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 ```
Replay list params.
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}") ```
Id of the replay.
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()) ```
Id of the session.
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()) ```
Id of the session.
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()) ```
Session list params.
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 ```
Session list params.
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}") ```
Id of the session.
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.