Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
4c73dff
fix(tool): handle tool call with no arguments
senamakel Sep 19, 2026
a54f0a7
fix(types): remove unused `From` impl for `MessageContent`
senamakel Sep 19, 2026
039614e
fix(anthropic): handle SSE stream with no data lines
senamakel Sep 19, 2026
e3d8b01
feat(model): add support for new model types
senamakel Sep 19, 2026
6baa55d
fix(message): handle empty content in system messages
senamakel Sep 19, 2026
a1b754e
fix(model): handle missing tokenizer config in model loading
senamakel Sep 19, 2026
a9c0a06
feat(message): add support for system messages in LLM inference
senamakel Sep 19, 2026
28254ba
fix(model): handle empty token list in logit processor
senamakel Sep 19, 2026
82be970
fix(message): handle empty message content in validation
senamakel Sep 19, 2026
50ab138
feat(anthropic): add support for system messages in request building
senamakel Sep 19, 2026
9498924
fix(model): handle missing model file path in inference
senamakel Sep 19, 2026
b05f4ae
fix(anthropic): correct request body construction for streaming
senamakel Sep 19, 2026
91d5ffe
feat(anthropic): add support for streaming responses
senamakel Sep 19, 2026
5331e32
fix(openai): handle missing content in streaming response
senamakel Sep 19, 2026
7618435
fix(model): handle missing tokenizer in model loading
senamakel Sep 19, 2026
16cf6d4
fix(openai): handle missing finish_reason in streaming chunks
senamakel Sep 19, 2026
969985a
fix(anthropic): handle empty content blocks in streaming responses
senamakel Sep 19, 2026
ec95785
fix(openai): handle empty response body in streaming
senamakel Sep 19, 2026
3169796
fix(anthropic): handle empty content blocks in streaming response
senamakel Sep 19, 2026
dee0b64
feat(model): add support for new model types
senamakel Sep 19, 2026
21e3de8
fix(anthropic): handle empty content blocks in streaming responses
senamakel Sep 19, 2026
53abd51
fix(anthropic): handle empty content blocks in streaming responses
senamakel Sep 19, 2026
0faa4d9
fix(message): correct test assertion for empty message content
senamakel Sep 19, 2026
626e5f0
fix(test): update Anthropic provider test to match new API response f…
senamakel Sep 19, 2026
1dc805b
fix(anthropic): correct streaming response handling for SSE events
senamakel Sep 19, 2026
ea016b7
fix(model): correct test for model inference with empty input
senamakel Sep 19, 2026
2c030f5
fix(openai): handle empty response in test helper
senamakel Sep 19, 2026
2507870
fix(openai): handle empty response from OpenAI API
senamakel Sep 19, 2026
d18a86b
fix(openai): handle SSE lines with leading whitespace
senamakel Sep 19, 2026
a0e247f
fix(network_guard): handle missing network interface gracefully
senamakel Sep 19, 2026
f594c8c
fix(network_guard): handle missing network guard file gracefully
senamakel Sep 19, 2026
9b506ae
fix(anthropic): correct test assertion for streaming response
senamakel Sep 19, 2026
8f81584
fix: handle edge case in LLM inference when input is empty
senamakel Sep 19, 2026
d8c7b92
fix: handle empty input in inference to prevent panic
senamakel Sep 19, 2026
359cdd1
fix(anthropic): handle empty streaming response from API
senamakel Sep 19, 2026
602a2c4
fix(openai): handle missing content in streaming response
senamakel Sep 19, 2026
a21c1f1
test(anthropic): add streaming boundary and error recovery tests
senamakel Sep 19, 2026
0d3b8a3
refactor(types): simplify reference name extraction
senamakel Sep 19, 2026
382a98c
fix(anthropic): correct test assertion for streaming response
senamakel Sep 19, 2026
e32d0f2
fix(network_guard): handle missing network interface gracefully
senamakel Sep 19, 2026
799d133
fix(model): correct test assertion for model loading
senamakel Sep 19, 2026
db78879
feat(model): add test for model inference
senamakel Sep 19, 2026
5b2a3ea
fix(model/types): handle missing tokenizer config gracefully
senamakel Sep 19, 2026
5d6ec54
fix(anthropic): reformat imports and inline expression
senamakel Sep 19, 2026
dbb210e
fix: handle missing error source in LLM error display
senamakel Sep 19, 2026
6b53575
fix(model): handle empty string in model type parsing
senamakel Sep 19, 2026
5a2ea5c
fix(model): handle empty string in model type parsing
senamakel Sep 19, 2026
85bc69f
fix(model): handle missing tokenizer config in model loading
senamakel Sep 19, 2026
86e9367
fix(model): handle missing model file path in inference
senamakel Sep 19, 2026
d1bf68c
fix(model): handle empty token sequence in model inference
senamakel Sep 19, 2026
04c8806
fix(model): handle missing tokenizer in model loading
senamakel Sep 19, 2026
2ff2594
fix(types): make message content field public
senamakel Sep 19, 2026
96072be
fix(model): handle missing dtype field in model type parsing
senamakel Sep 19, 2026
3f8640c
fix(model): handle missing tokenizer in model loading
senamakel Sep 19, 2026
cc4f667
fix(scope): handle empty message content in inference
senamakel Sep 19, 2026
9bec2fa
fix(anthropic): handle missing content block in streaming response
senamakel Sep 19, 2026
582a8ec
fix(anthropic): handle empty tool call arguments in request parsing
senamakel Sep 19, 2026
3280a9b
fix(anthropic): handle missing system prompt in request serialization
senamakel Sep 19, 2026
13d1bee
feat(openai): add support for streaming chat completions
senamakel Sep 19, 2026
06de45e
fix(openai): handle missing finish reason in chat completion response
senamakel Sep 19, 2026
9e38381
fix(openai): handle missing `content` field in chat completion response
senamakel Sep 19, 2026
fe3ffc5
fix(openai): handle missing finish_reason in streaming response
senamakel Sep 19, 2026
28d6105
chore: files changed crates/tinyinference-llm/src/model/types.rs
senamakel Sep 19, 2026
35e7f9e
fix(anthropic): correct test assertion for streaming response handling
senamakel Sep 19, 2026
4fcdceb
fix(openai): correct test assertion for streaming response
senamakel Sep 19, 2026
dfffc6e
feat(message): add test module for message handling
senamakel Sep 19, 2026
e7ac157
test(anthropic): reformat assertion for readability
senamakel Sep 19, 2026
782d014
fix(providers): correct type field name in provider response
senamakel Sep 19, 2026
524bf13
fix(anthropic): handle empty response from provider
senamakel Sep 19, 2026
502b425
fix(anthropic): handle empty response from API
senamakel Sep 19, 2026
9fed123
fix(anthropic): handle empty response from provider
senamakel Sep 19, 2026
46440fd
fix(anthropic): handle empty response from streaming endpoint
senamakel Sep 19, 2026
4ed7f09
fix(anthropic): handle missing content in streaming response
senamakel Sep 19, 2026
cc6eb38
fix(openai): handle empty response body in transport
senamakel Sep 19, 2026
43643fa
fix(openai): handle missing content in streaming chat completion chunks
senamakel Sep 19, 2026
f788a3d
fix(openai): handle empty response body in streaming
senamakel Sep 19, 2026
d6ef138
fix(openai): handle empty response body in transport layer
senamakel Sep 19, 2026
2633ee3
fix(openai): handle empty response body in streaming
senamakel Sep 19, 2026
dee2c16
feat(message): add support for system message types
senamakel Sep 19, 2026
38c8775
fix(message): remove unused `Message` struct
senamakel Sep 19, 2026
56fa417
fix(providers): correct test assertion for provider response
senamakel Sep 19, 2026
4622969
fix(providers): correct type inference for LLM response parsing
senamakel Sep 19, 2026
442bc34
fix(providers): handle empty response in inference result parsing
senamakel Sep 19, 2026
e3612ad
fix(providers): correct type mismatch in inference response parsing
senamakel Sep 19, 2026
c22bfd4
fix(providers): handle empty tool call arguments in Anthropic and OpenAI
senamakel Sep 19, 2026
bd0e8ea
fix(openai): handle empty response from OpenAI API
senamakel Sep 19, 2026
4807872
fix(openai): handle SSE data lines with leading whitespace
senamakel Sep 19, 2026
1147a31
fix(openai): handle SSE stream with no data lines
senamakel Sep 19, 2026
0f0558e
fix(openai): handle empty response from provider
senamakel Sep 19, 2026
92121e4
fix(openai): handle empty response body in streaming
senamakel Sep 19, 2026
f355c80
fix(openai): handle empty response body in transport
senamakel Sep 19, 2026
22fa61f
fix(openai): handle empty response body in transport layer
senamakel Sep 19, 2026
9a35c40
fix(openai): handle empty response body in streaming transport
senamakel Sep 19, 2026
d014de4
fix(openai): handle SSE stream termination without trailing newline
senamakel Sep 19, 2026
4bf3a18
fix(anthropic): handle empty content block in response parsing
senamakel Sep 19, 2026
bea1339
fix(anthropic): handle empty content blocks in streaming responses
senamakel Sep 19, 2026
c3be251
fix(anthropic): handle empty response content in streaming
senamakel Sep 19, 2026
9e4dffc
fix(anthropic): handle empty stream chunks from API
senamakel Sep 19, 2026
23d980a
fix(anthropic): handle empty stream chunks from API
senamakel Sep 19, 2026
2218fba
chore: files changed crates/tinyinference-llm/src/providers/anthropic…
senamakel Sep 19, 2026
8076afc
fix(anthropic): handle missing stop reason in streaming responses
senamakel Sep 19, 2026
aeecb4b
fix(anthropic): handle empty response body in streaming
senamakel Sep 19, 2026
60574a9
fix(openai): handle missing content in streaming response
senamakel Sep 19, 2026
e7bef94
fix(openai): pass request reference to stamp_origin
senamakel Sep 19, 2026
37231ac
fix(model): handle empty optional fields in model metadata parsing
senamakel Sep 19, 2026
32428fb
fix(anthropic): handle empty response from Anthropic API
senamakel Sep 19, 2026
bb3b620
fix(anthropic): handle empty response from provider
senamakel Sep 19, 2026
6c47a3a
test(message): add tests for MessageOrigin serialization and stamping
senamakel Sep 19, 2026
8120ef7
fix(anthropic): handle empty response from streaming endpoint
senamakel Sep 19, 2026
aa8b85e
fix(anthropic): handle empty response from provider
senamakel Sep 19, 2026
dcbc2b2
test(anthropic): add tests for origin metadata and tool call id profile
senamakel Sep 19, 2026
0d66257
fix(anthropic): correct test assertion for streaming response handling
senamakel Sep 19, 2026
bd80935
fix(openai, anthropic): reformat long method signatures and chained c…
senamakel Sep 19, 2026
e470323
fix(anthropic): correct test assertion for streaming response
senamakel Sep 19, 2026
f5a1fbc
fix(openai): correct test assertion for streaming response
senamakel Sep 19, 2026
df43dd6
feat(message): add support for system message type
senamakel Sep 19, 2026
120e2a6
fix(message): handle empty content in system messages
senamakel Sep 19, 2026
2b484b0
feat(message): add support for system messages in message types
senamakel Sep 19, 2026
e3fac32
feat(message): add support for system messages in message types
senamakel Sep 19, 2026
232cf4c
fix(message/types): rename `ChatMessage` to `Message` for consistency
senamakel Sep 19, 2026
7bda09e
feat(model): add support for new model types
senamakel Sep 19, 2026
d659dce
fix(openai): handle missing content field in streaming response
senamakel Sep 19, 2026
46cb7a8
fix(openai): handle missing content in streaming chat completion chunks
senamakel Sep 19, 2026
b0ee685
fix(message): handle empty message content in validation
senamakel Sep 19, 2026
9dd16a1
fix(message): handle empty message content in validation
senamakel Sep 19, 2026
599016c
fix(openai): update test to reflect new API response format
senamakel Sep 19, 2026
4c7cc5d
fix(openai): correct test assertion for streaming response
senamakel Sep 19, 2026
125fcc9
fix(message): handle empty content in test helper
senamakel Sep 19, 2026
a6ae30e
fix(message): correct test for assistant message content
senamakel Sep 19, 2026
e8953b5
test(message): reformat long assertions and method chains for readabi…
senamakel Sep 19, 2026
708522d
fix(message): handle empty content in test helper
senamakel Sep 19, 2026
477ee07
fix(message): remove unused test module
senamakel Sep 19, 2026
6e7f556
fix(message): correct test for message content validation
senamakel Sep 19, 2026
0a04a69
fix(openai): handle empty response body in streaming
senamakel Sep 19, 2026
38ef32b
fix(openai): handle SSE data lines with leading whitespace
senamakel Sep 19, 2026
01f29bd
fix(openai): handle SSE stream with missing data field
senamakel Sep 19, 2026
eb2ac43
fix(openai): handle SSE data lines with leading colon
senamakel Sep 19, 2026
0ba09a2
chore: files changed crates/tinyinference-llm/src/providers/openai/ss…
senamakel Sep 19, 2026
1e4bc4d
fix(openai): handle SSE data lines with leading colon
senamakel Sep 19, 2026
110897b
fix(openai/sse): handle SSE stream termination on incomplete chunk
senamakel Sep 19, 2026
e5e9db5
fix(openai): correct test assertion for streaming response
senamakel Sep 19, 2026
befea98
fix(openai): correct test assertion for streaming response
senamakel Sep 19, 2026
baaa226
chore(openai): reformat enum variants for consistency
senamakel Sep 19, 2026
ab5e637
Merge phase-3 into runtime-comparison
senamakel Sep 19, 2026
d7e6bb6
Merge phase-6 into runtime-comparison
senamakel Sep 19, 2026
dc70caa
Merge phase-7 into runtime-comparison
senamakel Sep 19, 2026
e1179d5
Merge phase-5 into runtime-comparison
senamakel Sep 19, 2026
a5709b4
Merge remote-tracking branch 'origin/main' into runtime-comparison
senamakel Sep 20, 2026
f3e95d7
feat(message): add support for system message type
senamakel Sep 20, 2026
555c0c8
feat(model): add support for quantized model types
senamakel Sep 20, 2026
001f735
fix(model): handle empty tokenizer vocabulary gracefully
senamakel Sep 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/tinyinference-llm/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ pub enum Error {
/// A provider model catalog used an invalid response envelope.
#[error("catalog error: {0}")]
Catalog(String),
/// The requested operation is not supported by this adapter.
#[error("unsupported operation: {0}")]
Unsupported(String),
}
2 changes: 2 additions & 0 deletions crates/tinyinference-llm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod error;
pub mod failure;
pub mod message;
pub mod model;
mod network_guard;
pub mod prompt_tools;
pub mod providers;
pub mod sentiment;
Expand All @@ -28,6 +29,7 @@ pub use model::{
ChatModel, ModelRequest, ModelResponse, ModelStream, ModelStreamItem,
context_window_for_model_id, model_id_supports_vision,
};
pub use network_guard::{allow_network_models, deny_network_models, network_models_denied};
pub use providers::{MockModel, ProviderKind, ProviderSpec};
pub use tool::{ToolCall, ToolDelta, ToolFormat, ToolSchema};
pub use usage::{Usage, UsageTotals};
52 changes: 35 additions & 17 deletions crates/tinyinference-llm/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ impl ContentBlock {
ContentBlock::Thinking { text, .. } => text.chars().count(),
ContentBlock::RedactedThinking { data } => data.chars().count(),
ContentBlock::ProviderExtension(value) => value.to_string().chars().count(),
// Non-text media has no character-based weight of its own;
// charge the same flat weight as an image so budgeting/compaction
// does not under-count a transcript dominated by audio, video, or
// document attachments.
ContentBlock::Audio(_) | ContentBlock::Video(_) | ContentBlock::Document(_) => {
IMAGE_CHAR_WEIGHT
}
}
}
}
Expand All @@ -102,9 +109,7 @@ fn concat_text(content: &[ContentBlock]) -> String {
impl Message {
/// Creates a system message from text.
pub fn system(content: impl Into<String>) -> Self {
Message::System(SystemMessage {
content: vec![ContentBlock::Text(content.into())],
})
Message::System(SystemMessage::text(content))
}

/// Creates a user message from text.
Expand All @@ -121,6 +126,7 @@ impl Message {
content: vec![ContentBlock::Text(content.into())],
tool_calls: Vec::new(),
usage: None,
origin: None,
})
}

