Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gemini #30

Merged
merged 12 commits into from
Jun 21, 2024
Merged

Gemini #30

merged 12 commits into from
Jun 21, 2024

Conversation

asukaminato0721
Copy link
Contributor

@asukaminato0721 asukaminato0721 commented Jun 17, 2024

fix #28

currently

GEMINI_API_KEY=<HERE THE KEY> cargo test --package lsp-ai --bin lsp-ai -- transformer_
backends::gemini::test::gemini_completion_do_generate --exact --show-output

works, code needs improve though.

@asukaminato0721
Copy link
Contributor Author

now

---- transformer_backends::gemini::test::gemini_completion_do_generate stdout ----
[src/transformer_backends/gemini.rs:203:9] response.generated_text = "\"```python\\ndef test_context():\\n    \\\"\\\"\\\"\\n    This function serves as a template for writing unit tests using the 'context' pattern.\\n\\n    The 'context' pattern helps organize test cases by grouping them based on the state they set up.\\n\\n    To use this template:\\n\\n    1. Replace the \\\"pass\\\" statement with your test code.\\n    2. Define the specific context you want to test within a \\\"with\\\" block.\\n    3. Use the `self.assertEqual()`, `self.assertTrue()`, etc. methods to assert the expected outcomes.\\n\\n    Example:\\n\\n    ```python\\n    def test_context(self):\\n        with self.subTest(\\\"Positive numbers\\\"):\\n            self.assertEqual(add(2, 3), 5)\\n\\n        with self.subTest(\\\"Negative numbers\\\"):\\n            self.assertEqual(add(-2, -3), -5)\\n    ```\\n    \\\"\\\"\\\"\\n    pass\\n```\\n\\n**Explanation:**\\n\\n* **`def test_context():`**: This defines a function named `test_context` which will contain your test cases.\\n* **Docstring**:  The docstring explains the purpose and usage of the function.\\n* **`with self.subTest(\\\"Positive numbers\\\"):`**: This block creates a subtest labeled \\\"Positive numbers\\\". It's useful for grouping related assertions and providing informative error messages.\\n* **`self.assertEqual(add(2, 3), 5)`**: This assertion checks if the result of calling `add(2, 3)` is equal to 5.\\n* **`with self.subTest(\\\"Negative numbers\\\"):`**: Another subtest block for testing negative numbers.\\n* **`self.assertEqual(add(-2, -3), -5)`**:  This assertion checks if the result of calling `add(-2, -3)` is equal to -5.\\n\\n**Key Points:**\\n\\n* **Context-Driven Testing:** The `with self.subTest(...)` pattern allows you to group tests based on specific contexts, making your tests more organized and readable.\\n* **Subtests:** Subtests provide informative error messages that specify the context in which the failure occurred.\\n* **Assertions:**  Use assertion methods (like `self.assertEqual()`, `self.assertTrue()`, etc.) to verify the expected outcomes of your tests.\\n\\n**Remember to replace the `pass` statement with your actual test code!** \\n\""

and

---- transformer_backends::gemini::test::gemini_chat_do_generate stdout ----
[src/transformer_backends/gemini.rs:235:9] &response = "\"Well, I mean, obviously I love winter!  It's the only time of year I get to exist!  But I hear spring is pretty nice, too, though I wouldn't know.  I tend to melt a little that time of year.  *shivers*  Just thinking about it makes me want to snuggle up next to my trusty snow-ball companion! \\n\""

@asukaminato0721
Copy link
Contributor Author

asukaminato0721 commented Jun 17, 2024

TODO:

I am not sure how the whole system works, but these two tests works well now.

and currently I hard coded the model.

@asukaminato0721 asukaminato0721 marked this pull request as ready for review June 17, 2024 18:09
@SilasMarvin
Copy link
Owner

This is looking really good! The only major note is that I don't think you actually want to support FIM. If you look at the mistral FIM, you see we supply both a prompt and suffix. The API for Mistral FIM specifically performs FIM. I think you want to support generateText and generateContent endpoints for the Gemini API.

Instead of do_fim you will probably want do_generate. You can see the Ollama implementation for an example:

