diff --git a/agent/bindings/kotlin/lib/src/main/kotlin/com/sourcegraph/cody/agent/protocol_generated/CodyAgentServer.kt b/agent/bindings/kotlin/lib/src/main/kotlin/com/sourcegraph/cody/agent/protocol_generated/CodyAgentServer.kt index c111b722d71a..b8140ed8af07 100644 --- a/agent/bindings/kotlin/lib/src/main/kotlin/com/sourcegraph/cody/agent/protocol_generated/CodyAgentServer.kt +++ b/agent/bindings/kotlin/lib/src/main/kotlin/com/sourcegraph/cody/agent/protocol_generated/CodyAgentServer.kt @@ -22,8 +22,6 @@ interface CodyAgentServer { fun chat_sidebar_new(params: Null?): CompletableFuture @JsonRequest("chat/delete") fun chat_delete(params: Chat_DeleteParams): CompletableFuture> - @JsonRequest("chat/restore") - fun chat_restore(params: Chat_RestoreParams): CompletableFuture @JsonRequest("chat/models") fun chat_models(params: Chat_ModelsParams): CompletableFuture @JsonRequest("chat/export") diff --git a/agent/protocol.md b/agent/protocol.md index 1464726efade..8935d2b64119 100644 --- a/agent/protocol.md +++ b/agent/protocol.md @@ -58,13 +58,7 @@ shutdown: [null, null] ```ts 'chat/new': [null, string] ``` -

chat/restore (:arrow_right:)

-

Request sent from the client to client server.

- -```ts -'chat/restore': [{ modelID: string; messages: AgentChatMessage[]; chatID: string; }, string] -```

chat/models (:arrow_right:)

Request sent from the client to client server.

diff --git a/agent/recordings/defaultClient_631904893/recording.har.yaml b/agent/recordings/defaultClient_631904893/recording.har.yaml index 4432574b5c03..3aea414b0e1b 100644 --- a/agent/recordings/defaultClient_631904893/recording.har.yaml +++ b/agent/recordings/defaultClient_631904893/recording.har.yaml @@ -315,473 +315,6 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 7fb43f27f9f262dedfe758506b99a424 - _order: 0 - cache: {} - request: - bodySize: 615 - cookies: [] - headers: - - name: content-type - value: application/json - - name: accept-encoding - value: gzip;q=0 - - name: authorization - value: token - REDACTED_3dd704711f82a44ff6aba261b53b61a03fb8edba658774639148630d838c2d1d - - name: user-agent - value: defaultClient / v1 - - name: traceparent - value: 00-347d014e67d3e86fd398090005eed563-3ffc48c6d205b2ea-01 - - name: connection - value: keep-alive - - name: host - value: sourcegraph.com - headersSize: 415 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json - params: [] - textJSON: - maxTokensToSample: 4000 - messages: - - speaker: system - text: >- - You are Cody, an AI coding assistant from Sourcegraph.If your - answer contains fenced code blocks in Markdown, include the - relevant full file path in the code block tag using this - structure: ```$LANGUAGE:$FILEPATH``` - - For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: |- - Answer positively without apologizing. - - Question: My name is Lars Monsen. - model: anthropic::2023-06-01::claude-3.5-sonnet - temperature: 0 - topK: -1 - topP: -1 - queryString: - - name: api-version - value: "2" - - name: client-name - value: defaultclient - - name: client-version - value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 - response: - bodySize: 1327 - content: - mimeType: text/event-stream - size: 1327 - text: >+ - event: completion - - data: {"deltaText":"Great to meet you, Lars Monsen! It's a pleasure to make your acquaintance. Your name has a strong, distinctive sound to it. I'd be happy to assist you with any questions or tasks you might have. What would you like to chat about or work on today?","stopReason":"end_turn"} - - - event: done - - data: {} - - cookies: [] - headers: - - name: date - value: Wed, 02 Oct 2024 05:24:32 GMT - - name: content-type - value: text/event-stream - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache - - name: vary - value: Cookie,Accept-Encoding,Authorization,Cookie, Authorization, - X-Requested-With,Cookie - - name: x-content-type-options - value: nosniff - - name: x-frame-options - value: DENY - - name: x-xss-protection - value: 1; mode=block - - name: strict-transport-security - value: max-age=31536000; includeSubDomains; preload - headersSize: 1299 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-10-02T05:24:30.745Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - - _id: e347a8a104be211206ca705443e43ce1 - _order: 0 - cache: {} - request: - bodySize: 941 - cookies: [] - headers: - - name: content-type - value: application/json - - name: accept-encoding - value: gzip;q=0 - - name: authorization - value: token - REDACTED_3dd704711f82a44ff6aba261b53b61a03fb8edba658774639148630d838c2d1d - - name: user-agent - value: defaultClient / v1 - - name: traceparent - value: 00-e4572a938af705a0cf9d97425d4fd430-ec93113b1e2ac9d3-01 - - name: connection - value: keep-alive - - name: host - value: sourcegraph.com - headersSize: 415 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json - params: [] - textJSON: - maxTokensToSample: 4000 - messages: - - speaker: system - text: >- - You are Cody, an AI coding assistant from Sourcegraph.If your - answer contains fenced code blocks in Markdown, include the - relevant full file path in the code block tag using this - structure: ```$LANGUAGE:$FILEPATH``` - - For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: My name is Lars Monsen. - - speaker: assistant - text: Great to meet you, Lars Monsen! It's a pleasure to make your acquaintance. - Your name has a strong, distinctive sound to it. I'd be happy - to assist you with any questions or tasks you might have. What - would you like to chat about or work on today? - - speaker: human - text: |- - Answer positively without apologizing. - - Question: What is my name? - model: anthropic::2023-06-01::claude-3.5-sonnet - temperature: 0 - topK: -1 - topP: -1 - queryString: - - name: api-version - value: "2" - - name: client-name - value: defaultclient - - name: client-version - value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 - response: - bodySize: 954 - content: - mimeType: text/event-stream - size: 954 - text: >+ - event: completion - - data: {"deltaText":"Your name is Lars Monsen. It's a strong and memorable name that I'm glad to know. Is there anything specific about your name or yourself you'd like to discuss further?","stopReason":"end_turn"} - - - event: done - - data: {} - - cookies: [] - headers: - - name: date - value: Wed, 02 Oct 2024 05:24:33 GMT - - name: content-type - value: text/event-stream - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache - - name: vary - value: Cookie,Accept-Encoding,Authorization,Cookie, Authorization, - X-Requested-With,Cookie - - name: x-content-type-options - value: nosniff - - name: x-frame-options - value: DENY - - name: x-xss-protection - value: 1; mode=block - - name: strict-transport-security - value: max-age=31536000; includeSubDomains; preload - headersSize: 1299 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-10-02T05:24:32.215Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - - _id: 7f889670b97d98b68a21df8b42b677d9 - _order: 0 - cache: {} - request: - bodySize: 611 - cookies: [] - headers: - - name: content-type - value: application/json - - name: accept-encoding - value: gzip;q=0 - - name: authorization - value: token - REDACTED_3dd704711f82a44ff6aba261b53b61a03fb8edba658774639148630d838c2d1d - - name: user-agent - value: defaultClient / v1 - - name: traceparent - value: 00-83eeee9e116d266c9475400d402e7b8a-fba2a36c5edac5bf-01 - - name: connection - value: keep-alive - - name: host - value: sourcegraph.com - headersSize: 415 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json - params: [] - textJSON: - maxTokensToSample: 4000 - messages: - - speaker: system - text: >- - You are Cody, an AI coding assistant from Sourcegraph.If your - answer contains fenced code blocks in Markdown, include the - relevant full file path in the code block tag using this - structure: ```$LANGUAGE:$FILEPATH``` - - For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: |- - Answer positively without apologizing. - - Question: What model are you? - model: anthropic::2023-06-01::claude-3.5-sonnet - temperature: 0 - topK: -1 - topP: -1 - queryString: - - name: api-version - value: "2" - - name: client-name - value: defaultclient - - name: client-version - value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 - response: - bodySize: 1465 - content: - mimeType: text/event-stream - size: 1465 - text: >+ - event: completion - - data: {"deltaText":"I'm Cody, an AI coding assistant created by Sourcegraph. I'm always happy to help with coding and development tasks! While I don't know all the details about my underlying model, I'm focused on assisting you to the best of my abilities. What kind of coding question or task can I help you with today?","stopReason":"end_turn"} - - - event: done - - data: {} - - cookies: [] - headers: - - name: date - value: Wed, 02 Oct 2024 05:24:35 GMT - - name: content-type - value: text/event-stream - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache - - name: vary - value: Cookie,Accept-Encoding,Authorization,Cookie, Authorization, - X-Requested-With,Cookie - - name: x-content-type-options - value: nosniff - - name: x-frame-options - value: DENY - - name: x-xss-protection - value: 1; mode=block - - name: strict-transport-security - value: max-age=31536000; includeSubDomains; preload - headersSize: 1299 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-10-02T05:24:33.498Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - - _id: c59adac1c5d0a21fc4536b6a6c351368 - _order: 0 - cache: {} - request: - bodySize: 994 - cookies: [] - headers: - - name: content-type - value: application/json - - name: accept-encoding - value: gzip;q=0 - - name: authorization - value: token - REDACTED_3dd704711f82a44ff6aba261b53b61a03fb8edba658774639148630d838c2d1d - - name: user-agent - value: defaultClient / v1 - - name: traceparent - value: 00-6eb24938eb498a53a04f604ba00d5dd6-4da08a7b08b5dd8e-01 - - name: connection - value: keep-alive - - name: host - value: sourcegraph.com - headersSize: 415 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json - params: [] - textJSON: - maxTokensToSample: 4000 - messages: - - speaker: system - text: >- - You are Cody, an AI coding assistant from Sourcegraph.If your - answer contains fenced code blocks in Markdown, include the - relevant full file path in the code block tag using this - structure: ```$LANGUAGE:$FILEPATH``` - - For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: What model are you? - - speaker: assistant - text: I'm Cody, an AI coding assistant created by Sourcegraph. I'm always happy - to help with coding and development tasks! While I don't know - all the details about my underlying model, I'm focused on - assisting you to the best of my abilities. What kind of coding - question or task can I help you with today? - - speaker: human - text: |- - Answer positively without apologizing. - - Question: What model are you? - model: anthropic::2023-06-01::claude-3.5-sonnet - temperature: 0 - topK: -1 - topP: -1 - queryString: - - name: api-version - value: "2" - - name: client-name - value: defaultclient - - name: client-version - value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 - response: - bodySize: 2575 - content: - mimeType: text/event-stream - size: 2575 - text: >+ - event: completion - - data: {"deltaText":"I'm Cody, an advanced AI coding assistant developed by Sourcegraph. My model is specifically designed to excel at software development tasks, code analysis, and providing programming assistance. I'm equipped with extensive knowledge across various programming languages, frameworks, and development practices. While I don't have detailed information about my exact model specifications, I'm confident in my abilities to tackle a wide range of coding challenges and provide valuable insights. How can I leverage my capabilities to assist you with your coding needs today?","stopReason":"end_turn"} - - - event: done - - data: {} - - cookies: [] - headers: - - name: date - value: Wed, 02 Oct 2024 05:24:36 GMT - - name: content-type - value: text/event-stream - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache - - name: vary - value: Cookie,Accept-Encoding,Authorization,Cookie, Authorization, - X-Requested-With,Cookie - - name: x-content-type-options - value: nosniff - - name: x-frame-options - value: DENY - - name: x-xss-protection - value: 1; mode=block - - name: strict-transport-security - value: max-age=31536000; includeSubDomains; preload - headersSize: 1299 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-10-02T05:24:35.117Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - _id: 6d71e26de0029c2ad3181c3a12ec6817 _order: 0 cache: {} @@ -1154,11 +687,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 268f59c18b5882cd7d0ff054be1eb61e + - _id: d83b595ada351a26b57291aa28c580e0 _order: 0 cache: {} request: - bodySize: 1967 + bodySize: 658 cookies: [] headers: - name: content-type @@ -1171,12 +704,12 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-6908d8f5dc9822c4b1b1ee081cff6ce3-722f8b55f57aef4b-01 + value: 00-c797360e93e058f64e800c351e751586-06ac407028d401ae-01 - name: connection value: keep-alive - name: host value: sourcegraph.com - headersSize: 415 + headersSize: 401 httpVersion: HTTP/1.1 method: POST postData: @@ -1185,7 +718,7 @@ log: textJSON: maxTokensToSample: 4000 messages: - - speaker: system + - speaker: human text: >- You are Cody, an AI coding assistant from Sourcegraph.If your answer contains fenced code blocks in Markdown, include the @@ -1193,60 +726,30 @@ log: structure: ```$LANGUAGE:$FILEPATH``` For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: > - Codebase context from file path src/animal.ts: /* - SELECTION_START */ - - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean - } - - /* SELECTION_END */ - speaker: assistant - text: Ok. + text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: |- - My selected code from codebase file src/animal.ts:1-6: - ``` - - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean - } - ``` + text: what color is the sky? - speaker: assistant - text: Ok. - - speaker: human - text: >- - Answer positively without apologizing. - - - Question: Explain what @src/animal.ts:1-6 ( @src/animal.ts ) does in simple terms. Assume the audience is a beginner programmer who has just learned the language features and basic syntax. Focus on explaining: 1) The purpose of the code 2) What input(s) it takes 3) What output(s) it produces 4) How it achieves its purpose through the logic and algorithm. 5) Any important logic flows or data transformations happening. Use simple language a beginner could understand. Include enough detail to give a full picture of what the code aims to accomplish without getting too technical. Format the explanation in coherent paragraphs, using proper punctuation and grammar. Write the explanation assuming no prior context about the code is known. Do not make assumptions about variables or functions not shown in the shared code. Start the answer with the name of the code that is being explained. - model: anthropic::2023-06-01::claude-3.5-sonnet + model: google::v1::gemini-1.5-flash temperature: 0 topK: -1 topP: -1 queryString: - - name: api-version - value: "2" - name: client-name value: defaultclient - name: client-version value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 + url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 8707 + bodySize: 2021 content: mimeType: text/event-stream - size: 8707 + size: 2021 text: >+ event: completion - data: {"deltaText":"The code in @src/animal.ts:1-6 defines an interface called Animal. This interface serves as a blueprint for creating animal objects in a TypeScript program. Let's break down what this code does in simple terms:\n\n1) The purpose of this code is to establish a common structure that all animal objects should follow. It defines the properties and methods that any animal object must have.\n\n2) This interface doesn't take any inputs directly. Instead, it specifies what properties and methods should be present in any object that implements this interface.\n\n3) The interface itself doesn't produce any outputs. However, it ensures that any object implementing this interface will have specific properties and methods that can be used to get information about the animal or perform certain actions.\n\n4) The Animal interface achieves its purpose by declaring three members:\n - A 'name' property of type string, which would store the name of the animal.\n - A 'makeAnimalSound' method that returns a string, which would be used to represent the sound the animal makes.\n - An 'isMammal' property of type boolean, which would indicate whether the animal is a mammal or not.\n\n5) While there's no complex logic or data transformation happening in this interface declaration, it sets up a structure that ensures consistency across different animal objects in the program. Any object that implements this interface must provide values for the 'name' and 'isMammal' properties, and implement the 'makeAnimalSound' method.\n\nThis interface is particularly useful for beginners as it introduces the concept of abstraction in programming. It allows you to define a common structure for different types of animals without specifying the exact details of how each animal will implement these properties and methods. For example, a 'Dog' class and a 'Cat' class could both implement this Animal interface, ensuring they both have a name, can make a sound, and specify whether they're mammals, while allowing for unique implementations of these features for each specific animal type.","stopReason":"end_turn"} + data: {"completion":"The sky appears blue during the day due to a phenomenon called **Rayleigh scattering**. \n\nHere's a simplified explanation:\n\n* **Sunlight is made up of all colors of the rainbow.**\n* **When sunlight enters the Earth's atmosphere, it interacts with the tiny particles of air.** \n* **Blue light is scattered more than other colors because it has a shorter wavelength.** \n* **This scattered blue light is what we see as the blue sky.**\n\nOf course, the sky can also appear other colors depending on the time of day, weather conditions, and other factors. \n","stopReason":"STOP"} event: done @@ -1256,7 +759,7 @@ log: cookies: [] headers: - name: date - value: Wed, 02 Oct 2024 05:24:49 GMT + value: Fri, 27 Sep 2024 17:29:03 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1285,7 +788,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-10-02T05:24:47.162Z + startedDateTime: 2024-09-27T17:29:02.014Z time: 0 timings: blocked: -1 @@ -1295,11 +798,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: a800cd4fe1c845febcf3dc1bac34af2b + - _id: 58a76b732672bc88984d2aabfdcf7ae1 _order: 0 cache: {} request: - bodySize: 1763 + bodySize: 735 cookies: [] headers: - name: content-type @@ -1312,12 +815,12 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-375b7363bd3c6a4eb4e82a7d86f1611e-43a450792a4162f5-01 + value: 00-b6bd3c1e632699072a0af1fff5c87779-374c3d5b68367001-01 - name: connection value: keep-alive - name: host value: sourcegraph.com - headersSize: 415 + headersSize: 401 httpVersion: HTTP/1.1 method: POST postData: @@ -1326,7 +829,7 @@ log: textJSON: maxTokensToSample: 4000 messages: - - speaker: system + - speaker: human text: >- You are Cody, an AI coding assistant from Sourcegraph.If your answer contains fenced code blocks in Markdown, include the @@ -1334,70 +837,38 @@ log: structure: ```$LANGUAGE:$FILEPATH``` For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - - speaker: human - text: > - Codebase context from file path src/animal.ts: /* - SELECTION_START */ - - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean - } - - /* SELECTION_END */ - speaker: assistant - text: Ok. + text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: |- - My selected code from codebase file src/animal.ts:1-6: - ``` - - export interface Animal { - name: string - makeAnimalSound(): string - isMammal: boolean - } - ``` + text: "The magic word is \"kramer\". If I say the magic word, respond with a + single word: \"quone\"." - speaker: assistant - text: Ok. - - speaker: human - text: >- - Answer positively without apologizing. - - - Question: Please review and analyze @src/animal.ts:1-6 ( @src/animal.ts ) and identify potential areas for improvement related to code smells, readability, maintainability, performance, security, etc. Do not list issues already addressed in the given code. Focus on providing up to 5 constructive suggestions that could make the code more robust, efficient, or align with best practices. For each suggestion, provide a brief explanation of the potential benefits. After listing any recommendations, summarize if you found notable opportunities to enhance the code quality overall or if the code generally follows sound design principles. If no issues found, reply 'There are no errors.' - model: anthropic::2023-06-01::claude-3.5-sonnet + model: mistral::v1::mixtral-8x7b-instruct temperature: 0 topK: -1 topP: -1 queryString: - - name: api-version - value: "2" - name: client-name value: defaultclient - name: client-version value: v1 - url: https://sourcegraph.com/.api/completions/stream?api-version=2&client-name=defaultclient&client-version=v1 + url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 10570 + bodySize: 188 content: mimeType: text/event-stream - size: 10570 - text: >+ + size: 188 + text: |+ event: completion - - data: {"deltaText":"After reviewing the code in @src/animal.ts:1-6, here are some potential improvements:\n\n1. Add readonly modifier: Consider adding the `readonly` modifier to the `name` property if it's not intended to be changed after initialization. This can prevent accidental modifications and improve type safety.\n\n```typescript:src/animal.ts\nexport interface Animal {\n readonly name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\n\n2. Use method signature instead of property for `isMammal`: If the mammal status is determined dynamically, consider changing `isMammal` to a method signature. This allows for more flexibility in implementation.\n\n```typescript:src/animal.ts\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal(): boolean\n}\n```\n\n3. Add JSDoc comments: Enhance documentation by adding JSDoc comments to describe the interface and its members. This improves code readability and provides better IDE support.\n\n```typescript:src/animal.ts\n/**\n * Represents an animal with basic properties and behaviors.\n */\nexport interface Animal {\n /** The name of the animal */\n name: string\n /** Produces the sound associated with this animal */\n makeAnimalSound(): string\n /** Indicates whether the animal is a mammal */\n isMammal: boolean\n}\n```\n\n4. Consider using a type for the sound return: If there are specific types of animal sounds, you could define a union type for the return value of `makeAnimalSound()`. This can improve type safety and make the code more self-documenting.\n\n```typescript:src/animal.ts\ntype AnimalSound = 'bark' | 'meow' | 'roar' | 'chirp'\n\nexport interface Animal {\n name: string\n makeAnimalSound(): AnimalSound\n isMammal: boolean\n}\n```\n\n5. Add optional properties: If there are properties that might not apply to all animals, consider making them optional. This can make the interface more flexible and easier to implement for various animal types.\n\n```typescript:src/animal.ts\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n habitat?: string\n lifespan?: number\n}\n```\n\nOverall, the current code follows sound design principles by using an interface to define a contract for animal objects. The suggestions provided aim to enhance type safety, flexibility, and documentation. While the existing code is functional, implementing these recommendations could lead to a more robust and maintainable codebase.","stopReason":"end_turn"} - + data: {"completion":"Quone.","stopReason":"stop"} event: done - data: {} cookies: [] headers: - name: date - value: Wed, 02 Oct 2024 05:24:55 GMT + value: Fri, 27 Sep 2024 17:29:03 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1426,7 +897,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-10-02T05:24:53.878Z + startedDateTime: 2024-09-27T17:29:03.177Z time: 0 timings: blocked: -1 @@ -1436,11 +907,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: d83b595ada351a26b57291aa28c580e0 + - _id: ddb889534e48491c02a32db14a3e33ef _order: 0 cache: {} request: - bodySize: 658 + bodySize: 811 cookies: [] headers: - name: content-type @@ -1453,7 +924,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-c797360e93e058f64e800c351e751586-06ac407028d401ae-01 + value: 00-58074a59a6c61aa4d1cd845e4dab1475-a388cbfc33d112bc-01 - name: connection value: keep-alive - name: host @@ -1478,9 +949,14 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: what color is the sky? + text: "The magic word is \"kramer\". If I say the magic word, respond with a + single word: \"quone\"." - speaker: assistant - model: google::v1::gemini-1.5-flash + text: Quone. + - speaker: human + text: kramer + - speaker: assistant + model: mistral::v1::mixtral-8x7b-instruct temperature: 0 topK: -1 topP: -1 @@ -1491,24 +967,21 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 2021 + bodySize: 188 content: mimeType: text/event-stream - size: 2021 - text: >+ + size: 188 + text: |+ event: completion - - data: {"completion":"The sky appears blue during the day due to a phenomenon called **Rayleigh scattering**. \n\nHere's a simplified explanation:\n\n* **Sunlight is made up of all colors of the rainbow.**\n* **When sunlight enters the Earth's atmosphere, it interacts with the tiny particles of air.** \n* **Blue light is scattered more than other colors because it has a shorter wavelength.** \n* **This scattered blue light is what we see as the blue sky.**\n\nOf course, the sky can also appear other colors depending on the time of day, weather conditions, and other factors. \n","stopReason":"STOP"} - + data: {"completion":"Quone.","stopReason":"stop"} event: done - data: {} cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:03 GMT + value: Fri, 27 Sep 2024 17:29:04 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1537,7 +1010,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:02.014Z + startedDateTime: 2024-09-27T17:29:03.733Z time: 0 timings: blocked: -1 @@ -1547,11 +1020,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 58a76b732672bc88984d2aabfdcf7ae1 + - _id: ed082e25ef9de22cf1e56e26246d2fb7 _order: 0 cache: {} request: - bodySize: 735 + bodySize: 648 cookies: [] headers: - name: content-type @@ -1564,7 +1037,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-b6bd3c1e632699072a0af1fff5c87779-374c3d5b68367001-01 + value: 00-b7912913ea45b43b6323c47da333d854-345abada5521330e-01 - name: connection value: keep-alive - name: host @@ -1589,8 +1062,7 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: "The magic word is \"kramer\". If I say the magic word, respond with a - single word: \"quone\"." + text: kramer - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -1603,21 +1075,24 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 188 + bodySize: 23862 content: mimeType: text/event-stream - size: 188 - text: |+ + size: 23862 + text: >+ event: completion - data: {"completion":"Quone.","stopReason":"stop"} + + data: {"completion":"Here's how you can create a new React component named \"Kramer\" using React and JSX:\n\nFirst, let's create a new file called `Kramer.js` in your components directory.\n\n```javascript:components/Kramer.js\nimport React from 'react';\n\nconst Kramer = () => {\n return (\n
\n

