{"id":28014141,"url":"https://github.com/cohesion-org/deepseek-go","last_synced_at":"2025-05-10T03:01:33.461Z","repository":{"id":265767805,"uuid":"896252863","full_name":"cohesion-org/deepseek-go","owner":"cohesion-org","description":"A Deepseek client written for Go supporting R-1, Chat V3, and Coder. Supports providers like Azure, OpenRouter and others. ","archived":false,"fork":false,"pushed_at":"2025-04-17T02:38:04.000Z","size":367,"stargazers_count":267,"open_issues_count":5,"forks_count":26,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-17T15:52:27.539Z","etag":null,"topics":["api","deepseek","go","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cohesion-org.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-29T22:08:49.000Z","updated_at":"2025-04-17T14:31:44.000Z","dependencies_parsed_at":"2025-02-15T19:27:33.923Z","dependency_job_id":"40e6e40d-7755-4a88-946f-be2b112bbb26","html_url":"https://github.com/cohesion-org/deepseek-go","commit_stats":null,"previous_names":["cohesion-org/deepseek-go"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cohesion-org%2Fdeepseek-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cohesion-org%2Fdeepseek-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cohesion-org%2Fdeepseek-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cohesion-org%2Fdeepseek-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cohesion-org","download_url":"https://codeload.github.com/cohesion-org/deepseek-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253356253,"owners_count":21895670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","deepseek","go","golang"],"created_at":"2025-05-10T03:01:01.340Z","updated_at":"2025-05-10T03:01:33.424Z","avatar_url":"https://github.com/cohesion-org.png","language":"Go","funding_links":[],"categories":["Large Language Model"],"sub_categories":["SDKs"],"readme":"# Deepseek-Go\n\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) \n[![Go Report Card](https://goreportcard.com/badge/github.com/cohesion-org/deepseek-go)](https://goreportcard.com/report/github.com/cohesion-org/deepseek-go)\n\nDeepseek-Go is a Go-based API client for the [Deepseek](https://deepseek.com) platform. It provides a clean and type-safe interface to interact with Deepseek's AI features, including chat completions with streaming, token usage tracking, and more.\n\n\n## Installation\n\n```sh\ngo get github.com/cohesion-org/deepseek-go\n```\ndeepseek-go currently uses `go 1.24.0`\n\n## Features\n\n- **Chat Completion**: Easily send chat messages and receive responses from Deepseek's AI models. It also supports streaming.\n- **Modular Design**: The library is structured into reusable components for building, sending, and handling requests and responses.\n- **External Providers**: Deepseek-go also supports external providers like OpenRouter, Azure, and even Ollama. \n- **MIT License**: Open-source and free for both personal and commercial use.\n\nThe recent gain in popularity and cybersecurity issues Deepseek has seen makes for many problems while using the API. Please refer to the [status](https://status.deepseek.com/) page for the current status.\n\n## Getting Started\n\nHere's a quick example of how to use the library:\n\n### Prerequisites\n\nBefore using the library, ensure you have:\n- A valid Deepseek API key.\n- Go installed on your system.\n\n### Supported Models\n\n- **deepseek-chat**  \n  A versatile model designed for conversational tasks. \u003cbr/\u003e\n  Usage: `Model: deepseek.DeepSeekChat`\n\n- **deepseek-reasoner**  \n  A specialized model for reasoning-based tasks.  \n  Usage: `Model: deepseek.DeepSeekReasoner`. \u003cbr/\u003e\n  **Note:** The [reasoner](https://api-docs.deepseek.com/guides/reasoning_model) requires unique conditions. Please refer to this issue [#8](https://github.com/cohesion-org/deepseek-go/issues/8). \n\n### External Providers\n- **Azure DeepSeekR1**  \n\tSame as `deepseek-reasoner`, but provided by Azure. \u003cbr/\u003e\n\tUsage: `Model: deepseek.AzureDeepSeekR1`\n\n- **OpenRouter DeepSeek1** \u003cbr/\u003e\n\tSame as `deepseek-reasoner`, but provided by OpenRouter. \u003cbr/\u003e\n  \tUsage: `Model: deepseek.OpenRouterR1`\n\n- **Ollama Support** \u003cbr/\u003e\n\tPlease read [Ollama Support](#ollama) for more info about this!\n\n\n\u003cdetails open\u003e\n\u003csummary\u003e Chat \u003c/summary\u003e\n\n### Example for chatting with deepseek\n\nEven more examples are avilable [here](/examples/README.md)\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n\t\n)\n\nfunc main() {\n\t// Set up the Deepseek client\n\tclient := deepseek.NewClient(\"\") // Empty API key triggers env lookup for \"DEEPSEEK_API_KEY\"\n\n\t// Create a chat completion request\n\trequest := \u0026deepseek.ChatCompletionRequest{\n\t\tModel: deepseek.DeepSeekChat,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleSystem, Content: \"Answer every question using slang.\"},\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"Which is the tallest mountain in the world?\"},\n\t\t},\n\t}\n\n\t// Send the request and handle the response\n\tctx := context.Background()\n\tresponse, err := client.CreateChatCompletion(ctx, request)\n\tif err != nil {\n\t\tlog.Fatalf(\"error: %v\", err)\n\t}\n\n\t// Print the response\n\tfmt.Println(\"Response:\", response.Choices[0].Message.Content)\n}\n```\n\u003c/details\u003e\n\n## More Examples:\n\n\u003cdetails\u003e\n\u003csummary\u003e Using external providers such as Azure or OpenRouter. \u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc main() {\n\n\t// Azure\n\tbaseURL := \"https://models.inference.ai.azure.com/\"\n\n\t// OpenRouter\n\t// baseURL := \"https://openrouter.ai/api/v1/\"\n\n\t// Set up the Deepseek client\n    client := deepseek.NewClient(os.Getenv(\"PROVIDER_API_KEY\"), baseURL)\n\n\t// Create a chat completion request\n\trequest := \u0026deepseek.ChatCompletionRequest{\n\t\tModel: deepseek.AzureDeepSeekR1,\n\t\t// Model: deepseek.OpenRouterDeepSeekR1,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"Which is the tallest mountain in the world?\"},\n\t\t},\n\t}\n\n\t// Send the request and handle the response\n\tctx := context.Background()\n\tresponse, err := client.CreateChatCompletion(ctx, request)\n\tif err != nil {\n\t\tlog.Fatalf(\"error: %v\", err)\n\t}\n\n\t// Print the response\n\tfmt.Println(\"Response:\", response.Choices[0].Message.Content)\n}\n```\n\nNote: If you wish to use other providers that are not supported by us, you can simply extend the baseURL(as shown above), and pass the name of your model as a string to `Model` while creating the `ChatCompletionRequest`. This will work as long as the provider follows the same API structure as Azure or OpenRouter.\n\n\n\u003c/details\u003e\n\n\u003cdetails \u003e\n\t\u003csummary\u003e Sending other params like Temp, Stop \u003c/summary\u003e\n\t\u003cstrong\u003e You just need to extend the ChatCompletionMessage with the supported parameters. \u003c/strong\u003e\n\n```go\n\trequest := \u0026deepseek.ChatCompletionRequest{\n\t\tModel: deepseek.DeepSeekChat,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"What is the meaning of deepseek\"},\n\t\t\t{Role: deepseek.ChatMessageRoleSystem, Content: \"Answer every question using slang\"},\n\t\t},\n\t\tTemperature: 1.0,\n\t\tStop:        []string{\"yo\", \"hello\"},\n\t\tResponseFormat: \u0026deepseek.ResponseFormat{\n\t\t\tType: \"text\",\n\t\t},\n\t}\n```\n\n\u003c/details\u003e\n\n\u003cdetails \u003e\n\t\u003csummary\u003e Multi-Conversation with Deepseek. \u003c/summary\u003e\n\n```go\npackage deepseek_examples\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc MultiChat() {\n\tclient := deepseek.NewClient(\"DEEPSEEK_API_KEY\")\n\tctx := context.Background()\n\n\tmessages := []deepseek.ChatCompletionMessage{{\n\t\tRole:    deepseek.ChatMessageRoleUser,\n\t\tContent: \"Who is the president of the United States? One word response only.\",\n\t}}\n\n\t// Round 1: First API call\n\tresponse1, err := client.CreateChatCompletion(ctx, \u0026deepseek.ChatCompletionRequest{\n\t\tModel:    deepseek.DeepSeekChat,\n\t\tMessages: messages,\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"Round 1 failed: %v\", err)\n\t}\n\n\tresponse1Message, err := deepseek.MapMessageToChatCompletionMessage(response1.Choices[0].Message)\n\tif err != nil {\n\t\tlog.Fatalf(\"Mapping to message failed: %v\", err)\n\t}\n\tmessages = append(messages, response1Message)\n\n\tlog.Printf(\"The messages after response 1 are: %v\", messages)\n\t// Round 2: Second API call\n\tmessages = append(messages, deepseek.ChatCompletionMessage{\n\t\tRole:    deepseek.ChatMessageRoleUser,\n\t\tContent: \"Who was the one in the previous term.\",\n\t})\n\n\tresponse2, err := client.CreateChatCompletion(ctx, \u0026deepseek.ChatCompletionRequest{\n\t\tModel:    deepseek.DeepSeekChat,\n\t\tMessages: messages,\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"Round 2 failed: %v\", err)\n\t}\n\n\tresponse2Message, err := deepseek.MapMessageToChatCompletionMessage(response2.Choices[0].Message)\n\tif err != nil {\n\t\tlog.Fatalf(\"Mapping to message failed: %v\", err)\n\t}\n\tmessages = append(messages, response2Message)\n\tlog.Printf(\"The messages after response 1 are: %v\", messages)\n\n}\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e Chat with Streaming \u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc main() {\n\tclient := deepseek.NewClient(os.Getenv(\"DEEPSEEK_API_KEY\"))\n\trequest := \u0026deepseek.StreamChatCompletionRequest{\n\t\tModel: deepseek.DeepSeekChat,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"Just testing if the streaming feature is working or not!\"},\n\t\t},\n\t\tStream: true,\n\t}\n\tctx := context.Background()\n\n\tstream, err := client.CreateChatCompletionStream(ctx, request)\n\tif err != nil {\n\t\tlog.Fatalf(\"ChatCompletionStream error: %v\", err)\n\t}\n\tvar fullMessage string\n\tdefer stream.Close()\n\tfor {\n\t\tresponse, err := stream.Recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tfmt.Println(\"\\nStream finished\")\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\nStream error: %v\\n\", err)\n\t\t\tbreak\n\t\t}\n\t\tfor _, choice := range response.Choices {\n\t\t\tfullMessage += choice.Delta.Content // Accumulate chunk content\n\t\t\tlog.Println(choice.Delta.Content)\n\t\t}\n\t}\n\tlog.Println(\"The full message is: \", fullMessage)\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e Get the balance(s) of the user. \u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc main() {\n\tclient := deepseek.NewClient(os.Getenv(\"DEEPSEEK_API_KEY\"))\n\tctx := context.Background()\n\tbalance, err := deepseek.GetBalance(client, ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Error getting balance: %v\", err)\n\t}\n\n\tif balance == nil {\n\t\tlog.Fatalf(\"Balance is nil\")\n\t}\n\n\tif len(balance.BalanceInfos) == 0 {\n\t\tlog.Fatalf(\"No balance information returned\")\n\t}\n\tlog.Printf(\"%+v\\n\", balance)\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e Get the list of All the models the API supports right now. This is different from what deepseek-go might support. \u003c/summary\u003e\n\n```go\nfunc ListModels() {\n\tclient := deepseek.NewClient(\"DEEPSEEK_API_KEY\")\n\tctx := context.Background()\n\tmodels, err := deepseek.ListAllModels(client, ctx)\n\tif err != nil {\n\t\tt.Fatalf(\"Error listing models: %v\", err)\n\t}\n\tfmt.Printf(\"\\n%+v\\n\", models)\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e \n\u003csummary\u003e Get the estimated tokens for the request. \u003c/summary\u003e\n\nThis is adpated from [the  Deepseek's estimation](https://api-docs.deepseek.com/quick_start/token_usage).\n\n```go\nfunc Estimation() {\n\tclient := deepseek.NewClient(\"DEEPSEEK_API_KEY\"))\n\trequest := \u0026deepseek.ChatCompletionRequest{\n\t\tModel: deepseek.DeepSeekChat,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleSystem, Content: \"Just respond with the time it might take you to complete this request.\"},\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"The text to evaluate the time is: Who is the greatest singer in the world?\"},\n\t\t},\n\t}\n\tctx := context.Background()\n\n\ttokens := deepseek.EstimateTokensFromMessages(request)\n\tfmt.Println(\"Estimated tokens for the request is: \", tokens.EstimatedTokens)\n\tresponse, err := client.CreateChatCompletion(ctx, request)\n\n\tif err != nil {\n\t\tlog.Fatalf(\"error: %v\", err)\n\t}\n\t\n\tfmt.Println(\"Response:\", response.Choices[0].Message.Content, \"\\nActual Tokens Used:\", response.Usage.PromptTokens)\n}\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e \n\n\u003csummary\u003e JSON mode for JSON extraction\u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc JsonMode() {\n\t// Book represents a book in a library\n\ttype Book struct {\n\t\tISBN            string `json:\"isbn\"`\n\t\tTitle           string `json:\"title\"`\n\t\tAuthor          string `json:\"author\"`\n\t\tGenre           string `json:\"genre\"`\n\t\tPublicationYear int    `json:\"publication_year\"`\n\t\tAvailable       bool   `json:\"available\"`\n\t}\n\n\ttype Books struct {\n\t\tBooks []Book `json:\"books\"`\n\t}\n\t// Creating a new client using OpenRouter; you can use your own API key and endpoint.\n\tclient := deepseek.NewClient(\n\t\tos.Getenv(\"OPENROUTER_API_KEY\"),\n\t\t\"https://openrouter.ai/api/v1/\",\n\t)\n\tctx := context.Background()\n\n\tprompt := `Provide book details in JSON format. Generate 10 JSON objects. \n\tPlease provide the JSON in the following format: { \"books\": [...] }\n\tExample: {\"isbn\": \"978-0321765723\", \"title\": \"The Lord of the Rings\", \"author\": \"J.R.R. Tolkien\", \"genre\": \"Fantasy\", \"publication_year\": 1954, \"available\": true}`\n\n\tresp, err := client.CreateChatCompletion(ctx, \u0026deepseek.ChatCompletionRequest{\n\t\tModel: \"mistralai/codestral-2501\", // Or another suitable model\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: prompt},\n\t\t},\n\t\tJSONMode: true,\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create chat completion: %v\", err)\n\t}\n\tif resp == nil || len(resp.Choices) == 0 {\n\t\tlog.Fatal(\"No response or choices found\")\n\t}\n\n\tlog.Printf(\"Response: %s\", resp.Choices[0].Message.Content)\n\n\textractor := deepseek.NewJSONExtractor(nil)\n\tvar books Books\n\tif err := extractor.ExtractJSON(resp, \u0026books); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Printf(\"\\n\\nExtracted Books: %+v\\n\\n\", books)\n\n\t// Basic validation to check if we got some books\n\tif len(books.Books) == 0 {\n\t\tlog.Print(\"No books were extracted from the JSON response\")\n\t} else {\n\t\tfmt.Println(\"Successfully extracted\", len(books.Books), \"books.\")\n\t}\n\n}\n```\nYou can see more examples inside the examples folder.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e \u003csummary\u003e Add more settings to your client with NewClientWithOptions \u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"log\"\n    \"time\"\n    \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc main() {\n    client, err := deepseek.NewClientWithOptions(\"your-api-key\",\n        deepseek.WithBaseURL(\"https://custom-api.com/\"),\n        deepseek.WithTimeout(10*time.Second),\n    )\n    if err != nil {\n        log.Fatalf(\"Error creating client: %v\", err)\n    }\n\n    fmt.Printf(\"Client initialized with BaseURL: %s and Timeout: %v\\n\", client.BaseURL, client.Timeout)\n}\n ```\nSee the examples folder for more information.\n\u003c/details\u003e\n\n\u003cdetails\u003e \n\u003csummary\u003e FIM Mode(Beta) \u003c/summary\u003e\n\nIn FIM (Fill In the Middle) completion, users can provide a prefix and a suffix (optional), and the model will complete the content in between. FIM is commonly used for content completion、code completion.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc FIM() {\n\tclient := deepseek.NewClient(os.Getenv(\"DEEPSEEK_API_KEY\"))\n\trequest := \u0026deepseek.FIMCompletionRequest{\n\t\tModel:  deepseek.DeepSeekChat,\n\t\tPrompt: \"def add(a, b):\",\n\t}\n\tctx := context.Background()\n\tresponse, err := client.CreateFIMCompletion(ctx, request)\n\tif err != nil {\n\t\tlog.Fatalf(\"error: %v\", err)\n\t}\n\tfmt.Println(\"\\n\", response.Choices[0].Text)\n}\n\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e \n\u003csummary\u003e Chat Prefix Completion (Beta)\u003c/summary\u003e\nThe chat prefix completion follows the [Chat Completion API](https://api-docs.deepseek.com/guides/chat_prefix_completion), where users provide an assistant's prefix message for the model to complete the rest of the message.\n\n```go\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\tdeepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc ChatPrefix() {\n\tclient := deepseek.NewClient(\n\t\tDEEPSEEK_API_KEY,\n\t\t\"https://api.deepseek.com/beta/\") // Use the beta endpoint\n\n\tctx := context.Background()\n\n\trequest := \u0026deepseek.ChatCompletionRequest{\n\t\tModel: deepseek.DeepSeekChat,\n\t\tMessages: []deepseek.ChatCompletionMessage{\n\t\t\t{Role: deepseek.ChatMessageRoleUser, Content: \"Please write quick sort code\"},\n\t\t\t{Role: deepseek.ChatMessageRoleAssistant, Content: \"```python\", Prefix: true},\n\t\t},\n\t\tStop: []string{\"```\"}, // Stop the prefix when the assistant sends the closing triple backticks\n\t}\n\tresponse, err := client.CreateChatCompletion(ctx, request)\n\tif err != nil {\n\t\tlog.Fatalf(\"error: %v\", err)\n\t}\n\tfmt.Println(response.Choices[0].Message.Content)\n\n}\n\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e Using external providers with image support (OpenRouter) \u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n\n    deepseek \"github.com/cohesion-org/deepseek-go\"\n)\n\nfunc main() {\n    // Create request with image URL\n    request := \u0026deepseek.ChatCompletionRequestWithImage{\n        Model: \"google/gemini-2.0-flash-001\",\n        Messages: []deepseek.ChatCompletionMessageWithImage{\n            deepseek.NewImageMessage(\n                deepseek.ChatMessageRoleUser,\n                \"Describe this image\",\n                \"https://example.com/path/to/image.jpg\",\n            ),\n        },\n    }\n\n    // Initialize client with OpenRouter\n    client := deepseek.NewClient(\n        os.Getenv(\"OPENROUTER_API_KEY\"),\n        \"https://openrouter.ai/api/v1/\",\n    )\n\n    // Send request and get response\n    response, err := client.CreateChatCompletionWithImage(context.Background(), request)\n    if err != nil {\n        log.Fatalf(\"error: %v\", err)\n    }\n\n    fmt.Println(\"Response:\", response.Choices[0].Message.Content)\n}\n```\n\nFor more advanced examples including streaming and base64 image support, see [OpenRouter Images Examples](/examples/13_openrouter_images/openrouter_images.go).\n\n\u003c/details\u003e\n\n---\n## Getting a Deepseek Key\n\nTo use the Deepseek API, you need an API key. You can obtain one by signing up on the [Deepseek website](https://platform.deepseek.com/api_keys)\n\n## Ollama\n\nDeepseek-go supports the usage of Ollama, but because of Ollama not following OpenAI policy, there are some extra types you need to be aware about. This is still an experimental feature so please understand that. \n\nYou can find all information about it at [Ollama Docs](/examples/ollama.md). \n\n---\n\n\n## Running Tests\n\n### Setup\n\n1. Copy the example environment file:\n   ```bash\n   cp .env.example .env\n   ```\n\n2. Add your DeepSeek API key to `.env`:\n   ```\n   TEST_DEEPSEEK_API_KEY=your_api_key_here\n   ```\n\n3. (Optional) Configure test timeout:\n   ```\n   # Default is 30s, increase for slower connections\n   TEST_TIMEOUT=1m\n   ```\n\n### Test Organization\n\nThe tests are organized into several files and folders:\n\n### Main Package\n- `client_test.go`: Client configuration and error handling\n- `chat_test.go`: Chat completion functionality \n- `chat_stream_test.go`: Chat streaming functionality\n- `models_test.go`: Model listing and retrieval\n- `balance_test.go`: Account balance operations\n- `tokens_test.go`: Token estimation utilities\n- `json_test.go`: JSON mode for extraction\n- `fim_test.go`: Tests for the FIM beta implementation\n\u003c!-- - `errors_test.go`: Tests the error handler --\u003e\n- `requestHandler_test.go`: Tests for the request handler\n- `responseHandler_test.go`: Tests for the response handler\n\n### Utils Package\n- `utils/requestBuilder_test.go`: Tests for the request builder\n\n### Running Tests\n\n1. Run all tests (requires API key):\n   ```bash\n   go test -v ./...\n   ```\n\n2. Run tests in short mode (skips API calls):\n   ```bash\n   go test -v -short ./...\n   ```\n\n3. Run tests with race detection:\n   ```bash\n   go test -v -race ./...\n   ```\n\n4. Run tests with coverage:\n   ```bash\n   go test -v -coverprofile=coverage.txt -covermode=atomic ./...\n   ```\n\n   View coverage in browser:\n   ```bash\n   go tool cover -html=coverage.txt\n   ```\n\n5. Run specific test:\n   ```bash\n   # Example: Run only chat completion tests\n   go test -v -run TestCreateChatCompletion ./...\n   ```\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n---\n\n## Credits\n- **`chat.go` Inspiration**: Adapted from [sashabaranov/go-openai](https://github.com/sashabaranov/go-openai/tree/master).\n- **`json.go` Inspiration**: Thanks a lot for [Mr. Peter](https://github.com/peterlodri92).\n\n---\n\n## Images\n\n\u003cdiv style=\"display:flex; justify-content: space-between; margin:20px;\"\u003e\n  \u003cimg src=\"internal/images/deepseek-go-big.png\" alt=\"Deepseek Go Big Logo\" style=\"border-radius:2%;\"\n  height=250px\u003e\n  \u003cimg src=\"internal/images/deepseek-go.png\" alt=\"Deepseek Go Logo\" style=\"scale: 90%; border-radius:100%\"\n  height=250px\u003e\n\n\u003c/div\u003e\n\nFeel free to contribute, open issues, or submit PRs to help improve Deepseek-Go! Let us know if you encounter any issues.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcohesion-org%2Fdeepseek-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcohesion-org%2Fdeepseek-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcohesion-org%2Fdeepseek-go/lists"}