Expand All @@ -135,12 +141,16 @@ impl Message {
}

/// Returns the concatenated text of all text content blocks.
///
/// [`Message::Custom`] carries no [`ContentBlock`]s; this returns its
/// `display` rendering (or an empty string when none was set).
pub fn text(&self) -> String {
match self {
Message::System(m) => concat_text(&m.content),
Message::User(m) => concat_text(&m.content),
Message::Assistant(m) => concat_text(&m.content),
Message::Tool(m) => concat_text(&m.content),
Message::Custom(m) => m.display.clone().unwrap_or_default(),
}
}

Expand All @@ -159,17 +169,27 @@ impl Message {
/// `String` allocation, which matters on hot paths such as token estimation
/// over a whole transcript.
pub fn char_len(&self) -> usize {
let content = match self {
match self {
Message::Custom(m) => m.display.as_deref().map_or(0, |d| d.chars().count()),
other => other
.content_blocks()
.iter()
.filter_map(ContentBlock::as_text)
.map(|t| t.chars().count())
.sum(),
}
}

/// Returns the ordered [`ContentBlock`]s for message kinds that carry
/// them. [`Message::Custom`] carries none.
fn content_blocks(&self) -> &[ContentBlock] {
match self {
Message::System(m) => &m.content,
Message::User(m) => &m.content,
Message::Assistant(m) => &m.content,
Message::Tool(m) => &m.content,
};
content
.iter()
.filter_map(ContentBlock::as_text)
.map(|t| t.chars().count())
.sum()
Message::Custom(_) => &[],
}
}

/// Approximate character weight of provider-visible content and structural
Expand All @@ -181,13 +201,11 @@ impl Message {
/// silently never trigger even as the real context window overflows. See
/// [`ContentBlock::estimated_char_weight`].
pub fn estimated_char_weight(&self) -> usize {
let content = match self {
Message::System(m) => &m.content,
Message::User(m) => &m.content,
Message::Assistant(m) => &m.content,
Message::Tool(m) => &m.content,
};
let content_weight: usize = content
if let Message::Custom(m) = self {
return m.display.as_deref().map_or(0, |d| d.chars().count());
}
let content_weight: usize = self
.content_blocks()
.iter()
.map(ContentBlock::estimated_char_weight)
.sum();
Expand Down
Loading
Loading