From 50f09a10c5b9c7c71fedc040e55316ff54c9784d Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Wed, 16 Sep 2026 18:20:38 -0700 Subject: [PATCH 1/8] trajectory type --- crates/lingua/src/universal/mod.rs | 1 + crates/lingua/src/universal/trajectory.rs | 61 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 crates/lingua/src/universal/trajectory.rs diff --git a/crates/lingua/src/universal/mod.rs b/crates/lingua/src/universal/mod.rs index 3a866011..fec68ced 100644 --- a/crates/lingua/src/universal/mod.rs +++ b/crates/lingua/src/universal/mod.rs @@ -19,6 +19,7 @@ pub mod response_format; pub mod stream; pub mod tool_choice; pub mod tools; +pub mod trajectory; pub mod transform; // Re-export main types for convenience diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs new file mode 100644 index 00000000..931315c9 --- /dev/null +++ b/crates/lingua/src/universal/trajectory.rs @@ -0,0 +1,61 @@ +use crate::{ + universal::{AssistantContent, UserContent}, + Message, UniversalParams, UniversalUsage, +}; +use serde_json::{Map, Value}; +use std::vec::Vec; + +pub struct Trajectory { + pub scope: Vec, + pub agent: Agent, + pub sections: Option>, + pub turns: Vec, + pub metadata: Map, +} + +pub enum Scope { + Span { id: String }, + Trace { trace_id: String }, + Thread { key: String, value: String }, +} + +pub struct Agent { + pub name: Option, + pub version: Option, + pub metadata: Map, + pub instructions: Option, // System prompt goes here +} + +pub struct Section { + pub name: String, + pub description: String, + pub step_ids: Vec, +} + +pub struct Turn { + pub id: String, // Best practice is to use the id of the first span + pub kind: StepKind, + + // Step definition + pub request: Vec, + pub work: Vec, + pub response: Option, + pub model: Option, + pub params: Option, + + // Metrics + pub usage: Option, + pub start_time: std::time::Instant, + pub end_time: Option, +} + +pub enum StepKind { + Agent, + SupportingWork, // Can u come up with a better name plz + Custom(String), +} + +pub enum WorkStep { + Step(Box), + Trajectory(Box), +} From be7e3b204c11ecf2582e75c1471cea2b2163d33f Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Wed, 16 Sep 2026 18:38:05 -0700 Subject: [PATCH 2/8] tweaks --- crates/lingua/src/universal/trajectory.rs | 43 +++++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index 931315c9..2c2b5b25 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -1,5 +1,5 @@ use crate::{ - universal::{AssistantContent, UserContent}, + universal::{AssistantContent, ToolContent, UserContent}, Message, UniversalParams, UniversalUsage, }; use serde_json::{Map, Value}; @@ -32,30 +32,51 @@ pub struct Section { pub step_ids: Vec, } +pub enum Step { + Turn(Turn), + Activity(Activity), +} + pub struct Turn { - pub id: String, // Best practice is to use the id of the first span - pub kind: StepKind, + pub request_id: String, + pub response_id: Option, // Step definition pub request: Vec, + pub response: Option, pub work: Vec, - pub response: Option, pub model: Option, pub params: Option, +} + +pub struct AgentResponse { + pub id: String, + pub response: Option, - // Metrics pub usage: Option, pub start_time: std::time::Instant, pub end_time: Option, } -pub enum StepKind { - Agent, - SupportingWork, // Can u come up with a better name plz - Custom(String), +pub struct ToolResult { + pub id: String, + pub content: ToolContent, + + pub start_time: std::time::Instant, + pub end_time: Option, +} + +pub struct SupportingWork { + pub id: String, + pub work: Vec, + pub usage: Option, + pub start_time: std::time::Instant, + pub end_time: Option, } pub enum WorkStep { - Step(Box), - Trajectory(Box), + AgentResponse(Box), + ToolResult(Box), + SupportingWork(Box), + SubAgent(Box), } From c2fc83ab935ad2498aa1f1077c57069cd2fc71e4 Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Wed, 16 Sep 2026 19:05:14 -0700 Subject: [PATCH 3/8] tweaks --- Cargo.lock | 4 +++ crates/lingua/Cargo.toml | 3 +- crates/lingua/src/universal/trajectory.rs | 42 +++++++++++++---------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae665c04..c6d104bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,8 +661,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-link 0.2.0", ] @@ -1978,6 +1980,7 @@ dependencies = [ "base64 0.22.1", "big_serde_json", "bytes", + "chrono", "coverage-report", "env_logger", "ipnet", @@ -3658,6 +3661,7 @@ version = "11.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ef1b7a6d914a34127ed8e1fa927eb7088903787bcded4fa3eef8f85ee1568be" dependencies = [ + "chrono", "thiserror 2.0.16", "ts-rs-macros", ] diff --git a/crates/lingua/Cargo.toml b/crates/lingua/Cargo.toml index 0032bd6c..b2ea3ac0 100644 --- a/crates/lingua/Cargo.toml +++ b/crates/lingua/Cargo.toml @@ -34,7 +34,8 @@ serde_json.workspace = true bytes.workspace = true yaml_serde.workspace = true serde_with.workspace = true -ts-rs.workspace = true +chrono.workspace = true +ts-rs = { workspace = true, features = ["chrono-impl"] } thiserror.workspace = true url.workspace = true urlencoding.workspace = true diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index 2c2b5b25..7b71ed38 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -2,6 +2,7 @@ use crate::{ universal::{AssistantContent, ToolContent, UserContent}, Message, UniversalParams, UniversalUsage, }; +use chrono::{DateTime, Utc}; use serde_json::{Map, Value}; use std::vec::Vec; @@ -11,6 +12,7 @@ pub struct Trajectory { pub sections: Option>, pub turns: Vec, pub metadata: Map, + pub version: Option, } pub enum Scope { @@ -23,7 +25,7 @@ pub struct Agent { pub name: Option, pub version: Option, pub metadata: Map, - pub instructions: Option, // System prompt goes here + pub instructions: Option, } pub struct Section { @@ -32,12 +34,8 @@ pub struct Section { pub step_ids: Vec, } -pub enum Step { - Turn(Turn), - Activity(Activity), -} - pub struct Turn { + // Each of these is the id of the corresponding span pub request_id: String, pub response_id: Option, @@ -45,38 +43,44 @@ pub struct Turn { pub request: Vec, pub response: Option, pub work: Vec, + pub model: Option, pub params: Option, + + pub start_time: DateTime, + pub end_time: Option>, } pub struct AgentResponse { - pub id: String, pub response: Option, pub usage: Option, - pub start_time: std::time::Instant, - pub end_time: Option, } pub struct ToolResult { - pub id: String, pub content: ToolContent, - - pub start_time: std::time::Instant, - pub end_time: Option, } -pub struct SupportingWork { - pub id: String, +pub struct LLMAnalysis { pub work: Vec, + pub model: Option, + pub params: Option, pub usage: Option, - pub start_time: std::time::Instant, - pub end_time: Option, } -pub enum WorkStep { +pub struct WorkStep { + pub id: String, // span's id + pub span_type: String, // span type + + pub start_time: DateTime, + pub end_time: Option>, + + pub work: Work, +} + +pub enum Work { AgentResponse(Box), ToolResult(Box), - SupportingWork(Box), + LLMAnalysis(Box), SubAgent(Box), } From 9ef0483c482e3364f5d9d262e549c8230ae3e05a Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Thu, 17 Sep 2026 08:50:09 -0700 Subject: [PATCH 4/8] improvements --- crates/lingua/src/processing/import.rs | 31 +++++++++++++++++++++++ crates/lingua/src/universal/trajectory.rs | 17 ++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/crates/lingua/src/processing/import.rs b/crates/lingua/src/processing/import.rs index d45e1fef..ddd5087f 100644 --- a/crates/lingua/src/processing/import.rs +++ b/crates/lingua/src/processing/import.rs @@ -198,6 +198,37 @@ fn try_parse_mixed_role_messages_for_import(data: &Value) -> Option let mut messages = Vec::new(); for item in items { + if let Ok(message) = serde_json::from_value::(item.clone()) { + let has_media = match &message { + Message::User { + content: UserContent::Array(parts), + } + | Message::System { + content: UserContent::Array(parts), + } + | Message::Developer { + content: UserContent::Array(parts), + } => parts.iter().any(|part| { + matches!( + part, + UserContentPart::Image { .. } + | UserContentPart::File { .. } + | UserContentPart::Audio { .. } + ) + }), + Message::Assistant { + content: AssistantContent::Array(parts), + .. + } => parts + .iter() + .any(|part| matches!(part, AssistantContentPart::File { .. })), + _ => false, + }; + if has_media { + messages.push(message); + continue; + } + } // Native Anthropic thinking blocks must use the canonical parser so adjacent text // metadata survives. Keep the existing parser order for every other role message. #[cfg(feature = "anthropic")] diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index 7b71ed38..9b66f49c 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -40,7 +40,7 @@ pub struct Turn { pub response_id: Option, // Step definition - pub request: Vec, + pub request: Option>, pub response: Option, pub work: Vec, @@ -49,20 +49,28 @@ pub struct Turn { pub start_time: DateTime, pub end_time: Option>, + pub compaction: Option, +} + +pub struct Compaction { + pub id: String, + pub replaced_message_count: Option, } pub struct AgentResponse { pub response: Option, pub usage: Option, + pub start_time: Option>, + pub end_time: Option>, } pub struct ToolResult { - pub content: ToolContent, + pub content: Option, } pub struct LLMAnalysis { - pub work: Vec, + pub work: Option>, pub model: Option, pub params: Option, pub usage: Option, @@ -71,6 +79,9 @@ pub struct LLMAnalysis { pub struct WorkStep { pub id: String, // span's id pub span_type: String, // span type + pub name: Option, + pub error: Option, + pub tool_call_id: Option, pub start_time: DateTime, pub end_time: Option>, From 234d7569b53b1b6c63a9570bd7f4f9af683e8638 Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Thu, 17 Sep 2026 09:22:12 -0700 Subject: [PATCH 5/8] remove tool call id --- crates/lingua/src/universal/trajectory.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index 9b66f49c..a9a07f7b 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -81,7 +81,6 @@ pub struct WorkStep { pub span_type: String, // span type pub name: Option, pub error: Option, - pub tool_call_id: Option, pub start_time: DateTime, pub end_time: Option>, From 3b70bcec55aee874fa2a8a02e100d5ef7c41abd2 Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Thu, 17 Sep 2026 12:42:56 -0700 Subject: [PATCH 6/8] generate types --- bindings/typescript/src/generated/Agent.ts | 4 ++ .../typescript/src/generated/AgentResponse.ts | 5 ++ .../typescript/src/generated/Compaction.ts | 3 + .../src/generated/InputTokenDetails.ts | 24 ++++++++ .../typescript/src/generated/LLMAnalysis.ts | 6 ++ .../src/generated/ModalityTokenCount.ts | 7 +++ .../src/generated/OutputTokenDetails.ts | 16 +++++ bindings/typescript/src/generated/Scope.ts | 3 + bindings/typescript/src/generated/Section.ts | 3 + .../src/generated/TokenBreakdown.ts | 7 +++ .../typescript/src/generated/TokenModality.ts | 6 ++ .../typescript/src/generated/ToolResult.ts | 4 ++ .../typescript/src/generated/Trajectory.ts | 7 +++ bindings/typescript/src/generated/Turn.ts | 8 +++ .../src/generated/UniversalUsage.ts | 60 +++++++++++++++++++ bindings/typescript/src/generated/Work.ts | 6 ++ bindings/typescript/src/generated/WorkStep.ts | 5 ++ bindings/typescript/src/types.ts | 5 ++ crates/lingua/src/processing/import.rs | 31 ---------- crates/lingua/src/universal/request.rs | 12 ++-- crates/lingua/src/universal/response.rs | 34 +++++++++-- crates/lingua/src/universal/trajectory.rs | 59 +++++++++++++++++- 22 files changed, 271 insertions(+), 44 deletions(-) create mode 100644 bindings/typescript/src/generated/Agent.ts create mode 100644 bindings/typescript/src/generated/AgentResponse.ts create mode 100644 bindings/typescript/src/generated/Compaction.ts create mode 100644 bindings/typescript/src/generated/InputTokenDetails.ts create mode 100644 bindings/typescript/src/generated/LLMAnalysis.ts create mode 100644 bindings/typescript/src/generated/ModalityTokenCount.ts create mode 100644 bindings/typescript/src/generated/OutputTokenDetails.ts create mode 100644 bindings/typescript/src/generated/Scope.ts create mode 100644 bindings/typescript/src/generated/Section.ts create mode 100644 bindings/typescript/src/generated/TokenBreakdown.ts create mode 100644 bindings/typescript/src/generated/TokenModality.ts create mode 100644 bindings/typescript/src/generated/ToolResult.ts create mode 100644 bindings/typescript/src/generated/Trajectory.ts create mode 100644 bindings/typescript/src/generated/Turn.ts create mode 100644 bindings/typescript/src/generated/UniversalUsage.ts create mode 100644 bindings/typescript/src/generated/Work.ts create mode 100644 bindings/typescript/src/generated/WorkStep.ts diff --git a/bindings/typescript/src/generated/Agent.ts b/bindings/typescript/src/generated/Agent.ts new file mode 100644 index 00000000..d272a6b1 --- /dev/null +++ b/bindings/typescript/src/generated/Agent.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { UserContent } from "./UserContent"; + +export type Agent = { name?: string, version?: string, metadata: Record, instructions?: UserContent, }; diff --git a/bindings/typescript/src/generated/AgentResponse.ts b/bindings/typescript/src/generated/AgentResponse.ts new file mode 100644 index 00000000..a9bb4310 --- /dev/null +++ b/bindings/typescript/src/generated/AgentResponse.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AssistantContent } from "./AssistantContent"; +import type { UniversalUsage } from "./UniversalUsage"; + +export type AgentResponse = { response?: AssistantContent, usage?: UniversalUsage, start_time?: string, end_time?: string, }; diff --git a/bindings/typescript/src/generated/Compaction.ts b/bindings/typescript/src/generated/Compaction.ts new file mode 100644 index 00000000..38b4dc27 --- /dev/null +++ b/bindings/typescript/src/generated/Compaction.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Compaction = { id: string, replaced_message_count?: number, }; diff --git a/bindings/typescript/src/generated/InputTokenDetails.ts b/bindings/typescript/src/generated/InputTokenDetails.ts new file mode 100644 index 00000000..f9b99b87 --- /dev/null +++ b/bindings/typescript/src/generated/InputTokenDetails.ts @@ -0,0 +1,24 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { ModalityTokenCount } from "./ModalityTokenCount"; +import type { TokenBreakdown } from "./TokenBreakdown"; + +/** + * Detailed subsets of inclusive prompt/input usage. + */ +export type InputTokenDetails = { +/** + * User/request content tokens by modality. Provider-generated tool prompts are separate. + */ +content_by_modality?: Array, +/** + * Cache-read tokens, which are included in `UniversalUsage::prompt_tokens`. + */ +cached?: TokenBreakdown, +/** + * Cache-write tokens, which are included in `UniversalUsage::prompt_tokens` when reported. + */ +cache_creation?: TokenBreakdown, +/** + * Provider-generated tool prompt tokens included in `UniversalUsage::prompt_tokens`. + */ +tool_prompt?: TokenBreakdown, }; diff --git a/bindings/typescript/src/generated/LLMAnalysis.ts b/bindings/typescript/src/generated/LLMAnalysis.ts new file mode 100644 index 00000000..d20a1d14 --- /dev/null +++ b/bindings/typescript/src/generated/LLMAnalysis.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Message } from "./Message"; +import type { UniversalParams } from "./UniversalParams"; +import type { UniversalUsage } from "./UniversalUsage"; + +export type LLMAnalysis = { work?: Array, model?: string, params?: UniversalParams, usage?: UniversalUsage, }; diff --git a/bindings/typescript/src/generated/ModalityTokenCount.ts b/bindings/typescript/src/generated/ModalityTokenCount.ts new file mode 100644 index 00000000..d98680fa --- /dev/null +++ b/bindings/typescript/src/generated/ModalityTokenCount.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { TokenModality } from "./TokenModality"; + +/** + * Token count for one modality. + */ +export type ModalityTokenCount = { modality?: TokenModality, token_count?: number, }; diff --git a/bindings/typescript/src/generated/OutputTokenDetails.ts b/bindings/typescript/src/generated/OutputTokenDetails.ts new file mode 100644 index 00000000..8a3cf2cf --- /dev/null +++ b/bindings/typescript/src/generated/OutputTokenDetails.ts @@ -0,0 +1,16 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { ModalityTokenCount } from "./ModalityTokenCount"; +import type { TokenBreakdown } from "./TokenBreakdown"; + +/** + * Detailed subsets of inclusive completion/output usage. + */ +export type OutputTokenDetails = { +/** + * Returned candidate content tokens by modality. Reasoning tokens are separate. + */ +content_by_modality?: Array, +/** + * Reasoning/thinking tokens included in `UniversalUsage::completion_tokens`. + */ +reasoning?: TokenBreakdown, }; diff --git a/bindings/typescript/src/generated/Scope.ts b/bindings/typescript/src/generated/Scope.ts new file mode 100644 index 00000000..8b2b636a --- /dev/null +++ b/bindings/typescript/src/generated/Scope.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Scope = { "type": "span", id: string, } | { "type": "trace", trace_id: string, } | { "type": "thread", key: string, value: string, }; diff --git a/bindings/typescript/src/generated/Section.ts b/bindings/typescript/src/generated/Section.ts new file mode 100644 index 00000000..cfa34cef --- /dev/null +++ b/bindings/typescript/src/generated/Section.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Section = { name: string, description: string, step_ids: Array, }; diff --git a/bindings/typescript/src/generated/TokenBreakdown.ts b/bindings/typescript/src/generated/TokenBreakdown.ts new file mode 100644 index 00000000..03195344 --- /dev/null +++ b/bindings/typescript/src/generated/TokenBreakdown.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { ModalityTokenCount } from "./ModalityTokenCount"; + +/** + * A token subset with an optional modality breakdown. + */ +export type TokenBreakdown = { total_tokens?: number, by_modality?: Array, }; diff --git a/bindings/typescript/src/generated/TokenModality.ts b/bindings/typescript/src/generated/TokenModality.ts new file mode 100644 index 00000000..56ee6c4e --- /dev/null +++ b/bindings/typescript/src/generated/TokenModality.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +/** + * A provider-independent token modality. + */ +export type TokenModality = "unspecified" | "text" | "image" | "audio" | "video" | "document"; diff --git a/bindings/typescript/src/generated/ToolResult.ts b/bindings/typescript/src/generated/ToolResult.ts new file mode 100644 index 00000000..c4df1579 --- /dev/null +++ b/bindings/typescript/src/generated/ToolResult.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { ToolContentPart } from "./ToolContentPart"; + +export type ToolResult = { input?: unknown, content?: Array, }; diff --git a/bindings/typescript/src/generated/Trajectory.ts b/bindings/typescript/src/generated/Trajectory.ts new file mode 100644 index 00000000..a8e75435 --- /dev/null +++ b/bindings/typescript/src/generated/Trajectory.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Agent } from "./Agent"; +import type { Scope } from "./Scope"; +import type { Section } from "./Section"; +import type { Turn } from "./Turn"; + +export type Trajectory = { scope: Array, agent: Agent, sections?: Array
, turns: Array, metadata: Record, version?: string, }; diff --git a/bindings/typescript/src/generated/Turn.ts b/bindings/typescript/src/generated/Turn.ts new file mode 100644 index 00000000..ca71899a --- /dev/null +++ b/bindings/typescript/src/generated/Turn.ts @@ -0,0 +1,8 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AgentResponse } from "./AgentResponse"; +import type { Compaction } from "./Compaction"; +import type { Message } from "./Message"; +import type { UniversalParams } from "./UniversalParams"; +import type { WorkStep } from "./WorkStep"; + +export type Turn = { request_id: string, response_id?: string, request?: Array, response?: AgentResponse, work: Array, model?: string, params?: UniversalParams, start_time: string, end_time?: string, compaction?: Compaction, }; diff --git a/bindings/typescript/src/generated/UniversalUsage.ts b/bindings/typescript/src/generated/UniversalUsage.ts new file mode 100644 index 00000000..54e44ca2 --- /dev/null +++ b/bindings/typescript/src/generated/UniversalUsage.ts @@ -0,0 +1,60 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { InputTokenDetails } from "./InputTokenDetails"; +import type { OutputTokenDetails } from "./OutputTokenDetails"; + +/** + * Token usage statistics. + */ +export type UniversalUsage = { +/** + * Tokens in the prompt/input, including provider-generated tool prompts when reported. + */ +prompt_tokens?: number, +/** + * Tokens in the completion/output + */ +completion_tokens?: number, +/** + * Total tokens. Preserves a provider-reported value or falls back to prompt plus completion. + */ +total_tokens?: number, +/** + * Cached tokens in the prompt (from prompt caching) + */ +prompt_cached_tokens?: number, +/** + * Tokens written to cache during this request + */ +prompt_cache_creation_tokens?: number, +/** + * Tokens written to the 5-minute-TTL cache (Anthropic split cache writes) + */ +prompt_cache_creation_5m_tokens?: number, +/** + * Tokens written to the 1-hour-TTL cache (Anthropic split cache writes) + */ +prompt_cache_creation_1h_tokens?: number, +/** + * True when `prompt_tokens` excludes the cache read/creation buckets. + * Anthropic-style usage reports `input_tokens` exclusive of cache + * tokens, while OpenAI-style usage reports `prompt_tokens` inclusive of + * them. Consumers that want an OpenAI-style inclusive prompt total must + * add the cache buckets back when this is set; see + * [`UniversalUsage::inclusive_prompt_tokens`]. Consumers that want an + * Anthropic-style exclusive input count must subtract the cache buckets + * when this is not set; see [`UniversalUsage::exclusive_prompt_tokens`]. + */ +prompt_tokens_exclude_cache?: boolean, +/** + * Reasoning/thinking tokens used in the completion. + * `Some(n)` only when `n > 0`; otherwise `None`. + */ +completion_reasoning_tokens?: number, +/** + * Detailed prompt/input token subsets and modality breakdowns. + */ +input_details?: InputTokenDetails, +/** + * Detailed completion/output token subsets and modality breakdowns. + */ +output_details?: OutputTokenDetails, }; diff --git a/bindings/typescript/src/generated/Work.ts b/bindings/typescript/src/generated/Work.ts new file mode 100644 index 00000000..885b31e6 --- /dev/null +++ b/bindings/typescript/src/generated/Work.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AgentResponse } from "./AgentResponse"; +import type { LLMAnalysis } from "./LLMAnalysis"; +import type { ToolResult } from "./ToolResult"; + +export type Work = { "type": "agent_response" } & AgentResponse | { "type": "tool_result" } & ToolResult | { "type": "llm_analysis" } & LLMAnalysis; diff --git a/bindings/typescript/src/generated/WorkStep.ts b/bindings/typescript/src/generated/WorkStep.ts new file mode 100644 index 00000000..1d968acc --- /dev/null +++ b/bindings/typescript/src/generated/WorkStep.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Trajectory } from "./Trajectory"; +import type { Work } from "./Work"; + +export type WorkStep = { id: string, span_type: string, name?: string, error?: unknown, start_time: string, end_time?: string, work: Work, sub_agent?: Trajectory, }; diff --git a/bindings/typescript/src/types.ts b/bindings/typescript/src/types.ts index 2e5f8f8c..5b4be0ac 100644 --- a/bindings/typescript/src/types.ts +++ b/bindings/typescript/src/types.ts @@ -42,3 +42,8 @@ export type { TokenBudget } from "./generated/TokenBudget"; export type { ChatCompletionRequestMessage } from "./generated/openai/ChatCompletionRequestMessage"; export type { InputItem } from "./generated/openai/InputItem"; export type { InputMessage } from "./generated/anthropic/InputMessage"; +export type { Trajectory } from "./generated/Trajectory"; +export type { Turn } from "./generated/Turn"; +export type { WorkStep } from "./generated/WorkStep"; +export type { AgentResponse } from "./generated/AgentResponse"; +export type { UniversalUsage } from "./generated/UniversalUsage"; diff --git a/crates/lingua/src/processing/import.rs b/crates/lingua/src/processing/import.rs index ddd5087f..d45e1fef 100644 --- a/crates/lingua/src/processing/import.rs +++ b/crates/lingua/src/processing/import.rs @@ -198,37 +198,6 @@ fn try_parse_mixed_role_messages_for_import(data: &Value) -> Option let mut messages = Vec::new(); for item in items { - if let Ok(message) = serde_json::from_value::(item.clone()) { - let has_media = match &message { - Message::User { - content: UserContent::Array(parts), - } - | Message::System { - content: UserContent::Array(parts), - } - | Message::Developer { - content: UserContent::Array(parts), - } => parts.iter().any(|part| { - matches!( - part, - UserContentPart::Image { .. } - | UserContentPart::File { .. } - | UserContentPart::Audio { .. } - ) - }), - Message::Assistant { - content: AssistantContent::Array(parts), - .. - } => parts - .iter() - .any(|part| matches!(part, AssistantContentPart::File { .. })), - _ => false, - }; - if has_media { - messages.push(message); - continue; - } - } // Native Anthropic thinking blocks must use the canonical parser so adjacent text // metadata survives. Keep the existing parser order for every other role message. #[cfg(feature = "anthropic")] diff --git a/crates/lingua/src/universal/request.rs b/crates/lingua/src/universal/request.rs index cd942d81..b9548581 100644 --- a/crates/lingua/src/universal/request.rs +++ b/crates/lingua/src/universal/request.rs @@ -91,7 +91,7 @@ pub enum TokenBudget { /// /// Uses canonical names - adapters handle mapping to provider-specific names. /// Provider-specific fields without canonical mappings are stored in `extras`. -#[derive(Debug, Clone, Default, Serialize, TS)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[ts(export)] pub struct UniversalParams { // === Sampling parameters === @@ -509,7 +509,7 @@ impl AsRef for SummaryMode { /// - OpenAI Chat: `"auto"` | `"none"` | `"required"` | `{ type: "function", function: { name } }` /// - OpenAI Responses: `"auto"` | `{ type: "function", name }` /// - Anthropic: `{ type: "auto" | "any" | "none" | "tool", name?, disable_parallel_tool_use? }` -#[derive(Debug, Clone, Default, Serialize, TS)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[ts(export)] pub struct ToolChoiceConfig { /// Selection mode - the semantic intent of the tool choice @@ -520,7 +520,7 @@ pub struct ToolChoiceConfig { } /// Tool selection mode (portable across providers). -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, TS)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)] #[ts(export)] pub enum ToolChoiceMode { /// Provider decides whether to use tools @@ -595,7 +595,7 @@ impl AsRef for ToolChoiceMode { /// - OpenAI Responses: nested under `text.format` /// - Google: `response_mime_type` + `response_schema` /// - Anthropic: `{ type: "json_schema", schema, name?, strict?, description? }` -#[derive(Debug, Clone, Default, Serialize, TS)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[ts(export)] pub struct ResponseFormatConfig { /// Output format type @@ -615,7 +615,7 @@ impl ResponseFormatConfig { } /// Response format type (portable across providers). -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, TS)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)] #[ts(export)] pub enum ResponseFormatType { /// Plain text output (default) @@ -666,7 +666,7 @@ impl AsRef for ResponseFormatType { } /// JSON schema configuration for structured output. -#[derive(Debug, Clone, Serialize, TS)] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] #[ts(export)] pub struct JsonSchemaConfig { /// Schema name (required by OpenAI) diff --git a/crates/lingua/src/universal/response.rs b/crates/lingua/src/universal/response.rs index 085ceb7e..0c01ccb5 100644 --- a/crates/lingua/src/universal/response.rs +++ b/crates/lingua/src/universal/response.rs @@ -11,6 +11,7 @@ use crate::universal::defaults::PLACEHOLDER_ID; use crate::universal::message::{AssistantContent, AssistantContentPart, Message}; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use ts_rs::TS; /// Universal response envelope for LLM API responses. /// @@ -79,7 +80,7 @@ impl ParsableResponseInfo { } /// A provider-independent token modality. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case")] pub enum TokenModality { Unspecified, @@ -91,69 +92,86 @@ pub enum TokenModality { } /// Token count for one modality. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, TS)] pub struct ModalityTokenCount { #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional)] pub modality: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + #[ts(optional, type = "number")] pub token_count: Option, } /// A token subset with an optional modality breakdown. #[skip_serializing_none] -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, TS)] pub struct TokenBreakdown { + #[ts(optional, type = "number")] pub total_tokens: Option, + #[ts(optional)] pub by_modality: Option>, } /// Detailed subsets of inclusive prompt/input usage. #[skip_serializing_none] -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, TS)] pub struct InputTokenDetails { /// User/request content tokens by modality. Provider-generated tool prompts are separate. + #[ts(optional)] pub content_by_modality: Option>, /// Cache-read tokens, which are included in `UniversalUsage::prompt_tokens`. + #[ts(optional)] pub cached: Option, /// Cache-write tokens, which are included in `UniversalUsage::prompt_tokens` when reported. + #[ts(optional)] pub cache_creation: Option, /// Provider-generated tool prompt tokens included in `UniversalUsage::prompt_tokens`. + #[ts(optional)] pub tool_prompt: Option, } /// Detailed subsets of inclusive completion/output usage. #[skip_serializing_none] -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, TS)] pub struct OutputTokenDetails { /// Returned candidate content tokens by modality. Reasoning tokens are separate. + #[ts(optional)] pub content_by_modality: Option>, /// Reasoning/thinking tokens included in `UniversalUsage::completion_tokens`. + #[ts(optional)] pub reasoning: Option, } /// Token usage statistics. #[skip_serializing_none] -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] pub struct UniversalUsage { /// Tokens in the prompt/input, including provider-generated tool prompts when reported. + #[ts(optional, type = "number")] pub prompt_tokens: Option, /// Tokens in the completion/output + #[ts(optional, type = "number")] pub completion_tokens: Option, /// Total tokens. Preserves a provider-reported value or falls back to prompt plus completion. + #[ts(optional, type = "number")] pub total_tokens: Option, /// Cached tokens in the prompt (from prompt caching) + #[ts(optional, type = "number")] pub prompt_cached_tokens: Option, /// Tokens written to cache during this request + #[ts(optional, type = "number")] pub prompt_cache_creation_tokens: Option, /// Tokens written to the 5-minute-TTL cache (Anthropic split cache writes) + #[ts(optional, type = "number")] pub prompt_cache_creation_5m_tokens: Option, /// Tokens written to the 1-hour-TTL cache (Anthropic split cache writes) + #[ts(optional, type = "number")] pub prompt_cache_creation_1h_tokens: Option, /// True when `prompt_tokens` excludes the cache read/creation buckets. @@ -165,16 +183,20 @@ pub struct UniversalUsage { /// Anthropic-style exclusive input count must subtract the cache buckets /// when this is not set; see [`UniversalUsage::exclusive_prompt_tokens`]. #[serde(default, skip_serializing_if = "std::ops::Not::not")] + #[ts(as = "Option", optional)] pub prompt_tokens_exclude_cache: bool, /// Reasoning/thinking tokens used in the completion. /// `Some(n)` only when `n > 0`; otherwise `None`. + #[ts(optional, type = "number")] pub completion_reasoning_tokens: Option, /// Detailed prompt/input token subsets and modality breakdowns. + #[ts(optional)] pub input_details: Option, /// Detailed completion/output token subsets and modality breakdowns. + #[ts(optional)] pub output_details: Option, } diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index a9a07f7b..acdf8172 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -3,94 +3,151 @@ use crate::{ Message, UniversalParams, UniversalUsage, }; use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; +use serde_with::skip_serializing_none; use std::vec::Vec; +use ts_rs::TS; +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[ts(export)] pub struct Trajectory { pub scope: Vec, pub agent: Agent, + #[ts(optional)] pub sections: Option>, pub turns: Vec, + #[ts(type = "Record")] pub metadata: Map, + #[ts(optional)] pub version: Option, } +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(tag = "type", rename_all = "snake_case")] pub enum Scope { Span { id: String }, Trace { trace_id: String }, Thread { key: String, value: String }, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct Agent { + #[ts(optional)] pub name: Option, + #[ts(optional)] pub version: Option, + #[ts(type = "Record")] pub metadata: Map, + #[ts(optional)] pub instructions: Option, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct Section { pub name: String, pub description: String, pub step_ids: Vec, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct Turn { // Each of these is the id of the corresponding span pub request_id: String, + #[ts(optional)] pub response_id: Option, // Step definition + #[ts(optional)] pub request: Option>, + #[ts(optional)] pub response: Option, pub work: Vec, + #[ts(optional)] pub model: Option, + #[ts(optional)] pub params: Option, pub start_time: DateTime, + #[ts(optional)] pub end_time: Option>, + #[ts(optional)] pub compaction: Option, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct Compaction { pub id: String, + #[ts(optional)] pub replaced_message_count: Option, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct AgentResponse { + #[ts(optional)] pub response: Option, + #[ts(optional)] pub usage: Option, + #[ts(optional)] pub start_time: Option>, + #[ts(optional)] pub end_time: Option>, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct ToolResult { + #[ts(optional, type = "unknown")] + pub input: Option, + #[ts(optional)] pub content: Option, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct LLMAnalysis { + #[ts(optional)] pub work: Option>, + #[ts(optional)] pub model: Option, + #[ts(optional)] pub params: Option, + #[ts(optional)] pub usage: Option, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct WorkStep { pub id: String, // span's id pub span_type: String, // span type + #[ts(optional)] pub name: Option, + #[ts(optional, type = "unknown")] pub error: Option, pub start_time: DateTime, + #[ts(optional)] pub end_time: Option>, pub work: Work, + #[ts(optional)] + pub sub_agent: Option>, } +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(tag = "type", rename_all = "snake_case")] pub enum Work { AgentResponse(Box), ToolResult(Box), + #[serde(rename = "llm_analysis")] LLMAnalysis(Box), - SubAgent(Box), } From ec2c221cf824aceb8a84fb6fd93b5c8f5d6f6663 Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Thu, 17 Sep 2026 15:19:32 -0700 Subject: [PATCH 7/8] add debugger annotations --- .../typescript/src/generated/EvidenceField.ts | 3 + .../typescript/src/generated/EvidencePart.ts | 3 + bindings/typescript/src/generated/Finding.ts | 5 ++ .../src/generated/FindingEvidence.ts | 5 ++ .../src/generated/FindingSeverity.ts | 3 + .../typescript/src/generated/Trajectory.ts | 3 +- crates/lingua/src/universal/trajectory.rs | 67 +++++++++++++++++++ 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 bindings/typescript/src/generated/EvidenceField.ts create mode 100644 bindings/typescript/src/generated/EvidencePart.ts create mode 100644 bindings/typescript/src/generated/Finding.ts create mode 100644 bindings/typescript/src/generated/FindingEvidence.ts create mode 100644 bindings/typescript/src/generated/FindingSeverity.ts diff --git a/bindings/typescript/src/generated/EvidenceField.ts b/bindings/typescript/src/generated/EvidenceField.ts new file mode 100644 index 00000000..75aecf97 --- /dev/null +++ b/bindings/typescript/src/generated/EvidenceField.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type EvidenceField = "input" | "output" | "error"; diff --git a/bindings/typescript/src/generated/EvidencePart.ts b/bindings/typescript/src/generated/EvidencePart.ts new file mode 100644 index 00000000..9043e5fd --- /dev/null +++ b/bindings/typescript/src/generated/EvidencePart.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type EvidencePart = "reasoning" | "arguments"; diff --git a/bindings/typescript/src/generated/Finding.ts b/bindings/typescript/src/generated/Finding.ts new file mode 100644 index 00000000..ea304f5c --- /dev/null +++ b/bindings/typescript/src/generated/Finding.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { FindingEvidence } from "./FindingEvidence"; +import type { FindingSeverity } from "./FindingSeverity"; + +export type Finding = { title?: string, severity?: FindingSeverity, kind?: string, hypothesis?: string, root_cause?: string, next_steps?: Array, evidence?: Array, pattern_id?: string, }; diff --git a/bindings/typescript/src/generated/FindingEvidence.ts b/bindings/typescript/src/generated/FindingEvidence.ts new file mode 100644 index 00000000..562fd775 --- /dev/null +++ b/bindings/typescript/src/generated/FindingEvidence.ts @@ -0,0 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { EvidenceField } from "./EvidenceField"; +import type { EvidencePart } from "./EvidencePart"; + +export type FindingEvidence = { step_id: string, field?: EvidenceField, part?: EvidencePart, explanation?: string, quote?: string, highlight_terms?: Array, leading_text?: string, trailing_text?: string, }; diff --git a/bindings/typescript/src/generated/FindingSeverity.ts b/bindings/typescript/src/generated/FindingSeverity.ts new file mode 100644 index 00000000..cbef2c70 --- /dev/null +++ b/bindings/typescript/src/generated/FindingSeverity.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type FindingSeverity = "critical" | "high" | "medium" | "low"; diff --git a/bindings/typescript/src/generated/Trajectory.ts b/bindings/typescript/src/generated/Trajectory.ts index a8e75435..87d64d83 100644 --- a/bindings/typescript/src/generated/Trajectory.ts +++ b/bindings/typescript/src/generated/Trajectory.ts @@ -1,7 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { Agent } from "./Agent"; +import type { Finding } from "./Finding"; import type { Scope } from "./Scope"; import type { Section } from "./Section"; import type { Turn } from "./Turn"; -export type Trajectory = { scope: Array, agent: Agent, sections?: Array
, turns: Array, metadata: Record, version?: string, }; +export type Trajectory = { scope: Array, agent: Agent, sections?: Array
, findings?: Array, turns: Array, metadata: Record, version?: string, }; diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index acdf8172..f74a37c1 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -17,6 +17,8 @@ pub struct Trajectory { pub agent: Agent, #[ts(optional)] pub sections: Option>, + #[ts(optional)] + pub findings: Option>, pub turns: Vec, #[ts(type = "Record")] pub metadata: Map, @@ -53,6 +55,71 @@ pub struct Section { pub step_ids: Vec, } +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +pub struct Finding { + #[ts(optional)] + pub title: Option, + #[ts(optional)] + pub severity: Option, + #[ts(optional)] + pub kind: Option, + #[ts(optional)] + pub hypothesis: Option, + #[ts(optional)] + pub root_cause: Option, + #[ts(optional)] + pub next_steps: Option>, + #[ts(optional)] + pub evidence: Option>, + #[ts(optional)] + pub pattern_id: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "snake_case")] +pub enum FindingSeverity { + Critical, + High, + Medium, + Low, +} + +#[skip_serializing_none] +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +pub struct FindingEvidence { + pub step_id: String, + #[ts(optional)] + pub field: Option, + #[ts(optional)] + pub part: Option, + #[ts(optional)] + pub explanation: Option, + #[ts(optional)] + pub quote: Option, + #[ts(optional)] + pub highlight_terms: Option>, + #[ts(optional)] + pub leading_text: Option, + #[ts(optional)] + pub trailing_text: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "snake_case")] +pub enum EvidenceField { + Input, + Output, + Error, +} + +#[derive(Debug, Clone, Serialize, Deserialize, TS)] +#[serde(rename_all = "snake_case")] +pub enum EvidencePart { + Reasoning, + Arguments, +} + #[skip_serializing_none] #[derive(Debug, Clone, Serialize, Deserialize, TS)] pub struct Turn { From e12246e6956254781cb6cb6abcc67ac40015e5df Mon Sep 17 00:00:00 2001 From: Ankur Goyal Date: Tue, 22 Sep 2026 16:24:07 -0700 Subject: [PATCH 8/8] add interruption --- bindings/typescript/src/generated/Turn.ts | 2 +- crates/lingua/src/universal/trajectory.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bindings/typescript/src/generated/Turn.ts b/bindings/typescript/src/generated/Turn.ts index ca71899a..a8a319e2 100644 --- a/bindings/typescript/src/generated/Turn.ts +++ b/bindings/typescript/src/generated/Turn.ts @@ -5,4 +5,4 @@ import type { Message } from "./Message"; import type { UniversalParams } from "./UniversalParams"; import type { WorkStep } from "./WorkStep"; -export type Turn = { request_id: string, response_id?: string, request?: Array, response?: AgentResponse, work: Array, model?: string, params?: UniversalParams, start_time: string, end_time?: string, compaction?: Compaction, }; +export type Turn = { request_id: string, response_id?: string, request?: Array, response?: AgentResponse, work: Array, model?: string, params?: UniversalParams, start_time: string, end_time?: string, interrupted?: boolean, compaction?: Compaction, }; diff --git a/crates/lingua/src/universal/trajectory.rs b/crates/lingua/src/universal/trajectory.rs index f74a37c1..b9da5171 100644 --- a/crates/lingua/src/universal/trajectory.rs +++ b/crates/lingua/src/universal/trajectory.rs @@ -144,6 +144,8 @@ pub struct Turn { #[ts(optional)] pub end_time: Option>, #[ts(optional)] + pub interrupted: Option, + #[ts(optional)] pub compaction: Option, }