Compare commits
203 Commits
v0.181.8
...
tool-rende
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac63ea504a | ||
|
|
11aaea964f | ||
|
|
cd9a45a262 | ||
|
|
1965029528 | ||
|
|
46c738d724 | ||
|
|
b18bd2d67b | ||
|
|
7e0a97fabe | ||
|
|
8ba9429e60 | ||
|
|
0b75c13034 | ||
|
|
38ec45008c | ||
|
|
97641c3298 | ||
|
|
ca8f6e8a3f | ||
|
|
db53da49e1 | ||
|
|
df94dcdea6 | ||
|
|
1c85901440 | ||
|
|
9fb77ad176 | ||
|
|
cad3ee8def | ||
|
|
feafad2f9d | ||
|
|
42cb40170e | ||
|
|
7dc3a39edf | ||
|
|
86ef00054b | ||
|
|
9e8afa8daa | ||
|
|
fc1b3889c2 | ||
|
|
698cdc4d1a | ||
|
|
85c5d8af3a | ||
|
|
34c6fee959 | ||
|
|
1774cad933 | ||
|
|
ee7b1ec7f2 | ||
|
|
14b43d573c | ||
|
|
d39e1e03b8 | ||
|
|
9e504a1ed9 | ||
|
|
b25ec65b48 | ||
|
|
ca4cc4764b | ||
|
|
ea33d78ae4 | ||
|
|
e36a2f2739 | ||
|
|
cbd9b4cc39 | ||
|
|
64f8b1e739 | ||
|
|
4f936d8100 | ||
|
|
97abf21a28 | ||
|
|
5fb1411e4d | ||
|
|
b04f7a4c7c | ||
|
|
61b7a05792 | ||
|
|
cc15598e09 | ||
|
|
7ee9109ade | ||
|
|
c21fdd212b | ||
|
|
a28929592e | ||
|
|
3b787e85a4 | ||
|
|
1264e7a200 | ||
|
|
bfe08e449f | ||
|
|
df3c7a73b5 | ||
|
|
0dc3dffe38 | ||
|
|
b306a0221b | ||
|
|
d385a60ed1 | ||
|
|
b27922129c | ||
|
|
6220b86f94 | ||
|
|
448db20eaa | ||
|
|
e4a6943c76 | ||
|
|
f03efeda73 | ||
|
|
862d0c07ca | ||
|
|
56ed5dcc89 | ||
|
|
b3f47dc5e0 | ||
|
|
fe1ae1860e | ||
|
|
c165729b3f | ||
|
|
22b937f27f | ||
|
|
fdaf2a27bf | ||
|
|
0414908c4a | ||
|
|
d3abc61728 | ||
|
|
e7a0f0e876 | ||
|
|
5996c58452 | ||
|
|
b6ee367ee0 | ||
|
|
aa026156f2 | ||
|
|
d5cc576b0c | ||
|
|
f3274851d9 | ||
|
|
500d8f2943 | ||
|
|
e3830d2ef5 | ||
|
|
4f9f443452 | ||
|
|
1556b446e7 | ||
|
|
5ca8a3e342 | ||
|
|
aeea3645ff | ||
|
|
a577a72f69 | ||
|
|
5a7222edc5 | ||
|
|
097aefeac4 | ||
|
|
99a9647b78 | ||
|
|
fa90b3a986 | ||
|
|
8049fc1038 | ||
|
|
85b811a783 | ||
|
|
d60dbbc791 | ||
|
|
656302ee4c | ||
|
|
956f359045 | ||
|
|
3b46fca64c | ||
|
|
d6d9c383cb | ||
|
|
8cfb9beb17 | ||
|
|
0708d476ca | ||
|
|
57669b4908 | ||
|
|
b1f7133a7b | ||
|
|
ac9e2f30bb | ||
|
|
a2fbe82c42 | ||
|
|
57d8c99473 | ||
|
|
41827372fe | ||
|
|
9949512b64 | ||
|
|
b9051e65d4 | ||
|
|
adbebb28dc | ||
|
|
caf0d6c5fa | ||
|
|
525755c28e | ||
|
|
ea0f5144c9 | ||
|
|
b78ac5410f | ||
|
|
2462b949bc | ||
|
|
ec7d28648a | ||
|
|
c1259c136e | ||
|
|
6ddad64af1 | ||
|
|
69d7ea7b60 | ||
|
|
d0e82b0538 | ||
|
|
10821aae2c | ||
|
|
03aadb4e5b | ||
|
|
8ab252c42d | ||
|
|
e74af03065 | ||
|
|
4bcd37a537 | ||
|
|
e3d212ac60 | ||
|
|
8b077f0c41 | ||
|
|
288da0f072 | ||
|
|
b8d05bb641 | ||
|
|
02e4267bc6 | ||
|
|
c2afc2271b | ||
|
|
7bc62de267 | ||
|
|
f3adf41c25 | ||
|
|
6162d9942d | ||
|
|
156dd32a35 | ||
|
|
2747915569 | ||
|
|
75b9a3b6a8 | ||
|
|
9bd3dbcf28 | ||
|
|
435fff94bd | ||
|
|
558d61b907 | ||
|
|
02a8ece074 | ||
|
|
1a899fda60 | ||
|
|
183f57f318 | ||
|
|
cc9cc12f7b | ||
|
|
1bc5618f61 | ||
|
|
ef8fe52877 | ||
|
|
982196343f | ||
|
|
cfe5620a2a | ||
|
|
5fe86f7e70 | ||
|
|
c94b587e1a | ||
|
|
43cb925a59 | ||
|
|
cf0d1e4229 | ||
|
|
2f5a4f7e80 | ||
|
|
80441f675b | ||
|
|
393d6560a3 | ||
|
|
3d48efad67 | ||
|
|
277a3f8d6f | ||
|
|
5e286897d3 | ||
|
|
9e38c45a9b | ||
|
|
1db3d92066 | ||
|
|
a7674d3edc | ||
|
|
ee4b6a8db4 | ||
|
|
c04c5812b6 | ||
|
|
cba96b5a38 | ||
|
|
8b5ea05163 | ||
|
|
ec40e2d85c | ||
|
|
819bb8fffb | ||
|
|
c6e2d20a02 | ||
|
|
7492ec3f67 | ||
|
|
4d8df0a00b | ||
|
|
3f71ae9897 | ||
|
|
2086f7d85b | ||
|
|
315f1bf168 | ||
|
|
0c82541f0a | ||
|
|
b9724d9cbe | ||
|
|
e5b347b03a | ||
|
|
e123c4bced | ||
|
|
ed3722023e | ||
|
|
ece4a1cd7c | ||
|
|
9986a21970 | ||
|
|
c674e8d62d | ||
|
|
e5e3e9ac8c | ||
|
|
399d19231b | ||
|
|
c98bcc72b8 | ||
|
|
fe27d11f08 | ||
|
|
9693eab098 | ||
|
|
e2aaf9b704 | ||
|
|
9abfbdff43 | ||
|
|
cd85b430e4 | ||
|
|
d3e4de7c72 | ||
|
|
ee950f5bc4 | ||
|
|
501b539286 | ||
|
|
444b7b8acb | ||
|
|
8a6ed4a2ca | ||
|
|
b4af5b2ce0 | ||
|
|
ee33d313e2 | ||
|
|
0a132779a1 | ||
|
|
d23c2d4b02 | ||
|
|
b9f10c0adb | ||
|
|
9f9746872e | ||
|
|
01ec6e0f77 | ||
|
|
07a77792c5 | ||
|
|
108ae0b5b0 | ||
|
|
500964a6fa | ||
|
|
0a58e54477 | ||
|
|
8539e23018 | ||
|
|
c7d27753ee | ||
|
|
b7b7f1ccdd | ||
|
|
142f9917d0 | ||
|
|
f8092bf0d2 | ||
|
|
0ba8432b0b |
36
.github/ISSUE_TEMPLATE/01_bug_agent.yml
vendored
Normal file
36
.github/ISSUE_TEMPLATE/01_bug_agent.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Bug Report (Agent Panel)
|
||||
description: Zed Agent Panel Bugs
|
||||
type: "Bug"
|
||||
labels: ["agent", "ai"]
|
||||
title: "Agent Panel: <a short description of the Agent Panel bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
<!-- Please include the LLM provider and model name you are using -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
Expected Behavior:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
36
.github/ISSUE_TEMPLATE/02_bug_edit_predictions.yml
vendored
Normal file
36
.github/ISSUE_TEMPLATE/02_bug_edit_predictions.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Bug Report (Edit Predictions)
|
||||
description: Zed Edit Predictions bugs
|
||||
type: "Bug"
|
||||
labels: ["ai", "inline completion", "zeta"]
|
||||
title: "Edit Predictions: <a short description of the Edit Prediction bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
<!-- Please include the LLM provider and model name you are using -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
Expected Behavior:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
35
.github/ISSUE_TEMPLATE/03_bug_git.yml
vendored
Normal file
35
.github/ISSUE_TEMPLATE/03_bug_git.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Bug Report (Git)
|
||||
description: Zed Git-Related Bugs
|
||||
type: "Bug"
|
||||
labels: ["git"]
|
||||
title: "Git: <a short description of the Git bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
Expected Behavior:
|
||||
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
56
.github/ISSUE_TEMPLATE/10_bug_report.yml
vendored
Normal file
56
.github/ISSUE_TEMPLATE/10_bug_report.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Bug Report (Other)
|
||||
description: |
|
||||
Something else is broken in Zed (exclude crashing).
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Provide a one sentence summary and detailed reproduction steps
|
||||
value: |
|
||||
<!-- Begin your issue with a one sentence summary -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install.
|
||||
- Any code must be sufficient to reproduce (include context!)
|
||||
- Code must as text, not just as a screenshot.
|
||||
- Issues with insufficient detail may be summarily closed.
|
||||
-->
|
||||
|
||||
Steps to reproduce:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
Expected Behavior:
|
||||
Actual Behavior:
|
||||
|
||||
<!-- Before Submitting, did you:
|
||||
1. Include settings.json, keymap.json, .editorconfig if relevant?
|
||||
2. Check your Zed.log for relevant errors? (please include!)
|
||||
3. Click Preview to ensure everything looks right?
|
||||
4. Hide videos, large images and logs in ``` inside collapsible blocks:
|
||||
|
||||
<details><summary>click to expand</summary>
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
</details>
|
||||
-->
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: |
|
||||
Open Zed, from the command palette select "zed: Copy System Specs Into Clipboard"
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
@@ -5,10 +5,12 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
description: Summarize the issue with detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
<!-- Begin your issue with a one sentence summary -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
@@ -16,7 +18,6 @@ body:
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
|
||||
Expected Behavior:
|
||||
|
||||
validations:
|
||||
@@ -40,10 +41,11 @@ body:
|
||||
value: |
|
||||
<details><summary>Zed.log</summary>
|
||||
|
||||
<!-- Click below this line and paste or drag-and-drop your log-->
|
||||
```
|
||||
<!-- Paste your log inside the code block. -->
|
||||
```log
|
||||
|
||||
```
|
||||
<!-- Click above this line and paste or drag-and-drop your log--></details>
|
||||
|
||||
</details>
|
||||
validations:
|
||||
required: false
|
||||
57
.github/ISSUE_TEMPLATE/1_bug_report.yml
vendored
57
.github/ISSUE_TEMPLATE/1_bug_report.yml
vendored
@@ -1,57 +0,0 @@
|
||||
name: Bug Report
|
||||
description: |
|
||||
Something is broken in Zed (exclude crashing).
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
<!-- Be verbose: Include all steps necessary to reproduce from a clean Zed installation. -->
|
||||
<!-- Code snippets are better than images, a repository link that reproduces the issue is ideal. -->
|
||||
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
Actual Behavior:
|
||||
|
||||
Expected Behavior:
|
||||
|
||||
<!--
|
||||
Is there anything additional necessary to reproduce this issue?
|
||||
- settings.json, keymap.json, .editorconfig etc?
|
||||
- Does it happen intermittently or only with specific projects / file types?
|
||||
- Have you found a workaround?
|
||||
|
||||
Did you check your Zed.log to see if there is any relevant details there?
|
||||
- When including large items (videos, screenshots, logs, configs) please wrap with:
|
||||
|
||||
<details><summary>See inside for XXXXYYY</summary>
|
||||
|
||||
```shell
|
||||
code
|
||||
```
|
||||
|
||||
</details>
|
||||
-->
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,9 +4,6 @@ contact_links:
|
||||
- name: Feature Request
|
||||
url: https://github.com/zed-industries/zed/discussions/new/choose
|
||||
about: To request a feature, open a new Discussion in one of the appropriate Discussion categories
|
||||
- name: Zed Discussion Forum
|
||||
url: https://github.com/zed-industries/zed/discussions
|
||||
about: A community discussion forum
|
||||
- name: "Zed Discord: #Support Channel"
|
||||
- name: "Zed Discord"
|
||||
url: https://zed.dev/community-links
|
||||
about: Real-time discussion and user support
|
||||
|
||||
2
.github/actions/run_tests_windows/action.yml
vendored
2
.github/actions/run_tests_windows/action.yml
vendored
@@ -23,4 +23,4 @@ runs:
|
||||
- name: Run tests
|
||||
shell: pwsh
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: cargo nextest run --workspace --no-fail-fast
|
||||
run: cargo nextest run --workspace --no-fail-fast --config='profile.dev.debug="limited"'
|
||||
|
||||
53
.github/workflows/ci.yml
vendored
53
.github/workflows/ci.yml
vendored
@@ -114,7 +114,9 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
name: Check workspace-hack crate
|
||||
needs: [job_spec]
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
runs-on:
|
||||
- buildjet-8vcpu-ubuntu-2204
|
||||
steps:
|
||||
@@ -131,13 +133,13 @@ jobs:
|
||||
- name: Check workspace-hack Cargo.toml is up-to-date
|
||||
run: |
|
||||
cargo hakari generate --diff || {
|
||||
echo "To fix, run script/update-workspace-hack";
|
||||
echo "To fix, run script/update-workspace-hack or script/update-workspace-hack.ps1";
|
||||
false
|
||||
}
|
||||
- name: Check all crates depend on workspace-hack
|
||||
run: |
|
||||
cargo hakari manage-deps --dry-run || {
|
||||
echo "To fix, run script/update-workspace-hack"
|
||||
echo "To fix, run script/update-workspace-hack or script/update-workspace-hack.ps1"
|
||||
false
|
||||
}
|
||||
|
||||
@@ -706,6 +708,51 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
nix-build:
|
||||
timeout-minutes: 60
|
||||
name: Nix Build
|
||||
continue-on-error: true
|
||||
if: github.repository_owner == 'zed-industries' && contains(github.event.pull_request.labels.*.name, 'run-nix')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
system:
|
||||
- os: x86 Linux
|
||||
runner: buildjet-16vcpu-ubuntu-2204
|
||||
install_nix: true
|
||||
- os: arm Mac
|
||||
runner: [macOS, ARM64, test]
|
||||
install_nix: false
|
||||
runs-on: ${{ matrix.system.runner }}
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
GIT_LFS_SKIP_SMUDGE: 1 # breaks the livekit rust sdk examples which we don't actually depend on
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
clean: false
|
||||
- name: Set path
|
||||
if: ${{ ! matrix.system.install_nix }}
|
||||
run: |
|
||||
echo "/nix/var/nix/profiles/default/bin" >> $GITHUB_PATH
|
||||
echo "/Users/administrator/.nix-profile/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31
|
||||
if: ${{ matrix.system.install_nix }}
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: zed-industries
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
skipPush: true
|
||||
- run: nix build .#debug
|
||||
- name: Limit /nix/store to 50GB
|
||||
run: "[ $(du -sm /nix/store | cut -f1) -gt 50000 ] && nix-collect-garbage -d"
|
||||
|
||||
auto-release-preview:
|
||||
name: Auto release preview
|
||||
if: |
|
||||
|
||||
3
.github/workflows/release_nightly.yml
vendored
3
.github/workflows/release_nightly.yml
vendored
@@ -216,7 +216,8 @@ jobs:
|
||||
name: zed-industries
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
- run: nix build
|
||||
- run: nix-collect-garbage -d
|
||||
- name: Limit /nix/store to 50GB
|
||||
run: '[ $(du -sm /nix/store | cut -f1) -gt 50000 ] && nix-collect-garbage -d'
|
||||
|
||||
update-nightly-tag:
|
||||
name: Update nightly tag
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[
|
||||
{
|
||||
"label": "Debug Zed with LLDB",
|
||||
"adapter": "lldb",
|
||||
"adapter": "LLDB",
|
||||
"program": "$ZED_WORKTREE_ROOT/target/debug/zed",
|
||||
"request": "launch",
|
||||
"cwd": "$ZED_WORKTREE_ROOT"
|
||||
},
|
||||
{
|
||||
"label": "Debug Zed with GDB",
|
||||
"adapter": "gdb",
|
||||
"adapter": "GDB",
|
||||
"program": "$ZED_WORKTREE_ROOT/target/debug/zed",
|
||||
"request": "launch",
|
||||
"cwd": "$ZED_WORKTREE_ROOT",
|
||||
|
||||
255
Cargo.lock
generated
255
Cargo.lock
generated
@@ -124,6 +124,43 @@ dependencies = [
|
||||
"zed_actions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agent_eval"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"agent",
|
||||
"anyhow",
|
||||
"assistant_tool",
|
||||
"assistant_tools",
|
||||
"clap",
|
||||
"client",
|
||||
"collections",
|
||||
"context_server",
|
||||
"dap",
|
||||
"env_logger 0.11.8",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"gpui_tokio",
|
||||
"language",
|
||||
"language_model",
|
||||
"language_models",
|
||||
"node_runtime",
|
||||
"project",
|
||||
"prompt_store",
|
||||
"release_channel",
|
||||
"reqwest_client",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_json_lenient",
|
||||
"settings",
|
||||
"smol",
|
||||
"tempfile",
|
||||
"util",
|
||||
"walkdir",
|
||||
"workspace-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.8"
|
||||
@@ -579,43 +616,6 @@ dependencies = [
|
||||
"zed_actions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assistant_eval"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"agent",
|
||||
"anyhow",
|
||||
"assistant_tool",
|
||||
"assistant_tools",
|
||||
"clap",
|
||||
"client",
|
||||
"collections",
|
||||
"context_server",
|
||||
"dap",
|
||||
"env_logger 0.11.8",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"gpui_tokio",
|
||||
"language",
|
||||
"language_model",
|
||||
"language_models",
|
||||
"node_runtime",
|
||||
"project",
|
||||
"prompt_store",
|
||||
"release_channel",
|
||||
"reqwest_client",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_json_lenient",
|
||||
"settings",
|
||||
"smol",
|
||||
"tempfile",
|
||||
"util",
|
||||
"walkdir",
|
||||
"workspace-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assistant_settings"
|
||||
version = "0.1.0"
|
||||
@@ -912,18 +912,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-native-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"native-tls",
|
||||
"thiserror 1.0.69",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-net"
|
||||
version = "2.0.0"
|
||||
@@ -1093,18 +1081,6 @@ version = "4.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||
|
||||
[[package]]
|
||||
name = "async-tls"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/zed-industries/async-tls?rev=1e759a4b5e370f87dc15e40756ac4f8815b61d9d#1e759a4b5e370f87dc15e40756ac4f8815b61d9d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustls 0.23.26",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.88"
|
||||
@@ -1118,12 +1094,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-tungstenite"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c348fb0b6d132c596eca3dcd941df48fb597aafcb07a738ec41c004b087dc99"
|
||||
checksum = "ef0f7efedeac57d9b26170f72965ecfd31473ca52ca7a64e925b0b6f5f079886"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-tls",
|
||||
"atomic-waker",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@@ -1131,7 +1105,10 @@ dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tungstenite 0.24.0",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tungstenite 0.26.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1647,7 +1624,7 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"pin-project-lite",
|
||||
"rustls 0.21.12",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
@@ -2837,7 +2814,6 @@ name = "client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-native-tls",
|
||||
"async-recursion 0.3.2",
|
||||
"async-tungstenite",
|
||||
"chrono",
|
||||
@@ -2848,6 +2824,7 @@ dependencies = [
|
||||
"feature_flags",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"gpui_tokio",
|
||||
"http_client",
|
||||
"http_client_tls",
|
||||
"log",
|
||||
@@ -2869,6 +2846,7 @@ dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
"tiny_http",
|
||||
"tokio",
|
||||
"tokio-socks",
|
||||
"url",
|
||||
"util",
|
||||
@@ -4049,7 +4027,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "dap-types"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/zed-industries/dap-types?rev=bfd4af0#bfd4af084bbaa5f344e6925370d7642e41d0b5b8"
|
||||
source = "git+https://github.com/zed-industries/dap-types?rev=be69a016ba710191b9fdded28c8b042af4b617f7#be69a016ba710191b9fdded28c8b042af4b617f7"
|
||||
dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -6607,7 +6585,7 @@ dependencies = [
|
||||
name = "http_client_tls"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-platform-verifier",
|
||||
"workspace-hack",
|
||||
]
|
||||
@@ -6706,7 +6684,7 @@ dependencies = [
|
||||
"http 1.3.1",
|
||||
"hyper 1.6.0",
|
||||
"hyper-util",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
@@ -7451,8 +7429,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jupyter-protocol"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9ae6296f9476658b3550293c113996daf75fa542cd8d078abb4c60207bded14"
|
||||
source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -7467,8 +7444,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jupyter-websocket-client"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49c1ba895c5271ff8dcae51c347fd3588905ba0025a57e20955fd231fe1228cc"
|
||||
source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -7899,7 +7875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8682,7 +8658,6 @@ dependencies = [
|
||||
"collections",
|
||||
"ctor",
|
||||
"env_logger 0.11.8",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"indoc",
|
||||
"itertools 0.14.0",
|
||||
@@ -8776,8 +8751,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nbformat"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "244c1673f02b4d5f3c51b6f8ed28d57182cb166a50a6dbf651a3d53e23dc81c0"
|
||||
source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -9556,15 +9530,6 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.4.2+3.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.107"
|
||||
@@ -9573,7 +9538,6 @@ checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
@@ -9997,7 +9961,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"env_logger 0.10.2",
|
||||
@@ -10034,7 +9998,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-conda"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"lazy_static",
|
||||
@@ -10053,7 +10017,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-core"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
@@ -10068,7 +10032,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-env-var-path"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -10084,7 +10048,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-fs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10093,7 +10057,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-global-virtualenvs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10106,7 +10070,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-homebrew"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -10124,7 +10088,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-jsonrpc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"log",
|
||||
@@ -10137,7 +10101,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-linux-global-python"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10150,7 +10114,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-mac-commandlinetools"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10163,7 +10127,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-mac-python-org"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10176,7 +10140,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-mac-xcode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10189,7 +10153,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-pipenv"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10202,7 +10166,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-pixi"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10214,7 +10178,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-poetry"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"lazy_static",
|
||||
@@ -10235,7 +10199,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-pyenv"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -10253,7 +10217,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-python-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"lazy_static",
|
||||
@@ -10270,7 +10234,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-reporter"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"log",
|
||||
@@ -10284,7 +10248,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-telemetry"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"env_logger 0.10.2",
|
||||
"lazy_static",
|
||||
@@ -10299,7 +10263,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-venv"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10311,7 +10275,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-virtualenv"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10323,7 +10287,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-virtualenvwrapper"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"log",
|
||||
"msvc_spectre_libs",
|
||||
@@ -10336,7 +10300,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pet-windows-registry"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -10348,13 +10312,13 @@ dependencies = [
|
||||
"pet-virtualenv",
|
||||
"pet-windows-store",
|
||||
"regex",
|
||||
"winreg 0.52.0",
|
||||
"winreg 0.55.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pet-windows-store"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0#1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0"
|
||||
source = "git+https://github.com/microsoft/python-environment-tools.git?rev=845945b830297a50de0e24020b980a65e4820559#845945b830297a50de0e24020b980a65e4820559"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -10364,7 +10328,7 @@ dependencies = [
|
||||
"pet-python-utils",
|
||||
"pet-virtualenv",
|
||||
"regex",
|
||||
"winreg 0.52.0",
|
||||
"winreg 0.55.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11237,7 +11201,7 @@ dependencies = [
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"socket2",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
@@ -11256,7 +11220,7 @@ dependencies = [
|
||||
"rand 0.9.0",
|
||||
"ring",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.12",
|
||||
@@ -11864,7 +11828,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"rustls-pki-types",
|
||||
@@ -12102,8 +12066,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "runtimelib"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9af6ed9fd10d7ee940676945510c197c2a472806bb652096a713985c44ffd643"
|
||||
source = "git+https://github.com/ConradIrwin/runtimed?rev=7130c804216b6914355d15d0b91ea91f6babd734#7130c804216b6914355d15d0b91ea91f6babd734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-dispatcher",
|
||||
@@ -12256,9 +12219,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.26"
|
||||
version = "0.23.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
|
||||
checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
@@ -12332,7 +12295,7 @@ dependencies = [
|
||||
"jni",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki 0.103.1",
|
||||
@@ -13430,7 +13393,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rust_decimal",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -14659,9 +14622,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.44.1"
|
||||
version = "1.44.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
|
||||
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes 1.10.1",
|
||||
@@ -14723,7 +14686,7 @@ version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
|
||||
dependencies = [
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -14783,7 +14746,7 @@ checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.2",
|
||||
@@ -15330,24 +15293,6 @@ dependencies = [
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes 1.10.1",
|
||||
"data-encoding",
|
||||
"http 1.3.1",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"sha1",
|
||||
"thiserror 1.0.69",
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.26.2"
|
||||
@@ -15360,7 +15305,7 @@ dependencies = [
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.9.0",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-pki-types",
|
||||
"sha1",
|
||||
"thiserror 2.0.12",
|
||||
@@ -17251,6 +17196,16 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winresource"
|
||||
version = "0.1.20"
|
||||
@@ -17696,12 +17651,11 @@ dependencies = [
|
||||
"rust_decimal",
|
||||
"rustix 0.38.44",
|
||||
"rustix 1.0.5",
|
||||
"rustls 0.23.26",
|
||||
"rustls 0.23.25",
|
||||
"rustls-webpki 0.103.1",
|
||||
"scopeguard",
|
||||
"sea-orm",
|
||||
"sea-query-binder",
|
||||
"security-framework 2.11.1",
|
||||
"security-framework 3.2.0",
|
||||
"security-framework-sys",
|
||||
"semver",
|
||||
@@ -17732,6 +17686,7 @@ dependencies = [
|
||||
"toml_edit",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tungstenite 0.26.2",
|
||||
"unicode-properties",
|
||||
"url",
|
||||
"uuid",
|
||||
@@ -18085,7 +18040,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.181.8"
|
||||
version = "0.182.0"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"agent",
|
||||
|
||||
35
Cargo.toml
35
Cargo.toml
@@ -8,7 +8,7 @@ members = [
|
||||
"crates/assets",
|
||||
"crates/assistant",
|
||||
"crates/assistant_context_editor",
|
||||
"crates/assistant_eval",
|
||||
"crates/agent_eval",
|
||||
"crates/assistant_settings",
|
||||
"crates/assistant_slash_command",
|
||||
"crates/assistant_slash_commands",
|
||||
@@ -215,7 +215,7 @@ askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant = { path = "crates/assistant" }
|
||||
assistant_context_editor = { path = "crates/assistant_context_editor" }
|
||||
assistant_eval = { path = "crates/assistant_eval" }
|
||||
assistant_eval = { path = "crates/agent_eval" }
|
||||
assistant_settings = { path = "crates/assistant_settings" }
|
||||
assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
|
||||
@@ -396,7 +396,7 @@ async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "8
|
||||
async-recursion = "1.0.0"
|
||||
async-tar = "0.5.0"
|
||||
async-trait = "0.1"
|
||||
async-tungstenite = "0.28"
|
||||
async-tungstenite = "0.29.1"
|
||||
async-watch = "0.3.1"
|
||||
async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
|
||||
aws-config = { version = "1.6.1", features = ["behavior-version-latest"] }
|
||||
@@ -425,7 +425,7 @@ core-foundation = "0.10.0"
|
||||
core-foundation-sys = "0.8.6"
|
||||
ctor = "0.4.0"
|
||||
dashmap = "6.0"
|
||||
dap-types = { git = "https://github.com/zed-industries/dap-types", rev = "bfd4af0" }
|
||||
dap-types = { git = "https://github.com/zed-industries/dap-types", rev = "be69a016ba710191b9fdded28c8b042af4b617f7" }
|
||||
derive_more = "0.99.17"
|
||||
dirs = "4.0"
|
||||
ec4rs = "1.1"
|
||||
@@ -453,8 +453,8 @@ indoc = "2"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
jsonwebtoken = "9.3"
|
||||
jupyter-protocol = { version = "0.6.0" }
|
||||
jupyter-websocket-client = { version = "0.9.0" }
|
||||
jupyter-protocol = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
jupyter-websocket-client = { git = "https://github.com/ConradIrwin/runtimed" ,rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
libc = "0.2"
|
||||
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
|
||||
linkify = "0.10.0"
|
||||
@@ -463,21 +463,22 @@ log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
markup5ever_rcdom = "0.3.0"
|
||||
mlua = { version = "0.10", features = ["lua54", "vendored", "async", "send"] }
|
||||
nanoid = "0.4"
|
||||
nbformat = { version = "0.10.0" }
|
||||
nbformat = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
nix = "0.29"
|
||||
objc = "0.2"
|
||||
open = "5.0.0"
|
||||
num-format = "0.4.4"
|
||||
ordered-float = "2.1.1"
|
||||
palette = { version = "0.7.5", default-features = false, features = ["std"] }
|
||||
parking_lot = "0.12.1"
|
||||
pathdiff = "0.2"
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-pixi = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-pixi = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
@@ -500,13 +501,13 @@ reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "fd110f
|
||||
"stream",
|
||||
] }
|
||||
rsa = "0.9.6"
|
||||
runtimelib = { version = "0.25.0", default-features = false, features = [
|
||||
runtimelib = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734", default-features = false, features = [
|
||||
"async-dispatcher-runtime",
|
||||
] }
|
||||
rustc-demangle = "0.1.23"
|
||||
rust-embed = { version = "8.4", features = ["include-exclude"] }
|
||||
rustc-hash = "2.1.0"
|
||||
rustls = { version = "0.23.26" }
|
||||
rustls = { version = "0.23.22" }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
scap = { git = "https://github.com/zed-industries/scap", rev = "08f0a01417505cc0990b9931a37e5120db92e0d0", default-features = false }
|
||||
schemars = { version = "0.8", features = ["impl_json_schema", "indexmap2"] }
|
||||
@@ -660,7 +661,6 @@ features = [
|
||||
# TODO livekit https://github.com/RustAudio/cpal/pull/891
|
||||
[patch.crates-io]
|
||||
cpal = { git = "https://github.com/zed-industries/cpal", rev = "fd8bc2fd39f1f5fdee5a0690656caff9a26d9d50" }
|
||||
real-async-tls = { git = "https://github.com/zed-industries/async-tls", rev = "1e759a4b5e370f87dc15e40756ac4f8815b61d9d", package = "async-tls" }
|
||||
notify = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
|
||||
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
|
||||
|
||||
@@ -669,7 +669,6 @@ workspace-hack = { path = "tooling/workspace-hack" }
|
||||
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
debug = "limited"
|
||||
codegen-units = 16
|
||||
|
||||
[profile.dev.package]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax = docker/dockerfile:1.2
|
||||
|
||||
FROM rust:1.81-bookworm as builder
|
||||
FROM rust:1.86-bookworm as builder
|
||||
WORKDIR app
|
||||
COPY . .
|
||||
|
||||
|
||||
1
assets/icons/arrow_down_right.svg
Normal file
1
assets/icons/arrow_down_right.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-right-icon lucide-arrow-down-right"><path d="m7 7 10 10"/><path d="M17 7v10H7"/></svg>
|
||||
|
After Width: | Height: | Size: 300 B |
@@ -1,3 +1 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2H6.5C6.5 1.86739 6.44732 1.74021 6.35355 1.64645C6.25979 1.55268 6.13261 1.5 6 1.5V2ZM2 1.5C1.72386 1.5 1.5 1.72386 1.5 2C1.5 2.27614 1.72386 2.5 2 2.5L2 1.5ZM5.5 6C5.5 6.27614 5.72386 6.5 6 6.5C6.27614 6.5 6.5 6.27614 6.5 6H5.5ZM1.64645 5.64645C1.45118 5.84171 1.45118 6.15829 1.64645 6.35355C1.84171 6.54882 2.15829 6.54882 2.35355 6.35355L1.64645 5.64645ZM6 1.5H2L2 2.5H6V1.5ZM5.5 2V6H6.5V2H5.5ZM5.64645 1.64645L1.64645 5.64645L2.35355 6.35355L6.35355 2.35355L5.64645 1.64645Z" fill="white"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-right-icon lucide-arrow-up-right"><path d="M7 7h10v10"/><path d="M7 17 17 7"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 608 B After Width: | Height: | Size: 296 B |
1
assets/icons/bug_off.svg
Normal file
1
assets/icons/bug_off.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bug-off-icon lucide-bug-off"><path d="M15 7.13V6a3 3 0 0 0-5.14-2.1L8 2"/><path d="M14.12 3.88 16 2"/><path d="M22 13h-4v-2a4 4 0 0 0-4-4h-1.3"/><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"/><path d="m2 2 20 20"/><path d="M7.7 7.7A4 4 0 0 0 6 11v3a6 6 0 0 0 11.13 3.13"/><path d="M12 20v-8"/><path d="M6 13H2"/><path d="M3 21c0-2.1 1.7-3.9 3.8-4"/></svg>
|
||||
|
After Width: | Height: | Size: 551 B |
1
assets/icons/circle_off.svg
Normal file
1
assets/icons/circle_off.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-off-icon lucide-circle-off"><path d="m2 2 20 20"/><path d="M8.35 2.69A10 10 0 0 1 21.3 15.65"/><path d="M19.08 19.08A10 10 0 1 1 4.92 4.92"/></svg>
|
||||
|
After Width: | Height: | Size: 357 B |
1
assets/icons/power.svg
Normal file
1
assets/icons/power.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-power-icon lucide-power"><path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.77.04"/></svg>
|
||||
|
After Width: | Height: | Size: 294 B |
@@ -311,6 +311,7 @@
|
||||
"ctrl-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }],
|
||||
"ctrl-k u": ["pane::CloseCleanItems", { "close_pinned": false }],
|
||||
"ctrl-k w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"ctrl-k ctrl-w": "workspace::CloseAllItemsAndPanes",
|
||||
"back": "pane::GoBack",
|
||||
"ctrl-alt--": "pane::GoBack",
|
||||
"ctrl-alt-_": "pane::GoForward",
|
||||
@@ -481,6 +482,8 @@
|
||||
"alt-shift-r": ["task::Spawn", { "reveal_target": "center" }]
|
||||
// also possible to spawn tasks by name:
|
||||
// "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }]
|
||||
// or by tag:
|
||||
// "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }],
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -455,7 +455,8 @@
|
||||
"cmd-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }],
|
||||
"cmd-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }],
|
||||
"cmd-k u": ["pane::CloseCleanItems", { "close_pinned": false }],
|
||||
"cmd-k cmd-w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"cmd-k w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"cmd-k cmd-w": "workspace::CloseAllItemsAndPanes",
|
||||
"cmd-f": "project_search::ToggleFocus",
|
||||
"cmd-g": "search::SelectNextMatch",
|
||||
"cmd-shift-g": "search::SelectPreviousMatch",
|
||||
@@ -524,7 +525,7 @@
|
||||
"cmd-k cmd-9": ["editor::FoldAtLevel", 9],
|
||||
"cmd-k cmd-0": "editor::FoldAll",
|
||||
"cmd-k cmd-j": "editor::UnfoldAll",
|
||||
// Using `ctrl-space` in Zed requires disabling the macOS global shortcut.
|
||||
// Using `ctrl-space` / `ctrl-shift-space` in Zed requires disabling the macOS global shortcut.
|
||||
// System Preferences->Keyboard->Keyboard Shortcuts->Input Sources->Select the previous input source (uncheck)
|
||||
"ctrl-space": "editor::ShowCompletions",
|
||||
"ctrl-shift-space": "editor::ShowWordCompletions",
|
||||
@@ -632,6 +633,8 @@
|
||||
"ctrl-alt-shift-r": ["task::Spawn", { "reveal_target": "center" }]
|
||||
// also possible to spawn tasks by name:
|
||||
// "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }]
|
||||
// or by tag:
|
||||
// "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }],
|
||||
}
|
||||
},
|
||||
// Bindings from Sublime Text
|
||||
@@ -1000,6 +1003,8 @@
|
||||
"cmd-home": "terminal::ScrollToTop",
|
||||
"shift-end": "terminal::ScrollToBottom",
|
||||
"cmd-end": "terminal::ScrollToBottom",
|
||||
// Using `ctrl-shift-space` in Zed requires disabling the macOS global shortcut.
|
||||
// System Preferences->Keyboard->Keyboard Shortcuts->Input Sources->Select the previous input source (uncheck)
|
||||
"ctrl-shift-space": "terminal::ToggleViMode",
|
||||
"ctrl-k up": "pane::SplitUp",
|
||||
"ctrl-k down": "pane::SplitDown",
|
||||
|
||||
@@ -44,6 +44,12 @@
|
||||
"[ /": "vim::PreviousComment",
|
||||
"] *": "vim::NextComment",
|
||||
"] /": "vim::NextComment",
|
||||
"[ -": "vim::PreviousLesserIndent",
|
||||
"[ +": "vim::PreviousGreaterIndent",
|
||||
"[ =": "vim::PreviousSameIndent",
|
||||
"] -": "vim::NextLesserIndent",
|
||||
"] +": "vim::NextGreaterIndent",
|
||||
"] =": "vim::NextSameIndent",
|
||||
// Word motions
|
||||
"w": "vim::NextWordStart",
|
||||
"e": "vim::NextWordEnd",
|
||||
@@ -335,27 +341,106 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_mode == helix_normal",
|
||||
"context": "vim_mode == helix_normal && !menu",
|
||||
"bindings": {
|
||||
"escape": "editor::Cancel",
|
||||
"ctrl-[": "editor::Cancel",
|
||||
":": "command_palette::Toggle",
|
||||
"shift-d": "vim::DeleteToEndOfLine",
|
||||
"shift-j": "vim::JoinLines",
|
||||
"y": "editor::Copy",
|
||||
"shift-y": "vim::YankLine",
|
||||
"i": "vim::InsertBefore",
|
||||
"shift-i": "vim::InsertFirstNonWhitespace",
|
||||
"a": "vim::InsertAfter",
|
||||
"d": "vim::HelixDelete",
|
||||
"w": "vim::NextWordStart",
|
||||
"e": "vim::NextWordEnd",
|
||||
"b": "vim::PreviousWordStart",
|
||||
"shift-a": "vim::InsertEndOfLine",
|
||||
"o": "vim::InsertLineBelow",
|
||||
"shift-o": "vim::InsertLineAbove",
|
||||
"~": "vim::ChangeCase",
|
||||
"ctrl-a": "vim::Increment",
|
||||
"ctrl-x": "vim::Decrement",
|
||||
"p": "vim::Paste",
|
||||
"shift-p": ["vim::Paste", { "before": true }],
|
||||
"u": "vim::Undo",
|
||||
"ctrl-r": "vim::Redo",
|
||||
"r": "vim::PushReplace",
|
||||
"s": "vim::Substitute",
|
||||
"shift-s": "vim::SubstituteLine",
|
||||
">": "vim::Indent",
|
||||
"<": "vim::Outdent",
|
||||
"=": "vim::AutoIndent",
|
||||
"g u": "vim::PushLowercase",
|
||||
"g shift-u": "vim::PushUppercase",
|
||||
"g ~": "vim::PushOppositeCase",
|
||||
"\"": "vim::PushRegister",
|
||||
"g q": "vim::PushRewrap",
|
||||
"g w": "vim::PushRewrap",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"insert": "vim::InsertBefore",
|
||||
// tree-sitter related commands
|
||||
"[ x": "editor::SelectLargerSyntaxNode",
|
||||
"] x": "editor::SelectSmallerSyntaxNode",
|
||||
"] d": "editor::GoToDiagnostic",
|
||||
"[ d": "editor::GoToPreviousDiagnostic",
|
||||
"] c": "editor::GoToHunk",
|
||||
"[ c": "editor::GoToPreviousHunk",
|
||||
// Goto mode
|
||||
"g n": "pane::ActivateNextItem",
|
||||
"g p": "pane::ActivatePreviousItem",
|
||||
// "tab": "pane::ActivateNextItem",
|
||||
// "shift-tab": "pane::ActivatePrevItem",
|
||||
"shift-h": "pane::ActivatePreviousItem",
|
||||
"shift-l": "pane::ActivateNextItem",
|
||||
"g l": "vim::EndOfLine",
|
||||
"g h": "vim::StartOfLine",
|
||||
"g s": "vim::FirstNonWhitespace", // "g s" default behavior is "space s"
|
||||
"g e": "vim::EndOfDocument",
|
||||
"g y": "editor::GoToTypeDefinition",
|
||||
"g r": "editor::FindAllReferences", // zed specific
|
||||
"g t": "vim::WindowTop",
|
||||
"g c": "vim::WindowMiddle",
|
||||
"g b": "vim::WindowBottom",
|
||||
|
||||
"h": "vim::Left",
|
||||
"j": "vim::Down",
|
||||
"k": "vim::Up",
|
||||
"l": "vim::Right"
|
||||
"x": "editor::SelectLine",
|
||||
"shift-x": "editor::SelectLine",
|
||||
// Window mode
|
||||
"space w h": "workspace::ActivatePaneLeft",
|
||||
"space w l": "workspace::ActivatePaneRight",
|
||||
"space w k": "workspace::ActivatePaneUp",
|
||||
"space w j": "workspace::ActivatePaneDown",
|
||||
"space w q": "pane::CloseActiveItem",
|
||||
"space w s": "pane::SplitRight",
|
||||
"space w r": "pane::SplitRight",
|
||||
"space w v": "pane::SplitDown",
|
||||
"space w d": "pane::SplitDown",
|
||||
// Space mode
|
||||
"space f": "file_finder::Toggle",
|
||||
"space k": "editor::Hover",
|
||||
"space s": "outline::Toggle",
|
||||
"space shift-s": "project_symbols::Toggle",
|
||||
"space d": "editor::GoToDiagnostic",
|
||||
"space r": "editor::Rename",
|
||||
"space a": "editor::ToggleCodeActions",
|
||||
"space h": "editor::SelectAllMatches",
|
||||
"space c": "editor::ToggleComments",
|
||||
"space y": "editor::Copy",
|
||||
"space p": "editor::Paste",
|
||||
// Match mode
|
||||
"m m": "vim::Matching",
|
||||
"m i w": ["workspace::SendKeystrokes", "v i w"],
|
||||
"shift-u": "editor::Redo",
|
||||
"ctrl-c": "editor::ToggleComments",
|
||||
"d": "vim::HelixDelete",
|
||||
"c": "vim::Substitute",
|
||||
"shift-c": "editor::AddSelectionBelow"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"context": "vim_mode == insert && !(showing_code_actions || showing_completions)",
|
||||
"bindings": {
|
||||
"ctrl-p": "editor::ShowCompletions",
|
||||
"ctrl-n": "editor::ShowCompletions"
|
||||
"ctrl-p": "editor::ShowWordCompletions",
|
||||
"ctrl-n": "editor::ShowWordCompletions"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,8 +16,6 @@ no need to create backup files (e.g. `.bak` files) because these files will just
|
||||
|
||||
When attempting to resolve issues around failing tests, never simply remove the failing tests. Unless the user explicitly asks you to remove tests, ALWAYS attempt to fix the code causing the tests to fail.
|
||||
|
||||
Ignore "TODO"-type comments unless they're relevant to the user's explicit request or the user specifically asks you to address them. It is, however, okay to include them in codebase summaries.
|
||||
|
||||
<style>
|
||||
Editing code:
|
||||
- Make sure to take previous edits into account.
|
||||
|
||||
@@ -1200,7 +1200,27 @@
|
||||
// When set to 0, waits indefinitely.
|
||||
//
|
||||
// Default: 0
|
||||
"lsp_fetch_timeout_ms": 0
|
||||
"lsp_fetch_timeout_ms": 0,
|
||||
// Controls what range to replace when accepting LSP completions.
|
||||
//
|
||||
// When LSP servers give an `InsertReplaceEdit` completion, they provides two ranges: `insert` and `replace`. Usually, `insert`
|
||||
// contains the word prefix before your cursor and `replace` contains the whole word.
|
||||
//
|
||||
// Effectively, this setting just changes whether Zed will use the received range for `insert` or `replace`, so the results may
|
||||
// differ depending on the underlying LSP server.
|
||||
//
|
||||
// Possible values:
|
||||
// 1. "insert"
|
||||
// Replaces text before the cursor, using the `insert` range described in the LSP specification.
|
||||
// 2. "replace"
|
||||
// Replaces text before and after the cursor, using the `replace` range described in the LSP specification.
|
||||
// 3. "replace_subsequence"
|
||||
// Behaves like `"replace"` if the text that would be replaced is a subsequence of the completion text,
|
||||
// and like `"insert"` otherwise.
|
||||
// 4. "replace_suffix"
|
||||
// Behaves like `"replace"` if the text after the cursor is a suffix of the completion, and like
|
||||
// `"insert"` otherwise.
|
||||
"lsp_insert_mode": "replace_suffix"
|
||||
},
|
||||
// Different settings for specific languages.
|
||||
"languages": {
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
// "args": ["--login"]
|
||||
// }
|
||||
// }
|
||||
"shell": "system"
|
||||
"shell": "system",
|
||||
// Represents the tags for inline runnable indicators, or spawning multiple tasks at once.
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -87,9 +87,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -472,9 +472,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -857,9 +857,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -1242,9 +1242,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
@@ -1627,9 +1627,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
@@ -2012,9 +2012,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
|
||||
@@ -11,13 +11,22 @@ use language::{BinaryStatus, LanguageRegistry, LanguageServerId};
|
||||
use project::{
|
||||
EnvironmentErrorMessage, LanguageServerProgress, LspStoreEvent, Project,
|
||||
ProjectEnvironmentEvent,
|
||||
git_store::{GitStoreEvent, Repository},
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp::Reverse, fmt::Write, path::Path, sync::Arc, time::Duration};
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
fmt::Write,
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use ui::{ButtonLike, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
||||
use util::truncate_and_trailoff;
|
||||
use workspace::{StatusItemView, Workspace, item::ItemHandle};
|
||||
|
||||
const GIT_OPERATION_DELAY: Duration = Duration::from_millis(0);
|
||||
|
||||
actions!(activity_indicator, [ShowErrorMessage]);
|
||||
|
||||
pub enum Event {
|
||||
@@ -105,6 +114,15 @@ impl ActivityIndicator {
|
||||
)
|
||||
.detach();
|
||||
|
||||
cx.subscribe(
|
||||
&project.read(cx).git_store().clone(),
|
||||
|_, _, event: &GitStoreEvent, cx| match event {
|
||||
project::git_store::GitStoreEvent::JobsUpdated => cx.notify(),
|
||||
_ => {}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
|
||||
if let Some(auto_updater) = auto_updater.as_ref() {
|
||||
cx.observe(auto_updater, |_, _, cx| cx.notify()).detach();
|
||||
}
|
||||
@@ -285,6 +303,34 @@ impl ActivityIndicator {
|
||||
});
|
||||
}
|
||||
|
||||
let current_job = self
|
||||
.project
|
||||
.read(cx)
|
||||
.active_repository(cx)
|
||||
.map(|r| r.read(cx))
|
||||
.and_then(Repository::current_job);
|
||||
// Show any long-running git command
|
||||
if let Some(job_info) = current_job {
|
||||
if Instant::now() - job_info.start >= GIT_OPERATION_DELAY {
|
||||
return Some(Content {
|
||||
icon: Some(
|
||||
Icon::new(IconName::ArrowCircle)
|
||||
.size(IconSize::Small)
|
||||
.with_animation(
|
||||
"arrow-circle",
|
||||
Animation::new(Duration::from_secs(2)).repeat(),
|
||||
|icon, delta| {
|
||||
icon.transform(Transformation::rotate(percentage(delta)))
|
||||
},
|
||||
)
|
||||
.into_any_element(),
|
||||
),
|
||||
message: job_info.message.into(),
|
||||
on_click: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Show any language server installation info.
|
||||
let mut downloading = SmallVec::<[_; 3]>::new();
|
||||
let mut checking_for_update = SmallVec::<[_; 3]>::new();
|
||||
|
||||
@@ -21,7 +21,10 @@ use gpui::{
|
||||
linear_color_stop, linear_gradient, list, percentage, pulsating_between,
|
||||
};
|
||||
use language::{Buffer, LanguageRegistry};
|
||||
use language_model::{ConfiguredModel, LanguageModelRegistry, LanguageModelToolUseId, Role};
|
||||
use language_model::{
|
||||
ConfiguredModel, LanguageModelRegistry, LanguageModelToolUseId, Role, StringToolOutput,
|
||||
ToolOutput,
|
||||
};
|
||||
use markdown::parser::CodeBlockKind;
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle, ParsedMarkdown, without_fences};
|
||||
use project::ProjectItem as _;
|
||||
@@ -36,6 +39,7 @@ use text::ToPoint;
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Disclosure, IconButton, KeyBinding, Scrollbar, ScrollbarState, Tooltip, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
use util::markdown::MarkdownString;
|
||||
use workspace::{OpenOptions, Workspace};
|
||||
|
||||
use crate::context_store::ContextStore;
|
||||
@@ -74,7 +78,7 @@ struct RenderedMessage {
|
||||
struct RenderedToolUse {
|
||||
label: Entity<Markdown>,
|
||||
input: Entity<Markdown>,
|
||||
output: Entity<Markdown>,
|
||||
output: ToolOutput,
|
||||
}
|
||||
|
||||
impl RenderedMessage {
|
||||
@@ -729,21 +733,28 @@ impl ActiveThread {
|
||||
tool_use_id: LanguageModelToolUseId,
|
||||
tool_label: impl Into<SharedString>,
|
||||
tool_input: &serde_json::Value,
|
||||
tool_output: SharedString,
|
||||
tool_output: ToolOutput,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let rendered = RenderedToolUse {
|
||||
label: render_tool_use_markdown(tool_label.into(), self.language_registry.clone(), cx),
|
||||
input: render_tool_use_markdown(
|
||||
format!(
|
||||
"```json\n{}\n```",
|
||||
serde_json::to_string_pretty(tool_input).unwrap_or_default()
|
||||
MarkdownString::code_block(
|
||||
"json",
|
||||
&serde_json::to_string_pretty(tool_input).unwrap_or_default(),
|
||||
)
|
||||
.to_string()
|
||||
.into(),
|
||||
self.language_registry.clone(),
|
||||
cx,
|
||||
),
|
||||
output: render_tool_use_markdown(tool_output, self.language_registry.clone(), cx),
|
||||
output: render_tool_use_markdown(
|
||||
tool_output.clone(),
|
||||
self.language_registry.clone(),
|
||||
cx,
|
||||
),
|
||||
output: StringToolOutput::new(tool_output, language_registry: Arc<LanguageRegistry>),
|
||||
|
||||
};
|
||||
self.rendered_tool_uses
|
||||
.insert(tool_use_id.clone(), rendered);
|
||||
@@ -1746,7 +1757,7 @@ impl ActiveThread {
|
||||
.segments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.last()
|
||||
.next_back()
|
||||
.filter(|(_, segment)| matches!(segment, RenderedMessageSegment::Thinking { .. }))
|
||||
.map(|(index, _)| index)
|
||||
} else {
|
||||
@@ -2094,24 +2105,50 @@ impl ActiveThread {
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Result")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(div().w_full().text_ui_sm(cx).children(
|
||||
rendered_tool_use.as_ref().map(|rendered| {
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
.on_url_click({
|
||||
let workspace = self.workspace.clone();
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(text, workspace.clone(), window, cx);
|
||||
let tool_name = tool_use.name.to_string();
|
||||
let tool_registry = assistant_tool::ToolRegistry::global(cx);
|
||||
|
||||
if let Some(_tool) = tool_registry.tool(&tool_name) {
|
||||
// Tool doesn't have a render method, but ToolOutput does
|
||||
match rendered.output.render(window, cx) {
|
||||
Some(rendered) => rendered,
|
||||
None => {
|
||||
// Default to rendering the output as markdown
|
||||
div()
|
||||
.child(
|
||||
Label::new("Result")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(
|
||||
div().w_full().text_ui_sm(cx).child(
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
.on_url_click({
|
||||
let workspace = self.workspace.clone();
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(
|
||||
text,
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
log::error!("Tool not found: {tool_name}");
|
||||
gpui::Empty.into_any_element()
|
||||
}
|
||||
}),
|
||||
)),
|
||||
),
|
||||
@@ -2158,16 +2195,30 @@ impl ActiveThread {
|
||||
div()
|
||||
.text_ui_sm(cx)
|
||||
.children(rendered_tool_use.as_ref().map(|rendered| {
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
.on_url_click({
|
||||
let workspace = self.workspace.clone();
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(text, workspace.clone(), window, cx);
|
||||
}
|
||||
})
|
||||
let tool_name = tool_use.name.to_string();
|
||||
let tool_registry = assistant_tool::ToolRegistry::global(cx);
|
||||
|
||||
tool_registry
|
||||
.tool(&tool_name)
|
||||
.and_then(|_tool| None) // Tool doesn't have a render method, but ToolOutput does
|
||||
.unwrap_or_else(|| {
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
.on_url_click({
|
||||
let workspace = self.workspace.clone();
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(
|
||||
text,
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
})
|
||||
.into_any_element()
|
||||
})
|
||||
})),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -28,7 +28,7 @@ use std::{
|
||||
time::Instant,
|
||||
};
|
||||
use streaming_diff::{CharOperation, LineDiff, LineOperation, StreamingDiff};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
|
||||
pub struct BufferCodegen {
|
||||
alternatives: Vec<Entity<CodegenAlternative>>,
|
||||
@@ -601,7 +601,7 @@ impl CodegenAlternative {
|
||||
|
||||
let error_message = result.as_ref().err().map(|error| error.to_string());
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
message_id,
|
||||
kind: AssistantKind::Inline,
|
||||
|
||||
@@ -112,6 +112,7 @@ impl ContextPickerCompletionProvider {
|
||||
icon_path: Some(mode.icon().path().into()),
|
||||
documentation: None,
|
||||
source: project::CompletionSource::Custom,
|
||||
insert_text_mode: None,
|
||||
// This ensures that when a user accepts this completion, the
|
||||
// completion menu will still be shown after "@category " is
|
||||
// inserted
|
||||
@@ -163,6 +164,7 @@ impl ContextPickerCompletionProvider {
|
||||
new_text,
|
||||
label: CodeLabel::plain(thread_entry.summary.to_string(), None),
|
||||
documentation: None,
|
||||
insert_text_mode: None,
|
||||
source: project::CompletionSource::Custom,
|
||||
icon_path: Some(icon_for_completion.path().into()),
|
||||
confirm: Some(confirm_completion_callback(
|
||||
@@ -209,6 +211,7 @@ impl ContextPickerCompletionProvider {
|
||||
documentation: None,
|
||||
source: project::CompletionSource::Custom,
|
||||
icon_path: Some(IconName::Globe.path().into()),
|
||||
insert_text_mode: None,
|
||||
confirm: Some(confirm_completion_callback(
|
||||
IconName::Globe.path().into(),
|
||||
url_to_fetch.clone(),
|
||||
@@ -290,6 +293,7 @@ impl ContextPickerCompletionProvider {
|
||||
documentation: None,
|
||||
source: project::CompletionSource::Custom,
|
||||
icon_path: Some(completion_icon_path),
|
||||
insert_text_mode: None,
|
||||
confirm: Some(confirm_completion_callback(
|
||||
crease_icon_path,
|
||||
file_name,
|
||||
@@ -352,6 +356,7 @@ impl ContextPickerCompletionProvider {
|
||||
documentation: None,
|
||||
source: project::CompletionSource::Custom,
|
||||
icon_path: Some(IconName::Code.path().into()),
|
||||
insert_text_mode: None,
|
||||
confirm: Some(confirm_completion_callback(
|
||||
IconName::Code.path().into(),
|
||||
symbol.name.clone().into(),
|
||||
|
||||
@@ -31,7 +31,7 @@ use project::LspAction;
|
||||
use project::{CodeAction, ProjectTransaction};
|
||||
use prompt_store::PromptBuilder;
|
||||
use settings::{Settings, SettingsStore};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use terminal_view::{TerminalView, terminal_panel::TerminalPanel};
|
||||
use text::{OffsetRangeExt, ToPoint as _};
|
||||
use ui::prelude::*;
|
||||
@@ -402,7 +402,7 @@ impl InlineAssistant {
|
||||
codegen_ranges.push(anchor_range);
|
||||
|
||||
if let Some(model) = LanguageModelRegistry::read_global(cx).inline_assistant_model() {
|
||||
self.telemetry.report_assistant_event(AssistantEvent {
|
||||
self.telemetry.report_assistant_event(AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::Inline,
|
||||
phase: AssistantPhase::Invoked,
|
||||
@@ -987,7 +987,7 @@ impl InlineAssistant {
|
||||
.map(|language| language.name())
|
||||
});
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::Inline,
|
||||
message_id,
|
||||
|
||||
@@ -222,7 +222,8 @@ impl MessageEditor {
|
||||
|
||||
let thread = self.thread.clone();
|
||||
let context_store = self.context_store.clone();
|
||||
let checkpoint = self.project.read(cx).git_store().read(cx).checkpoint(cx);
|
||||
let git_store = self.project.read(cx).git_store().clone();
|
||||
let checkpoint = git_store.update(cx, |git_store, cx| git_store.checkpoint(cx));
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
let checkpoint = checkpoint.await.ok();
|
||||
|
||||
@@ -6,7 +6,7 @@ use language_model::{
|
||||
ConfiguredModel, LanguageModelRegistry, LanguageModelRequest, report_assistant_event,
|
||||
};
|
||||
use std::{sync::Arc, time::Instant};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use terminal::Terminal;
|
||||
|
||||
pub struct TerminalCodegen {
|
||||
@@ -79,7 +79,7 @@ impl TerminalCodegen {
|
||||
|
||||
let error_message = result.as_ref().err().map(|error| error.to_string());
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::InlineTerminal,
|
||||
message_id,
|
||||
|
||||
@@ -18,7 +18,7 @@ use language_model::{
|
||||
};
|
||||
use prompt_store::PromptBuilder;
|
||||
use std::sync::Arc;
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use terminal_view::TerminalView;
|
||||
use ui::prelude::*;
|
||||
use util::ResultExt;
|
||||
@@ -292,7 +292,7 @@ impl TerminalInlineAssistant {
|
||||
let codegen = assist.codegen.read(cx);
|
||||
let executor = cx.background_executor().clone();
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::InlineTerminal,
|
||||
message_id: codegen.message_id.clone(),
|
||||
|
||||
@@ -471,11 +471,11 @@ impl Thread {
|
||||
cx.emit(ThreadEvent::CheckpointChanged);
|
||||
cx.notify();
|
||||
|
||||
let project = self.project.read(cx);
|
||||
let restore = project
|
||||
.git_store()
|
||||
.read(cx)
|
||||
.restore_checkpoint(checkpoint.git_checkpoint.clone(), cx);
|
||||
let git_store = self.project().read(cx).git_store().clone();
|
||||
let restore = git_store.update(cx, |git_store, cx| {
|
||||
git_store.restore_checkpoint(checkpoint.git_checkpoint.clone(), cx)
|
||||
});
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
let result = restore.await;
|
||||
this.update(cx, |this, cx| {
|
||||
@@ -506,11 +506,11 @@ impl Thread {
|
||||
};
|
||||
|
||||
let git_store = self.project.read(cx).git_store().clone();
|
||||
let final_checkpoint = git_store.read(cx).checkpoint(cx);
|
||||
let final_checkpoint = git_store.update(cx, |git_store, cx| git_store.checkpoint(cx));
|
||||
cx.spawn(async move |this, cx| match final_checkpoint.await {
|
||||
Ok(final_checkpoint) => {
|
||||
let equal = git_store
|
||||
.read_with(cx, |store, cx| {
|
||||
.update(cx, |store, cx| {
|
||||
store.compare_checkpoints(
|
||||
pending_checkpoint.git_checkpoint.clone(),
|
||||
final_checkpoint.clone(),
|
||||
@@ -522,7 +522,7 @@ impl Thread {
|
||||
|
||||
if equal {
|
||||
git_store
|
||||
.read_with(cx, |store, cx| {
|
||||
.update(cx, |store, cx| {
|
||||
store.delete_checkpoint(pending_checkpoint.git_checkpoint, cx)
|
||||
})?
|
||||
.detach();
|
||||
@@ -533,7 +533,7 @@ impl Thread {
|
||||
}
|
||||
|
||||
git_store
|
||||
.read_with(cx, |store, cx| {
|
||||
.update(cx, |store, cx| {
|
||||
store.delete_checkpoint(final_checkpoint, cx)
|
||||
})?
|
||||
.detach();
|
||||
@@ -1651,10 +1651,10 @@ impl Thread {
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|repo| {
|
||||
repo.read_with(cx, |repo, _| {
|
||||
repo.update(cx, |repo, _| {
|
||||
let current_branch =
|
||||
repo.branch.as_ref().map(|branch| branch.name.to_string());
|
||||
repo.send_job(|state, _| async move {
|
||||
repo.send_job(None, |state, _| async move {
|
||||
let RepositoryState::Local { backend, .. } = state else {
|
||||
return GitState {
|
||||
remote_url: None,
|
||||
|
||||
@@ -6,6 +6,7 @@ use collections::HashMap;
|
||||
use futures::FutureExt as _;
|
||||
use futures::future::Shared;
|
||||
use gpui::{App, SharedString, Task};
|
||||
use language_model::ToolOutput;
|
||||
use language_model::{
|
||||
LanguageModelRegistry, LanguageModelRequestMessage, LanguageModelToolResult,
|
||||
LanguageModelToolUse, LanguageModelToolUseId, MessageContent, Role,
|
||||
@@ -32,7 +33,7 @@ pub enum ToolUseStatus {
|
||||
NeedsConfirmation,
|
||||
Pending,
|
||||
Running,
|
||||
Finished(SharedString),
|
||||
Finished(ToolOutput),
|
||||
Error(SharedString),
|
||||
}
|
||||
|
||||
@@ -131,6 +132,7 @@ impl ToolUseState {
|
||||
tool_name: tool_use.clone(),
|
||||
is_error: tool_result.is_error,
|
||||
content: tool_result.content.clone(),
|
||||
tool_output: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -153,6 +155,7 @@ impl ToolUseState {
|
||||
tool_name: tool_use.name.clone(),
|
||||
content: "Tool canceled by user".into(),
|
||||
is_error: true,
|
||||
tool_output: None,
|
||||
},
|
||||
);
|
||||
pending_tools.push(tool_use.clone());
|
||||
@@ -331,7 +334,7 @@ impl ToolUseState {
|
||||
&mut self,
|
||||
tool_use_id: LanguageModelToolUseId,
|
||||
tool_name: Arc<str>,
|
||||
output: Result<String>,
|
||||
output: Result<ToolOutput>,
|
||||
cx: &App,
|
||||
) -> Option<PendingToolUse> {
|
||||
match output {
|
||||
@@ -346,16 +349,19 @@ impl ToolUseState {
|
||||
.map(|model| model.model.max_token_count() * BYTES_PER_TOKEN_ESTIMATE)
|
||||
.unwrap_or(usize::MAX);
|
||||
|
||||
let tool_result = if tool_result.len() <= tool_output_limit {
|
||||
tool_result
|
||||
} else {
|
||||
let truncated = truncate_lines_to_byte_limit(&tool_result, tool_output_limit);
|
||||
// Get string representation of the tool result
|
||||
let response_text = tool_result.response_for_model();
|
||||
|
||||
format!(
|
||||
"Tool result too long. The first {} bytes:\n\n{}",
|
||||
truncated.len(),
|
||||
truncated
|
||||
)
|
||||
// Check length and truncate if needed
|
||||
let final_tool_result = if response_text.len() <= tool_output_limit {
|
||||
response_text.to_string()
|
||||
} else {
|
||||
let response_string = response_text.to_string();
|
||||
let truncated =
|
||||
truncate_lines_to_byte_limit(&response_string, tool_output_limit);
|
||||
let truncated_len = truncated.len();
|
||||
|
||||
format!("Tool result too long. The first {truncated_len} bytes:\n\n{truncated}")
|
||||
};
|
||||
|
||||
self.tool_results.insert(
|
||||
@@ -363,8 +369,9 @@ impl ToolUseState {
|
||||
LanguageModelToolResult {
|
||||
tool_use_id: tool_use_id.clone(),
|
||||
tool_name,
|
||||
content: tool_result.into(),
|
||||
content: Arc::from(final_tool_result),
|
||||
is_error: false,
|
||||
tool_output: Some(Arc::new(tool_result)),
|
||||
},
|
||||
);
|
||||
self.pending_tool_uses_by_id.remove(&tool_use_id)
|
||||
@@ -377,6 +384,7 @@ impl ToolUseState {
|
||||
tool_name,
|
||||
content: err.to_string().into(),
|
||||
is_error: true,
|
||||
tool_output: None,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -451,6 +459,7 @@ impl ToolUseState {
|
||||
} else {
|
||||
tool_result.content.clone()
|
||||
},
|
||||
tool_output: tool_result.tool_output.clone(),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "assistant_eval"
|
||||
name = "agent_eval"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
@@ -9,7 +9,7 @@ license = "GPL-3.0-or-later"
|
||||
workspace = true
|
||||
|
||||
[[bin]]
|
||||
name = "assistant_eval"
|
||||
name = "agent_eval"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::git_commands::{run_git, setup_temp_repo};
|
||||
use crate::headless_assistant::{HeadlessAppState, HeadlessAssistant};
|
||||
use crate::{get_exercise_language, get_exercise_name, templates_eval::Template};
|
||||
use crate::{get_exercise_language, get_exercise_name};
|
||||
use agent::RequestKind;
|
||||
use anyhow::{Result, anyhow};
|
||||
use collections::HashMap;
|
||||
@@ -18,8 +18,6 @@ use std::{
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct EvalResult {
|
||||
pub exercise_name: String,
|
||||
pub template_name: String,
|
||||
pub score: String,
|
||||
pub diff: String,
|
||||
pub assistant_response: String,
|
||||
pub elapsed_time_ms: u128,
|
||||
@@ -29,7 +27,6 @@ pub struct EvalResult {
|
||||
pub output_tokens: usize,
|
||||
pub total_tokens: usize,
|
||||
pub tool_use_counts: usize,
|
||||
pub judge_model_name: String, // Added field for judge model name
|
||||
}
|
||||
|
||||
pub struct EvalOutput {
|
||||
@@ -251,29 +248,6 @@ pub async fn read_instructions(exercise_path: &Path) -> Result<String> {
|
||||
Ok(instructions)
|
||||
}
|
||||
|
||||
pub async fn read_example_solution(exercise_path: &Path, language: &str) -> Result<String> {
|
||||
// Map the language to the file extension
|
||||
let language_extension = match language {
|
||||
"python" => "py",
|
||||
"go" => "go",
|
||||
"rust" => "rs",
|
||||
"typescript" => "ts",
|
||||
"javascript" => "js",
|
||||
"ruby" => "rb",
|
||||
"php" => "php",
|
||||
"bash" => "sh",
|
||||
"multi" => "diff",
|
||||
"internal" => "diff",
|
||||
_ => return Err(anyhow!("Unsupported language: {}", language)),
|
||||
};
|
||||
let example_path = exercise_path
|
||||
.join(".meta")
|
||||
.join(format!("example.{}", language_extension));
|
||||
println!("Reading example solution from: {}", example_path.display());
|
||||
let example = smol::unblock(move || std::fs::read_to_string(&example_path)).await?;
|
||||
Ok(example)
|
||||
}
|
||||
|
||||
pub async fn save_eval_results(exercise_path: &Path, results: Vec<EvalResult>) -> Result<()> {
|
||||
let eval_dir = exercise_path.join("evaluation");
|
||||
fs::create_dir_all(&eval_dir)?;
|
||||
@@ -311,12 +285,8 @@ pub async fn save_eval_results(exercise_path: &Path, results: Vec<EvalResult>) -
|
||||
// Group the new results by test name (exercise name)
|
||||
for result in results {
|
||||
let exercise_name = &result.exercise_name;
|
||||
let template_name = &result.template_name;
|
||||
|
||||
println!(
|
||||
"Adding result: exercise={}, template={}",
|
||||
exercise_name, template_name
|
||||
);
|
||||
println!("Adding result: exercise={}", exercise_name);
|
||||
|
||||
// Ensure the exercise entry exists
|
||||
if eval_data.get(exercise_name).is_none() {
|
||||
@@ -329,7 +299,7 @@ pub async fn save_eval_results(exercise_path: &Path, results: Vec<EvalResult>) -
|
||||
}
|
||||
|
||||
// Add this result under the timestamp with template name as key
|
||||
eval_data[exercise_name][×tamp][template_name] = serde_json::to_value(&result)?;
|
||||
eval_data[exercise_name][×tamp] = serde_json::to_value(&result)?;
|
||||
}
|
||||
|
||||
// Write back to file with pretty formatting
|
||||
@@ -344,9 +314,7 @@ pub async fn save_eval_results(exercise_path: &Path, results: Vec<EvalResult>) -
|
||||
|
||||
pub async fn run_exercise_eval(
|
||||
exercise_path: PathBuf,
|
||||
template: Template,
|
||||
model: Arc<dyn LanguageModel>,
|
||||
judge_model: Arc<dyn LanguageModel>,
|
||||
app_state: Arc<HeadlessAppState>,
|
||||
base_sha: String,
|
||||
_framework_path: PathBuf,
|
||||
@@ -359,68 +327,15 @@ pub async fn run_exercise_eval(
|
||||
"\n\nWhen writing the code for this prompt, use {} to achieve the goal.",
|
||||
language
|
||||
));
|
||||
let example_solution = read_example_solution(&exercise_path, &language).await?;
|
||||
|
||||
println!(
|
||||
"Running evaluation for exercise: {} with template: {}",
|
||||
exercise_name, template.name
|
||||
);
|
||||
println!("Running evaluation for exercise: {}", exercise_name);
|
||||
|
||||
// Create temporary directory with exercise files
|
||||
let temp_dir = setup_temp_repo(&exercise_path, &base_sha).await?;
|
||||
let temp_path = temp_dir.path().to_path_buf();
|
||||
|
||||
if template.name == "ProjectCreation" {
|
||||
for entry in fs::read_dir(&temp_path)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
|
||||
// Skip directories that start with dot (like .docs, .meta, .git)
|
||||
if path.is_dir()
|
||||
&& path
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.map(|name| name.starts_with("."))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Delete regular files
|
||||
if path.is_file() {
|
||||
println!(" Deleting file: {}", path.display());
|
||||
fs::remove_file(path)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit the deletion so it shows up in the diff
|
||||
run_git(&temp_path, &["add", "."]).await?;
|
||||
run_git(
|
||||
&temp_path,
|
||||
&["commit", "-m", "Remove root files for clean slate"],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let local_commit_sha = run_git(&temp_path, &["rev-parse", "HEAD"]).await?;
|
||||
|
||||
// Prepare prompt based on template
|
||||
let prompt = match template.name {
|
||||
"ProjectCreation" => format!(
|
||||
"I need to create a new implementation for this exercise. Please create all the necessary files in the best location.\n\n{}",
|
||||
instructions
|
||||
),
|
||||
"CodeModification" => format!(
|
||||
"I need help updating my code to meet these requirements. Please modify the appropriate files:\n\n{}",
|
||||
instructions
|
||||
),
|
||||
"ConversationalGuidance" => format!(
|
||||
"I'm trying to solve this coding exercise but I'm not sure where to start. Can you help me understand the requirements and guide me through the solution process without writing code for me?\n\n{}",
|
||||
instructions
|
||||
),
|
||||
_ => instructions.clone(),
|
||||
};
|
||||
|
||||
let start_time = SystemTime::now();
|
||||
|
||||
// Create a basic eval struct to work with the existing system
|
||||
@@ -430,7 +345,7 @@ pub async fn run_exercise_eval(
|
||||
url: format!("file://{}", temp_path.display()),
|
||||
base_sha: local_commit_sha, // Use the local commit SHA instead of the framework base SHA
|
||||
},
|
||||
user_prompt: prompt,
|
||||
user_prompt: instructions.clone(),
|
||||
};
|
||||
|
||||
// Run the evaluation
|
||||
@@ -441,79 +356,6 @@ pub async fn run_exercise_eval(
|
||||
// Get diff from git
|
||||
let diff = eval_output.diff.clone();
|
||||
|
||||
// For project creation template, we need to compare with reference implementation
|
||||
let judge_output = if template.name == "ProjectCreation" {
|
||||
let project_judge_prompt = template
|
||||
.content
|
||||
.replace(
|
||||
"<!-- ```requirements go here``` -->",
|
||||
&format!("```\n{}\n```", instructions),
|
||||
)
|
||||
.replace(
|
||||
"<!-- ```reference code goes here``` -->",
|
||||
&format!("```{}\n{}\n```", language, example_solution),
|
||||
)
|
||||
.replace(
|
||||
"<!-- ```git diff goes here``` -->",
|
||||
&format!("```\n{}\n```", diff),
|
||||
);
|
||||
|
||||
// Use the run_with_prompt method which we'll add to judge.rs
|
||||
let judge = crate::judge::Judge {
|
||||
original_diff: None,
|
||||
original_message: Some(project_judge_prompt),
|
||||
model: judge_model.clone(),
|
||||
};
|
||||
|
||||
cx.update(|cx| judge.run_with_prompt(cx))?.await?
|
||||
} else if template.name == "CodeModification" {
|
||||
// For CodeModification, we'll compare the example solution with the LLM-generated solution
|
||||
let code_judge_prompt = template
|
||||
.content
|
||||
.replace(
|
||||
"<!-- ```reference code goes here``` -->",
|
||||
&format!("```{}\n{}\n```", language, example_solution),
|
||||
)
|
||||
.replace(
|
||||
"<!-- ```git diff goes here``` -->",
|
||||
&format!("```\n{}\n```", diff),
|
||||
);
|
||||
|
||||
// Use the run_with_prompt method
|
||||
let judge = crate::judge::Judge {
|
||||
original_diff: None,
|
||||
original_message: Some(code_judge_prompt),
|
||||
model: judge_model.clone(),
|
||||
};
|
||||
|
||||
cx.update(|cx| judge.run_with_prompt(cx))?.await?
|
||||
} else {
|
||||
// Conversational template
|
||||
let conv_judge_prompt = template
|
||||
.content
|
||||
.replace(
|
||||
"<!-- ```query goes here``` -->",
|
||||
&format!("```\n{}\n```", instructions),
|
||||
)
|
||||
.replace(
|
||||
"<!-- ```transcript goes here``` -->",
|
||||
&format!("```\n{}\n```", eval_output.last_message),
|
||||
)
|
||||
.replace(
|
||||
"<!-- ```git diff goes here``` -->",
|
||||
&format!("```\n{}\n```", diff),
|
||||
);
|
||||
|
||||
// Use the run_with_prompt method for consistency
|
||||
let judge = crate::judge::Judge {
|
||||
original_diff: None,
|
||||
original_message: Some(conv_judge_prompt),
|
||||
model: judge_model.clone(),
|
||||
};
|
||||
|
||||
cx.update(|cx| judge.run_with_prompt(cx))?.await?
|
||||
};
|
||||
|
||||
let elapsed_time = start_time.elapsed()?;
|
||||
|
||||
// Calculate total tokens as the sum of input and output tokens
|
||||
@@ -522,14 +364,9 @@ pub async fn run_exercise_eval(
|
||||
let tool_use_counts = eval_output.tool_use_counts.values().sum::<u32>();
|
||||
let total_tokens = input_tokens + output_tokens;
|
||||
|
||||
// Get judge model name
|
||||
let judge_model_name = judge_model.id().0.to_string();
|
||||
|
||||
// Save results to evaluation directory
|
||||
let result = EvalResult {
|
||||
exercise_name: exercise_name.clone(),
|
||||
template_name: template.name.to_string(),
|
||||
score: judge_output.trim().to_string(),
|
||||
diff,
|
||||
assistant_response: eval_output.last_message.clone(),
|
||||
elapsed_time_ms: elapsed_time.as_millis(),
|
||||
@@ -541,7 +378,6 @@ pub async fn run_exercise_eval(
|
||||
output_tokens: output_tokens.try_into().unwrap(),
|
||||
total_tokens: total_tokens.try_into().unwrap(),
|
||||
tool_use_counts: tool_use_counts.try_into().unwrap(),
|
||||
judge_model_name, // Add judge model name to result
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
@@ -4,12 +4,10 @@ use assistant_tool::ToolWorkingSet;
|
||||
use client::{Client, UserStore};
|
||||
use collections::HashMap;
|
||||
use dap::DapRegistry;
|
||||
use futures::StreamExt;
|
||||
use gpui::{App, AsyncApp, Entity, SemanticVersion, Subscription, Task, prelude::*};
|
||||
use gpui::{App, Entity, SemanticVersion, Subscription, Task, prelude::*};
|
||||
use language::LanguageRegistry;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModel, LanguageModelProviderId, LanguageModelRegistry,
|
||||
LanguageModelRequest,
|
||||
};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::{Project, RealFs};
|
||||
@@ -246,34 +244,3 @@ pub fn authenticate_model_provider(
|
||||
let model_provider = model_registry.provider(&provider_id).unwrap();
|
||||
model_provider.authenticate(cx)
|
||||
}
|
||||
|
||||
pub async fn send_language_model_request(
|
||||
model: Arc<dyn LanguageModel>,
|
||||
request: LanguageModelRequest,
|
||||
cx: &mut AsyncApp,
|
||||
) -> anyhow::Result<String> {
|
||||
match model.stream_completion_text(request, &cx).await {
|
||||
Ok(mut stream) => {
|
||||
let mut full_response = String::new();
|
||||
|
||||
// Process the response stream
|
||||
while let Some(chunk_result) = stream.stream.next().await {
|
||||
match chunk_result {
|
||||
Ok(chunk_str) => {
|
||||
full_response.push_str(&chunk_str);
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(anyhow!(
|
||||
"Error receiving response from language model: {err}"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(full_response)
|
||||
}
|
||||
Err(err) => Err(anyhow!(
|
||||
"Failed to get response from language model. Error was: {err}"
|
||||
)),
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ mod eval;
|
||||
mod get_exercise;
|
||||
mod git_commands;
|
||||
mod headless_assistant;
|
||||
mod judge;
|
||||
mod templates_eval;
|
||||
|
||||
use clap::Parser;
|
||||
use eval::{run_exercise_eval, save_eval_results};
|
||||
@@ -15,11 +13,10 @@ use headless_assistant::{authenticate_model_provider, find_model};
|
||||
use language_model::LanguageModelRegistry;
|
||||
use reqwest_client::ReqwestClient;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use templates_eval::all_templates;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
name = "assistant_eval",
|
||||
name = "agent_eval",
|
||||
disable_version_flag = true,
|
||||
before_help = "Tool eval runner"
|
||||
)]
|
||||
@@ -37,24 +34,17 @@ struct Args {
|
||||
/// Name of the model (default: "claude-3-7-sonnet-latest")
|
||||
#[arg(long, default_value = "claude-3-7-sonnet-latest")]
|
||||
model_name: String,
|
||||
/// Name of the judge model (default: value of `--model_name`).
|
||||
/// Name of the editor model (default: value of `--model_name`).
|
||||
#[arg(long)]
|
||||
judge_model_name: Option<String>,
|
||||
editor_model_name: Option<String>,
|
||||
/// Number of evaluations to run concurrently (default: 3)
|
||||
#[arg(short, long, default_value = "3")]
|
||||
#[arg(short, long, default_value = "5")]
|
||||
concurrency: usize,
|
||||
/// Maximum number of exercises to evaluate per language
|
||||
#[arg(long)]
|
||||
max_exercises_per_language: Option<usize>,
|
||||
}
|
||||
|
||||
// First, let's define the order in which templates should be executed
|
||||
const TEMPLATE_EXECUTION_ORDER: [&str; 3] = [
|
||||
"ProjectCreation",
|
||||
"CodeModification",
|
||||
"ConversationalGuidance",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let args = Args::parse();
|
||||
@@ -76,7 +66,7 @@ fn main() {
|
||||
let app_state = headless_assistant::init(cx);
|
||||
|
||||
let model = find_model(&args.model_name, cx).unwrap();
|
||||
let judge_model = if let Some(model_name) = &args.judge_model_name {
|
||||
let editor_model = if let Some(model_name) = &args.editor_model_name {
|
||||
find_model(model_name, cx).unwrap()
|
||||
} else {
|
||||
model.clone()
|
||||
@@ -87,7 +77,7 @@ fn main() {
|
||||
});
|
||||
|
||||
let model_provider_id = model.provider_id();
|
||||
let judge_model_provider_id = judge_model.provider_id();
|
||||
let editor_model_provider_id = editor_model.provider_id();
|
||||
|
||||
let framework_path_clone = framework_path.clone();
|
||||
let languages_clone = languages.clone();
|
||||
@@ -100,15 +90,17 @@ fn main() {
|
||||
.unwrap()
|
||||
.await
|
||||
.unwrap();
|
||||
cx.update(|cx| authenticate_model_provider(judge_model_provider_id.clone(), cx))
|
||||
cx.update(|cx| authenticate_model_provider(editor_model_provider_id.clone(), cx))
|
||||
.unwrap()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read base SHA from setup.json
|
||||
println!("framework path: {}", framework_path_clone.display());
|
||||
|
||||
let base_sha = read_base_sha(&framework_path_clone).await.unwrap();
|
||||
|
||||
// Find all exercises for the specified languages
|
||||
println!("base sha: {}", base_sha);
|
||||
|
||||
let all_exercises = find_exercises(
|
||||
&framework_path_clone,
|
||||
&languages_clone
|
||||
@@ -140,23 +132,12 @@ fn main() {
|
||||
|
||||
println!("Will run {} exercises", exercises_to_run.len());
|
||||
|
||||
// Get all templates and sort them according to the execution order
|
||||
let mut templates = all_templates();
|
||||
templates.sort_by_key(|template| {
|
||||
TEMPLATE_EXECUTION_ORDER
|
||||
.iter()
|
||||
.position(|&name| name == template.name)
|
||||
.unwrap_or(usize::MAX)
|
||||
});
|
||||
|
||||
// Create exercise eval tasks - each exercise is a single task that will run templates sequentially
|
||||
let exercise_tasks: Vec<_> = exercises_to_run
|
||||
.into_iter()
|
||||
.map(|exercise_path| {
|
||||
let exercise_name = get_exercise_name(&exercise_path);
|
||||
let templates_clone = templates.clone();
|
||||
let model_clone = model.clone();
|
||||
let judge_model_clone = judge_model.clone();
|
||||
let app_state_clone = app_state.clone();
|
||||
let base_sha_clone = base_sha.clone();
|
||||
let framework_path_clone = framework_path_clone.clone();
|
||||
@@ -166,56 +147,22 @@ fn main() {
|
||||
println!("Processing exercise: {}", exercise_name);
|
||||
let mut exercise_results = Vec::new();
|
||||
|
||||
// Determine the language for this exercise
|
||||
let language = match get_exercise_language(&exercise_path) {
|
||||
Ok(lang) => lang,
|
||||
match run_exercise_eval(
|
||||
exercise_path.clone(),
|
||||
model_clone.clone(),
|
||||
app_state_clone.clone(),
|
||||
base_sha_clone.clone(),
|
||||
framework_path_clone.clone(),
|
||||
cx_clone.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
println!("Completed {}", exercise_name);
|
||||
exercise_results.push(result);
|
||||
}
|
||||
Err(err) => {
|
||||
println!(
|
||||
"Error determining language for {}: {}",
|
||||
exercise_name, err
|
||||
);
|
||||
return exercise_results;
|
||||
}
|
||||
};
|
||||
|
||||
// Run each template sequentially for this exercise
|
||||
for template in templates_clone {
|
||||
// For "multi" or "internal" language, only run the CodeModification template
|
||||
if (language == "multi" || language == "internal")
|
||||
&& template.name != "CodeModification"
|
||||
{
|
||||
println!(
|
||||
"Skipping {} template for {} language",
|
||||
template.name, language
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
match run_exercise_eval(
|
||||
exercise_path.clone(),
|
||||
template.clone(),
|
||||
model_clone.clone(),
|
||||
judge_model_clone.clone(),
|
||||
app_state_clone.clone(),
|
||||
base_sha_clone.clone(),
|
||||
framework_path_clone.clone(),
|
||||
cx_clone.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
println!(
|
||||
"Completed {} with template {} - score: {}",
|
||||
exercise_name, template.name, result.score
|
||||
);
|
||||
exercise_results.push(result);
|
||||
}
|
||||
Err(err) => {
|
||||
println!(
|
||||
"Error running {} with template {}: {}",
|
||||
exercise_name, template.name, err
|
||||
);
|
||||
}
|
||||
println!("Error running {}: {}", exercise_name, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,38 +321,54 @@ pub async fn stream_completion(
|
||||
.map(|output| output.0)
|
||||
}
|
||||
|
||||
/// An individual rate limit.
|
||||
#[derive(Debug)]
|
||||
pub struct RateLimit {
|
||||
pub limit: usize,
|
||||
pub remaining: usize,
|
||||
pub reset: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl RateLimit {
|
||||
fn from_headers(resource: &str, headers: &HeaderMap<HeaderValue>) -> Result<Self> {
|
||||
let limit =
|
||||
get_header(&format!("anthropic-ratelimit-{resource}-limit"), headers)?.parse()?;
|
||||
let remaining = get_header(
|
||||
&format!("anthropic-ratelimit-{resource}-remaining"),
|
||||
headers,
|
||||
)?
|
||||
.parse()?;
|
||||
let reset = DateTime::parse_from_rfc3339(get_header(
|
||||
&format!("anthropic-ratelimit-{resource}-reset"),
|
||||
headers,
|
||||
)?)?
|
||||
.to_utc();
|
||||
|
||||
Ok(Self {
|
||||
limit,
|
||||
remaining,
|
||||
reset,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://docs.anthropic.com/en/api/rate-limits#response-headers>
|
||||
#[derive(Debug)]
|
||||
pub struct RateLimitInfo {
|
||||
pub requests_limit: usize,
|
||||
pub requests_remaining: usize,
|
||||
pub requests_reset: DateTime<Utc>,
|
||||
pub tokens_limit: usize,
|
||||
pub tokens_remaining: usize,
|
||||
pub tokens_reset: DateTime<Utc>,
|
||||
pub requests: Option<RateLimit>,
|
||||
pub tokens: Option<RateLimit>,
|
||||
pub input_tokens: Option<RateLimit>,
|
||||
pub output_tokens: Option<RateLimit>,
|
||||
}
|
||||
|
||||
impl RateLimitInfo {
|
||||
fn from_headers(headers: &HeaderMap<HeaderValue>) -> Result<Self> {
|
||||
let tokens_limit = get_header("anthropic-ratelimit-tokens-limit", headers)?.parse()?;
|
||||
let requests_limit = get_header("anthropic-ratelimit-requests-limit", headers)?.parse()?;
|
||||
let tokens_remaining =
|
||||
get_header("anthropic-ratelimit-tokens-remaining", headers)?.parse()?;
|
||||
let requests_remaining =
|
||||
get_header("anthropic-ratelimit-requests-remaining", headers)?.parse()?;
|
||||
let requests_reset = get_header("anthropic-ratelimit-requests-reset", headers)?;
|
||||
let tokens_reset = get_header("anthropic-ratelimit-tokens-reset", headers)?;
|
||||
let requests_reset = DateTime::parse_from_rfc3339(requests_reset)?.to_utc();
|
||||
let tokens_reset = DateTime::parse_from_rfc3339(tokens_reset)?.to_utc();
|
||||
|
||||
Ok(Self {
|
||||
requests_limit,
|
||||
tokens_limit,
|
||||
requests_remaining,
|
||||
tokens_remaining,
|
||||
requests_reset,
|
||||
tokens_reset,
|
||||
})
|
||||
fn from_headers(headers: &HeaderMap<HeaderValue>) -> Self {
|
||||
Self {
|
||||
requests: RateLimit::from_headers("requests", headers).log_err(),
|
||||
tokens: RateLimit::from_headers("tokens", headers).log_err(),
|
||||
input_tokens: RateLimit::from_headers("input-tokens", headers).log_err(),
|
||||
output_tokens: RateLimit::from_headers("output-tokens", headers).log_err(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,7 +434,7 @@ pub async fn stream_completion_with_rate_limit_info(
|
||||
}
|
||||
})
|
||||
.boxed();
|
||||
Ok((stream, rate_limits.log_err()))
|
||||
Ok((stream, Some(rate_limits)))
|
||||
} else {
|
||||
let mut body = Vec::new();
|
||||
response
|
||||
|
||||
@@ -57,7 +57,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use streaming_diff::{CharOperation, LineDiff, LineOperation, StreamingDiff};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use terminal_view::terminal_panel::TerminalPanel;
|
||||
use text::{OffsetRangeExt, ToPoint as _};
|
||||
use theme::ThemeSettings;
|
||||
@@ -315,7 +315,7 @@ impl InlineAssistant {
|
||||
if let Some(ConfiguredModel { model, .. }) =
|
||||
LanguageModelRegistry::read_global(cx).default_model()
|
||||
{
|
||||
self.telemetry.report_assistant_event(AssistantEvent {
|
||||
self.telemetry.report_assistant_event(AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::Inline,
|
||||
phase: AssistantPhase::Invoked,
|
||||
@@ -892,7 +892,7 @@ impl InlineAssistant {
|
||||
.map(|language| language.name())
|
||||
});
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::Inline,
|
||||
message_id,
|
||||
@@ -3148,7 +3148,7 @@ impl CodegenAlternative {
|
||||
|
||||
let error_message = result.as_ref().err().map(|error| error.to_string());
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
message_id,
|
||||
kind: AssistantKind::Inline,
|
||||
|
||||
@@ -27,7 +27,7 @@ use std::{
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use terminal::Terminal;
|
||||
use terminal_view::TerminalView;
|
||||
use theme::ThemeSettings;
|
||||
@@ -324,7 +324,7 @@ impl TerminalInlineAssistant {
|
||||
let codegen = assist.codegen.read(cx);
|
||||
let executor = cx.background_executor().clone();
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::InlineTerminal,
|
||||
message_id: codegen.message_id.clone(),
|
||||
@@ -1183,7 +1183,7 @@ impl Codegen {
|
||||
|
||||
let error_message = result.as_ref().err().map(|error| error.to_string());
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: None,
|
||||
kind: AssistantKind::InlineTerminal,
|
||||
message_id,
|
||||
|
||||
@@ -40,7 +40,7 @@ use std::{
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};
|
||||
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
|
||||
use text::{BufferSnapshot, ToPoint};
|
||||
use ui::IconName;
|
||||
use util::{ResultExt, TryFutureExt, post_inc};
|
||||
@@ -2498,7 +2498,7 @@ impl AssistantContext {
|
||||
.language()
|
||||
.map(|language| language.name());
|
||||
report_assistant_event(
|
||||
AssistantEvent {
|
||||
AssistantEventData {
|
||||
conversation_id: Some(this.id.0.clone()),
|
||||
kind: AssistantKind::Panel,
|
||||
phase: AssistantPhase::Response,
|
||||
|
||||
@@ -127,6 +127,7 @@ impl SlashCommandCompletionProvider {
|
||||
new_text,
|
||||
label: command.label(cx),
|
||||
icon_path: None,
|
||||
insert_text_mode: None,
|
||||
confirm,
|
||||
source: CompletionSource::Custom,
|
||||
})
|
||||
@@ -228,6 +229,7 @@ impl SlashCommandCompletionProvider {
|
||||
new_text,
|
||||
documentation: None,
|
||||
confirm,
|
||||
insert_text_mode: None,
|
||||
source: CompletionSource::Custom,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# Tool Evals
|
||||
|
||||
A framework for evaluating and benchmarking the agent panel generations.
|
||||
|
||||
## Overview
|
||||
|
||||
Tool Evals provides a headless environment for running assistants evaluations on code repositories. It automates the process of:
|
||||
|
||||
1. Setting up test code and repositories
|
||||
2. Sending prompts to language models
|
||||
3. Allowing the assistant to use tools to modify code
|
||||
4. Collecting metrics on performance and tool usage
|
||||
5. Evaluating results against known good solutions
|
||||
|
||||
## How It Works
|
||||
|
||||
The system consists of several key components:
|
||||
|
||||
- **Eval**: Loads exercises from the zed-ace-framework repository, creates temporary repos, and executes evaluations
|
||||
- **HeadlessAssistant**: Provides a headless environment for running the AI assistant
|
||||
- **Judge**: Evaluates AI-generated solutions against reference implementations and assigns scores
|
||||
- **Templates**: Defines evaluation frameworks for different tasks (Project Creation, Code Modification, Conversational Guidance)
|
||||
|
||||
## Setup Requirements
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Rust and Cargo
|
||||
- Git
|
||||
- Python (for report generation)
|
||||
- Network access to clone repositories
|
||||
- Appropriate API keys for language models and git services (Anthropic, GitHub, etc.)
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Ensure you have the required API keys set, either from a dev run of Zed or via these environment variables:
|
||||
- `ZED_ANTHROPIC_API_KEY` for Claude models
|
||||
- `ZED_GITHUB_API_KEY` for GitHub API (or similar)
|
||||
|
||||
## Usage
|
||||
|
||||
### Running Evaluations
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
cargo run -p assistant_eval -- --all
|
||||
|
||||
# Run only specific languages
|
||||
cargo run -p assistant_eval -- --all --languages python,rust
|
||||
|
||||
# Limit concurrent evaluations
|
||||
cargo run -p assistant_eval -- --all --concurrency 5
|
||||
|
||||
# Limit number of exercises per language
|
||||
cargo run -p assistant_eval -- --all --max-exercises-per-language 3
|
||||
```
|
||||
|
||||
### Evaluation Template Types
|
||||
|
||||
The system supports three types of evaluation templates:
|
||||
|
||||
1. **ProjectCreation**: Tests the model's ability to create new implementations from scratch
|
||||
2. **CodeModification**: Tests the model's ability to modify existing code to meet new requirements
|
||||
3. **ConversationalGuidance**: Tests the model's ability to provide guidance without writing code
|
||||
|
||||
### Support Repo
|
||||
|
||||
The [zed-industries/zed-ace-framework](https://github.com/zed-industries/zed-ace-framework) contains the analytics and reporting scripts.
|
||||
@@ -1,37 +0,0 @@
|
||||
use crate::headless_assistant::send_language_model_request;
|
||||
use anyhow::anyhow;
|
||||
use gpui::{App, Task};
|
||||
use language_model::{
|
||||
LanguageModel, LanguageModelRequest, LanguageModelRequestMessage, MessageContent, Role,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct Judge {
|
||||
#[allow(dead_code)]
|
||||
pub original_diff: Option<String>,
|
||||
pub original_message: Option<String>,
|
||||
pub model: Arc<dyn LanguageModel>,
|
||||
}
|
||||
|
||||
impl Judge {
|
||||
pub fn run_with_prompt(&self, cx: &mut App) -> Task<anyhow::Result<String>> {
|
||||
let Some(prompt) = self.original_message.as_ref() else {
|
||||
return Task::ready(Err(anyhow!("No prompt provided in original_message")));
|
||||
};
|
||||
|
||||
let request = LanguageModelRequest {
|
||||
messages: vec![LanguageModelRequestMessage {
|
||||
role: Role::User,
|
||||
content: vec![MessageContent::Text(prompt.clone())],
|
||||
cache: false,
|
||||
}],
|
||||
temperature: Some(0.0),
|
||||
tools: Vec::new(),
|
||||
stop: Vec::new(),
|
||||
};
|
||||
|
||||
let model = self.model.clone();
|
||||
let request = request.clone();
|
||||
cx.spawn(async move |cx| send_language_model_request(model, request, cx).await)
|
||||
}
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Template {
|
||||
pub name: &'static str,
|
||||
pub content: &'static str,
|
||||
}
|
||||
|
||||
pub fn all_templates() -> Vec<Template> {
|
||||
vec![
|
||||
Template {
|
||||
name: "ProjectCreation",
|
||||
content: r#"
|
||||
# Project Creation Evaluation Template
|
||||
|
||||
## Instructions
|
||||
|
||||
Evaluate how well the AI assistant created a new implementation from scratch. Score it between 0.0 and 1.0 based on quality and fulfillment of requirements.
|
||||
- 1.0 = Perfect implementation that creates all necessary files with correct functionality.
|
||||
- 0.0 = Completely fails to create working files or meet requirements.
|
||||
|
||||
Note: A git diff output is required. If no code changes are provided (i.e., no git diff output), the score must be 0.0.
|
||||
|
||||
## Evaluation Criteria
|
||||
|
||||
Please consider the following aspects in order of importance:
|
||||
|
||||
1. **File Creation (25%)**
|
||||
- Did the assistant create all necessary files?
|
||||
- Are the files appropriately named and organized?
|
||||
- Did the assistant create a complete solution without missing components?
|
||||
|
||||
2. **Functional Correctness (40%)**
|
||||
- Does the implementation fulfill all specified requirements?
|
||||
- Does it handle edge cases properly?
|
||||
- Is it free of logical errors and bugs?
|
||||
- Do all components work together as expected?
|
||||
|
||||
3. **Code Quality (20%)**
|
||||
- Is the code well-structured, readable and well-documented?
|
||||
- Does it follow language-specific best practices?
|
||||
- Is there proper error handling?
|
||||
- Are naming conventions clear and consistent?
|
||||
|
||||
4. **Architecture Design (15%)**
|
||||
- Is the code modular and extensible?
|
||||
- Is there proper separation of concerns?
|
||||
- Are appropriate design patterns used?
|
||||
- Is the overall architecture appropriate for the requirements?
|
||||
|
||||
## Input
|
||||
|
||||
Requirements:
|
||||
<!-- ```requirements go here``` -->
|
||||
|
||||
Reference Implementation:
|
||||
<!-- ```reference code goes here``` -->
|
||||
|
||||
AI-Generated Implementation (git diff output):
|
||||
<!-- ```git diff goes here``` -->
|
||||
|
||||
## Output Format
|
||||
|
||||
THE ONLY OUTPUT SHOULD BE A SCORE BETWEEN 0.0 AND 1.0.
|
||||
|
||||
EXAMPLE ONE:
|
||||
|
||||
0.92
|
||||
|
||||
EXAMPLE TWO:
|
||||
|
||||
0.85
|
||||
|
||||
EXAMPLE THREE:
|
||||
|
||||
0.78
|
||||
"#,
|
||||
},
|
||||
Template {
|
||||
name: "CodeModification",
|
||||
content: r#"
|
||||
# Code Modification Evaluation Template
|
||||
|
||||
## Instructions
|
||||
|
||||
Evaluate how well the AI assistant modified existing code to meet requirements. Score between 0.0 and 1.0 based on quality and appropriateness of changes.
|
||||
- 1.0 = Perfect modifications that correctly implement all requirements.
|
||||
- 0.0 = Failed to make appropriate changes or introduced serious errors.
|
||||
|
||||
## Evaluation Criteria
|
||||
|
||||
Please consider the following aspects in order of importance:
|
||||
|
||||
1. **Functional Correctness (50%)**
|
||||
- Do the modifications correctly implement the requirements?
|
||||
- Did the assistant modify the right files and code sections?
|
||||
- Are the changes free of bugs and logical errors?
|
||||
- Do the modifications maintain compatibility with existing code?
|
||||
|
||||
2. **Modification Approach (25%)**
|
||||
- Are the changes minimal and focused on what needs to be changed?
|
||||
- Did the assistant avoid unnecessary modifications?
|
||||
- Are the changes integrated seamlessly with the existing codebase?
|
||||
- Did the assistant preserve the original code style and patterns?
|
||||
|
||||
3. **Code Quality (15%)**
|
||||
- Are the modifications well-structured and documented?
|
||||
- Do they follow the same conventions as the original code?
|
||||
- Is there proper error handling in the modified code?
|
||||
- Are the changes readable and maintainable?
|
||||
|
||||
4. **Solution Completeness (10%)**
|
||||
- Do the modifications completely address all requirements?
|
||||
- Are there any missing changes or overlooked requirements?
|
||||
- Did the assistant consider all necessary edge cases?
|
||||
|
||||
## Input
|
||||
|
||||
Original:
|
||||
<!-- ```reference code goes here``` -->
|
||||
|
||||
New (git diff output):
|
||||
<!-- ```git diff goes here``` -->
|
||||
|
||||
## Output Format
|
||||
|
||||
THE ONLY OUTPUT SHOULD BE A SCORE BETWEEN 0.0 AND 1.0.
|
||||
|
||||
EXAMPLE ONE:
|
||||
|
||||
0.92
|
||||
|
||||
EXAMPLE TWO:
|
||||
|
||||
0.85
|
||||
|
||||
EXAMPLE THREE:
|
||||
|
||||
0.78
|
||||
"#,
|
||||
},
|
||||
Template {
|
||||
name: "ConversationalGuidance",
|
||||
content: r#"
|
||||
# Conversational Guidance Evaluation Template
|
||||
|
||||
## Instructions
|
||||
|
||||
Evaluate the quality of the AI assistant's conversational guidance and score it between 0.0 and 1.0.
|
||||
- 1.0 = Perfect guidance with ideal information gathering, clarification, and advice without writing code.
|
||||
- 0.0 = Completely unhelpful, inappropriate guidance, or wrote code when it should not have.
|
||||
|
||||
## Evaluation Criteria
|
||||
|
||||
ABSOLUTE REQUIREMENT:
|
||||
- The assistant should NOT generate complete code solutions in conversation mode.
|
||||
- If the git diff shows the assistant wrote complete code, the score should be significantly reduced.
|
||||
|
||||
1. **Information Gathering Effectiveness (30%)**
|
||||
- Did the assistant ask relevant and precise questions?
|
||||
- Did it efficiently narrow down the problem scope?
|
||||
- Did it avoid unnecessary or redundant questions?
|
||||
- Was questioning appropriately paced and contextual?
|
||||
|
||||
2. **Conceptual Guidance (30%)**
|
||||
- Did the assistant provide high-level approaches and strategies?
|
||||
- Did it explain relevant concepts and algorithms?
|
||||
- Did it offer planning advice without implementing the solution?
|
||||
- Did it suggest a structured approach to solving the problem?
|
||||
|
||||
3. **Educational Value (20%)**
|
||||
- Did the assistant help the user understand the problem better?
|
||||
- Did it provide explanations that would help the user learn?
|
||||
- Did it guide without simply giving away answers?
|
||||
- Did it encourage the user to think through parts of the problem?
|
||||
|
||||
4. **Conversation Quality (20%)**
|
||||
- Was the conversation logically structured and easy to follow?
|
||||
- Did the assistant maintain appropriate context throughout?
|
||||
- Was the interaction helpful without being condescending?
|
||||
- Did the conversation reach a satisfactory conclusion with clear next steps?
|
||||
|
||||
## Input
|
||||
|
||||
Initial Query:
|
||||
<!-- ```query goes here``` -->
|
||||
|
||||
Conversation Transcript:
|
||||
<!-- ```transcript goes here``` -->
|
||||
|
||||
Git Diff:
|
||||
<!-- ```git diff goes here``` -->
|
||||
|
||||
## Output Format
|
||||
|
||||
THE ONLY OUTPUT SHOULD BE A SCORE BETWEEN 0.0 AND 1.0.
|
||||
|
||||
EXAMPLE ONE:
|
||||
|
||||
0.92
|
||||
|
||||
EXAMPLE TWO:
|
||||
|
||||
0.85
|
||||
|
||||
EXAMPLE THREE:
|
||||
|
||||
0.78
|
||||
"#,
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -8,13 +8,15 @@ use std::fmt::Formatter;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use gpui::{App, Entity, SharedString, Task};
|
||||
use gpui::{self, App, Entity, SharedString, Task};
|
||||
use icons::IconName;
|
||||
use language_model::LanguageModelRequestMessage;
|
||||
use language_model::LanguageModelToolSchemaFormat;
|
||||
use language_model::ToolOutput;
|
||||
use project::Project;
|
||||
|
||||
pub use crate::action_log::*;
|
||||
// StringToolOutput is now directly imported from language_model
|
||||
pub use crate::tool_registry::*;
|
||||
pub use crate::tool_working_set::*;
|
||||
|
||||
@@ -66,7 +68,7 @@ pub trait Tool: 'static + Send + Sync {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>>;
|
||||
) -> Task<Result<ToolOutput>>;
|
||||
}
|
||||
|
||||
impl Debug for dyn Tool {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use futures::io::BufReader;
|
||||
use futures::{AsyncBufReadExt, AsyncReadExt};
|
||||
use gpui::{App, Entity, Task};
|
||||
@@ -76,7 +77,7 @@ impl Tool for BashTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input: BashToolInput = match serde_json::from_value(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -123,7 +124,7 @@ impl Tool for BashTool {
|
||||
worktree.read(cx).abs_path()
|
||||
};
|
||||
|
||||
cx.spawn(async move |_| {
|
||||
cx.spawn(async move |_| -> Result<ToolOutput> {
|
||||
// Add 2>&1 to merge stderr into stdout for proper interleaving.
|
||||
let command = format!("({}) 2>&1", input.command);
|
||||
|
||||
@@ -192,25 +193,21 @@ impl Tool for BashTool {
|
||||
String::from_utf8_lossy(&output_bytes).into()
|
||||
};
|
||||
|
||||
let output_with_status = if status.success() {
|
||||
if status.success() {
|
||||
if output_string.is_empty() {
|
||||
"Command executed successfully.".to_string()
|
||||
Ok(StringToolOutput::new("Command executed successfully."))
|
||||
} else {
|
||||
output_string.to_string()
|
||||
Ok(StringToolOutput::new(output_string))
|
||||
}
|
||||
} else {
|
||||
format!(
|
||||
Ok(StringToolOutput::new(format!(
|
||||
"{}{}{}{}",
|
||||
ERR_MESSAGE_1,
|
||||
status.code().unwrap_or(-1),
|
||||
ERR_MESSAGE_2,
|
||||
output_string,
|
||||
)
|
||||
};
|
||||
|
||||
debug_assert!(output_with_status.len() <= STDOUT_LIMIT);
|
||||
|
||||
Ok(output_with_status)
|
||||
)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool, ToolWorkingSet};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use futures::future::join_all;
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -210,7 +211,7 @@ impl Tool for BatchTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<BatchToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -280,7 +281,7 @@ impl Tool for BatchTool {
|
||||
match result {
|
||||
Ok(output) => {
|
||||
formatted_results
|
||||
.push_str(&format!("Tool '{}' result:\n{}\n\n", tool_name, output));
|
||||
.push_str(&format!("Tool '{}' result:\n{}\n\n", tool_name, output.response_for_model()));
|
||||
}
|
||||
Err(err) => {
|
||||
error_occurred = true;
|
||||
@@ -295,7 +296,7 @@ impl Tool for BatchTool {
|
||||
.push_str("Note: Some tool invocations failed. See individual results above.");
|
||||
}
|
||||
|
||||
Ok(formatted_results.trim().to_string())
|
||||
Ok(StringToolOutput::new(formatted_results.trim().to_string()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::sync::Arc;
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use collections::IndexMap;
|
||||
use gpui::{App, AsyncApp, Entity, Task};
|
||||
use language::{OutlineItem, ParseStatus, Point};
|
||||
@@ -129,7 +130,7 @@ impl Tool for CodeSymbolsTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<CodeSymbolsInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -147,8 +148,8 @@ impl Tool for CodeSymbolsTool {
|
||||
};
|
||||
|
||||
cx.spawn(async move |cx| match input.path {
|
||||
Some(path) => file_outline(project, path, action_log, regex, input.offset, cx).await,
|
||||
None => project_symbols(project, regex, input.offset, cx).await,
|
||||
Some(path) => file_outline(project, path, action_log, regex, input.offset, cx).await.map(StringToolOutput::new),
|
||||
None => project_symbols(project, regex, input.offset, cx).await.map(StringToolOutput::new),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::LanguageModelRequestMessage;
|
||||
use language_model::LanguageModelToolSchemaFormat;
|
||||
@@ -77,7 +78,7 @@ impl Tool for CopyPathTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<CopyPathToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -105,10 +106,10 @@ impl Tool for CopyPathTool {
|
||||
|
||||
cx.background_spawn(async move {
|
||||
match copy_task.await {
|
||||
Ok(_) => Ok(format!(
|
||||
Ok(_) => Ok(StringToolOutput::new(format!(
|
||||
"Copied {} to {}",
|
||||
input.source_path, input.destination_path
|
||||
)),
|
||||
))),
|
||||
Err(err) => Err(anyhow!(
|
||||
"Failed to copy {} to {}: {}",
|
||||
input.source_path,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language_model::LanguageModelRequestMessage;
|
||||
use language_model::LanguageModelToolSchemaFormat;
|
||||
@@ -68,7 +69,7 @@ impl Tool for CreateDirectoryTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<CreateDirectoryToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -87,7 +88,7 @@ impl Tool for CreateDirectoryTool {
|
||||
.await
|
||||
.map_err(|err| anyhow!("Unable to create directory {destination_path}: {err}"))?;
|
||||
|
||||
Ok(format!("Created directory {destination_path}"))
|
||||
Ok(StringToolOutput::new(format!("Created directory {destination_path}")))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language_model::LanguageModelRequestMessage;
|
||||
use language_model::LanguageModelToolSchemaFormat;
|
||||
@@ -73,7 +74,7 @@ impl Tool for CreateFileTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<CreateFileToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -104,7 +105,7 @@ impl Tool for CreateFileTool {
|
||||
.await
|
||||
.map_err(|err| anyhow!("Unable to save buffer for {destination_path}: {err}"))?;
|
||||
|
||||
Ok(format!("Created file {destination_path}"))
|
||||
Ok(StringToolOutput::new(format!("Created file {destination_path}")))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use futures::{SinkExt, StreamExt, channel::mpsc};
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -63,7 +64,7 @@ impl Tool for DeletePathTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let path_str = match serde_json::from_value::<DeletePathToolInput>(input) {
|
||||
Ok(input) => input.path,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -124,7 +125,7 @@ impl Tool for DeletePathTool {
|
||||
|
||||
match delete {
|
||||
Some(deletion_task) => match deletion_task.await {
|
||||
Ok(()) => Ok(format!("Deleted {path_str}")),
|
||||
Ok(()) => Ok(StringToolOutput::new(format!("Deleted {path_str}"))),
|
||||
Err(err) => Err(anyhow!("Failed to delete {path_str}: {err}")),
|
||||
},
|
||||
None => Err(anyhow!(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language::{DiagnosticSeverity, OffsetRangeExt};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -83,7 +84,7 @@ impl Tool for DiagnosticsTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
match serde_json::from_value::<DiagnosticsToolInput>(input)
|
||||
.ok()
|
||||
.and_then(|input| input.path)
|
||||
@@ -120,9 +121,9 @@ impl Tool for DiagnosticsTool {
|
||||
}
|
||||
|
||||
if output.is_empty() {
|
||||
Ok("File doesn't have errors or warnings!".to_string())
|
||||
Ok(StringToolOutput::new("File doesn't have errors or warnings!"))
|
||||
} else {
|
||||
Ok(output)
|
||||
Ok(StringToolOutput::new(output))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -155,9 +156,9 @@ impl Tool for DiagnosticsTool {
|
||||
});
|
||||
|
||||
if has_diagnostics {
|
||||
Task::ready(Ok(output))
|
||||
Task::ready(Ok(StringToolOutput::new(output)))
|
||||
} else {
|
||||
Task::ready(Ok("No errors or warnings found in the project.".to_string()))
|
||||
Task::ready(Ok(StringToolOutput::new("No errors or warnings found in the project.")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::sync::Arc;
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Context as _, Result, anyhow, bail};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use futures::AsyncReadExt as _;
|
||||
use gpui::{App, AppContext as _, Entity, Task};
|
||||
use html_to_markdown::{TagHandler, convert_html_to_markdown, markdown};
|
||||
@@ -146,7 +147,7 @@ impl Tool for FetchTool {
|
||||
_project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<FetchToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -164,7 +165,7 @@ impl Tool for FetchTool {
|
||||
bail!("no textual content found");
|
||||
}
|
||||
|
||||
Ok(text)
|
||||
Ok(StringToolOutput::new(text))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{replace::replace_with_flexible_indent, schema::json_schema_for};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AppContext, AsyncApp, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -159,7 +160,7 @@ impl Tool for FindReplaceFileTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<FindReplaceFileToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -251,7 +252,7 @@ impl Tool for FindReplaceFileTool {
|
||||
}).await;
|
||||
|
||||
|
||||
Ok(format!("Edited {}:\n\n```diff\n{}\n```", input.path.display(), diff_str))
|
||||
Ok(StringToolOutput::new(format!("Edited {}:\n\n```diff\n{}\n```", input.path.display(), diff_str)))
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -77,7 +78,7 @@ impl Tool for ListDirectoryTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<ListDirectoryToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -101,7 +102,7 @@ impl Tool for ListDirectoryTool {
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
return Task::ready(Ok(output));
|
||||
return Task::ready(Ok(StringToolOutput::new(output)));
|
||||
}
|
||||
|
||||
let Some(project_path) = project.read(cx).find_project_path(&input.path, cx) else {
|
||||
@@ -133,8 +134,8 @@ impl Tool for ListDirectoryTool {
|
||||
.unwrap();
|
||||
}
|
||||
if output.is_empty() {
|
||||
return Task::ready(Ok(format!("{} is empty.", input.path)));
|
||||
return Task::ready(Ok(StringToolOutput::new(format!("{} is empty.", input.path))));
|
||||
}
|
||||
Task::ready(Ok(output))
|
||||
Task::ready(Ok(StringToolOutput::new(output)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -90,7 +91,7 @@ impl Tool for MovePathTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<MovePathToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -116,10 +117,10 @@ impl Tool for MovePathTool {
|
||||
|
||||
cx.background_spawn(async move {
|
||||
match rename_task.await {
|
||||
Ok(_) => Ok(format!(
|
||||
Ok(_) => Ok(StringToolOutput::new(format!(
|
||||
"Moved {} to {}",
|
||||
input.source_path, input.destination_path
|
||||
)),
|
||||
))),
|
||||
Err(err) => Err(anyhow!(
|
||||
"Failed to move {} to {}: {}",
|
||||
input.source_path,
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use chrono::{Local, Utc};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -60,7 +61,7 @@ impl Tool for NowTool {
|
||||
_project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
_cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input: NowToolInput = match serde_json::from_value(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -72,6 +73,6 @@ impl Tool for NowTool {
|
||||
};
|
||||
let text = format!("The current datetime is {now}.");
|
||||
|
||||
Task::ready(Ok(text))
|
||||
Task::ready(Ok(StringToolOutput::new(text)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -53,7 +54,7 @@ impl Tool for OpenTool {
|
||||
_project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input: OpenToolInput = match serde_json::from_value(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -62,7 +63,7 @@ impl Tool for OpenTool {
|
||||
cx.background_spawn(async move {
|
||||
open::that(&input.path_or_url).context("Failed to open URL or file path")?;
|
||||
|
||||
Ok(format!("Successfully opened {}", input.path_or_url))
|
||||
Ok(StringToolOutput::new(format!("Successfully opened {}", input.path_or_url)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AppContext, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -71,7 +72,7 @@ impl Tool for PathSearchTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let (offset, glob) = match serde_json::from_value::<PathSearchToolInput>(input) {
|
||||
Ok(input) => (input.offset, input.glob),
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -110,7 +111,7 @@ impl Tool for PathSearchTool {
|
||||
}
|
||||
|
||||
if matches.is_empty() {
|
||||
Ok(format!("No paths in the project matched the glob {glob:?}"))
|
||||
Ok(StringToolOutput::new(format!("No paths in the project matched the glob {glob:?}")))
|
||||
} else {
|
||||
// Sort to group entries in the same directory together.
|
||||
matches.sort();
|
||||
@@ -134,7 +135,7 @@ impl Tool for PathSearchTool {
|
||||
matches.join("\n")
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
Ok(StringToolOutput::new(response))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||
use crate::{code_symbols_tool::file_outline, schema::json_schema_for};
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use itertools::Itertools;
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -88,7 +89,7 @@ impl Tool for ReadFileTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<ReadFileToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -114,9 +115,9 @@ impl Tool for ReadFileTool {
|
||||
let lines = text.split('\n').skip(start - 1);
|
||||
if let Some(end) = input.end_line {
|
||||
let count = end.saturating_sub(start).max(1); // Ensure at least 1 line
|
||||
Itertools::intersperse(lines.take(count), "\n").collect()
|
||||
Itertools::intersperse(lines.take(count), "\n").collect::<String>()
|
||||
} else {
|
||||
Itertools::intersperse(lines, "\n").collect()
|
||||
Itertools::intersperse(lines, "\n").collect::<String>()
|
||||
}
|
||||
})?;
|
||||
|
||||
@@ -124,7 +125,7 @@ impl Tool for ReadFileTool {
|
||||
log.buffer_read(buffer, cx);
|
||||
})?;
|
||||
|
||||
Ok(result)
|
||||
Ok(StringToolOutput::new(result))
|
||||
} else {
|
||||
// No line ranges specified, so check file size to see if it's too big.
|
||||
let file_size = buffer.read_with(cx, |buffer, _cx| buffer.text().len())?;
|
||||
@@ -137,13 +138,13 @@ impl Tool for ReadFileTool {
|
||||
log.buffer_read(buffer, cx);
|
||||
})?;
|
||||
|
||||
Ok(result)
|
||||
Ok(StringToolOutput::new(result))
|
||||
} else {
|
||||
// File is too big, so return an error with the outline
|
||||
// and a suggestion to read again with line numbers.
|
||||
let outline = file_outline(project, file_path, action_log, None, 0, cx).await?;
|
||||
|
||||
Ok(format!("This file was too big to read all at once. Here is an outline of its symbols:\n\n{outline}\n\nUsing the line numbers in this outline, you can call this tool again while specifying the start_line and end_line fields to see the implementations of symbols in the outline."))
|
||||
Ok(StringToolOutput::new(format!("This file was too big to read all at once. Here is an outline of its symbols:\n\n{outline}\n\nUsing the line numbers in this outline, you can call this tool again while specifying the start_line and end_line fields to see the implementations of symbols in the outline.")))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use futures::StreamExt;
|
||||
use gpui::{App, Entity, Task};
|
||||
use language::OffsetRangeExt;
|
||||
@@ -83,7 +84,7 @@ impl Tool for RegexSearchTool {
|
||||
project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
const CONTEXT_LINES: u32 = 2;
|
||||
|
||||
let (offset, regex) = match serde_json::from_value::<RegexSearchToolInput>(input) {
|
||||
@@ -179,16 +180,16 @@ impl Tool for RegexSearchTool {
|
||||
}
|
||||
|
||||
if matches_found == 0 {
|
||||
Ok("No matches found".to_string())
|
||||
Ok(StringToolOutput::new("No matches found".to_string()))
|
||||
} else if has_more_matches {
|
||||
Ok(format!(
|
||||
Ok(StringToolOutput::new(format!(
|
||||
"Showing matches {}-{} (there were more matches found; use offset: {} to see next page):\n{output}",
|
||||
offset + 1,
|
||||
offset + matches_found,
|
||||
offset + RESULTS_PER_PAGE,
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
Ok(format!("Found {matches_found} matches:\n{output}"))
|
||||
Ok(StringToolOutput::new(format!("Found {matches_found} matches:\n{output}")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, AsyncApp, Entity, Task};
|
||||
use language::{self, Anchor, Buffer, BufferSnapshot, Location, Point, ToPoint, ToPointUtf16};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -122,7 +123,7 @@ impl Tool for SymbolInfoTool {
|
||||
project: Entity<Project>,
|
||||
action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
let input = match serde_json::from_value::<SymbolInfoToolInput>(input) {
|
||||
Ok(input) => input,
|
||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||
@@ -203,7 +204,7 @@ impl Tool for SymbolInfoTool {
|
||||
if output.is_empty() {
|
||||
Err(anyhow!("None found."))
|
||||
} else {
|
||||
Ok(output)
|
||||
Ok(StringToolOutput::new(output))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||
use crate::schema::json_schema_for;
|
||||
use anyhow::{Result, anyhow};
|
||||
use assistant_tool::{ActionLog, Tool};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
use project::Project;
|
||||
@@ -51,10 +52,10 @@ impl Tool for ThinkingTool {
|
||||
_project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
_cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
// This tool just "thinks out loud" and doesn't perform any actions.
|
||||
Task::ready(match serde_json::from_value::<ThinkingToolInput>(input) {
|
||||
Ok(_input) => Ok("Finished thinking.".to_string()),
|
||||
Ok(_input) => Ok(StringToolOutput::new("Finished thinking.")),
|
||||
Err(err) => Err(anyhow!(err)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -131,8 +131,9 @@ impl Render for Breadcrumbs {
|
||||
}),
|
||||
),
|
||||
None => element
|
||||
// Match the height of the `ButtonLike` in the other arm.
|
||||
// Match the height and padding of the `ButtonLike` in the other arm.
|
||||
.h(rems_from_px(22.))
|
||||
.pl_1()
|
||||
.child(breadcrumbs_stack),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use livekit_client::{self as livekit, TrackSid};
|
||||
use postage::{sink::Sink, stream::Stream, watch};
|
||||
use project::Project;
|
||||
use settings::Settings as _;
|
||||
use std::{any::Any, future::Future, mem, sync::Arc, time::Duration};
|
||||
use std::{any::Any, future::Future, mem, rc::Rc, sync::Arc, time::Duration};
|
||||
use util::{ResultExt, TryFutureExt, post_inc};
|
||||
|
||||
pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
@@ -944,8 +944,8 @@ impl Room {
|
||||
)
|
||||
})?;
|
||||
if self.live_kit.as_ref().map_or(true, |kit| kit.deafened) {
|
||||
if matches!(track, livekit_client::RemoteTrack::Audio(_)) {
|
||||
track.set_enabled(false, cx);
|
||||
if publication.is_audio() {
|
||||
publication.set_enabled(false, cx);
|
||||
}
|
||||
}
|
||||
match track {
|
||||
@@ -1594,7 +1594,7 @@ fn spawn_room_connection(
|
||||
|
||||
let muted_by_user = Room::mute_on_join(cx);
|
||||
this.live_kit = Some(LiveKitRoom {
|
||||
room: Arc::new(room),
|
||||
room: Rc::new(room),
|
||||
screen_track: LocalTrack::None,
|
||||
microphone_track: LocalTrack::None,
|
||||
next_publish_id: 0,
|
||||
@@ -1617,7 +1617,7 @@ fn spawn_room_connection(
|
||||
}
|
||||
|
||||
struct LiveKitRoom {
|
||||
room: Arc<livekit::Room>,
|
||||
room: Rc<livekit::Room>,
|
||||
screen_track: LocalTrack,
|
||||
microphone_track: LocalTrack,
|
||||
/// Tracks whether we're currently in a muted state due to auto-mute from deafening or manual mute performed by user.
|
||||
|
||||
@@ -7,6 +7,8 @@ fn main() {
|
||||
|
||||
if cfg!(target_os = "macos") {
|
||||
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.15.7");
|
||||
// Weakly link ScreenCaptureKit to ensure can be used on macOS 10.15+.
|
||||
println!("cargo:rustc-link-arg=-Wl,-weak_framework,ScreenCaptureKit");
|
||||
}
|
||||
|
||||
// Populate git sha environment variable if git is available
|
||||
|
||||
@@ -18,7 +18,7 @@ test-support = ["clock/test-support", "collections/test-support", "gpui/test-sup
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
async-recursion = "0.3"
|
||||
async-tungstenite = { workspace = true, features = ["async-std", "async-tls"] }
|
||||
async-tungstenite = { workspace = true, features = ["tokio", "tokio-rustls-manual-roots"] }
|
||||
chrono = { workspace = true, features = ["serde"] }
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
@@ -26,6 +26,7 @@ credentials_provider.workspace = true
|
||||
feature_flags.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui_tokio.workspace = true
|
||||
http_client.workspace = true
|
||||
http_client_tls.workspace = true
|
||||
log.workspace = true
|
||||
@@ -51,6 +52,7 @@ url.workspace = true
|
||||
util.workspace = true
|
||||
worktree.workspace = true
|
||||
telemetry.workspace = true
|
||||
tokio.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -67,4 +69,3 @@ windows.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa.workspace = true
|
||||
async-native-tls = { version = "0.5.0", features = ["vendored"] }
|
||||
|
||||
@@ -20,7 +20,7 @@ use futures::{
|
||||
AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt, TryFutureExt as _, TryStreamExt,
|
||||
channel::oneshot, future::BoxFuture,
|
||||
};
|
||||
use gpui::{App, AppContext as _, AsyncApp, Entity, Global, Task, WeakEntity, actions};
|
||||
use gpui::{App, AsyncApp, Entity, Global, Task, WeakEntity, actions};
|
||||
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||
use parking_lot::RwLock;
|
||||
use postage::watch;
|
||||
@@ -1086,7 +1086,7 @@ impl Client {
|
||||
let rpc_url = self.rpc_url(http, release_channel);
|
||||
let system_id = self.telemetry.system_id();
|
||||
let metrics_id = self.telemetry.metrics_id();
|
||||
cx.background_spawn(async move {
|
||||
cx.spawn(async move |cx| {
|
||||
use HttpOrHttps::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -1105,7 +1105,12 @@ impl Client {
|
||||
.host_str()
|
||||
.zip(rpc_url.port_or_known_default())
|
||||
.ok_or_else(|| anyhow!("missing host in rpc url"))?;
|
||||
let stream = connect_socks_proxy_stream(proxy.as_ref(), rpc_host).await?;
|
||||
|
||||
let stream = {
|
||||
let handle = cx.update(|cx| gpui_tokio::Tokio::handle(cx)).ok().unwrap();
|
||||
let _guard = handle.enter();
|
||||
connect_socks_proxy_stream(proxy.as_ref(), rpc_host).await?
|
||||
};
|
||||
|
||||
log::info!("connected to rpc endpoint {}", rpc_url);
|
||||
|
||||
@@ -1144,30 +1149,19 @@ impl Client {
|
||||
request_headers.insert("x-zed-metrics-id", HeaderValue::from_str(&metrics_id)?);
|
||||
}
|
||||
|
||||
match url_scheme {
|
||||
Https => {
|
||||
let (stream, _) =
|
||||
async_tungstenite::async_tls::client_async_tls_with_connector(
|
||||
request,
|
||||
stream,
|
||||
Some(http_client_tls::tls_config().into()),
|
||||
)
|
||||
.await?;
|
||||
Ok(Connection::new(
|
||||
stream
|
||||
.map_err(|error| anyhow!(error))
|
||||
.sink_map_err(|error| anyhow!(error)),
|
||||
))
|
||||
}
|
||||
Http => {
|
||||
let (stream, _) = async_tungstenite::client_async(request, stream).await?;
|
||||
Ok(Connection::new(
|
||||
stream
|
||||
.map_err(|error| anyhow!(error))
|
||||
.sink_map_err(|error| anyhow!(error)),
|
||||
))
|
||||
}
|
||||
}
|
||||
let (stream, _) = async_tungstenite::tokio::client_async_tls_with_connector_and_config(
|
||||
request,
|
||||
stream,
|
||||
Some(Arc::new(http_client_tls::tls_config()).into()),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Connection::new(
|
||||
stream
|
||||
.map_err(|error| anyhow!(error))
|
||||
.sink_map_err(|error| anyhow!(error)),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1639,7 +1633,7 @@ mod tests {
|
||||
use crate::test::FakeServer;
|
||||
|
||||
use clock::FakeSystemClock;
|
||||
use gpui::{BackgroundExecutor, TestAppContext};
|
||||
use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
|
||||
use http_client::FakeHttpClient;
|
||||
use parking_lot::Mutex;
|
||||
use proto::TypedEnvelope;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
//! socks proxy
|
||||
use anyhow::{Result, anyhow};
|
||||
use futures::io::{AsyncRead, AsyncWrite};
|
||||
use http_client::Uri;
|
||||
use tokio_socks::{
|
||||
io::Compat,
|
||||
tcp::{Socks4Stream, Socks5Stream},
|
||||
};
|
||||
use tokio_socks::tcp::{Socks4Stream, Socks5Stream};
|
||||
|
||||
pub(crate) async fn connect_socks_proxy_stream(
|
||||
proxy: Option<&Uri>,
|
||||
@@ -14,7 +10,7 @@ pub(crate) async fn connect_socks_proxy_stream(
|
||||
let stream = match parse_socks_proxy(proxy) {
|
||||
Some((socks_proxy, SocksVersion::V4)) => {
|
||||
let stream = Socks4Stream::connect_with_socket(
|
||||
Compat::new(smol::net::TcpStream::connect(socks_proxy).await?),
|
||||
tokio::net::TcpStream::connect(socks_proxy).await?,
|
||||
rpc_host,
|
||||
)
|
||||
.await
|
||||
@@ -23,13 +19,15 @@ pub(crate) async fn connect_socks_proxy_stream(
|
||||
}
|
||||
Some((socks_proxy, SocksVersion::V5)) => Box::new(
|
||||
Socks5Stream::connect_with_socket(
|
||||
Compat::new(smol::net::TcpStream::connect(socks_proxy).await?),
|
||||
tokio::net::TcpStream::connect(socks_proxy).await?,
|
||||
rpc_host,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| anyhow!("error connecting to socks {}", err))?,
|
||||
) as Box<dyn AsyncReadWrite>,
|
||||
None => Box::new(smol::net::TcpStream::connect(rpc_host).await?) as Box<dyn AsyncReadWrite>,
|
||||
None => {
|
||||
Box::new(tokio::net::TcpStream::connect(rpc_host).await?) as Box<dyn AsyncReadWrite>
|
||||
}
|
||||
};
|
||||
Ok(stream)
|
||||
}
|
||||
@@ -60,5 +58,11 @@ enum SocksVersion {
|
||||
V5,
|
||||
}
|
||||
|
||||
pub(crate) trait AsyncReadWrite: AsyncRead + AsyncWrite + Unpin + Send + 'static {}
|
||||
impl<T: AsyncRead + AsyncWrite + Unpin + Send + 'static> AsyncReadWrite for T {}
|
||||
pub(crate) trait AsyncReadWrite:
|
||||
tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static
|
||||
{
|
||||
}
|
||||
impl<T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static> AsyncReadWrite
|
||||
for T
|
||||
{
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use std::io::Write;
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Instant;
|
||||
use std::{env, mem, path::PathBuf, sync::Arc, time::Duration};
|
||||
use telemetry_events::{AssistantEvent, AssistantPhase, Event, EventRequestBody, EventWrapper};
|
||||
use telemetry_events::{AssistantEventData, AssistantPhase, Event, EventRequestBody, EventWrapper};
|
||||
use util::{ResultExt, TryFutureExt};
|
||||
use worktree::{UpdatedEntriesSet, WorktreeId};
|
||||
|
||||
@@ -329,7 +329,7 @@ impl Telemetry {
|
||||
drop(state);
|
||||
}
|
||||
|
||||
pub fn report_assistant_event(self: &Arc<Self>, event: AssistantEvent) {
|
||||
pub fn report_assistant_event(self: &Arc<Self>, event: AssistantEventData) {
|
||||
let event_type = match event.phase {
|
||||
AssistantPhase::Response => "Assistant Responded",
|
||||
AssistantPhase::Invoked => "Assistant Invoked",
|
||||
|
||||
@@ -33,7 +33,6 @@ clock.workspace = true
|
||||
collections.workspace = true
|
||||
dashmap.workspace = true
|
||||
derive_more.workspace = true
|
||||
buffer_diff.workspace = true
|
||||
envy = "0.4.2"
|
||||
futures.workspace = true
|
||||
google_ai.workspace = true
|
||||
@@ -85,6 +84,7 @@ assistant_slash_command.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
async-trait.workspace = true
|
||||
audio.workspace = true
|
||||
buffer_diff.workspace = true
|
||||
call = { workspace = true, features = ["test-support"] }
|
||||
channel.workspace = true
|
||||
client = { workspace = true, features = ["test-support"] }
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
alter table models
|
||||
add column max_input_tokens_per_minute bigint not null default 0,
|
||||
add column max_output_tokens_per_minute bigint not null default 0;
|
||||
@@ -127,7 +127,7 @@ async fn update_billing_preferences(
|
||||
|
||||
SnowflakeRow::new(
|
||||
"Spend Limit Updated",
|
||||
user.metrics_id,
|
||||
Some(user.metrics_id),
|
||||
user.admin,
|
||||
None,
|
||||
json!({
|
||||
|
||||
@@ -149,6 +149,37 @@ pub async fn post_crash(
|
||||
"crash report"
|
||||
);
|
||||
|
||||
if let Some(kinesis_client) = app.kinesis_client.clone() {
|
||||
if let Some(stream) = app.config.kinesis_stream.clone() {
|
||||
let properties = json!({
|
||||
"app_version": report.header.app_version,
|
||||
"os_version": report.header.os_version,
|
||||
"os_name": "macOS",
|
||||
"bundle_id": report.header.bundle_id,
|
||||
"incident_id": report.header.incident_id,
|
||||
"installation_id": installation_id,
|
||||
"description": description,
|
||||
"backtrace": summary,
|
||||
});
|
||||
let row = SnowflakeRow::new(
|
||||
"Crash Reported",
|
||||
None,
|
||||
false,
|
||||
Some(installation_id),
|
||||
properties,
|
||||
);
|
||||
let data = serde_json::to_vec(&row)?;
|
||||
kinesis_client
|
||||
.put_record()
|
||||
.stream_name(stream)
|
||||
.partition_key(row.insert_id.unwrap_or_default())
|
||||
.data(data.into())
|
||||
.send()
|
||||
.await
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(slack_panics_webhook) = app.config.slack_panics_webhook.clone() {
|
||||
let payload = slack::WebhookBody::new(|w| {
|
||||
w.add_section(|s| s.text(slack::Text::markdown(description)))
|
||||
@@ -314,6 +345,8 @@ pub async fn post_panic(
|
||||
.ok();
|
||||
}
|
||||
|
||||
let backtrace = panic.backtrace.join("\n");
|
||||
|
||||
tracing::error!(
|
||||
service = "client",
|
||||
version = %panic.app_version,
|
||||
@@ -322,10 +355,40 @@ pub async fn post_panic(
|
||||
incident_id = %incident_id,
|
||||
installation_id = %panic.installation_id.clone().unwrap_or_default(),
|
||||
description = %panic.payload,
|
||||
backtrace = %panic.backtrace.join("\n"),
|
||||
backtrace = %backtrace,
|
||||
"panic report"
|
||||
);
|
||||
|
||||
if let Some(kinesis_client) = app.kinesis_client.clone() {
|
||||
if let Some(stream) = app.config.kinesis_stream.clone() {
|
||||
let properties = json!({
|
||||
"app_version": panic.app_version,
|
||||
"os_name": panic.os_name,
|
||||
"os_version": panic.os_version,
|
||||
"incident_id": incident_id,
|
||||
"installation_id": panic.installation_id,
|
||||
"description": panic.payload,
|
||||
"backtrace": backtrace,
|
||||
});
|
||||
let row = SnowflakeRow::new(
|
||||
"Panic Reported",
|
||||
None,
|
||||
false,
|
||||
panic.installation_id.clone(),
|
||||
properties,
|
||||
);
|
||||
let data = serde_json::to_vec(&row)?;
|
||||
kinesis_client
|
||||
.put_record()
|
||||
.stream_name(stream)
|
||||
.partition_key(row.insert_id.unwrap_or_default())
|
||||
.data(data.into())
|
||||
.send()
|
||||
.await
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
|
||||
let backtrace = if panic.backtrace.len() > 25 {
|
||||
let total = panic.backtrace.len();
|
||||
format!(
|
||||
@@ -711,7 +774,7 @@ pub struct SnowflakeRow {
|
||||
impl SnowflakeRow {
|
||||
pub fn new(
|
||||
event_type: impl Into<String>,
|
||||
metrics_id: Uuid,
|
||||
metrics_id: Option<Uuid>,
|
||||
is_staff: bool,
|
||||
system_id: Option<String>,
|
||||
event_properties: serde_json::Value,
|
||||
@@ -720,7 +783,7 @@ impl SnowflakeRow {
|
||||
time: chrono::Utc::now(),
|
||||
event_type: event_type.into(),
|
||||
device_id: system_id,
|
||||
user_id: Some(metrics_id.to_string()),
|
||||
user_id: metrics_id.map(|id| id.to_string()),
|
||||
insert_id: Some(uuid::Uuid::new_v4().to_string()),
|
||||
event_properties,
|
||||
user_properties: Some(json!({"is_staff": is_staff})),
|
||||
|
||||
@@ -316,10 +316,14 @@ async fn perform_completion(
|
||||
is_staff = claims.is_staff,
|
||||
provider = params.provider.to_string(),
|
||||
model = model,
|
||||
tokens_remaining = rate_limit_info.tokens_remaining,
|
||||
requests_remaining = rate_limit_info.requests_remaining,
|
||||
requests_reset = ?rate_limit_info.requests_reset,
|
||||
tokens_reset = ?rate_limit_info.tokens_reset,
|
||||
tokens_remaining = rate_limit_info.tokens.as_ref().map(|limits| limits.remaining),
|
||||
input_tokens_remaining = rate_limit_info.input_tokens.as_ref().map(|limits| limits.remaining),
|
||||
output_tokens_remaining = rate_limit_info.output_tokens.as_ref().map(|limits| limits.remaining),
|
||||
requests_remaining = rate_limit_info.requests.as_ref().map(|limits| limits.remaining),
|
||||
requests_reset = ?rate_limit_info.requests.as_ref().map(|limits| limits.reset),
|
||||
tokens_reset = ?rate_limit_info.tokens.as_ref().map(|limits| limits.reset),
|
||||
input_tokens_reset = ?rate_limit_info.input_tokens.as_ref().map(|limits| limits.reset),
|
||||
output_tokens_reset = ?rate_limit_info.output_tokens.as_ref().map(|limits| limits.reset),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -499,6 +503,10 @@ async fn check_usage_limit(
|
||||
model.max_requests_per_minute as usize / users_in_recent_minutes;
|
||||
let per_user_max_tokens_per_minute =
|
||||
model.max_tokens_per_minute as usize / users_in_recent_minutes;
|
||||
let per_user_max_input_tokens_per_minute =
|
||||
model.max_input_tokens_per_minute as usize / users_in_recent_minutes;
|
||||
let per_user_max_output_tokens_per_minute =
|
||||
model.max_output_tokens_per_minute as usize / users_in_recent_minutes;
|
||||
let per_user_max_tokens_per_day = model.max_tokens_per_day as usize / users_in_recent_days;
|
||||
|
||||
let usage = state
|
||||
@@ -506,29 +514,55 @@ async fn check_usage_limit(
|
||||
.get_usage(user_id, provider, model_name, Utc::now())
|
||||
.await?;
|
||||
|
||||
let checks = [
|
||||
(
|
||||
usage.requests_this_minute,
|
||||
per_user_max_requests_per_minute,
|
||||
UsageMeasure::RequestsPerMinute,
|
||||
),
|
||||
(
|
||||
usage.tokens_this_minute,
|
||||
per_user_max_tokens_per_minute,
|
||||
UsageMeasure::TokensPerMinute,
|
||||
),
|
||||
(
|
||||
usage.tokens_this_day,
|
||||
per_user_max_tokens_per_day,
|
||||
UsageMeasure::TokensPerDay,
|
||||
),
|
||||
];
|
||||
let checks = match (provider, model_name) {
|
||||
(LanguageModelProvider::Anthropic, "claude-3-7-sonnet") => vec![
|
||||
(
|
||||
usage.requests_this_minute,
|
||||
per_user_max_requests_per_minute,
|
||||
UsageMeasure::RequestsPerMinute,
|
||||
),
|
||||
(
|
||||
usage.input_tokens_this_minute,
|
||||
per_user_max_tokens_per_minute,
|
||||
UsageMeasure::InputTokensPerMinute,
|
||||
),
|
||||
(
|
||||
usage.output_tokens_this_minute,
|
||||
per_user_max_tokens_per_minute,
|
||||
UsageMeasure::OutputTokensPerMinute,
|
||||
),
|
||||
(
|
||||
usage.tokens_this_day,
|
||||
per_user_max_tokens_per_day,
|
||||
UsageMeasure::TokensPerDay,
|
||||
),
|
||||
],
|
||||
_ => vec![
|
||||
(
|
||||
usage.requests_this_minute,
|
||||
per_user_max_requests_per_minute,
|
||||
UsageMeasure::RequestsPerMinute,
|
||||
),
|
||||
(
|
||||
usage.tokens_this_minute,
|
||||
per_user_max_tokens_per_minute,
|
||||
UsageMeasure::TokensPerMinute,
|
||||
),
|
||||
(
|
||||
usage.tokens_this_day,
|
||||
per_user_max_tokens_per_day,
|
||||
UsageMeasure::TokensPerDay,
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
for (used, limit, usage_measure) in checks {
|
||||
if used > limit {
|
||||
let resource = match usage_measure {
|
||||
UsageMeasure::RequestsPerMinute => "requests_per_minute",
|
||||
UsageMeasure::TokensPerMinute => "tokens_per_minute",
|
||||
UsageMeasure::InputTokensPerMinute => "input_tokens_per_minute",
|
||||
UsageMeasure::OutputTokensPerMinute => "output_tokens_per_minute",
|
||||
UsageMeasure::TokensPerDay => "tokens_per_day",
|
||||
};
|
||||
|
||||
@@ -540,19 +574,24 @@ async fn check_usage_limit(
|
||||
is_staff = claims.is_staff,
|
||||
provider = provider.to_string(),
|
||||
model = model.name,
|
||||
usage_measure = resource,
|
||||
requests_this_minute = usage.requests_this_minute,
|
||||
tokens_this_minute = usage.tokens_this_minute,
|
||||
input_tokens_this_minute = usage.input_tokens_this_minute,
|
||||
output_tokens_this_minute = usage.output_tokens_this_minute,
|
||||
tokens_this_day = usage.tokens_this_day,
|
||||
users_in_recent_minutes = users_in_recent_minutes,
|
||||
users_in_recent_days = users_in_recent_days,
|
||||
max_requests_per_minute = per_user_max_requests_per_minute,
|
||||
max_tokens_per_minute = per_user_max_tokens_per_minute,
|
||||
max_input_tokens_per_minute = per_user_max_input_tokens_per_minute,
|
||||
max_output_tokens_per_minute = per_user_max_output_tokens_per_minute,
|
||||
max_tokens_per_day = per_user_max_tokens_per_day,
|
||||
);
|
||||
|
||||
SnowflakeRow::new(
|
||||
"Language Model Rate Limited",
|
||||
claims.metrics_id,
|
||||
Some(claims.metrics_id),
|
||||
claims.is_staff,
|
||||
claims.system_id.clone(),
|
||||
json!({
|
||||
@@ -561,6 +600,8 @@ async fn check_usage_limit(
|
||||
"users_in_recent_days": users_in_recent_days,
|
||||
"max_requests_per_minute": per_user_max_requests_per_minute,
|
||||
"max_tokens_per_minute": per_user_max_tokens_per_minute,
|
||||
"max_input_tokens_per_minute": per_user_max_input_tokens_per_minute,
|
||||
"max_output_tokens_per_minute": per_user_max_output_tokens_per_minute,
|
||||
"max_tokens_per_day": per_user_max_tokens_per_day,
|
||||
"plan": match claims.plan {
|
||||
Plan::Free => "free".to_string(),
|
||||
@@ -656,8 +697,12 @@ impl<S> Drop for TokenCountingStream<S> {
|
||||
login = claims.github_user_login,
|
||||
authn.jti = claims.jti,
|
||||
is_staff = claims.is_staff,
|
||||
provider = provider.to_string(),
|
||||
model = model,
|
||||
requests_this_minute = usage.requests_this_minute,
|
||||
tokens_this_minute = usage.tokens_this_minute,
|
||||
input_tokens_this_minute = usage.input_tokens_this_minute,
|
||||
output_tokens_this_minute = usage.output_tokens_this_minute,
|
||||
);
|
||||
|
||||
let properties = json!({
|
||||
@@ -674,7 +719,7 @@ impl<S> Drop for TokenCountingStream<S> {
|
||||
});
|
||||
SnowflakeRow::new(
|
||||
"Language Model Used",
|
||||
claims.metrics_id,
|
||||
Some(claims.metrics_id),
|
||||
claims.is_staff,
|
||||
claims.system_id.clone(),
|
||||
properties,
|
||||
@@ -726,6 +771,8 @@ pub fn log_usage_periodically(state: Arc<LlmState>) {
|
||||
model = usage.model,
|
||||
requests_this_minute = usage.requests_this_minute,
|
||||
tokens_this_minute = usage.tokens_this_minute,
|
||||
input_tokens_this_minute = usage.input_tokens_this_minute,
|
||||
output_tokens_this_minute = usage.output_tokens_this_minute,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ impl TokenUsage {
|
||||
pub struct Usage {
|
||||
pub requests_this_minute: usize,
|
||||
pub tokens_this_minute: usize,
|
||||
pub input_tokens_this_minute: usize,
|
||||
pub output_tokens_this_minute: usize,
|
||||
pub tokens_this_day: usize,
|
||||
pub tokens_this_month: TokenUsage,
|
||||
pub spending_this_month: Cents,
|
||||
@@ -39,6 +41,8 @@ pub struct ApplicationWideUsage {
|
||||
pub model: String,
|
||||
pub requests_this_minute: usize,
|
||||
pub tokens_this_minute: usize,
|
||||
pub input_tokens_this_minute: usize,
|
||||
pub output_tokens_this_minute: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
@@ -94,6 +98,10 @@ impl LlmDatabase {
|
||||
let past_minute = now - Duration::minutes(1);
|
||||
let requests_per_minute = self.usage_measure_ids[&UsageMeasure::RequestsPerMinute];
|
||||
let tokens_per_minute = self.usage_measure_ids[&UsageMeasure::TokensPerMinute];
|
||||
let input_tokens_per_minute =
|
||||
self.usage_measure_ids[&UsageMeasure::InputTokensPerMinute];
|
||||
let output_tokens_per_minute =
|
||||
self.usage_measure_ids[&UsageMeasure::OutputTokensPerMinute];
|
||||
|
||||
let mut results = Vec::new();
|
||||
for ((provider, model_name), model) in self.models.iter() {
|
||||
@@ -114,6 +122,8 @@ impl LlmDatabase {
|
||||
|
||||
let mut requests_this_minute = 0;
|
||||
let mut tokens_this_minute = 0;
|
||||
let mut input_tokens_this_minute = 0;
|
||||
let mut output_tokens_this_minute = 0;
|
||||
while let Some(usage) = usages.next().await {
|
||||
let usage = usage?;
|
||||
if usage.measure_id == requests_per_minute {
|
||||
@@ -136,6 +146,26 @@ impl LlmDatabase {
|
||||
.iter()
|
||||
.copied()
|
||||
.sum::<i64>() as usize;
|
||||
} else if usage.measure_id == input_tokens_per_minute {
|
||||
input_tokens_this_minute += Self::get_live_buckets(
|
||||
&usage,
|
||||
now.naive_utc(),
|
||||
UsageMeasure::InputTokensPerMinute,
|
||||
)
|
||||
.0
|
||||
.iter()
|
||||
.copied()
|
||||
.sum::<i64>() as usize;
|
||||
} else if usage.measure_id == output_tokens_per_minute {
|
||||
output_tokens_this_minute += Self::get_live_buckets(
|
||||
&usage,
|
||||
now.naive_utc(),
|
||||
UsageMeasure::OutputTokensPerMinute,
|
||||
)
|
||||
.0
|
||||
.iter()
|
||||
.copied()
|
||||
.sum::<i64>() as usize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +174,8 @@ impl LlmDatabase {
|
||||
model: model_name.clone(),
|
||||
requests_this_minute,
|
||||
tokens_this_minute,
|
||||
input_tokens_this_minute,
|
||||
output_tokens_this_minute,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -239,6 +271,10 @@ impl LlmDatabase {
|
||||
self.get_usage_for_measure(&usages, now, UsageMeasure::RequestsPerMinute)?;
|
||||
let tokens_this_minute =
|
||||
self.get_usage_for_measure(&usages, now, UsageMeasure::TokensPerMinute)?;
|
||||
let input_tokens_this_minute =
|
||||
self.get_usage_for_measure(&usages, now, UsageMeasure::InputTokensPerMinute)?;
|
||||
let output_tokens_this_minute =
|
||||
self.get_usage_for_measure(&usages, now, UsageMeasure::OutputTokensPerMinute)?;
|
||||
let tokens_this_day =
|
||||
self.get_usage_for_measure(&usages, now, UsageMeasure::TokensPerDay)?;
|
||||
let spending_this_month = if let Some(monthly_usage) = &monthly_usage {
|
||||
@@ -267,6 +303,8 @@ impl LlmDatabase {
|
||||
Ok(Usage {
|
||||
requests_this_minute,
|
||||
tokens_this_minute,
|
||||
input_tokens_this_minute,
|
||||
output_tokens_this_minute,
|
||||
tokens_this_day,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: monthly_usage
|
||||
@@ -337,6 +375,31 @@ impl LlmDatabase {
|
||||
&tx,
|
||||
)
|
||||
.await?;
|
||||
let input_tokens_this_minute = self
|
||||
.update_usage_for_measure(
|
||||
user_id,
|
||||
is_staff,
|
||||
model.id,
|
||||
&usages,
|
||||
UsageMeasure::InputTokensPerMinute,
|
||||
now,
|
||||
// Cache read input tokens are not counted for the purposes of rate limits (but they are still billed).
|
||||
tokens.input + tokens.input_cache_creation,
|
||||
&tx,
|
||||
)
|
||||
.await?;
|
||||
let output_tokens_this_minute = self
|
||||
.update_usage_for_measure(
|
||||
user_id,
|
||||
is_staff,
|
||||
model.id,
|
||||
&usages,
|
||||
UsageMeasure::OutputTokensPerMinute,
|
||||
now,
|
||||
tokens.output,
|
||||
&tx,
|
||||
)
|
||||
.await?;
|
||||
let tokens_this_day = self
|
||||
.update_usage_for_measure(
|
||||
user_id,
|
||||
@@ -485,6 +548,8 @@ impl LlmDatabase {
|
||||
Ok(Usage {
|
||||
requests_this_minute,
|
||||
tokens_this_minute,
|
||||
input_tokens_this_minute,
|
||||
output_tokens_this_minute,
|
||||
tokens_this_day,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: monthly_usage.input_tokens as usize,
|
||||
@@ -684,7 +749,9 @@ impl UsageMeasure {
|
||||
fn bucket_count(&self) -> usize {
|
||||
match self {
|
||||
UsageMeasure::RequestsPerMinute => MINUTE_BUCKET_COUNT,
|
||||
UsageMeasure::TokensPerMinute => MINUTE_BUCKET_COUNT,
|
||||
UsageMeasure::TokensPerMinute
|
||||
| UsageMeasure::InputTokensPerMinute
|
||||
| UsageMeasure::OutputTokensPerMinute => MINUTE_BUCKET_COUNT,
|
||||
UsageMeasure::TokensPerDay => DAY_BUCKET_COUNT,
|
||||
}
|
||||
}
|
||||
@@ -692,7 +759,9 @@ impl UsageMeasure {
|
||||
fn total_duration(&self) -> Duration {
|
||||
match self {
|
||||
UsageMeasure::RequestsPerMinute => Duration::minutes(1),
|
||||
UsageMeasure::TokensPerMinute => Duration::minutes(1),
|
||||
UsageMeasure::TokensPerMinute
|
||||
| UsageMeasure::InputTokensPerMinute
|
||||
| UsageMeasure::OutputTokensPerMinute => Duration::minutes(1),
|
||||
UsageMeasure::TokensPerDay => Duration::hours(24),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ pub struct Model {
|
||||
pub name: String,
|
||||
pub max_requests_per_minute: i64,
|
||||
pub max_tokens_per_minute: i64,
|
||||
pub max_input_tokens_per_minute: i64,
|
||||
pub max_output_tokens_per_minute: i64,
|
||||
pub max_tokens_per_day: i64,
|
||||
pub price_per_million_input_tokens: i32,
|
||||
pub price_per_million_cache_creation_input_tokens: i32,
|
||||
|
||||
@@ -8,6 +8,8 @@ use sea_orm::entity::prelude::*;
|
||||
pub enum UsageMeasure {
|
||||
RequestsPerMinute,
|
||||
TokensPerMinute,
|
||||
InputTokensPerMinute,
|
||||
OutputTokensPerMinute,
|
||||
TokensPerDay,
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 2,
|
||||
tokens_this_minute: 3000,
|
||||
input_tokens_this_minute: 3000,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 3000,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 3000,
|
||||
@@ -102,6 +104,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 1,
|
||||
tokens_this_minute: 2000,
|
||||
input_tokens_this_minute: 2000,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 3000,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 3000,
|
||||
@@ -140,6 +144,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 2,
|
||||
tokens_this_minute: 5000,
|
||||
input_tokens_this_minute: 5000,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 6000,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 6000,
|
||||
@@ -160,6 +166,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 0,
|
||||
tokens_this_minute: 0,
|
||||
input_tokens_this_minute: 0,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 5000,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 6000,
|
||||
@@ -197,6 +205,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 1,
|
||||
tokens_this_minute: 4000,
|
||||
input_tokens_this_minute: 4000,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 9000,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 10000,
|
||||
@@ -240,6 +250,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 1,
|
||||
tokens_this_minute: 1500,
|
||||
input_tokens_this_minute: 1500,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 1500,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 1000,
|
||||
@@ -278,6 +290,8 @@ async fn test_tracking_usage(db: &mut LlmDatabase) {
|
||||
Usage {
|
||||
requests_this_minute: 2,
|
||||
tokens_this_minute: 2800,
|
||||
input_tokens_this_minute: 2500,
|
||||
output_tokens_this_minute: 0,
|
||||
tokens_this_day: 2800,
|
||||
tokens_this_month: TokenUsage {
|
||||
input: 2000,
|
||||
|
||||
@@ -356,6 +356,7 @@ impl Server {
|
||||
.add_request_handler(forward_mutating_project_request::<proto::BlameBuffer>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::MultiLspQuery>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::RestartLanguageServers>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::StopLanguageServers>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::LinkedEditingRange>)
|
||||
.add_message_handler(create_buffer_for_peer)
|
||||
.add_request_handler(update_buffer)
|
||||
@@ -983,7 +984,7 @@ impl Server {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn snapshot<'a>(self: &'a Arc<Self>) -> ServerSnapshot<'a> {
|
||||
pub async fn snapshot(self: &Arc<Self>) -> ServerSnapshot {
|
||||
ServerSnapshot {
|
||||
connection_pool: ConnectionPoolGuard {
|
||||
guard: self.connection_pool.lock(),
|
||||
@@ -4152,13 +4153,13 @@ async fn get_llm_api_token(
|
||||
|
||||
fn to_axum_message(message: TungsteniteMessage) -> anyhow::Result<AxumMessage> {
|
||||
let message = match message {
|
||||
TungsteniteMessage::Text(payload) => AxumMessage::Text(payload),
|
||||
TungsteniteMessage::Binary(payload) => AxumMessage::Binary(payload),
|
||||
TungsteniteMessage::Ping(payload) => AxumMessage::Ping(payload),
|
||||
TungsteniteMessage::Pong(payload) => AxumMessage::Pong(payload),
|
||||
TungsteniteMessage::Text(payload) => AxumMessage::Text(payload.as_str().to_string()),
|
||||
TungsteniteMessage::Binary(payload) => AxumMessage::Binary(payload.into()),
|
||||
TungsteniteMessage::Ping(payload) => AxumMessage::Ping(payload.into()),
|
||||
TungsteniteMessage::Pong(payload) => AxumMessage::Pong(payload.into()),
|
||||
TungsteniteMessage::Close(frame) => AxumMessage::Close(frame.map(|frame| AxumCloseFrame {
|
||||
code: frame.code.into(),
|
||||
reason: frame.reason,
|
||||
reason: frame.reason.as_str().to_owned().into(),
|
||||
})),
|
||||
// We should never receive a frame while reading the message, according
|
||||
// to the `tungstenite` maintainers:
|
||||
@@ -4178,14 +4179,14 @@ fn to_axum_message(message: TungsteniteMessage) -> anyhow::Result<AxumMessage> {
|
||||
|
||||
fn to_tungstenite_message(message: AxumMessage) -> TungsteniteMessage {
|
||||
match message {
|
||||
AxumMessage::Text(payload) => TungsteniteMessage::Text(payload),
|
||||
AxumMessage::Binary(payload) => TungsteniteMessage::Binary(payload),
|
||||
AxumMessage::Ping(payload) => TungsteniteMessage::Ping(payload),
|
||||
AxumMessage::Pong(payload) => TungsteniteMessage::Pong(payload),
|
||||
AxumMessage::Text(payload) => TungsteniteMessage::Text(payload.into()),
|
||||
AxumMessage::Binary(payload) => TungsteniteMessage::Binary(payload.into()),
|
||||
AxumMessage::Ping(payload) => TungsteniteMessage::Ping(payload.into()),
|
||||
AxumMessage::Pong(payload) => TungsteniteMessage::Pong(payload.into()),
|
||||
AxumMessage::Close(frame) => {
|
||||
TungsteniteMessage::Close(frame.map(|frame| TungsteniteCloseFrame {
|
||||
code: frame.code.into(),
|
||||
reason: frame.reason,
|
||||
reason: frame.reason.as_ref().into(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
||||
client_a
|
||||
.fs()
|
||||
.insert_tree(
|
||||
"/a",
|
||||
path!("/a"),
|
||||
json!({
|
||||
"1.txt": "one",
|
||||
"2.txt": "two",
|
||||
@@ -683,7 +683,7 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
let (project_a, worktree_id) = client_a.build_local_project("/a", cx_a).await;
|
||||
let (project_a, worktree_id) = client_a.build_local_project(path!("/a"), cx_a).await;
|
||||
active_call_a
|
||||
.update(cx_a, |call, cx| call.set_location(Some(&project_a), cx))
|
||||
.await
|
||||
|
||||
@@ -6866,10 +6866,14 @@ async fn test_remote_git_branches(
|
||||
|
||||
assert_eq!(branches_b, branches_set);
|
||||
|
||||
cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
cx_b.update(|cx| {
|
||||
repo_b.update(cx, |repository, _cx| {
|
||||
repository.change_branch(new_branch.to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
executor.run_until_parked();
|
||||
|
||||
@@ -6892,18 +6896,18 @@ async fn test_remote_git_branches(
|
||||
|
||||
// Also try creating a new branch
|
||||
cx_b.update(|cx| {
|
||||
repo_b
|
||||
.read(cx)
|
||||
.create_branch("totally-new-branch".to_string())
|
||||
repo_b.update(cx, |repository, _cx| {
|
||||
repository.create_branch("totally-new-branch".to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
cx_b.update(|cx| {
|
||||
repo_b
|
||||
.read(cx)
|
||||
.change_branch("totally-new-branch".to_string())
|
||||
repo_b.update(cx, |repository, _cx| {
|
||||
repository.change_branch("totally-new-branch".to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
||||
@@ -283,7 +283,7 @@ async fn test_ssh_collaboration_git_branches(
|
||||
let repo_b = cx_b.update(|cx| project_b.read(cx).active_repository(cx).unwrap());
|
||||
|
||||
let branches_b = cx_b
|
||||
.update(|cx| repo_b.read(cx).branches())
|
||||
.update(|cx| repo_b.update(cx, |repo_b, _cx| repo_b.branches()))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
@@ -297,10 +297,14 @@ async fn test_ssh_collaboration_git_branches(
|
||||
|
||||
assert_eq!(&branches_b, &branches_set);
|
||||
|
||||
cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
cx_b.update(|cx| {
|
||||
repo_b.update(cx, |repo_b, _cx| {
|
||||
repo_b.change_branch(new_branch.to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
executor.run_until_parked();
|
||||
|
||||
@@ -325,18 +329,18 @@ async fn test_ssh_collaboration_git_branches(
|
||||
|
||||
// Also try creating a new branch
|
||||
cx_b.update(|cx| {
|
||||
repo_b
|
||||
.read(cx)
|
||||
.create_branch("totally-new-branch".to_string())
|
||||
repo_b.update(cx, |repo_b, _cx| {
|
||||
repo_b.create_branch("totally-new-branch".to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
cx_b.update(|cx| {
|
||||
repo_b
|
||||
.read(cx)
|
||||
.change_branch("totally-new-branch".to_string())
|
||||
repo_b.update(cx, |repo_b, _cx| {
|
||||
repo_b.change_branch("totally-new-branch".to_string())
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
||||
@@ -315,6 +315,7 @@ impl MessageEditor {
|
||||
icon_path: None,
|
||||
confirm: None,
|
||||
documentation: None,
|
||||
insert_text_mode: None,
|
||||
source: CompletionSource::Custom,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -35,7 +35,7 @@ use ui::{
|
||||
};
|
||||
use util::{ResultExt, TryFutureExt, maybe};
|
||||
use workspace::{
|
||||
OpenChannelNotes, Workspace,
|
||||
Deafen, LeaveCall, Mute, OpenChannelNotes, ScreenShare, ShareProject, Workspace,
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, NotifyResultExt, NotifyTaskExt},
|
||||
};
|
||||
@@ -80,6 +80,57 @@ pub fn init(cx: &mut App) {
|
||||
});
|
||||
}
|
||||
});
|
||||
// TODO: make it possible to bind this one to a held key for push to talk?
|
||||
// how to make "toggle_on_modifiers_press" contextual?
|
||||
workspace.register_action(|_, _: &Mute, window, cx| {
|
||||
let room = ActiveCall::global(cx).read(cx).room().cloned();
|
||||
if let Some(room) = room {
|
||||
window.defer(cx, move |_window, cx| {
|
||||
room.update(cx, |room, cx| room.toggle_mute(cx))
|
||||
});
|
||||
}
|
||||
});
|
||||
workspace.register_action(|_, _: &Deafen, window, cx| {
|
||||
let room = ActiveCall::global(cx).read(cx).room().cloned();
|
||||
if let Some(room) = room {
|
||||
window.defer(cx, move |_window, cx| {
|
||||
room.update(cx, |room, cx| room.toggle_deafen(cx))
|
||||
});
|
||||
}
|
||||
});
|
||||
workspace.register_action(|_, _: &LeaveCall, window, cx| {
|
||||
CollabPanel::leave_call(window, cx);
|
||||
});
|
||||
workspace.register_action(|workspace, _: &ShareProject, window, cx| {
|
||||
let project = workspace.project().clone();
|
||||
println!("{project:?}");
|
||||
window.defer(cx, move |_window, cx| {
|
||||
ActiveCall::global(cx).update(cx, move |call, cx| {
|
||||
if let Some(room) = call.room() {
|
||||
println!("{room:?}");
|
||||
if room.read(cx).is_sharing_project() {
|
||||
call.unshare_project(project, cx).ok();
|
||||
} else {
|
||||
call.share_project(project, cx).detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
workspace.register_action(|_, _: &ScreenShare, window, cx| {
|
||||
let room = ActiveCall::global(cx).read(cx).room().cloned();
|
||||
if let Some(room) = room {
|
||||
window.defer(cx, move |_window, cx| {
|
||||
room.update(cx, |room, cx| {
|
||||
if room.is_screen_sharing() {
|
||||
room.unshare_screen(cx).ok();
|
||||
} else {
|
||||
room.share_screen(cx).detach_and_log_err(cx);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::{Result, anyhow, bail};
|
||||
use assistant_tool::{ActionLog, Tool, ToolSource};
|
||||
use language_model::{ToolOutput, StringToolOutput};
|
||||
use gpui::{App, Entity, Task};
|
||||
use icons::IconName;
|
||||
use language_model::{LanguageModelRequestMessage, LanguageModelToolSchemaFormat};
|
||||
@@ -76,7 +77,7 @@ impl Tool for ContextServerTool {
|
||||
_project: Entity<Project>,
|
||||
_action_log: Entity<ActionLog>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<ToolOutput>> {
|
||||
if let Some(server) = self.server_manager.read(cx).get_server(&self.server_id) {
|
||||
let tool_name = self.tool.name.clone();
|
||||
let server_clone = server.clone();
|
||||
@@ -114,7 +115,7 @@ impl Tool for ContextServerTool {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
Ok(StringToolOutput::new(result))
|
||||
})
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("Context server not found")))
|
||||
|
||||
@@ -1280,10 +1280,6 @@ mod tests {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn to_proto(&self, _: &App) -> rpc::proto::File {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ pub enum Model {
|
||||
Gpt4o,
|
||||
#[serde(alias = "gpt-4", rename = "gpt-4")]
|
||||
Gpt4,
|
||||
#[serde(alias = "gpt-4.1", rename = "gpt-4.1")]
|
||||
Gpt4_1,
|
||||
#[serde(alias = "gpt-3.5-turbo", rename = "gpt-3.5-turbo")]
|
||||
Gpt3_5Turbo,
|
||||
#[serde(alias = "o1", rename = "o1")]
|
||||
@@ -52,8 +50,6 @@ pub enum Model {
|
||||
Claude3_7SonnetThinking,
|
||||
#[serde(alias = "gemini-2.0-flash", rename = "gemini-2.0-flash-001")]
|
||||
Gemini20Flash,
|
||||
#[serde(alias = "gemini-2.5-pro", rename = "gemini-2.5-pro")]
|
||||
Gemini25Pro,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@@ -61,12 +57,11 @@ impl Model {
|
||||
match self {
|
||||
Self::Gpt4o
|
||||
| Self::Gpt4
|
||||
| Self::Gpt4_1
|
||||
| Self::Gpt3_5Turbo
|
||||
| Self::Claude3_5Sonnet
|
||||
| Self::Claude3_7Sonnet
|
||||
| Self::Claude3_7SonnetThinking => true,
|
||||
Self::O3Mini | Self::O1 | Self::Gemini20Flash | Self::Gemini25Pro => false,
|
||||
Self::O3Mini | Self::O1 | Self::Gemini20Flash => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +69,6 @@ impl Model {
|
||||
match id {
|
||||
"gpt-4o" => Ok(Self::Gpt4o),
|
||||
"gpt-4" => Ok(Self::Gpt4),
|
||||
"gpt-4.1" => Ok(Self::Gpt4_1),
|
||||
"gpt-3.5-turbo" => Ok(Self::Gpt3_5Turbo),
|
||||
"o1" => Ok(Self::O1),
|
||||
"o3-mini" => Ok(Self::O3Mini),
|
||||
@@ -82,7 +76,6 @@ impl Model {
|
||||
"claude-3-7-sonnet" => Ok(Self::Claude3_7Sonnet),
|
||||
"claude-3.7-sonnet-thought" => Ok(Self::Claude3_7SonnetThinking),
|
||||
"gemini-2.0-flash-001" => Ok(Self::Gemini20Flash),
|
||||
"gemini-2.5-pro" => Ok(Self::Gemini25Pro),
|
||||
_ => Err(anyhow!("Invalid model id: {}", id)),
|
||||
}
|
||||
}
|
||||
@@ -91,7 +84,6 @@ impl Model {
|
||||
match self {
|
||||
Self::Gpt3_5Turbo => "gpt-3.5-turbo",
|
||||
Self::Gpt4 => "gpt-4",
|
||||
Self::Gpt4_1 => "gpt-4.1",
|
||||
Self::Gpt4o => "gpt-4o",
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
@@ -99,7 +91,6 @@ impl Model {
|
||||
Self::Claude3_7Sonnet => "claude-3-7-sonnet",
|
||||
Self::Claude3_7SonnetThinking => "claude-3.7-sonnet-thought",
|
||||
Self::Gemini20Flash => "gemini-2.0-flash-001",
|
||||
Self::Gemini25Pro => "gemini-2.5-pro",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +98,6 @@ impl Model {
|
||||
match self {
|
||||
Self::Gpt3_5Turbo => "GPT-3.5",
|
||||
Self::Gpt4 => "GPT-4",
|
||||
Self::Gpt4_1 => "GPT-4.1",
|
||||
Self::Gpt4o => "GPT-4o",
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
@@ -115,7 +105,6 @@ impl Model {
|
||||
Self::Claude3_7Sonnet => "Claude 3.7 Sonnet",
|
||||
Self::Claude3_7SonnetThinking => "Claude 3.7 Sonnet Thinking",
|
||||
Self::Gemini20Flash => "Gemini 2.0 Flash",
|
||||
Self::Gemini25Pro => "Gemini 2.5 Pro",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,15 +112,13 @@ impl Model {
|
||||
match self {
|
||||
Self::Gpt4o => 64_000,
|
||||
Self::Gpt4 => 32_768,
|
||||
Self::Gpt4_1 => 1_047_576,
|
||||
Self::Gpt3_5Turbo => 12_288,
|
||||
Self::O3Mini => 64_000,
|
||||
Self::O1 => 20_000,
|
||||
Self::Claude3_5Sonnet => 200_000,
|
||||
Self::Claude3_7Sonnet => 90_000,
|
||||
Self::Claude3_7SonnetThinking => 90_000,
|
||||
Self::Gemini20Flash => 128_000,
|
||||
Self::Gemini25Pro => 128_000,
|
||||
Model::Gemini20Flash => 128_000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ mod tests {
|
||||
use language::{
|
||||
Point,
|
||||
language_settings::{
|
||||
AllLanguageSettings, AllLanguageSettingsContent, CompletionSettings,
|
||||
AllLanguageSettings, AllLanguageSettingsContent, CompletionSettings, LspInsertMode,
|
||||
WordsCompletionMode,
|
||||
},
|
||||
};
|
||||
@@ -294,6 +294,7 @@ mod tests {
|
||||
words: WordsCompletionMode::Disabled,
|
||||
lsp: true,
|
||||
lsp_fetch_timeout_ms: 0,
|
||||
lsp_insert_mode: LspInsertMode::Insert,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -525,6 +526,7 @@ mod tests {
|
||||
words: WordsCompletionMode::Disabled,
|
||||
lsp: true,
|
||||
lsp_fetch_timeout_ms: 0,
|
||||
lsp_insert_mode: LspInsertMode::Insert,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ffi::OsStr;
|
||||
use anyhow::{Result, bail};
|
||||
use async_trait::async_trait;
|
||||
use gpui::AsyncApp;
|
||||
use task::{DebugAdapterConfig, DebugTaskDefinition};
|
||||
use task::{DebugAdapterConfig, DebugRequestType, DebugTaskDefinition};
|
||||
|
||||
use crate::*;
|
||||
|
||||
@@ -74,13 +74,37 @@ impl DebugAdapter for GdbDebugAdapter {
|
||||
}
|
||||
|
||||
fn request_args(&self, config: &DebugTaskDefinition) -> Value {
|
||||
let mut args = json!({
|
||||
"request": match config.request {
|
||||
DebugRequestType::Launch(_) => "launch",
|
||||
DebugRequestType::Attach(_) => "attach",
|
||||
},
|
||||
});
|
||||
|
||||
let map = args.as_object_mut().unwrap();
|
||||
match &config.request {
|
||||
dap::DebugRequestType::Attach(attach_config) => {
|
||||
json!({"pid": attach_config.process_id})
|
||||
DebugRequestType::Attach(attach) => {
|
||||
map.insert("pid".into(), attach.process_id.into());
|
||||
}
|
||||
dap::DebugRequestType::Launch(launch_config) => {
|
||||
json!({"program": launch_config.program, "cwd": launch_config.cwd})
|
||||
|
||||
DebugRequestType::Launch(launch) => {
|
||||
map.insert("program".into(), launch.program.clone().into());
|
||||
|
||||
if !launch.args.is_empty() {
|
||||
map.insert("args".into(), launch.args.clone().into());
|
||||
}
|
||||
|
||||
if let Some(stop_on_entry) = config.stop_on_entry {
|
||||
map.insert(
|
||||
"stopAtBeginningOfMainSubprogram".into(),
|
||||
stop_on_entry.into(),
|
||||
);
|
||||
}
|
||||
if let Some(cwd) = launch.cwd.as_ref() {
|
||||
map.insert("cwd".into(), cwd.to_string_lossy().into_owned().into());
|
||||
}
|
||||
}
|
||||
}
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,16 +83,25 @@ impl DebugAdapter for GoDebugAdapter {
|
||||
}
|
||||
|
||||
fn request_args(&self, config: &DebugTaskDefinition) -> Value {
|
||||
match &config.request {
|
||||
let mut args = match &config.request {
|
||||
dap::DebugRequestType::Attach(attach_config) => {
|
||||
json!({
|
||||
"processId": attach_config.process_id
|
||||
"processId": attach_config.process_id,
|
||||
})
|
||||
}
|
||||
dap::DebugRequestType::Launch(launch_config) => json!({
|
||||
"program": launch_config.program,
|
||||
"cwd": launch_config.cwd,
|
||||
"args": launch_config.args
|
||||
}),
|
||||
};
|
||||
|
||||
let map = args.as_object_mut().unwrap();
|
||||
|
||||
if let Some(stop_on_entry) = config.stop_on_entry {
|
||||
map.insert("stopOnEntry".into(), stop_on_entry.into());
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user