async fn get_completion(

I feel like the Ollama implementation is probably a better example to go off of than the Mistral FIM one. Let me know if this doesn't make sense and I am happy to clarify anything!

@asukaminato0721
Copy link
Contributor Author

ok, find this problem: openai use this

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ChatMessage {
    pub role: String,
    pub content: String,
}

but gemini use

"contents": [
              {
                "role":"user",
                "parts":[{
                 "text": "Pretend you're a snowman and stay in character for each response."}]
                },
              {
                "role": "model",
                "parts":[{
                 "text": "Hello! It's so cold! Isn't that great?"}]
                },
              {
                "role": "user",
                "parts":[{
                 "text": "What's your favorite season of the year?"}]
                }
             ]

the chat functionality seems need to change the system, so support completion first.

@SilasMarvin
Copy link
Owner

SilasMarvin commented Jun 18, 2024

ok, find this problem: openai use this

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ChatMessage {
    pub role: String,
    pub content: String,
}

but gemini use

"contents": [
              {
                "role":"user",
                "parts":[{
                 "text": "Pretend you're a snowman and stay in character for each response."}]
                },
              {
                "role": "model",
                "parts":[{
                 "text": "Hello! It's so cold! Isn't that great?"}]
                },
              {
                "role": "user",
                "parts":[{
                 "text": "What's your favorite season of the year?"}]
                }
             ]

the chat functionality seems need to change the system, so support completion first.

I would create a new struct GeminiChatMessage and implement From<ChatMessage>. It would look something like:

#[derive(Serialize)]
struct Part {
    text: String
}

#[derive(Serialize)]
struct GeminiChatMessage {
    role: String,
    parts: Vec<Part>
}

impl From<ChatMessage> for GeminiChatMessage {
    fn from(value: ChatMessage) -> Self {
        // Finish from code here
    }
}

Let me know if this isn't helpful, and I can make a PR into your branch with some suggestions.

@asukaminato0721
Copy link
Contributor Author

now it works well.

[src/transformer_backends/gemini.rs:292:9] &response.generated_text = "\"Oh, definitely winter! I mean, where else would a snowman like me be happy? It's a time for snowballs and sledding, and best of all, making new friends. Like you! 😄 \\n\""
test transformer_backends::gemini::test::gemini_chat_do_generate ... ok
[src/transformer_backends/gemini.rs:259:9] response.generated_text = "\"```python\\ndef test_context():\\n    \\\"\\\"\\\"This function is a placeholder for testing the context.\\n\\n    You can add your own assertions and logic here to test specific aspects of the context.\\n    \\\"\\\"\\\"\\n    pass\\n\\ndef test_code():\\n    \\\"\\\"\\\"This function is a placeholder for testing your code.\\n\\n    You can add your own assertions and logic here to test the functionality of your code.\\n    \\\"\\\"\\\"\\n    # Example:\\n    assert 1 + 1 == 2, \\\"Basic arithmetic should work.\\\"\\n```\\n\\n**Explanation:**\\n\\n1. **`test_context()`:**\\n   - This function is designed to test the context within which your code will run.\\n   - You can use this to check:\\n     - **Environment variables:**  Are the necessary environment variables set correctly?\\n     - **Dependencies:** Are all the required libraries installed and accessible?\\n     - **Data:** Is the data (if any) loaded properly and in the expected format?\\n\\n2. **`test_code()`:**\\n   - This function is for testing the core logic of your code.\\n   - It should include:\\n     - **Assertions:** Use the `assert` keyword to verify that your code produces the expected output.\\n     - **Example:** The provided example `assert 1 + 1 == 2, \\\"Basic arithmetic should work.\\\"` demonstrates how to use an assertion.\\n\\n**Example Usage (within a test file):**\\n\\n```python\\nimport unittest\\n\\nclass MyTests(unittest.TestCase):\\n    def test_context(self):\\n        # Add your assertions about the context here\\n        # ...\\n\\n    def test_code(self):\\n        # Add your code tests here\\n        # ...\\n\\nif __name__ == '__main__':\\n    unittest.main()\\n```\\n\\n**To Run Tests:**\\n\\n1. **Save the code** in a file (e.g., `test_my_code.py`).\\n2. **Execute the tests:**\\n   - From your terminal, run: `python -m unittest test_my_code.py`\\n\\n**Remember:**\\n\\n- Replace the placeholder comments with your actual test logic.\\n- Tailor the tests to cover all the functionality of your code.\\n- Use descriptive test names that clearly indicate what is being tested. \\n\""
test transformer_backends::gemini::test::gemini_completion_do_generate ... ok

with

cargo test -- --nocapture

@SilasMarvin
Copy link
Owner

I actually made a pr into your branch: asukaminato0721#1

If you can merge that I should be able to merge this in.

@SilasMarvin
Copy link
Owner

Hey sorry I tested it with my editor and had to add a few more updates to get the prompt to format correctly: asukaminato0721#2

I'm not able to get good completion responses from it. When I test it using the default chat prompts I have outlined in the Configuration section it loves to include quotes in its response. We can merge this once you merge my pr in, but before I update the wiki it would be nice to have some prompts we know work well.

@asukaminato0721
Copy link
Contributor Author

cc @SilasMarvin mind take a look?

@SilasMarvin SilasMarvin merged commit 2c53880 into SilasMarvin:main Jun 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add google generative language api support
2 participants