Commit Graph

761 Commits

Author SHA1 Message Date
Christian Bromann
bd8ab5520b fix(core): strip null id/name from tool-call-chunk deltas in compat bridge
Many provider integrations (notably Anthropic's `input_json_delta`
path) attach the tool-call `id` and `name` only to the first
`tool_use` chunk; subsequent per-chunk slices carry `id=None,
name=None` and just the fresh `args` segment. The compat bridge
forwarded those `None` values verbatim, producing wire payloads like
`{"type": "tool_call_chunk", "id": null, "name": null, "args": "..."}`.

Consumers that fold deltas via a naive `{...target, ...delta}` spread
(e.g. the langgraph-js SDK's `MessageAssembler.applyContentDelta`)
interpret those as "identifier reset to null" and lose the id/name
captured from `content-block-start`. Downstream extractors then drop
the chunk until the final `content-block-finish` arrives — visible to
end users as tool-call cards appearing all-at-once at the end of a
turn instead of streaming in incrementally (the Deep Agent example
rendering four subagents in a single flicker rather than one after
another).

Introduce `_to_protocol_delta_block` and route every
`content-block-delta` emission (sync / async chunk streams and the
`message_to_events` replay path) through it. For `tool_call_chunk`
and `server_tool_call_chunk` shapes, drop `id` / `name` keys when
they would serialize to `null`. This matches the wire shape produced
by langgraph-js's `toProtocolDeltaBlock`, where identifiers are only
surfaced when they carry a real value.
2026-04-22 18:40:36 -07:00
Nick Hollon
06dcfaa596 feat(core): propagate async pump hook through AsyncProjection
Under caller-driven async streaming, `AsyncChatModelStream`
projections deadlocked when iterated inside an outer `async for
stream in run.messages` loop: the projection's `asyncio.Event` was
only set by external dispatch, but no task was driving the pump
while the consumer was suspended in the inner iteration.

Mirror the sync `Projection._request_more` path on the async side:
- `AsyncProjection.set_arequest_more` stores an async pull callback.
- `_AsyncProjectionIterator.__anext__` drains the callback in an
  inner loop when wired, falling back to the event wait otherwise.
- `_await_impl` drives the callback too so `await stream.output`
  and `await stream.usage` advance the producer.
- `AsyncChatModelStream.set_arequest_more` fans the callback out to
  every projection so langgraph's `AsyncGraphRunStream` can wire it
  on stream construction via a transformer `_bind_apump` hook.

Pump-exhaustion-without-completion ends iteration cleanly rather
than hanging — matches the pragmatic contract for graphs that
exhaust mid-stream.
2026-04-18 13:11:04 -04:00
Nick Hollon
a8ce29ab8c fix linting issues 2026-04-17 11:15:07 -04:00
Nick Hollon
cee4dd3852 fix docstring formatting to use google-style single backticks 2026-04-17 11:09:12 -04:00
Nick Hollon
2c449ca1f5 refactor(core): trust content_blocks in compat bridge
Collapse _compat_bridge to a single path that reads msg.content_blocks
and emits protocol events. The translator / best-effort / tool_call_chunks
extraction all live in content_blocks already — the legacy branch,
_PROTOCOL_PASS_THROUGH_TYPES, _SELF_CONTAINED_BLOCK_TYPES skeleton
handling, and manual reasoning-variant sniffing were duplicating work.

Side fixes picked up along the way:

- No-provider chunks with both text content and tool_call_chunks silently
  dropped the tool call because the legacy extractor put both at index 0.
  content_blocks places them on distinct indices.
- "server_tool_call_result" (typo) replaced with "server_tool_result" in
  ChatModelStream's finish dispatch and the test that exercises it —
  matches the protocol type that every translator actually emits.

Also collapses duplicated tool_call_chunk / server_tool_call_chunk
handling in chat_model_stream into shared merge/sweep helpers so the
two code paths can't drift apart again (which is how the typo survived).

_compat_bridge.py: 855 -> 581 lines. No public API changes.
2026-04-17 10:29:00 -04:00
Nick Hollon
63ca3f2831 feat(core): content-block completeness in v2 stream pipeline
Extend the v2 stream and compat bridge to handle every protocol
ContentBlock variant end-to-end — server tool calls, invalid tool calls,
images, audio, video, file, and non-standard blocks — not just text,
reasoning, and regular tool calls. Previously these were silently dropped
at the bridge's extractor, had no handler in ChatModelStream, and could
not appear in .output.content.

The stream now keeps an index-ordered `_blocks` snapshot as the single
source of truth for .output.content, alongside the existing typed
accumulators that drive the public projections. `_assemble_message`
builds content from that snapshot, emitting protocol-shape `tool_call`
blocks instead of the legacy `tool_use` shape, and collapses to a bare
string only when the message contains exactly one text block.

Bridge extractors (_extract_blocks_from_chunk, _extract_final_blocks) now
pass through any protocol-shape block in msg.content, _accumulate_block
and _delta_block handle server_tool_call_chunk and self-contained types,
and _finalize_block promotes server_tool_call_chunk to server_tool_call
(falling back to invalid_tool_call on JSON failure, symmetric with
regular tool calls). The standard `invalid_tool_calls` field on AIMessage
is also surfaced by the final-block extractor.

Forward-looking: today's partners keep provider-native shapes in
msg.content and expose protocol blocks lazily via the `.content_blocks`
property, so these paths are latent until partners either populate
msg.content with protocol shape or override _stream_chat_model_events.
The bridge is ready.
2026-04-17 09:15:32 -04:00
Nick Hollon
0efc5d538e fix(core): preserve invalid_tool_call blocks in v2 stream output
The compat bridge produces InvalidToolCallBlock when tool-call JSON parse
fails, but ChatModelStream had no handler for it. The finish event was
silently ignored, the stale chunk stayed in _tool_call_chunks, and
_finish's sweep re-parsed (failed again), fell back to args={}, and
appended a valid-looking ToolCallBlock — so the protocol said "invalid"
while the assembled AIMessage said "valid with empty args". An agent layer
downstream could then dispatch the malformed call.

The finish handler now routes invalid_tool_call blocks into
_invalid_tool_calls_acc and deletes the stale chunk entry; _finish's sweep
emits InvalidToolCallBlock on JSON failure instead of an empty-args tool
call; _assemble_message passes invalid_tool_calls through to AIMessage.
2026-04-17 09:06:44 -04:00
Nick Hollon
416d55b3d6 promote projection and stream producer API to public
Renames the stream's and projections' "private" producer-side methods to
public names, since they are the intended call surface for anyone driving
the stream (the pump, langgraph's forthcoming handler, tests). Removes
~36 `noqa: SLF001` suppressions along the way.

On `_ProjectionBase`:
- `_push` -> `push`
- `_finish` -> `complete`
- `_fail` -> `fail`
- adds `done` / `error` read-only properties for sidekicks (iterator)
- `SyncProjection.set_request_more(cb)` replaces direct `_request_more` assignment

On `ChatModelStream`:
- `_bind_pump` -> `bind_pump`
- `_fail` -> `fail`
- adds `output_message` property (non-blocking peek)
- new `dispatch(event)` method replaces the module-level `dispatch_event`
  helper (kept as a thin deprecated wrapper for back-compat)

The genuinely internal helpers (`_record_event`, `_push_*`, `_finish`
on the stream, `_drain`, `_assemble_message`) stay private — they have
one caller each, inside the class.

Remaining SLF001 suppressions in this file are intentional
`_AsyncProjectionIterator` coupling to its projection's `_deltas` and
`_event`; annotated with a comment.
2026-04-16 17:45:15 -04:00
Nick Hollon
8773cb8c4e add on_stream_event callback for v2 protocol events
Adds a new `on_stream_event` hook on `LLMManagerMixin` / `AsyncCallbackHandler`
that fires once per `MessagesData` event produced by `stream_v2` /
`astream_v2`, with dispatch methods on `CallbackManagerForLLMRun` and
`AsyncCallbackManagerForLLMRun`.

This is v2's observer hook, analogous to `on_llm_new_token` in v1 but at
event granularity rather than chunk. It fires uniformly whether the
provider emits events natively via `_stream_chat_model_events` or goes
through the chunk-to-event compat bridge — observers see the same event
stream regardless of how the underlying model produces output.

Primary consumer: langgraph's forthcoming `StreamProtocolMessagesHandler`,
which can now be a one-line forwarder (lookup namespace metadata by run_id,
push `(ns, "messages", (event, meta))` to the graph's output stream)
instead of re-implementing the chunks-to-events state machine internally.

Does not fire from v1 `stream()` / `astream()`. Purely additive —
`on_chat_model_start`, `on_llm_end`, and `on_llm_error` continue to
bracket a v2 call as they do a v1 call.
2026-04-16 16:53:56 -04:00
Nick Hollon
a1d331e8f0 populate on_llm_end, propagate cancellation, add message_to_events
- `stream_v2` / `astream_v2` now pass the assembled `AIMessage` to
  `on_llm_end` via `LLMResult(generations=[[ChatGeneration(message=...)]])`,
  so LangSmith and other tracers see the final response on v2 calls (was
  previously `generations=[]`).
- `astream_v2`'s producer re-raises `asyncio.CancelledError` ahead of the
  generic handler, so cancellation propagates normally instead of being
  converted into `on_llm_error` + a swallowed exception.
- New `message_to_events` / `amessage_to_events` in `_compat_bridge`
  replay a finalized `AIMessage` as a synthetic content-block lifecycle.
  Intended for the langgraph-side handler that emits protocol events for
  non-streamed node outputs (cache hits, `model.invoke()` inside a node,
  checkpointed state). Turns `_extract_final_blocks` from a dangling
  helper into a real caller.
- Document the optional `_stream_chat_model_events` /
  `_astream_chat_model_events` provider hooks inline at the getattr
  sites so integrators can discover the expected signature.
2026-04-16 16:26:12 -04:00
Nick Hollon
6b203f082d fix(core): forward bound kwargs through RunnableBinding.stream_v2
Add explicit `stream_v2` / `astream_v2` overrides on `RunnableBinding` that
merge `self.kwargs` into the delegated call, mirroring the existing
`stream` / `astream` / `invoke` overrides. Without these, calls that chained
through `bind` or `bind_tools` fell through `__getattr__` (which merges
`self.config` but not `self.kwargs`) and silently dropped bound tools,
stop sequences, and other runtime kwargs.

The returns are typed as `Any` to avoid pulling chat-model types into
`langchain_core.runnables.base`; the method only makes sense when the bound
runnable is a chat model, and `AttributeError` propagates unchanged if it
isn't.

Adds tests covering bound-kwarg forwarding for both sync and async paths
plus the call-time kwarg override semantics.
2026-04-16 15:03:03 -04:00
Nick Hollon
14442f4d10 feat(core): add content-block-centric streaming (v2)
Add `BaseChatModel.stream_v2()` / `astream_v2()` returning a `ChatModelStream`
with typed projections (`.text`, `.reasoning`, `.tool_calls`, `.usage`,
`.output`) plus raw protocol event iteration. Providers that only implement
`_stream()` get a compat bridge that converts `AIMessageChunk`s to the
content-block protocol lifecycle, preserving usage and response metadata for
v1 parity.

- New module `chat_model_stream.py` with `ChatModelStream`, `AsyncChatModelStream`,
  and push/pull projection hierarchy (`SyncProjection`, `SyncTextProjection`,
  `AsyncProjection`).
- New module `_compat_bridge.py` that converts chunk streams to protocol
  events, with `response_metadata` preserved via `MessageStartData.metadata`
  and `MessageFinishData.metadata`.
- `stream_v2` wires `on_chat_model_start` / `on_llm_end` / `on_llm_error`
  callbacks into the pump; `astream_v2` spawns a producer task and awaits it
  alongside the output so `on_llm_end` fires before `await stream` returns.
- tool_use finish-reason inference runs after finalization so malformed
  tool-call JSON (finalized as `invalid_tool_call`) does not flip
  `finish_reason` to `"tool_use"`.
- Add `langchain-protocol>=0.0.6` dependency (local path override retained
  for dev).

Tests cover projection semantics, tool-call streaming (single + parallel +
malformed args), async/sync event replay, callback firing, and v1 parity
(text, tool calls, usage, response metadata, reasoning+text ordering, error
propagation).
2026-04-16 14:41:24 -04:00
Jacob Lee
a6eb829701 fix(core): Use reference counting for storing inherited run trees to support garbage collection (#36660)
When a langsmith `@traceable` function invokes a LangChain Runnable or
LangGraph subgraph, the callback manager's `_configure` function injects
the `@traceable` RunTree into the `LangChainTracer`'s `run_map` so that
child runs can resolve their parent for trace nesting. However, since
the RunTree was created outside the tracer's callback lifecycle,
`_end_trace` never removes it. The entry persists in `run_map`
indefinitely, retaining the full RunTree and its entire child tree.

In applications with nested subgraph invocations (e.g. an outer
investigation graph delegating to skill agent subgraphs, each compiled
as their own `StateGraph`), this causes RunTree objects to accumulate
linearly with every call.

**Fix:** Track which `run_map` entries were injected externally via a
shared `_external_run_ids` refcount dict on `_TracerCore`. When
`_start_trace` adds a child under an external parent, it increments the
count. When `_end_trace` finishes a child, it decrements — and evicts
the external parent from `run_map` once the last child completes.

The refcount (rather than a simple set) is necessary because a single
external parent may have multiple sibling children in the callback chain
(e.g. a `prompt | llm` `RunnableSequence`). Only truly external runs are
tracked — the `_configure` guard `if run_id_str not in handler.run_map`
prevents tracer-managed runs from being misclassified.
2026-04-13 09:50:37 -04:00
Eugene Yurtsev
af4d711a2f chore(core): reduce streaming metadata / perf (#36588)
- looking into reducing streaming metadata / perfm

---------

Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2026-04-10 10:47:54 -04:00
Eugene Yurtsev
af2ed47c6f fix(core): add more sanitization to templates (#36612)
add more sanitization to templates
2026-04-08 14:10:10 -04:00
ccurme
7629c74726 fix(core): handle symlinks in deprecated prompt save path (#36585)
Resolve symlinks before validating file extensions in the deprecated
`save()` method on prompt classes.

Credit to Jeff Ponte (@JDP-Security) for reporting the symlink
resolution issue.
2026-04-07 10:45:42 -04:00
Michael Chin
ebecdddb1b fix(core): add init validator and serialization mappings for Bedrock models (#34510)
Adds serialization mappings for `ChatBedrockConverse` and `BedrockLLM`
to unblock standard tests on `langchain-core>=1.2.5` (context:
[langchain-aws#821](https://github.com/langchain-ai/langchain-aws/pull/821)).
Also introduces a class-specific validator system in
`langchain_core.load` that blocks deserialization of AWS Bedrock models
when `endpoint_url` or `base_url` parameters are present, preventing
SSRF attacks via crafted serialized payloads.

Closes #34645

## Changes
- Add `ChatBedrockConverse` and `BedrockLLM` entries to
`SERIALIZABLE_MAPPING` in `mapping.py`, mapping legacy paths to their
`langchain_aws` import locations
- Add `validators.py` with `_bedrock_validator` — rejects
deserialization kwargs containing `endpoint_url` or `base_url` for all
Bedrock-related classes (`ChatBedrock`, `BedrockChat`,
`ChatBedrockConverse`, `ChatAnthropicBedrock`, `BedrockLLM`, `Bedrock`)
- `CLASS_INIT_VALIDATORS` registry covers both serialized (legacy) keys
and resolved import paths from `ALL_SERIALIZABLE_MAPPINGS`, preventing
bypass via direct-path payloads
- Move kwargs extraction and all validator checks
(`CLASS_INIT_VALIDATORS` + `init_validator`) in `Reviver.__call__` to
run **before** `importlib.import_module()` — fail fast on security
violations before executing third-party code
- Class-specific validators are independent of `init_validator` and
cannot be disabled by passing `init_validator=None`

## Testing
- `test_validator_registry_keys_in_serializable_mapping` — structural
invariant test ensuring every `CLASS_INIT_VALIDATORS` key exists in
`ALL_SERIALIZABLE_MAPPINGS`
- 10 end-to-end `load()` tests covering all Bedrock class paths (legacy
aliases, resolved import paths, `ChatAnthropicBedrock`,
`init_validator=None` bypass attempt)
- Unit tests for `_bedrock_validator` covering `endpoint_url`,
`base_url`, both params, and safe kwargs

---------

Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-04-03 19:22:39 -04:00
ccurme
0b5f2c08ee fix(core): harden check for txt files in deprecated prompt loading functions (#36471) 2026-04-02 16:42:48 -04:00
jasiecky
c9f51aef85 fix(core): fixed typos in the documentation (#36459)
Fixes #36458 

Fixed typos in the documentation in the core module.
2026-04-02 11:32:12 -04:00
Weiguang Li
e6c1b29e80 fix(core): add "computer" to _WellKnownOpenAITools (#36261) 2026-03-29 08:54:42 -04:00
Jacob Lee
389f7ad1bc revert: Revert "fix(core): trace invocation params in metadata" (#36322) 2026-03-27 19:14:02 -04:00
ccurme
27add91347 fix(core): validate paths in prompt.save and load_prompt, deprecate methods (#36200) 2026-03-24 14:27:14 -04:00
Mason Daugherty
2f64d80cc6 fix(core,model-profiles): add missing ModelProfile fields, warn on schema drift (#36129)
PR #35788 added 7 new fields to the `langchain-profiles` CLI output
(`name`, `status`, `release_date`, `last_updated`, `open_weights`,
`attachment`, `temperature`) but didn't update `ModelProfile` in
`langchain-core`. Partner packages like `langchain-aws` that set
`extra="forbid"` on their Pydantic models hit `extra_forbidden`
validation errors when Pydantic encountered undeclared TypedDict keys at
construction time. This adds the missing fields, makes `ModelProfile`
forward-compatible, provides a base-class hook so partners can stop
duplicating model-profile validator boilerplate, migrates all in-repo
partners to the new hook, and adds runtime + CI-time warnings for schema
drift.

## Changes

### `langchain-core`
- Add `__pydantic_config__ = ConfigDict(extra="allow")` to
`ModelProfile` so unknown profile keys pass Pydantic validation even on
models with `extra="forbid"` — forward-compatibility for when the CLI
schema evolves ahead of core
- Declare the 7 missing fields on `ModelProfile`: `name`, `status`,
`release_date`, `last_updated`, `open_weights` (metadata) and
`attachment`, `temperature` (capabilities)
- Add `_warn_unknown_profile_keys()` in `model_profile.py` — emits a
`UserWarning` when a profile dict contains keys not in `ModelProfile`,
suggesting a core upgrade. Wrapped in a bare `except` so introspection
failures never crash model construction
- Add `BaseChatModel._resolve_model_profile()` hook that returns `None`
by default. Partners can override this single method instead of
redefining the full `_set_model_profile` validator — the base validator
calls it automatically
- Add `BaseChatModel._check_profile_keys` as a separate
`model_validator` that calls `_warn_unknown_profile_keys`. Uses a
distinct method name so partner overrides of `_set_model_profile` don't
inadvertently suppress the check

### `langchain-profiles` CLI
- Add `_warn_undeclared_profile_keys()` to the CLI (`cli.py`), called
after merging augmentations in `refresh()` — warns at profile-generation
time (not just runtime) when emitted keys aren't declared in
`ModelProfile`. Gracefully skips if `langchain-core` isn't installed
- Add guard test
`test_model_data_to_profile_keys_subset_of_model_profile` in
model-profiles — feeds a fully-populated model dict to
`_model_data_to_profile()` and asserts every emitted key exists in
`ModelProfile.__annotations__`. CI fails before any release if someone
adds a CLI field without updating the TypedDict

### Partner packages
- Migrate all 10 in-repo partners to the `_resolve_model_profile()`
hook, replacing duplicated `@model_validator` / `_set_model_profile`
overrides: anthropic, deepseek, fireworks, groq, huggingface, mistralai,
openai (base + azure), openrouter, perplexity, xai
- Anthropic retains custom logic (context-1m beta → `max_input_tokens`
override); all others reduce to a one-liner
- Add `pr_lint.yml` scope for the new `model-profiles` package
2026-03-23 00:44:27 -04:00
Mason Daugherty
5ffece5c03 chore(core): remove stale blockbuster allowlist for deleted context module (#36168)
Closes #29530

---

Remove a stale BlockBuster allowlist entry in `conftest.py` referencing
`aconfig_with_context` — the function and its containing module
(`langchain_core/beta/runnables/context.py`) were deleted in `fded6c6b1`
(Sep 2025, #32850). Spotted by @antonio-mello-ai in #29530.
2026-03-22 20:39:55 -04:00
ccurme
70c88c0e72 fix(core): trace invocation params in metadata (#36080) 2026-03-18 13:20:18 -04:00
Eugene Yurtsev
dd136337d7 feat(core): harden anti-ssrf (#35960)
harden anti-ssrf

---------

Co-authored-by: Mason Daugherty <mason@langchain.dev>
2026-03-18 10:41:43 -04:00
Mohammad Mohtashim
b21c0a8062 fix(core): preserve default_factory when generating tool call schema (#35550) 2026-03-08 15:34:21 -04:00
Mason Daugherty
61fd90a2f3 fix(core): extract usage metadata from serialized tracer message outputs (#35526)
Fixes missing `run.metadata.usage_metadata` population in
`LangChainTracer` for real LLM/chat traces following #34414

- Fix extraction to read usage from serialized tracer message shape:
`outputs.generations[*][*].message.kwargs.usage_metadata`
- Remove non-serialized direct message shape handling
(`message.usage_metadata`) from extractor to match real tracer output
path
- Clarify tracer docstrings around chat callback naming
(`on_chat_model_start` + shared `on_llm_end`) to reduce ambiguity

## Why

#34414 introduced usage duplication into `run.metadata.usage_metadata`,
but the extractor read `message.usage_metadata`.

In real tracer flow, messages are serialized with `dumpd(...)` during
run completion, so usage metadata lives under
`message.kwargs.usage_metadata`. Because of this mismatch, duplication
did not trigger in real traces.
2026-03-02 17:43:33 -05:00
Guofang.Tang
78678534f9 fix(core): treat empty tool chunk ids as missing in merge (#35414) 2026-02-24 18:12:49 -05:00
Tanzim Hossain Romel
2d1492a864 fix(core): improve error message for non-JSON-serializable tool schemas (#34376) 2026-02-22 17:32:00 -05:00
Balaji Seshadri
d6e46bb4b0 fix(core): improve typing/docs for on_chat_model_start to clarify required positional args (#35324) 2026-02-22 14:46:32 -05:00
yaowubarbara
5053436dcf fix(core): fix merge_lists incorrectly merging parallel tool calls (#35281) 2026-02-18 20:33:17 -05:00
Shivangi Sharma
3686bcbd96 fix(core): accept int temperature in _get_ls_params for LangSmith tracing (#35302) 2026-02-18 18:30:02 -05:00
ccurme
9c160e2368 revert: accept integer temperature values in _get_ls_params (#35319) 2026-02-18 18:19:28 -05:00
Balaji Seshadri
a9f3627229 fix(core): accept integer temperature values in _get_ls_params (#35317) 2026-02-18 17:52:13 -05:00
KarthikRed2000
a565cf85eb fix(core): prevent recursion error when args_schema is dict (#35260) 2026-02-17 17:47:17 -05:00
Mason Daugherty
ba3ad67328 fix(core): preserve index and timestamp fields when merging (#34731)
Porting https://github.com/langchain-ai/langchainjs/pull/9781
2026-02-17 11:29:41 -05:00
Christophe Bornet
b97c629f9a style: bump ruff version to 0.15 (#35042) 2026-02-12 19:34:02 -05:00
ccurme
16cabfa212 fix(core): fix setting ChatGeneration.text (#35191) 2026-02-12 15:43:53 -05:00
ccurme
2b4b1dc29a fix(openai): sanitize urls when counting tokens in images (#35143) 2026-02-10 15:25:10 -05:00
ccurme
e8e47b083e feat(core): count tokens from tool schemas in count_tokens_approximately (#35098) 2026-02-09 14:10:44 -05:00
ccurme
032d01dd0f fix(core): adjust cap when scaling approximate token counts (#35017) 2026-02-04 19:02:48 -05:00
ccurme
5981ee142c fix(core): apply cap when scaling approximate token counts (#35005) 2026-02-03 21:20:48 -05:00
ccurme
09654f4382 feat(core): allow scaling by reported usage when counting tokens approximately (#34996) 2026-02-03 15:19:18 -05:00
Mason Daugherty
ae5b50f37f test(core): increase delta_time for flaky test (#34982)
This regularly flaked
2026-02-02 13:33:15 -05:00
Nandana Dileep
ef067078b8 fix(core): fix nested mustache variable extraction and update docs (#34872) 2026-01-31 21:30:57 -05:00
Akshaya Shanbhogue
84864d77ed fix(core): allow base model annotations for empty model (#34932) 2026-01-31 20:49:02 -05:00
Louis Auneau
f5252b438e fix(core): google docstring parsing with no arguments/reserved arguments (#34861) 2026-01-30 22:48:58 -05:00
Lewis Whitehill
0c9d392d41 test(core): add tests for approximate token counting with multimodal messages (#34898) 2026-01-30 12:35:16 -08:00
zer0
6ff8436fb0 fix(core): raise outputparserexception for unknown tools (#34923) 2026-01-30 09:35:31 -08:00