llms/openai: sanitize HTTP errors to prevent API key exposure (#1393)
Fix security issue where context deadline errors could expose API keys and
sensitive request details in error messages. Added sanitizeHTTPError function
to detect context timeouts and network errors, then return generic error
messages without exposing sensitive information.
Changes:
- Added sanitizeHTTPError() function to sanitize HTTP client errors
- Updated chat.go to use sanitizeHTTPError() for http.Do() errors
- Updated embeddings.go to use sanitizeHTTPError() for http.Do() errors
- Added comprehensive test cases to prevent regression
* llms/openai: sanitize HTTP errors to prevent API key exposure (#1393)
Fix security issue where context deadline errors could expose API keys and
sensitive request details in error messages. Added sanitizeHTTPError function
to detect context timeouts and network errors, then return generic error
messages without exposing sensitive information.
Changes:
- Added sanitizeHTTPError() function to sanitize HTTP client errors
- Updated chat.go to use sanitizeHTTPError() for http.Do() errors
- Updated embeddings.go to use sanitizeHTTPError() for http.Do() errors
- Added comprehensive test cases to prevent regression
* agents: fix ChainCallOption silent failure (#1416)
Fix issue where ChainCallOption parameters were silently ignored by Executor.Call() and Agent implementations.
Changes:
- Updated Agent.Plan() interface signature to accept variadic ChainCallOption parameters
- Updated Executor.Call() to accept and propagate options to Agent.Plan()
- Updated Executor.doIteration() to propagate options through the chain
- Updated OneShotZeroAgent.Plan() to accept and pass options to chains.Predict()
- Updated ConversationalAgent.Plan() to accept and pass options to chains.Predict()
- Updated OpenAIFunctionsAgent.Plan() to accept and pass options to LLM.GenerateContent()
- Exported GetLLMCallOptions() function for option conversion (was getLLMCallOptions)
- Updated test mock to match new Agent interface signature
Now users can pass LLM configuration options (temperature, max tokens, etc.) through executors to agents.
llms/anthropic: add streaming thinking/reasoning token support
Implement StreamingReasoningFunc support in the Anthropic client to enable
real-time streaming of thinking tokens during extended thinking responses.
Changes:
- Add StreamingReasoningFunc field to messagePayload, MessageRequest structs
- Modify handleThinkingDelta() to call StreamingReasoningFunc when thinking
chunks arrive during streaming
- Wire up StreamingReasoningFunc from llms.CallOptions through to the
Anthropic client payload
- Update setMessageDefaults to enable streaming when StreamingReasoningFunc
is provided
This follows the same pattern as the OpenAI client (chat.go:638-663) and
enables thinking tokens to stream in real-time at the BEGINNING of the
response, rather than appearing after the response completes.
Fixes issue where thinking_delta events were not calling the streaming
reasoning callback, causing thinking content to only be available after
response completion.
* vectorstores/milvus: complete migration to new SDK v2 client (#1397)
Complete the migration from the archived milvus-sdk-go/v2 to the new
github.com/milvus-io/milvus/client/v2 SDK as tracked in issue #1397.
**New Implementation**:
- Add complete vectorstores/milvus/v2/ package with new SDK client
- Implement all core vectorstore operations (Add, Search, Delete, etc.)
- Add comprehensive test suite with unit and integration tests
- Include migration example and documentation
**Key Changes**:
- New milvus.go with updated client initialization and operations
- Updated options.go with v2 SDK configuration patterns
- Added example_migration.go demonstrating upgrade path
- Comprehensive README.md with migration guide
- Updated go.mod/go.sum with new SDK dependencies
**Documentation**:
- Add docs/package-lock.json for documentation build dependencies
- Provide clear migration path from v1 to v2 implementation
- Maintain backward compatibility where possible
This completes the migration work started in earlier commits and provides
a full replacement for the deprecated SDK while maintaining the same
vectorstore interface.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* style: apply gofmt formatting to v2 package files
* fix: remove unused async field from v2 Store struct
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Add Server-Sent Events (SSE) streaming support to JSONDebugClient
- Display HTTP request/response headers with sensitive value scrubbing
- Parse and highlight token usage from streaming API events
llms: update OpenAI model context sizes
Add support for latest OpenAI models with accurate context windows:
- GPT-4o and GPT-4o-mini: 128K tokens
- GPT-4 Turbo variants: 128K tokens
- GPT-3.5 Turbo: 16K tokens (corrected from 4K)
Includes comprehensive test coverage for all model variants.
Reference: https://platform.openai.com/docs/models
Co-authored-by: paulnegz <paulnegz@example.com>
examples: change maximum tokens from 104 to 1024 in openai_chat_example.go as it says in README.md of the example
Fixing a typo of llms.WithMaxtokens(104) to llms.WithMaxtokens(1024)
* docs: fix outdated API references and examples across documentation
Update documentation to reflect current API patterns and fix outdated code examples:
- Update Error struct definition with Provider and Details fields in architecture docs
- Fix code examples to use CallOptions (WithTemperature, WithMaxTokens) instead of constructor options
- Update chain execution pattern from chain.Run() to chains.Run()
- Add context parameter to memory interface methods
- Update Vertex AI examples to use new googleai/vertex package structure
- Change from vertexai.New() to vertex.New() with updated option names
- Fix import paths for Google AI and Vertex AI integration
- Update minimum Go version requirement from 1.21 to 1.23
These changes ensure documentation examples work with the current codebase and provide accurate guidance for developers.
* docs: expand integration documentation and fix remaining API references
- Add comprehensive examples to chat and embeddings integration pages
- Fix missing context imports in LLM provider configuration
- Update Vertex AI examples to use correct vertex.New() syntax
- Fix broken link in CloudSQL vectorstore README
- Transform placeholder pages into useful developer resources
* docs: fix relative link in embeddings integrations page
chore: update all examples to use v0.1.14-pre.4
- Remove replace directives from 5 examples that had local path references
- Update all 75 example go.mod files to use the latest pre-release version
- Ensures examples work correctly for users who clone the repository
docs: complete basic chat application tutorial with progressive examples
Completely rewrite the basic chat application tutorial with a structured, step-by-step approach:
**Tutorial Documentation**:
- Restructure tutorial into 6 clear progressive steps
- Add proper setup instructions and prerequisites
- Include code examples for each step with explanations
- Improve clarity and flow from basic to advanced concepts
**Complete Working Example**:
- Add `examples/tutorial-basic-chat-app/` with full implementation
- Include separate files for each tutorial step (step3-step6)
- Add comprehensive README with usage instructions
- Support multiple execution modes via command-line arguments
**Progressive Implementation Steps**:
- Step 3: Basic single-shot LLM interaction
- Step 4: Interactive chat loop without memory
- Step 5: Chat with manual conversation memory management
- Step 6: Advanced chat using chains with automatic memory
**Features Added**:
- Go module setup with proper dependencies
- Error handling and graceful exit functionality
- Multiple chat implementations demonstrating different approaches
- Clear documentation linking tutorial to working code
- Support for running individual steps or complete implementation
The tutorial now provides a complete learning path from basic LLM usage to sophisticated conversation management using LangChainGo's chains and memory systems.
* vectorstores/milvus: update deprecation notice for archived SDK
The Milvus SDK at github.com/milvus-io/milvus-sdk-go/v2 has been archived.
Updated the deprecation notice to inform users and reference issue #1334
which tracks the migration to the new SDK at github.com/milvus-io/milvus/client/v2.
The migration will be done in a way that maintains backward compatibility
to avoid breaking existing users.
Updates #1334
* vectorstores/milvus: update deprecation notice with archival date and issue reference
Add specific archival date (March 21, 2025) to the deprecation notice and clarify
that migration to the new SDK will require breaking changes in a future version.
Update issue reference from #1334 to #1397 for migration tracking.
Updates #1397
* llms: add prompt caching and reasoning token support
Add comprehensive infrastructure for prompt caching and reasoning/thinking tokens:
- Add ReasoningModel interface for models supporting extended reasoning
- Add CacheControl and CachedContent types for prompt caching
- Add ThinkingConfig with modes (none, low, medium, high, auto)
- Add token budget calculation and usage tracking for thinking tokens
- Add WithPromptCaching, WithThinking, and related call options
- Add model detection for reasoning-capable models (OpenAI o1/o3, Claude 3.7+, DeepSeek)
- Update options documentation for better provider compatibility notes
- Remove testify imports tracking file
Supports provider-specific implementations while maintaining consistent API.
* testing: add comprehensive LLM testing framework
Add standardized testing infrastructure for all LLM providers following Go's testing/fstest design philosophy:
- Add llmtest package with automatic capability discovery and parallel testing
- Add TestLLM function that probes and tests all supported LLM features
- Add provider-specific test files for all LLM implementations (anthropic, bedrock, cloudflare, cohere, ernie, fake, googleai, huggingface, llamafile, local, maritaca, mistral, ollama, openai, watsonx)
- Add comprehensive tests for prompt caching, reasoning tokens, and token utilization
- Add MockLLM implementation for testing without API calls
- Add ValidateLLM function for basic model validation
- Support automatic detection of streaming, tool calls, reasoning, and caching capabilities
The framework provides a simple API (TestLLM) that automatically discovers and tests all supported capabilities, enabling consistent testing across all provider implementations.
* llms: implement provider-specific prompt caching and reasoning support
Add comprehensive provider-specific implementations for prompt caching and reasoning tokens:
**Anthropic (Claude)**:
- Add prompt caching with ephemeral cache controls and beta headers
- Add extended thinking support for Claude 3.7+ with budget token configuration
- Add interleaved thinking for tool calls and 128K output support
- Add thinking content extraction from <thinking> tags
- Add cache token tracking (creation/read input tokens)
**Google AI (Gemini)**:
- Add CachingHelper for pre-created cached content management
- Add reasoning detection for Gemini 2.0+ models
- Add cached content support via metadata
- Add standardized token usage reporting with cache information
**Ollama**:
- Add ContextCache for in-memory conversation context caching
- Add reasoning support detection for DeepSeek R1, QwQ, and thinking models
- Add Think parameter support for reasoning-capable models
- Add cache statistics and hit/miss tracking
**OpenAI**:
- Add reasoning support detection for o1/o3 series and future GPT-5
- Add system message handling for models without system support (o1/o3)
- Add thinking content extraction and standardized token reporting
- Add metadata filtering to prevent internal fields from reaching API
- Add ReasoningEffort parameter preparation for future models
**Cross-provider features**:
- Implement ReasoningModel interface across all providers
- Add standardized GenerationInfo fields (ThinkingContent, ThinkingTokens, etc.)
- Add provider-specific options (WithPromptCaching, WithExtendedOutput, etc.)
- Add comprehensive test coverage for caching and reasoning features
- Add model capability detection and validation
All providers now support the unified prompt caching and reasoning interfaces while maintaining their specific implementation details and capabilities.
* examples: add comprehensive prompt caching and reasoning examples
Add practical examples demonstrating prompt caching and reasoning token features across multiple LLM providers:
**Anthropic Examples**:
- Add anthropic-extended-capabilities example showing combined extended thinking + 128K output
- Add anthropic-interleaved-thinking example demonstrating thinking between tool calls
- Show token budget management and thinking content extraction
- Include comprehensive README documentation for each example
**Multi-Provider Examples**:
- Add googleai-reasoning-caching example with Gemini 2.0+ reasoning and cached content
- Add ollama-reasoning-caching example with DeepSeek R1/QwQ models and context caching
- Add prompt-caching example showing Anthropic's 90% cost reduction on cached tokens
- Add reasoning-tokens example comparing o1-mini, Claude 3.7, and standard models
**Key Features Demonstrated**:
- Prompt caching for cost optimization and faster responses
- Reasoning/thinking tokens for improved response quality
- Token usage analysis and cache hit/miss tracking
- Provider-specific capabilities and configuration options
- Real-world use cases like data analysis, Q&A systems, and multi-step reasoning
All examples include detailed documentation, error handling, and clear output formatting to help developers understand and implement these advanced LLM features.
* gofmt: fix formatting in messages.go
- Add nil/bounds checks in OpenAI Functions Agent ParseOutput
- Handle multiple tool calls properly instead of just first one
- Fix Anthropic panic when content is nil or empty (fixes#993)
- Prevent index out of bounds errors in agent parsing
tools/scraper: fix context cancellation to prevent hanging
Fixes issue where web scraper would hang indefinitely even when
context was cancelled. The problem was that c.Wait() was called
unconditionally after checking context cancellation.
Changes:
- Wrap c.Wait() in goroutine with completion channel
- Use select statement to race context cancellation vs completion
- Ensures scraper properly respects context timeouts/cancellation
test: fix race conditions in httprr and azureaisearch tests
Add thread-safe access to global record flag in httprr package and prevent
tests that modify global state from running in parallel. Fix race condition
in Azure AI Search tests by properly capturing request counter in a local
variable before use.
examples/groq: add temporary replace directive
Add replace directive to use local langchaingo module. This ensures the example
works with the current codebase that includes the metadata filtering fix from
PR #1376.
The replace directive should be removed after the next release.
Update all example project go.mod files to reference v0.1.14-pre.3
instead of v0.1.14-pre.2. This ensures examples use the latest pre-release
version with recent fixes and improvements.
* embeddings/vertexai,memory: remove deprecated PaLM test and add recordings
Remove deprecated VertexAI PaLM embeddings test (PaLM API deprecated August 2024).
Add missing test recordings for memory/token buffer tests.
* vectorstores/redisvector: regenerate test recordings and compress
Regenerate test recordings for Docker container compatibility.
Compress large recordings (>50KB) with gzip for space efficiency.
* vectorstores/chroma: regenerate test recordings and compress
Regenerate test recordings for Docker container compatibility.
Compress large recordings (>50KB) with gzip for space efficiency.
* vectorstores/milvus: add deprecation notice and compress recordings
Add deprecation notice for Milvus vectorstore.
Compress test recordings with gzip for space efficiency.
* vectorstores/opensearch: regenerate test recordings and compress
Regenerate test recordings for Docker container compatibility.
Fix test to properly set up service_role for local tests.
Compress large recordings with gzip for space efficiency.
* vectorstores/weaviate: regenerate test recordings and compress
Regenerate test recordings for Docker container compatibility.
Compress large recordings (>50KB) with gzip for space efficiency.
* vectorstores/{pgvector,alloydb,cloudsql}: regenerate and compress recordings
Regenerate test recordings for Docker container compatibility.
Compress large recordings (>50KB) with gzip for space efficiency.
Covers pgvector, AlloyDB, and CloudSQL PostgreSQL vectorstores.
* tools/wikipedia: regenerate test recordings
Update test recordings with current Wikipedia API responses.
test: improve test resilience with better HTTP recording handling
Add hasExistingRecording helper to detect available recordings and skip tests
gracefully when recordings are unavailable. Replace generic credential checks
with specific recording validation and provide clear error messages.
* openai: omit temperature field for reasoning models
Adds special handling for GPT-5, o1, and o3 models that only accept default
temperature values. These reasoning models reject requests with non-default
temperature settings, causing API errors.
- Modify ChatRequest.MarshalJSON to omit temperature field for reasoning models
- Add isReasoningModel helper function to identify affected models
- Add comprehensive tests for temperature field handling and model detection"
* openai: update test recordings for temperature field handling
Update test recordings to reflect the new temperature field serialization behavior
implemented in the reasoning models fix. These recordings show the temperature
field correctly positioned at the end of request JSON objects, ensuring proper
omission when needed for GPT-5, o1, and o3 models.
* test: update OpenAI test recordings
Re-record OpenAI package test recordings to match updated JSON field
ordering from the temperature field positioning changes.
Update all example project go.mod files to reference v0.1.14-pre.2
instead of v0.1.14-pre.1. This ensures examples use the latest pre-release
version with recent fixes and improvements.
Add comprehensive support for token limits in OpenAI API requests:
- Add WithMaxCompletionTokens() option for explicitly setting the modern field
- Add WithLegacyMaxTokensField() option for compatibility with older servers
- Implement custom JSON marshaling to prevent both fields being sent simultaneously
- Add documentation explaining token limit options and best practices
- Add comprehensive tests for serialization behavior and option handling
This implementation properly handles both max_tokens (legacy) and
max_completion_tokens (modern) fields while preventing API errors
from sending both fields at once.
* build: add examples-updater tool and update examples to v0.1.14-pre.1
Add a new tool to automate updating langchaingo version references in example
projects and use it to update all examples to v0.1.14-pre.1. The tool also
removes temporary replace directives that are no longer needed.
- Add update-examples Makefile target that runs the new tool
- Create internal/devtools/examples-updater implementation
- Update all example go.mod files to reference v0.1.14-pre.1
- Remove replace directives in googleai and vertex examples
- Update dependencies in main go.mod/go.sum
* httprr: improve header normalization and test container setup
Add header normalization to make HTTP recordings more stable:
- Add normalizeGoogleAPIClientHeader and normalizeVersionHeader functions
- Normalize User-Agent, x-goog-api-client and other version headers
- Remove OpenAI-Project header for consistency
- Preserve body for both replay lookup and recording
- Add comprehensive tests for header normalization
Improve testcontainer environment detection:
- Better handling of non-standard Docker socket paths
- Disable Ryuk reaper by default for resource efficiency
- Add verbose logging option via environment variable
* httputil: add ApiKeyTransport for query parameter API keys
Add a reusable ApiKeyTransport that adds API keys to URL query parameters:
- Create ApiKeyTransport implementation in httputil package
- Add comprehensive tests for the new transport
- Refactor googleai_test.go to use the shared transport
- Update chains/llm_test.go to use ApiKeyTransport with proper key scrubbing
This improves how API keys are handled with client libraries that don't
properly set keys when using custom HTTP clients, particularly useful
with httprr for testing Google API integrations.
* openai: remove duplicate MaxTokens field assignment
Remove redundant assignment where both MaxTokens and MaxCompletionTokens
were being set to the same value. MaxCompletionTokens is the preferred
field name that reflects OpenAI's API changes, while MaxTokens was
previously kept for backward compatibility.
* vectorstores/maridadb: add test infrastructure for MariaDB vectorstore
Add TestMain function for MariaDB vectorstore tests that ensures the proper
test environment is set up using the testctr package. This enables consistent
test container setup and teardown for MariaDB integration tests.
* all: normalize all httprr recordings for consistency
Update test recordings across all packages to use normalized headers:
- Standardize User-Agent to 'langchaingo-httprr'
- Normalize version information in x-goog-api-client headers
- Remove OpenAI-Project headers for consistency
- Fix deprecated Anthropic completion API tests
- Update HuggingFace test recordings with valid responses
These changes make test recordings stable across dependency updates
and different environments, preventing test failures from version changes.
* devtools: add utility tool for normalizing httprr test recordings
Add a command-line tool that standardizes version information in httprr recordings:
- Normalizes x-goog-api-client headers to use placeholder versions
- Standardizes x-amz-user-agent headers for consistency
- Replaces Go version strings with generic placeholders
- Supports dry-run mode to preview changes without modifying files
- Includes verbose output option for detailed change reporting
This tool helps maintain consistent test recordings across different environments
and dependency versions, preventing test failures from version changes.
* llms/openai: update OpenAI embedding test to use text-embedding-3-small model
Update the embedding test to use the current text-embedding-3-small model:
- Change model from text-embedding-ada-002 to text-embedding-3-small
- Adjust dimensions parameter from 1234 to 256 to match model capabilities
- Update test recording with appropriate response data
This change ensures tests remain compatible with OpenAI's current embedding
models and prevents test failures from API version changes.
* hook up anthropic tool calls to bedrock
* standardize anthropic bedrock tool calling constants and tests
* add integration tests for bedrock anthropic tool calling
* clean up bedrock anthropic tool integration test formatting
* suppress function length linter warnings in bedrock tool tests
Add //nolint:funlen directives to TestBedrockWithTools and
TestBedrockToolCallMultipleIterations to prevent linter warnings
about function length while maintaining comprehensive test coverage.
---------
Co-authored-by: Ryan Kois <ryank@runreveal.com>
* bedrock anthropic tool calling support
* bedrock: add comprehensive tool calling tests and fix test type usage
- Add integration tests for single and multi-iteration tool calling workflows
- Fix test expectations to match new function/tool role support
- Use proper anthropicContentBlock type instead of inline structs
- Add weather and search tool testing scenarios
* fix: bedrock LLM add modelProvider to resolve "unsupported provider"
* fix: remove version 2 config for golangci-lint v1 compatibility
* Revert "fix: remove version 2 config for golangci-lint v1 compatibility"
This reverts commit fe27edcb4c850a8796a703aa70ca69674a2ed244.
* fix go ci test
---------
Co-authored-by: Dreamans <dreamans@163.com>
- Add WithModelProvider option to explicitly set provider for edge cases
- Improve provider detection to handle Nova models and inference profiles
- Add comprehensive unit tests for Nova provider detection
- Add bedrock-provider-example demonstrating usage
- Fix CreateCompletion to accept optional provider parameter
This allows users to specify the provider explicitly when automatic
detection doesn't work correctly (e.g., custom inference endpoints),
and adds full support for Amazon Nova models.
Fixes: #1345
Co-authored-by: Travis Cline <travis.cline@gmail.com>
llms/anthropic: add tool support for streaming responses
Add support for input_json_delta events in streaming API responses to
properly handle tool use during streaming. The implementation includes:
- Handle input_json_delta events in parseStreamingMessageResponse
- Add handleJSONDelta function for accumulating partial JSON data
- Improve error messages with type information for debugging
- Add comprehensive tests for streaming with tool use scenarios
This enables proper tool calling functionality when using Anthropic's
streaming API, ensuring partial JSON tool inputs are correctly
accumulated and parsed.
Co-authored-by: Travis Cline <travis.cline@gmail.com>
* openaiclient: add dimensions option while creating embeddings
* openaiclient: fix dimensions json tag in embeddings payload
Fix the JSON struct tag for the Dimensions field in embeddingPayload from
"omitzero" to the correct "omitempty". This ensures the dimensions parameter
is properly omitted from API requests when not specified.
* openaiclient: fix test name for dimensions test case
Correct the test name from "without dimensions" to "with dimensions" in
TestMakeEmbeddingRequest to accurately reflect the test's purpose. This
ensures the test name properly describes that it's testing the behavior
with dimensions specified, not without.
---------
Co-authored-by: Travis Cline <travis.cline@gmail.com>
Add proper handling for SSE comment lines (starting with ':') and other
non-data fields in streaming responses according to the SSE specification.
The implementation now explicitly checks for "data:" prefixes before
processing lines, improving compatibility with various providers.
Add comprehensive tests for different SSE comment patterns including
OpenRouter comments, comments without spaces, and other SSE fields.
* llms: fix memory leaks by adding Close methods and improving goroutine handling
Add Close methods to GoogleAI and Vertex clients to properly clean up resources
and prevent memory leaks from underlying gRPC connections. Update examples to
demonstrate proper client cleanup with defer statements.
Improve goroutine management in OpenAI streaming response handling with proper
context cancellation and non-blocking channel operations to prevent goroutine
leaks in error scenarios.
* examples: add replace directives for testing memory leak fixes
Add temporary replace directives to GoogleAI and Vertex example go.mod files
to test the Close() method changes from the previous commit. These directives
allow the examples to use the local version of the library with the memory
leak fixes before they're included in the next release.
* agents: improve robustness of MRKL and OpenAI Functions agents
Enhance agent implementations with more flexible output parsing and better tool handling:
- Add case-insensitive "Final Answer" detection with multiple variations
- Improve regex patterns for action/input extraction in MRKL agent
- Refactor OpenAI Functions agent to properly handle parallel tool calls
- Enhance tool response grouping and formatting in conversation history
- Fix whitespace handling in agent outputs
These changes make both agents more resilient to variations in model outputs.
* agents: fix linting issues
- Remove unused mrkl_improved.go file
- Fix gofmt formatting in mrkl.go and openai_functions_agent.go
- Clean up whitespace inconsistencies
* vectorstores: add MariaDB and Dolt vector store implementations
Add new vector store implementations for MariaDB and Dolt databases.
Both support similarity search with metadata filtering and score thresholds.
From PR #1147
Co-authored-by: Dustin Brown <coffeegoddd@users.noreply.github.com>
* go.mod: update testcontainers for MariaDB vector store tests
Update testcontainers-go and testcontainers-go/modules/mariadb to v0.38.0
for MariaDB vector store test support.
* vectorstores: fix database handling in MariaDB and Dolt implementations
Change value receivers to pointer receivers for init() and createOrGetDatabase()
methods to ensure proper state updates. Refactor database creation logic to first
check if database exists before creating or updating, replacing the previous
INSERT ON DUPLICATE KEY approach with a more explicit flow.
---------
Co-authored-by: Dustin Brown <coffeegoddd@users.noreply.github.com>