diff --git a/agent/CHANGELOG.md b/agent/CHANGELOG.md index f1930f7ca5df..268d906e30b1 100644 --- a/agent/CHANGELOG.md +++ b/agent/CHANGELOG.md @@ -10,6 +10,15 @@ This is a log of all notable changes to the Cody command-line tool. [Unreleased] ### Changed +## 5.5.12 + +### Fixed + +- `cody chat --context-file` will now fail fast if the provided file is too + large to fit into the context window. Previously, `cody chat` silently ignored + this error and the LLM would respond with a confusing message about missing + context. To bypass this check, use `--ignore-context-window-errors`. + ## 5.5.11 ### Fixed diff --git a/agent/package.json b/agent/package.json index bb1172413c4b..1698a1168fd3 100644 --- a/agent/package.json +++ b/agent/package.json @@ -1,6 +1,6 @@ { "name": "@sourcegraph/cody", - "version": "5.5.11", + "version": "5.5.12", "description": "Cody CLI is the same technology that powers Cody in the IDE but available from the command-line.", "license": "Apache-2.0", "repository": { @@ -13,6 +13,7 @@ "scripts": { "build:root": "pnpm -C .. run -s build", "build:agent": "node src/esbuild.mjs", + "build:for-tests": "pnpm run -s build:root && pnpm run -s build:agent", "build:webviews": "pnpm -C ../vscode _build:webviews --mode production --outDir ../../agent/dist/webviews", "build": "pnpm run -s build:root && pnpm run -s build:webviews && pnpm run -s build:agent", "build-minify": "pnpm run build --minify", diff --git a/agent/recordings/cody-chat_103640681/recording.har.yaml b/agent/recordings/cody-chat_103640681/recording.har.yaml index 443772c18fd7..310c1f5a26e1 100644 --- a/agent/recordings/cody-chat_103640681/recording.har.yaml +++ b/agent/recordings/cody-chat_103640681/recording.har.yaml @@ -36,26 +36,24 @@ log: queryString: [] url: https://sourcegraph.sourcegraph.com/.api/client-config response: - bodySize: 191 + bodySize: 183 content: encoding: base64 mimeType: text/plain; charset=utf-8 - size: 191 - text: "[\"H4sIAAAAAAAAA2zMsQpCMQyF4b1PEe7sE7hJcXBzc861EQtNI80pKnLf3UVwyfz953wSE\ - dFytfI+dl6blGVPGFN2P7gzQuAJy6aPJpB4OR2m2VS5F48/gFHXiWo9dFceyNYhL1xq\ - L/YMM7UizQ/n019v3FzSlr4AAAD//w==\",\"AwCYZZ0K3wAAAA==\"]" + size: 183 + text: "[\"H4sIAAAAAAAAA2zMsQoCMRCE4T5PEa6+J7CTYGF3nfWeu2AguyvJBBXx3W1shK2/f+adc\ + s55uTq/TkZ7E14OGX3K+oMbIQSa\",\"8OJ6bwKJl3PAtbgqGY/4A+h1n6huoQ+ljuI\ + GeeJSjf0RZuosbRy387+mT/oCAAD//wMAc0i0Et4AAAA=\"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:58 GMT + value: Tue, 13 Aug 2024 19:01:28 GMT - name: content-type value: text/plain; charset=utf-8 - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -75,12 +73,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1365 + headersSize: 1258 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.806Z + startedDateTime: 2024-08-13T19:01:28.077Z time: 0 timings: blocked: -1 @@ -90,11 +88,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 67bca6fe77aa075277907719042acf02 + - _id: b5ceae943af989c36c626faa496b3c02 _order: 0 cache: {} request: - bodySize: 278 + bodySize: 259 cookies: [] headers: - name: content-type @@ -123,7 +121,7 @@ log: text: You are Cody, an AI coding assistant from Sourcegraph. - speaker: human text: respond with "hello" and nothing else - model: anthropic/claude-3-5-sonnet-20240620 + model: claude-3.5-sonnet temperature: 0.2 topK: -1 topP: -1 @@ -150,15 +148,13 @@ log: cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:59 GMT + value: Tue, 13 Aug 2024 19:01:31 GMT - name: content-type value: text/event-stream - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "522" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -176,12 +172,12 @@ log: value: 1; mode=block - name: strict-transport-security value: max-age=31536000; includeSubDomains; preload - headersSize: 1322 + headersSize: 1215 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:58.201Z + startedDateTime: 2024-08-13T19:01:29.569Z time: 0 timings: blocked: -1 @@ -191,11 +187,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 7e06b3087ccb0cbc2c410b6309126d40 + - _id: b33f9ea19dd116f2ef31b76450455f55 _order: 0 cache: {} request: - bodySize: 403 + bodySize: 532 cookies: [] headers: - name: content-type @@ -222,14 +218,23 @@ log: messages: - speaker: system text: You are Cody, an AI coding assistant from Sourcegraph. + - speaker: human + text: |- + Codebase context from file animal.ts: + ```typescript + interface StrangeAnimal { + makesSound(): 'coo' | 'moo' + } + ``` + - speaker: assistant + text: Ok. - speaker: human text: >- - You have access to the provided codebase context. Answer - positively without apologizing. + You have access to the provided codebase context. Question: implement a cow. Only print the code without any explanation. - model: anthropic/claude-3-5-sonnet-20240620 + model: claude-3.5-sonnet temperature: 0.2 topK: -1 topP: -1 @@ -242,14 +247,14 @@ log: value: 6.0.0-SNAPSHOT url: https://sourcegraph.sourcegraph.com/.api/completions/stream?api-version=1&client-name=jetbrains&client-version=6.0.0-SNAPSHOT response: - bodySize: 17000 + bodySize: 1297 content: mimeType: text/event-stream - size: 17000 + size: 1297 text: >+ event: completion - data: {"completion":"Here's a simple implementation of a cow in Python:\n\n```python\nclass Cow:\n def __init__(self, name):\n self.name = name\n self.milk = 0\n\n def moo(self):\n return f\"{self.name} says: Moo!\"\n\n def produce_milk(self, amount):\n self.milk += amount\n return f\"{self.name} produced {amount} liters of milk.\"\n\n def get_milk(self):\n milk_produced = self.milk\n self.milk = 0\n return f\"Collected {milk_produced} liters of milk from {self.name}.\"\n```","stopReason":"end_turn"} + data: {"completion":"```typescript\nclass Cow implements StrangeAnimal {\n makesSound(): 'coo' | 'moo' {\n return 'moo';\n }\n}\n```","stopReason":"end_turn"} event: done @@ -259,7 +264,7 @@ log: cookies: [] headers: - name: date - value: Fri, 19 Jul 2024 04:09:33 GMT + value: Tue, 13 Aug 2024 19:01:34 GMT - name: content-type value: text/event-stream - name: transfer-encoding @@ -288,121 +293,7 @@ log: redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-19T04:09:31.538Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - - _id: 6d68e70caae8b436c57cef420e5762cc - _order: 0 - cache: {} - request: - bodySize: 916 - cookies: [] - headers: - - name: content-type - value: application/json - - name: accept-encoding - value: gzip;q=0 - - name: authorization - value: token - REDACTED_964f5256e709a8c5c151a63d8696d5c7ac81604d179405864d88ff48a9232364 - - name: user-agent - value: jetbrains / 6.0.0-SNAPSHOT - - name: connection - value: keep-alive - - name: host - value: sourcegraph.sourcegraph.com - headersSize: 371 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json - params: [] - textJSON: - fast: true - maxTokensToSample: 400 - messages: - - speaker: human - text: You are Cody, an AI coding assistant from Sourcegraph. - - speaker: assistant - text: I am Cody, an AI coding assistant from Sourcegraph. - - speaker: human - text: "You are helping the user search over a codebase. List some filename - fragments that would match files relevant to read to answer - the user's query. Present your results in a *single* XML list - in the following format: a single - keyworda space separated list of synonyms - and variants of the keyword, including acronyms, - abbreviations, and expansionsa numerical - weight between 0.0 and 1.0 that indicates the importance of - the keyword. Here is the user - query: what is squirrel? Explain as briefly as - possible." - - speaker: assistant - temperature: 0 - topK: 1 - queryString: - - name: client-name - value: jetbrains - - name: client-version - value: 6.0.0-SNAPSHOT - url: https://sourcegraph.sourcegraph.com/.api/completions/stream?client-name=jetbrains&client-version=6.0.0-SNAPSHOT - response: - bodySize: 8530 - content: - mimeType: text/event-stream - size: 8530 - text: >+ - event: completion - - data: {"completion":"\u003ckeywords\u003e\n\u003ckeyword\u003e\n\u003cvalue\u003esquirrel\u003c/value\u003e\n\u003cvariants\u003esquirrels sciuridae rodent\u003c/variants\u003e\n\u003cweight\u003e1.0\u003c/weight\u003e\n\u003c/keyword\u003e\n\u003ckeyword\u003e\n\u003cvalue\u003eoverview\u003c/value\u003e\n\u003cvariants\u003esummary brief explanation\u003c/variants\u003e\n\u003cweight\u003e0.8\u003c/weight\u003e\n\u003c/keyword\u003e\n\u003c/keywords\u003e","stopReason":"end_turn"} - - - event: done - - data: {} - - cookies: [] - headers: - - name: date - value: Tue, 16 Jul 2024 15:15:01 GMT - - name: content-type - value: text/event-stream - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: retry-after - value: "520" - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache - - name: vary - value: 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: 1322 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-07-16T15:15:00.436Z + startedDateTime: 2024-08-13T19:01:33.443Z time: 0 timings: blocked: -1 @@ -462,26 +353,28 @@ log: value: null url: https://sourcegraph.sourcegraph.com/.api/graphql?ContextFilters response: - bodySize: 163 + bodySize: 104 content: encoding: base64 mimeType: application/json - size: 163 - text: "[\"H4sIAAAAAAAAAxTIQQqAIBBG4bvMMqgDuA1aRvtoMehPBJOKTmSIdw/f5oNXybEymUr5U\ - nRtcN8cvKLocoki5X4Tvx0UK48Dmb1SQgwr39hYFcmToWkQ9ueIwncUTAO1o/V+AAAA\ - //8=\",\"AwBK/4wNZQAAAA==\"]" + size: 104 + text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqzixJBdHJ+SmVzvl5JakVJW6ZOSWpRcUg0aLEciWrv\ + NKcnNra2loAAAAA//8DADYuyGU1AAAA\"]" + textDecoded: + data: + site: + codyContextFilters: + raw: null cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:58 GMT + value: Tue, 13 Aug 2024 19:01:28 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -501,12 +394,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.815Z + startedDateTime: 2024-08-13T19:01:28.603Z time: 0 timings: blocked: -1 @@ -571,37 +464,25 @@ log: value: null url: https://sourcegraph.sourcegraph.com/.api/graphql?CurrentSiteCodyLlmConfiguration response: - bodySize: 248 + bodySize: 227 content: encoding: base64 mimeType: application/json - size: 248 - text: "[\"H4sIAAAAAAAAA3zOTQrCMBAF4LvMuqFj6g9222278wJDktrQmilJikrJ3aWKKBZcDTze+\ - 5gZNEWCcoZgo1muYn2v66Zi19rz5Clads+8o9iwNgOUQC52nkercjXQpI0oxE4Eds5E\ - IVFucS8Rss+koduJe+MClBuJiBm0FGL1X+zI9tOLK/AAP5s1qfgyDmZ594221psr+z7\ - kIZJXrI2HVe8LOiJiSik9AAAA//8DABY6yDgVAQAA\"]" - textDecoded: - data: - site: - codyLLMConfiguration: - chatModel: anthropic/claude-3-5-sonnet-20240620 - chatModelMaxTokens: 12000 - completionModel: fireworks/starcoder - completionModelMaxTokens: 9000 - fastChatModel: anthropic/claude-3-haiku-20240307 - fastChatModelMaxTokens: 12000 + size: 227 + text: "[\"H4sIAAAAAAAAA4TOwQrCMAzG8XfJedPiFKTXXbfbXiC02VaczWhTUEbfXeZlygRPgY8/P\ + 7KARUHQC0QntF7D9tk0bc2+d0MKKI79ex9RWrY0\",\"gYbIKRgaAs7j0UyYLJXV4VJ\ + G9p4Eiq1t8dHxjXwEXSmlVAE9Rqn/UBv0Ve8xw/d5ovXDX1wUDIYtBdiVH9RJna855/\ + wCAAD//wMALGYOWAoBAAA=\"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:57 GMT + value: Tue, 13 Aug 2024 19:01:27 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -621,12 +502,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.338Z + startedDateTime: 2024-08-13T19:01:27.603Z time: 0 timings: blocked: -1 @@ -692,20 +573,18 @@ log: mimeType: application/json size: 139 text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqzixJBdHJ+SmVPj6+zvl5aZnppUWJJZn5eWD53MSiE\ - uf8vJLUipLwzLyU/HIlK6XUvMSknNQUpdra2loAAAAA//8=\",\"AwDoCDSlSwAAAA==\ + uf8vJLUipLwzLyU/HIlK6WUzOLEpJzUFKXa2tpa\",\"AAAAAP//AwArMNn0TAAAAA==\ \"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:57 GMT + value: Tue, 13 Aug 2024 19:01:27 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -725,12 +604,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.377Z + startedDateTime: 2024-08-13T19:01:27.641Z time: 0 timings: blocked: -1 @@ -790,30 +669,23 @@ log: value: null url: https://sourcegraph.sourcegraph.com/.api/graphql?CurrentSiteCodyLlmProvider response: - bodySize: 128 + bodySize: 131 content: encoding: base64 mimeType: application/json - size: 128 + size: 131 text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqzixJBdHJ+SmVPj6+zvl5aZnppUWJJZn5eSDxgqL8s\ - syU1CIlK6Xi/NKi5NT0osSCDKXa2tpaAAAAAP//AwAfFAXARQAAAA==\"]" - textDecoded: - data: - site: - codyLLMConfiguration: - provider: sourcegraph + syU1CIlK6Xi/NKi5NT0osSCDKXa2tpaAAAAAP//\",\"AwAfFAXARQAAAA==\"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:57 GMT + value: Tue, 13 Aug 2024 19:01:27 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -833,12 +705,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.357Z + startedDateTime: 2024-08-13T19:01:27.622Z time: 0 timings: blocked: -1 @@ -909,38 +781,25 @@ log: value: null url: https://sourcegraph.sourcegraph.com/.api/graphql?CurrentUser response: - bodySize: 228 + bodySize: 231 content: encoding: base64 mimeType: application/json - size: 228 + size: 231 text: "[\"H4sIAAAAAAAAAzSOuwrCQBBF/2XqLawXLO0kgpggiMWQncTRzWyY2Qgx7L9LfJTncricB\ - QJmBL9AO6mS5NpIV+QAHppzFdt72hxOjy04uKE1pNwxhd2AHMF3GI0cBLYx4lzhQOBl\ - itHBZKTyYWhTmDNZZunBAT4xo9bH/d8clQfU+ff43ZL2KPzCzElszZEUyMBfrqWU8gY\ - AAP//AwAAXh5NtQAAAA==\"]" - textDecoded: - data: - currentUser: - avatarURL: null - displayName: null - hasVerifiedEmail: false - id: VXNlcjo0OTk= - organizations: - nodes: [] - primaryEmail: null - username: codytesting + QJmBL9AO6mS5NpIV+QAHppzFdt72hxOjy04uKE1\",\"pNwxhd2AHMF3GI0cBLYx4lz\ + hQOBlitHBZKTyYWhTmDNZZunBAT4xo9bH/d8clQfU+ff43ZL2KPzCzElszZEUyMBfrq\ + WU8gYAAP//AwAAXh5NtQAAAA==\"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:57 GMT + value: Tue, 13 Aug 2024 19:01:27 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -960,12 +819,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.396Z + startedDateTime: 2024-08-13T19:01:27.661Z time: 0 timings: blocked: -1 @@ -975,11 +834,11 @@ log: send: 0 ssl: -1 wait: 0 - - _id: 26ecc9d2f361f4c40e9a9bf4b2f8bea8 + - _id: e83b435a530574a277932bc0a0cad82a _order: 0 cache: {} request: - bodySize: 735 + bodySize: 101 cookies: [] headers: - _fromType: array @@ -997,258 +856,50 @@ log: value: "*/*" - _fromType: array name: content-length - value: "735" + value: "101" - _fromType: array name: accept-encoding value: gzip,deflate - name: host value: sourcegraph.sourcegraph.com - headersSize: 352 + headersSize: 356 httpVersion: HTTP/1.1 method: POST postData: mimeType: application/json; charset=utf-8 params: [] textJSON: - query: >- + query: |- - query GetCodyContext($repos: [ID!]!, $query: String!, $codeResultsCount: Int!, $textResultsCount: Int!) { - getCodyContext(repos: $repos, query: $query, codeResultsCount: $codeResultsCount, textResultsCount: $textResultsCount) { - ...on FileChunkContext { - blob { - path - repository { - id - name - } - commit { - oid - } - url - } - startLine - endLine - chunkContent - } + query SiteProductVersion { + site { + productVersion } } - variables: - codeResultsCount: 15 - query: overview squirrel - repos: - - UmVwb3NpdG9yeTozOTk= - textResultsCount: 5 - queryString: - - name: GetCodyContext - value: null - url: https://sourcegraph.sourcegraph.com/.api/graphql?GetCodyContext - response: - bodySize: 5426 - content: - encoding: base64 - mimeType: application/json - size: 5426 - text: "[\"H4sIAAAAAAAA/+w7gXLbuI6/gtXOzTk5W9o0bd+udzKzbZru5l7a9CXuu3tXZVRKgmS+S\ - KSWpJykTf79BiRly46dJu3ezd1sPJ2pDQIgCIAACDKfg5wZFow/ByWafZlf7Uth8NIE\ - 4w+fg7SSKQ01zEyDcZDVeaSv6lRWOuLCoBKsivTvLVcKq+jk4MWrNwdhnQfDQGEjNTd\ - SXRE5z4Nx8L7++0W6+7bJf/3pCify0/HkfC8YBoLVGIyDkptpm4aZrCMtW5VhqVgz7X\ - 8PboZBJuuaG2IpLU98nuY/PsOn6V+eZc+znR8xYz/uPNn96Qf2Y8qePn/2Y7aLu5gWR\ - NuqKhgH0Zcn+uW+XKNRRAqK7quWm2GgDVPmiAsMxj8MAxS5+/5kGGTTVpxb3QsTjIPv\ - 4dQziEUsgpvhLWPkMotynEUpy85LJVuRj7gopKqZ4VJE+vcq4iLHyz+hQR6ims1G2fl\ - hnVX+dkQG+bXlORMZAhM55DJraxTGcgeWytbAheKGixJoc6VMI1jHYBmhaLjgZsoFmC\ - nC6WKdwJqm4pllE9IsI/jwhpeKOSI5QzXjeHE2qOfApAOGdb61QtDH64Z/4+V01KCyy\ - iD5y5bnqGMBMIIPL5nJpiAbnHNICZIsII6PRX7DDCrOKv4Jc8hYNsWzQd2DJRY2l+tI\ - ZuekkBSnbMalOhtUDpJ0EIe6ztVD5yPRu/dHR8nJwd/eH5xOksnBm3dHLyYHZGmsSMS\ - EC83LqdF/Qpf/GhXdEY+e3XL9uP3hh93su9EIXqHOFE/Rum/TqkZqBFnYn+9OQEswU2\ - aAF3AlW6ikPMccCGCAC3gOtRRmqsHwGgl2IdsqhxQhq5ApKJSsLavOs+FiegVmyjVcM\ - A2ZQmYwh9HICoSx+P57OPaosTgUGpWB3IrY2P04RYVhaPfTYg0eL8VCKreJWWFQgc4U\ - otBTaQZ6y62jZueoSVBk+gqMBJ6jMLy4slJmUyZK1FCzHJeFOp2z0rG4hpcHr49PDqD\ - /uQZ48XpycALXsRiPNn3G13eMxaJbCq9ZiXaxcL0GBnb9PQ28b3JmnA153VS4CGDaYK\ - Pd2vV0bhxJSKR50kBHYMkLZKZVGKVtCQW/jAxmU8gxNdaiom2W9fJOyVKh1jYqwBkcL\ - s/e+GGoeYXaSDGPTnAGbzoY/CcBO/CE6XPYuQV5so7wH+uA/7UOaJ3GAV8tRXgqj6KF\ - p2horS5zGPACFFY4Y8JsdbT71kMqWS6htRrVqGAZF+Uc80XTKDnDHNIrYLQRaO/lgKL\ - kAlFZOiPbbEpxdD6cyRw3sKD8t5lDN3oHgxw1L4Un5MbRorZmf3+4IVpT5s2qVlMqEO\ - WftyzcqIc74u7TNSXHBC8N7M8Z0TaeUDjMucKMdAmZFIZxoeHdlZlKYS1K+9TPbh3WV\ - iLQarK8RuKeIWCdYp5zUWobA//6BpnQsBDaRs2lAEtzI3z0KGFz9RFcqAXj4qQABpPT\ - v0PBK7R1DjA3f8GxyodQoqBiAvVaKZx8ti7yoxPFhKZyBZWGiqeKqathJ6LzxB69ndA\ - tY2iXJFvTtEbfEqpTDdPk4bS3dditrpSsAq5Jg1Q9NqB5zSvm9agFbxo0NFyimaKi0k\ - 4Cg0ZhjgUXmINo6xQVJcVO0E6T7zUrkb4fCN0qF38VUqmPOTRUr6IGpqhe1IZVFeZjw\ - v748WMsGt50YBipjszJbi6Nx3Jr8EZhWYaNcWoqZFXJC9IvU6UNZ9ryvoYX/vc8L73q\ - 5c97fYikYG1lWVwTz+VEBauAL3+WSBzPj6MRF01rPnaTvg==\",\"Y2ZqExJBFxa+S8\ - 7kxGs7mfMksybWPT/CNbxltStn5k4LvlQ3eub4G+mLZAQp4BrigJDjAPzqv+K4JlONa\ - sZSXnFz9Xhwe5CSluPpk/4R7qfbdawPnksZnWsopPKxyZ5ehpShM6ZxxEohteEZ+CLa\ - bhRZ9A9u/6phSbQwFv1jHdZNJa+QQp6rp1ilJSgsKDRL61ofpkzkqZTnq6xAoz0zng2\ - mxjR6HEUdZthTtDVCl+Up2Szx2LKL60k00g1mvKA19dWwqJER3h5PDsbwWiqYyguScr\ - vVuH3Xol0VLRZ1uyxAtmoFyReLeriy/hUsqUBzg8DymguujWJGqhWrnQ3CMHL/LNoG9\ - 9hal8SOlyU3S8dwLrKqzbGLjsvh8BoOLhmVrNrGj/FodN2PWvMfNrhsb7+RgjYvF+X2\ - NlxbZdKp6FzIC0gupigS0LJGYysyOuMoKUqakulpKpnKNZBFnjyHGo3iGaW1CpXhohz\ - CFFlFuWyK2bkTB7a3X2HaluXqhDlBaUZmkv48E2Vr0CFU0hIRF6utfSls6vB9iL5+6v\ - maoOFVxZT+Fu+MFuwSz25DYXl3n41Y8gwTg9qEpfyzhc6HKWdzCfp091bIpLKEDpK61\ - 5HkdSOVgUEsYhMHmesZx4H7KXX3jSwXUc6kLx1QVzzDOYqWak5I4lGJG9hIZOK+RQpm\ - +DTKZCVVh94bLaUsK4xKOcrqJsrqZh2OYgUTLFJY4mWzdpIN1uhpFJnKpmuY35MyUqj\ - bynwNA3PVOK1tkeBFKzLggpvBFnwmZryAZAjyHMZ7IHV4JOV52xyI2SAO3h4n+8dHxy\ - dxsPUzfCfPHUFsrDLDt3Kf/oc9KFilqTg1N7G4mU8yQW3eSnEkM1a9ogKXUyAcGNj25\ - gonXgTacK+40kNApbwcJ8jyV1wNnHETuyfjgJZgCmZYdVgcKCXVEUuxGhhLOYQ4UMhy\ - exRYIRKxYUJI43ui4z34cLYAfL5xKET9miq18R7QGgaZuQTvpKG/4BhCY6tH0mp4go3\ - ct/uaSsotGHw4S68MWnGk2uoUptC0SnTLohkGnXOH/y65WFmlm8Iy918t9y2vYvrPYN\ - 10nX6S9i1eDDrphyB4ZZFZVZ26ve1W7JwodLBu0ZQ0E8qr1giEqJgosQPobhG8gO88L\ - DzUZJv5+mJjwtdklWIQB63AywYzg7mrev/FrqijpDJ54JbiF/PVIfsxWm/Wy+ZAvfv8\ - 2wN1Ua+J2aoVhtc4j89GZVLMej/ppH2/EK25oUP2cpyrWXaOikK1UYgjh9Px80qZ0K6\ - Ee8XHtaqcx8qvDrL3JKx4GtkYsYjMUQS/uZqZNjIwu3vCWBBr6Pb2a4qsLjSthqV7RS\ - Q/URc6Tp3H0KFFQ0+ttiinAttrCLxrkXRMsOrqk+t+G8VmqDRaWW3no+Ait1N4ym4Bq\ - zNqo9rMdPHfh93ep7/ghYFPbTLscPpGD91Qh54SfabaOtVzli8XMEJpmNKols/52275\ - 4Ts7RlhZJTVLaXGLz4czawEbxKxaj4UleM141SqEVEraQybHxkxXOglcGJ8ko4iitr+\ - Z0MBA4MWqmkKfS/vhfUk1Q1hSzAaNbMH2qv694m1ecieFFYzPXxOZ949fHbw9nhy+/s\ - djZN6gl82R+fa98fY2/DJjqhUlE/mUj7TKHmAV1nB7rqpQJVkpH9PlRrUs22Sn3wra/\ - cvtVtADc0OpmiyyPFyCaJQ08n5JauFJfhWzHcejGzD3T3h/ZK6yQYnSOyrTxQ1bj0/k\ - r6rJ7NcBFfO+Dt7WhplWh6f2v/nBw3END/XAlu/ddgnfC4WZLAX/hDbSHVwaFJpLcbC\ - urA==\",\"9rwpRmYyRx0eihmreN61p23uC51MiyL67vl121D9g/kRE2XLSrzfzO/F/\ - I4T8w3zelrBq0UisIekfZnjoTBYgUPRUBHYXcuQ9aqKl/bmg0p2ys4ln6FwVTazN3K0\ - Cb11Bhq2yfN8ON9amWOg8PcWtYFt647h8uiJGxyC1uDG/TnCc0uW0QmKasvp0+lIr+S\ - b8d5CvaQvHS6nse7Iktv23gp1uF9JjYPuIKdKe57xKwh/RbNc9Qy2wok89O7eUdFRjo\ - TQXcXk8nfDrirJ8vnRc3XmFa1l5nIIJMDWwoXguz0SH74qYy7OfVFjb+Ei3aYRul7hb\ - thcPcbsh6nrYa/lAGbQXIVzBgXkWMQixwKKwdb4Gy1KglRMnUfppyrxl5Bh+ql6tOlD\ - FfZgqy4+0OO1sG4P+O12/iebsZ1Iq8x646n1pSchQR8t/XCVbbb1Ha2LNv3Z51Jrfdj\ - fdbbOKqY1/frs3vk4BPBYhceyp0nDDM8o0UKx+/MftfP/4/jkr6fvXuwfPHrC/VV1x+\ - Patbt9w2c22xQGFBn9jzHwy/eHR68ejXs/Nf2/M2yYsk/4mK8fpKz/q0aeyhmqx3veL\ - 6vmjgR8u0f14MuD/k3AF+5u/9daGRPU5jfSwbrrSSpK6Gj4cV5NOPhM8hzqxS1YFIGQ\ - Bpg9h6MwUHGBflU02AfDznrwE3/XJgxcwh48+3lxrfrRsSplxUTp5bHC14yLToo7ZFg\ - rwdr5Z0zB5bxT7efN9JSpxs9LG0I3LEN4LWVXWjnlvGSqA/SqKqurl+zTgFbW9C4O71\ - TaRrVtVFwnfKc633NZ0iDZ11+I9m8hYmMvdp3Q/sWsvey2nq6XgBfMv3pcAG88k8/Op\ - W0pGwdDoP+HEAcry4jFivixiIOb4TKPUhIHZ/Gv5ZHZ61dnvYfx+B++FPf3ziTk4tLZ\ - 2eZbOynztKTtueLxyP1AXT3wj9u+NoVXkuWDOIii8cpxnzw2DnpA+4jjTvSs1UbWSX+\ - OvTU8YjHvDkDC66ZadATsT9sLINEbpnWHvm5Vntquo99LsNA9N/pV79Fud7h8c+rJYz\ - PwQap6kBP7isXTA9PAduZ1jIfGwv6RWYfjB/d3hrC/YymeeIxQt+m8pdjhFRZld8mnZ\ - rb5uL/j3GjtRroHygPQHoi6QO81SL/9iLXc+9Ft+sQ3gHYfe2bforc7PP72g/Ze54z8\ - dbmBRjEO/EQ2tc8HvEt07uOdm5js71gGvkR+CnhpUOSaUHu9N6J9GhY7i76bbbg5Wsu\ - 8V1V3E3Zz9yZeHVr1WTfJl1GXqVZJSDZKJPs7xO3f7N+Tum+6bVCFVm5CvOnE708ym0\ - H97FaD0S3w2eBQGCxRAd+Cz0T/8C312KG4h2LueAl3ux0xLzFynI1LmeRY6EVBUkp7R\ - O4XI79wmdh5EtVWqJNSRlEpxzkWS2TLJcgCMHCeQQax5cr8EB0Mvc+oTMMefFi4ZBz0\ - 3ja5E0J/0J7kb4PpBJFQkNgw5PLnhsGuRFw/3LIS1whi766TTOaY2Lvr2xiL54orA63\ - hS+hn/n/7B3tzjcwnHxW8whF2bwR0+E8tRRx0VC5E2fPJ3jc8DbxlGsNKK8jkxa/Ju6\ - MXk9fHJ2+S04MXJ/u/dVPPuOb+b0WsxFGf9ThJdJv6MKyTZCFxjs0to0d3PlgcLqP23\ - 7psHiQ1ZZuHuyfrd4/PH6ZvQlsvYb8RszT0SybrxNkose9CE/suNIrG/n3oRmz/TD9x\ - z/SjaNy9199I4Z+UJrSvFWLiHv9F0Xj1jemQovPZzc1/BwAA//84ilWu9UYAAA==\"]" - cookies: [] - headers: - - name: date - value: Tue, 16 Jul 2024 15:15:02 GMT - - name: content-type - value: application/json - - name: transfer-encoding - value: chunked - - name: connection - value: keep-alive - - name: retry-after - value: "519" - - name: access-control-allow-credentials - value: "true" - - name: access-control-allow-origin - value: "" - - name: cache-control - value: no-cache, max-age=0 - - name: content-encoding - value: gzip - - name: vary - value: 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: 1356 - httpVersion: HTTP/1.1 - redirectURL: "" - status: 200 - statusText: OK - startedDateTime: 2024-07-16T15:15:01.805Z - time: 0 - timings: - blocked: -1 - connect: -1 - dns: -1 - receive: 0 - send: 0 - ssl: -1 - wait: 0 - - _id: b4499992cdf92807c09248d1e216cbdb - _order: 0 - cache: {} - request: - bodySize: 253 - cookies: [] - headers: - - _fromType: array - name: authorization - value: token - REDACTED_964f5256e709a8c5c151a63d8696d5c7ac81604d179405864d88ff48a9232364 - - _fromType: array - name: content-type - value: application/json; charset=utf-8 - - _fromType: array - name: user-agent - value: jetbrains / 6.0.0-SNAPSHOT - - _fromType: array - name: accept - value: "*/*" - - _fromType: array - name: content-length - value: "253" - - _fromType: array - name: accept-encoding - value: gzip,deflate - - name: host - value: sourcegraph.sourcegraph.com - headersSize: 350 - httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json; charset=utf-8 - params: [] - textJSON: - query: | - - query Repositories($names: [String!]!, $first: Int!) { - repositories(names: $names, first: $first) { - nodes { - name - id - } - } - } - variables: - first: 1 - names: - - github.com/sourcegraph/sourcegraph + variables: {} queryString: - - name: Repositories + - name: SiteProductVersion value: null - url: https://sourcegraph.sourcegraph.com/.api/graphql?Repositories + url: https://sourcegraph.sourcegraph.com/.api/graphql?SiteProductVersion response: - bodySize: 175 + bodySize: 139 content: encoding: base64 mimeType: application/json - size: 175 - text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqSi3IL84syS/KTC0G8fPyU0CM6GqlvMTcVCUrpfTMk\ - ozSJL3k/Fz94vzSouTU9KLEggxktpKOUmaKkpVSaG5YeZKxX0GKu2Vlakh+lX9Itq1S\ - bWxtbS0AAAD//w==\",\"AwARSH8wbwAAAA==\"]" + size: 139 + text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqzixJBdEFRfkppcklYalFxZn5eUpWSkYW5iYmRvFGB\ + kYmugYWuobG8aZ6ZrrGpkZGKclpJolpKclKtbW1\",\"AAAAAP//AwD5OZ82SQAAAA==\ + \"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:15:00 GMT + value: Tue, 13 Aug 2024 19:01:27 GMT - name: content-type value: application/json - name: transfer-encoding value: chunked - name: connection value: keep-alive - - name: retry-after - value: "520" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin @@ -1268,12 +919,12 @@ log: value: max-age=31536000; includeSubDomains; preload - name: content-encoding value: gzip - headersSize: 1356 + headersSize: 1249 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:15:00.245Z + startedDateTime: 2024-08-13T19:01:27.565Z time: 0 timings: blocked: -1 @@ -1283,83 +934,73 @@ log: send: 0 ssl: -1 wait: 0 - - _id: e83b435a530574a277932bc0a0cad82a + - _id: 277d6b682e1c0a9e7bf94342d2ae2090 _order: 0 cache: {} request: - bodySize: 101 + bodySize: 0 cookies: [] headers: - _fromType: array name: authorization value: token REDACTED_964f5256e709a8c5c151a63d8696d5c7ac81604d179405864d88ff48a9232364 - - _fromType: array - name: content-type - value: application/json; charset=utf-8 - _fromType: array name: user-agent value: jetbrains / 6.0.0-SNAPSHOT - _fromType: array name: accept value: "*/*" - - _fromType: array - name: content-length - value: "101" - _fromType: array name: accept-encoding value: gzip,deflate - name: host value: sourcegraph.sourcegraph.com - headersSize: 356 + headersSize: 294 httpVersion: HTTP/1.1 - method: POST - postData: - mimeType: application/json; charset=utf-8 - params: [] - textJSON: - query: |- - - query SiteProductVersion { - site { - productVersion - } - } - variables: {} - queryString: - - name: SiteProductVersion - value: null - url: https://sourcegraph.sourcegraph.com/.api/graphql?SiteProductVersion + method: GET + queryString: [] + url: https://sourcegraph.sourcegraph.com/.api/modelconfig/supported-models.json response: - bodySize: 136 + bodySize: 769 content: encoding: base64 - mimeType: application/json - size: 136 - text: "[\"H4sIAAAAAAAAA6pWSkksSVSyqlYqzixJBdEFRfkppcklYalFxZn5eUpWSkYWRqbGxvFGB\ - kYmugbmuoZm8aZ6prqJBomGFolmBqmWBiZKtbW1AAAAAP//AwBtpsiNSQAAAA==\"]" - textDecoded: - data: - site: - productVersion: 282533_2024-07-16_5.5-a0a18a60e904 + mimeType: text/plain; charset=utf-8 + size: 769 + text: "[\"H4sIAAAAAAAA/+yZT1OjPhjH730VDNefYBqK9cfN7YyuB1dndXYPOx7S8LTNCAmThFrH8\ + b3vQFoUSgutTl2tnpB8n28SPk/+9rFjWZZlKzqBmPw=\",\"AqmY4HZg2V0X2QemTMK\ + ULV4jF7novxCmi8JEiikLQSo7sP7kr7K/x+IpF7EwiyVcT6RIGJ3HFsUhU0lEHn6QGD\ + LdSaErZE8H661HTMK9kHeqwfq00LW2HgsxjqDB98yIWpuKBDhhDaaXCfCT8/amMVNak\ + qjB9WKuerbNn27nPGMRQrQWZq74CaMS0iDACHsOOnJQNwhoRNIQHM9RgnPQDS0a5GrL\ + s65r1Xl9C23F2cEI9xDG/1eDKEnIkEVMMyh3plCQVAsq4iQCXaVrHCZE26XXt0t1aBg\ + L+ZC1a0giwimE1XYoTXSatSB7Gi7nkWYg8wSWsFRGBdcw078ZD8W9HVQ4mG9DZuc8Sf\ + WNuAOeVeMhhFBNb2Iyu0z1S2UPIVTSPbVItA3Yu/5m9F1/I/5+KQOOMHrvDCCUppLQh\ + 20zIJHicyWAI5K0aT4uhv5ljbYefOb6zwz7L+hV6BPC7tK21L/Xieux576Gu4f6781d\ + JbD9XP9G0Ps7Y17sroJg2g0CpYmkIgTZgPlaEzmo05UIr3TbkOmHYodR77gVO+wfvQq\ + d2b0abmOIGWdO1/WdRAonIhpU0+p8lsdYXde3rpa7XgLZyv5rgq4K33qwriA+ioiabM\ + z8NItqS31dFfs4Qe8Q+vzoZ6jHbJb94xzP+kOHcaVlSpuYX5gY63jW/7aWN6FUpFyrw\ + 2JRODRHxsNW1e5jHuxuoV6RBhhvkQcYvz4R1lW8pyvB7pLB3DHl2/Seg3C+TR8n2ukt\ + 9aM6/1/d1IjKs36tz54i3eE8v5Kpo1M5bAXWuqlTLtOtd/xo92qfZtR6rt+asef6LSm\ + vdP1ap1/qNoDcedFTO4QRSSN9sbhTf26F+Tzb3aLaI6L0oF18TXR22B4YcPMfdVae7z\ + umS0+dvwEAAP//+9VDaCYaAAA=\"]" cookies: [] headers: - name: date - value: Tue, 16 Jul 2024 15:14:57 GMT + value: Tue, 13 Aug 2024 19:01:28 GMT - name: content-type - value: application/json - - name: transfer-encoding - value: chunked + value: text/plain; charset=utf-8 + - name: content-length + value: "769" - name: connection value: keep-alive - - name: retry-after - value: "523" - name: access-control-allow-credentials value: "true" - name: access-control-allow-origin value: "" - name: cache-control value: no-cache, max-age=0 + - name: content-encoding + value: gzip - name: vary value: Accept-Encoding, Authorization, Cookie, Authorization, X-Requested-With, Cookie @@ -1371,14 +1012,12 @@ log: value: 1; mode=block - name: strict-transport-security value: max-age=31536000; includeSubDomains; preload - - name: content-encoding - value: gzip - headersSize: 1356 + headersSize: 1251 httpVersion: HTTP/1.1 redirectURL: "" status: 200 statusText: OK - startedDateTime: 2024-07-16T15:14:57.299Z + startedDateTime: 2024-08-13T19:01:28.257Z time: 0 timings: blocked: -1 diff --git a/agent/src/TestClient.ts b/agent/src/TestClient.ts index f13d024d0637..e134035fc83a 100644 --- a/agent/src/TestClient.ts +++ b/agent/src/TestClient.ts @@ -102,7 +102,7 @@ export function buildAgentBinary(): void { // To see the full error, run this file in isolation: // // pnpm test agent/src/index.test.ts - execSync('pnpm run build ', { + execSync('pnpm run build:for-tests ', { cwd: getAgentDir(), stdio: 'inherit', }) diff --git a/agent/src/cli/__snapshots__/command-chat.test.ts.snap b/agent/src/cli/__snapshots__/command-chat.test.ts.snap index d2c683878102..3520aec046ea 100644 --- a/agent/src/cli/__snapshots__/command-chat.test.ts.snap +++ b/agent/src/cli/__snapshots__/command-chat.test.ts.snap @@ -11,25 +11,12 @@ stdout: |+ - Here's a simple implementation of a cow in Python: - - \`\`\`python - class Cow: - def __init__(self, name): - self.name = name - self.milk = 0 - - def moo(self): - return f"{self.name} says: Moo!" - - def produce_milk(self, amount): - self.milk += amount - return f"{self.name} produced {amount} liters of milk." - - def get_milk(self): - milk_produced = self.milk - self.milk = 0 - return f"Collected {milk_produced} liters of milk from {self.name}." + \`\`\`typescript + class Cow implements StrangeAnimal { + makesSound(): 'coo' | 'moo' { + return 'moo'; + } + } \`\`\` stderr: "" diff --git a/agent/src/cli/command-chat.ts b/agent/src/cli/command-chat.ts index aa15ac7761ec..8bebd7f12752 100644 --- a/agent/src/cli/command-chat.ts +++ b/agent/src/cli/command-chat.ts @@ -1,4 +1,4 @@ -import ora, { spinners } from 'ora' +import ora, { type Ora, spinners } from 'ora' import path from 'node:path' @@ -6,7 +6,9 @@ import type { Polly } from '@pollyjs/core' import { type ContextItem, ModelUsage, TokenCounter } from '@sourcegraph/cody-shared' import { Command } from 'commander' +import Table from 'easy-table' import * as vscode from 'vscode' +import type { ExtensionTranscriptMessage } from '../../../vscode/src/chat/protocol' import { activate } from '../../../vscode/src/extension.node' import { startPollyRecording } from '../../../vscode/src/testutils/polly' import packageJson from '../../package.json' @@ -33,6 +35,7 @@ export interface ChatOptions { debug: boolean silent: boolean isTesting?: boolean + ignoreContextWindowErrors: boolean streams?: Streams } @@ -74,6 +77,11 @@ Enterprise Only: ) .option('--context-file ', 'Local files to include in the context') .option('--show-context', 'Show context items in reply', false) + .option( + '--ignore-context-window-errors', + 'If true, does not fail fast when a context file is too large to fit into the LLMs context window', + false + ) .option('--silent', 'Disable streaming reply', false) .option('--debug', 'Enable debug logging', false) .action(async (options: ChatOptions, cmd) => { @@ -149,8 +157,19 @@ export async function chatAction(options: ChatOptions): Promise { }) } + if (!serverInfo.authStatus?.isLoggedIn) { + notLoggedIn(spinner) + return 1 + } + + const endpoint = serverInfo.authStatus.endpoint ?? options.endpoint + const tokenSource = new vscode.CancellationTokenSource() + const token = tokenSource.token + + let isFirstMessageCheck = true + messageHandler.registerNotification('webview/postMessage', message => { - if (message.message.type === 'transcript') { + if (message.message.type === 'transcript' && !token.isCancellationRequested) { const lastMessage = message.message.messages.at(-1) if (lastMessage?.model && !spinner.text.startsWith('Model')) { const modelName = @@ -159,14 +178,18 @@ export async function chatAction(options: ChatOptions): Promise { spinner.spinner = spinners.dots } spinner.prefixText = (lastMessage?.text ?? '') + '\n' + + if (isFirstMessageCheck && !options.ignoreContextWindowErrors) { + const contextFiles = message.message.messages.at(0)?.contextFiles + if (contextFiles && contextFiles.length > 0) { + isFirstMessageCheck = false + } + + validateContext(message.message, spinner, endpoint, tokenSource) + } } }) - if (!serverInfo.authStatus?.isLoggedIn) { - notLoggedIn(spinner) - return 1 - } - spinner.text = 'Asking Cody...' const id = await client.request('chat/new', null) @@ -239,16 +262,24 @@ export async function chatAction(options: ChatOptions): Promise { return 1 } const addEnhancedContext = isNonEmptyArray(options.contextRepo) - const response = await client.request('chat/submitMessage', { - id, - message: { - command: 'submit', - submitType: 'user', - text: messageText, - contextFiles, - addEnhancedContext, + const response = await client.request( + 'chat/submitMessage', + { + id, + message: { + command: 'submit', + submitType: 'user', + text: messageText, + contextFiles, + addEnhancedContext, + }, }, - }) + { token: tokenSource.token } + ) + + if (token.isCancellationRequested) { + return 1 + } if (response.type !== 'transcript') { spinner.fail( @@ -281,15 +312,10 @@ export async function chatAction(options: ChatOptions): Promise { spinner.clear() if (options.showContext) { - const reponseContextFiles = response.messages.flatMap(m => m.contextFiles ?? []) + const responseContextFiles = response.messages.flatMap(m => m.contextFiles ?? []) streams.log('> Context items:\n') - for (const [i, item] of reponseContextFiles.entries()) { - const uri = vscode.Uri.from(item.uri as any) - const endpoint = serverInfo.authStatus.endpoint ?? options.endpoint - // Workaround for strange URI authority resopnse, reported in - // https://sourcegraph.slack.com/archives/C05AGQYD528/p1721382757890889 - const remoteURL = new URL(uri.path, endpoint).toString() - const displayText = uri.scheme === 'file' ? uri.fsPath : remoteURL + for (const [i, item] of responseContextFiles.entries()) { + const displayText = uriDisplayText(item, endpoint) streams.log(`> ${i + 1}. ${displayText}\n`) } streams.log('\n') @@ -300,6 +326,14 @@ export async function chatAction(options: ChatOptions): Promise { return 0 } +function uriDisplayText(item: ContextItem, endpoint: string): string { + const uri = vscode.Uri.from(item.uri as any) + // Workaround for strange URI authority resopnse, reported in + // https://sourcegraph.slack.com/archives/C05AGQYD528/p1721382757890889 + const remoteURL = new URL(uri.path, endpoint).toString() + return uri.scheme === 'file' ? uri.fsPath : remoteURL +} + function toUri(dir: string, relativeOrAbsolutePath: string): vscode.Uri { const absolutePath = path.isAbsolute(relativeOrAbsolutePath) ? relativeOrAbsolutePath @@ -346,3 +380,32 @@ async function readStdin(): Promise { process.stdin.on('error', reject) }) } + +function validateContext( + message: ExtensionTranscriptMessage, + spinner: Ora, + endpoint: string, + tokenSource: vscode.CancellationTokenSource +): void { + const tooLargeItems = message.messages.flatMap(messages => + (messages.contextFiles ?? []).filter(item => item.isTooLarge) + ) + if (tooLargeItems.length > 0) { + const t = new Table() + for (const item of tooLargeItems) { + t.cell('File', uriDisplayText(item, endpoint)) + t.cell('Reason', item.isTooLargeReason) + t.newRow() + } + spinner.text = '' + spinner.prefixText = '' + spinner.fail( + 'The provided context is too large to fit into the context window. \n' + + 'To fix this problem, either remove the files from --context-file or\n' + + 'edit these files so they become small enough to fit into the context window.\n' + + 'Alternatively, set the flag --ignore-context-window-errors to skip this check.\n\n' + + t.toString() + ) + tokenSource.cancel() + } +} diff --git a/vscode/src/jsonrpc/jsonrpc.ts b/vscode/src/jsonrpc/jsonrpc.ts index c28e1a78da14..e7468f05b643 100644 --- a/vscode/src/jsonrpc/jsonrpc.ts +++ b/vscode/src/jsonrpc/jsonrpc.ts @@ -109,8 +109,14 @@ export class MessageHandler { public async request( method: M, - params: ParamsOf + params: ParamsOf, + extra?: { token?: vscode.CancellationToken } ): Promise> { + if (extra?.token !== undefined) { + return await this.conn.sendRequest(method, params, extra.token) + } + // Strangely enough: the tests will fail with a cryptic error if we pass + // an undefined `token` variable as the third parameter to `sendRequest`. return await this.conn.sendRequest(method, params) } @@ -133,10 +139,11 @@ export class MessageHandler { request: async ( method: M, params: ParamsOf, - cancelToken: vscode.CancellationToken = new vscode.CancellationTokenSource().token + extra?: { token?: vscode.CancellationToken } ) => { const handler = this.requestHandlers.get(method) if (handler) { + const cancelToken = extra?.token ?? new vscode.CancellationTokenSource().token return await handler(params, cancelToken) } throw new Error(`No such request handler: ${method}`)