* Remove integration markers from database tests
Removed @pytest.mark.integration from database tests to allow them to run
while excluding API integration tests that call external services.
Database tests (now run):
- tests/test_edge_int.py
- tests/test_graphiti_int.py
- tests/test_node_int.py
- tests/test_entity_exclusion_int.py
- tests/cross_encoder/test_bge_reranker_client_int.py
- tests/driver/test_falkordb_driver.py
API integration tests (excluded):
- tests/llm_client/test_anthropic_client_int.py
- tests/utils/maintenance/test_temporal_operations_int.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Apply ruff formatting to falkordb driver and node queries
- Quote style fixes in falkordb_driver.py
- Trailing whitespace cleanup in node_db_queries.py
- Update uv.lock
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove api-integration-tests job from CI workflow
The api-integration-tests job has been removed since API integration tests
are now excluded via @pytest.mark.integration marker.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix database-integration-tests to run all database tests
Previously only ran test_graphiti_mock.py, now runs all database tests:
- tests/test_graphiti_mock.py
- tests/test_graphiti_int.py
- tests/test_node_int.py
- tests/test_edge_int.py
- tests/test_entity_exclusion_int.py
- tests/cross_encoder/test_bge_reranker_client_int.py
- tests/driver/test_falkordb_driver.py
The -m "not integration" filter excludes API integration tests that call
external services (Anthropic, OpenAI, etc).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Restore integration markers for tests that call LLM APIs
test_graphiti_int.py and test_entity_exclusion_int.py call graphiti.add_episode()
and graphiti.search_() which require LLM API calls, so they are API integration
tests, not pure database tests.
Final categorization:
Pure unit tests (no external dependencies):
- tests/llm_client/test_*.py (except test_anthropic_client_int.py)
- tests/embedder/test_*.py
- tests/utils/maintenance/test_*.py (except test_temporal_operations_int.py)
- tests/utils/search/search_utils_test.py
- tests/test_text_utils.py
Database tests (require Neo4j/FalkorDB, no API calls):
- tests/test_graphiti_mock.py
- tests/test_node_int.py
- tests/test_edge_int.py
- tests/cross_encoder/test_bge_reranker_client_int.py
- tests/driver/test_falkordb_driver.py
API integration tests (excluded via @pytest.mark.integration):
- tests/test_graphiti_int.py
- tests/test_entity_exclusion_int.py
- tests/llm_client/test_anthropic_client_int.py
- tests/utils/maintenance/test_temporal_operations_int.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Separate unit and integration tests to allow external contributors
This change addresses the issue where external contributor PRs fail unit
tests because GitHub secrets (API keys) are unavailable to external PRs
for security reasons.
Changes:
- Split GitHub Actions workflow into two jobs:
- unit-tests: Runs without API keys or database connections (all PRs)
- integration-tests: Runs only for internal contributors with API keys
- Renamed test_bge_reranker_client.py to test_bge_reranker_client_int.py
to follow naming convention for integration tests
- Unit tests now skip all tests requiring databases or API keys
- Integration tests properly separated into:
- Database integration tests (no API keys)
- API integration tests (requires OPENAI_API_KEY, etc.)
The unit-tests job now:
- Runs for all PRs (internal and external)
- Requires no GitHub secrets
- Disables all database drivers
- Excludes all integration test files
- Passes 93 tests successfully
The integration-tests job:
- Only runs for internal contributors (same repo PRs or pushes to main)
- Has access to GitHub secrets
- Tests database operations and API integrations
- Uses conditional: github.event.pull_request.head.repo.full_name == github.repository
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Separate database tests from API integration tests
Restructured the workflow into three distinct jobs:
1. unit-tests: Runs on all PRs, no external dependencies (93 tests)
- No API keys required
- No database connections required
- Fast execution
2. database-integration-tests: Runs on all PRs with databases (NEW)
- Requires Neo4j and FalkorDB services
- No API keys required
- Tests database operations without external API calls
- Includes: test_graphiti_mock.py, test_falkordb_driver.py,
and utils/maintenance tests
3. api-integration-tests: Runs only for internal contributors
- Requires API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
- Conditional execution for same-repo PRs only
- Tests that make actual API calls to LLM providers
This ensures external contributor PRs can run both unit tests and
database integration tests successfully, while API integration tests
requiring secrets only run for internal contributors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Disable Kuzu in CI database integration tests
Kuzu requires downloading extensions from external URLs which fails in CI
environment due to network restrictions. Disable Kuzu for database and API
integration tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use pytest -k filter to skip Kuzu tests instead of DISABLE_KUZU
The original workflow used -k "neo4j" to filter tests. Kuzu requires
downloading FTS extensions from external URLs which fails in CI. Use
-k "neo4j or falkordb" to run tests against available databases while
skipping Kuzu parametrized tests.
This maintains the same test coverage as the original workflow while
properly separating unit, database, and API integration tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Upgrade Kuzu to v0.11.3+ to fix FTS extension download issue
Kuzu v0.11.3+ has FTS extension pre-installed, eliminating the need to
download it from external URLs. This fixes the "Could not establish
connection" error when trying to download libfts.kuzu_extension in CI.
Changes:
- Upgrade kuzu dependency from >=0.11.2 to >=0.11.3
- Remove pytest -k filters to run all database tests (Neo4j, FalkorDB, Kuzu)
- FTS extension is now available immediately without network calls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Move pure unit tests from database integration to unit test job
The reviewer correctly identified that test_bulk_utils.py,
test_edge_operations.py, and test_node_operations.py are pure unit tests
using only mocks - they don't require database connections.
Changes:
- Removed tests/utils/maintenance/ from ignore list (too broad)
- Added specific ignore for test_temporal_operations_int.py (true integration test)
- Moved test_bulk_utils.py, test_edge_operations.py, test_node_operations.py to unit tests
- Kept test_graphiti_mock.py in database integration (uses real graph_driver fixture)
This reduces database integration test time and properly categorizes tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Skip flaky LLM-based tests in test_temporal_operations_int.py
- test_get_edge_contradictions_multiple_existing
- test_invalidate_edges_partial_update
These tests rely on OpenAI LLM responses for edge contradiction detection and produce non-deterministic results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use pytest -k filter for API integration tests
Replace explicit file listing with `pytest tests/ -k "_int"` to automatically discover all integration tests in any subdirectory. This improves maintainability by eliminating the need to manually update the workflow when adding new integration test files.
Excludes:
- tests/driver/ (runs separately in database-integration-tests)
- tests/test_graphiti_mock.py (runs separately in database-integration-tests)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Rename workflow from "Unit Tests" to "Tests"
The workflow now runs multiple test types (unit, database integration, and API integration), so "Tests" is a more accurate name.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Refactor prompt structure: move MESSAGES after instructions
Reordered prompt structure in extract_nodes.py to place MESSAGES section
after instructions/guidelines in both extract_attributes and extract_summary
functions for improved prompt clarity.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add sentence-aware text truncator for entity summaries
- Created truncate_at_sentence() utility function that truncates text at
sentence boundaries while respecting max character limits
- Added MAX_SUMMARY_CHARS constant (250 chars) for entity summaries
- Applied truncator to entity summaries in prompts (extract_nodes.py)
- Applied truncator to LLM-generated summaries (node_operations.py)
- Added comprehensive test suite for truncation logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Clean up formatting in extract_attributes prompt
- Remove extra blank lines
- Fix indentation of MESSAGES tag
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Bump version to 0.22.0pre3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Remove ensure_ascii configuration parameter
- Changed to_prompt_json default from ensure_ascii=True to False
- Removed ensure_ascii parameter from Graphiti.__init__ and GraphitiClients
- Removed ensure_ascii from all function signatures and context dictionaries
- Removed ensure_ascii from all test files
- All JSON serialization now preserves Unicode characters by default
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* format
---------
Co-authored-by: Claude <noreply@anthropic.com>
Add NodeSummaryFilter callback parameter to extract_attributes_from_nodes
and extract_attributes_from_node functions, allowing consumers to
selectively skip summary regeneration for specific nodes.
This enables downstream applications to implement custom logic for
throttling or filtering which nodes should have summaries regenerated,
reducing unnecessary LLM calls and token costs.
Key changes:
- Add NodeSummaryFilter type alias: Callable[[EntityNode], Awaitable[bool]]
- Update extract_attributes_from_nodes with optional should_summarize_node parameter
- Update extract_attributes_from_node with conditional summary generation logic
- Add 5 comprehensive test cases covering callback functionality
- Maintain full backwards compatibility (default None = all summaries generated)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* fix: Prevent duplicate edge facts within same episode
This fixes three related bugs that allowed verbatim duplicate edge facts:
1. Fixed LLM deduplication: Changed related_edges_context to use integer
indices instead of UUIDs, matching the EdgeDuplicate model expectations.
2. Fixed batch deduplication: Removed episode skip in dedupe_edges_bulk
that prevented comparing edges from the same episode. Added self-comparison
guard to prevent edge from comparing against itself.
3. Added fast-path deduplication: Added exact string matching before parallel
processing in resolve_extracted_edges to catch within-episode duplicates
early, preventing race conditions where concurrent edges can't see each other.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: Add tests for edge deduplication fixes
Added three tests to verify the edge deduplication fixes:
1. test_dedupe_edges_bulk_deduplicates_within_episode: Verifies that
dedupe_edges_bulk now compares edges from the same episode after
removing the `if i == j: continue` check.
2. test_resolve_extracted_edge_uses_integer_indices_for_duplicates:
Validates that the LLM receives integer indices for duplicate
detection and correctly processes returned duplicate_facts.
3. test_resolve_extracted_edges_fast_path_deduplication: Confirms that
the fast-path exact string matching deduplicates identical edges
before parallel processing, preventing race conditions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: Remove unused variables flagged by ruff
- Remove unused loop variable 'j' in bulk_utils.py
- Remove unused return value 'edges_by_episode' in test
- Replace unused 'edge_uuid' with '_' in test loop
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* chore: Update dependencies and enhance edge resolution logic
- Add new dependencies: boto3, opensearch-py, and langchain-aws to pyproject.toml.
- Modify Graphiti class to handle additional parameters in edge resolution.
- Improve edge type handling in deduplication logic by introducing custom edge type names.
- Enhance tests for edge resolution to cover new scenarios and ensure correct behavior.
This update improves the flexibility and functionality of edge operations while ensuring compatibility with new libraries.
* refactor: Clean up test_edge_operations.py and format response returns
- Remove unnecessary stubs for opensearchpy module.
- Format return values in llm_client.generate_response for consistency.
- Enhance readability by ensuring proper indentation and structure in test cases.
This refactor improves the clarity and maintainability of the test suite for edge operations.
* bump version to 0.30.0pre5 and enhance docstring for resolve_extracted_edge function
- Update version in pyproject.toml to 0.30.0pre5.
- Add detailed docstring to resolve_extracted_edge function in edge_operations.py, clarifying parameters and return values.
This update improves documentation clarity for the edge resolution process.
* fix: Add edge type validation based on node labels
- Add DEFAULT_EDGE_NAME constant for 'RELATES_TO'
- Implement pre-resolution validation to reset invalid edge names
- Add post-resolution validation for LLM-returned fact types
- Rename parameter from edge_types to edge_type_candidates for clarity
- Add comprehensive tests for validation scenarios
This ensures edges conform to edge_type_map constraints and prevents
misclassification when edge types don't match node label pairs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: Bump version to 0.30.0pre4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Refactor deduplication logic to enhance node resolution and track duplicate pairs (#929)
* Simplify deduplication process in bulk_utils by reusing canonical nodes.
* Update dedup_helpers to store duplicate pairs during resolution.
* Modify node_operations to append duplicate pairs when resolving nodes.
* Add tests to verify deduplication behavior and ensure correct state updates.
* reveret to concurrent dedup with fanout and then reconcilation
* add performance note for deduplication loop in bulk_utils
* enhance deduplication logic in bulk_utils to handle missing canonical nodes gracefully
* Update graphiti_core/utils/bulk_utils.py
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* refactor deduplication logic in bulk_utils to use directed union-find for canonical UUID resolution
* implement _build_directed_uuid_map for efficient UUID resolution in bulk_utils
* document directed union-find lookup in bulk_utils for clarity
---------
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* add repository guidelines and project structure documentation
* update neo4j image version and modify test command to disable specific databases
* implement deduplication helpers and integrate with node operations
* refactor string formatting to use single quotes in node operations
* enhance deduplication helpers with UUID indexing and update resolution logic
* implement exact fact matching (#931)
* gpt-5-mini and gpt-5-nano default
* bump version
* remove unused imports
* linter
* update
* disable neptune errors while we get a fixture in place
* update pyright
* revert non-structured completions
* fix typo
* Prepare code
* Fix tests
* As -> AS, remove trailing spaces
* Enable more tests for FalkorDB
* Fix more cypher queries
* Return all created nodes and edges
* Add Neo4j service to unit tests workflow
- Introduced Neo4j as a service in the GitHub Actions workflow for unit tests.
- Configured Neo4j with appropriate ports, authentication, and health checks.
- Updated test steps to include waiting for Neo4j and running integration tests against it.
- Set environment variables for Neo4j connection in both non-integration and integration test steps.
* Update Neo4j authentication in unit tests workflow
- Changed Neo4j authentication password from 'test' to 'testpass' in the GitHub Actions workflow.
- Updated health check command to reflect the new password.
- Ensured consistency across all test steps that utilize Neo4j credentials.
* fix health check
* Fix Neo4j integration tests in CI workflow
Remove reference to non-existent test_neo4j_driver.py file from test command.
Integration tests now run via parametrized tests using the drivers list.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add OPENAI_API_KEY to Neo4j integration tests
Neo4j integration tests require OpenAI API access for LLM functionality.
Add the secret environment variable to enable these tests to run properly.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Neo4j Cypher syntax error in BFS search queries
Replace parameter substitution in relationship pattern ranges (*1..$depth)
with direct string interpolation (*1..{bfs_max_depth}). Neo4j doesn't allow
parameter maps in MATCH pattern ranges - they must be literal values.
Fixed in both node_bfs_search and edge_bfs_search functions.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix variable name mismatch in edge_bfs_search query
Change relationship variable from 'r' to 'e' to match ENTITY_EDGE_RETURN
constant expectations. The ENTITY_EDGE_RETURN constant references variable
'e' for relationships, but the query was using 'r', causing "Variable e
not defined" errors.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Isolate database tests in CI workflow
- FalkorDB tests: Add DISABLE_NEO4J=1 and remove Neo4j env vars
- Neo4j tests: Keep current setup without DISABLE_NEO4J flag
This ensures proper test isolation where each test suite only runs
against its intended database backend.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Siddhartha Sahu <sid@kuzudb.com>
Co-authored-by: Claude <noreply@anthropic.com>
* graphiti-graph-name
* fix-lint
* fix-unittest
* clone-update
* groupid-none
* groupid-def-fulltext
* lint
* Remove redundant function definition for fulltext_query in search_utils.py
* Refactor get_default_group_id function and remove redundant code in falkordb_driver and search_utils. Added import statement in driver.py.
* Refactor test cases in test_falkordb_driver.py for improved readability by consolidating multi-line assertions into single lines. No functional changes made.
* Refactor fulltext_query function in search_utils.py to use double quotes for group_id in the filter list, enhancing consistency in query syntax.
* Remove duplicate assignment of fuzzy_query in episode_fulltext_search function in search_utils.py to eliminate redundancy.
* Remove duplicate assignment of fuzzy_query in community_fulltext_search function in search_utils.py to streamline code.
---------
Co-authored-by: Gal Shubeli <galshubeli93@gmail.com>
* feat: enhance GeminiClient with max tokens management
- Introduced a mapping for maximum output tokens for various Gemini models.
- Added methods to resolve max tokens based on precedence rules, allowing for more flexible token management.
- Updated tests to verify max tokens behavior, ensuring explicit parameters take precedence and fallback mechanisms work correctly.
This change improves the handling of token limits for different models, enhancing the client’s configurability and usability.
* refactor: streamline max tokens retrieval in GeminiClient
- Removed the fallback to DEFAULT_MAX_TOKENS in favor of directly using model-specific maximum tokens.
- Simplified the logic for determining max tokens, enhancing code clarity and maintainability.
This change improves the efficiency of token management within the GeminiClient.
* feat(gemini): embedding batch size & lite default
The new `gemini-embedding-001` model only allows one embedding input per batch
(instance), but has other impressive statistics:
https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text-embeddings-api
The -DEFAULT_SMALL_MODEL must not have the 'models/' prefix.
* Refactor: Improve Gemini Client Error Handling and Reliability
This commit introduces several improvements to the Gemini client to enhance its robustness and reliability.
- Implemented more specific error handling for various Gemini API responses, including rate limits and safety blocks.
- Added a JSON salvaging mechanism to gracefully handle incomplete or malformed JSON responses from the API.
- Introduced detailed logging for failed LLM generations to simplify debugging and troubleshooting.
- Refined the Gemini embedder to better handle empty or invalid embedding responses.
- Updated and corrected tests to align with the improved error handling and reliability features.
* fix: cleanup in _log_failed_generation()
* fix: cleanup in _log_failed_generation()
* Fix ruff B904 error in gemini_client.py
* fix(gemini): correct retry logic and enhance error logging
Updated the retry mechanism in the GeminiClient to ensure it retries the maximum number of times specified. Improved error logging to provide clearer insights when all retries are exhausted, including detailed information about the last error encountered.
* fix(gemini): enhance error handling for safety blocks and update tests
Refined error handling in the GeminiClient to improve detection of safety block conditions. Updated test cases to reflect changes in exception messages and ensure proper retry logic is enforced. Enhanced mock responses in tests to better simulate real-world scenarios, including handling of invalid JSON responses.
* revert default gemini to text-embedding-001
---------
Co-authored-by: Daniel Chalef <131175+danielchalef@users.noreply.github.com>
* fix: remove global DEFAULT_DATABASE usage in favor of driver-specific
config
Fixes bugs introduced in PR #607. This removes reliance on the global
DEFAULT_DATABASE environment variable. It specifies the database within
each driver. PR #607 introduced a Neo4j compatability, as the database
names are different when attempting to support FalkorDB.
This refactor improves compatability across database types and ensures
future reliance by isolating the configuraiton to the driver level.
* fix: make falkordb support optional
This ensures that the the optional dependency and subsequent import is compliant with the graphiti-core project dependencies.
* chore: fmt code
* chore: undo changes to uv.lock
* fix: undo potentially breaking changes to drive interface
* fix: ensure a default database of "None" is provided - falling back to internal default
* chore: ensure default value exists for session and delete_all_indexes
* chore: fix typos and grammar
* chore: update package versions and dependencies in uv.lock and bulk_utils.py
* docs: update database configuration instructions for Neo4j and FalkorDB
Clarified default database names and how to override them in driver constructors. Updated testing requirements to include specific commands for running integration and unit tests.
* fix: ensure params defaults to an empty dictionary in Neo4jDriver
Updated the execute_query method to initialize params as an empty dictionary if not provided, ensuring compatibility with the database configuration.
---------
Co-authored-by: Urmzd <urmzd@dal.ca>
* add support for Gemini 2.5 model thinking budget
* allow adding thinking config to support current and future gemini models
* merge
* improve client; add reranker
* refactor: change type hint for gemini_messages to Any for flexibility
* refactor: update GeminiRerankerClient to use direct relevance scoring and improve ranking logic. Add tests
* fix fixtures
---------
Co-authored-by: realugbun <github.disorder751@passmail.net>
* migrate to pyright
* Refactor type checking to use Pyright, update dependencies, and clean up code.
- Replaced MyPy with Pyright in configuration files and CI workflows.
- Updated `pyproject.toml` and `uv.lock` to reflect new dependencies and versions.
- Adjusted type hints and fixed minor code issues across various modules for better compatibility with Pyright.
- Added new packages `backoff` and `posthog` to the project dependencies.
* Update CI workflows to install all extra dependencies for type checking and unit tests
* Update dependencies in uv.lock to replace MyPy with Pyright and add nodeenv package. Adjust type hinting in config.py for compatibility with Pyright.
* remove temporary debug logging
* add anthropic api to .env.example
* move anthropic int tests to llm_client dir to better match existing test structure
* update `TestLLMClient` to `MockLLMClient` to eliminate pytest warning
* update Anthropic client to use tool calling and add tests
* fix linting errors before creating pull request by making literal types for anthropic models