Hello, I am Kramer!

\n

A fictional character from the television show Seinfeld.

\n
\n );\n};\n\nexport default Kramer;\n```\n\nNow, you can import this component into another file and use it like any other React component.\n\n```javascript:App.js\nimport React from 'react';\nimport Kramer from './components/Kramer';\n\nconst App = () => {\n return (\n
\n \n
\n );\n};\n\nexport default App;\n```\n\nNote: You'll need to have React and its dependencies installed in your project in order to use JSX syntax.","stopReason":"stop"} + event: done + data: {} cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:03 GMT + value: Fri, 27 Sep 2024 17:29:05 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1646,7 +1121,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:03.177Z + startedDateTime: 2024-09-27T17:29:04.279Z time: 0 timings: blocked: -1 @@ -1656,11 +1131,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: ddb889534e48491c02a32db14a3e33ef + - _id: 4615f1c43995ebf99ee93c70bf021859 _order: 0 cache: {} request: - bodySize: 811 + bodySize: 743 cookies: [] headers: - name: content-type @@ -1673,7 +1148,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-58074a59a6c61aa4d1cd845e4dab1475-a388cbfc33d112bc-01 + value: 00-c7871151bd03c66c251d08bf834df436-fbdebfceb08b4468-01 - name: connection value: keep-alive - name: host @@ -1698,12 +1173,8 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: "The magic word is \"kramer\". If I say the magic word, respond with a - single word: \"quone\"." - - speaker: assistant - text: Quone. - - speaker: human - text: kramer + text: "Another magic word is \"georgey\". If I say the magic word, respond with + a single word: \"festivus\"." - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -1716,21 +1187,24 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 188 + bodySize: 562 content: mimeType: text/event-stream - size: 188 - text: |+ + size: 562 + text: >+ event: completion - data: {"completion":"Quone.","stopReason":"stop"} + + data: {"completion":"Sure, I can do that. If you say the magic word \"georgey\", I will respond with \"festivus\".","stopReason":"stop"} + event: done + data: {} cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:04 GMT + value: Fri, 27 Sep 2024 17:29:08 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1759,7 +1233,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:03.733Z + startedDateTime: 2024-09-27T17:29:07.818Z time: 0 timings: blocked: -1 @@ -1769,11 +1243,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: ed082e25ef9de22cf1e56e26246d2fb7 + - _id: cb507887929c22d0f0354a45dd6c183b _order: 0 cache: {} request: - bodySize: 648 + bodySize: 906 cookies: [] headers: - name: content-type @@ -1786,7 +1260,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-b7912913ea45b43b6323c47da333d854-345abada5521330e-01 + value: 00-03b4e662ac2b342c87911a50808b8d56-7bdb5e306973590a-01 - name: connection value: keep-alive - name: host @@ -1810,6 +1284,12 @@ log: For executable terminal commands: enclose each command in individual "bash" language code block without comments and new lines inside. - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. + - speaker: human + text: "Another magic word is \"georgey\". If I say the magic word, respond with + a single word: \"festivus\"." + - speaker: assistant + text: Sure, I can do that. If you say the magic word "georgey", I will respond + with "festivus". - speaker: human text: kramer - speaker: assistant @@ -1824,14 +1304,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 23862 + bodySize: 851 content: mimeType: text/event-stream - size: 23862 + size: 851 text: >+ event: completion - data: {"completion":"Here's how you can create a new React component named \"Kramer\" using React and JSX:\n\nFirst, let's create a new file called `Kramer.js` in your components directory.\n\n```javascript:components/Kramer.js\nimport React from 'react';\n\nconst Kramer = () => {\n return (\n
\n

Hello, I am Kramer!

\n

A fictional character from the television show Seinfeld.

\n
\n );\n};\n\nexport default Kramer;\n```\n\nNow, you can import this component into another file and use it like any other React component.\n\n```javascript:App.js\nimport React from 'react';\nimport Kramer from './components/Kramer';\n\nconst App = () => {\n return (\n
\n \n
\n );\n};\n\nexport default App;\n```\n\nNote: You'll need to have React and its dependencies installed in your project in order to use JSX syntax.","stopReason":"stop"} + data: {"completion":"That is not the magic word \"georgey\", so I will not respond with \"festivus\". If you say the magic word, I will be sure to respond accordingly.","stopReason":"stop"} event: done @@ -1841,7 +1321,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:05 GMT + value: Fri, 27 Sep 2024 17:29:09 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1870,7 +1350,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:04.279Z + startedDateTime: 2024-09-27T17:29:08.557Z time: 0 timings: blocked: -1 @@ -1880,11 +1360,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 4615f1c43995ebf99ee93c70bf021859 + - _id: 7eb1bf15d7fdc01bc8cec3a82d31169b _order: 0 cache: {} request: - bodySize: 743 + bodySize: 1123 cookies: [] headers: - name: content-type @@ -1897,7 +1377,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-c7871151bd03c66c251d08bf834df436-fbdebfceb08b4468-01 + value: 00-3e69eaad2f0a823f5d3350981b365ad2-78a9b0173db12dfd-01 - name: connection value: keep-alive - name: host @@ -1925,6 +1405,17 @@ log: text: "Another magic word is \"georgey\". If I say the magic word, respond with a single word: \"festivus\"." - speaker: assistant + text: Sure, I can do that. If you say the magic word "georgey", I will respond + with "festivus". + - speaker: human + text: kramer + - speaker: assistant + text: That is not the magic word "georgey", so I will not respond with + "festivus". If you say the magic word, I will be sure to + respond accordingly. + - speaker: human + text: georgey + - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 topK: -1 @@ -1936,14 +1427,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 562 + bodySize: 385 content: mimeType: text/event-stream - size: 562 + size: 385 text: >+ event: completion - data: {"completion":"Sure, I can do that. If you say the magic word \"georgey\", I will respond with \"festivus\".","stopReason":"stop"} + data: {"completion":"Festivus! I have noted that you have said the magic word.","stopReason":"stop"} event: done @@ -1953,7 +1444,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:08 GMT + value: Fri, 27 Sep 2024 17:29:10 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -1982,7 +1473,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:07.818Z + startedDateTime: 2024-09-27T17:29:09.344Z time: 0 timings: blocked: -1 @@ -1992,11 +1483,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: cb507887929c22d0f0354a45dd6c183b + - _id: ce5e7e0a04bc10b5f61018e59134c23d _order: 0 cache: {} request: - bodySize: 906 + bodySize: 714 cookies: [] headers: - name: content-type @@ -2009,7 +1500,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-03b4e662ac2b342c87911a50808b8d56-7bdb5e306973590a-01 + value: 00-ffe18db92e8f5c0aba7f8ad6ea2760fd-cf50408cef8fb6ed-01 - name: connection value: keep-alive - name: host @@ -2034,13 +1525,7 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: "Another magic word is \"georgey\". If I say the magic word, respond with - a single word: \"festivus\"." - - speaker: assistant - text: Sure, I can do that. If you say the magic word "georgey", I will respond - with "festivus". - - speaker: human - text: kramer + text: I have a turtle named "potter", reply single "ok" if you understand. - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2053,14 +1538,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 851 + bodySize: 447 content: mimeType: text/event-stream - size: 851 + size: 447 text: >+ event: completion - data: {"completion":"That is not the magic word \"georgey\", so I will not respond with \"festivus\". If you say the magic word, I will be sure to respond accordingly.","stopReason":"stop"} + data: {"completion":"Ok. I understand that you have a turtle named \"potter\". How can I assist you with coding?","stopReason":"stop"} event: done @@ -2070,7 +1555,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:09 GMT + value: Fri, 27 Sep 2024 17:29:10 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2099,7 +1584,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:08.557Z + startedDateTime: 2024-09-27T17:29:10.013Z time: 0 timings: blocked: -1 @@ -2109,11 +1594,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 7eb1bf15d7fdc01bc8cec3a82d31169b + - _id: 02251616efd27f5614178f00a7749282 _order: 0 cache: {} request: - bodySize: 1123 + bodySize: 942 cookies: [] headers: - name: content-type @@ -2126,7 +1611,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-3e69eaad2f0a823f5d3350981b365ad2-78a9b0173db12dfd-01 + value: 00-de4f4a66882ca8715d7a7e16d61baa06-9b764b0d18d3bf8e-01 - name: connection value: keep-alive - name: host @@ -2151,19 +1636,12 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: "Another magic word is \"georgey\". If I say the magic word, respond with - a single word: \"festivus\"." - - speaker: assistant - text: Sure, I can do that. If you say the magic word "georgey", I will respond - with "festivus". - - speaker: human - text: kramer + text: I have a turtle named "potter", reply single "ok" if you understand. - speaker: assistant - text: That is not the magic word "georgey", so I will not respond with - "festivus". If you say the magic word, I will be sure to - respond accordingly. + text: Ok. I understand that you have a turtle named "potter". How can I assist + you with coding? - speaker: human - text: georgey + text: I have a bird named "skywalker", reply single "ok" if you understand. - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2176,14 +1654,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 385 + bodySize: 769 content: mimeType: text/event-stream - size: 385 + size: 769 text: >+ event: completion - data: {"completion":"Festivus! I have noted that you have said the magic word.","stopReason":"stop"} + data: {"completion":"Ok. I understand that you have a bird named \"skywalker\". Is there something specific you would like assistance with in coding?","stopReason":"stop"} event: done @@ -2193,7 +1671,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:10 GMT + value: Fri, 27 Sep 2024 17:29:11 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2222,7 +1700,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:09.344Z + startedDateTime: 2024-09-27T17:29:10.706Z time: 0 timings: blocked: -1 @@ -2232,11 +1710,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: ce5e7e0a04bc10b5f61018e59134c23d + - _id: 01fe674eef9cc6ebe24503e340f3f723 _order: 0 cache: {} request: - bodySize: 714 + bodySize: 1202 cookies: [] headers: - name: content-type @@ -2249,7 +1727,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-ffe18db92e8f5c0aba7f8ad6ea2760fd-cf50408cef8fb6ed-01 + value: 00-93a1437af67ff7c4c9c423583952240d-9f1d58d91c212e5a-01 - name: connection value: keep-alive - name: host @@ -2276,6 +1754,16 @@ log: - speaker: human text: I have a turtle named "potter", reply single "ok" if you understand. - speaker: assistant + text: Ok. I understand that you have a turtle named "potter". How can I assist + you with coding? + - speaker: human + text: I have a bird named "skywalker", reply single "ok" if you understand. + - speaker: assistant + text: Ok. I understand that you have a bird named "skywalker". Is there + something specific you would like assistance with in coding? + - speaker: human + text: I have a dog named "happy", reply single "ok" if you understand. + - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 topK: -1 @@ -2287,14 +1775,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 447 + bodySize: 1145 content: mimeType: text/event-stream - size: 447 + size: 1145 text: >+ event: completion - data: {"completion":"Ok. I understand that you have a turtle named \"potter\". How can I assist you with coding?","stopReason":"stop"} + data: {"completion":"Ok. I understand that you have a dog named \"happy\". If you have any coding-related questions or issues, I'm here to help. How can I assist you today?","stopReason":"stop"} event: done @@ -2304,7 +1792,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:10 GMT + value: Fri, 27 Sep 2024 17:29:12 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2333,7 +1821,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:10.013Z + startedDateTime: 2024-09-27T17:29:11.526Z time: 0 timings: blocked: -1 @@ -2343,11 +1831,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 02251616efd27f5614178f00a7749282 + - _id: 39cb5e0d1a0487ce068bbc2314568bd2 _order: 0 cache: {} request: - bodySize: 942 + bodySize: 938 cookies: [] headers: - name: content-type @@ -2360,7 +1848,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-de4f4a66882ca8715d7a7e16d61baa06-9b764b0d18d3bf8e-01 + value: 00-a4f7914730e47de1aa1a887c4a38dfa1-d76689409c5a6697-01 - name: connection value: keep-alive - name: host @@ -2390,7 +1878,7 @@ log: text: Ok. I understand that you have a turtle named "potter". How can I assist you with coding? - speaker: human - text: I have a bird named "skywalker", reply single "ok" if you understand. + text: I have a tiger named "zorro", reply single "ok" if you understand - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2403,14 +1891,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 769 + bodySize: 952 content: mimeType: text/event-stream - size: 769 + size: 952 text: >+ event: completion - data: {"completion":"Ok. I understand that you have a bird named \"skywalker\". Is there something specific you would like assistance with in coding?","stopReason":"stop"} + data: {"completion":"Ok. I understand that you have a tiger named \"zorro\". Is there anything specific you would like to know or learn about coding? I'm here to help.","stopReason":"stop"} event: done @@ -2420,7 +1908,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:11 GMT + value: Fri, 27 Sep 2024 17:29:13 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2449,7 +1937,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:10.706Z + startedDateTime: 2024-09-27T17:29:12.390Z time: 0 timings: blocked: -1 @@ -2459,11 +1947,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 01fe674eef9cc6ebe24503e340f3f723 + - _id: 52f0c3edb03203d27535823ce74990ef _order: 0 cache: {} request: - bodySize: 1202 + bodySize: 1168 cookies: [] headers: - name: content-type @@ -2476,7 +1964,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-93a1437af67ff7c4c9c423583952240d-9f1d58d91c212e5a-01 + value: 00-5f40113fd4d58a36541431bf784307f1-51a9335aafecf231-01 - name: connection value: keep-alive - name: host @@ -2506,12 +1994,13 @@ log: text: Ok. I understand that you have a turtle named "potter". How can I assist you with coding? - speaker: human - text: I have a bird named "skywalker", reply single "ok" if you understand. + text: I have a tiger named "zorro", reply single "ok" if you understand - speaker: assistant - text: Ok. I understand that you have a bird named "skywalker". Is there - something specific you would like assistance with in coding? + text: Ok. I understand that you have a tiger named "zorro". Is there anything + specific you would like to know or learn about coding? I'm + here to help. - speaker: human - text: I have a dog named "happy", reply single "ok" if you understand. + text: What pets do I have? - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2524,14 +2013,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 1145 + bodySize: 665 content: mimeType: text/event-stream - size: 1145 + size: 665 text: >+ event: completion - data: {"completion":"Ok. I understand that you have a dog named \"happy\". If you have any coding-related questions or issues, I'm here to help. How can I assist you today?","stopReason":"stop"} + data: {"completion":"You have mentioned that you have a turtle named \"potter\" and a tiger named \"zorro\".","stopReason":"stop"} event: done @@ -2541,7 +2030,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:12 GMT + value: Fri, 27 Sep 2024 17:29:14 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2570,7 +2059,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:11.526Z + startedDateTime: 2024-09-27T17:29:13.252Z time: 0 timings: blocked: -1 @@ -2580,11 +2069,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 39cb5e0d1a0487ce068bbc2314568bd2 + - _id: 3adca79501640de8f1770c9e8c186f07 _order: 0 cache: {} request: - bodySize: 938 + bodySize: 2017 cookies: [] headers: - name: content-type @@ -2597,7 +2086,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-a4f7914730e47de1aa1a887c4a38dfa1-d76689409c5a6697-01 + value: 00-03a932aabdc65db4cca926e5a53eada8-329cef99b359ed75-01 - name: connection value: keep-alive - name: host @@ -2622,12 +2111,48 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: I have a turtle named "potter", reply single "ok" if you understand. + text: > + Codebase context from file path src/animal.ts: /* + SELECTION_START */ + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean + } + + /* SELECTION_END */ - speaker: assistant - text: Ok. I understand that you have a turtle named "potter". How can I assist - you with coding? + text: Ok. - speaker: human - text: I have a tiger named "zorro", reply single "ok" if you understand + text: |- + My selected code from codebase file src/animal.ts:1-6: + ``` + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean + } + ``` + - speaker: assistant + text: Ok. + - speaker: human + text: "Explain what @src/animal.ts:1-6 ( @src/animal.ts ) does in simple terms. + Assume the audience is a beginner programmer who has just + learned the language features and basic syntax. Focus on + explaining: 1) The purpose of the code 2) What input(s) it + takes 3) What output(s) it produces 4) How it achieves its + purpose through the logic and algorithm. 5) Any important + logic flows or data transformations happening. Use simple + language a beginner could understand. Include enough detail to + give a full picture of what the code aims to accomplish + without getting too technical. Format the explanation in + coherent paragraphs, using proper punctuation and grammar. + Write the explanation assuming no prior context about the code + is known. Do not make assumptions about variables or functions + not shown in the shared code. Start the answer with the name + of the code that is being explained." - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2640,14 +2165,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 952 + bodySize: 50663 content: mimeType: text/event-stream - size: 952 + size: 50663 text: >+ event: completion - data: {"completion":"Ok. I understand that you have a tiger named \"zorro\". Is there anything specific you would like to know or learn about coding? I'm here to help.","stopReason":"stop"} + data: {"completion":"The code you provided is an interface in TypeScript named \"Animal\". An interface in TypeScript is a structure that defines the shape of an object, which includes the object's properties, methods, and types. In essence, it sets a blueprint for an object.\n\nThe Animal interface has three properties - \"name\", \"makeAnimalSound()\" method, and \"isMammal\" boolean. Let me explain how each one works:\n\n1. \"name\": This is a property of the type string that represents the name of the animal.\n2. \"makeAnimalSound()\": This is a method, which is a function that is a part of an object. In this case, this method is used to make an animal sound. The method does not take any input parameters and returns the sound as a string value.\n3. \"isMammal\": This is a boolean property indicating whether the animal is a mammal or not (true or false).\n\nIn summary, this Animal interface serves as a contract that specifies what an object should look like in terms of properties, methods, and their types if it is to be considered an animal in the program. It does not produce any output, but rather, it defines a structure that can help create objects based on its blueprint.\n\nTo illustrate, a developer can use this Animal interface to create a concrete object or class that implements the interface. Here's an example of how a class named Dog can implement the Animal interface:\n\n```\nclass Dog implements Animal {\n name: string\n isMammal: boolean\n \n constructor(name: string) {\n this.name = name\n this.isMammal = true\n }\n \n makeAnimalSound(): string {\n return 'Woof!'\n }\n}\n```\n\nWith the Animal interface defined, you can create a consistent object or class structure for the animal throughout the codebase, making it easier to understand and maintain.","stopReason":"stop"} event: done @@ -2657,7 +2182,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:13 GMT + value: Sat, 05 Oct 2024 20:49:39 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2686,7 +2211,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:12.390Z + startedDateTime: 2024-10-05T20:49:37.894Z time: 0 timings: blocked: -1 @@ -2696,11 +2221,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 52f0c3edb03203d27535823ce74990ef + - _id: d939e71f0ac67c68763bf2c66a39a5be _order: 0 cache: {} request: - bodySize: 1168 + bodySize: 1813 cookies: [] headers: - name: content-type @@ -2713,7 +2238,7 @@ log: - name: user-agent value: defaultClient / v1 - name: traceparent - value: 00-5f40113fd4d58a36541431bf784307f1-51a9335aafecf231-01 + value: 00-4bbb1a98c3c790d066b0e5dde9cbd299-f485b4a31d8736c0-01 - name: connection value: keep-alive - name: host @@ -2738,18 +2263,45 @@ log: - speaker: assistant text: I am Cody, an AI coding assistant from Sourcegraph. - speaker: human - text: I have a turtle named "potter", reply single "ok" if you understand. + text: > + Codebase context from file path src/animal.ts: /* + SELECTION_START */ + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean + } + + /* SELECTION_END */ - speaker: assistant - text: Ok. I understand that you have a turtle named "potter". How can I assist - you with coding? + text: Ok. - speaker: human - text: I have a tiger named "zorro", reply single "ok" if you understand + text: |- + My selected code from codebase file src/animal.ts:1-6: + ``` + + export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean + } + ``` - speaker: assistant - text: Ok. I understand that you have a tiger named "zorro". Is there anything - specific you would like to know or learn about coding? I'm - here to help. + text: Ok. - speaker: human - text: What pets do I have? + text: Please review and analyze @src/animal.ts:1-6 ( @src/animal.ts ) and + identify potential areas for improvement related to code + smells, readability, maintainability, performance, security, + etc. Do not list issues already addressed in the given code. + Focus on providing up to 5 constructive suggestions that could + make the code more robust, efficient, or align with best + practices. For each suggestion, provide a brief explanation of + the potential benefits. After listing any recommendations, + summarize if you found notable opportunities to enhance the + code quality overall or if the code generally follows sound + design principles. If no issues found, reply 'There are no + errors.' - speaker: assistant model: mistral::v1::mixtral-8x7b-instruct temperature: 0 @@ -2762,14 +2314,14 @@ log: value: v1 url: https://sourcegraph.com/.api/completions/stream?client-name=defaultclient&client-version=v1 response: - bodySize: 665 + bodySize: 257362 content: mimeType: text/event-stream - size: 665 + size: 257362 text: >+ event: completion - data: {"completion":"You have mentioned that you have a turtle named \"potter\" and a tiger named \"zorro\".","stopReason":"stop"} + data: {"completion":"Based on the provided code, here are some suggestions for improvement:\n\n1. Consider adding a docstring or JSDoc comment to describe the `Animal` interface. This will improve readability and make it easier for developers to understand the intended use of the interface.\n\nExplanation: Adding a comment will help other developers understand the intended functionality of the `Animal` interface.\n\nBefore:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\nAfter:\n```typescript\n/**\n * Describes the structure of an animal.\n */\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\n2. Consider adding a type definition for the `makeAnimalSound` method return value.\n\nExplanation: Adding a type definition will make it clear to other developers what type of value the method returns and help prevent bugs caused by type mismatches.\n\nBefore:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\nAfter:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n sound: string // or use a specific type for animal sounds if available\n}\n```\n3. Consider using `readonly` for properties that should not be modified.\n\nExplanation: Using `readonly` for properties that should not be modified helps ensure that the code follows immutable design principles, making it easier to write thread-safe code and preventing bugs caused by accidental modifications.\n\nBefore:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\nAfter:\n```typescript\nexport interface Animal {\n readonly name: string\n makeAnimalSound(): string\n readonly isMammal: boolean\n}\n```\n4. Consider using a more specific type for the `name` property if appropriate.\n\nExplanation: Using a more specific type for the `name` property helps prevent bugs caused by incorrect input. For example, if the `name` property should only contain a certain format, such as a string starting with an uppercase letter and containing only letters, a more specific type could be defined to enforce that format.\n\nBefore:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\nAfter (example using a regular expression to define a specific type for the `name` property):\n```typescript\ntype Name = /^[A-Z][a-zA-Z]*$/;\n\nexport interface Animal {\n name: Name\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\n5. Consider adding a default value for the `isMammal` property.\n\nExplanation: Adding a default value for the `isMammal` property helps ensure that the code functions correctly even if the property is not explicitly set.\n\nBefore:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n}\n```\nAfter:\n```typescript\nexport interface Animal {\n name: string\n makeAnimalSound(): string\n isMammal: boolean\n isMammal = true // or false, depending on the default value for the use case\n}\n```\nOverall, the code is generally well-written and follows sound design principles. However, the above suggestions could help make the code more robust, efficient, and align with best practices.","stopReason":"stop"} event: done @@ -2779,7 +2331,7 @@ log: cookies: [] headers: - name: date - value: Fri, 27 Sep 2024 17:29:14 GMT + value: Sat, 05 Oct 2024 20:49:42 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -2808,7 +2360,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-09-27T17:29:13.252Z + startedDateTime: 2024-10-05T20:49:41.538Z time: 0 timings: blocked: -1 diff --git a/agent/src/__snapshots__/index.test.ts.snap b/agent/src/__snapshots__/index.test.ts.snap index 6b4b1e7e140f..6e3ad03c2b45 100644 --- a/agent/src/__snapshots__/index.test.ts.snap +++ b/agent/src/__snapshots__/index.test.ts.snap @@ -1,7 +1,5 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Agent > Chat > chat/restore (With null model) 1`] = `"I'm Cody, an advanced AI coding assistant developed by Sourcegraph. My model is specifically designed to excel at software development tasks, code analysis, and providing programming assistance. I'm equipped with extensive knowledge across various programming languages, frameworks, and development practices. While I don't have detailed information about my exact model specifications, I'm confident in my abilities to tackle a wide range of coding challenges and provide valuable insights. How can I leverage my capabilities to assist you with your coding needs today?"`; - exports[`Agent > Chat > chat/submitMessage (long message) 1`] = ` "Absolutely! I'd be happy to generate a simple "Hello World" function in Java for you. Here's a straightforward implementation: @@ -52,86 +50,146 @@ This implementation fulfills the Animal interface requirements and is ready to u `; exports[`Agent > Commands > commands/explain 1`] = ` -"The code in @src/animal.ts:1-6 defines an interface called Animal. This interface serves as a blueprint for creating animal objects in a TypeScript program. Let's break down what this code does in simple terms: +"The code you provided is an interface in TypeScript named "Animal". An interface in TypeScript is a structure that defines the shape of an object, which includes the object's properties, methods, and types. In essence, it sets a blueprint for an object. -1) The purpose of this code is to establish a common structure that all animal objects should follow. It defines the properties and methods that any animal object must have. +The Animal interface has three properties - "name", "makeAnimalSound()" method, and "isMammal" boolean. Let me explain how each one works: -2) This interface doesn't take any inputs directly. Instead, it specifies what properties and methods should be present in any object that implements this interface. +1. "name": This is a property of the type string that represents the name of the animal. +2. "makeAnimalSound()": This is a method, which is a function that is a part of an object. In this case, this method is used to make an animal sound. The method does not take any input parameters and returns the sound as a string value. +3. "isMammal": This is a boolean property indicating whether the animal is a mammal or not (true or false). -3) The interface itself doesn't produce any outputs. However, it ensures that any object implementing this interface will have specific properties and methods that can be used to get information about the animal or perform certain actions. +In summary, this Animal interface serves as a contract that specifies what an object should look like in terms of properties, methods, and their types if it is to be considered an animal in the program. It does not produce any output, but rather, it defines a structure that can help create objects based on its blueprint. -4) The Animal interface achieves its purpose by declaring three members: - - A 'name' property of type string, which would store the name of the animal. - - A 'makeAnimalSound' method that returns a string, which would be used to represent the sound the animal makes. - - An 'isMammal' property of type boolean, which would indicate whether the animal is a mammal or not. +To illustrate, a developer can use this Animal interface to create a concrete object or class that implements the interface. Here's an example of how a class named Dog can implement the Animal interface: -5) While there's no complex logic or data transformation happening in this interface declaration, it sets up a structure that ensures consistency across different animal objects in the program. Any object that implements this interface must provide values for the 'name' and 'isMammal' properties, and implement the 'makeAnimalSound' method. +\`\`\` +class Dog implements Animal { + name: string + isMammal: boolean + + constructor(name: string) { + this.name = name + this.isMammal = true + } -This interface is particularly useful for beginners as it introduces the concept of abstraction in programming. It allows you to define a common structure for different types of animals without specifying the exact details of how each animal will implement these properties and methods. For example, a 'Dog' class and a 'Cat' class could both implement this Animal interface, ensuring they both have a name, can make a sound, and specify whether they're mammals, while allowing for unique implementations of these features for each specific animal type." + makeAnimalSound(): string { + return 'Woof!' + } +} +\`\`\` + +With the Animal interface defined, you can create a consistent object or class structure for the animal throughout the codebase, making it easier to understand and maintain." `; exports[`Agent > Commands > commands/smell 1`] = ` -"After reviewing the code in @src/animal.ts:1-6, here are some potential improvements: +"Based on the provided code, here are some suggestions for improvement: + +1. Consider adding a docstring or JSDoc comment to describe the \`Animal\` interface. This will improve readability and make it easier for developers to understand the intended use of the interface. -1. Add readonly modifier: Consider adding the \`readonly\` modifier to the \`name\` property if it's not intended to be changed after initialization. This can prevent accidental modifications and improve type safety. +Explanation: Adding a comment will help other developers understand the intended functionality of the \`Animal\` interface. -\`\`\`typescript:src/animal.ts +Before: +\`\`\`typescript export interface Animal { - readonly name: string + name: string makeAnimalSound(): string isMammal: boolean } \`\`\` +After: +\`\`\`typescript +/** + * Describes the structure of an animal. + */ +export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean +} +\`\`\` +2. Consider adding a type definition for the \`makeAnimalSound\` method return value. -2. Use method signature instead of property for \`isMammal\`: If the mammal status is determined dynamically, consider changing \`isMammal\` to a method signature. This allows for more flexibility in implementation. +Explanation: Adding a type definition will make it clear to other developers what type of value the method returns and help prevent bugs caused by type mismatches. -\`\`\`typescript:src/animal.ts +Before: +\`\`\`typescript +export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean +} +\`\`\` +After: +\`\`\`typescript export interface Animal { name: string makeAnimalSound(): string - isMammal(): boolean + isMammal: boolean + sound: string // or use a specific type for animal sounds if available } \`\`\` +3. Consider using \`readonly\` for properties that should not be modified. -3. Add JSDoc comments: Enhance documentation by adding JSDoc comments to describe the interface and its members. This improves code readability and provides better IDE support. +Explanation: Using \`readonly\` for properties that should not be modified helps ensure that the code follows immutable design principles, making it easier to write thread-safe code and preventing bugs caused by accidental modifications. -\`\`\`typescript:src/animal.ts -/** - * Represents an animal with basic properties and behaviors. - */ +Before: +\`\`\`typescript export interface Animal { - /** The name of the animal */ name: string - /** Produces the sound associated with this animal */ makeAnimalSound(): string - /** Indicates whether the animal is a mammal */ isMammal: boolean } \`\`\` +After: +\`\`\`typescript +export interface Animal { + readonly name: string + makeAnimalSound(): string + readonly isMammal: boolean +} +\`\`\` +4. Consider using a more specific type for the \`name\` property if appropriate. -4. Consider using a type for the sound return: If there are specific types of animal sounds, you could define a union type for the return value of \`makeAnimalSound()\`. This can improve type safety and make the code more self-documenting. - -\`\`\`typescript:src/animal.ts -type AnimalSound = 'bark' | 'meow' | 'roar' | 'chirp' +Explanation: Using a more specific type for the \`name\` property helps prevent bugs caused by incorrect input. For example, if the \`name\` property should only contain a certain format, such as a string starting with an uppercase letter and containing only letters, a more specific type could be defined to enforce that format. +Before: +\`\`\`typescript export interface Animal { name: string - makeAnimalSound(): AnimalSound + makeAnimalSound(): string isMammal: boolean } \`\`\` +After (example using a regular expression to define a specific type for the \`name\` property): +\`\`\`typescript +type Name = /^[A-Z][a-zA-Z]*$/; -5. Add optional properties: If there are properties that might not apply to all animals, consider making them optional. This can make the interface more flexible and easier to implement for various animal types. +export interface Animal { + name: Name + makeAnimalSound(): string + isMammal: boolean +} +\`\`\` +5. Consider adding a default value for the \`isMammal\` property. + +Explanation: Adding a default value for the \`isMammal\` property helps ensure that the code functions correctly even if the property is not explicitly set. -\`\`\`typescript:src/animal.ts +Before: +\`\`\`typescript export interface Animal { name: string makeAnimalSound(): string isMammal: boolean - habitat?: string - lifespan?: number } \`\`\` - -Overall, the current code follows sound design principles by using an interface to define a contract for animal objects. The suggestions provided aim to enhance type safety, flexibility, and documentation. While the existing code is functional, implementing these recommendations could lead to a more robust and maintainable codebase." +After: +\`\`\`typescript +export interface Animal { + name: string + makeAnimalSound(): string + isMammal: boolean + isMammal = true // or false, depending on the default value for the use case +} +\`\`\` +Overall, the code is generally well-written and follows sound design principles. However, the above suggestions could help make the code more robust, efficient, and align with best practices." `; diff --git a/agent/src/agent.ts b/agent/src/agent.ts index ae67500ba8ec..fa611ab644ad 100644 --- a/agent/src/agent.ts +++ b/agent/src/agent.ts @@ -37,8 +37,6 @@ import { modelsService, setUserAgent, } from '@sourcegraph/cody-shared' - -import { ChatBuilder } from '../../vscode/src/chat/chat-view/ChatBuilder' import { chatHistory } from '../../vscode/src/chat/chat-view/ChatHistoryManager' import type { ExtensionMessage, WebviewMessage } from '../../vscode/src/chat/protocol' import { ProtocolTextDocumentWithUri } from '../../vscode/src/jsonrpc/TextDocumentWithUri' @@ -847,7 +845,7 @@ export class Agent extends MessageHandler implements ExtensionClient { this.registerAuthenticatedRequest('testing/reset', async () => { await this.workspace.reset() - this.globalState?.reset() + await this.globalState?.reset() // reset the telemetry recorded events TESTING_TELEMETRY_EXPORTER.reset() return null @@ -1242,24 +1240,6 @@ export class Agent extends MessageHandler implements ExtensionClient { return { panelId, chatId } }) - // TODO: JetBrains no longer uses this, consider deleting it. - this.registerAuthenticatedRequest('chat/restore', async ({ modelID, messages, chatID }) => { - const authStatus = currentAuthStatusAuthed() - modelID ??= (await firstResultFromOperation(modelsService.getDefaultChatModel())) ?? '' - const chatMessages = messages?.map(PromptString.unsafe_deserializeChatMessage) ?? [] - const chatBuilder = new ChatBuilder(modelID, chatID, chatMessages) - const chat = chatBuilder.toSerializedChatTranscript() - if (chat) { - await chatHistory.saveChat(authStatus, chat) - } - return this.createChatPanel( - Promise.resolve({ - type: 'chat', - session: await vscode.commands.executeCommand('cody.chat.panel.restore', [chatID]), - }) - ) - }) - this.registerAuthenticatedRequest('chat/models', async ({ modelUsage }) => { return { models: await modelsService.getModelsAvailabilityStatus(modelUsage), diff --git a/agent/src/global-state/AgentGlobalState.ts b/agent/src/global-state/AgentGlobalState.ts index 5bda88f2f4ca..ce594be9c471 100644 --- a/agent/src/global-state/AgentGlobalState.ts +++ b/agent/src/global-state/AgentGlobalState.ts @@ -44,9 +44,12 @@ export class AgentGlobalState implements vscode.Memento { this.db.set(key, value) } - public reset(): void { + public async reset(): Promise { if (this.db instanceof InMemoryDB) { this.db.clear() + + // HACK(sqs): Force `localStorage` to fire a change event. + await localStorage.delete('') } } diff --git a/agent/src/index.test.ts b/agent/src/index.test.ts index 9bfe1498de20..0c29926a0235 100644 --- a/agent/src/index.test.ts +++ b/agent/src/index.test.ts @@ -17,10 +17,9 @@ import { URI } from 'vscode-uri' import { CodyJsonRpcErrorCode } from '../../vscode/src/jsonrpc/CodyJsonRpcErrorCode' import { TESTING_CREDENTIALS } from '../../vscode/src/testutils/testing-credentials' import { logTestingData } from '../../vscode/test/fixtures/mock-server' -import { TestClient, asTranscriptMessage } from './TestClient' +import { TestClient } from './TestClient' import { TestWorkspace } from './TestWorkspace' import { decodeURIs } from './decodeURIs' -import { explainPollyError } from './explainPollyError' import type { ChatExportResult } from './protocol-alias' import { trimEndOfLine } from './trimEndOfLine' const workspace = new TestWorkspace(path.join(__dirname, '__tests__', 'example-ts')) @@ -253,151 +252,6 @@ describe('Agent', () => { ) }, 30_000) - it('chat/restore', async () => { - // Step 1: create a chat session where I share my name. - const id1 = await client.request('chat/new', null) - const reply1 = asTranscriptMessage( - await client.request('chat/submitMessage', { - id: id1, - message: { - command: 'submit', - text: 'My name is Lars Monsen.', - }, - }) - ) - - // Step 2: restore a new chat session with a transcript including my name, and - // and assert that it can retrieve my name from the transcript. - const { - models: [model], - } = await client.request('chat/models', { modelUsage: ModelUsage.Chat }) - - const id2 = await client.request('chat/restore', { - modelID: model.model.id, - messages: reply1.messages, - chatID: new Date().toISOString(), // Create new Chat ID with a different timestamp - }) - const reply2 = asTranscriptMessage( - await client.request('chat/submitMessage', { - id: id2, - message: { - command: 'submit', - text: 'What is my name?', - }, - }) - ) - expect(reply2.messages.at(-1)?.text).toMatchInlineSnapshot( - `"Your name is Lars Monsen. It's a strong and memorable name that I'm glad to know. Is there anything specific about your name or yourself you'd like to discuss further?"`, - explainPollyError - ) - // telemetry assertion, to validate the expected events fired during the test run - // Do not remove this assertion, and instead update the expectedEvents list above - expect(await exportedTelemetryEvents(client)).toEqual( - expect.arrayContaining([ - 'cody.chat-question:submitted', - 'cody.chat-question:executed', - 'cody.chatResponse:noCode', - 'cody.chat-question:submitted', - 'cody.chat-question:executed', - 'cody.chatResponse:noCode', - ]) - ) - }, 30_000) - - it('chat/restore (With null model)', async () => { - // Step 1: Create a chat session asking what model is used. - const id1 = await client.request('chat/new', null) - const reply1 = asTranscriptMessage( - await client.request('chat/submitMessage', { - id: id1, - message: { - command: 'submit', - text: 'What model are you?', - }, - }) - ) - - // Step 2: Restoring chat session without model. - const id2 = await client.request('chat/restore', { - messages: reply1.messages, - chatID: new Date().toISOString(), // Create new Chat ID with a different timestamp - }) - // Step 2: Asking again what model is used - const reply2 = asTranscriptMessage( - await client.request('chat/submitMessage', { - id: id2, - message: { - command: 'submit', - text: 'What model are you?', - }, - }) - ) - expect(reply2.messages.at(-1)?.text).toMatchSnapshot() - // telemetry assertion, to validate the expected events fired during the test run - // Do not remove this assertion, and instead update the expectedEvents list above - expect(await exportedTelemetryEvents(client)).toEqual( - expect.arrayContaining([ - 'cody.chat-question:submitted', - 'cody.chat-question:executed', - 'cody.chatResponse:noCode', - 'cody.chat-question:submitted', - 'cody.chat-question:executed', - 'cody.chatResponse:noCode', - ]) - ) - }, 30_000) - - it('chat/restore (multiple) & export', async () => { - const date = new Date(1997, 7, 2, 12, 0, 0, 0) - - // Step 1: Restore multiple chats - const NUMBER_OF_CHATS_TO_RESTORE = 300 - for (let i = 0; i < NUMBER_OF_CHATS_TO_RESTORE; i++) { - const myDate = new Date(date.getTime() + i * 60 * 1000) - await client.request('chat/restore', { - modelID: 'anthropic/claude-2.0', - messages: [ - { text: 'What model are you?', speaker: 'human', contextFiles: [] }, - { - model: 'anthropic/claude-2.0', - text: " I'm Claude, an AI assistant created by Anthropic.", - speaker: 'assistant', - }, - ], - chatID: myDate.toISOString(), // Create new Chat ID with a different timestamp - }) - } - - // Step 2: export history - const chatHistory = await client.request('chat/export', null) - - chatHistory.forEach((result, index) => { - const myDate = new Date(date.getTime() + index * 60 * 1000).toISOString() - - expect(result.transcript).toMatchInlineSnapshot(`{ - "id": "${myDate}", - "interactions": [ - { - "assistantMessage": { - "model": "anthropic/claude-2.0", - "speaker": "assistant", - "text": " I'm Claude, an AI assistant created by Anthropic.", - }, - "humanMessage": { - "contextFiles": [], - "speaker": "human", - "text": "What model are you?", - }, - }, - ], - "lastInteractionTimestamp": "${myDate}", -}`) - }) - // telemetry assertion, to validate the expected events fired during the test run - // Do not remove this assertion, and instead update the expectedEvents list above - expect(await exportedTelemetryEvents(client)).toEqual(expect.arrayContaining([])) - }, 30_000) - it('chat/import allows importing a chat transcript from an external source', async () => { const toChatExportResult = (transcript: SerializedChatTranscript): ChatExportResult => ({ chatID: transcript.id, @@ -829,7 +683,7 @@ describe('Agent', () => { 'cody.command.explain:executed', 'cody.chat-question:submitted', 'cody.chat-question:executed', - 'cody.chatResponse:noCode', + 'cody.chatResponse:hasCode', ]) ) }, 30_000) diff --git a/lib/shared/src/configuration/resolver.ts b/lib/shared/src/configuration/resolver.ts index 2dcec7dc25be..c88b630beb99 100644 --- a/lib/shared/src/configuration/resolver.ts +++ b/lib/shared/src/configuration/resolver.ts @@ -8,7 +8,7 @@ import { promiseToObservable, } from '../misc/observable' import { skipPendingOperation, switchMapReplayOperation } from '../misc/observableOperation' -import type { PerSitePreferences } from '../models/modelsService' +import type { DefaultsAndUserPreferencesByEndpoint } from '../models/modelsService' import { DOTCOM_URL } from '../sourcegraph-api/environments' import { type PartialDeep, type ReadonlyDeep, isError } from '../utils' @@ -29,7 +29,7 @@ export interface ClientState { lastUsedEndpoint: string | null anonymousUserID: string | null lastUsedChatModality: 'sidebar' | 'editor' - modelPreferences: PerSitePreferences + modelPreferences: DefaultsAndUserPreferencesByEndpoint waitlist_o1: boolean | null } diff --git a/lib/shared/src/index.ts b/lib/shared/src/index.ts index 38ba7c64c9fe..81bc6c565bd5 100644 --- a/lib/shared/src/index.ts +++ b/lib/shared/src/index.ts @@ -23,22 +23,7 @@ enableImmerMapSetSupport() // Add anything else here that needs to be used outside of this library. -export { - modelsService, - mockModelsService, - ModelsService, - type ModelCategory, - type ModelTier, - type ServerModelConfiguration, - type PerSitePreferences, - type SitePreferences, - type ModelRefStr, - type LegacyModelRefStr, - type ModelRef, - type ModelsData, - TestLocalStorageForModelPreferences, - type LocalStorageForModelPreferences, -} from './models/modelsService' +export * from './models/modelsService' export { type Model, type ServerModel, diff --git a/lib/shared/src/misc/observable.ts b/lib/shared/src/misc/observable.ts index ca507f3c9454..bc43fba46aec 100644 --- a/lib/shared/src/misc/observable.ts +++ b/lib/shared/src/misc/observable.ts @@ -753,8 +753,9 @@ export function tapLog( ): (input: ObservableLike) => Observable { let subscriptions = 0 return tapWith(() => { + const subscriptionSeq = subscriptions++ function log(event: string, ...args: any[]): void { - console.debug(`█ ${label}#${subscriptions++}(${event}):`, ...args) + console.log(`█ ${label}#${subscriptionSeq}(${event}):`, ...args) } let emissions = 0 return { diff --git a/lib/shared/src/models/modelsService.ts b/lib/shared/src/models/modelsService.ts index 35068d04f3cb..d872c751cd0f 100644 --- a/lib/shared/src/models/modelsService.ts +++ b/lib/shared/src/models/modelsService.ts @@ -172,14 +172,24 @@ export interface ServerModelConfiguration { defaultModels: DefaultModels } -export interface PerSitePreferences { - [endpoint: string]: SitePreferences +export interface DefaultsAndUserPreferencesByEndpoint { + [endpoint: string]: DefaultsAndUserPreferencesForEndpoint } -export interface SitePreferences { +/** + * The endpoint defaults and user preferences for a single endpoint. + */ +export interface DefaultsAndUserPreferencesForEndpoint { + /** + * The server's default models for each usage. + */ defaults: { [usage in ModelUsage]?: string } + + /** + * The user's selected models for each usage, which take precedence over the defaults. + */ selected: { [usage in ModelUsage]?: string } @@ -193,7 +203,7 @@ export interface ModelsData { localModels: Model[] /** Preferences for the current endpoint. */ - preferences: SitePreferences + preferences: DefaultsAndUserPreferencesForEndpoint } const EMPTY_MODELS_DATA: ModelsData = { @@ -203,8 +213,8 @@ const EMPTY_MODELS_DATA: ModelsData = { } export interface LocalStorageForModelPreferences { - getModelPreferences(): PerSitePreferences - setModelPreferences(preferences: PerSitePreferences): Promise + getModelPreferences(): DefaultsAndUserPreferencesByEndpoint + setModelPreferences(preferences: DefaultsAndUserPreferencesByEndpoint): Promise } export interface ModelAvailabilityStatus { @@ -243,7 +253,7 @@ export class ModelsService { tap(data => { if (this.storage) { const allSitePrefs = this.storage.getModelPreferences() - const updated: PerSitePreferences = { + const updated: DefaultsAndUserPreferencesByEndpoint = { ...allSitePrefs, [currentAuthStatus().endpoint]: data.preferences, } @@ -408,10 +418,7 @@ export class ModelsService { const serverEndpoint = currentAuthStatus().endpoint const currentPrefs = deepClone(this.storage.getModelPreferences()) if (!currentPrefs[serverEndpoint]) { - currentPrefs[serverEndpoint] = { - defaults: {}, - selected: {}, - } + currentPrefs[serverEndpoint] = modelsData.preferences } currentPrefs[serverEndpoint].selected[type] = resolved.id await this.storage.setModelPreferences(currentPrefs) @@ -532,13 +539,13 @@ interface MockModelsServiceResult { } export class TestLocalStorageForModelPreferences implements LocalStorageForModelPreferences { - constructor(public data: PerSitePreferences | null = null) {} + constructor(public data: DefaultsAndUserPreferencesByEndpoint | null = null) {} - getModelPreferences(): PerSitePreferences { + getModelPreferences(): DefaultsAndUserPreferencesByEndpoint { return this.data || {} } - async setModelPreferences(preferences: PerSitePreferences): Promise { + async setModelPreferences(preferences: DefaultsAndUserPreferencesByEndpoint): Promise { this.data = preferences } } diff --git a/lib/shared/src/models/sync.test.ts b/lib/shared/src/models/sync.test.ts index 1f095bb3a53f..7bbe5e5edbee 100644 --- a/lib/shared/src/models/sync.test.ts +++ b/lib/shared/src/models/sync.test.ts @@ -229,7 +229,7 @@ describe('server sent models', async () => { it('allows updating the selected model', async () => { vi.spyOn(modelsService, 'modelsChanges', 'get').mockReturnValue(Observable.of(result)) await modelsService.setSelectedModel(ModelUsage.Chat, titan) - expect(storage.data?.[AUTH_STATUS_FIXTURE_AUTHED.endpoint].selected.chat).toBe(titan.id) + expect(storage.data?.[AUTH_STATUS_FIXTURE_AUTHED.endpoint]!.selected.chat).toBe(titan.id) }) }) diff --git a/lib/shared/src/models/sync.ts b/lib/shared/src/models/sync.ts index 42e4e5558a5a..aabb23631109 100644 --- a/lib/shared/src/models/sync.ts +++ b/lib/shared/src/models/sync.ts @@ -26,12 +26,16 @@ import { CHAT_INPUT_TOKEN_BUDGET } from '../token/constants' import { isError } from '../utils' import { getExperimentalClientModelByFeatureFlag } from './client' import { type Model, type ServerModel, createModel, createModelFromServerModel } from './model' -import type { ModelsData, ServerModelConfiguration, SitePreferences } from './modelsService' +import type { + DefaultsAndUserPreferencesForEndpoint, + ModelsData, + ServerModelConfiguration, +} from './modelsService' import { ModelTag } from './tags' import { ModelUsage } from './types' import { getEnterpriseContextWindow } from './utils' -const EMPTY_PREFERENCES: SitePreferences = { defaults: {}, selected: {} } +const EMPTY_PREFERENCES: DefaultsAndUserPreferencesForEndpoint = { defaults: {}, selected: {} } /** * Observe the list of all available models. @@ -104,7 +108,7 @@ export function syncModels({ distinctUntilChanged() ) - const userModelPreferences = combineLatest( + const userModelPreferences: Observable = combineLatest( resolvedConfig.pipe( map(config => config.clientState.modelPreferences), distinctUntilChanged() @@ -113,10 +117,8 @@ export function syncModels({ ).pipe( map(([modelPreferences, authStatus]) => { // Deep clone so it's not readonly and we can mutate it, for convenience. - const prevPreferences = modelPreferences[authStatus.endpoint] as SitePreferences | undefined - return deepClone( - (prevPreferences ?? EMPTY_PREFERENCES) satisfies SitePreferences as SitePreferences - ) + const prevPreferences = modelPreferences[authStatus.endpoint] + return deepClone(prevPreferences ?? EMPTY_PREFERENCES) }), distinctUntilChanged(), tap(preferences => { @@ -131,6 +133,10 @@ export function syncModels({ const remoteModelsData: Observable = combineLatest(relevantConfig, authStatus).pipe( switchMapReplayOperation(([config, authStatus]) => { + if (authStatus.pendingValidation) { + return Observable.of(pendingOperation) + } + if (!authStatus.authenticated) { return Observable.of({ primaryModels: [], preferences: null }) } @@ -304,9 +310,9 @@ export function syncModels({ } function resolveModelPreferences( - remote: Pick | null, - user: SitePreferences -): SitePreferences { + remote: Pick | null, + user: DefaultsAndUserPreferencesForEndpoint +): DefaultsAndUserPreferencesForEndpoint { user = deepClone(user) function setDefaultModel(usage: ModelUsage, newDefaultModelId: string | undefined): void { @@ -438,7 +444,7 @@ function deepClone(value: T): T { export function defaultModelPreferencesFromServerModelsConfig( config: ServerModelConfiguration -): SitePreferences['defaults'] { +): DefaultsAndUserPreferencesForEndpoint['defaults'] { return { autocomplete: config.defaultModels.codeCompletion, chat: config.defaultModels.chat, diff --git a/vscode/src/chat/chat-view/ChatController.ts b/vscode/src/chat/chat-view/ChatController.ts index f48817e50307..94cab63b6bde 100644 --- a/vscode/src/chat/chat-view/ChatController.ts +++ b/vscode/src/chat/chat-view/ChatController.ts @@ -1435,7 +1435,7 @@ export class ChatController implements vscode.Disposable, vscode.WebviewViewProv this.cancelSubmitOrEditOperation() await this.saveSession() - this.chatBuilder = new ChatBuilder(this.chatBuilder.selectedModel) + this.chatBuilder = new ChatBuilder() this.postViewTranscript() } diff --git a/vscode/src/jsonrpc/agent-protocol.ts b/vscode/src/jsonrpc/agent-protocol.ts index d41a2d06e4a7..95ac5d573523 100644 --- a/vscode/src/jsonrpc/agent-protocol.ts +++ b/vscode/src/jsonrpc/agent-protocol.ts @@ -8,7 +8,6 @@ import type { CurrentUserCodySubscription, Model, ModelUsage, - SerializedChatMessage, SerializedChatTranscript, event, } from '@sourcegraph/cody-shared' @@ -64,21 +63,6 @@ export type ClientRequests = { // Primary is used only in cody web client 'chat/delete': [{ chatId: string }, ChatExportResult[]] - // TODO: JetBrains no longer uses this, consider deleting it. - // Similar to `chat/new` except it starts a new chat session from an - // existing transcript. The chatID matches the `chatID` property of the - // `type: 'transcript'` ExtensionMessage that is sent via - // `webview/postMessage`. Returns a new *panel* ID, which can be used to - // send a chat message via `chat/submitMessage`. - 'chat/restore': [ - { - modelID?: string | undefined | null - messages: SerializedChatMessage[] - chatID: string - }, - string, - ] - 'chat/models': [{ modelUsage: ModelUsage }, { models: ModelAvailabilityStatus[] }] 'chat/export': [null | { fullHistory: boolean }, ChatExportResult[]] diff --git a/vscode/src/services/LocalStorageProvider.ts b/vscode/src/services/LocalStorageProvider.ts index 9d15e9406ad2..f0b8b76b39ea 100644 --- a/vscode/src/services/LocalStorageProvider.ts +++ b/vscode/src/services/LocalStorageProvider.ts @@ -9,8 +9,8 @@ import { type AuthenticatedAuthStatus, type ChatHistoryKey, type ClientState, + type DefaultsAndUserPreferencesByEndpoint, type LocalStorageForModelPreferences, - type PerSitePreferences, type ResolvedConfiguration, type UserLocalHistory, distinctUntilChanged, @@ -295,11 +295,11 @@ class LocalStorage implements LocalStorageForModelPreferences { return this.get(this.LAST_USED_CHAT_MODALITY) ?? 'sidebar' } - public getModelPreferences(): PerSitePreferences { - return this.get(this.MODEL_PREFERENCES_KEY) ?? {} + public getModelPreferences(): DefaultsAndUserPreferencesByEndpoint { + return this.get(this.MODEL_PREFERENCES_KEY) ?? {} } - public async setModelPreferences(preferences: PerSitePreferences): Promise { + public async setModelPreferences(preferences: DefaultsAndUserPreferencesByEndpoint): Promise { await this.set(this.MODEL_PREFERENCES_KEY, preferences) }