1 line
8.5 KiB
JSON
1 line
8.5 KiB
JSON
{"repo": "antonmedv/howto", "files": {"main.go": {"d190fa1d3d18b13a28f9c874c113b221359b3e68": {"t": 1785745617.8824847, "n": 954, "h": "14e9a1b99e2ff391", "c": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nvar apiKeyEnvs = []struct {\n\tenv string\n\tprovider *LLMProvider\n}{\n\t{\"OPENAI_API_KEY\", openai},\n\t{\"GEMINI_API_KEY\", gemini},\n\t{\"DEEPSEEK_API_KEY\", deepseek},\n}\n\nfunc main() {\n\tcmd := strings.Join(os.Args[1:], \" \")\n\tif cmd == \"\" {\n\t\tfmt.Println(\"usage: howto <query>\")\n\t\tos.Exit(1)\n\t}\n\n\tprovider, apiKey := detectProvider()\n\tif provider == nil {\n\t\tfmt.Fprintln(os.Stderr, \"error: no API key found\")\n\t\tfmt.Fprintln(os.Stderr, \"set one of: OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY\")\n\t\tos.Exit(1)\n\t}\n\n\tmodel := os.Getenv(\"HOWTO_MODEL\")\n\n\tresponse, err := queryLLM(provider, apiKey, model, prompt(cmd))\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"error: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tinsertInput(sanitizeCommand(response))\n}\n\nfunc detectProvider() (*LLMProvider, string) {\n\tfor _, e := range apiKeyEnvs {\n\t\tif key := os.Getenv(e.env); key != \"\" {\n\t\t\treturn e.provider, key\n\t\t}\n\t}\n\treturn nil, \"\"\n}\n"}, "759aa87989c42ba39136374cb9b14fefbf8b42be": {"t": 1785754881.980667, "n": 954, "h": "14e9a1b99e2ff391", "c": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nvar apiKeyEnvs = []struct {\n\tenv string\n\tprovider *LLMProvider\n}{\n\t{\"OPENAI_API_KEY\", openai},\n\t{\"GEMINI_API_KEY\", gemini},\n\t{\"DEEPSEEK_API_KEY\", deepseek},\n}\n\nfunc main() {\n\tcmd := strings.Join(os.Args[1:], \" \")\n\tif cmd == \"\" {\n\t\tfmt.Println(\"usage: howto <query>\")\n\t\tos.Exit(1)\n\t}\n\n\tprovider, apiKey := detectProvider()\n\tif provider == nil {\n\t\tfmt.Fprintln(os.Stderr, \"error: no API key found\")\n\t\tfmt.Fprintln(os.Stderr, \"set one of: OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY\")\n\t\tos.Exit(1)\n\t}\n\n\tmodel := os.Getenv(\"HOWTO_MODEL\")\n\n\tresponse, err := queryLLM(provider, apiKey, model, prompt(cmd))\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"error: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tinsertInput(sanitizeCommand(response))\n}\n\nfunc detectProvider() (*LLMProvider, string) {\n\tfor _, e := range apiKeyEnvs {\n\t\tif key := os.Getenv(e.env); key != \"\" {\n\t\t\treturn e.provider, key\n\t\t}\n\t}\n\treturn nil, \"\"\n}\n"}, "e599bbba29a1cf9ade96549fbad8823a26462c35": {"t": 1785754883.5637674, "n": 523, "h": "5396de849d5c550a", "c": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc main() {\n\tcmd := strings.Join(os.Args[1:], \" \")\n\tif cmd == \"\" {\n\t\tfmt.Println(\"usage: howto <query>\")\n\t\tos.Exit(1)\n\t}\n\n\topenAIKey, ok := os.LookupEnv(\"OPENAI_API_KEY\")\n\tif !ok {\n\t\tpanic(\"OPENAI_API_KEY not set\")\n\t}\n\n\topenAiModel := \"gpt-4o\"\n\tmodel, ok := os.LookupEnv(\"OPENAI_MODEL\")\n\tif ok {\n\t\topenAiModel = model\n\t}\n\n\tresponse, err := queryOpenAI(openAIKey, openAiModel, prompt(cmd), 1000)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tinsertInput(sanitizeCommand(response))\n}\n"}}, "providers.go": {"d190fa1d3d18b13a28f9c874c113b221359b3e68": {"t": 1785746054.0972044, "n": 2368, "h": "fd2d50e58670ad17", "c": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\ntype LLMProvider struct {\n\tName string\n\tEndpoint string\n\tDefaultModel string\n}\n\nvar (\n\topenai = &LLMProvider{\n\t\tName: \"OpenAI\",\n\t\tEndpoint: \"https://api.openai.com/v1/chat/completions\",\n\t\tDefaultModel: \"gpt-4o\",\n\t}\n\tgemini = &LLMProvider{\n\t\tName: \"Gemini\",\n\t\tEndpoint: \"https://generativelanguage.googleapis.com/v1beta/openai/chat/completions\",\n\t\tDefaultModel: \"gemini-2.0-flash\",\n\t}\n\tdeepseek = &LLMProvider{\n\t\tName: \"DeepSeek\",\n\t\tEndpoint: \"https://api.deepseek.com/chat/completions\",\n\t\tDefaultModel: \"deepseek-chat\",\n\t}\n)\n\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []Message `json:\"messages\"`\n\tMaxTokens int `json:\"max_tokens\"`\n}\n\ntype Message struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\ntype ChatResponse struct {\n\tChoices []struct {\n\t\tMessage Message `json:\"message\"`\n\t} `json:\"choices\"`\n\tError *APIError `json:\"error,omitempty\"`\n}\n\ntype APIError struct {\n\tMessage string `json:\"message\"`\n}\n\nfunc queryLLM(provider *LLMProvider, apiKey, model, prompt string) (string, error) {\n\tif model == \"\" {\n\t\tmodel = provider.DefaultModel\n\t}\n\n\trequestBody := ChatRequest{\n\t\tModel: model,\n\t\tMessages: []Message{{Role: \"user\", Content: prompt}},\n\t\tMaxTokens: 1000,\n\t}\n\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", provider.Endpoint, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+apiKey)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar chatResp ChatResponse\n\tif err := json.Unmarshal(body, &chatResp); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif chatResp.Error != nil {\n\t\treturn \"\", fmt.Errorf(\"API error: %s\", chatResp.Error.Message)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API returned status %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\tif len(chatResp.Choices) > 0 {\n\t\treturn chatResp.Choices[0].Message.Content, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"no response from %s\", provider.Name)\n}\n"}, "759aa87989c42ba39136374cb9b14fefbf8b42be": {"t": 1785754882.8754942, "n": 2368, "h": "fd2d50e58670ad17", "c": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\ntype LLMProvider struct {\n\tName string\n\tEndpoint string\n\tDefaultModel string\n}\n\nvar (\n\topenai = &LLMProvider{\n\t\tName: \"OpenAI\",\n\t\tEndpoint: \"https://api.openai.com/v1/chat/completions\",\n\t\tDefaultModel: \"gpt-4o\",\n\t}\n\tgemini = &LLMProvider{\n\t\tName: \"Gemini\",\n\t\tEndpoint: \"https://generativelanguage.googleapis.com/v1beta/openai/chat/completions\",\n\t\tDefaultModel: \"gemini-2.0-flash\",\n\t}\n\tdeepseek = &LLMProvider{\n\t\tName: \"DeepSeek\",\n\t\tEndpoint: \"https://api.deepseek.com/chat/completions\",\n\t\tDefaultModel: \"deepseek-chat\",\n\t}\n)\n\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []Message `json:\"messages\"`\n\tMaxTokens int `json:\"max_tokens\"`\n}\n\ntype Message struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\ntype ChatResponse struct {\n\tChoices []struct {\n\t\tMessage Message `json:\"message\"`\n\t} `json:\"choices\"`\n\tError *APIError `json:\"error,omitempty\"`\n}\n\ntype APIError struct {\n\tMessage string `json:\"message\"`\n}\n\nfunc queryLLM(provider *LLMProvider, apiKey, model, prompt string) (string, error) {\n\tif model == \"\" {\n\t\tmodel = provider.DefaultModel\n\t}\n\n\trequestBody := ChatRequest{\n\t\tModel: model,\n\t\tMessages: []Message{{Role: \"user\", Content: prompt}},\n\t\tMaxTokens: 1000,\n\t}\n\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treq, err := http.NewRequest(\"POST\", provider.Endpoint, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+apiKey)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar chatResp ChatResponse\n\tif err := json.Unmarshal(body, &chatResp); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif chatResp.Error != nil {\n\t\treturn \"\", fmt.Errorf(\"API error: %s\", chatResp.Error.Message)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API returned status %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\tif len(chatResp.Choices) > 0 {\n\t\treturn chatResp.Choices[0].Message.Content, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"no response from %s\", provider.Name)\n}\n"}}}} |