Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
## [Unreleased]

### Fixed
- **Citation validation**: Preserve LLM-provided citations when a validation context does not include source text, instead of raising a `TypeError`.
- **v2 message handling**: Preserve caller-owned message lists and nested content across request preparation and retries for OpenAI-compatible, Cohere, Mistral, OpenRouter, Writer, and xAI handlers. ([#2417](https://github.com/567-labs/instructor/issues/2417), [#2428](https://github.com/567-labs/instructor/issues/2428))
- **v2 JSON extraction**: Prefer the final complete top-level JSON value in text responses and retain every JSON object when multiple objects arrive in one streaming chunk.
- **v2 schemas**: Treat fields with Pydantic `default_factory` values as optional in generated OpenAI tool schemas.
Expand Down
2 changes: 2 additions & 0 deletions instructor/v2/dsl/citation.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def validate_sources(self, info: ValidationInfo) -> "CitationMixin":

# Get the context from the info
text_chunks = info.context.get("context", None)
if text_chunks is None:
return self

# Get the spans of the substring_phrase in the context
spans = list(self.get_spans(text_chunks))
Expand Down
11 changes: 11 additions & 0 deletions tests/coverage/test_dsl_small_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ def test_citation_keeps_quotes_without_context_and_recovers_fuzzy_quotes() -> No
assert list(cited.get_spans(context)) == [(21, 42)]


def test_citation_keeps_quotes_when_validation_context_lacks_context_key() -> None:
quotes = ["Jaxon is 20 years old"]

cited = Claim.model_validate(
{"fact": "age", "substring_quotes": quotes},
context={"request_id": "req_123"},
)

assert cited.substring_quotes == quotes


@pytest.mark.parametrize(
("value", "complete"),
[("", False), (" \n\t", False), ('{"ok": true}', True), ('{"ok":', False)],
Expand Down